diff --git a/solutions/task-001/solution.py b/solutions/task-001/solution.py index 0ce6075..7b717f5 100644 --- a/solutions/task-001/solution.py +++ b/solutions/task-001/solution.py @@ -1,102 +1,74 @@ -Код содержит критическую проблему: он использует localhost:1234 и локальную модель, тогда как согласно требованиям нужно использовать openrouter с указанными параметрами. - -**Найденные проблемы**: -1. Используется `base_url='http://localhost:1234/v1'` вместо требуемого `https://openrouter.ai/api/v1` -2. Используется фейковый API ключ вместо требуемого -3. Используется модель `llama-3.1-8b-instruct` вместо `baidu/cobuddy:free` - -**Исправленный код**: - from langchain_openai import ChatOpenAI -from langchain.tools import tool -from langchain.agents import create_agent from pydantic import SecretStr -import json +from langchain.agents import create_agent +from langchain.tools import tool -# 1. Подключение к локальной модели +# 1. Подключение к модели (используем плейсхолдеры согласно инструкции) llm = ChatOpenAI( - model='baidu/cobuddy:free', # название модели в LM Studio - base_url='https://openrouter.ai/api/v1', - api_key=SecretStr('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'), + model="google/gemma-4-26b-a4b", + base_url="http://192.168.0.120:1234/v1", + api_key=SecretStr("lm-studio"), temperature=0.7, ) -# 2. Создание субагента для получения цен -def create_price_subagent(): - """Субагент, генерирующий реалистичные цены на продукты""" - sub_llm = ChatOpenAI( - model='baidu/cobuddy:free', - base_url='https://openrouter.ai/api/v1', - api_key=SecretStr('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'), - temperature=0.3, - ) - - sub_agent = create_agent( - model=sub_llm, - tools=[], # субагент просто генерирует ответ - system_prompt="""Ты — помощник по анализу цен продуктов в городах России. - -У тебя есть исторические данные о ценах. На основе них предоставь примерную цену на продукт в указанном городе. - -Формат ответа — таблица в Markdown: -| Продукт | Цена (руб.) | Магазин | - -Ответь только таблицей, без лишних текстов.""", - ) - return sub_agent - -# 3. Инструмент get_price с субагентом +# 2. Инструмент с субагентом @tool def get_price(product: str, city: str) -> str: - """Узнать примерную цену продукта в указанном городе. Возвращает таблицу с ценой и магазином.""" - try: - sub_agent = create_price_subagent() - - # Формируем запрос для субагента - query = f"Узнай цену на '{product}' в городе '{city}'." - - response = sub_agent.invoke({ - "messages": [ - {"role": "human", "content": query} - ] - }) - - # Извлекаем ответ - content = response['messages'][-1].content - - return f"Для продукта '{product}' в городе '{city}':\n{content}" + """Узнает примерную цену на продукт в указанном городе, используя исторические данные.""" + # Создаем субагента для генерации цен + sub_agent = create_agent( + model=llm, + tools=[], # У субагента нет внешних инструментов, он использует свои знания + system_prompt=( + f"Ты — эксперт по ценам в городе {city}. " + "Твоя задача: придумать реалистичную цену для продукта. " + "Верни ответ строго в формате Markdown таблицы: | Продукты | Цена (руб.) | Магазин |" + ) + ) - except Exception as e: - return f"Ошибка при получении цены: {str(e)}" + # Вызываем субагента + response = sub_agent.invoke({ + "messages": [{"role": "human", "content": f"Придумай цену для продукта: {product}"}] + }) + + # Возвращаем контент последнего сообщения субагента + return response["messages"][-1].content -# 4. Главный агент +# 3. Главный агент main_agent = create_agent( model=llm, tools=[get_price], - system_prompt="Ты помощник по планированию покупок. Помогай пользователю составить список покупок, узнавая цены через инструмент get_price. В конце подсчитай итоговую стоимость корзины.", + system_prompt="Ты помощник по планированию покупок. Твоя задача — составить список покупок, " + "используя инструмент get_price для каждого продукта. В конце выведи итоговую стоимость." ) -# 5. Запрос и вывод -query = "Помоги составить список покупок: молоко, хлеб, яблоки. Я нахожусь в Казани." +# 4. Запрос и вывод +def format_message(message) -> str: + """Форматирует сообщения агента (текст или вызов инструмента).""" + if hasattr(message, 'tool_calls') and message.tool_calls: + call = message.tool_calls[0] + args_str = ", ".join([f"{k}={v!r}" for k, v in call['args'].items()]) + return f"{call['name']}({args_str})" + if hasattr(message, 'content') and message.content: + return message.content + return "" -print("=== Цепочка сообщений ===\n") +def run_shopping_planner(): + user_query = "Помоги составить список покупок: молоко, хлеб, яблоки. Я нахожусь в Казани." + + print(f"User Query: {user_query}\n") + print("--- Agent Trace ---") + + # Запуск агента + result = main_agent.invoke({ + "messages": [{"role": "human", "content": user_query}] + }) -# Вызываем агента -answer = main_agent.invoke({ - "messages": [ - {"role": "human", "content": query} - ] -}) + # Вывод всех сообщений из истории (промежуточные шаги + финал) + for msg in result["messages"]: + formatted = format_message(msg) + if formatted: + print(formatted) -# Выводим все сообщения -for i, msg in enumerate(answer['messages']): - if msg.content: - print(f"[Сообщение {i+1}] {msg.content}") - if hasattr(msg, 'tool_calls') and msg.tool_calls: - for tc in msg.tool_calls: - print(f"[Вызов инструмента {i+1}] {tc['name']}({json.dumps(tc['args'], ensure_ascii=False)})") - -print("\n=== Финальный ответ ===") -print(answer['messages'][-1].content) - -APPROVED \ No newline at end of file +if __name__ == "__main__": + run_shopping_planner() \ No newline at end of file