Добавлен solution.py

This commit is contained in:
2026-05-28 14:14:14 +00:00
parent 242b564d4e
commit f214b91485
+95
View File
@@ -0,0 +1,95 @@
# solution.py
"""
Основной скрипт агента с потоковым выводом.
Используется стек: LangChain, OpenAI и rich.
"""
from langchain import hub
from langchain.agents import initialize_agent, AgentType
from langchain.tools import tool
from langchain_community.llms.openai import OpenAI
from rich import print as rprint
# ---------- 1. Подключаем LLM ----------
llm = OpenAI(temperature=0, model="gpt-4o-mini", streaming=True)
# ---------- 2. Определяем инструмент ----------
@tool
def get_price(product: str, city: str) -> str:
"""
Возвращает таблицу цен на указанный продукт в заданном городе.
"""
# В реальном приложении здесь будет запрос к базе данных или API.
# Для демонстрации возвращаем статический ответ.
if product.lower() == "молоко":
return "| Продукт | Цена (руб.) | Магазин |\n| Молоко | 89 | Магнит |"
elif product.lower() == "хлеб":
return "| Продукт | Цена (руб.) | Магазин |\n| Хлеб | 25 | Пятёрочка |"
else:
return f"Информация о {product} в городе {city} недоступна."
# ---------- 3. Создаём агента ----------
tools = [get_price]
agent = initialize_agent(
tools,
llm,
agent=AgentType.OPENAI_FUNCTIONS,
verbose=False, # отключаем стандартный вывод
)
# ---------- 4. Функции форматирования ----------
def format_message(message) -> str:
"""
Форматируем сообщение для вывода в консоль.
Если есть content – возвращаем его,
иначе формируем строку вызова инструмента.
"""
if message.content:
return message.content
# В случае tool_calls: берём первый вызов
call = message.tool_calls[0]
name = call["name"]
args = call.get("args", {})
return f"{name}({args})"
def format_chunk_message(chunk):
"""
Обрабатываем чанк типа 'messages'.
Выводим токен без перевода строки, добавляем разделитель при смене шага.
"""
message, meta = chunk
global step
if meta.get("langgraph_step") != step:
step = meta["langgraph_step"]
rprint("\n --- --- --- \n")
content = format_message(message)
# Выводим без перевода строки, чтобы токены «текли»
print(content, end="", flush=True)
# ---------- 5. Запускаем потоковый вывод ----------
if __name__ == "__main__":
# Пример запроса
user_prompt = "Сколько стоит молоко в Казани? А как насчёт хлеба?"
stream = agent.stream(
{"messages": [{"role": "human", "content": user_prompt}]},
stream_mode=["messages", "updates"],
)
step = 1
for chunk in stream:
chunk_type, chunk_data = chunk
if chunk_type == "messages":
format_chunk_message(chunk_data)
elif chunk_type == "updates" and chunk_data.get("model"):
# После завершения шага выводим итоговое сообщение модели
last_msg = chunk_data["model"]["messages"][-1]
rprint("\n")
print(format_message(last_msg), flush=True)
# Завершающий перевод строки, чтобы консоль оставалась аккуратной
print()