承接上一节的后端配置与多存储路由,我们已经掌握了虚拟文件系统的各种后端方案,智能体可以灵活地读写不同存储中的文件了。但智能体的能力还受限于我们手动编写的工具——每加一个新能力就要写一个 tool 函数,效率不高。
本节我们学习 MCP (模型上下文协议) ,了解如何通过标准协议快速接入外部工具服务,并以百度搜索为例,让智能体获得实时网页搜索能力。
一、认识 MCP(模型上下文协议)
1.1 什么是 MCP?
MCP(Model Context Protocol,模型上下文协议)是一个开放的标准协议,用于让 AI 助手(智能体)连接外部工具和数据源。简单说,MCP 就是智能体世界的「USB 接口」——只要设备支持 USB 标准,插上去就能用,不需要每个设备单独装驱动。
核心价值:
- 标准化:所有 MCP 服务器遵循统一协议,智能体不需要为每个工具写适配代码
- 即插即用:配置一个 MCP 服务器地址,智能体自动发现并使用所有工具
- 生态丰富:社区已经有大量 MCP 服务器(文件系统、数据库、API、搜索引擎等)
- 语言无关:MCP 服务器可以用任何语言写,智能体用任何语言都能调用
1.2 MCP 的三种传输方式
MCP 服务器支持三种传输方式,适用于不同场景:
| 方式 | 说明 | 适用场景 |
|---|---|---|
stdio | 通过标准输入输出通信,服务器作为本地子进程运行 | 本地工具、命令行工具 |
sse | Server-Sent Events,HTTP 长连接 | 远程服务、实时推送 |
streamableHttp / http | 可流式 HTTP 传输 | 远程 API 服务、云服务 |
💡 百度搜索 MCP 使用的就是
streamableHttp方式,通过 HTTP 接口提供搜索能力。
1.3 MCP 工具的工作流程
用户提问 → 智能体判断需要搜索 → 调用 MCP 搜索工具
→ 请求发送到 MCP 服务器 → 服务器执行搜索 → 返回结果
→ 智能体基于搜索结果生成回答
整个过程对智能体来说,MCP 工具和我们手动写的自定义工具没有区别——都是接收参数、返回结果。区别在于 MCP 工具是自动发现的,不需要我们手动定义。
二、百度搜索 MCP
百度搜索是百度智能云推出的 MCP 工具服务,提供实时网页搜索能力:
配置格式
百度搜索 MCP 的标准配置如下:
{
"mcpServers": {
"web-search-mcp-server": {
"type": "streamableHttp",
"description": "根据用户提问,搜索实时网页信息",
"url": "https://qianfan.baidubce.com/v2/tools/web-search/mcp",
"headers": {
"Authorization": "Bearer 你的API密钥"
}
}
}
}
参数说明:
| 字段 | 说明 |
|---|---|
type | 传输方式,千帆搜索使用 streamableHttp |
description | 服务器描述,帮助智能体理解这个服务器能做什么 |
url | MCP 服务器的端点地址 |
headers.Authorization | 认证信息,格式为 Bearer + API密钥 |
💡 你需要在百度智能云千帆平台申请 API 密钥,替换上面的
你的API密钥。
三、在 Deep Agents 中使用 MCP 工具
Deep Agents 原生支持 MCP 协议,通过官方 @langchain/mcp-adapters 包可以快速接入任意 MCP 服务器,只需要几行代码。
3.1 安装依赖
npm install @langchain/mcp-adapters
3.2 基本用法
集成 MCP 工具只需要三步:
import { createDeepAgent } from "deepagents";
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
// 第一步:创建 MCP 客户端,配置服务器
const client = new MultiServerMCPClient({
"qianfan-search": {
transport: "http",
url: "https://qianfan.baidubce.com/v2/tools/web-search/mcp",
headers: {
Authorization: "Bearer 你的API密钥",
},
},
});
// 第二步:获取所有 MCP 工具
const tools = await client.getTools();
// 第三步:传入 createDeepAgent
const agent = createDeepAgent({
model: model,
tools: tools, // MCP 工具直接传入,和自定义工具一样
systemPrompt: "你是一个智能助手,可以使用搜索工具查找实时信息。",
});
就是这么简单!MultiServerMCPClient 会自动:
-
连接到所有配置的 MCP 服务器
-
发现每个服务器提供的工具
-
将 MCP 工具转换为 LangChain 工具格式
-
处理工具调用和结果返回
3.3 配置多个 MCP 服务器
MultiServerMCPClient 支持同时配置多个服务器,智能体自动管理所有工具:
const client = new MultiServerMCPClient({
// 百度搜索
"qianfan-search": {
transport: "http",
url: "https://qianfan.baidubce.com/v2/tools/web-search/mcp",
headers: {
Authorization: `Bearer ${process.env.QIANFAN_MCP_API_KEY}`,
},
},
// 本地文件系统 MCP(stdio 方式)
"filesystem": {
transport: "stdio",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "./workspace"],
},
// GitHub MCP(stdio 方式)
"github": {
transport: "stdio",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-github"],
env: { GITHUB_TOKEN: process.env.GITHUB_TOKEN },
},
});
const tools = await client.getTools();
💡 每个服务器的 key(比如
qianfan-search)是自定义的名称,用于区分不同的服务器。工具名会自动加上服务器前缀,避免冲突。
四、实战:百度千帆网页搜索
下面我们做一个完整的示例,用百度搜索 MCP 让智能体获得实时搜索能力。
4.1 环境准备
在 .env 中添加千帆 API 密钥:
# .env
# 百度搜索 MCP 密钥
QIANFAN_MCP_API_KEY=你的千帆API密钥
4.2 完整代码
新建 09-mcp-tools.js:
/*
* Deep Agents 教程 09:MCP 工具集成(百度搜索)
*/
import "dotenv/config";
import { createDeepAgent } from "deepagents";
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { model } from "./00-model.js";
// ============================================================
// 1. 创建 MCP 客户端并加载工具
// ============================================================
async function createAgentWithMcp() {
console.log("🔌 正在连接 MCP 服务器...\n");
// 创建 MCP 客户端,配置千帆搜索服务器
const mcpClient = new MultiServerMCPClient({
"qianfan-search": {
transport: "http",
url: "https://qianfan.baidubce.com/v2/tools/web-search/mcp",
headers: {
Authorization: `Bearer ${process.env.QIANFAN_MCP_API_KEY || ""}`,
},
},
});
// 获取所有 MCP 工具
const tools = await mcpClient.getTools();
console.log(`✅ 已加载 ${tools.length} 个 MCP 工具:`);
tools.forEach((tool) => {
console.log(` - ${tool.name}: ${tool.description?.slice(0, 50) || "无描述"}...`);
});
console.log("");
// 创建智能体,注入 MCP 工具
const agent = createDeepAgent({
model: model,
tools: tools,
systemPrompt: `你是一个智能助手,可以使用百度千帆搜索工具查找实时网页信息。
使用搜索工具的规则:
1. 当用户询问时事新闻、最新动态、实时数据等需要最新信息的问题时,请使用搜索工具
2. 搜索时用简洁的关键词,不要用完整句子
3. 搜索结果可能包含多个来源,请综合整理后回答
4. 回答事实性问题时,如果不确定,请搜索确认
5. 回答中可以简要提及信息来自搜索结果
回答语言:中文`,
});
return { agent, mcpClient };
}
// ============================================================
// 2. 流式输出辅助函数
// ============================================================
async function streamAgent(agent, input) {
console.log("\n🧑 用户:", input);
console.log("\n🤖 思考中...\n");
const stream = await agent.streamEvents(
{ messages: [{ role: "user", content: input }] },
{ version: "v3" }
);
await Promise.all([
// AI 回答
(async () => {
for await (const message of stream.messages) {
if (message.reasoning) {
process.stdout.write("💭 思考: ");
for await (const token of message.reasoning) {
if (token) process.stdout.write(token);
}
console.log("\n");
}
if (message.text) {
process.stdout.write("🤖 回答: ");
for await (const token of message.text) {
if (token) process.stdout.write(token);
}
console.log("\n");
}
}
})(),
// 工具调用
(async () => {
for await (const call of stream.toolCalls) {
const inputStr = JSON.stringify(call.input).slice(0, 100);
console.log(`🔧 [工具调用] ${call.name}`);
console.log(` 参数: ${inputStr}...`);
const status = await call.status;
if (status === "finished") {
const output = await call.output;
const shortOutput = typeof output === "string"
? output.slice(0, 150) + "..."
: JSON.stringify(output).slice(0, 150) + "...";
console.log(` ✅ 结果: ${shortOutput}`);
} else if (status === "error") {
console.log(` ❌ 错误: ${await call.error}`);
}
console.log("");
}
})(),
]);
}
// ============================================================
// 3. 主函数
// ============================================================
async function main() {
console.log("\n" + "=".repeat(60));
console.log("🔍 Deep Agents MCP 工具集成演示");
console.log("=".repeat(60));
console.log("MCP 服务器: 百度千帆 AI 搜索");
console.log("=".repeat(60) + "\n");
// 创建带 MCP 工具的智能体
const { agent } = await createAgentWithMcp();
// 支持命令行传入自定义问题
const args = process.argv.slice(2);
if (args.length > 0) {
const customQuestion = args.join(" ");
await streamAgent(agent, customQuestion);
} else {
// 默认演示问题
const questions = [
"搜索一下今天的热点新闻有哪些",
"Deep Agents 框架最新版本是多少?",
];
for (const q of questions) {
await streamAgent(agent, q);
console.log("─".repeat(60) + "\n");
}
}
console.log("\n✅ 演示完成!");
console.log("\n💡 使用方式:");
console.log(" node 09-mcp-tools.js 你的问题");
console.log(" 例如:node 09-mcp-tools.js 今天的天气怎么样");
console.log("");
}
main().catch(console.error);
4.3 运行测试
# 默认演示
node 09-mcp-tools.js
# 自定义问题
node 09-mcp-tools.js 今天的热点新闻有哪些
运行后你会看到:
- 程序连接到千帆 MCP 服务器,加载搜索工具
- 智能体根据问题判断是否需要搜索
- 调用搜索工具,传入查询参数
- 获取搜索结果,整理后生成回答
五、MCP 工具的更多用法
5.1 stdio 类型的 MCP 服务器
除了 HTTP 方式,MCP 还支持 stdio 方式——服务器作为本地子进程运行,通过标准输入输出通信。
const client = new MultiServerMCPClient({
// 文件系统 MCP(stdio 方式)
"filesystem": {
transport: "stdio",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/directory"],
},
// GitHub MCP(stdio 方式)
"github": {
transport: "stdio",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-github"],
env: {
GITHUB_TOKEN: process.env.GITHUB_TOKEN,
},
},
});
stdio 方式的特点:
- 服务器在本地运行,延迟低
- 适合本地工具、文件系统操作
- 不需要公网访问
- 通过环境变量传递配置和密钥
5.2 工具过滤
如果 MCP 服务器提供了很多工具,但你只想让智能体用其中一部分,可以在配置中过滤:
const client = new MultiServerMCPClient({
"my-server": {
transport: "http",
url: "https://example.com/mcp",
// 只允许这些工具
allowedTools: ["search", "get_news"],
// 或者禁用某些工具
// disabledTools: ["delete_file", "format_disk"],
},
});
allowedTools:白名单,只保留列出的工具disabledTools:黑名单,移除列出的工具
5.3 MCP 工具 + 自定义工具混合使用
MCP 工具和自定义工具可以一起使用,直接放在同一个数组里就行:
import { tool } from "langchain";
import { z } from "zod";
// 自定义工具
const myCustomTool = tool(
async ({ input }) => {
return `处理结果: ${input}`;
},
{
name: "my_custom_tool",
description: "一个自定义工具",
schema: z.object({
input: z.string().describe("输入参数"),
}),
}
);
// MCP 工具
const mcpTools = await client.getTools();
// 合并使用
const agent = createDeepAgent({
model: model,
tools: [...mcpTools, myCustomTool], // 合并在一起
});
六、核心要点总结
6.1 MCP 集成三步法
- 配置:用
MultiServerMCPClient配置 MCP 服务器地址和参数 - 获取:调用
client.getTools()获取所有工具 - 注入:把工具数组传给
createDeepAgent的tools参数
6.2 MCP vs 自定义工具
| 对比项 | 自定义工具 | MCP 工具 |
|---|---|---|
| 开发方式 | 手动写函数 | 配置服务器地址即可 |
| 工具数量 | 自己写多少有多少 | 取决于 MCP 服务器 |
| 维护成本 | 自己维护代码 | 服务器方维护 |
| 灵活性 | 完全可控 | 受限于服务器提供的功能 |
| 适用场景 | 项目特定逻辑 | 通用能力(搜索、文件、数据库等) |
6.3 百度搜索使用建议
- 适合:时事新闻、最新资讯、事实核查、产品信息查询
- 不适合:纯推理、计算、代码生成等不需要外部信息的任务
- 技巧:在系统提示词中说明搜索的使用场景,智能体会更准确地判断何时调用
6.4 安全注意事项
-
API 密钥不要硬编码在代码里,用环境变量管理
-
MCP 工具的权限要控制好,不要让智能体调用危险操作
-
生产环境建议做好调用频率限制和成本监控
-
用
allowedTools/disabledTools控制工具暴露范围
七、常见问题排查
1. 连接 MCP 服务器失败
- 检查 URL 是否正确
- 确认 API 密钥有效
- 检查网络是否能访问该地址(国内服务可能需要特定网络环境)
- 确认传输方式(
transport)是否正确
2. 智能体不调用 MCP 工具
- 检查工具的 description 是否清晰描述了功能
- 在系统提示词中说明工具的使用场景
- 用户的问题要足够明确,让智能体判断需要调用工具
3. getTools() 返回空数组
- 确认 MCP 服务器是否正常运行
- 检查配置的 transport 类型是否正确
- 查看控制台的错误信息,可能是认证失败或连接超时
4. 工具调用超时
- MCP 服务器响应可能较慢,搜索类工具通常需要 2-5 秒
- 可以在配置中调整超时时间
5. stdio 服务器启动失败
- 检查 command 和 args 是否正确
- 确认依赖包已安装(比如 npx 能拉到对应的包)
- 检查环境变量是否正确设置
6. 多个 MCP 服务器的工具重名怎么办?
MultiServerMCPClient会自动给工具名加上服务器前缀- 比如服务器
qianfan-search的search工具会变成qianfan-search_search - 不会有命名冲突
下一节我们将学习 Deep Agents 的技能(Skills)体系,了解如何用渐进式披露的方式管理大量专业知识,让智能体既能拥有丰富的领域能力,又不会浪费上下文 token。