☰
DeepAgents 工具(Tools)实战:用 create_deep_agent 接入 MCP 工具链
2026/10/2 6:18:23 网站建设 项目流程

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_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册账号,然后进控制台 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 创建 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_URL="https://taotoken.net/api"

在 Python 里读取的时候,用os.environ["TAOTOKEN_API_KEY"]就行。这样代码可以提交到 Git,Key 留在本地环境里。

有一点要注意: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-python

3.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_key=os.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_results=max_results, include_raw_content=include_raw_content, topic=topic, )

注意 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( model="openai:gpt-5.5", tools=tools, ) 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( model="openai: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( model="gpt-5.5", base_url="https://taotoken.net/api", api_key=os.environ["TAOTOKEN_API_KEY"], ) agent = create_deep_agent( model=llm, tools=[internet_search], )

这里三件套齐全:Base URL 是https://taotoken.net/api,Key 从环境变量读,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( model="gpt-5.5", base_url="https://taotoken.net/api", api_key=os.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( model=llm, 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 参数对不对,再看工具函数有没有抛异常,最后看返回结果有没有正确回传给模型。这三步走完,九成问题能定位。剩下的那一成,多半是模型本身对工具调用的支持问题,换个模型就好。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询