“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)

推荐学习路径

  1. 第一周:理解 LLM API,写一个简单的聊天机器人
  2. 第二周:学习 Tool Use,让 AI 能调用一个工具
  3. 第三周:实现 ReAct 模式,让 AI 能自主决策
  4. 第四周:添加 MCP 支持,连接真实的服务
  5. 第五周:添加安全和监控,准备上生产

如果你觉得这篇文章有用,欢迎分享给还在 PPT 里画 AI Agent 的同事。

也欢迎在评论区分享你的 Agent 开发经历——无论是成功还是翻车,都是宝贵的经验。 🤖

记住:真正能干活的 Agent,是一行一行代码写出来的,不是 PPT 画出来的。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