第九章:主流 Agent 开发框架实战 —— 站在巨人的肩膀上
9.1 为什么要用框架?
前面几章我们从零手写了 Agent 的各个模块。在实际项目中,使用成熟的框架可以:
- 节省 80% 的样板代码
- 开箱即用的工具集成、记忆管理、流式输出
- 经过社区验证的最佳实践
- 生态丰富,有大量插件和示例
JS/TS 生态中最主流的 Agent 框架:
| 框架 | 定位 | 适合场景 |
|---|---|---|
| Mastra | TypeScript Agent 全栈框架 | Agent 应用、工作流、MCP 服务 |
| Vercel AI SDK | 全栈 AI 应用开发 | Web 应用、Next.js 项目 |
| LangChain.js | 通用 Agent 开发 | 复杂 Agent、RAG、多 Agent |
| OpenAI Agents SDK | OpenAI 官方 Agent 编排 | 多 Agent 协调、Guardrails |
| MCP SDK | MCP 协议工具开发 | 标准化工具服务 |
9.2 Mastra —— TypeScript 生态最火的 Agent 框架 🔥
Mastra 是由 Gatsby 团队打造的 TypeScript Agent 框架,GitHub 22k+ stars,是目前 JS 生态中功能最完整、社区最活跃的 Agent 开发框架。
为什么选 Mastra?
- 纯 TypeScript 原生,类型安全,开发体验极佳
- 一站式:Agent + Workflow + RAG + Memory + Evals + MCP Server,全部内置
- 40+ 模型提供商,一个接口切换 OpenAI/Anthropic/Google/DeepSeek 等
- 深度集成:React、Next.js、Vercel AI SDK、CopilotKit
- 生产就绪:内置可观测性(OpenTelemetry)、评估(Evals)、日志
安装
# 推荐:用 CLI 快速创建项目
npm create mastra@latest
# 或手动安装
npm install @mastra/core @mastra/memory基础 Agent
// mastra-agent.mjs
import { Mastra } from '@mastra/core';
import { Agent } from '@mastra/core/agent';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
// 定义工具
const weatherTool = {
id: 'get_weather',
description: '获取指定城市的天气信息',
inputSchema: z.object({
city: z.string().describe('城市名称'),
}),
execute: async ({ context }) => {
const mockData = { '北京': 25, '上海': 30, '深圳': 32 };
return { city: context.city, temperature: mockData[context.city] || 20, unit: '°C' };
},
};
// 创建 Agent
const assistant = new Agent({
name: 'weather-assistant',
instructions: '你是一个天气助手,可以查询城市天气并给出穿衣建议。',
model: openai('gpt-4o'),
tools: { get_weather: weatherTool },
});
// 运行
const mastra = new Mastra({ agents: { assistant } });
const agent = mastra.getAgent('assistant');
const response = await agent.generate('北京和上海哪个更热?');
console.log(response.text);Mastra Workflow(图式工作流)
Mastra 的工作流引擎使用直观的链式语法,支持分支、并行、人工审批(Human-in-the-loop):
// mastra-workflow.mjs
import { Workflow, Step } from '@mastra/core/workflows';
import { z } from 'zod';
// 定义步骤
const analyzeStep = new Step({
id: 'analyze',
inputSchema: z.object({ requirement: z.string() }),
execute: async ({ context }) => {
// 调用 LLM 分析需求
return { analysis: `需求分析结果: ${context.requirement}` };
},
});
const codeStep = new Step({
id: 'code',
execute: async ({ context }) => {
return { code: '// 生成的代码...' };
},
});
const reviewStep = new Step({
id: 'review',
execute: async ({ context }) => {
return { approved: true, feedback: '代码质量良好' };
},
});
// 构建工作流
const devWorkflow = new Workflow({ name: 'dev-pipeline' })
.then(analyzeStep)
.then(codeStep)
.then(reviewStep);
devWorkflow.commit();
const result = await devWorkflow.execute({
triggerData: { requirement: '开发一个 REST API' },
});
console.log(result);Mastra Memory(记忆系统)
// mastra-memory.mjs
import { Agent } from '@mastra/core/agent';
import { Memory } from '@mastra/memory';
import { openai } from '@ai-sdk/openai';
// 创建带记忆的 Agent
const memory = new Memory();
const agent = new Agent({
name: 'personal-assistant',
instructions: '你是一个个人助手,记住用户的偏好和历史对话。',
model: openai('gpt-4o'),
memory, // 自动管理对话历史 + 工作记忆 + 语义记忆
});
// 多轮对话,自动管理记忆
const res1 = await agent.generate('我喜欢用 TypeScript 开发', {
threadId: 'user-123',
});
const res2 = await agent.generate('推荐一个框架吧', {
threadId: 'user-123', // 同一个 thread,Agent 记得之前的偏好
});
console.log(res2.text); // 会结合 TypeScript 偏好推荐Mastra MCP Server
Mastra 可以直接把你的 Agent 和工具暴露为 MCP Server:
// mastra-mcp-server.mjs
import { MCPServer } from '@mastra/mcp';
const server = new MCPServer({
name: 'my-tools',
version: '1.0.0',
agents: { assistant }, // 直接暴露 Agent
tools: { get_weather: weatherTool },
});
// 启动后,任何 MCP Client(Claude Desktop、VS Code 等)都能连接
await server.start();💡 Mastra 还内置了 Evals(评估) 系统,可以自动化测试 Agent 的输出质量,这对进入生产环境至关重要。
9.3 Vercel AI SDK —— 最适合 Web 应用的选择
Vercel AI SDK 是目前 JS/TS 生态中最推荐 的 AI 开发框架。API 简洁,TypeScript 支持极好。
安装
npm install ai @ai-sdk/openai
# 如果用其他模型提供商:
# npm install @ai-sdk/anthropic
# npm install @ai-sdk/google基础对话
// vercel-basic.mjs
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
const { text } = await generateText({
model: openai('gpt-4o'),
prompt: '用一句话解释什么是 JavaScript 闭包',
});
console.log(text);流式输出
// vercel-stream.mjs
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
const { textStream } = streamText({
model: openai('gpt-4o'),
prompt: '写一首关于 JavaScript 的五言绝句',
});
for await (const chunk of textStream) {
process.stdout.write(chunk);
}Agent + 工具使用
// vercel-agent.mjs
import { generateText, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod'; // Vercel AI SDK 用 zod 定义工具参数
const result = await generateText({
model: openai('gpt-4o'),
system: '你是一个有用的助手,可以使用工具帮助用户。',
prompt: '北京和上海哪个更热?',
tools: {
getWeather: tool({
description: '获取指定城市的天气信息',
parameters: z.object({
city: z.string().describe('城市名称'),
}),
execute: async ({ city }) => {
// 模拟天气 API
const data = { '北京': 25, '上海': 30 };
return { city, temperature: data[city] || 20, unit: '°C' };
},
}),
},
maxSteps: 5, // 最大迭代步数(Agent Loop)
});
console.log(result.text);
// 查看工具调用过程
for (const step of result.steps) {
if (step.toolCalls) {
for (const tc of step.toolCalls) {
console.log(` 🔧 调用 ${tc.toolName}(${JSON.stringify(tc.args)}) → ${JSON.stringify(tc.result)}`);
}
}
}结构化输出
// vercel-structured.mjs
import { generateObject } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
const { object } = await generateObject({
model: openai('gpt-4o'),
schema: z.object({
name: z.string().describe('菜名'),
ingredients: z.array(z.string()).describe('食材列表'),
cookingTime: z.number().describe('烹饪时间(分钟)'),
difficulty: z.enum(['easy', 'medium', 'hard']).describe('难度'),
steps: z.array(z.string()).describe('步骤'),
}),
prompt: '给我一个简单的西红柿炒鸡蛋食谱',
});
console.log(JSON.stringify(object, null, 2));
// 输出保证符合 schema 定义的结构多模型切换
// Vercel AI SDK 最大的优点之一:统一的 API,切换模型只需改一行
import { openai } from '@ai-sdk/openai';
import { anthropic } from '@ai-sdk/anthropic';
import { google } from '@ai-sdk/google';
// 根据任务选择模型
const models = {
fast: openai('gpt-4o-mini'), // 快速简单任务
powerful: openai('gpt-4o'), // 通用任务
code: anthropic('claude-sonnet-4-20250514'), // 代码任务
long: google('gemini-2.5-pro'), // 超长上下文
};
// 使用时只需换 model 参数
const { text } = await generateText({
model: models.code, // 换这里就行
prompt: '...',
});9.4 LangChain.js —— 功能最全的 Agent 框架
LangChain 是目前生态最完整的 Agent 框架,适合构建复杂的 Agent 系统。
安装
npm install langchain @langchain/openai @langchain/core基础使用
// langchain-basic.mjs
import { ChatOpenAI } from '@langchain/openai';
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
const model = new ChatOpenAI({
modelName: 'gpt-4o',
temperature: 0,
});
const response = await model.invoke([
new SystemMessage('你是一个 JavaScript 专家。'),
new HumanMessage('解释一下 Event Loop'),
]);
console.log(response.content);LangChain Agent + 工具
// langchain-agent.mjs
import { ChatOpenAI } from '@langchain/openai';
import { DynamicTool } from '@langchain/core/tools';
import { createReactAgent } from '@langchain/langgraph/prebuilt';
const model = new ChatOpenAI({ modelName: 'gpt-4o', temperature: 0 });
// 定义工具
const tools = [
new DynamicTool({
name: 'calculator',
description: '用于数学计算。输入数学表达式,返回计算结果。',
func: async (input) => {
try {
const sanitized = input.replace(/[^0-9+\-*/().%\s]/g, '');
const result = Function(`"use strict"; return (${sanitized})`)();
return String(result);
} catch {
return '计算错误';
}
},
}),
new DynamicTool({
name: 'get_current_time',
description: '获取当前日期和时间',
func: async () => new Date().toLocaleString('zh-CN'),
}),
];
// 创建 ReAct Agent
const agent = createReactAgent({
llm: model,
tools,
});
// 运行
const result = await agent.invoke({
messages: [{ role: 'user', content: '现在几点?计算 12345 * 67890 等于多少?' }],
});
console.log(result.messages.at(-1).content);LangChain RAG
// langchain-rag.mjs
import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
import { MemoryVectorStore } from 'langchain/vectorstores/memory';
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
// 1. 准备文档
const documents = [
'第一章:JavaScript 是一种动态类型语言...',
'第二章:Node.js 是 JavaScript 的服务端运行时...',
'第三章:Express 是最流行的 Node.js Web 框架...',
];
// 2. 分块
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 500,
chunkOverlap: 50,
});
const docs = [];
for (const text of documents) {
const chunks = await splitter.createDocuments([text]);
docs.push(...chunks);
}
// 3. 向量化并存储
const vectorStore = await MemoryVectorStore.fromDocuments(
docs,
new OpenAIEmbeddings()
);
// 4. 搜索
const results = await vectorStore.similaritySearch('Express 怎么创建路由?', 3);
console.log('搜索结果:', results.map(r => r.pageContent));
// 5. 结合 LLM 回答
const model = new ChatOpenAI({ modelName: 'gpt-4o' });
const context = results.map(r => r.pageContent).join('\n\n');
const response = await model.invoke([
{ role: 'system', content: `根据以下参考信息回答问题:\n${context}` },
{ role: 'user', content: 'Express 怎么创建路由?' },
]);
console.log(response.content);9.5 OpenAI Agents SDK —— 官方 Agent 编排方案
OpenAI 在 2025 年发布了重大 API 更新:Responses API 取代了旧的 Chat Completions + Assistants API,并推出了开源的 Agents SDK 用于多 Agent 编排。
⚠️ 重要变更:Assistants API 计划于 2026 年中停用,新项目请使用 Responses API。
Responses API(最新)
// openai-responses.mjs
import OpenAI from 'openai';
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
// OpenAI 最新的 Responses API(2025年发布)
// 内置了 Agent 功能:工具调用、代码执行、文件搜索
const response = await openai.responses.create({
model: 'gpt-4o',
input: '帮我分析这段 JSON 数据的结构',
tools: [
{ type: 'code_interpreter' }, // 内置代码执行工具
],
});
console.log(response.output_text);Responses API 内置了强大的工具:
// Responses API 内置工具套件
const response = await openai.responses.create({
model: 'gpt-4o',
input: '搜索今天的科技新闻',
tools: [
{ type: 'web_search_preview' }, // 内置网页搜索
{ type: 'file_search', // 内置文件搜索
vector_store_ids: ['vs_xxx'] },
{ type: 'code_interpreter' }, // 内置代码执行
{ type: 'computer_use_preview', // Computer Use(预览)
display_width: 1024, display_height: 768, environment: 'browser' },
],
});
console.log(response.output_text);OpenAI Agents SDK(多 Agent 编排)
OpenAI 的开源 Agents SDK 提供了多 Agent 协作的官方方案(由实验性 Swarm 项目演化而来):
# 注意:目前仅支持 Python,Node.js 版本即将推出
# pip install openai-agents
from agents import Agent, Runner, WebSearchTool, function_tool, guardrail
@function_tool
def submit_refund(item_id: str, reason: str):
# 退款逻辑
return "success"
support_agent = Agent(
name="Support",
instructions="你是客服 Agent,可以处理退款。",
tools=[submit_refund],
)
shopping_agent = Agent(
name="Shopping",
instructions="你是购物助手,可以搜索商品。",
tools=[WebSearchTool()],
)
# Triage Agent 自动路由到合适的专业 Agent
triage_agent = Agent(
name="Triage",
instructions="将用户路由到正确的 Agent。",
handoffs=[shopping_agent, support_agent], # Handoffs 任务移交
)
# 运行
output = Runner.run_sync(
starting_agent=triage_agent,
input="我想退款",
)Agents SDK 的核心特性:
- Handoffs(任务移交):Agent 间智能转交控制权
- Guardrails(安全护栏):可配置的输入/输出安全检查
- 追踪与可观测性:可视化 Agent 执行轨迹
Assistants API(即将停用)
// openai-assistant.mjs
import OpenAI from 'openai';
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
// 1. 创建 Assistant
const assistant = await openai.beta.assistants.create({
name: 'Code Helper',
instructions: '你是一个编程助手,帮助用户写 JavaScript 代码。',
model: 'gpt-4o',
tools: [{ type: 'code_interpreter' }],
});
// 2. 创建会话
const thread = await openai.beta.threads.create();
// 3. 发送消息
await openai.beta.threads.messages.create(thread.id, {
role: 'user',
content: '用 JavaScript 实现斐波那契数列,并计算前20项',
});
// 4. 运行 Assistant
const run = await openai.beta.threads.runs.createAndPoll(thread.id, {
assistant_id: assistant.id,
});
// 5. 获取结果
if (run.status === 'completed') {
const messages = await openai.beta.threads.messages.list(thread.id);
const lastMsg = messages.data[0];
console.log(lastMsg.content[0].text.value);
}9.5 框架选择指南
9.6 框架选择指南
你的需求是什么?
│
├── TypeScript Agent 应用(全功能:Agent + RAG + 记忆 + 工作流)
│ └→ Mastra(首选)
│
├── 需要与 Next.js/React 深度集成
│ └→ Vercel AI SDK(可与 Mastra 结合)
│
├── 复杂 Agent(RAG + 工具 + 多 Agent)
│ └→ LangChain.js 或 Mastra
│
├── 多 Agent 编排 + Guardrails(Python)
│ └→ OpenAI Agents SDK
│
├── 需要标准化的工具协议
│ └→ MCP SDK
│
└── Electron 桌面应用
└→ Mastra 或 Vercel AI SDK + 自建模块我的推荐
作为 JS/TS 开发者构建 Agent 应用:
- 首选 Mastra — 功能最全面的 TS Agent 框架,内置 Agent/Workflow/RAG/Memory/Evals/MCP
- Web 应用用 Vercel AI SDK — API 最简洁,Next.js 集成最好(Mastra 也基于它)
- MCP 集成用官方 MCP SDK 或 Mastra 内置支持
- 记忆系统用 Mastra Memory 或结合本地数据库自建(参考第 7 章)
9.7 实战:用 Vercel AI SDK 构建完整 Agent
// complete-agent.mjs
import { generateText, streamText, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
import fs from 'fs/promises';
import path from 'path';
// 工具定义
const agentTools = {
readFile: tool({
description: '读取文件内容',
parameters: z.object({
filePath: z.string().describe('文件路径'),
}),
execute: async ({ filePath }) => {
try {
const content = await fs.readFile(filePath, 'utf-8');
return { success: true, content };
} catch (err) {
return { success: false, error: err.message };
}
},
}),
writeFile: tool({
description: '写入文件内容',
parameters: z.object({
filePath: z.string().describe('文件路径'),
content: z.string().describe('要写入的内容'),
}),
execute: async ({ filePath, content }) => {
try {
await fs.mkdir(path.dirname(filePath), { recursive: true });
await fs.writeFile(filePath, content, 'utf-8');
return { success: true };
} catch (err) {
return { success: false, error: err.message };
}
},
}),
listDir: tool({
description: '列出目录内容',
parameters: z.object({
dirPath: z.string().describe('目录路径'),
}),
execute: async ({ dirPath }) => {
try {
const entries = await fs.readdir(dirPath, { withFileTypes: true });
return {
items: entries.map(e => ({
name: e.name,
type: e.isDirectory() ? 'dir' : 'file',
})),
};
} catch (err) {
return { error: err.message };
}
},
}),
searchInFile: tool({
description: '在文件中搜索文本',
parameters: z.object({
filePath: z.string().describe('文件路径'),
searchText: z.string().describe('要搜索的文本'),
}),
execute: async ({ filePath, searchText }) => {
try {
const content = await fs.readFile(filePath, 'utf-8');
const lines = content.split('\n');
const matches = [];
lines.forEach((line, idx) => {
if (line.toLowerCase().includes(searchText.toLowerCase())) {
matches.push({ line: idx + 1, content: line.trim() });
}
});
return { matches, total: matches.length };
} catch (err) {
return { error: err.message };
}
},
}),
};
// 串流式 Agent 执行
async function runAgent(userMessage) {
const { textStream, steps } = streamText({
model: openai('gpt-4o'),
system: `你是一个桌面编程助手 Agent。你可以读写文件、搜索代码。
帮助用户完成编程任务。在执行文件操作前,请先告知用户你将要做什么。`,
prompt: userMessage,
tools: agentTools,
maxSteps: 10,
});
// 流式输出
for await (const chunk of textStream) {
process.stdout.write(chunk);
}
console.log();
}
// 运行
await runAgent('列出当前目录下的所有文件');9.8 小结
本章你学到了:
- ✅ Mastra — TypeScript 生态最全面的 Agent 框架
- ✅ Vercel AI SDK — 最简洁的 AI 开发框架
- ✅ LangChain.js — 最全面的 Agent 框架
- ✅ OpenAI Agents SDK — 官方多 Agent 编排方案
- ✅ 框架选择指南
- ✅ 用框架构建完整 Agent 的实战
练习
- 用 Mastra 创建一个带工具和记忆的 Agent
- 用 Vercel AI SDK 实现一个带工具的对话 Agent
- 用 LangChain.js 实现一个 RAG 问答系统
- 对比不同框架的开发体验,选择你最喜欢的
下一章是本教程的重头戏 —— 用 Electron 构建桌面 AI Agent 应用!