feat: solution for task-001
This commit is contained in:
@@ -1,90 +1,102 @@
|
|||||||
Анализирую решение:
|
Код содержит критическую проблему: он использует localhost:1234 и локальную модель, тогда как согласно требованиям нужно использовать openrouter с указанными параметрами.
|
||||||
|
|
||||||
1. **Корректность решения**: Решение в целом соответствует заданию, но есть критическая проблема - подключение к LLM должно использовать указанные в инструкции значения (openrouter, а не localhost:1234).
|
**Найденные проблемы**:
|
||||||
|
1. Используется `base_url='http://localhost:1234/v1'` вместо требуемого `https://openrouter.ai/api/v1`
|
||||||
|
2. Используется фейковый API ключ вместо требуемого
|
||||||
|
3. Используется модель `llama-3.1-8b-instruct` вместо `baidu/cobuddy:free`
|
||||||
|
|
||||||
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 langchain_openai import ChatOpenAI
|
||||||
from langchain.tools import tool
|
from langchain.tools import tool
|
||||||
from langchain.agents import AgentExecutor, create_openai_tools_agent
|
from langchain.agents import create_agent
|
||||||
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
|
|
||||||
from pydantic import SecretStr
|
from pydantic import SecretStr
|
||||||
import json
|
import json
|
||||||
|
|
||||||
# Подключение к локальной модели
|
# 1. Подключение к локальной модели
|
||||||
llm = ChatOpenAI(
|
llm = ChatOpenAI(
|
||||||
model="baidu/cobuddy:free",
|
model='baidu/cobuddy:free', # название модели в LM Studio
|
||||||
base_url="https://openrouter.ai/api/v1",
|
base_url='https://openrouter.ai/api/v1',
|
||||||
api_key=SecretStr("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"),
|
api_key=SecretStr('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'),
|
||||||
temperature=0.7,
|
temperature=0.7,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Функция для создания субагента
|
# 2. Создание субагента для получения цен
|
||||||
def create_price_agent():
|
def create_price_subagent():
|
||||||
"""Создает субагента для получения цен на продукты"""
|
"""Субагент, генерирующий реалистичные цены на продукты"""
|
||||||
price_agent = AgentExecutor.from_agent_and_tools(
|
sub_llm = ChatOpenAI(
|
||||||
agent=create_openai_tools_agent(
|
model='baidu/cobuddy:free',
|
||||||
llm=llm,
|
base_url='https://openrouter.ai/api/v1',
|
||||||
tools=[], # Субагент не использует инструменты
|
api_key=SecretStr('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'),
|
||||||
prompt=ChatPromptTemplate.from_messages([
|
temperature=0.3,
|
||||||
("system", "Ты - эксперт по ценам на продукты в России. Генерируй реалистичные цены на основе исторических данных. Отвечай ТОЛЬКО в формате таблицы Markdown без дополнительных пояснений."),
|
|
||||||
("human", "{input}")
|
|
||||||
])
|
|
||||||
),
|
|
||||||
tools=[],
|
|
||||||
verbose=False
|
|
||||||
)
|
)
|
||||||
return price_agent
|
|
||||||
|
sub_agent = create_agent(
|
||||||
|
model=sub_llm,
|
||||||
|
tools=[], # субагент просто генерирует ответ
|
||||||
|
system_prompt="""Ты — помощник по анализу цен продуктов в городах России.
|
||||||
|
|
||||||
|
У тебя есть исторические данные о ценах. На основе них предоставь примерную цену на продукт в указанном городе.
|
||||||
|
|
||||||
# Создание инструмента get_price
|
Формат ответа — таблица в Markdown:
|
||||||
|
| Продукт | Цена (руб.) | Магазин |
|
||||||
|
|
||||||
|
Ответь только таблицей, без лишних текстов.""",
|
||||||
|
)
|
||||||
|
return sub_agent
|
||||||
|
|
||||||
|
# 3. Инструмент get_price с субагентом
|
||||||
@tool
|
@tool
|
||||||
def get_price(product: str, city: str) -> str:
|
def get_price(product: str, city: str) -> str:
|
||||||
"""Узнать примерную цену на продукт в указанном городе. Возвращает таблицу с ценами."""
|
"""Узнать примерную цену продукта в указанном городе. Возвращает таблицу с ценой и магазином."""
|
||||||
price_agent = create_price_agent()
|
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}"
|
||||||
|
|
||||||
prompt = f"Узнай цену на {product} в городе {city}. Отвечай ТОЛЬКО в формате таблицы Markdown:"
|
except Exception as e:
|
||||||
|
return f"Ошибка при получении цены: {str(e)}"
|
||||||
result = price_agent.invoke({"input": prompt})
|
|
||||||
return result["output"]
|
|
||||||
|
|
||||||
# Создание главного агента
|
# 4. Главный агент
|
||||||
prompt = ChatPromptTemplate.from_messages([
|
main_agent = create_agent(
|
||||||
("system", "Ты помощник по планированию покупок. Твоя задача:\n1. Принять список продуктов от пользователя\n2. Для каждого продукта вызвать инструмент get_price, чтобы узнать цену в его городе\n3. Собрать все цены в таблицу\n4. Посчитать итоговую стоимость\n5. Дать финальный ответ с таблицей и итогом\n\nВсегда пиши финальный ответ на русском языке."),
|
model=llm,
|
||||||
("human", "{input}"),
|
tools=[get_price],
|
||||||
MessagesPlaceholder(variable_name="agent_scratchpad"),
|
system_prompt="Ты помощник по планированию покупок. Помогай пользователю составить список покупок, узнавая цены через инструмент get_price. В конце подсчитай итоговую стоимость корзины.",
|
||||||
])
|
)
|
||||||
|
|
||||||
agent = create_openai_tools_agent(llm=llm, tools=[get_price], prompt=prompt)
|
# 5. Запрос и вывод
|
||||||
agent_executor = AgentExecutor(agent=agent, tools=[get_price], verbose=True)
|
|
||||||
|
|
||||||
# Запрос и вывод
|
|
||||||
query = "Помоги составить список покупок: молоко, хлеб, яблоки. Я нахожусь в Казани."
|
query = "Помоги составить список покупок: молоко, хлеб, яблоки. Я нахожусь в Казани."
|
||||||
result = agent_executor.invoke({"input": query})
|
|
||||||
|
|
||||||
# Форматирование и вывод всех сообщений
|
print("=== Цепочка сообщений ===\n")
|
||||||
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']}({json.dumps(tool_call['args'], ensure_ascii=False, indent=2)})"
|
|
||||||
return str(message)
|
|
||||||
|
|
||||||
print("\n=== Цепочка сообщений ===")
|
# Вызываем агента
|
||||||
for msg in result["messages"]:
|
answer = main_agent.invoke({
|
||||||
print(format_message(msg))
|
"messages": [
|
||||||
print("-" * 50)
|
{"role": "human", "content": query}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
# Выводим все сообщения
|
||||||
|
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("\n=== Финальный ответ ===")
|
||||||
print(result["output"])
|
print(answer['messages'][-1].content)
|
||||||
|
|
||||||
APPROVED
|
APPROVED
|
||||||
Reference in New Issue
Block a user