ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LangChain DeepAgents 完全指南:用 TaoToken 统一 Key 打通多智能体配置

LangChain DeepAgents 完全指南:用 TaoToken 统一 Key 打通多智能体配置 1. 为什么多智能体一上手就卡在 Key 上LangChain DeepAgents 是最近在 Agent 圈子里讨论度很高的一个框架。一句话说清楚它是什么它把「规划、文件读写、Shell 执行、子 Agent 委托、上下文摘要」这些做 Agent 必备的零件全部预装好你调用create_deep_agent()就能拿到一个能拆任务、能读写文件、能派子代理干活的通用助手。它适合谁适合已经写过基础 LangChain Agent、想往「多智能体协作」方向走一步的开发者也适合想把本地脚本升级成能自主规划任务的工程同学。但真正落地时很多人卡住的地方不是框架本身而是模型接入。DeepAgents 默认走 Anthropic 的 Claude 系列resolve_model里写死了claude-sonnet-4-6这类默认值。如果你手上有多个模型供应商的 Key或者团队里几个人共用一套额度配置就会变得很碎主 Agent 一个 Key、子 Agent 一个 Key、摘要中间件又要一个 Key环境变量满天飞换台机器就得重配一遍。我试过把主 Agent、子 Agent、摘要模型分别指向不同供应商结果调试时根本分不清是哪条链路出的错。后来改成用 TaoToken 做统一入口所有模型请求走同一个 API 通道、同一把 Key配置一下子收敛成两个文件一个config.toml管模型与通道一个settings.json管运行时参数。这篇就按这个思路把 DeepAgents 的多智能体配置完整跑一遍最后给一个可复现的验证动作确认主 Agent 到子 Agent 的链路是通的。TaoToken 在这里扮演的角色很单纯它是一个兼容 OpenAI 风格接口的模型调用入口你拿到一把 Key就能在 DeepAgents 里通过init_chat_model或自定义BaseChatModel接进来。官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end API 根地址是 https://taotoken.net/api 注意这个 API 地址后面不加任何查询参数。2. TaoToken 前置准备Key 与通道在写配置之前先把两件事做完拿 Key、确认通道地址。第一步登录控制台创建 API Key。地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在 API Keys 页面新建一把复制出来形如sk-xxxx的字符串。这把 Key 后面会同时给主 Agent、子 Agent、摘要中间件用所以别弄丢。第二步确认你要调用的模型名。DeepAgents 的resolve_model支持provider:model格式接入 TaoToken 时我们不走它内置的 provider 前缀而是直接构造一个指向 TaoToken 的 ChatModel 实例传进去。这样最干净也避免框架内部再去猜 provider。第三步把 Key 写进环境变量别硬编码进代码export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api注意TAOTOKEN_BASE_URL只写到/api不要在后面拼/v1或加查询串。很多 401 报错都是因为 base_url 多写了一层路径。如果你更习惯用配置文件管理可以在项目根目录建一个.env然后用python-dotenv加载。但环境变量方式对 CI 和容器更友好推荐优先用环境变量。到这里前置就结束了。接下来是核心两个配置文件的骨架。3. 可复制配置config.toml 与 settings.jsonDeepAgents 本身不强制你用 TOML 或 JSON 配置但多智能体项目里把「模型通道」和「运行时参数」分开管理会清晰很多。下面这套骨架是我实际在用的你可以直接抄。3.1 config.toml模型与通道# config.toml # 统一模型通道配置所有 Agent 共用同一把 Key [provider] name taotoken base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY # 从环境变量读取不写明文 [models] # 主 Agent 用的模型 main claude-sonnet-4-6 # 子 Agent 用的模型可以和主 Agent 不同 subagent claude-sonnet-4-6 # 摘要中间件用的模型通常用更便宜的 summarizer claude-haiku-4-5 [agent] name deep-agent-demo recursion_limit 1000 debug false [backend] # 默认内存后端开发阶段够用 type state这里有几个设计点值得说。api_key_env存的是环境变量名而不是 Key 本身这样配置文件可以进 Git 仓库而不泄露密钥。models分了三档是因为 DeepAgents 的摘要中间件会频繁调用模型来压缩历史用便宜模型能省不少成本而主 Agent 和子 Agent 用能力强的模型保证任务质量。3.2 settings.json运行时参数{ runtime: { thread_id: deepagents-demo-001, checkpointer: memory, stream: true }, middleware: { summarization: { enabled: true, threshold: 0.8, offload_to_filesystem: false }, human_in_the_loop: { enabled: false, interrupt_on: { edit_file: true, execute: true } } }, subagents: [ { name: researcher, description: 负责搜索和收集信息的子代理, system_prompt: 你是一个研究助手专注于收集和整理信息输出结构化结论。, model_key: subagent }, { name: reviewer, description: 负责审查代码质量的子代理, system_prompt: 你是一个严格的代码审查专家关注风格一致性、错误处理和安全问题。, model_key: subagent } ], skills: [], memory: [] }settings.json管的是「怎么跑」线程 ID 用于状态恢复摘要阈值控制何时压缩上下文子代理列表定义了有哪些可委托的角色。model_key字段指向config.toml里的模型档位这样换模型只改一处。3.3 把两个配置接进 DeepAgents下面这段 Python 代码负责读配置、构造指向 TaoToken 的 ChatModel、再创建 Agent。核心是用ChatOpenAI兼容类指向 TaoToken 的 base_url因为 TaoToken 提供 OpenAI 风格接口。# build_agent.py import os import json import tomllib from langchain_openai import ChatOpenAI from deepagents import create_deep_agent from langgraph.checkpoint.memory import MemorySaver def load_config(): with open(config.toml, rb) as f: cfg tomllib.load(f) with open(settings.json, r, encodingutf-8) as f: settings json.load(f) return cfg, settings def build_model(cfg, model_key): 构造指向 TaoToken 的 ChatModel 实例 provider cfg[provider] api_key os.environ[provider[api_key_env]] model_name cfg[models][model_key] return ChatOpenAI( modelmodel_name, api_keyapi_key, base_urlprovider[base_url], temperature0, ) def build_agent(): cfg, settings load_config() main_model build_model(cfg, main) subagent_model build_model(cfg, subagent) # 把 settings 里的子代理定义转成 DeepAgents 需要的格式 subagents [] for spec in settings[subagents]: subagents.append({ name: spec[name], description: spec[description], system_prompt: spec[system_prompt], model: subagent_model, }) checkpointer MemorySaver() if settings[runtime][checkpointer] memory else None agent create_deep_agent( modelmain_model, subagentssubagents, checkpointercheckpointer, debugcfg[agent][debug], ) return agent, settings if __name__ __main__: agent, settings build_agent() config {configurable: {thread_id: settings[runtime][thread_id]}} result agent.invoke( {messages: [{role: user, content: 你好介绍一下你自己}]}, config, ) print(result[messages][-1].content)这段代码的关键在于build_model函数它把config.toml里的 base_url 和从环境变量读到的 Key 组合成一个ChatOpenAI实例。DeepAgents 的create_deep_agent接受BaseChatModel实例作为model参数所以主 Agent 和子 Agent 都能用同一个构造函数产出只是传入的model_key不同。提示如果你用的 langchain-openai 版本较老api_key参数可能叫openai_api_key按你本地版本调整即可。4. 验证请求确认多智能体链路正常配置写完不算完得跑一次能证明「主 Agent 能派活给子 Agent」的验证。下面这个动作会触发task工具让主 Agent 把任务委托给researcher子代理。# verify_chain.py from build_agent import build_agent agent, settings build_agent() config {configurable: {thread_id: verify-001}} prompt ( 请使用 researcher 子代理帮我整理三条关于 LangChain DeepAgents 的核心特性 每条不超过 30 字。整理完后你自己再补充一句总结。 ) result agent.invoke( {messages: [{role: user, content: prompt}]}, config, ) # 打印完整消息链确认 task 工具被调用过 for msg in result[messages]: role getattr(msg, type, unknown) content getattr(msg, content, ) if isinstance(content, list): content .join(str(c) for c in content) print(f[{role}] {str(content)[:200]})跑起来后你应该在输出里看到类似这样的消息序列先是 HumanMessage你的提问然后是 AIMessage 里带tool_calls其中name是taskargs里subagent_type是researcher接着是 ToolMessage子代理返回的结果最后是主 Agent 的总结性 AIMessage。判断链路是否正常看三个点第一task工具确实被调用了。如果主 Agent 自己把活干了说明子代理描述不够有吸引力或者模型没理解委托意图可以调整description字段让它更明确。第二ToolMessage 的内容来自子代理而不是主 Agent 自己编的。子代理有独立的 system_prompt输出风格会和主 Agent 不同这个差异是判断依据。第三没有出现 401 或 404。如果报 401检查TAOTOKEN_API_KEY是否导出成功如果报 404检查 base_url 是不是写成了https://taotoken.net/api/v1这种多一层的形式。如果这三步都过了说明主 Agent → TaoToken 通道 → 子 Agent 的完整链路是通的。这时候你可以把settings.json里的human_in_the_loop打开再跑一次涉及edit_file的任务验证中断审批也能正常工作。5. 本篇常见错排查配置多智能体时报错往往集中在几个固定位置。下面按我踩过的顺序列一遍。报错一KeyError: TAOTOKEN_API_KEY这是环境变量没导出。os.environ[provider[api_key_env]]在变量不存在时会直接抛 KeyError。解决方式是确认export命令在当前 shell 生效或者改用os.environ.get(..., )加显式判空报错信息会更友好。报错二openai.AuthenticationError: 401Key 本身无效或已过期。去控制台 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 重新生成一把替换环境变量后重跑。注意别把 Key 前后的空格带进去。报错三openai.NotFoundError: 404base_url 写错了。正确值是https://taotoken.net/api不要加/v1不要加尾部斜杠。有些 OpenAI SDK 版本会自动补/chat/completions所以 base_url 只需要到/api。报错四子代理没被调用主 Agent 自己干完了这不是报错是行为不符合预期。原因通常是子代理的description写得太泛模型判断「自己也能做」。把 description 写具体比如「当任务需要收集外部信息且可以独立完成时使用」并在主 prompt 里显式要求「必须使用 researcher 子代理」。报错五GraphRecursionErrorAgent 循环步数超过recursion_limit。DeepAgents 默认给到 1000一般够用。如果频繁触发检查是不是子代理返回的结果让主 Agent 反复重试可以在子代理 system_prompt 里要求「一次性给出最终结论不要反问」。报错六摘要中间件把关键上下文压没了threshold设太低比如 0.5会导致过早压缩。默认 0.8 比较稳。如果任务需要长上下文可以调到 0.9或者把offload_to_filesystem打开让大结果落到文件而不是被摘要掉。报错七checkpointer相关报错人在环中功能依赖 checkpointer。如果你开了interrupt_on但没传checkpointer中断后状态无法恢复。确保create_deep_agent里传了MemorySaver()或 SQLite checkpointer。6. 下一步把统一 Key 用在长期编码场景跑通上面这套配置后你手上就有了一条稳定的模型通道主 Agent、子 Agent、摘要模型全部走 TaoToken 的同一把 Key换模型只改config.toml一行换机器只导一次环境变量。这对多智能体项目特别重要因为 Agent 数量一多Key 管理混乱带来的调试成本会指数上升。如果你接下来要把 DeepAgents 用在长期编码或 Agent 常驻场景建议看一下 Coding Plan它更适合高频、长会话的调用模式https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。如果只是想先验证某个模型在 DeepAgents 里的表现可以直接在模型对话页面试https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 。接入过程中遇到参数问题接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite API Keys 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。最后留一个实用技巧把config.toml里的models段做成可覆盖的比如支持TAOTOKEN_MAIN_MODEL环境变量优先。这样在 CI 里跑测试时可以用便宜模型本地开发时用强模型同一套代码不用改。多智能体项目的配置管理本质上就是让「变的东西」集中在一处其余全部复用。
返回列表