add main.py
This commit is contained in:
@@ -0,0 +1,107 @@
|
|||||||
|
"""Самописный поисковый deep agent (deepagents + виртуальная ФС + экспорт)."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent
|
||||||
|
if str(ROOT) not in sys.path:
|
||||||
|
sys.path.insert(0, str(ROOT))
|
||||||
|
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from langchain_core.messages import HumanMessage
|
||||||
|
from langchain_openai import ChatOpenAI
|
||||||
|
|
||||||
|
from deepagents import create_deep_agent
|
||||||
|
from deepagents.backends import LocalShellBackend
|
||||||
|
|
||||||
|
from export_utils import export_virtual_files
|
||||||
|
from research_tools import get_page_content, web_search
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
WORKSPACE_DIR = ROOT / "workspace"
|
||||||
|
OUTPUT_DIR = ROOT / "output"
|
||||||
|
|
||||||
|
OPENROUTER_BASE_URL = os.getenv("OPENROUTER_BASE_URL", "https://openrouter.ai/api/v1")
|
||||||
|
OPENROUTER_MODEL = os.getenv(
|
||||||
|
"OPENROUTER_MODEL",
|
||||||
|
"poolside/laguna-m.1:free",
|
||||||
|
)
|
||||||
|
|
||||||
|
SYSTEM_PROMPT = """\
|
||||||
|
Ты исследовательский deep agent (курс deep agents from scratch).
|
||||||
|
|
||||||
|
Возможности:
|
||||||
|
- web_search и get_page_content — поиск и чтение материалов в интернете
|
||||||
|
- ls, read_file, write_file, edit_file — виртуальная файловая система
|
||||||
|
|
||||||
|
Правила:
|
||||||
|
1. Получив задачу, найди информацию в интернете.
|
||||||
|
2. Сохраняй заметки и выжимки в виртуальные файлы (например /notes/topic.md).
|
||||||
|
3. Структурируй файлы по смыслу (папки notes/, research/).
|
||||||
|
4. В конце кратко сообщи, какие файлы созданы.
|
||||||
|
|
||||||
|
Пиши на русском, если пользователь не просит иначе.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def build_llm() -> ChatOpenAI:
|
||||||
|
return ChatOpenAI(
|
||||||
|
model=OPENROUTER_MODEL,
|
||||||
|
base_url=OPENROUTER_BASE_URL,
|
||||||
|
api_key=os.getenv("OPENAI_API_KEY"),
|
||||||
|
temperature=0.2,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def build_agent():
|
||||||
|
WORKSPACE_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
backend = LocalShellBackend(
|
||||||
|
root_dir=str(WORKSPACE_DIR),
|
||||||
|
virtual_mode=True,
|
||||||
|
inherit_env=True,
|
||||||
|
)
|
||||||
|
return create_deep_agent(
|
||||||
|
model=build_llm(),
|
||||||
|
tools=[web_search, get_page_content],
|
||||||
|
system_prompt=SYSTEM_PROMPT,
|
||||||
|
backend=backend,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def run_research(query: str) -> list[str]:
|
||||||
|
agent = build_agent()
|
||||||
|
print(f"Модель: {OPENROUTER_MODEL}")
|
||||||
|
print(f"Запрос: {query}\n")
|
||||||
|
|
||||||
|
result = await agent.ainvoke(
|
||||||
|
{"messages": [HumanMessage(content=query)]}
|
||||||
|
)
|
||||||
|
last = result["messages"][-1]
|
||||||
|
print("\n--- Ответ агента ---")
|
||||||
|
print(getattr(last, "content", last))
|
||||||
|
|
||||||
|
exported = export_virtual_files(WORKSPACE_DIR, OUTPUT_DIR)
|
||||||
|
print("\n--- Экспорт в output/ ---")
|
||||||
|
if exported:
|
||||||
|
for path in exported:
|
||||||
|
print(f" {path}")
|
||||||
|
else:
|
||||||
|
print(" (файлов для экспорта не найдено)")
|
||||||
|
return exported
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
query = (
|
||||||
|
" ".join(sys.argv[1:])
|
||||||
|
if len(sys.argv) > 1
|
||||||
|
else "Краткий обзор Model Context Protocol (MCP): что это и зачем нужен."
|
||||||
|
)
|
||||||
|
asyncio.run(run_research(query))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user