feat: solution for task-001

This commit is contained in:
+61 -88
View File
@@ -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**
APPROVED