
Deep Research — 多 Agent 协作深度研究系统概述一个纯手搓的多 Agent 研究系统。用户输入一个研究问题系统自动从 4 个认知维度并行搜索、Agent 间对抗辩论验证声明可信度、最终综合输出带置信度标注的中文研究报告。零编排框架依赖——Agent 循环、消息管理、工具调用、上下文压缩、并行编排全部自研约 2100 行 Python。架构全景用户输入 → main.py (CLI 日志) │ ▼ pipeline.py (三阶段流水线) │ ├── Phase 1: Orchestrator → 4 研究员并行搜索 (Fan-out) │ 产出: 4 张 ResearchCard (每张含 5-10 条 Claim) │ ├── Phase 2: Verifier → Refuter → Verifier rebuttal (Pipeline) │ 产出: 4 张 VerifiedCard (每条 Claim 标记 verified/suspect/false/disputed) │ └── Phase 3: Scorer Extractor (Barrier) → Editor 产出: report.md evidence.json audit.jsonl核心模块1. Agent 层 (core/agent.py)每个 Agent 是一个完整的 LLM 自主循环┌──────────────────────────────────────────┐ │ Agent.run(task) │ │ │ │ 1. 追加 task 到 mutable_messages │ │ 2. 检查是否需要压缩 (compressor) │ │ 3. 组装上下文: system blackboard msg │ │ 4. 调用 LLM (litellm.acompletion) │ │ 5. 有 tool_calls? → 执行工具 → 回到 2 │ │ 6. 无 tool_calls → 返回 content │ │ │ │ 最多 20 轮工具调用防止无限循环 │ └──────────────────────────────────────────┘关键设计决策mutable_messages[]是 Agent 的私有对话历史完全透明可观测。每次run()重置为空Agent 之间无隐式状态泄漏。_call_llm()不做任何后处理——原样返回{content, tool_calls}字典调用方决定如何处理。Blackboard 上下文在每次 LLM 调用时动态注入为 system 消息不是静态拼接。2. 工具层 (core/tool.py)每个工具继承BuildTool遵循四阶段流水线validate_input() → 类型检查、默认值填充、参数校验 │ check_permissions() → 安全门禁 (URL 白名单、路径沙箱) │ execute() → 干活 (API 调用、文件读取、数据库查询) │ format_result() → 转成 LLM 能消费的文本classFirecrawlSearchTool(BuildTool):namefirecrawl_searchdescription搜索网络...parameters{# JSON Schema直接用作 OpenAI function callingtype:object,properties:{query:{type:string},limit:{type:integer},},required:[query],}asyncdefexecute(self,args):# 同步 API 调用用 asyncio.to_thread 包装returnawaitasyncio.to_thread(lambda:Firecrawl(api_key...).search(...))defformat_result(self,raw):# Firecrawl 返回对象 → 文本列表return\n.join(f{r.title}\n{r.url}\n{r.description}forrinraw.data)当前工具集工具基类类型说明firecrawl_searchBuildTool搜索Firecrawl API 全网搜索tavily_searchBuildTool搜索Tavily API 结构化搜索web_fetchBuildTool读取HTTP GET HTML→textsqlite_readBuildTool数据库读取 Run 的所有研究数据工具按 API key 可用性动态加载get_search_tools()检查FIRECRAWL_API_KEY和TAVILY_API_KEY返回实际可用的工具列表。3. Blackboard (core/blackboard.py)Agent 间通过 Blackboard 交换数据不通过函数参数传递Phase 1 完成: blackboard.write(run:42:cards, [ResearchCard × 4]) Phase 2 Verifier: cards blackboard.read(run:42:cards) ← 直接从黑板上拿 Phase 3 Scorer: cards blackboard.read(run:42:cards) verified blackboard.read(run:42:verified)Blackboard 是非侵入式的——Agent 的_call_llm()在每次调用前自动从 Blackboard 提取相关上下文注入 system 消息。Agent 本身不感知 Blackboard 的存在。4. 压缩层 (core/compressor.py)当 Agent 的mutable_messages超过 30 条时滑动窗口 LLM 摘要旧消息 [0..N-20] → LLM 生成摘要 → [summary]: 已搜索了 X、Y、Z主要发现... 最近消息 [N-20..N] → 保留原文压缩用独立的 LLM 调用DeepSeek Chatmax_tokens800失败时优雅降级为(summary unavailable)。5. 文件去重 (core/file_cache.py)两个研究员访问同一个 URL 时不重复请求cacheFileCache(ttl_seconds300)# 5 分钟过期contentcache.get_or_fetch(https://arxiv.org/paper.pdf,fetcherhttpx.get)6. 编排器 (core/orchestrator.py)三个组合原语全部基于标准库asyncio# 并行 — 一个失败不影响其他resultsawaitparallel(task_a(),task_b(),task_c())# 串行流水线 — 前一个的输出是后一个的输入finalawaitpipeline(initial,stage1,stage2,stage3)# 屏障 — 语义别名awaitbarrier(score(),extract())# 等价于 parallel10 个 Agent 配置所有 Agent 配置集中在agents/registry.py声明式定义industry:{role:行业全景研究员,goal:绘制竞争格局、采用模式和真实世界使用情况。...,backstory:你是一位追踪技术采用曲线的行业分析师。...,tools:[*get_search_tools(),WebFetchTool()],llm:deepseek,}create_agent(**config)工厂函数负责组装Agent实例——注入 LLM 配置、Blackboard、FileCache。全线使用 DeepSeek Chat。#Agent工具职责1Orchestrator无拆解问题 → 4 份 Research Brief2-54×Researcher搜索 WebFetch多视角并行搜索产出 Claim 列表6VerifierWebFetch SQLite逐条核查来源真实性7Refuter搜索主动搜索反面证据、逻辑漏洞8ScorerSQLite三维度 (来源/一致性/覆盖) 评分9ExtractorSQLite提炼共识、矛盾、盲区、时效性10EditorSQLite撰写 5 段式中文报告Phase 1 详细流程Fan-out 并行研究Orchestrator.run(task) │ 把 X 拆成 4 个视角输出 JSON │ → {technical: {sub_q, keywords, sources}, industry: {...}, ...} │ ├─ Researcher[technical].run(技术深度视角...) ──┐ ├─ Researcher[industry].run(行业全景视角...) ──┤ ├─ Researcher[critical].run(批判质疑视角...) ──┤ parallel() └─ Researcher[future].run(未来趋势视角...) ──┘ │ 每个 Researcher 内部循环: LLM → tool_calls(firecrawl_search) → 执行 → 结果追加 LLM → tool_calls(web_fetch) → 执行 → 结果追加 LLM → tool_calls(firecrawl_search) → 执行 → 结果追加 LLM → content(JSON ResearchCard) → 返回 parse_json_response() → safe_construct_list(Claim) → ResearchCard 重试: 如果输出是 ReAct 文本格式 → 纠正提示 → 重试 (最多 2 次)Phase 2 详细流程对抗验证每个 ResearchCard 独立进入 3 轮辩论流水线Pipeline 模式4 张卡并行ResearchCard │ ├─ Round 1: Verifier │ 逐条核查URL 可访问来源支持声明置信度合理 │ → entries: [{claim_index, status: verified|suspect|false, reasoning}] │ → 全部 verified? → ✅ 提前结束跳过 Round 2/3 │ ├─ Round 2: Refuter (仅在 Round 1 有可疑时触发) │ 刻意攻击搜反面证据、找逻辑漏洞、抓过度泛化 │ → refutations: [{claim_index, challenge, severity, counter_evidence}] │ → 无反驳? → ✅ 提前结束 │ └─ Round 3: Verifier rebuttal (仅在 Round 2 有反驳时触发) 回应每项质疑ACCEPT/REJECT/DISPUTED → final entries resolved: true/false早期退出机制如果 Round 1 全部 verified跳过后续轮次如果 Round 2 无反驳同样提前结束。只有真正有争议的声明才走完三轮。Phase 3 详细流程综合输出┌─ Scorer.run(task) ──→ ScoreResult ──┐ barrier()─┤ ├─→ Editor → report.md └─ Extractor.run(task) ──→ InsightResult ┘ └─→ evidence.json └─→ audit.jsonlScorer 和 Extractor 并行执行Barrier都完成后 Editor 收到两者的产物开始撰写报告。如果 Editor 输出为空自动降级为结构化数据生成的 fallback 报告。数据流总览Phase 1 Phase 2 Phase 3 ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │Orchestrat│───→│Researcher│───→│ Verifier │───→│ Scorer │──┐ │ 拆解 │ │ ×4 并行 │ │ 核查 │ │ 评分 │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ ├─→ Editor ─→ report.md ▼ ▼ ▼ │ ResearchCard VerifiedCard ScoreResult │ ×4 (Blackboard) ×4 (Blackboard) (Blackboard) │ │ ┌──────────┐ │ │Extractor │───────┘ │ 提炼 │ └──────────┘ InsightResult (Blackboard)关键技术栈层技术说明LLM 调用litellm统一的 completion 接口支持任何 OpenAI-compatible 端点数据模型Pydantic v2Claim / ResearchCard / VerifiedCard / ScoreResult / InsightResult状态存储SQLite WAL6 表写操作带锁重试 (5 次0.5s 退避)JSON 解析response_parser.py4 策略管线直接解析 → fence 提取 → 正则提取 → JSON 修复安全构建safe_construct.pyPydantic 逐字段构建单字段异常不丢整卡搜索Firecrawl Tavily按 API key 可用性动态加载消息压缩Compressor滑动窗口 (保留 20 条) LLM 摘要文件缓存FileCacheURL 级去重TTL 300s并行编排asyncio.gatherreturn_exceptionsTrue单 Agent 崩溃不连累其他日志logging双通道 (file DEBUG console INFO)第三方库静音运行cddeep-researchcp.env.example .env# 填入 DEEPSEEK_API_KEY, FIRECRAWL_API_KEY, QWEN_*pipinstall-e.deep-research你的研究问题产出在runs/{run_id}/report.md— 5 段式中文研究报告evidence.json— 完整结构化证据audit.jsonl— 逐事件审计追踪 (可回放)项目地址本项目已开源在 GitHub 上欢迎 Star、Fork 和贡献GitHub 仓库: https://github.com/bai1535/deep-research