1. 项目概述:构建能自我修复的AI智能体

如果你正在尝试用AI智能体(比如OpenCode、Cursor这类工具)来帮你写代码,那你一定遇到过这个场景:智能体生成的代码跑不起来,控制台里一堆红字错误,然后你不得不像个翻译官一样,把错误日志复制粘贴回去,告诉它“这里错了,改一下”。这个“写代码-报错-人工介入-再改”的循环,始终没有真正闭合。智能体负责“写”,而“调试”这个更烧脑的活儿,依然牢牢攥在你手里。

这个问题的核心在于,智能体在运行时是“盲”的。它看不到自己执行时产生的痕迹——那些API调用、数据库查询、函数执行路径和抛出的异常。它只能根据你给的错误信息(通常还是经过你筛选和转述的)去猜测问题所在。这就像让一个医生在不看任何检查报告、只凭病人模糊的口述下诊断,效率和准确性可想而知。

那么,有没有可能让智能体自己“看”到这些运行时信息,自己诊断并修复问题呢?答案是肯定的。这篇教程要分享的,就是如何构建一个能“自我修复”的AI智能体。它不再是那个写完代码就撒手不管的“甩手掌柜”,而是一个能主动运行测试、查询自己的运行轨迹、分析失败根因,并最终修复Bug的“全栈工程师”。整个过程,无需你阅读一行日志或手动给出修复提示。

我们将通过一个具体的Demo来实现:一个存在多处Bug的“文本转SQL”应用。当测试失败时,我们的智能体会通过一个名为MCP的协议,从云端观测平台查询自己刚刚产生的运行轨迹,精准定位问题(比如调错了API、读错了响应字段、表名对不上),然后自动修复代码,直到所有测试通过。

整个技术栈的核心是三个开源工具: Monocle (用于自动埋点采集轨迹)、 Okahu Cloud (用于存储和通过MCP协议暴露轨迹数据)、以及支持MCP的 OpenCode智能体 。无论你是AI应用开发者、平台工程师,还是对智能体自治能力感兴趣的探索者,这套方案都能为你打开一扇新的大门,让你看到下一代软件开发和运维的雏形。

2. 核心思路与技术选型解析

要实现智能体的自我修复,关键在于打通“代码执行”与“运行时可观测性”之间的壁垒。传统的调试依赖于开发者在本地打断点、看日志,但这套模式对智能体不适用。我们需要一套能让智能体以编程方式“感知”自身状态的基础设施。

2.1 为什么是“轨迹”,而不是“日志”?

首先,我们要区分“日志”和“轨迹”。日志是离散的、文本化的记录,需要人类去阅读理解。而轨迹是结构化的、带有上下文关联的调用链数据。一个典型的轨迹会记录:一次LLM调用的输入输出和耗时、一次数据库查询的语句和结果、一次工具调用的参数和返回值,以及这些操作之间的父子关系。

对于智能体来说,结构化的轨迹数据远比非结构化的日志文本更有价值。它可以直接被解析成JSON,智能体可以像查询数据库一样,精确地询问:“最近一次名为 generate_sql 的工作流中,哪个LLM调用失败了?错误信息是什么?” 这为基于证据的推理奠定了基础。

2.2 技术栈深度拆解:Monocle + Okahu MCP

我们的方案建立在两个核心组件之上,它们分别解决了“数据采集”和“数据消费”的问题。

Monocle:零配置的自动埋点库 它的价值主张极其简单:一行代码,开启全链路追踪。对于使用流行LLM SDK(如OpenAI、LangChain、LlamaIndex)的应用,Monocle能自动注入埋点,捕获每一次调用,生成符合OpenTelemetry标准的轨迹数据。这意味着,你不需要在智能体生成的每一段代码里手动添加打点逻辑——事实上,你也做不到,因为代码是动态生成的。Monocle的自动注入机制,使得“可观测性”成为基础设施的一部分,而非事后添加的负担。

