DeepAgents 子智能体实战:用 CompiledSubAgent 拆解 LangGraph 多智能体协作 1. 从单体 Agent 到子智能体为什么需要 SubAgent 拆分如果你用 LangGraph 搭过一个稍微复杂点的 Agent大概率会遇到这种局面一个 system prompt 里塞了搜索、写代码、查数据库、做总结四五种职责工具列表挂了一长串模型每次选工具都像在抽奖。任务一复杂它就开始「忘记」前面的约束或者把搜索工具用在根本不需要搜索的地方。这不是模型不行而是你把太多职责压给了一个决策单元。DeepAgents 里的 SubAgent子智能体就是来解决这个问题的。简单说它允许你把一个「全能 Agent」拆成若干个职责单一、工具集独立、提示词独立的小 Agent主 Agent 只负责判断「这个任务该交给谁」具体执行交给子 Agent。这跟微服务拆分的思路很像主 Agent 是网关SubAgent 是各个业务服务各自只关心自己的事。而 CompiledSubAgent 是 SubAgent 的一种特殊形态。普通的 SubAgent 用字典配置就行本质上是「换个提示词 换套工具」的轻量分身CompiledSubAgent 则允许你把一个已经编译好的 LangGraph 图直接挂进来当子 Agent 用。这意味着你之前写好的多节点工作流——比如「先检索再分析再校验」这种固定管线——可以原封不动地变成一个可被主 Agent 调用的子智能体。这套机制适合谁如果你正在用 LangGraph 做多智能体协作或者你的 Agent 已经出现了「职责过载、工具误用、上下文爆炸」的征兆那 SubAgent 拆分就是下一步该做的事。本文会给你可复制的 SubAgent 配置骨架、CompiledSubAgent 的接线示例以及编译和调用链路的验证动作目标是把单一智能体真正拆成可独立编译的子智能体。2. TaoToken 前置准备给 DeepAgents 配一个稳定的模型入口在动手写 SubAgent 之前得先把模型调用这条链路打通。DeepAgents 本身不绑定某一家模型它通过 LangChain 的 ChatModel 接口调用后端所以你需要一个兼容 OpenAI 协议、能稳定拿到 Key 的入口。我这边实测下来用 TaoToken 的 API 接入比较省事Base URL 和 Key 拿到就能直接喂给ChatOpenAI。先到 TaoToken 控制台创建一个 API Key。地址是 https://taotoken.net/api-keys 登录后点创建复制那串sk-开头的 Key存到环境变量里别硬编码进代码export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api这里有个容易踩的坑Base URL 末尾不要带/v1LangChain 的 OpenAI 兼容层会自己拼路径。如果你写成https://taotoken.net/api/v1请求会变成/api/v1/v1/chat/completions直接 404。我试过这个错排查了十几分钟才反应过来。模型 ID 方面DeepAgents 的create_deep_agent里model参数填的是模型标识比如gpt-4o、claude-3-5-sonnet这类。你可以在模型对话页先确认一下当前可用的模型列表https://taotoken.net/models 选一个支持 function calling 的因为 SubAgent 的工具调用依赖这个能力。如果你打算长期跑编码类或 Agent 类任务可以考虑 Coding Plan额度更划算适合反复调试多智能体链路https://taotoken.net/coding-plan 。不过前期验证阶段按量付费的 Key 就够用了。配置好之后先写一个最小的连通性测试确认模型能正常返回再往上叠 SubAgent 逻辑。这样出问题的时候你能快速判断是模型链路的问题还是 Agent 编排的问题import os from langchain_openai import ChatOpenAI llm ChatOpenAI( modelgpt-4o, api_keyos.environ[TAOTOKEN_API_KEY], base_urlos.environ[TAOTOKEN_BASE_URL], temperature0, ) resp llm.invoke(用一句话说明什么是子智能体) print(resp.content)跑通这段说明 Base URL、Key、Model ID 三件套都对上了。接下来才是 SubAgent 的正题。3. 可复制的 SubAgent 配置骨架与 LangGraph 节点接线DeepAgents 创建子 Agent 有两条路字典配置和 CompiledSubAgent。字典配置适合「换个提示词和工具」的轻量场景CompiledSubAgent 适合「我有一张现成的 LangGraph 图想直接复用」。先看字典配置的骨架。核心字段就四个name、description、system_prompt、tools。name是主 Agent 调用时的标识description决定主 Agent 什么时候会想到用它system_prompt是这个子 Agent 的专属指令tools是它被允许使用的工具集。注意model字段可以省略省略就继承主 Agent 的模型。from deepagents import create_deep_agent from langchain_core.tools import tool tool def mock_internet_search(query: str) - str: 模拟网络搜索返回与 query 相关的摘要。 return f关于「{query}」的检索结果该领域近期有三项关键进展。 research_subagent { name: research-agent, description: 用于深入研究问题执行网络搜索并合成信息。当任务需要外部资料时调用。, system_prompt: 你是一名专业研究员。请遵循以下步骤 1. 理解用户的研究问题。 2. 使用 mock_internet_search 工具进行检索。 3. 从结果中提炼关键信息合成一份结构化摘要。 4. 回答保持简洁不超过 300 字。, tools: [mock_internet_search], } agent create_deep_agent( modelgpt-4o, system_prompt你是协调员。对于复杂研究任务请使用 task 工具委托给 research-agent。, subagents[research_subagent], )这段代码里主 Agent 的 system_prompt 明确告诉它「用 task 工具委托」这是关键。如果你不写这句主 Agent 可能自己硬扛不去调用子 Agent。description也要写得具体它是主 Agent 做路由决策的依据写「研究助手」不如写「当任务需要外部资料检索时调用」。再看 CompiledSubAgent。假设你已经用 LangGraph 搭了一张「先搜索后分析」的两步图现在想把它整个挂成子 Agentfrom deepagents import create_deep_agent, CompiledSubAgent from langgraph.graph import StateGraph, MessagesState, START from langchain_core.messages import HumanMessage def search_node(state: MessagesState): return {messages: [HumanMessage(contentf已搜索: {state[messages][-1].content})]} def analysis_node(state: MessagesState): return {messages: [HumanMessage(content已分析结果。结论是: 潜力巨大。)]} builder StateGraph(MessagesState) builder.add_node(search, search_node) builder.add_node(analysis, analysis_node) builder.add_edge(START, search) builder.add_edge(search, analysis) custom_graph builder.compile() custom_subagent CompiledSubAgent( nameadvanced-analyzer, description执行先搜索后深度分析的复杂工作流。当任务需要多步分析时调用。, runnablecustom_graph, ) agent create_deep_agent( modelgpt-4o, subagents[custom_subagent], )这里runnable必须是已经compile()过的图传未编译的 builder 会报错。CompiledSubAgent 的价值在于你那张图内部的节点、边、状态流转都是固定的主 Agent 不需要知道里面怎么跑只需要知道「这个子 Agent 能干什么」。这跟把一段复杂逻辑封装成函数是一个道理。如果你用的是 Cline MCP 或者 Claude Code 这类工具来辅助写代码记得把 Base URL、Key、Model ID 三件套配全否则工具链会报认证失败。Cline 的 MCP 配置里baseUrl填https://taotoken.net/apiapiKey填你的 Key模型选支持工具调用的。4. 验证请求与成功结果编译、调用链路怎么确认配置写完不代表能跑。SubAgent 的验证要分三层图能不能编译、主 Agent 能不能路由、子 Agent 能不能执行。第一层编译验证。如果你用的是 CompiledSubAgent先单独把图跑一遍确认节点和边没问题result custom_graph.invoke({messages: [HumanMessage(content测试输入)]}) for msg in result[messages]: print(msg.content)预期输出里应该能看到「已搜索」和「已分析」两条消息说明图内部流转正常。如果这里就报错别急着往主 Agent 里塞先把图调通。第二层路由验证。创建主 Agent 后发一个明确需要子 Agent 的任务观察主 Agent 是否调用了task工具response agent.invoke({ messages: [HumanMessage(content帮我研究一下多智能体协作的近期进展)] }) print(response[messages][-1].content)成功的情况下你会看到主 Agent 先输出一段「我将委托给 research-agent」之类的调度信息然后子 Agent 返回检索摘要最后主 Agent 汇总。如果主 Agent 自己直接回答了说明description写得不够有区分度或者 system_prompt 里的委托指令不够强。第三层工具隔离验证。这是 SubAgent 拆分最实际的好处子 Agent 只能看到自己tools列表里的工具。你可以故意给 research-agent 一个它没有的工具名看它是否会尝试调用。正常情况下它应该只会在自己的工具集里选。实测下来三层都过了说明你的 SubAgent 拆分是成立的。这时候再往主 Agent 里加第二个、第三个子 Agent逐个验证别一次性全塞进去否则出问题很难定位是哪个子 Agent 的配置有毛病。5. 本篇常见错排查401、local proxy failed、reading choices、OAuthSubAgent 链路跑不通报错往往集中在几个地方。我按实际遇到的频率排一下。401 Unauthorized。最常见的原因是 Key 没读到或者 Base URL 拼错。先确认环境变量真的注入了echo $TAOTOKEN_API_KEY echo $TAOTOKEN_BASE_URL如果 Key 是空的检查你的 shell 配置或者.env加载逻辑。如果 Key 有值但还是 401检查 Base URL 是不是多带了/v1。正确写法是https://taotoken.net/api不带版本号后缀。local proxy failed。这个报错通常出现在你本地配了某些网络层但请求没走通。先确认你的运行环境能正常访问https://taotoken.net/api用 curl 测一下curl -s -o /dev/null -w %{http_code} https://taotoken.net/api/models \ -H Authorization: Bearer $TAOTOKEN_API_KEY返回 200 说明链路通返回其他码再对照排查。注意别在代码里硬编码任何本地转发地址直接用官方 Base URL。reading choices 相关报错。这类错误一般是响应结构不符合预期常见于模型返回了非标准格式或者你用的模型不支持 function calling。SubAgent 依赖工具调用如果模型不支持主 Agent 的task工具就调不起来。换一个明确支持工具调用的模型 ID 再试。OAuth 相关报错。如果你在用 Claude Code 或者某些 CLI 工具它们可能默认走 OAuth 流程。这时候需要在工具的配置里显式指定 API Key 模式把 Base URL 和 Key 填进去。Claude Code 的配置可以参考接入文档https://taotoken.net/doc 里面有各客户端的配置示例。排查的核心思路是先确认模型链路通curl 测再确认图能编译单独 invoke最后确认主 Agent 能路由看 task 调用。分层定位别一上来就怀疑 SubAgent 配置。6. 把子智能体接进你的 LangGraph 工作流SubAgent 拆分的本质是把「一个 Agent 做所有事」变成「主 Agent 调度 子 Agent 执行」。字典配置适合快速分身CompiledSubAgent 适合复用已有图。两者可以混用主 Agent 的subagents列表里既能放字典也能放 CompiledSubAgent 实例。落地的时候记住三个动作先跑通模型链路再单独验证每张图最后逐个接入主 Agent 验证路由。别跳过任何一层否则报错会混在一起排查成本翻倍。如果你要把这套链路用到长期编码或 Agent 任务上Coding Plan 的额度更适合反复调试https://taotoken.net/coding-plan 。模型对话页可以用来快速确认某个模型 ID 是否可用https://taotoken.net/models 。接入文档里有各客户端的完整配置https://taotoken.net/doc 。API Key 管理在 https://taotoken.net/api-keys 。最后给一个实用技巧给每个子 Agent 的description加上「当……时调用」的触发条件比单纯描述能力更能提升主 Agent 的路由准确率。这是我在多个项目里反复验证过的比调 temperature 管用。