← 返回主线
02

第 02 站 · 已发布

lead-agent 工厂

架构 risk ●●●○○
源码锚点 · @0fb18e3

上一章里,用户输入已经被 Gateway 登记成一次 run。现在它进入 make_lead_agent():这一章看 DeerFlow 如何把「运行时选项 + 应用配置」装配成一张可运行的 LangGraph agent 图。

先记住一件事,后面所有细节都围绕它展开:这里是装配线,不负责思考。 真正的推理发生在模型、工具和中间件的交互里;这个函数只负责把零件按规矩装好,然后把图交出去。它装完就退场,连图都不亲自执行。

flowchart TD
FE["前端 / API"] --> GW["DeerFlow Gateway · run_agent()"]
GW --> MK["make_lead_agent(config)"]
MK -->|"兼容适配:解析 AppConfig"| RC["_get_runtime_config(config)"]
RC --> MLA["_make_lead_agent(config, app_config=...)"]
MLA --> CA["create_agent(model, tools, middleware, prompt, ThreadState)"]
CA --> G["编译出的 LangGraph agent 图"]
一次 run 怎么走到一张编译好的 agent 图

一个函数,两个名字

打开 agent.py ,你会看到一对长得很像的函数:make_lead_agent()_make_lead_agent()。那个下划线不是装饰,它划出了整篇最重要的一条边界。

make_lead_agent(config) 只收一个参数,因为 LangGraph Server 要求图工厂必须能「只凭一个 config」被调起(见 langgraph.json )。它干的活很轻:解析出 AppConfig(优先用运行时注入的,回退到 get_app_config()),然后把活转交给下划线版本。它是兼容适配器

_make_lead_agent(config, *, app_config) 才是真正的装配函数。那个 *app_config 设成只能按关键字传——因为两个参数语义上都像 config,位置传参太容易搞混。它做的是确定性的事:从运行时选项 + 应用配置,一步步把图组装出来。

运行选项是怎么拼出来的

_get_runtime_config()config["configurable"]config["context"] 合并。注意这不是数学并集,而是有顺序的:先铺 configurable,再让 context 覆盖同名键。

它读出的核心字段是每次 run 的选项,不是全局应用设置:

model_name / model
thinking_enabled
reasoning_effort
is_plan_mode
subagent_enabled
max_concurrent_subagents
is_bootstrap
agent_name

模型怎么选

模型解析有明确的优先级:

请求里的 model_name
  > 自定义 agent 配置里的模型
  > AppConfig.models[0]

如果 thinking_enabled=True,但选中的模型并不支持 thinking,工厂会记一条 warning,然后把 thinking_enabled 关掉。想开启 thinking mode,也得看模型支不支持。

最终配方

所有零件就位后,最终调用会收束成这样:

create_agent(
    model=create_chat_model(...),
    tools=filtered_tools,
    middleware=build_middlewares(...),
    system_prompt=apply_prompt_template(...),
    state_schema=ThreadState,
)

心智模型一句话:

Lead Agent 图 = 模型 + 工具 + 中间件 + system_prompt + ThreadState

create_agent() 提供标准的「模型 ↔ 工具」循环;DeerFlow 在这里负责备齐材料(模型、工具)和运行约束(中间件、prompt、状态结构)。

干净装配 · _make_lead_agent

  • 显式接收 AppConfig
  • 从运行时选项确定性组装
  • 更容易测试、推理

兼容代价 · make_lead_agent

  • 单参 ABI(LangGraph Server 要求)
  • app_config 走 runtime config + 全局回退
  • cfg 命名重载、config 被就地改写

会绊倒你的地方


装配线看完了。它最大的好处,恰恰是无聊——行为确定、可预测、不自作主张。下一章先不急着拆中间件,而是看工具列表如何被筛出来;因为模型能调用什么,决定了这张图实际能做什么。