from monocle_apptrace import setup_monocle_telemetry
# 这一行之后,所有支持的SDK调用都会被自动追踪
setup_monocle_telemetry(workflow_name="text_to_sql_analyst")

Okahu MCP:为智能体设计的观测平台 Okahu是一个云端的AI应用可观测性平台,可以接收并存储来自Monocle的轨迹数据。但它的关键创新在于对 MCP 的支持。MCP是一个新兴的开放协议,旨在为AI智能体提供标准化的数据源访问接口。你可以把它理解为智能体世界的“API网关”或“驱动程序”。

传统的观测平台提供的是给人看的Dashboard,充满了图表和可点击的界面。智能体无法与这些界面交互。Okahu通过MCP,将同样的轨迹数据以结构化的JSON API形式暴露出来。智能体只需要像调用一个普通函数一样,请求 /okahu:get_latest_traces ,就能获取到分析问题所需的一切信息。这实现了从“Human-in-the-loop”到“Agent-in-the-loop”的范式转变。

2.3 方案优势与设计考量

选择这个组合,主要基于以下几点考量:

  1. 对生成式代码友好 :Monocle的自动埋点不依赖预定义的代码结构,完美适配智能体动态生成代码的特性。
  2. 闭环反馈 :MCP协议提供了低延迟、程序化的数据访问通道,使得“执行-观测-决策-修复”这个循环可以在秒级内完成。
  3. 证据驱动,避免幻觉 :我们为智能体设定了一条核心规则:“无轨迹,不修复”。智能体必须依据从MCP获取的具体错误轨迹来制定修复方案,而不能基于训练数据中的普遍知识进行猜测。这极大地减少了智能体“一本正经地胡说八道”,提出错误修复方案的风险。
  4. 轻量集成 :整个方案对现有代码的侵入性极低。主要配置集中在环境变量和智能体的提示词工程上,业务逻辑代码几乎不受影响。

3. 环境搭建与核心组件配置

理论讲完了,我们动手把环境搭起来。这个Demo的所有代码都是开源的,你可以完全复现。请确保你的系统已安装Python 3.10或更高版本。

3.1 前期准备与依赖安装

首先,克隆项目仓库并创建独立的Python虚拟环境,这是一个好习惯,可以避免包依赖冲突。

git clone https://github.com/Arindam200/awesome-ai-apps
cd awesome-ai-apps/mcp_ai_agents/telemetry-mcp-okahu
python3 -m venv venv
source venv/bin/activate  # Windows系统请使用 `venv\Scripts\activate`

接下来,安装核心的Python依赖包。这些包涵盖了轨迹采集、测试验证、AI模型调用和Web服务。

pip install monocle_apptrace monocle_test_tools openai fastapi pytest python-dotenv
  • monocle_apptrace : 核心的自动埋点库。
  • monocle_test_tools : 基于轨迹的测试验证框架,它能验证“是否产生了正确的轨迹”,而不仅仅是“代码是否运行”。
  • openai : 调用GPT-4o等模型的官方SDK。
  • fastapi & pytest : 用于构建Demo应用和运行测试。
  • python-dotenv : 管理环境变量。

3.2 密钥配置与数据初始化

这个Demo需要两个关键的API密钥:

  1. OpenAI API Key :用于调用GPT-4o模型生成SQL。
  2. Okahu API Key :用于将轨迹数据发送到Okahu云端,并通过MCP查询。

在项目根目录下创建一个名为 .env 的文件,填入你的密钥:

# .env 文件内容
OPENAI_API_KEY="sk-your-openai-key-here"
OPENAI_MODEL="gpt-4o"
OKAHU_API_KEY="your-okahu-key-here"
MONOCLE_EXPORTER="okahu"

