Imported from zkforge/DeepResearchAgent (
AGENTS.md). Install upstream withnpx skills add zkforge/DeepResearchAgent. Copyright stays with the author.
本文件为后续 Codex/agent 会话记录此仓库中不易从代码直接推断的约束。
Commands
- 安装依赖:
uv sync --dev - 静态检查:
uv run ruff check . - 全量测试:
uv run pytest - 聚焦测试示例:
uv run pytest tests/test_tools_budget.py::test_search_budget_stops_after_limit - CLI 单题:
uv run deepresearch "法国的首都是哪里?";调试工具循环加--verbose - FastAPI:
uv run uvicorn deepresearch.api:app --host 0.0.0.0 --port 8000 - 批量运行:
uv run python -m deepresearch.batch --input data/question.jsonl --output data/runs/agent_v1.jsonl --resume --skip-id 16 - 并发批量运行示例:追加
--concurrency 4,同时产出agent_v1.metrics.jsonl - 评分候选答案:
uv run python -m deepresearch.evaluate score --candidate data/runs/agent_v1.jsonl --answer data/answer.jsonl - Metrics 报表:
uv run python -m deepresearch.evaluate report --metrics data/runs/agent_v1.metrics.jsonl - 错题明细导出:
score加--error-details data/runs/agent_v1.errors.jsonl
Architecture
- 包源码在
src/deepresearch/,通过pyproject.toml的deepresearch = "deepresearch.cli:main"暴露 CLI。 config.py从.env加载不可变Settings;真实运行默认要求OPENAI_API_KEY。SERPAPI_API_KEY、SERPER_API_KEYS、IQS_API_KEY、JINA_API_KEYS是可选增强源,缺失付费搜索源时默认使用 DuckDuckGo 免费搜索兜底。可用RESEARCH_MODEL、SUMMARY_MODEL、FINALIZER_MODEL分别配置三个角色的模型,STRUCTURED_JSON_OUTPUT控制 summary/finalizer 是否走 JSON mode。agent.py用 LangChaincreate_agent和 LangGraph 执行 ReAct;每题共享SearchBudget,搜索耗尽、递归上限、上下文过大或总超时都会转入 finalizer,最终仍应返回纯文本答案。ResearchAgent实例缓存 research/summary/finalizer 三个 ChatOpenAI,避免每步重建。tools.py提供search与visit两个 Agent 工具;search会按语言和已配置 key 在 IQS、SerpApi、Serper、DuckDuckGo 间 fallback,visit优先 Jina Reader,失败后直接httpx + BeautifulSoup抓取。api.py暴露POST /answer、SSEPOST /stream和GET /healthz;ResearchAgent被lru_cache保持为进程级单例。metrics.py提供单题MetricsRecorder,通过 contextvar 在 agent/工具中采集 token、provider 命中、访问成功率等信号;batch.py在答案 JSONL 旁写.metrics.jsonl。batch.py顺序或并发处理 JSONL 并保证单题失败不影响后续题;evaluate.py不仅做准确率对比,还会归纳错因类别和输出 metrics 汇总,仅用于离线。
Workflow Notes
- 这是赛题 Agent 工程:禁止微调、禁止第三方 Agent API、禁止硬编码评测题答案;只允许百炼 Qwen 模型和不含 Agent 能力的搜索/访问工具。
data/question.jsonl只包含题目输入;Agent、工具、批量运行只能读取id与question。data/answer.jsonl是真实答案文件,只允许离线评估读取,不得注入 prompt、检索词或生产代码逻辑。- 保留并扩展
tools.py的泄露防护:不要搜索整题原句,不要访问题解、竞赛心得、question.jsonl、validation.jsonl、reference_answers.jsonl、answer.jsonl、answers.jsonl、submit_results.jsonl等答案泄露来源。 - 最终答案必须是可精确匹配的短纯文本;
output.py的模型输出清理和evaluate.py的评分归一化是两个边界,不要为了评分方便把评估归一化规则混入生产答案清理。 - 工具输出必须受
VISIT_CHAR_LIMIT、MAX_TOOL_RESULT_CHARS、MAX_CONTEXT_TOKENS等配置约束;新增工具或 provider 时保持失败返回可读文本,而不是让单题异常中断批处理。 docs/赛题.md记录了两个特殊样例:测试题 16 因百炼风控作废,批量基线通常跳过;题 93 的 Irina Kirilenko 应按 Irina Kotkina 理解。
