数据截至 (上游 commit f72f75d8c3eb)
Tongyi DeepResearch — 架构与原理
30 秒导读: Tongyi DeepResearch 是阿里通义实验室开源的「深度研究」智能体。核心是一个 300 亿参数(每 token 只激活 33 亿)的模型 + 一段 ReAct 循环:模型一边想、一边调用「网页搜索 / 读网页 / 学术搜索 / Python 沙箱 / 文件解析」这几样工具,把结果读回上下文,循环几十轮,最后吐出一段
<answer>。这份文档解剖的是仓库里真正能跑的推理代码(inference/),不是模型权重也不是训练。
1. 这是什么(零基础也能懂)
-
一句话定义: 一个会自己上网查资料、读网页、算数,然后写出带引证的研究报告的 AI 智能体。
-
解决什么问题 / 给谁用: 假设你问一个需要「查好几个网站、交叉验证、还得算一下」才能答的刁钻问题(例:某冷门赛事第 3 名选手母校的现任校长是谁)。普通聊天模型只能凭记忆瞎猜;Tongyi DeepResearch 会像人一样反复搜索、点 开网页、提炼、再搜,直到凑齐证据。它面向做深度信息检索、评测 agentic 能力的研究者和开发者。
-
它能做什么(功能):
- 批量 Google 网页搜索、Google Scholar 学术搜索
- 访问网页并自动摘要成「证据 + 总结」
- 在沙箱里跑 Python(算数、数据处理)
- 解析本地上传的 PDF / DOCX / 音视频等文件
- 长程多轮推理(默认最多 100 轮 LLM 调用,单题上限 2.5 小时)
-
用起来什么样: 准备一个
.jsonl,每行一条问题,然后:# 1) 配好 API key(Serper 搜索、Jina 读网页、沙箱端点……)cp .env.example .env && vim .env# 2) 一键起 vLLM 服务 + 跑推理bash inference/run_react_infer.sh脚本会用 vLLM 把模型托起来(见
inference/run_react_infer.sh:30-37),再让run_multi_react.py并发地把每道题喂给 agent 循环。 -
一句话直觉 / 类比: 把它想成一个只会用便利贴记事的实习研究员——每一轮它先在便利贴上写下「我在想什么、要查什么」,派人去查(工具),把查来的结果贴回笔记本(上下文),再看着整叠笔记想下一步。笔记本(上下文窗口)贴满了(超 110K token)就必须马上下结论交差。
2. 顶层全景(它大概怎么转)
整个系统分三层:起服务 → 跑 agent 循环 → 评分。核心价值在中间那层的 ReAct 循环。
怎么读这张图: 从上到下是一次推理任务的生命周期;中间虚线框内是每道题都要转很多圈的主循环。
┌───────────────────────────────────────────────┐
│ run_react_infer.sh:起 8 个 vLLM 服务(6001-6008)│
└───────────────────────┬───────────────────────┘
│
┌────────────────────────▼──────────────────────┐
│ run_multi_react.py:读数据集、按题分派端口、 │
│ 线程池并发、每题跑 roll_out_count 次(默认 3) │
└────────────────────────┬──────────────────────┘
│ 每个 (题, rollout) 一个任务
┌────────────────────────▼──────────────────────┐
│ MultiTurnReactAgent._run │
│ ┌ ─ ─ ─ ─ ─ ─ ─ 主循环(每题几十轮) ─ ─ ─ ─ ┐ │
│ ① call_server → 模型输出「思考+工具调用」 │
│ ② 解析 <tool_call> → 派发给某个工具 │
│ ③ 工具结果包成 <tool_response> 塞回上下文 │
│ ④ 出现 <answer> 或超时/超长 → 收尾 │
│ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │
└────────────────────────┬──────────────────────┘
│ 每轮结果写成 iterN.jsonl
┌────────────────────────▼──────────────────────┐
│ evaluate_deepsearch_official.py: │
│ LLM-as-judge 判对错 → 算 Pass@1 / Pass@3 │
└────────────────── ─────────────────────────────┘
部件一句话职责:
| 部件 | 干什么 | 在哪个文件 |
|---|---|---|
run_react_infer.sh | 拉起 8 个 vLLM 推理服务,再启动推理脚本 | inference/run_react_infer.sh |
run_multi_react.py | 读数据、分片、按题粘性分配端口、线程池并发跑 | inference/run_multi_react.py |
MultiTurnReactAgent | ReAct 主循环本体:调模型、派工具、管上下文 | inference/react_agent.py |
SYSTEM_PROMPT | 告诉模型自己是谁、有哪些工具、输出格式 | inference/prompt.py |
Search / Scholar | 调 Serper 打 Google / Google Scholar | inference/tool_search.py、tool_scholar.py |
Visit | 用 Jina 抓网页 + LLM 摘要成证据 | inference/tool_visit.py |
PythonInterpreter | 把代码丢进 SandboxFusion 沙箱执行 | inference/tool_python.py |
FileParser | 解析本地文件 / 音视频 | inference/tool_file.py |
evaluate_* | LLM-as-judge 打分 + Pass@k 统计 | evaluation/ |
主线走一遍(高层,不进代码):
- 一道题进来,拼上
SYSTEM_PROMPT(含工具清单 + 当天日期)作为对话开头。 - 模型回一段:先
<think>…</think>想,再要么<tool_call>…</tool_call>调工具,要么直 接<answer>…</answer>交卷。 - 若是工具调用 → 派发执行 → 结果包成
<tool_response>追加到对话,回到第 2 步。 - 直到模型给出
<answer>,或触发三种「刹车」(轮数用完 / 超 2.5 小时 / 上下文超 110K token)。 - 每道题独立跑 3 次(rollout),每次结果落一个
iterN.jsonl;评测脚本再用一个「裁判模型」逐条判对错,算出 Pass@1 / Pass@3。
3. 阅读地图(建议顺序)
先读 §1、§2 建立全景,再按下面顺序下钻:
- 01-react-loop.md — 先读这个。主循环是整个项目的心脏:一次「思考→工具→观察」怎么滚成多轮,
<tool_call>/<answer>怎么被解析,三种刹车怎么触发。 - 02-tools.md — 五个工具各自怎么实现、Python 工具为什么走「JSON +
<code>双段」这条特殊路径、工具派发的custom_call_tool有哪些坑。 - 03-context-and-robustness.md — 128K 上下文怎么算、怎么在超限前一步「强制收尾」、各层重试/降级/容错的设计。
- 04-evaluation.md — 多次 rollout + LLM-as-judge + Pass@k 的评测闭 环,以及它对不同数据集换不同裁判模型的做法。
一个诚实的前置说明: README 宣传两种推理范式——ReAct 和 Heavy(基于 IterResearch 的测试时扩展)。但仓库
FAQ.md明确写道 Heavy Mode 尚未完全开源("The Heavy Mode is not fully open-sourced yet")。所以这套文档只讲真实存在于inference/的 ReAct 实现;凡涉及 Heavy 的部分,以「代码里没有」如实标注,不臆测。