关键配置解析 MONOCLE_EXPORTER=okahu 这一行至关重要。它指示Monocle库将采集到的轨迹数据直接发送到Okahu Cloud,而不是输出到本地控制台。在我们的Demo中,我们会故意屏蔽所有本地日志输出,从而强制智能体必须通过查询Okahu MCP来获取调试信息,模拟生产环境下的真实场景。

最后,运行数据库初始化脚本,创建一个包含 users orders 表的SQLite数据库,这是我们文本转SQL应用将要查询的对象。

python setup_db.py

3.3 理解预设的Bug与测试套件

为了演示的确定性和可重复性,Demo中预置了一个存在三个故意引入Bug的 analyst.py 文件。这三个Bug涵盖了从API使用错误到业务逻辑错误的典型场景:

Bug编号 问题描述 在轨迹中会看到什么
Bug #1 使用了已废弃的 client.completions.create() 方法,而不是正确的 client.chat.completions.create() API错误: "NotFoundError: /v1/completions not found for gpt-4o"
Bug #2 试图访问响应对象的 .text 属性,但OpenAI SDK返回的聊天完成对象正确的属性是 .message.content 属性错误: AttributeError ,指示 .text 不存在。
Bug #3 给LLM的提示词中描述数据库有 customers products 表,但实际数据库是 users orders 表。 SQL执行错误: "no such table: customers"

