# solution.py """ Пример агента с Human-in-the-Loop через middleware. При каждом вызове инструмента агент останавливается, выводит информацию и ожидает решения пользователя: approve / reject (с возможностью указать причину отказа). """ from langchain import ChatOpenAI from langchain.tools import tool from langgraph.checkpoint.memory import MemorySaver from langchain.agents.middleware import HumanInTheLoopMiddleware from langchain.agents import create_react_agent from langgraph.types import Command # 1. Модель LLM (замените на нужную модель и укажите ключ API) llm = ChatOpenAI( model="gpt-4o-mini", # пример модели, можно заменить temperature=0.7, ) # 2. Простой инструмент @tool def get_weather(city: str, date: str) -> str: """Возвращает погоду в городе на указанную дату.""" return f"Погода в {city} на {date}: солнечно 25°C." # 3. Хранилище памяти для чекпоинтера memory = MemorySaver() # 4. Создание агента с HumanInTheLoopMiddleware agent = create_react_agent( tools=[get_weather], llm=llm, system_prompt="Ты полезный ассистент, отвечай точно.", checkpointer=memory, middleware=[ HumanInTheLoopMiddleware( interrupt_on={"get_weather": True}, # прерывать на каждом вызове description_prefix="Подтвердите вызов инструмента", ), ], ) def run_agent(): """ Запускает агента, обрабатывает прерывания и выводит финальный ответ. """ config = {"configurable": {"thread_id": "session-1"}} # Инициализируем запрос result = agent.invoke( {"messages": [{"role": "human", "content": "Какая погода в Казани сегодня?"}]}, config=config, ) # Обрабатываем прерывания до тех пор, пока они не исчезнут while "__interrupt__" in result: interrupt_payload = result["__interrupt__"][0].value action_requests = interrupt_payload.get("action_requests", []) review_configs = interrupt_payload.get("review_configs", {}) decisions = [] for req in action_requests: name = req.get("name") args = req.get("args", {}) print("\nИнструмент:", name) print("Аргументы:", args) allowed = review_configs.get(name, {}).get( "allowed_decisions", ["approve", "reject"] ) print("Разрешённые решения:", allowed) choice = input("a=approve, r=reject: ").strip().lower() if choice == "r": msg = input("Причина отказа: ") decisions.append({"type": "reject", "message": msg}) else: decisions.append({"type": "approve"}) # Возобновляем выполнение агента result = agent.invoke(Command(resume={"decisions": decisions}), config=config) # Финальный ответ агента final_answer = result["messages"][-1].content print("\nОтвет агента:\n", final_answer) if __name__ == "__main__": run_agent()