快速入门
几分钟内构建你的第一个 Deep Agent
从安装依赖到运行一个具备规划、搜索和子 Agent 能力的研究型智能体我们要构建什么
一个能自主规划、搜索、总结的研究型 Agent
传统聊天机器人只能一问一答。但现实中的研究任务需要多步推理、工具调用、上下文管理。Deep Agent 就是为此而生。
传统 LLM 调用
- 单次问答,没有规划能力
- 无法自主决定"接下来做什么"
- 长上下文管理靠手动拼接
- 复杂任务需要人类逐步指挥
Deep Agent
- 自动将任务拆解为子任务并规划执行顺序
- 自主选择工具(搜索、文件读写等)
- 内置虚拟文件系统管理大量上下文
- 可生成子 Agent 委派复杂子任务
前提条件
你必须有
- 一个模型提供商的 API Key(Gemini、OpenAI、Anthropic 等均可)
- 一个 Tavily API Key(用于搜索功能,免费注册)
- Node.js 运行环境
模型要求
- 模型必须支持 tool calling(工具调用)
- 推荐:Gemini 3.1 Pro、GPT-5.5、Claude Sonnet 4.6
- 也支持 Ollama 本地模型
可选但推荐
- LangChain Docs MCP Server(让 AI 编程助手访问最新文档)
- LangChain Skills(提升 Agent 在 LangChain 任务上的表现)
安装依赖
只需一行命令,安装核心包和搜索工具
Deep Agents 的核心包是 deepagents,配合 langchain 和 @langchain/tavily 即可快速启动。
$ npm install deepagents langchain @langchain/core @langchain/tavily
或使用其他包管理器:
$ yarn add deepagents langchain @langchain/core @langchain/tavily
$ pnpm add deepagents langchain @langchain/core @langchain/tavily
各包的作用
| 包名 | 做什么 |
|---|---|
deepagents | Deep Agent 核心,包含规划引擎和子 Agent 管理 |
langchain | LLM 调用和工具集成的基础层 |
@langchain/core | LangChain 核心抽象(消息、工具等) |
@langchain/tavily | Tavily 搜索 API 的 LangChain 封装 |
关于搜索提供商
本教程使用 Tavily 作为搜索提供商,但你可以替换为任何搜索 API:
- DuckDuckGo Search
- SerpAPI
- Brave Search
只需修改工具实现即可,Agent 代码不需要变。
配置密钥
配置你的模型提供商和搜索服务的密钥
Deep Agents 通过环境变量读取 API Key。根据你的模型提供商设置对应的变量:
Google Gemini
export GOOGLE_API_KEY="your-api-key"
export TAVILY_API_KEY="your-tavily-api-key"
OpenAI
export OPENAI_API_KEY="your-api-key"
export TAVILY_API_KEY="your-tavily-api-key"
Anthropic
export ANTHROPIC_API_KEY="your-api-key"
export TAVILY_API_KEY="your-tavily-api-key"
DeepSeek
# DeepSeek 通过 @langchain/community 的 ChatDeepSeek 接入
# 或直接使用 "deepseek:模型名" 字符串(如 deepseek:deepseek-chat)
export DEEPSEEK_API_KEY="your-api-key"
export TAVILY_API_KEY="your-tavily-api-key"
通过 @langchain/community 的 ChatDeepSeek 或以 deepseek:模型名 字符串接入。具体可用型号与参数以 DeepSeek 官方公告为准。
OpenRouter
export OPENROUTER_API_KEY="your-api-key"
export TAVILY_API_KEY="your-tavily-api-key"
Fireworks
export FIREWORKS_API_KEY="your-api-key"
export TAVILY_API_KEY="your-tavily-api-key"
Baseten
export BASETEN_API_KEY="your-api-key"
export TAVILY_API_KEY="your-tavily-api-key"
Ollama
# 本地使用:Ollama 必须在你的机器上运行
# 云端使用:设置你的 Ollama API Key 以进行托管推理
export OLLAMA_API_KEY="your-api-key"
export TAVILY_API_KEY="your-tavily-api-key"
其他提供商
# 设置你的提供商的 API Key
export <PROVIDER>_API_KEY="your-api-key"
export TAVILY_API_KEY="your-tavily-api-key"
Deep Agents 支持所有 LangChain 聊天模型,请设置你的提供商对应的 API Key。
支持的提供商
| 提供商 | 环境变量 |
|---|---|
GOOGLE_API_KEY | |
| OpenAI | OPENAI_API_KEY |
| Anthropic | ANTHROPIC_API_KEY |
| DeepSeek | DEEPSEEK_API_KEY |
| OpenRouter | OPENROUTER_API_KEY |
| Fireworks | FIREWORKS_API_KEY |
| Ollama | OLLAMA_API_KEY |
配置格式
创建 Agent 时以 provider:model 格式指定模型:
// Google Gemini
model: "google-genai:gemini-3.1-pro-preview"
// OpenAI
model: "openai:gpt-5.5"
// Anthropic
model: "anthropic:claude-sonnet-4-6"
// DeepSeek(通过 @langchain/community 的 ChatDeepSeek,或直接用 "deepseek:模型名")
model: "deepseek:deepseek-chat" // 稳妥示例:具体可用型号与参数以 DeepSeek 官方公告为准
// Ollama 本地
model: "ollama:llama3"
API key not found,请确认环境变量已正确设置。在 Windows 上使用 set 而非 export,或者使用 .env 文件配合 dotenv 包。
创建搜索工具
用 LangChain 的 tool 函数封装 Tavily 搜索能力
工具是 Agent 感知外部世界的手脚。我们用 tool() 函数把 Tavily 搜索封装成 Agent 可调用的工具。
比喻是为了帮你理解——实际上,工具不过是一段定义了 name、description 和 schema 的函数。Agent 通过 LLM 的 tool calling 能力来决定何时调用它,并非真的有"手脚"。
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { z } from "zod";
// 定义搜索工具:tool() 接收执行函数和元数据两个参数
const internetSearch = tool(
// 执行函数:每次 Agent 决定搜索时调用
async ({
query, // 搜索关键词
maxResults = 5, // 最多返回几条结果
topic = "general", // 搜索类别:general / news / finance
includeRawContent = false, // 是否包含原始网页内容(更耗 token)
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
// 创建 Tavily 搜索实例,传入 API Key 和配置
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
// _call() 执行搜索并返回结果
return await tavilySearch._call({ query });
},
// 元数据:帮助 LLM 理解工具的用途和参数
{
name: "internet_search", // Agent 调用时的工具名称
description: "Run a web search", // LLM 据此判断何时该调用此工具
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5)
.describe("Maximum number of results"),
topic: z.enum(["general", "news", "finance"])
.optional().default("general")
.describe("Search topic category"),
includeRawContent: z.boolean().optional().default(false)
.describe("Whether to include raw content"),
}),
},
);
工具代码解读
理解 tool() 函数的两个核心部分
第一部分:执行函数
即 tool() 的第一个参数,一个 async 函数:
- 接收参数:
query(搜索词)、maxResults、topic、includeRawContent - 内部创建
TavilySearch实例 - 调用
_call({ query })执行搜索 - 返回搜索结果给 Agent
第二部分:工具描述
即 tool() 的第二个参数,一个配置对象:
name:工具名称,Agent 通过它调用description:工具描述,帮助 LLM 决定何时调用schema:用 Zod 定义参数结构,LLM 据此生成合法调用
description 太模糊(如 "search stuff")会导致 LLM 在不该调用时调用,或者该调用时不调用。写清楚工具做什么、输入是什么、输出是什么。
创建智能体
用 createDeepAgent() 一行代码组装完整智能体
接下来,用 createDeepAgent() 把模型、工具和系统提示词组合在一起:
import { createDeepAgent } from "deepagents";
// 系统提示词:定义 Agent 的角色、工作方式和工具使用说明
// 这个提示词会叠加在 SDK 内置提示之上,不会替换它
const researchInstructions = `You are an expert researcher.
Your job is to conduct thorough research
and then write a polished report.
You have access to an internet search tool
as your primary means of gathering information.
## \`internet_search\`
Use this to run an internet search for a given query.
You can specify the max number of results to return,
the topic, and whether raw content should be included.
`;
const agent = createDeepAgent({
model: "google-genai:gemini-3.1-pro-preview", // 以 "provider:model" 格式指定模型
tools: [internetSearch], // Agent 会自主决定何时调用搜索
systemPrompt: researchInstructions, // 你的自定义提示叠加在 SDK 默认提示之上
});
其他模型提供商配置(点击展开)
OpenAI
import { createDeepAgent } from "deepagents";
// 系统提示词:引导 Agent 成为专业研究人员
const researchInstructions = `You are an expert researcher.
Your job is to conduct thorough research
and then write a polished report.
You have access to an internet search tool
as your primary means of gathering information.
## \`internet_search\`
Use this to run an internet search for a given query.
You can specify the max number of results to return,
the topic, and whether raw content should be included.
`;
const agent = createDeepAgent({
model: "openai:gpt-5.5",
tools: [internetSearch],
systemPrompt: researchInstructions,
});
Anthropic
import { createDeepAgent } from "deepagents";
// 系统提示词:引导 Agent 成为专业研究人员
const researchInstructions = `You are an expert researcher.
Your job is to conduct thorough research
and then write a polished report.
You have access to an internet search tool
as your primary means of gathering information.
## \`internet_search\`
Use this to run an internet search for a given query.
You can specify the max number of results to return,
the topic, and whether raw content should be included.
`;
const agent = createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
tools: [internetSearch],
systemPrompt: researchInstructions,
});
DeepSeek
import { createDeepAgent } from "deepagents";
// 系统提示词:引导 Agent 成为专业研究人员
const researchInstructions = `You are an expert researcher.
Your job is to conduct thorough research
and then write a polished report.
You have access to an internet search tool
as your primary means of gathering information.
## \`internet_search\`
Use this to run an internet search for a given query.
You can specify the max number of results to return,
the topic, and whether raw content should be included.
`;
const agent = createDeepAgent({
model: "deepseek:deepseek-chat", // 稳妥示例:具体可用型号以 DeepSeek 官方公告为准
tools: [internetSearch],
systemPrompt: researchInstructions,
});
DeepSeek 通过 @langchain/community 的 ChatDeepSeek 接入,或直接使用 deepseek:模型名 字符串。需设置 DEEPSEEK_API_KEY 环境变量。
OpenRouter
import { createDeepAgent } from "deepagents";
// 系统提示词:引导 Agent 成为专业研究人员
const researchInstructions = `You are an expert researcher.
Your job is to conduct thorough research
and then write a polished report.
You have access to an internet search tool
as your primary means of gathering information.
## \`internet_search\`
Use this to run an internet search for a given query.
You can specify the max number of results to return,
the topic, and whether raw content should be included.
`;
const agent = createDeepAgent({
model: "openrouter:anthropic/claude-sonnet-4-6",
tools: [internetSearch],
systemPrompt: researchInstructions,
});
Fireworks
import { createDeepAgent } from "deepagents";
// 系统提示词:引导 Agent 成为专业研究人员
const researchInstructions = `You are an expert researcher.
Your job is to conduct thorough research
and then write a polished report.
You have access to an internet search tool
as your primary means of gathering information.
## \`internet_search\`
Use this to run an internet search for a given query.
You can specify the max number of results to return,
the topic, and whether raw content should be included.
`;
const agent = createDeepAgent({
model: "fireworks:accounts/fireworks/models/qwen3p5-397b-a17b",
tools: [internetSearch],
systemPrompt: researchInstructions,
});
Baseten
import { createDeepAgent } from "deepagents";
// 系统提示词:引导 Agent 成为专业研究人员
const researchInstructions = `You are an expert researcher.
Your job is to conduct thorough research
and then write a polished report.
You have access to an internet search tool
as your primary means of gathering information.
## \`internet_search\`
Use this to run an internet search for a given query.
You can specify the max number of results to return,
the topic, and whether raw content should be included.
`;
const agent = createDeepAgent({
model: "baseten:zai-org/GLM-5",
tools: [internetSearch],
systemPrompt: researchInstructions,
});
Ollama
import { createDeepAgent } from "deepagents";
// 系统提示词:引导 Agent 成为专业研究人员
const researchInstructions = `You are an expert researcher.
Your job is to conduct thorough research
and then write a polished report.
You have access to an internet search tool
as your primary means of gathering information.
## \`internet_search\`
Use this to run an internet search for a given query.
You can specify the max number of results to return,
the topic, and whether raw content should be included.
`;
const agent = createDeepAgent({
model: "ollama:llama3",
tools: [internetSearch],
systemPrompt: researchInstructions,
});
model(以 provider:model 格式指定)、tools(工具数组)、systemPrompt(系统提示词,引导 Agent 的行为和角色)。就这三样,一个完整的智能体就建好了。
代码逐行解读
理解 createDeepAgent 的每个参数
model 参数
以 "provider:model" 格式传入,例如:
"google-genai:gemini-3.1-pro-preview""openai:gpt-5.5""anthropic:claude-sonnet-4-6""deepseek:deepseek-chat""ollama:llama3"
也可以传入已初始化的模型实例,以自定义参数。
tools 参数
一个包含所有工具的数组。Agent 会根据用户任务自主选择调用哪些工具、调用几次。
本例中只有 internetSearch,但你可以添加更多工具。
systemPrompt 参数
系统提示词决定 Agent 的角色和行为。写好提示词的技巧:
- 明确角色定位("expert researcher")
- 描述可用工具及使用方式
- 规定输出格式和质量标准
internet_search 工具的使用说明,这帮助 LLM 理解每个参数的用途,从而做出更好的调用决策。
运行 Agent
用 invoke() 启动 Agent,传入用户消息即可
创建好 Agent 后,用 invoke() 方法运行它。传入一个包含用户消息的对象:
const result = await agent.invoke({
messages: [{ role: "user", content: "What is langgraph?" }],
});
// 打印 Agent 的响应
console.log(result.messages[result.messages.length - 1].content);
输入格式
invoke() 接收一个对象,包含 messages 数组。每条消息有 role 和 content。
你可以传入单条消息,也可以传入完整对话历史。
输出格式
返回结果中的 messages 数组包含了完整的对话历史,包括 Agent 的所有中间步骤。
result.messages 的最后一条就是 Agent 的最终回复。
invoke()。
工作原理
Deep Agent 自动执行五个阶段
当你调用 invoke() 后,Deep Agent 会自动执行以下步骤:
1. 规划方案
用 write_todos 工具拆解任务
2. 执行研究
调用 internet_search 收集信息
3. 管理上下文
用文件系统工具存取大量数据
4. 生成子 Agent
委派复杂子任务给专门 Agent
5. 综合报告
整合研究发现为连贯响应
| 阶段 | 内置工具 | 做什么 |
|---|---|---|
| 规划 | write_todos |
将研究任务分解为可执行的子任务列表 |
| 上下文管理 | write_file / read_file |
用虚拟文件系统处理大量搜索结果,避免上下文溢出 |
| 委派 | 子 Agent 机制 | 为复杂子任务创建专门的子 Agent 并行处理 |
流式输出
实时获取 Agent 执行的每一步更新
invoke() 会等待整个任务完成后才返回。如果你需要实时监控 Agent 的执行过程,可以使用流式输出。
invoke() — 批量模式
- 等待全部完成后一次性返回
- 适合后台任务、批处理
- 用户看不到中间过程
stream() — 流式模式
- 实时推送每一步的更新
- 适合前端展示、进度追踪
- 可观察工具调用和子 Agent 工作
// 流式获取 Agent 执行过程 —— 每完成一步就推送一个事件
const stream = await agent.stream({
messages: [{ role: "user", content: "What is langgraph?" }],
});
for await (const event of stream) {
// 每个 event 包含一步更新的信息
// 事件类型包括:工具调用(tool_calls)、工具结果(tool_results)、LLM 响应等
console.log(event);
}
调试与追踪
用 LangSmith 可视化查看 Agent 的完整执行过程
当 Agent 行为不符合预期时,LangSmith 能帮你追踪每一个规划步骤、工具调用和子 Agent 委派。
LangSmith 能追踪什么
- Agent 的任务规划和分解过程
- 每次工具调用的输入和输出
- 子 Agent 的创建和委派情况
- LLM 的每次请求和响应
- Token 消耗和执行耗时
如何设置
- 注册 LangSmith 账号
- 设置环境变量:
LANGSMITH_API_KEY - 设置
LANGSMITH_TRACING=true - 运行 Agent,自动记录追踪
完整代码汇总
从零到运行的所有代码,一个文件搞定
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { z } from "zod";
import { createDeepAgent } from "deepagents";
// 1. 创建搜索工具 —— 封装 Tavily API 为 LangChain 工具格式
const internetSearch = tool(
async ({ query, maxResults = 5, topic = "general" }) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY, // 从环境变量读取密钥
topic,
});
return await tavilySearch._call({ query }); // 执行搜索并返回结果
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
}),
},
);
// 2. 创建 Deep Agent —— 传入模型、工具和系统提示词
const agent = createDeepAgent({
model: "google-genai:gemini-3.1-pro-preview",
tools: [internetSearch],
systemPrompt: "You are an expert researcher. "
+ "Conduct thorough research and write reports.",
});
// 3. 运行 —— invoke() 等待完整结果后返回
const result = await agent.invoke({
messages: [{ role: "user", content: "What is langgraph?" }],
});
// result.messages 数组包含完整对话历史,最后一条是 Agent 最终回复
console.log(result.messages[result.messages.length - 1].content);
GOOGLE_API_KEY(或你选择的提供商 Key)和 TAVILY_API_KEY 环境变量。使用 ESM 模式("type": "module" in package.json)或 .mjs 后缀。
使用 DeepSeek 的完整代码
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { z } from "zod";
import { createDeepAgent } from "deepagents";
// 1. 创建搜索工具 —— 封装 Tavily API 为 LangChain 工具格式
const internetSearch = tool(
async ({ query, maxResults = 5, topic = "general" }) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY, // 从环境变量读取密钥
topic,
});
return await tavilySearch._call({ query }); // 执行搜索并返回结果
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
}),
},
);
// 2. 创建 Deep Agent —— 使用 DeepSeek 模型
const agent = createDeepAgent({
model: "deepseek:deepseek-chat", // 稳妥示例:具体可用型号以 DeepSeek 官方公告为准
tools: [internetSearch],
systemPrompt: "You are an expert researcher. "
+ "Conduct thorough research and write reports.",
});
// 3. 运行 —— invoke() 等待完整结果后返回
const result = await agent.invoke({
messages: [{ role: "user", content: "What is langgraph?" }],
});
console.log(result.messages[result.messages.length - 1].content);
DeepSeek 通过 @langchain/community 的 ChatDeepSeek 接入,或直接使用 deepseek:模型名 字符串。需设置 DEEPSEEK_API_KEY 和 TAVILY_API_KEY 环境变量。具体可用型号与参数以 DeepSeek 官方公告为准。
下一步学什么
你已经构建了第一个 Deep Agent,接下来可以深入这些方向
自定义你的 Agent
了解自定义选项,包括自定义系统提示词、工具和子 Agent。让 Agent 更贴合你的业务需求。
必读
添加长期记忆
启用持久化记忆,让 Agent 跨对话记住用户偏好和历史信息。
进阶
部署到生产环境
使用 Managed Deep Agents 在 LangSmith 中创建、运行和管理 Deep Agent 的生产部署。
生产