From f2bf2ef02ce4998a298aec16a302b6749f3fd401 Mon Sep 17 00:00:00 2001 From: lonpatovaadelina Date: Thu, 28 May 2026 10:37:43 +0000 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20agent.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent.py | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 agent.py diff --git a/agent.py b/agent.py new file mode 100644 index 0000000..655fed5 --- /dev/null +++ b/agent.py @@ -0,0 +1,116 @@ +# agent.py + +""" +Простой LangChain‑агент с поддержкой потокового вывода через `agent.stream()`. +Внутри используется один инструмент – get_price, который вызывает под‑агента, +обрабатывающего запросы к «базе цен». +""" + +from langchain.agents import create_agent +from langchain.tools import tool +from rich import print as rprint + +# --------------------------------------------------------------------------- # +# 1. Определяем LLM (Ollama) – это единственный доступный LLM в задании. +# --------------------------------------------------------------------------- # +try: + from langchain_ollama import ChatOllama +except ImportError: # если Ollama недоступен, используем простой Mock‑LLM + class DummyLLM: + def __call__(self, *args, **kwargs): + return "Mock response" + + llm = DummyLLM() +else: + llm = ChatOllama(model="llama3.1") # пример модели + +# --------------------------------------------------------------------------- # +# 2. Создаём инструмент get_price. +# --------------------------------------------------------------------------- # + +@tool +def get_price(product: str, city: str) -> str: + """ + Возвращает таблицу цен на указанный продукт в заданном городе. + Для демонстрации используется под‑агент, который формирует ответ. + """ + # Под‑агент – простая функция, которая возвращает строку + sub_agent = create_agent( + llm=llm, + tools=[], + verbose=False, + agent_type="openai-tools", + ) + + # Запускаем под‑агента в режиме invoke (т.к. он короткий) + result = sub_agent.invoke({ + "messages": [ + {"role": "human", "content": f"Сколько стоит {product} в городе {city}?"} + ] + }) + return result["output"] + +# --------------------------------------------------------------------------- # +# 3. Создаём главный агент с инструментом get_price. +# --------------------------------------------------------------------------- # + +agent = create_agent( + llm=llm, + tools=[get_price], + verbose=False, + agent_type="openai-tools", +) + +# --------------------------------------------------------------------------- # +# 4. Функции для форматирования и вывода чанков. +# --------------------------------------------------------------------------- # + +step = 1 + +def format_chunk_message(chunk): + """ + Выводит токен текста без перевода строки. + При смене шага печатает разделитель. + """ + global step + message, meta = chunk + if meta["langgraph_step"] != step: + step = meta["langgraph_step"] + rprint("\n--- --- ---\n") + if message.content: + print(message.content, end="", flush=True) + +def format_message(message): + """ + Форматирует сообщение для вывода в режиме invoke. + """ + if message.content: + return message.content + # Если нет content – это вызов инструмента + tool_call = message.tool_calls[0] + return f"{tool_call['name']}({tool_call['args']})" + +# --------------------------------------------------------------------------- # +# 5. Запускаем потоковый вывод. +# --------------------------------------------------------------------------- # + +if __name__ == "__main__": + # Пример запроса к агенту + stream = agent.stream( + { + "messages": [ + {"role": "human", "content": "Покажи мне цены на молоко и хлеб в Казани."} + ] + }, + stream_mode=["messages", "updates"], + ) + + for chunk in stream: + chunk_type, chunk_data = chunk + if chunk_type == "messages": + format_chunk_message(chunk_data) + elif chunk_type == "updates": + # При завершении шага выводим итоговое сообщение + if chunk_data.get("model"): + last_msg = chunk_data["model"]["messages"][-1] + rprint("\n" + format_message(last_msg) + "\n") \ No newline at end of file