Добавлен solution.py

This commit is contained in:
2026-05-28 11:18:04 +00:00
parent 21011e573d
commit 5b37357f65
+115
View File
@@ -0,0 +1,115 @@
# solution.py
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langchain.tools import tool
from langchain_ollama import ChatOllama
from langgraph.checkpoint.memory import MemorySaver
from langgraph.types import Command
from rich import print as rprint
# ------------------------------------------------------------------
# 1. Определяем инструмент get_weather
# ------------------------------------------------------------------
@tool("get_weather")
def get_weather(city: str, date: str) -> str:
"""
Возвращает погоду в указанном городе и дате.
Для демонстрации возвращаем фиктивный ответ.
"""
return f"Погода в {city} на {date}: солнечно, 25°C."
# ------------------------------------------------------------------
# 2. Создаём LLM (Ollama) и агент с HumanInTheLoopMiddleware
# ------------------------------------------------------------------
llm = ChatOllama(model="llama3") # используем Ollama
memory = MemorySaver() # память для сохранения пауз
agent = create_agent(
model=llm,
tools=[get_weather],
system_prompt="Ты полезный ассистент, помогающий пользователю.",
middleware=[
HumanInTheLoopMiddleware(
interrupt_on={
"get_weather": True # все решения: approve, edit, reject
},
description_prefix="Подтвердите вызов инструмента",
),
],
checkpointer=memory,
)
# ------------------------------------------------------------------
# 3. Функция для запроса решений у пользователя
# ------------------------------------------------------------------
def ask_decisions(action_requests):
"""
action_requests – список словарей с полями name, args и опционально description.
Возвращает список решений в том же порядке: approve/reject.
"""
decisions = []
for idx, act in enumerate(action_requests, start=1):
rprint(f"\n--- Подтверждение #{idx} ---")
rprint(f"[bold]Инструмент:[/bold] {act['name']}")
rprint(f"[bold]Аргументы:[/bold] {act['args']}")
if "description" in act:
rprint(f"[bold]Описание:[/bold] {act['description']}")
while True:
choice = input("a = approve, r = reject: ").strip().lower()
if choice == "a":
decisions.append({"type": "approve"})
break
elif choice == "r":
msg = input("Сообщение для агента (причина отказа): ")
decisions.append({"type": "reject", "message": msg})
break
else:
rprint("[red]Неверный ввод. Пожалуйста, введите 'a' или 'r'.[/red]")
return decisions
# ------------------------------------------------------------------
# 4. Основной цикл взаимодействия с агентом
# ------------------------------------------------------------------
def main():
thread_id = "сессия-1"
config = {"configurable": {"thread_id": thread_id}}
while True:
user_msg = input("\nВы: ")
if not user_msg.strip():
continue
# первый вызов агента
result = agent.invoke(
{"messages": [{"role": "human", "content": user_msg}]},
config=config,
)
# цикл обработки пауз
while "__interrupt__" in result:
interrupt_value = result["__interrupt__"][0].value
action_requests = interrupt_value.get("action_requests", [])
if not action_requests:
rprint("[yellow]Пауза без действий. Продолжаем...[/yellow]")
break
decisions = ask_decisions(action_requests)
# возобновляем выполнение
result = agent.invoke(
Command(resume={"decisions": decisions}),
config=config,
)
# вывод финального ответа агента
if "messages" in result and result["messages"]:
last_msg = result["messages"][-1]
rprint(f"\n[bold]Агент:[/bold] {last_msg['content']}")
else:
rprint("[red]Ответ не получен.[/red]")
if __name__ == "__main__":
main()