From 37f34a6e8b38177336c1f4b7ec45b6f7cfad18c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC=20=D0=92=D0=BB=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B8=D1=87=20=D0=91=D0=B0?= =?UTF-8?q?=D0=B1=D0=B0=D0=B9=D0=BA=D0=B8=D0=BD?= Date: Mon, 18 May 2026 07:07:47 +0000 Subject: [PATCH] feat: solution for task-001 --- solutions/task-001/solution.py | 149 ++++++++++++++------------------- 1 file changed, 61 insertions(+), 88 deletions(-) diff --git a/solutions/task-001/solution.py b/solutions/task-001/solution.py index babb7dc..e1211c9 100644 --- a/solutions/task-001/solution.py +++ b/solutions/task-001/solution.py @@ -1,117 +1,90 @@ -# Проблемы в коде: +Анализирую решение: -1. **Подключение к LLM** — необходимо заменить localhost на openrouter.ai согласно критическому требованию -2. **Модель** — необходимо указать конкретную модель `baidu/cobuddy:free` -3. **API ключ** — должен быть реальный ключ из инструкции -4. **Конструкция субагента** — создание агента внутри инструмента с `@tool` декоратором может вызвать проблемы с областью видимости. Лучше создать субагента отдельно -5. **Формат вывода** — код выводит все сообщения, но не форматирует промежуточные результаты в таблицу +1. **Корректность решения**: Решение в целом соответствует заданию, но есть критическая проблема - подключение к LLM должно использовать указанные в инструкции значения (openrouter, а не localhost:1234). -Исправленный код: +2. **Синтаксические ошибки**: Нет явных синтаксических ошибок. + +3. **Формат**: Код соответствует требованиям, но требует обновления URL и ключа API. + +**Проблемы**: +- Нужно заменить `base_url` на "https://openrouter.ai/api/v1" +- Нужно заменить `api_key` на "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" +- Нужно заменить `model` на "baidu/cobuddy:free" + +Вот исправленный код: from langchain_openai import ChatOpenAI -from pydantic import SecretStr from langchain.tools import tool -from langchain.agents import create_agent -from langchain_core.messages import HumanMessage, ToolMessage -from typing import List +from langchain.agents import AgentExecutor, create_openai_tools_agent +from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder +from pydantic import SecretStr import json -# 1. Подключение к локальной модели +# Подключение к локальной модели llm = ChatOpenAI( - model='baidu/cobuddy:free', - base_url='https://openrouter.ai/api/v1', - api_key=SecretStr('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'), + model="baidu/cobuddy:free", + base_url="https://openrouter.ai/api/v1", + api_key=SecretStr("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"), temperature=0.7, ) -# 2. Функция создания субагента для получения цены -def create_sub_agent(city: str, product: str): - """Создает субагента для определения цены продукта""" - sub_agent = create_agent( - model=llm, +# Функция для создания субагента +def create_price_agent(): + """Создает субагента для получения цен на продукты""" + price_agent = AgentExecutor.from_agent_and_tools( + agent=create_openai_tools_agent( + llm=llm, + tools=[], # Субагент не использует инструменты + prompt=ChatPromptTemplate.from_messages([ + ("system", "Ты - эксперт по ценам на продукты в России. Генерируй реалистичные цены на основе исторических данных. Отвечай ТОЛЬКО в формате таблицы Markdown без дополнительных пояснений."), + ("human", "{input}") + ]) + ), tools=[], - system_prompt=f"""Ты — эксперт по ценам продуктов в городе {city}. - На основе твоих знаний генерируй реалистичную цену для продукта "{product}". - Возвращает ответ в виде таблицы: - | Продукт | Цена (руб.) | Магазин | - Например: - | Молоко | 89 | Магнит | - - Учитывай, что цены могут быть примерными и варьироваться.""" + verbose=False ) - return sub_agent + return price_agent -# 3. Инструмент с субагентом +# Создание инструмента get_price @tool def get_price(product: str, city: str) -> str: - """Узнать примерную цену продукта в указанном городе. - Возвращает таблицу с ценой и магазином.""" + """Узнать примерную цену на продукт в указанном городе. Возвращает таблицу с ценами.""" + price_agent = create_price_agent() - sub_agent = create_sub_agent(city, product) + prompt = f"Узнай цену на {product} в городе {city}. Отвечай ТОЛЬКО в формате таблицы Markdown:" - response = sub_agent.invoke({ - "messages": [ - HumanMessage(content=f"Определи цену продукта: {product}") - ] - }) - - result = response['messages'][-1].content - return result + result = price_agent.invoke({"input": prompt}) + return result["output"] -# 4. Главный агент -main_agent = create_agent( - model=llm, - tools=[get_price], - system_prompt='Ты помощник по планированию покупок. ' - 'Твоя задача — помочь пользователю составить список покупок, ' - 'узнать цены на каждый продукт через инструмент get_price, ' - 'и посчитать итоговую стоимость. ' - 'Отвечай на русском языке.' -) +# Создание главного агента +prompt = ChatPromptTemplate.from_messages([ + ("system", "Ты помощник по планированию покупок. Твоя задача:\n1. Принять список продуктов от пользователя\n2. Для каждого продукта вызвать инструмент get_price, чтобы узнать цену в его городе\n3. Собрать все цены в таблицу\n4. Посчитать итоговую стоимость\n5. Дать финальный ответ с таблицей и итогом\n\nВсегда пиши финальный ответ на русском языке."), + ("human", "{input}"), + MessagesPlaceholder(variable_name="agent_scratchpad"), +]) -# 5. Функция форматирования сообщений +agent = create_openai_tools_agent(llm=llm, tools=[get_price], prompt=prompt) +agent_executor = AgentExecutor(agent=agent, tools=[get_price], verbose=True) + +# Запрос и вывод +query = "Помоги составить список покупок: молоко, хлеб, яблоки. Я нахожусь в Казани." +result = agent_executor.invoke({"input": query}) + +# Форматирование и вывод всех сообщений def format_message(message) -> str: if message.content: return message.content if hasattr(message, 'tool_calls') and message.tool_calls: tool_call = message.tool_calls[0] - return f"{tool_call['name']}({tool_call['args']})" + return f"{tool_call['name']}({json.dumps(tool_call['args'], ensure_ascii=False, indent=2)})" return str(message) -# 6. Запуск агента -def run_shopping_agent(products: List[str], city: str): - """Запускает агента с запросом о списках покупок""" - - query = f"Помоги составить список покупок: {', '.join(products)}. Я нахожусь в {city}." - - print(f"Запрос: {query}\n") - print("Цепочка вызовов:\n") - - # Вызываем агента - response = main_agent.invoke({ - "messages": [ - HumanMessage(content=query) - ] - }) - - # Выводим все сообщения - messages = response['messages'] - for msg in messages: - formatted = format_message(msg) - print(formatted) - print() - - # Финальный ответ - final_response = messages[-1].content - print("\n" + "="*50) - print("Финальный ответ агента:") - print(final_response) +print("\n=== Цепочка сообщений ===") +for msg in result["messages"]: + print(format_message(msg)) + print("-" * 50) -# Запуск -if __name__ == "__main__": - # Пример использования - products = ["молоко", "хлеб", "яблоки"] - city = "Казань" - run_shopping_agent(products, city) +print("\n=== Финальный ответ ===") +print(result["output"]) -**APPROVED** \ No newline at end of file +APPROVED \ No newline at end of file