import os import asyncio from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage from langchain.tools import tool from deepagents import create_deep_agent from deepagents.backends import FilesystemBackend, LocalShellBackend, CompositeBackend from pydantic import BaseModel, Field from langchain_core.output_parsers import PydanticOutputParser # Настройка LLM через OpenRouter llm = ChatOpenAI( model="openai/gpt-oss-20b:free", base_url="https://openrouter.ai/api/v1", api_key=os.getenv("OPENAI_API_KEY"), temperature=0.0, ) # Бэкенд для хранения файлов и выполнения команд backend = CompositeBackend( [ LocalShellBackend(workspace_dir="./workspace"), FilesystemBackend(), ] ) # Инструмент для проверки корректности вывода @tool def validate_output(output: str) -> str: """Проверяет, что вывод содержит все необходимые поля.""" issues = [] if "goal:" not in output.lower(): issues.append("Missing goal") if "timeline:" not in output.lower(): issues.append("Missing timeline") if "resources:" not in output.lower(): issues.append("Missing resources") if "milestones:" not in output.lower(): issues.append("Missing milestones") if "evaluation:" not in output.lower(): issues.append("Missing evaluation") return "OK" if not issues else f"Issues: {', '.join(issues)}" # Модель структуры плана class PlanOutput(BaseModel): goal: str = Field(description="Краткое описание цели обучения") timeline: str = Field(description="План по времени (месяцы/недели)") resources: list[str] = Field(description="Список ресурсов и курсов") milestones: list[str] = Field(description="Ключевые контрольные точки") evaluation: str = Field(description="Методы оценки прогресса") parser = PydanticOutputParser(pydantic_object=PlanOutput) # Создание агента agent = create_deep_agent( model=llm, tools=[validate_output], backend=backend, system_prompt=( "You are a helpful agent that creates a structured AI fluency plan. " "Return the plan in a format that matches the PlanOutput schema. " "After generating the plan, use the validate_output tool to ensure all fields are present." ), ) async def main(): # Запрос к агенту result = await agent.ainvoke( {"messages": [HumanMessage(content="Build a personal AI fluency plan for me.")]}, {"configurable": {"thread_id": "ai-fluency-plan"}}, ) # Получаем последний вывод агента plan_text = result["messages"][-1].content # Парсим в структуру try: plan = parser.parse(plan_text) except Exception as e: print("Failed to parse plan:", e) print("Raw output:", plan_text) return # Выводим план print("\nPersonal AI Fluency Plan") print("------------------------") print(f"Goal: {plan.goal}\n") print(f"Timeline:\n{plan.timeline}\n") print("Resources:") for r in plan.resources: print(f"- {r}") print("\nMilestones:") for m in plan.milestones: print(f"- {m}") print(f"\nEvaluation:\n{plan.evaluation}") if __name__ == "__main__": asyncio.run(main())