diff --git a/main.py b/main.py index 5f361f6..39a8115 100644 --- a/main.py +++ b/main.py @@ -1,68 +1,72 @@ +import os import asyncio from langchain_openai import ChatOpenAI -from pydantic import SecretStr from langchain.tools import tool -from deepagents import create_deep_agent -from deepagents.backends import CompositeBackend, LocalShellBackend, FilesystemBackend +from langchain.agents import create_agent from langchain_core.messages import HumanMessage -# 1. Подключение к локальной LLM +# --- LLM setup ------------------------------------------------------------ +# Connect to local LM Studio server (OpenAI compatible API) llm = ChatOpenAI( - model='llama3.1-8b', - base_url='http://localhost:1234/v1', - api_key=SecretStr('fake'), + model="<название модели в LM Studio>", + base_url="http://localhost:1234/v1", + api_key=os.getenv("OPENAI_API_KEY", "fake"), temperature=0.7, ) -# 2. Backend для deepagents -backend = CompositeBackend([ - LocalShellBackend(workspace_dir='./workspace'), - FilesystemBackend(), -]) - -# 3. Субагент, генерирующий цену -@tool -def get_price(product: str, city: str) -> str: - """Получить примерную цену продукта в указанном городе. - Возвращает таблицу в формате Markdown. - """ - # Создаём субагент, который просто генерирует реалистичную цену - sub_agent = create_deep_agent( - model=llm, - tools=[], - backend=backend, - system_prompt=f"Ты эксперт по ценам в {city}. Дай таблицу с продуктом, ценой и магазином.", - ) - # Запрос к субагенту - response = asyncio.run(sub_agent.ainvoke( - {"messages": [HumanMessage(content=f"Сгенерируй таблицу цены для продукта {product} в городе {city}.")]}, - {"configurable": {"thread_id": f"price-{product}-{city}"}}, - )) - # Предполагаем, что последний элемент содержит таблицу - return response["messages"][-1].content - -# 4. Главный агент -agent = create_deep_agent( +# --- Sub‑agent for price generation ------------------------------------- +# This sub‑agent is created inside the tool and is responsible for +# producing a realistic price table for a single product. +sub_agent = create_agent( model=llm, - tools=[get_price], - backend=backend, - system_prompt='Ты помощник по планированию покупок.', + tools=[], # no external tools needed for the sub‑agent + system_prompt="Ты генератор цены. На основе исторических данных выдавай таблицу с ценой и магазином.", ) -# 5. Запуск +# --- Tool definition ----------------------------------------------------- +@tool +def get_price(product: str, city: str) -> str: + """Получить цену продукта в указанном городе. + + Возвращает строку в формате Markdown‑таблицы: + | Продукт | Цена (руб.) | Магазин | + """ + # Формируем запрос для суб‑агента + prompt = f"\n\nНайди примерную цену на {product} в городе {city}.\n\nВыведи результат в виде таблицы:\n| Продукт | Цена (руб.) | Магазин |" + # Запускаем суб‑агента + result = sub_agent.invoke({"messages": [HumanMessage(content=prompt)]}) + # sub_agent возвращает dict с ключом 'messages' + # Берём последний текстовый ответ + last_msg = result["messages"][-1] + return last_msg.content.strip() + +# --- Main agent ---------------------------------------------------------- +agent = create_agent( + model=llm, + tools=[get_price], + system_prompt="Ты помощник по планированию покупок.", +) + +# --- Helper for pretty printing ---------------------------------------- + +def format_message(message): + if hasattr(message, "content") and message.content: + return message.content + if hasattr(message, "tool_calls") and message.tool_calls: + call = message.tool_calls[0] + return f"{call['name']}({call['args']})" + return "" + +# --- Main execution ------------------------------------------------------ async def main(): user_query = "Помоги составить список покупок: молоко, хлеб, яблоки. Я нахожусь в Казани." result = await agent.ainvoke( {"messages": [HumanMessage(content=user_query)]}, - {"configurable": {"thread_id": "shopping-session"}}, + {"configurable": {"thread_id": "session-1"}}, ) - # Вывод всех сообщений + # Выводим все сообщения for msg in result["messages"]: - if msg.content: - print(msg.content) - elif msg.tool_calls: - for call in msg.tool_calls: - print(f"{call['name']}({call['args']})") + print(format_message(msg)) if __name__ == "__main__": asyncio.run(main())