commit c71eeeddb2c221d115027441d2e33c81e963ed94 Author: Даниил Викторов Date: Thu Jul 2 08:34:35 2026 +0000 add: main.py — ai-fluency diff --git a/main.py b/main.py new file mode 100644 index 0000000..cc7c002 --- /dev/null +++ b/main.py @@ -0,0 +1,95 @@ +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()) \ No newline at end of file