ARTICLE DETAIL

资讯详情

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

DeepAgents 工具(Tools)实战:用 create_deep_agent 接入 MCP 工具链

DeepAgents 工具(Tools)实战:用 create_deep_agent 接入 MCP 工具链 1. DeepAgents 工具链到底解决什么问题适合谁上手DeepAgents 里的 Tools 模块说白了就是给智能体装「手脚」。模型本身只会生成文本它没法真的去查数据库、读你本地文件、调第三方接口。Tools 就是把这些外部能力包装成模型能理解、能调用的函数让create_deep_agent创建出来的 Agent 真正能干活。我一开始接触 DeepAgents 的时候最直观的感受是它把「工具注册」这件事做得比裸写 LangChain Agent 省心。你不需要手写一堆 JSON Schema只要把普通 Python 函数、tool装饰过的 LangChain 工具、或者 MCP 服务暴露出来的工具列表统一塞进tools参数框架会自动解析函数签名和 docstring 生成入参结构。这对快速搭原型特别友好。那它适合谁三类人值得花时间跑一遍一是已经在用 LangChain 做 Agent、但被工具 Schema 维护折磨的开发者二是想接 MCP 协议、把本地或远程服务开放给智能体调用的工程师三是需要给 Agent 挂载文件操作、Shell 执行、子智能体调度这类内置能力又不想从零实现的人。DeepAgents 的内置 harness 工具默认就带ls、read_file、write_file、edit_file、glob、grep、execute、task、write_todos这一套开箱即用。核心检索词先摆清楚DeepAgents Tools 是连接智能体与外部世界的桥梁create_deep_agent是创建入口MCP 是工具协议标准LangChain 生态提供适配层。这四个词串起来就是本篇要跑通的完整链路。实际场景里我遇到最多的问题是「工具声明了但模型不调用」或者「调用了但参数对不上」。前者通常是 docstring 写得太模糊模型判断不出什么时候该用后者多半是类型标注缺失框架生成的 Schema 和实际入参不匹配。这两个坑后面会专门讲排查方法。还有一个容易被忽略的点DeepAgents 对模型生态的适配挺广Google、OpenAI、Anthropic、OpenRouter、Fireworks、Baseten、Ollama 都能通过model参数指定。这意味着你可以用本地 Ollama 跑代码模型做开发调试上线再切到云端模型工具层代码完全不用改。这个灵活性在迭代阶段很实用。接下来我会按「前置准备 → 可复制配置 → 验证调用 → 排错」的顺序走一遍每一步都给能直接粘贴的代码和配置。你跟着做本地应该能跑通一次完整的工具调用链路。2. TaoToken 前置准备拿到 Base URL、API Key 和 Model ID在写工具代码之前得先把模型接入这块搞定。DeepAgents 本身不提供模型服务它通过 LangChain 的模型接口去调各家大模型。这里我用 TaoToken 作为统一接入层原因是它兼容 OpenAI 风格的接口配置简单而且一个 Key 能切换多个模型省得每个厂商单独申请。你需要准备三样东西Base URL、API Key、Model ID。这三件套是后面所有配置的基础缺一不可。Base URL 用https://taotoken.net/api注意这个地址不带任何查询参数直接作为 OpenAI 兼容端点使用。API Key 需要你去控制台生成路径是 API Keys 管理页。Model ID 则取决于你想用哪个模型比如gpt-5.5、claude-sonnet-4-6这类标识。具体操作步骤先打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册账号然后进控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 创建 API Key。创建完记得复制保存页面刷新后就看不清完整 Key 了。拿到 Key 之后建议先做一次最小验证确认 Key 和 Base URL 能通。可以用 curl 直接打一个 chat completions 请求curl https://taotoken.net/api/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { model: gpt-5.5, messages: [{role: user, content: ping}] }如果返回里有choices字段和正常内容说明接入层没问题。如果返回 401那就是 Key 不对或者没带上如果返回模型不存在那就是 Model ID 写错了。这两个错误后面排障章节会细说。环境变量建议这样设置避免把 Key 硬编码进代码export TAOTOKEN_API_KEY你的Key export TAOTOKEN_BASE_URLhttps://taotoken.net/api在 Python 里读取的时候用os.environ[TAOTOKEN_API_KEY]就行。这样代码可以提交到 GitKey 留在本地环境里。有一点要注意TaoToken 是合规的 API 接入服务不是那种灰色中转。你按正常流程注册、生成 Key、调用接口即可。如果团队里有人问「能不能直连生产数据库」答案是不行MCP 工具也不应该直连生产库这个后面会强调。模型选择上如果你只是本地跑通工具调用链路用便宜的小模型就够了。等链路验证通过再换成能力更强的模型做实际任务。DeepAgents 的model参数支持openai:、anthropic:、google_genai:等前缀配合 TaoToken 的 Base URL你可以用同一套代码切换不同底层模型。前置准备做完接下来就是写工具声明和 Agent 创建代码了。3. 可复制配置自定义工具 MCP 工具 create_deep_agent 挂载这一节是核心我会给出完整的可复制配置。分三块自定义工具声明、MCP 工具接入、以及用create_deep_agent把两者挂载起来。先装依赖pip install deepagents langchain-mcp-adapters tavily-python3.1 自定义工具声明DeepAgents 支持直接传入可调用对象。普通函数、tool装饰器定义的 LangChain 工具、工具描述字典都行。框架会自动解析函数签名和 docstring 生成入参结构多数场景不用手写 Schema。下面封装一个 Tavily 网页搜索工具这是最常见的自定义工具场景import os from typing import Literal from tavily import TavilyClient from deepagents import create_deep_agent tavily_client TavilyClient(api_keyos.environ[TAVILY_API_KEY]) def internet_search( query: str, max_results: int 5, topic: Literal[general, news, finance] general, include_raw_content: bool False, ): 互联网网页搜索工具用于查询实时信息。 Args: query: 搜索关键词 max_results: 返回结果数量默认 5 topic: 搜索主题分类 include_raw_content: 是否包含原始网页内容 return tavily_client.search( query, max_resultsmax_results, include_raw_contentinclude_raw_content, topictopic, )注意 docstring 的写法。模型靠这段描述判断「什么时候该调用这个工具」。如果你只写「搜索工具」四个字模型很可能在该搜的时候不搜。写清楚用途、参数含义、返回什么调用准确率会明显提升。3.2 MCP 工具接入MCP 是模型上下文协议一套面向智能体对接外部服务的开源标准。DeepAgents 原生支持加载任意 MCP 服务开放的工具。配置本地 MCP 服务的写法import asyncio from langchain_mcp_adapters.client import MultiServerMCPClient from deepagents import create_deep_agent async def main(): client MultiServerMCPClient({ my_server: { transport: http, url: http://localhost:8000/mcp, } }) tools await client.get_tools() agent create_deep_agent( modelopenai:gpt-5.5, toolstools, ) result await agent.ainvoke( {messages: [{role: user, content: 调用MCP服务完成任务}]}, config{configurable: {thread_id: 1}}, ) print(result) asyncio.run(main())transport支持http和stdio两种。本地服务用http指向http://localhost:8000/mcp如果是命令行工具类的 MCP 服务用stdio配command和args。3.3 用 create_deep_agent 挂载工具把自定义工具和 MCP 工具合并挂载import os from deepagents import create_deep_agent agent create_deep_agent( modelopenai:gpt-5.5, tools[internet_search, *mcp_tools], )如果你用 TaoToken 作为接入层需要配置 OpenAI 兼容的 base_url。LangChain 的 ChatOpenAI 支持base_url参数from langchain_openai import ChatOpenAI from deepagents import create_deep_agent llm ChatOpenAI( modelgpt-5.5, base_urlhttps://taotoken.net/api, api_keyos.environ[TAOTOKEN_API_KEY], ) agent create_deep_agent( modelllm, tools[internet_search], )这里三件套齐全Base URL 是https://taotoken.net/apiKey 从环境变量读Model ID 是gpt-5.5。如果你用 Claude Code 或者 Cline 这类工具配置逻辑一样都是填这三项。3.4 内置 harness 工具除了手动注入的工具所有 Deep Agent 实例默认搭载一套内置工具不用额外开发。清单如下工具名称功能说明ls列出指定目录下所有文件read_file读取文件内容支持分页与多模态解析write_file创建新文件或覆盖已有内容edit_file基于字符串精准匹配做局部修改delete删除单个文件支持递归删除文件夹glob使用通配符批量检索文件grep在文件内搜索目标文本execute执行 Shell 命令仅沙箱环境可用task派生子智能体用于任务拆分与调度write_todos维护结构化待办任务清单这些工具默认就在你不需要在tools里显式声明。如果你发现 Agent 能读文件但不能执行 Shell检查一下是不是跑在非沙箱环境里execute只在沙箱可用。配置写完之后下一步就是验证调用链路是否真的通了。4. 验证请求跑通一次完整的工具调用链路配置写完不代表能跑。这一节我会给一个可复现的验证脚本从发起请求到看到工具调用结果完整走一遍。先写一个最小验证脚本只挂一个自定义工具排除 MCP 的干扰import os from deepagents import create_deep_agent from langchain_openai import ChatOpenAI llm ChatOpenAI( modelgpt-5.5, base_urlhttps://taotoken.net/api, api_keyos.environ[TAOTOKEN_API_KEY], ) def get_weather(city: str) - str: 查询指定城市的天气情况。 Args: city: 城市名称例如 北京、上海 mock_data {北京: 晴25度, 上海: 多云28度} return mock_data.get(city, 暂无数据) agent create_deep_agent( modelllm, tools[get_weather], ) result agent.invoke( {messages: [{role: user, content: 北京今天天气怎么样}]}, config{configurable: {thread_id: test-1}}, ) for msg in result[messages]: print(type(msg).__name__, :, getattr(msg, content, msg))跑这个脚本你应该能看到类似这样的输出先是 HumanMessage 带用户问题然后是 AIMessage 里包含 tool_calls 字段指明调用了get_weather且参数是{city: 北京}接着是 ToolMessage 返回晴25度最后是 AIMessage 把结果组织成自然语言回复。如果你看到 tool_calls 但后面没有 ToolMessage说明工具执行环节断了检查函数是不是抛异常了。如果连 tool_calls 都没有模型直接编了个答案说明 docstring 没让模型意识到该调工具。验证 MCP 工具的时候先单独确认 MCP 服务本身能通curl http://localhost:8000/mcp/tools返回工具列表 JSON 就说明 MCP 服务正常。然后在 Python 里单独调client.get_tools()打印工具数量和名称tools await client.get_tools() print(f加载了 {len(tools)} 个工具) for t in tools: print(-, t.name)确认工具加载成功再挂到 Agent 上。这样分层验证出问题容易定位。验证成功的标志有三个一是请求返回 200 且 messages 列表完整二是能看到 tool_calls 和对应的 ToolMessage三是最终回复内容引用了工具返回的数据而不是模型自己编的。我实测下来最容易出问题的是 thread_id 没传或者传重复。config{configurable: {thread_id: xxx}}这个配置用于维持对话状态不传的话某些场景会报错。每次新对话换个 id别复用。链路跑通之后把验证脚本里的 mock 工具换成真实工具再逐步加 MCP 工具一次加一个加完就验证。这样出问题能快速定位是哪个工具引入的。5. 常见错误排查401、local proxy failed、reading choices、OAuth这一节对照真实报错来讲。我把踩过的坑按错误信息分类每条给现象、原因、解法。5.1 401 Unauthorized现象请求返回{error: {message: Invalid API key, type: invalid_request_error}}。原因通常是三种Key 没设置、Key 复制不完整、Header 格式不对。检查环境变量echo $TAOTOKEN_API_KEY有没有值。检查代码里是不是写成了Bearer加空格加 Key少空格会失败。如果你用的是 LangChain 的 ChatOpenAI确认api_key参数传对了不是openai_api_key这种旧参数名。5.2 local proxy failed / connection refused现象httpx.ConnectError: [Errno 111] Connection refused或者local proxy failed。这个多半是 Base URL 写错了。确认是https://taotoken.net/api不是https://taotoken.net/api/v1或者别的路径。有些 OpenAI 兼容服务需要/v1后缀TaoToken 不需要。另外检查本地网络能不能访问外网公司内网可能有防火墙限制。5.3 reading choices 报错现象KeyError: choices或者reading choices field失败。这说明返回的 JSON 结构里没有choices字段。常见原因是请求打到了错误的端点比如把 chat completions 的请求发到了 models 列表接口。确认 URL 是/api/chat/completions。还有一种可能是模型名写错了服务端返回了错误结构。打印完整响应体看看实际返回了什么。5.4 OAuth 相关错误现象OAuth token expired或者invalid_grant。如果你用的是 Claude Code 或者某些需要 OAuth 的工具token 过期是常见问题。重新走一遍授权流程或者改用 API Key 方式接入。TaoToken 的 API Key 方式不涉及 OAuth配置更简单。如果你在 Cline 或 CC Switch 里配置确保 Base URL、Key、Model ID 三件套都填了缺一个都会报认证类错误。5.5 工具不被调用现象模型直接回复没有 tool_calls。检查 docstring 是不是太简略。把工具用途、适用场景、参数含义写清楚。另外确认tools参数真的传进去了打印一下agent的工具列表。有些模型对工具调用的支持较弱换一个工具调用能力强的模型试试。5.6 MCP 工具加载为空现象client.get_tools()返回空列表。确认 MCP 服务地址和端口对transport类型匹配。http 服务用http命令行工具用stdio。stdio 模式下检查command路径是不是绝对路径args是不是完整。本地服务没启动的话先手动启动再跑脚本。排错的核心思路是分层先验证模型接入层curl 打 chat completions再验证工具加载层打印工具列表最后验证调用链路看 tool_calls 和 ToolMessage。哪一层断了就修哪一层别一上来就怀疑框架。6. 长期编码与 Agent 场景的接入建议如果你只是跑个 demo上面这些够了。但如果你要把 DeepAgents 用到长期编码或者 Agent 工作流里有几个点值得注意。工具粒度别太细。一个工具干一件事但别把每个小操作都拆成独立工具。工具太多模型选择困难调用准确率反而下降。我一般把相关操作合并成一个工具用参数区分行为。docstring 当文档写。模型靠它理解工具你写得越清楚调用越准。参数类型标注要完整Literal类型能限定取值范围减少模型传错参数的概率。MCP 工具不要直连生产库。这是安全底线。MCP 服务应该暴露只读或者受限的操作写操作走审批流程。生产环境的数据库连接信息不要出现在 MCP 配置里。模型切换留好接口。用 TaoToken 这类统一接入层的好处是换模型只改 Model ID工具代码不动。开发阶段用便宜模型上线切强模型成本可控。验证脚本保留。每次加新工具先跑验证脚本确认链路通再集成到主流程。这样出问题能快速回滚。如果你需要长期跑编码类 Agent可以考虑 Coding Plan 这类方案配合工具链做持续任务。模型对话页面可以用来快速验证单个工具的调用效果不用每次都写脚本。接入文档里有更详细的参数说明和示例遇到配置问题可以先查文档。API Keys 管理页可以随时生成新 Key 或吊销旧 Key建议定期轮换。最后说一个实际经验工具调用失败的时候先看模型返回的 tool_calls 参数对不对再看工具函数有没有抛异常最后看返回结果有没有正确回传给模型。这三步走完九成问题能定位。剩下的那一成多半是模型本身对工具调用的支持问题换个模型就好。
返回列表