"""Deep research agent: веб-поиск, виртуальные файлы, экспорт на диск. Основано на курсе deep agents from scratch: https://github.com/langchain-ai/deep-agents-from-scratch/blob/main/notebooks/4_full_agent.ipynb """ from __future__ import annotations import os import sys from pathlib import Path from dotenv import load_dotenv from deepagents import create_deep_agent from deepagents.backends import LocalShellBackend from langchain_openai import ChatOpenAI from export_tools import DEFAULT_OUTPUT_DIR, WORKSPACE_DIR, export_virtual_files, export_workspace_to_disk from web_tools import get_page_content, web_search load_dotenv() SYSTEM_PROMPT = """\ Ты исследовательский deep-агент (стиль deep agents from scratch). Твоя работа: 1. Искать информацию в интернете через web_search и при необходимости get_page_content. 2. Сохранять результаты во ВИРТУАЛЬНЫЕ файлы через write_file (например /research/query.md, /research/summary.md, /research/sources.txt). Не оставляй всё только в чате. 3. Используй write_todos для плана исследования. 4. В КОНЦЕ обязательно вызови export_virtual_files с target_dir="./output", чтобы выгрузить виртуальные файлы в реальную файловую систему. Правила: - Один инструмент за шаг, если возможно. - В файлах — структурированные заметки: запрос, источники, выводы. - Отвечай на русском. """ def build_agent(): WORKSPACE_DIR.mkdir(parents=True, exist_ok=True) backend = LocalShellBackend( root_dir=str(WORKSPACE_DIR.resolve()), virtual_mode=True, inherit_env=True, ) llm = ChatOpenAI( model=os.getenv("OPENAI_MODEL", "openai/gpt-oss-20b:free"), base_url=os.getenv("OPENAI_BASE_URL", "https://openrouter.ai/api/v1"), api_key=os.getenv("OPENAI_API_KEY", "fake"), temperature=0.2, ) return create_deep_agent( model=llm, tools=[web_search, get_page_content, export_virtual_files], system_prompt=SYSTEM_PROMPT, backend=backend, ) def run_research(query: str) -> None: agent = build_agent() print(f"Запрос: {query}\n") print("Агент работает (поиск → виртуальные файлы → экспорт)...\n") result = agent.invoke( { "messages": [ { "role": "human", "content": ( f"Исследуй тему: {query}. " "Сохрани заметки в виртуальные файлы и в конце выгрузи их через export_virtual_files." ), } ] } ) last = result["messages"][-1] print("\n--- Ответ агента ---") print(getattr(last, "content", last)) # Гарантированный экспорт, даже если агент не вызвал инструмент exported = export_workspace_to_disk(output_dir=DEFAULT_OUTPUT_DIR) print(f"\n--- Файлы на диске ({DEFAULT_OUTPUT_DIR}) ---") if exported: for path in exported: print(f" {path}") else: print(" (пусто — агент не создал файлов в agent_workspace)") def main() -> None: query = " ".join(sys.argv[1:]).strip() or "LangGraph deep agents и context engineering" run_research(query) if __name__ == "__main__": main()