从 PPT 到生产:手把手教你搭建一个真正能干活的 AI Agent
这篇文章探讨了如何构建真正实用的AI Agent系统。作者首先通过幽默的对比揭示了理想中与现实中AI Agent的巨大差距,指出当前大多数AI Agent项目最终沦为"高级聊天机器人"的困境。文章定义了"真正能干活"的AI Agent应具备的6项核心能力,包括理解复杂目标、自主规划步骤、多工具协作等,并提出了AI Agent的核心公式:AI Agent = LLM(大脑) + Tools(手脚)
“AI Agent 就像我的前任——PPT 里很美好,现实中一塌糊涂。”
—— 某位被 AI Agent 折磨了三个月的架构师
前言:AI Agent 的理想与现实
2025 年,Sam Altman 说这是"AI Agent 之年"。
2026 年了,我们来看看现实:
PPT 里的 AI Agent:
用户:帮我分析竞品,写一份报告,发给老板
AI Agent:好的,已完成。报告已发送,老板回复说很满意。
现实中的 AI Agent:
用户:帮我分析竞品
AI Agent:好的,我需要访问竞品网站...
AI Agent:抱歉,我无法访问外部网站
用户:那我把数据给你
AI Agent:好的,分析完成。您需要我写报告吗?
用户:是的
AI Agent:报告写好了。您需要我发送吗?
用户:是的,发给老板
AI Agent:抱歉,我无法发送邮件
用户:...
AI Agent:但我可以告诉您应该怎么发送 :)
用户:💀
这就是为什么大多数 AI Agent 项目最后都变成了"高级聊天机器人"。
但今天,我要教你如何打破这个魔咒。
上一篇我们聊了 MCP——给 AI 装上手脚的协议。
这一篇,我们来聊聊如何用这些"手脚",搭建一个真正能干活的 AI Agent。
第一章:什么是"真正能干活"的 AI Agent?
1.1 先定义一下"能干活"
// what-is-real-ai-agent.ts
// 定义"真正能干活"的AI Agent
interface RealAIAgent {
// ❌ 不是这样的
fakeCapabilities: [
"能回答问题", // 这是ChatGPT
"能生成代码", // 这是Copilot
"能执行单个命令", // 这是CLI工具
"能按固定流程执行" // 这是自动化脚本
]
// ✅ 而是这样的
realCapabilities: [
"理解复杂、模糊的目标",
"自主规划执行步骤",
"调用多个工具协作完成任务",
"处理执行过程中的异常",
"根据反馈调整策略",
"知道什么时候该问人"
]
}
// 举个例子
const taskComparison = {
简单任务: {
input: "今天天气怎么样",
chatbot: "✅ 能做",
agent: "✅ 能做(但杀鸡用牛刀)",
},
中等任务: {
input: "帮我查一下最近一周的销售数据,生成图表",
chatbot: "❌ 只能告诉你怎么做",
agent: "✅ 直接查数据库,生成图表,保存文件",
},
复杂任务: {
input: "分析我们产品的用户流失原因,提出改进建议,创建任务分配给相关人员",
chatbot: "❌ 完全做不到",
agent: "✅ 查数据→分析→写报告→创建Jira→通知相关人",
},
模糊任务: {
input: "最近产品好像有点问题,帮我看看",
chatbot: "❌ 不知道从何下手",
agent: "✅ 检查错误日志→分析用户反馈→查看监控指标→定位问题",
},
}
1.2 AI Agent 的核心公式
2026 年,业界达成了一个共识:
AI Agent = LLM + Tools + Guidance
┌─────────────────────────────────────────────────────────────┐
│ AI Agent核心公式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ LLM │ │
│ │ (大脑:理解、推理、决策) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Tools │ │
│ │ (手脚:执行具体操作) │ │
│ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │
│ │ │数据库│ │文件 │ │API │ │浏览器│ │邮件 │ ... │ │
│ │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Guidance │ │
│ │ (规则:约束、流程、安全) │ │
│ │ • 什么能做,什么不能做 │ │
│ │ • 遇到问题怎么处理 │ │
│ │ • 什么时候需要人工确认 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
缺少任何一个,都不是真正的 AI Agent:
- 没有 LLM → 只是自动化脚本
- 没有 Tools → 只是聊天机器人
- 没有 Guidance → 是个危险的定时炸弹
第二章:AI Agent 的五种编排模式
在开始写代码之前,你需要了解 AI Agent 的几种常见架构模式。
2.1 模式一:Prompt Chaining(提示链)
最简单的模式:一个任务的输出是下一个任务的输入。
// pattern-prompt-chaining.ts
// 提示链模式示例
async function promptChaining(userRequest: string) {
// 步骤1:理解用户需求
const understanding = await llm.chat(`
用户说:${userRequest}
请分析用户的核心需求是什么?
`)
// 步骤2:制定计划
const plan = await llm.chat(`
用户需求:${understanding}
请制定一个执行计划,列出需要的步骤。
`)
// 步骤3:执行计划
const execution = await llm.chat(`
执行计划:${plan}
请执行这个计划并返回结果。
`)
// 步骤4:总结结果
const summary = await llm.chat(`
执行结果:${execution}
请用简洁的语言总结给用户。
`)
return summary
}
// 优点:简单、可预测、易调试
// 缺点:不灵活、无法处理异常、链条断了就完蛋
// 适用:流程固定的简单任务
2.2 模式二:Router(路由模式)
根据输入类型,分发到不同的处理器。
// pattern-router.ts
// 路由模式示例
interface Router {
classify: (input: string) => Promise<string>
handlers: Record<string, (input: string) => Promise<string>>
}
async function routerPattern(userRequest: string) {
// 步骤1:分类用户请求
const category = await llm.chat(`
用户请求:${userRequest}
请将这个请求分类为以下类别之一:
- code_review: 代码审查相关
- data_analysis: 数据分析相关
- bug_fix: Bug修复相关
- documentation: 文档相关
- other: 其他
只返回类别名称。
`)
// 步骤2:路由到对应处理器
const handlers = {
code_review: async (req: string) => {
// 调用GitHub MCP,获取PR,进行审查
return await codeReviewAgent(req)
},
data_analysis: async (req: string) => {
// 调用数据库MCP,查询数据,生成报告
return await dataAnalysisAgent(req)
},
bug_fix: async (req: string) => {
// 调用日志MCP,分析错误,提出修复方案
return await bugFixAgent(req)
},
documentation: async (req: string) => {
// 调用文件系统MCP,读取代码,生成文档
return await documentationAgent(req)
},
other: async (req: string) => {
return await generalAgent(req)
},
}
const handler = handlers[category.trim()] || handlers.other
return await handler(userRequest)
}
// 优点:专业的事交给专业的Agent
// 缺点:分类错误会导致处理不当
// 适用:多类型任务的统一入口
2.3 模式三:Parallelization(并行模式)
同时执行多个独立任务,最后汇总结果。
// pattern-parallelization.ts
// 并行模式示例
async function parallelPattern(userRequest: string) {
// 场景:用户说"帮我全面分析一下这个项目的健康状况"
// 并行执行多个分析任务
const [
codeQuality,
securityScan,
performanceMetrics,
testCoverage,
dependencyCheck,
] = await Promise.all([
analyzeCodeQuality(), // 代码质量分析
runSecurityScan(), // 安全扫描
getPerformanceMetrics(), // 性能指标
checkTestCoverage(), // 测试覆盖率
auditDependencies(), // 依赖审计
])
// 汇总所有结果
const summary = await llm.chat(`
请根据以下分析结果,生成一份项目健康报告:
代码质量:${JSON.stringify(codeQuality)}
安全扫描:${JSON.stringify(securityScan)}
性能指标:${JSON.stringify(performanceMetrics)}
测试覆盖:${JSON.stringify(testCoverage)}
依赖审计:${JSON.stringify(dependencyCheck)}
请给出总体评分(1-10)和改进建议。
`)
return summary
}
// 优点:速度快、效率高
// 缺点:任务之间不能有依赖关系
// 适用:多维度分析、批量处理
2.4 模式四:Planner-Executor(规划-执行模式)
先规划,再执行,最经典的 Agent 模式。
// pattern-planner-executor.ts
// 规划-执行模式示例
interface Plan {
goal: string
steps: {
id: number
action: string
tool: string
params: Record<string, any>
dependsOn: number[]
}[]
}
async function plannerExecutorPattern(userRequest: string) {
// 步骤1:规划
const plan: Plan = await llm.chat(`
用户目标:${userRequest}
可用工具:
- github: 操作GitHub(list_prs, create_issue, merge_pr等)
- database: 查询数据库(query, insert, update)
- slack: 发送消息(post_message, create_channel)
- filesystem: 文件操作(read, write, list)
请制定一个执行计划,返回JSON格式:
{
"goal": "目标描述",
"steps": [
{
"id": 1,
"action": "动作描述",
"tool": "工具名",
"params": {},
"dependsOn": []
}
]
}
`)
// 步骤2:按依赖顺序执行
const results: Record<number, any> = {}
for (const step of topologicalSort(plan.steps)) {
// 检查依赖是否完成
const depsReady = step.dependsOn.every((dep) => results[dep] !== undefined)
if (!depsReady) {
throw new Error(`步骤 ${step.id} 的依赖未完成`)
}
// 执行步骤
console.log(`执行步骤 ${step.id}: ${step.action}`)
results[step.id] = await executeTool(step.tool, step.params, results)
}
// 步骤3:总结结果
return await llm.chat(`
目标:${plan.goal}
执行结果:${JSON.stringify(results)}
请总结执行情况。
`)
}
// 优点:结构清晰、可追踪、支持复杂任务
// 缺点:规划可能不准确、执行中难以调整
// 适用:目标明确的复杂任务
2.5 模式五:ReAct(推理-行动循环)
最强大也最复杂的模式:思考 → 行动 → 观察 → 再思考…
// pattern-react.ts
// ReAct模式示例
interface ReActStep {
thought: string // 思考:我应该做什么
action: string // 行动:调用什么工具
observation: string // 观察:得到了什么结果
}
async function reactPattern(userRequest: string) {
const history: ReActStep[] = []
const maxIterations = 10
for (let i = 0; i < maxIterations; i++) {
// 让LLM思考下一步
const response = await llm.chat(`
用户目标:${userRequest}
历史记录:
${history
.map(
(h) => `
思考:${h.thought}
行动:${h.action}
观察:${h.observation}
`
)
.join("\n")}
可用工具:
- search(query): 搜索信息
- read_file(path): 读取文件
- write_file(path, content): 写入文件
- run_query(sql): 执行SQL查询
- send_message(channel, text): 发送消息
- finish(answer): 完成任务并返回答案
请按以下格式回复:
思考:[你的思考过程]
行动:[工具名(参数)]
`)
// 解析LLM的回复
const { thought, action } = parseResponse(response)
// 检查是否完成
if (action.startsWith("finish(")) {
const answer = action.match(/finish\((.*)\)/)?.[1]
return answer
}
// 执行行动,获取观察结果
const observation = await executeAction(action)
// 记录这一轮
history.push({ thought, action, observation })
console.log(`
第${i + 1}轮:
💭 思考:${thought}
🔧 行动:${action}
👀 观察:${observation}
`)
}
return "达到最大迭代次数,任务未完成"
}
// 优点:灵活、自适应、能处理意外情况
// 缺点:不可预测、可能陷入循环、成本高
// 适用:探索性任务、复杂问题解决
2.6 如何选择模式?
┌─────────────────────────────────────────────────────────────┐
│ AI Agent模式选择指南 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 任务特点 推荐模式 复杂度 可控性 │
│ ───────────────────────────────────────────────────── │
│ 流程固定、步骤明确 Prompt Chaining ⭐ ⭐⭐⭐⭐⭐ │
│ 多类型任务入口 Router ⭐⭐ ⭐⭐⭐⭐ │
│ 多个独立子任务 Parallelization ⭐⭐ ⭐⭐⭐⭐ │
│ 目标明确、步骤复杂 Planner-Executor ⭐⭐⭐ ⭐⭐⭐ │
│ 目标模糊、需要探索 ReAct ⭐⭐⭐⭐ ⭐⭐ │
│ │
│ 实际项目中,通常是多种模式的组合: │
│ Router → Planner-Executor → Parallelization │
│ │
└─────────────────────────────────────────────────────────────┘
第三章:实战!搭建一个 DevOps AI Agent
说了这么多理论,来点实际的。
我们要搭建一个DevOps AI Agent,它能够:
- 监控服务健康状态
- 分析错误日志
- 自动创建 Issue
- 通知相关人员
3.1 架构设计
// devops-agent-architecture.ts
// DevOps Agent架构设计
/*
* DevOps Agent 架构
*
* ┌─────────────────────────────────────────────────────────┐
* │ 用户/触发器 │
* │ "服务好像有问题,帮我看看" │
* │ 或 定时触发/告警触发 │
* └─────────────────────────────────────────────────────────┘
* │
* ▼
* ┌─────────────────────────────────────────────────────────┐
* │ DevOps Agent │
* │ ┌─────────────────────────────────────────────────┐ │
* │ │ Orchestrator (编排器) │ │
* │ │ 使用ReAct模式进行推理和决策 │ │
* │ └─────────────────────────────────────────────────┘ │
* │ │ │
* │ ┌────────────────────┼────────────────────┐ │
* │ ▼ ▼ ▼ │
* │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
* │ │监控分析器│ │日志分析器│ │行动执行器│ │
* │ └──────────┘ └──────────┘ └──────────┘ │
* └─────────────────────────────────────────────────────────┘
* │ │ │
* ▼ ▼ ▼
* ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
* │ Datadog MCP │ │ Logs MCP │ │ GitHub MCP │
* │ Prometheus │ │ Sentry │ │ Slack MCP │
* └─────────────┘ └─────────────┘ └─────────────┘
*/
3.2 核心代码实现
// devops-agent.ts
// DevOps Agent 完整实现
import Anthropic from "@anthropic-ai/sdk"
// 定义可用的工具
const tools = [
{
name: "check_service_health",
description: "检查服务的健康状态,包括CPU、内存、响应时间等指标",
input_schema: {
type: "object",
properties: {
service_name: {
type: "string",
description: "服务名称,如 'api-gateway', 'user-service'",
},
},
required: ["service_name"],
},
},
{
name: "get_error_logs",
description: "获取指定服务最近的错误日志",
input_schema: {
type: "object",
properties: {
service_name: { type: "string" },
time_range: {
type: "string",
description: "时间范围,如 '1h', '24h', '7d'",
},
limit: { type: "number", description: "返回条数限制" },
},
required: ["service_name"],
},
},
{
name: "analyze_error_pattern",
description: "分析错误日志,找出错误模式和根因",
input_schema: {
type: "object",
properties: {
logs: { type: "string", description: "错误日志内容" },
},
required: ["logs"],
},
},
{
name: "create_github_issue",
description: "在GitHub创建Issue",
input_schema: {
type: "object",
properties: {
repo: { type: "string" },
title: { type: "string" },
body: { type: "string" },
labels: { type: "array", items: { type: "string" } },
assignees: { type: "array", items: { type: "string" } },
},
required: ["repo", "title", "body"],
},
},
{
name: "send_slack_message",
description: "发送Slack消息通知",
input_schema: {
type: "object",
properties: {
channel: { type: "string" },
message: { type: "string" },
mentions: { type: "array", items: { type: "string" } },
},
required: ["channel", "message"],
},
},
{
name: "get_recent_deployments",
description: "获取最近的部署记录",
input_schema: {
type: "object",
properties: {
service_name: { type: "string" },
limit: { type: "number" },
},
required: ["service_name"],
},
},
]
// 工具执行函数(实际项目中这些会调用真实的MCP Server)
async function executeTool(name: string, params: any): Promise<string> {
console.log(`🔧 执行工具: ${name}`)
console.log(` 参数: ${JSON.stringify(params)}`)
// 模拟工具执行结果
switch (name) {
case "check_service_health":
return JSON.stringify({
service: params.service_name,
status: "degraded",
cpu: "78%",
memory: "82%",
response_time: "2.3s (正常: <500ms)",
error_rate: "12% (正常: <1%)",
last_check: new Date().toISOString(),
})
case "get_error_logs":
return JSON.stringify({
total_errors: 1247,
sample_errors: [
{
timestamp: "2026-01-10T10:23:45Z",
level: "ERROR",
message: "Connection timeout to database: exceeded 30s",
count: 892,
},
{
timestamp: "2026-01-10T10:24:12Z",
level: "ERROR",
message: "Failed to process payment: upstream service unavailable",
count: 355,
},
],
})
case "analyze_error_pattern":
return JSON.stringify({
primary_issue: "数据库连接超时",
affected_percentage: "71%",
probable_cause: "数据库连接池耗尽或数据库服务器负载过高",
secondary_issue: "支付服务上游依赖不可用",
correlation: "数据库问题可能导致了支付服务的级联故障",
})
case "get_recent_deployments":
return JSON.stringify({
deployments: [
{
version: "v2.3.1",
deployed_at: "2026-01-10T09:15:00Z",
deployed_by: "xiaoming",
changes: "优化数据库查询,增加连接池大小",
},
{
version: "v2.3.0",
deployed_at: "2026-01-09T16:30:00Z",
deployed_by: "xiaohong",
changes: "新增批量导出功能",
},
],
})
case "create_github_issue":
return JSON.stringify({
success: true,
issue_number: 1234,
url: `https://github.com/${params.repo}/issues/1234`,
})
case "send_slack_message":
return JSON.stringify({
success: true,
channel: params.channel,
timestamp: new Date().toISOString(),
})
default:
return JSON.stringify({ error: `未知工具: ${name}` })
}
}
// DevOps Agent 主函数
async function devopsAgent(userRequest: string) {
const client = new Anthropic()
const systemPrompt = `你是一个专业的DevOps AI Agent,负责监控和维护系统健康。
你的工作流程:
1. 首先检查服务健康状态
2. 如果发现问题,获取并分析错误日志
3. 检查最近的部署记录,判断是否与部署相关
4. 根据分析结果,创建GitHub Issue记录问题
5. 通过Slack通知相关人员
注意事项:
- 在创建Issue前,确保已经充分分析了问题
- Issue标题要简洁明了,正文要包含详细的分析
- Slack通知要@相关的负责人
- 如果问题严重(错误率>10%),标记为紧急
请一步一步思考,每次只执行一个工具调用。`
const messages: any[] = [{ role: "user", content: userRequest }]
console.log("\n" + "=".repeat(60))
console.log("🤖 DevOps Agent 启动")
console.log("=".repeat(60))
console.log(`\n📝 用户请求: ${userRequest}\n`)
// ReAct循环
let iteration = 0
const maxIterations = 10
while (iteration < maxIterations) {
iteration++
console.log(`\n--- 第 ${iteration} 轮 ---`)
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 4096,
system: systemPrompt,
tools: tools,
messages: messages,
})
// 处理响应
for (const block of response.content) {
if (block.type === "text") {
console.log(`\n💭 思考: ${block.text}`)
} else if (block.type === "tool_use") {
console.log(`\n🔧 调用工具: ${block.name}`)
// 执行工具
const result = await executeTool(block.name, block.input)
console.log(`📋 结果: ${result}`)
// 将工具结果添加到消息历史
messages.push({ role: "assistant", content: response.content })
messages.push({
role: "user",
content: [
{
type: "tool_result",
tool_use_id: block.id,
content: result,
},
],
})
}
}
// 检查是否完成
if (response.stop_reason === "end_turn") {
const finalText = response.content.find((b) => b.type === "text")
if (finalText) {
console.log("\n" + "=".repeat(60))
console.log("✅ 任务完成")
console.log("=".repeat(60))
console.log(`\n${finalText.text}`)
return finalText.text
}
}
}
return "达到最大迭代次数"
}
// 运行示例
async function main() {
await devopsAgent("user-service好像有问题,帮我看看是怎么回事")
}
main().catch(console.error)
3.3 运行效果演示
============================================================
🤖 DevOps Agent 启动
============================================================
📝 用户请求: user-service好像有问题,帮我看看是怎么回事
--- 第 1 轮 ---
💭 思考: 用户反馈user-service可能有问题,我需要先检查服务的健康状态。
🔧 调用工具: check_service_health
📋 结果: {"service":"user-service","status":"degraded","cpu":"78%",
"memory":"82%","response_time":"2.3s","error_rate":"12%"}
--- 第 2 轮 ---
💭 思考: 服务状态是degraded,错误率高达12%,响应时间也很慢。
我需要获取错误日志来分析具体原因。
🔧 调用工具: get_error_logs
📋 结果: {"total_errors":1247,"sample_errors":[
{"message":"Connection timeout to database","count":892},
{"message":"Failed to process payment","count":355}]}
--- 第 3 轮 ---
💭 思考: 主要是数据库连接超时问题。让我检查最近的部署记录,
看看是否与最近的变更有关。
🔧 调用工具: get_recent_deployments
📋 结果: {"deployments":[{"version":"v2.3.1","deployed_at":"2026-01-10T09:15:00Z",
"changes":"优化数据库查询,增加连接池大小"}]}
--- 第 4 轮 ---
💭 思考: 今天早上9:15有一次部署,修改了数据库连接池。
问题很可能与这次部署有关。我需要创建Issue记录这个问题。
🔧 调用工具: create_github_issue
📋 结果: {"success":true,"issue_number":1234}
--- 第 5 轮 ---
💭 思考: Issue已创建。由于错误率超过10%,这是紧急问题,
我需要立即通知相关人员。
🔧 调用工具: send_slack_message
📋 结果: {"success":true,"channel":"#ops-alerts"}
============================================================
✅ 任务完成
============================================================
## 分析报告
### 问题概述
user-service 当前处于降级状态,错误率达到12%(正常<1%)。
### 根因分析
1. **主要问题**:数据库连接超时(占71%的错误)
2. **次要问题**:支付服务上游依赖不可用(级联故障)
3. **可能原因**:今天09:15的部署(v2.3.1)修改了数据库连接池配置
### 已采取行动
1. ✅ 创建GitHub Issue #1234 记录问题详情
2. ✅ 通过Slack #ops-alerts 通知了 @xiaoming @oncall-team
### 建议
1. 检查v2.3.1的连接池配置是否正确
2. 考虑回滚到v2.3.0
3. 检查数据库服务器负载情况
看到了吗?这才是真正能干活的 AI Agent。
它不是告诉你"你应该检查一下日志",而是直接帮你检查了。
第四章:让 Agent 更可靠的 5 个技巧
4.1 技巧一:结构化输出
让 LLM 返回结构化数据,而不是自由文本。
// tip-structured-output.ts
// 结构化输出技巧
// ❌ 不好的做法:让LLM自由发挥
const badPrompt = `
分析这个错误日志,告诉我问题是什么。
`
// LLM可能返回:
// "嗯,看起来是数据库的问题,可能是连接池不够用了,
// 也可能是查询太慢了,建议你检查一下..."
// 这种输出很难程序化处理
// ✅ 好的做法:要求结构化输出
const goodPrompt = `
分析这个错误日志,返回JSON格式:
{
"primary_issue": "主要问题(一句话)",
"severity": "low|medium|high|critical",
"affected_services": ["受影响的服务列表"],
"probable_causes": ["可能的原因列表"],
"recommended_actions": ["建议的行动列表"]
}
只返回JSON,不要其他内容。
`
// 更进一步:使用工具定义来强制结构化
const analysisToolDefinition = {
name: "report_analysis",
description: "报告错误分析结果",
input_schema: {
type: "object",
properties: {
primary_issue: { type: "string" },
severity: { enum: ["low", "medium", "high", "critical"] },
affected_services: { type: "array", items: { type: "string" } },
probable_causes: { type: "array", items: { type: "string" } },
recommended_actions: { type: "array", items: { type: "string" } },
},
required: ["primary_issue", "severity", "probable_causes"],
},
}
4.2 技巧二:失败重试与降级
Agent 执行过程中会遇到各种问题,要有应对策略。
// tip-retry-fallback.ts
// 失败重试与降级策略
interface RetryConfig {
maxRetries: number
backoffMs: number
fallbackAction?: () => Promise<any>
}
async function executeWithRetry(
action: () => Promise<any>,
config: RetryConfig
): Promise<any> {
let lastError: Error | null = null
for (let attempt = 1; attempt <= config.maxRetries; attempt++) {
try {
return await action()
} catch (error) {
lastError = error as Error
console.log(`⚠️ 第${attempt}次尝试失败: ${lastError.message}`)
if (attempt < config.maxRetries) {
const waitTime = config.backoffMs * Math.pow(2, attempt - 1)
console.log(` 等待 ${waitTime}ms 后重试...`)
await sleep(waitTime)
}
}
}
// 所有重试都失败了
if (config.fallbackAction) {
console.log(`🔄 执行降级策略...`)
return await config.fallbackAction()
}
throw lastError
}
// 使用示例
async function getServiceHealth(serviceName: string) {
return executeWithRetry(
() => mcpClient.call("check_service_health", { service_name: serviceName }),
{
maxRetries: 3,
backoffMs: 1000,
fallbackAction: async () => {
// 降级:返回缓存的数据或默认值
console.log("使用缓存的健康数据")
return getCachedHealthData(serviceName)
},
}
)
}
4.3 技巧三:人机协作检查点
关键操作前,让人类确认。
// tip-human-checkpoint.ts
// 人机协作检查点
interface CheckpointConfig {
requireConfirmation: boolean
timeout: number // 等待确认的超时时间
defaultAction: "proceed" | "abort"
}
const checkpointRules: Record<string, CheckpointConfig> = {
// 读取操作:不需要确认
read_file: {
requireConfirmation: false,
timeout: 0,
defaultAction: "proceed",
},
query_database: {
requireConfirmation: false,
timeout: 0,
defaultAction: "proceed",
},
// 创建操作:需要确认
create_issue: {
requireConfirmation: true,
timeout: 60000,
defaultAction: "abort",
},
send_message: {
requireConfirmation: true,
timeout: 60000,
defaultAction: "abort",
},
// 危险操作:必须确认,无默认通过
delete_file: {
requireConfirmation: true,
timeout: 120000,
defaultAction: "abort",
},
merge_pr: {
requireConfirmation: true,
timeout: 120000,
defaultAction: "abort",
},
deploy_service: {
requireConfirmation: true,
timeout: 300000,
defaultAction: "abort",
},
}
async function executeWithCheckpoint(
toolName: string,
params: any,
context: string
): Promise<any> {
const config = checkpointRules[toolName]
if (!config?.requireConfirmation) {
return await executeTool(toolName, params)
}
// 需要人工确认
console.log("\n" + "⚠️".repeat(20))
console.log(`\n🛑 需要确认以下操作:`)
console.log(` 工具: ${toolName}`)
console.log(` 参数: ${JSON.stringify(params, null, 2)}`)
console.log(` 上下文: ${context}`)
console.log(
`\n 等待确认中... (${config.timeout / 1000}秒后${
config.defaultAction === "proceed" ? "自动执行" : "自动取消"
})`
)
const confirmed = await waitForConfirmation(config.timeout)
if (confirmed) {
console.log(`✅ 已确认,执行操作`)
return await executeTool(toolName, params)
} else {
console.log(`❌ 操作已取消`)
return { cancelled: true, reason: "用户取消或超时" }
}
}
4.4 技巧四:上下文管理
长对话中,要管理好上下文,避免 token 爆炸。
// tip-context-management.ts
// 上下文管理策略
interface ContextManager {
maxTokens: number
messages: Message[]
summary: string
}
class SmartContextManager {
private maxTokens = 100000
private messages: Message[] = []
private summary = ""
addMessage(message: Message) {
this.messages.push(message)
this.pruneIfNeeded()
}
private async pruneIfNeeded() {
const currentTokens = this.estimateTokens()
if (currentTokens > this.maxTokens * 0.8) {
// 策略1:总结旧消息
const oldMessages = this.messages.slice(0, -10)
const newSummary = await this.summarize(oldMessages)
// 策略2:保留最近的消息
this.messages = this.messages.slice(-10)
// 策略3:将总结作为系统消息
this.summary = newSummary
console.log(
`📝 上下文已压缩: ${currentTokens} → ${this.estimateTokens()} tokens`
)
}
}
private async summarize(messages: Message[]): Promise<string> {
const response = await llm.chat(`
请总结以下对话的关键信息,保留:
1. 用户的原始目标
2. 已完成的操作和结果
3. 发现的问题和结论
4. 待处理的事项
对话内容:
${messages.map((m) => `${m.role}: ${m.content}`).join("\n")}
`)
return response
}
getContext(): { system: string; messages: Message[] } {
return {
system: this.summary ? `历史总结:${this.summary}` : "",
messages: this.messages,
}
}
}
4.5 技巧五:可观测性
让 Agent 的行为可追踪、可调试。
// tip-observability.ts
// Agent可观测性
interface AgentTrace {
traceId: string
startTime: Date
endTime?: Date
userRequest: string
steps: AgentStep[]
finalResult?: any
error?: string
}
interface AgentStep {
stepId: number
timestamp: Date
type: "thought" | "tool_call" | "tool_result" | "error"
content: any
duration?: number
tokenUsage?: { input: number; output: number }
}
class AgentTracer {
private traces: Map<string, AgentTrace> = new Map()
startTrace(userRequest: string): string {
const traceId = crypto.randomUUID()
this.traces.set(traceId, {
traceId,
startTime: new Date(),
userRequest,
steps: [],
})
return traceId
}
addStep(traceId: string, step: Omit<AgentStep, "stepId" | "timestamp">) {
const trace = this.traces.get(traceId)
if (trace) {
trace.steps.push({
...step,
stepId: trace.steps.length + 1,
timestamp: new Date(),
})
}
}
endTrace(traceId: string, result?: any, error?: string) {
const trace = this.traces.get(traceId)
if (trace) {
trace.endTime = new Date()
trace.finalResult = result
trace.error = error
// 输出追踪报告
this.printTraceReport(trace)
// 发送到监控系统
this.sendToMonitoring(trace)
}
}
private printTraceReport(trace: AgentTrace) {
console.log("\n" + "=".repeat(60))
console.log("📊 Agent执行追踪报告")
console.log("=".repeat(60))
console.log(`Trace ID: ${trace.traceId}`)
console.log(`用户请求: ${trace.userRequest}`)
console.log(
`总耗时: ${trace.endTime!.getTime() - trace.startTime.getTime()}ms`
)
console.log(`执行步骤: ${trace.steps.length}`)
console.log(`状态: ${trace.error ? "❌ 失败" : "✅ 成功"}`)
console.log("\n步骤详情:")
for (const step of trace.steps) {
const icon =
step.type === "thought"
? "💭"
: step.type === "tool_call"
? "🔧"
: step.type === "tool_result"
? "📋"
: "❌"
console.log(
` ${icon} [${step.stepId}] ${step.type}: ${JSON.stringify(
step.content
).slice(0, 100)}...`
)
}
}
}
第五章:常见坑与避坑指南
5.1 坑一:无限循环
Agent 陷入"思考 → 行动 → 思考 → 行动…"的死循环。
// pitfall-infinite-loop.ts
// 无限循环问题与解决方案
// ❌ 问题场景
const badAgent = async () => {
while (true) { // 危险!
const response = await llm.chat(...)
if (response.includes("完成")) break
// 如果LLM永远不说"完成"呢?
}
}
// ✅ 解决方案
const safeAgent = async () => {
const maxIterations = 15
const maxTime = 5 * 60 * 1000 // 5分钟
const startTime = Date.now()
for (let i = 0; i < maxIterations; i++) {
// 检查时间限制
if (Date.now() - startTime > maxTime) {
return { status: "timeout", message: "执行超时" }
}
const response = await llm.chat(...)
// 检查是否完成
if (response.stop_reason === "end_turn") {
return { status: "success", result: response }
}
// 检查是否在重复相同的操作
if (isRepeatingAction(response, history)) {
return { status: "stuck", message: "检测到重复操作,可能陷入循环" }
}
}
return { status: "max_iterations", message: "达到最大迭代次数" }
}
5.2 坑二:幻觉工具调用
LLM 调用不存在的工具,或者用错误的参数。
// pitfall-hallucinated-tools.ts
// 幻觉工具调用问题
// ❌ 问题场景
// LLM可能会"发明"工具:
// "我来调用 hack_into_system() 工具..."
// 或者用错参数:
// "调用 send_email(to: 123)" // to应该是字符串
// ✅ 解决方案:严格验证
function validateToolCall(toolName: string, params: any): ValidationResult {
// 1. 检查工具是否存在
const tool = availableTools.find((t) => t.name === toolName)
if (!tool) {
return { valid: false, error: `工具 "${toolName}" 不存在` }
}
// 2. 验证参数schema
const schemaValidation = validateSchema(params, tool.input_schema)
if (!schemaValidation.valid) {
return { valid: false, error: `参数验证失败: ${schemaValidation.error}` }
}
// 3. 检查参数值的合理性
const valueValidation = validateValues(toolName, params)
if (!valueValidation.valid) {
return { valid: false, error: `参数值不合理: ${valueValidation.error}` }
}
return { valid: true }
}
// 在执行前验证
async function safeExecuteTool(toolName: string, params: any) {
const validation = validateToolCall(toolName, params)
if (!validation.valid) {
// 不执行,而是告诉LLM错误
return {
error: true,
message: validation.error,
suggestion: "请检查工具名称和参数是否正确",
}
}
return await executeTool(toolName, params)
}
5.3 坑三:成本失控
Agent 跑起来很爽,账单来了很痛。
// pitfall-cost-control.ts
// 成本控制策略
interface CostLimits {
maxTokensPerRequest: number
maxTokensPerSession: number
maxTokensPerDay: number
maxToolCallsPerSession: number
}
class CostController {
private limits: CostLimits = {
maxTokensPerRequest: 4096,
maxTokensPerSession: 50000,
maxTokensPerDay: 500000,
maxToolCallsPerSession: 20,
}
private usage = {
sessionTokens: 0,
dailyTokens: 0,
toolCalls: 0,
}
checkAndUpdate(tokens: number, isToolCall: boolean): boolean {
// 检查是否超限
if (this.usage.sessionTokens + tokens > this.limits.maxTokensPerSession) {
console.warn("⚠️ 会话token限制已达到")
return false
}
if (this.usage.dailyTokens + tokens > this.limits.maxTokensPerDay) {
console.warn("⚠️ 每日token限制已达到")
return false
}
if (
isToolCall &&
this.usage.toolCalls >= this.limits.maxToolCallsPerSession
) {
console.warn("⚠️ 工具调用次数限制已达到")
return false
}
// 更新使用量
this.usage.sessionTokens += tokens
this.usage.dailyTokens += tokens
if (isToolCall) this.usage.toolCalls++
return true
}
getUsageReport(): string {
return `
会话Token: ${this.usage.sessionTokens}/${this.limits.maxTokensPerSession}
每日Token: ${this.usage.dailyTokens}/${this.limits.maxTokensPerDay}
工具调用: ${this.usage.toolCalls}/${this.limits.maxToolCallsPerSession}
`
}
}
第六章:2026 年 AI Agent 框架选型
6.1 主流框架对比
┌─────────────────────────────────────────────────────────────┐
│ 2026年AI Agent框架对比 │
├─────────────────────────────────────────────────────────────┤
│ │
│ LangGraph (LangChain) │
│ ├─ 特点:图结构工作流,状态管理强大 │
│ ├─ 优点:灵活、可视化、生态丰富 │
│ ├─ 缺点:学习曲线陡峭、过度抽象 │
│ └─ 适合:复杂工作流、需要精细控制的场景 │
│ │
│ CrewAI │
│ ├─ 特点:多Agent协作,角色扮演 │
│ ├─ 优点:简单直观、多Agent场景友好 │
│ ├─ 缺点:单Agent场景过于复杂 │
│ └─ 适合:需要多个专业Agent协作的场景 │
│ │
│ AutoGen (Microsoft) │
│ ├─ 特点:对话式多Agent、代码执行 │
│ ├─ 优点:微软背书、企业级支持 │
│ ├─ 缺点:配置复杂、文档不够清晰 │
│ └─ 适合:企业级应用、需要代码执行的场景 │
│ │
│ 原生SDK (Anthropic/OpenAI) │
│ ├─ 特点:直接使用API,无框架 │
│ ├─ 优点:简单、可控、无依赖 │
│ ├─ 缺点:需要自己实现很多功能 │
│ └─ 适合:简单场景、学习理解原理 │
│ │
└─────────────────────────────────────────────────────────────┘
6.2 我的建议
// framework-recommendation.ts
// 框架选择建议
const frameworkRecommendation = {
刚开始学习: {
recommendation: "原生SDK",
reason: "理解原理最重要,框架会掩盖细节",
},
简单的单Agent应用: {
recommendation: "原生SDK 或 LangGraph",
reason: "不需要复杂框架,保持简单",
},
复杂工作流: {
recommendation: "LangGraph",
reason: "图结构适合复杂流程,状态管理强大",
},
多Agent协作: {
recommendation: "CrewAI 或 AutoGen",
reason: "专门为多Agent设计,开箱即用",
},
企业级生产环境: {
recommendation: "LangGraph + 自定义封装",
reason: "需要可观测性、安全性、可维护性",
},
快速原型验证: {
recommendation: "CrewAI",
reason: "上手快,概念直观",
},
}
// 最重要的建议:
// 不要为了用框架而用框架
// 先理解原理,再选择工具
第七章:从 Demo 到生产的 Checklist
7.1 上线前必须检查的事项
┌─────────────────────────────────────────────────────────────┐
│ AI Agent生产环境Checklist │
├─────────────────────────────────────────────────────────────┤
│ │
│ 🔒 安全性 │
│ □ 所有工具都有权限控制 │
│ □ 敏感操作需要人工确认 │
│ □ API密钥安全存储(不在代码中) │
│ □ 输入验证和输出过滤 │
│ □ 审计日志完整 │
│ │
│ 💰 成本控制 │
│ □ Token使用量限制 │
│ □ 工具调用次数限制 │
│ □ 成本监控和告警 │
│ □ 异常使用检测 │
│ │
│ 🛡️ 可靠性 │
│ □ 超时处理 │
│ □ 重试机制 │
│ □ 降级策略 │
│ □ 错误处理和恢复 │
│ □ 最大迭代次数限制 │
│ │
│ 📊 可观测性 │
│ □ 请求追踪(Trace ID) │
│ □ 性能指标监控 │
│ □ 错误率监控 │
│ □ 用户反馈收集 │
│ │
│ 🧪 测试 │
│ □ 单元测试覆盖核心逻辑 │
│ □ 集成测试覆盖工具调用 │
│ □ 端到端测试覆盖主要场景 │
│ □ 压力测试验证并发能力 │
│ □ 混沌测试验证容错能力 │
│ │
│ 📝 文档 │
│ □ 架构文档 │
│ □ API文档 │
│ □ 运维手册 │
│ □ 故障处理指南 │
│ │
└─────────────────────────────────────────────────────────────┘
7.2 监控指标建议
// production-metrics.ts
// 生产环境监控指标
interface AgentMetrics {
// 性能指标
performance: {
avgResponseTime: number // 平均响应时间
p95ResponseTime: number // P95响应时间
avgIterations: number // 平均迭代次数
avgToolCalls: number // 平均工具调用次数
}
// 成功率指标
reliability: {
successRate: number // 任务成功率
errorRate: number // 错误率
timeoutRate: number // 超时率
humanEscalationRate: number // 人工介入率
}
// 成本指标
cost: {
avgTokensPerRequest: number // 每请求平均token
dailyTokenUsage: number // 每日token使用量
dailyCost: number // 每日成本
costPerSuccessfulTask: number // 每成功任务成本
}
// 用户满意度
satisfaction: {
thumbsUpRate: number // 点赞率
thumbsDownRate: number // 点踩率
retryRate: number // 重试率(用户不满意重新问)
}
}
// 告警阈值
const alertThresholds = {
errorRate: 0.05, // 错误率 > 5% 告警
p95ResponseTime: 30000, // P95 > 30秒 告警
dailyCost: 1000, // 日成本 > $1000 告警
humanEscalationRate: 0.3, // 人工介入率 > 30% 告警
}
结语:AI Agent 的正确期望
写到最后,我想说几句掏心窝子的话。
2026 年 AI Agent 的真实水平
能做到的:
- 自动化重复性的工作流程
- 辅助人类做决策
- 处理结构化的任务
- 7x24 小时不间断工作
还做不到的:
- 完全替代人类判断
- 处理高度模糊的任务
- 在没有人类监督下处理关键业务
- 100%可靠
正确的使用姿势
┌─────────────────────────────────────────────────────────────┐
│ AI Agent使用心态 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ❌ 错误期望: │
│ "AI Agent可以完全替代人,我可以躺平了" │
│ │
│ ✅ 正确期望: │
│ "AI Agent是一个能力很强但需要监督的实习生" │
│ │
│ 它可以: │
│ • 帮你做大量重复性工作 │
│ • 在你指导下完成复杂任务 │
│ • 7x24小时待命 │
│ • 不会抱怨、不会请假 │
│ │
│ 但你需要: │
│ • 给它明确的指导和边界 │
│ • 审核它的关键决策 │
│ • 处理它搞不定的情况 │
│ • 为它的错误负责 │
│ │
└─────────────────────────────────────────────────────────────┘
最后的话
AI Agent 不是魔法,它是工具。
一个强大的工具,但仍然是工具。
会用工具的人,效率是不会用的 10 倍。
但工具永远不会替代使用工具的人。
所以,与其担心被 AI 取代,不如学会驾驭 AI。
从今天开始,搭建你的第一个真正能干活的 AI Agent 吧。
附录:快速开始模板
最小可用 Agent 模板
// minimal-agent-template.ts
// 最小可用的AI Agent模板
import Anthropic from "@anthropic-ai/sdk"
const client = new Anthropic()
const tools = [
// 在这里定义你的工具
]
async function runAgent(userRequest: string) {
const messages = [{ role: "user", content: userRequest }]
for (let i = 0; i < 10; i++) {
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 4096,
tools,
messages,
})
// 处理工具调用
for (const block of response.content) {
if (block.type === "tool_use") {
const result = await executeTool(block.name, block.input)
messages.push({ role: "assistant", content: response.content })
messages.push({
role: "user",
content: [
{ type: "tool_result", tool_use_id: block.id, content: result },
],
})
}
}
if (response.stop_reason === "end_turn") {
return response.content.find((b) => b.type === "text")?.text
}
}
}
// 使用
runAgent("你的任务描述").then(console.log)
推荐学习路径
- 第一周:理解 LLM API,写一个简单的聊天机器人
- 第二周:学习 Tool Use,让 AI 能调用一个工具
- 第三周:实现 ReAct 模式,让 AI 能自主决策
- 第四周:添加 MCP 支持,连接真实的服务
- 第五周:添加安全和监控,准备上生产
如果你觉得这篇文章有用,欢迎分享给还在 PPT 里画 AI Agent 的同事。
也欢迎在评论区分享你的 Agent 开发经历——无论是成功还是翻车,都是宝贵的经验。 🤖
记住:真正能干活的 Agent,是一行一行代码写出来的,不是 PPT 画出来的。
更多推荐




所有评论(0)