feat: solution for task-001
This commit is contained in:
@@ -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 = price_agent.invoke({"input": prompt})
|
||||
return result["output"]
|
||||
|
||||
result = response['messages'][-1].content
|
||||
return result
|
||||
# Создание главного агента
|
||||
prompt = ChatPromptTemplate.from_messages([
|
||||
("system", "Ты помощник по планированию покупок. Твоя задача:\n1. Принять список продуктов от пользователя\n2. Для каждого продукта вызвать инструмент get_price, чтобы узнать цену в его городе\n3. Собрать все цены в таблицу\n4. Посчитать итоговую стоимость\n5. Дать финальный ответ с таблицей и итогом\n\nВсегда пиши финальный ответ на русском языке."),
|
||||
("human", "{input}"),
|
||||
MessagesPlaceholder(variable_name="agent_scratchpad"),
|
||||
])
|
||||
|
||||
# 4. Главный агент
|
||||
main_agent = create_agent(
|
||||
model=llm,
|
||||
tools=[get_price],
|
||||
system_prompt='Ты помощник по планированию покупок. '
|
||||
'Твоя задача — помочь пользователю составить список покупок, '
|
||||
'узнать цены на каждый продукт через инструмент get_price, '
|
||||
'и посчитать итоговую стоимость. '
|
||||
'Отвечай на русском языке.'
|
||||
)
|
||||
agent = create_openai_tools_agent(llm=llm, tools=[get_price], prompt=prompt)
|
||||
agent_executor = AgentExecutor(agent=agent, tools=[get_price], verbose=True)
|
||||
|
||||
# 5. Функция форматирования сообщений
|
||||
# Запрос и вывод
|
||||
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):
|
||||
"""Запускает агента с запросом о списках покупок"""
|
||||
print("\n=== Цепочка сообщений ===")
|
||||
for msg in result["messages"]:
|
||||
print(format_message(msg))
|
||||
print("-" * 50)
|
||||
|
||||
query = f"Помоги составить список покупок: {', '.join(products)}. Я нахожусь в {city}."
|
||||
print("\n=== Финальный ответ ===")
|
||||
print(result["output"])
|
||||
|
||||
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)
|
||||
|
||||
# Запуск
|
||||
if __name__ == "__main__":
|
||||
# Пример использования
|
||||
products = ["молоко", "хлеб", "яблоки"]
|
||||
city = "Казань"
|
||||
run_shopping_agent(products, city)
|
||||
|
||||
**APPROVED**
|
||||
APPROVED
|
||||
Reference in New Issue
Block a user