配套的测试文件 test_analyst.py 不仅测试代码功能,更关键的是使用 MonocleValidator 进行 轨迹验证 。这意味着,即使代码能跑通,但如果LLM没有被正确调用(例如因为Bug #1),导致没有生成预期的轨迹跨度,测试也会失败。这实现了对AI应用“黑盒”内部行为的“白盒”验证。

你可以随时运行 python reset_demo.py 将代码重置到最初的Bug状态,方便反复实验。

4. 自我修复智能体的实战演练

环境就绪,Bug就位,现在让我们启动智能体,观看它如何像一位老练的工程师一样,独立完成“测试-诊断-修复”的闭环。

4.1 配置智能体:赋予其“侦探”的规则

我们使用OpenCode智能体,并通过一个自定义的Agent模式( @analyst_v3 )来赋予它特定的行为规则。这个配置文件(通常位于 .opencode/agents/analyst_v3.md )是智能体行为的“宪法”,其中最关键的部分是 自我修复规则 约束条件

核心规则摘要:

  1. 测试先行 :首先运行测试套件,客观记录所有失败。
  2. 等待数据 :等待5秒,确保轨迹数据已被Okahu Cloud接收和处理。
  3. 证据查询 :通过Okahu MCP工具查询指定工作流( text_to_sql_analyst_v3 )的最新轨迹。 这是唯一允许的调试信息源
  4. 基于证据修复 :分析轨迹JSON,定位错误根本原因,并实施修复。
  5. 版本存档 :每次修复前,将当前代码存档到 versions/ 目录下,保留修改历史。
  6. 记录溯源 :记录用于诊断的轨迹ID,建立“问题-证据-修复”的可追溯链路。
  7. 循环迭代 :重复步骤1-6,直到所有测试通过。

黄金约束:“无猜测”原则

如果无法从MCP获取到相关轨迹,则立即停止并报告失败,绝不允许在无证据的情况下猜测性修复。

这条约束是防止智能体“幻觉”的防火墙。它强制智能体的每一个决策都必须有来自自身运行时产生的数据作为支撑,从而保证修复动作的准确性和可靠性。

4.2 触发自治循环:从失败到成功的全自动旅程

现在,我们向配置好的 @analyst_v3 智能体发出指令。这个提示词精心设计了任务步骤和边界:

@analyst_v3 修复这个存在Bug的文本转SQL代码库。`analyst.py`、`test_analyst.py`和`main.py`文件已存在但包含错误。
1.  运行测试:执行 `pytest test_analyst.py -v` 查看失败情况。
2.  分析轨迹:等待5秒,然后使用workflow_name='text_to_sql_analyst_v3'查询Okahu MCP。
3.  修复循环:
    - 将当前`analyst.py`存档至`versions/analyst_vN.py`
    - 基于轨迹分析修复Bug
    - 记录用于诊断的每个轨迹ID
    - 再次运行测试
    - 重复直至所有测试通过
4.  最终报告:输出一个总结表格,列出所有已修复的问题及其关联的轨迹ID。

规则:不创建调试文件。仅通过Okahu MCP轨迹进行调试。始终调用MCP工具从轨迹获取日志,不要使用终端里的本地日志。

发出指令后,你将看到一场完全自主的“外科手术”:

  1. 第一轮 :智能体运行测试,发现3处失败。它等待5秒后查询MCP,获得第一条错误轨迹,清晰地显示 NotFoundError: /v1/completions not found for gpt-4o 。它立刻明白是API方法用错了,于是将 completions.create() 改为 chat.completions.create() ,存档代码为 analyst_v1.py ,然后重新运行测试。
  2. 第二轮 :测试显示仍有2处失败。智能体再次查询MCP,看到新的轨迹中出现了 AttributeError ,指出 .text 属性不存在。它检查OpenAI SDK文档(或依靠其内部知识),将其修正为 .message.content ,存档为 analyst_v2.py
  3. 第三轮 :还剩1处失败。再次查询MCP,错误信息指向数据库层面: no such table: customers 。智能体对比轨迹中的SQL语句和提示词,发现提示词中的表名(customers/products)与实际数据库(users/orders)不匹配。它更新提示词中的表名,存档为 analyst_v3.py
  4. 终局 :所有测试通过。智能体生成一份清晰的修复报告。

整个过程中,你没有阅读任何错误日志,没有分析任何堆栈跟踪,也没有给出任何一条具体的修复提示。智能体独自完成了所有工作。

4.3 结果审查:可审计的修复报告

智能体最终输出的报告不是一句简单的“搞定”,而是一份具备可审计性的工单:

修复序号 问题描述 诊断所用的轨迹ID
1 错误的OpenAI API调用方式 trace_a1b2c3d4...
2 错误的响应对象属性访问 trace_e5f6g7h8...
3 提示词与数据库Schema不匹配 trace_i9j0k1l2...

这份报告的价值在于:

  • 可追溯 :任何一个人都可以拿着轨迹ID,去Okahu平台搜索对应的原始轨迹,亲眼看到导致修复的那个具体错误。
  • 可验证 versions/ 目录下保存了每一次迭代的代码版本,你可以逐行对比,理解智能体的修改逻辑。
  • 可信任 :因为遵守了“无猜测”原则,你知道每一个修复都有确凿的运行时证据支持,而非随机尝试。

至此,人的角色发生了根本性转变:从“调试操作员”变成了“系统监督员”。你负责设定规则、配置环境、触发任务和审计结果,而将重复性、模式化的调试工作交给了自治系统。

5. 关键要点与避坑指南

通过这个完整的Demo,我们不仅实现了一个技术原型,更验证了几个对未来AI工程化至关重要的理念。以下是我在实践和复现过程中总结的核心要点和常见问题。

5.1 成功构建自治系统的五大支柱

  1. 自动埋点非可选,而是必选项 永远不要指望智能体(或匆忙的开发者)会在生成的代码里手动添加埋点。可观测性必须像电力一样,成为即插即用的基础设施。Monocle这类零配置、自动注入的库是实现智能体自治的先决条件。在选择工具时,务必确认其是否支持你使用的LLM SDK和框架。

  2. MCP是智能体的“感官接口” 数据存在那里,和智能体能消费这些数据,是两回事。观测平台必须提供机器可读的API,而不仅仅是人机交互界面。MCP协议正在成为这个领域的事实标准。在评估观测平台时,除了看面板功能,一定要考察其是否提供或计划提供MCP兼容的接口。

  3. 用“无证据,不行动”规则锁死幻觉 这是最重要的设计原则。必须在智能体的行为准则中明确写入:禁止在缺乏运行时遥测数据的情况下进行修复。可以通过在提示词中强调,或是在Agent配置中作为硬性规则来实现。这能确保系统的输出是可靠和可解释的。

  4. 测试要验证行为,而不仅是输出 对于AI应用,传统的单元测试(给定输入,断言输出)是不够的。因为输出具有非确定性。我们需要像 Monocle Test Tools 这样的“轨迹测试”,它能验证“是否以正确的方式调用了LLM”、“是否触发了预期的工具”。这相当于对AI的“思考过程”进行断言,能捕捉到更多深层Bug。

  5. 人的角色升级:从执行者到架构师 当智能体接管了编码和调试,人的核心价值就上移了。你需要更专注于:设计智能体的行动规范和约束(提示词工程)、构建稳健的反馈循环(测试与验证体系)、以及配置和维护整个自治基础设施(如MCP服务器、轨迹存储)。这要求开发者具备更强的系统思维和架构能力。

5.2 实操中常见的坑与解决方案

问题1:智能体无法连接到Okahu MCP服务器。

  • 排查 :首先检查 .env 文件中的 OKAHU_API_KEY 是否正确,以及网络连接。最关键的一步是运行 opencode mcp auth okahu 完成MCP服务器的认证。这个命令会打开浏览器,引导你完成OAuth授权流程。没有有效的认证,后续的MCP查询都会失败。
  • 技巧 :可以将认证命令和密钥检查写入一个 setup.sh 脚本,确保任何复现Demo的人都不会遗漏这一步。

问题2:运行测试后,智能体查询MCP返回空数据或过时数据。

  • 原因 :轨迹数据从产生、导出、上传到云端可查询,有数秒的延迟。如果智能体在测试结束后立即查询,可能查不到。
  • 解决 :这就是为什么规则中明确要求“等待5秒”。这个等待时间需要根据你的网络延迟和Okahu的数据处理速度进行调整。在生产环境中,可以考虑让智能体轮询MCP接口,直到查询到非空数据为止,实现更稳健的等待。

问题3:智能体试图安装不在允许列表中的依赖包。

  • 预防 :在Agent配置中,明确列出 allowed_packages 。例如,只允许安装 monocle_apptrace, openai 等必要包。对于Demo,我们禁用了网络安装,所有依赖都已预装。在生产中,这能防止智能体引入不安全或不必要的依赖。
  • 处理 :如果遇到 ModuleNotFoundError ,智能体应首先检查是否在允许列表中,如果是则安装,否则应抛出清晰错误,而不是自行尝试安装未知包。

问题4:轨迹数据过于庞大,智能体无法有效处理。

  • 优化 :在通过MCP查询时,充分利用过滤参数。例如,只查询最近5分钟、特定工作流名称、且状态为错误的轨迹。Okahu MCP API通常支持 workflow_name , status , start_time , end_time 等过滤器。让智能体学习构造精准的查询,避免下载海量无关数据。

问题5:重置Demo后,智能体似乎“记住”了之前的修复。

  • 原理 :这通常不是智能体“记忆”,而是因为代码文件被重置了,但智能体工作区或上下文里可能还残留着之前的对话历史。
  • 解决 :最干净的方式是开启一个新的智能体会话(Session),或者在使用OpenCode时,确保提示词中包含了“忽略之前所有上下文,仅基于当前文件状态操作”的指令。对于追求绝对可重复性的演示,重启智能体进程是最可靠的方法。

构建自我修复的智能体并非一蹴而就,它需要你将可观测性提升到架构层面来考虑。这个Demo提供了一个完整的起点和经过验证的模式。接下来,你可以尝试将其应用到更复杂的场景,例如修复前端UI错误、优化数据库查询、甚至是根据性能轨迹进行代码重构。当你的智能体学会“自查自纠”时,你就真正意义上解放了生产力,迈向了一个人机协作的新阶段。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