第 2 章 · 角色的诞生

一句话结论:拆分 agent 的边界,不是「步骤」,而是「职责」。好的角色划分,让每个 agent 拥有「恰好够用的一套工具 + 恰好内聚的一份上下文」,既能独立工作,又不至于让协调成本吃掉收益。


1. 先问对问题:拆成几个?按什么拆?

第 1 章我们得出「要拆」,但没解决「按什么拆」。这有两层:

  1. 按步骤拆:搜 → 读 → 算 → 写,每个步骤一个 agent。
  2. 按职责拆:规划师 / 研究员 / 程序员 / 报告员,每类职责一个 agent。

DeerFlow 1.x 选了后者,而且给出了一个非常干净的角色表:

角色职责(一句话)只配给它的工具
Coordinator(协调器)入口:接请求、判断这是不是研究任务、决定要不要往下走路由逻辑,几乎无工具
Planner(规划师)把研究问题拆成一份结构化、多步骤的计划只有「产出计划」的模型能力
Researcher(研究员)搜索、抓取、读网页、查知识库搜索引擎、爬虫、MCP 检索工具
Coder(程序员)跑 Python 做数据分析、算数、画图Python REPL
Reporter(报告员)把一堆半成品汇总成带引用的最终报告只有「成稿」的模型能力

2. 思考的分叉:为什么「按职责」而不是「按步骤」?

方向 A:按步骤拆(搜-读-算-写各一个 agent)。

  • 看似更细,实则每个 agent 的职责太薄。一次深度研究里,「搜」和「读」往往是缠在一起反复发生的——搜到一篇,读一读,发现线索,再搜。硬拆成「搜 agent」「读 agent」,等于把一个自然的「搜-读」循环切成两段,协调成本暴涨。

方向 B:按职责拆(Planner/Researcher/Coder/Reporter)。

  • 每个角色内聚了一类会反复发生、且工具集相同的工作。Researcher 自己内部可以「搜→读→再搜」,因为它拥有这一整类任务需要的所有工具。

为什么选 B:

  • 核心判断标准是——「这个角色内部,是否拥有完成它那类工作的完整工具集?」 如果两个 agent 经常需要互相来回调用对方的工具,说明它们本就不该分开。
  • 按职责拆,还带来了一个隐性收益:工具集的最小权限(least privilege)。Researcher 拿不到 Python REPL,Coder 拿不到搜索引擎。这样每个 agent 的上下文里只有「它该关心的工具」,既省 token,又降低了「一个角色乱用工具搞坏全局」的风险。

类比:你开一家公司,是按「工序」拆(一个人只负责盖章、一个人只负责装订),还是按「岗位」拆(市场部、技术部、编辑部)?工序拆法适合流水线,但研究这种「充满回环和分支」的工作,岗位拆法才灵活。agent 角色划分,本质是组织设计问题,不是流水线切分问题。


3. 伪代码:角色的定义与工具绑定

# 角色的本质 = 一个 system prompt + 一个「工具白名单」
RESEARCHER = AgentRole(
    name="researcher",
    tools=[web_search, crawl, rag_retrieve],   # 只有检索类工具
    system_prompt="你是研究员,负责搜索、抓取、提炼信息,只输出结构化的事实与来源。"
)
 
CODER = AgentRole(
    name="coder",
    tools=[python_repl],                        # 只有代码执行
    system_prompt="你是程序员,负责写并运行 Python 做计算与画图,只输出代码运行结果。"
)
 
REPORTER = AgentRole(
    name="reporter",
    tools=[],                                    # 无工具,纯整合
    system_prompt="你是报告员,把研究团队的结论整合成带引用的最终报告。"
)

注意两点:

  1. tools 是白名单,不是「能给你什么」而是「只给你什么」。这行代码背后是一条安全/成本原则:一个角色不该碰它职责之外的工具。
  2. Reporter 的 tools=[] 很有意味——它不需要搜、不需要算,它只做「整合」。把工具清零,既省上下文,也强制它专注在「汇总」这一件事上。

4. 角色之间的「权力结构」

光有角色还不行,得定谁听谁的。DeerFlow 1.x 用的是层级式(hierarchical):

Coordinator(入口,只做路由)
    └── Planner(出计划)
            └── Research Team(Supervisor 派活给 Researcher/Coder)
                    ├── Researcher × N
                    └── Coder × N
                            └── Reporter(收尾,汇总成稿)

这是一个有向的、层级清晰的结构,不是一群 agent 平起平坐地聊天。为什么不用平级?这是第 5 章「调度循环」的核心议题,先在这里埋个钩子:平级聊天(如 AutoGen 群聊、CrewAI 自由协作)最大的问题是「没人对结果负责,也没有明确的收敛条件」——任务会聊着聊着发散掉。


思考题

Q:为什么 Planner 和 Reporter 都没有工具,却还是要拆成两个独立角色,而不是让同一个 agent「先规划、后成稿」?

参考答案:

因为规划与成稿发生在任务的两个阶段,需要「两种不同的上下文状态」。

  • Planner 面对的输入是「一句模糊的研究问题」,输出是「一份结构化计划」。它需要的是发散 + 结构化的能力。
  • Reporter 面对的输入是「研究团队攒下来的一大堆半成品结论」,输出是「一份成型报告」。它需要的是收敛 + 取舍的能力。

如果硬塞给同一个 agent,它会在「规划时」就被塞进大量成稿格式要求、在「成稿时」又残留规划期的中间态,上下文被两段任务互相污染。拆开,本质是让两段不同的「认知任务」各自拥有干净的上下文。 这和第 1 章的结论一脉相承:拆分永远是为「上下文聚焦」服务的。

顺带一个更深的追问:那为什么 Planner 出完计划,不直接把计划交给 Reporter,中间非要再插一个 Research Team?——因为「计划」和「最终报告」之间,隔着「大量不确定的执行工作」,这段工作无法被规划师或报告员任何一方单独承担。这个「中间地带」,正是下一章 Plan 契约要承载的东西。