"""Иерархический AI-агент: планирование списка покупок (LangChain + LM Studio).""" from __future__ import annotations from langchain.agents import create_agent from langchain.tools import tool from langchain_openai import ChatOpenAI from pydantic import SecretStr # Подключение к локальной LLM (LM Studio, OpenAI-совместимый API) llm = ChatOpenAI( model="local-model", base_url="http://localhost:1234/v1", api_key=SecretStr("fake"), temperature=0.7, ) @tool def get_price(product: str, city: str) -> str: """Узнать примерную цену продукта в указанном городе. Возвращает строку таблицы.""" price_agent = create_agent( model=llm, system_prompt=( "Ты эксперт по розничным ценам. " "Опирайся на типичные исторические цены в России. " "Ответ — одна строка таблицы: | Продукт | Цена (руб.) | Магазин |" ), ) result = price_agent.invoke( { "messages": [ { "role": "human", "content": ( f"Какая примерная цена на «{product}» в городе {city}? " "Верни одну строку таблицы | Продукт | Цена (руб.) | Магазин |" ), } ] } ) return result["messages"][-1].content def format_message(message) -> str: """Текст сообщения или вызов инструмента для вывода в консоль.""" if getattr(message, "content", None): return str(message.content) tool_calls = getattr(message, "tool_calls", None) or [] if tool_calls: tc = tool_calls[0] name = tc.get("name") if isinstance(tc, dict) else getattr(tc, "name", "?") args = tc.get("args") if isinstance(tc, dict) else getattr(tc, "args", {}) return f"{name}({args})" return str(message) shopping_agent = create_agent( model=llm, tools=[get_price], system_prompt="Ты помощник по планированию покупок", ) def main() -> None: question = ( "Помоги составить список покупок: молоко, хлеб, яблоки. Я нахожусь в Казани." ) answer = shopping_agent.invoke({"messages": [{"role": "human", "content": question}]}) print("--- Цепочка сообщений ---") for msg in answer["messages"]: print("---") print(format_message(msg)) print("---") print("Финальный ответ:") print(answer["messages"][-1].content) if __name__ == "__main__": main()