写在前面
先说代价:这套系统在调试阶段烧掉了数千美金的 Token。
但我认为值得写出来。因为这不是一个 demo,是在企业内部真实系统上跑通的端到端流程------Jira 里的一条 Bug,经过 AI 自动分析、修代码、做 Code Review、跑 SonarQube 扫描、执行单元测试、提交到 Gerrit,一路推进到 CI/CD 验证,最后回写评论到 Jira。
整个过程 AI 驱动,人只在关键节点做裁判。
这篇文章是对这套系统的完整复盘。包括它怎么设计的、哪些跑通了、哪些失败了、遭遇了哪些工程难题,以及我是怎么解决的。
为什么要做这件事
软件工程里有一类工作,每天在消耗大量人力,但流程高度标准化:Bug 修复。
一个典型的 Bug 处理链路是这样的:
收到 Bug 单 → 看日志 → 找根因 → 改代码 → 自测 → CR → 静态扫描
→ 单测 → 提交 → 等 CI → 加 Reviewer → 等 CR → 合入 → 更新 Jira
每一步都有固定动作,都需要工具交互,都依赖一定的经验积累。这是 AI Agent 天然适合介入的场景。
问题在于:这是一条 12+ 节点的长链路,涉及 Jira、日志系统、代码仓库、代码规范、Gerrit、CI/CD 流水线多个企业系统,任何一个环节的工具失败都可能让整个流程中断。
我花了相当长的时间,在 OpenClaw 平台上设计并调试了这套工作流,把它从纸面设计变成了真实可运行的系统。
系统架构:三层拆解
整套系统由三层组成:Skills(技能) 、Workflow(工作流) 、Platform(平台)。
css
┌────────────────────────────────────────────────┐
│ OpenClaw Platform │
│ (企业级 AI Coding Assistant,Claude 驱动) │
└──────────────────┬─────────────────────────────┘
│
┌──────────────────▼─────────────────────────────┐
│ Bug E2E Workflow │
│ 工作流定义:节点顺序、分支逻辑、重试策略 │
│ 人工确认门:A / B / C 三个关键决策点 │
└──────────────────┬─────────────────────────────┘
│
┌──────────────────▼─────────────────────────────┐
│ Skills │
│ 每个节点背后一个可独立运行的 AI 技能 │
│ jira-communication / rnd-automotive-issue- │
│ analyzer / write-code / ph-code-review / │
│ ph-sonar-scan / ph-junit-ut / commit-format / │
│ gerrit-verify / ... │
└────────────────────────────────────────────────┘
Skills 是原子单元。每个 Skill 对应一个具体能力,有独立的 SKILL.md 定义其上下文、输入输出规范、执行步骤。Agent 在执行时读取对应的 Skill 文档,按规范行动。
Workflow 是编排层。在 OpenClaw 中定义了节点的执行顺序、条件分支(如 Code Review 不通过时的重试路径)、人工确认触发点,以及跨 session 的状态管理。
Platform 是 OpenClaw,一套基于 Claude 的企业级 AI 编码助手,支持多 Agent 并发、子 Agent 调用、工作区持久化、工作流编排等能力。
完整工作流:12 个节点
工作流从收到 Bug 单开始,到 Jira 更新结束,中间经过以下节点:
| # | 节点 | 对应 Skill | 状态 |
|---|---|---|---|
| 1 | 获取 Bug 信息与日志 | jira-communication |
✅ |
| 2 | 分析 Bug 根因 | rnd-automotive-issue-analyzer |
✅ |
| 3 | 拉取源码 | code-fetch |
✅ |
| 4 | 修复代码 | write-android-code |
✅ |
| 5 | Code Review | ph-code-review |
✅ |
| 6 | 静态代码扫描 | ph-sonar-scan |
✅ |
| 7 | 单元测试生成与执行 | ph-junit-ut |
✅ |
| 8 | 提交代码 | commit-format |
✅ |
| 9 | CI/CD Verify 结果轮询 | gerrit-verify |
✅ |
| 10 | Gerrit 添加 Reviewer | --- | ✅ |
| 11 | 自动化回归测试 | --- | ✅ |
| 12 | Jira 回写评论 | jira-communication |
✅ |
一个节点背后不只是"调用 API"这么简单。以分析 Bug 根因为例:
- 从 Jira 下载日志附件(通常是
.zip) - 解压,定位关键日志文件
- 调用
rnd-automotive-issue-analyzer,这个 Skill 专门针对车载 Android 系统的崩溃、黑屏、系统稳定性问题做了定制化的分析逻辑 - 输出根因判断、涉及模块、可能的修复方向
然后才是代码修复阶段。
**为什么"拉取源码"节点是最难的?** 要自动从 Bug 描述里推断出对应的代码仓库,需要一份"模块 → 代码仓库"的映射表,并且要求 Bug 单在创建时填写了准确的模块信息。此外,有些代码仓极大,如果 Agent 每次都全量拉取,效率极低;但如果缓存代码,工作区空间管理又是一个复杂问题。这个节点目前处于跨团队评估阶段(研发效能 + IT + 开发 + 测试)。
实测:6 个典型场景
光说设计没有意义,真正有价值的是实测时发生了什么。我选了 6 个最有代表性的场景做记录。
Case 1:最接近理想状态的一次完整跑通
这是最让我满意的一次执行。工作流按预期完整走完:
css
获取 Bug 信息
→ 下载日志 → 解压 → 分析根因
→ 修改代码
→ Code Review(通过)
→ SonarQube 扫描
→ 单元测试
→ Commit to Gerrit
→ 定时轮询 Verify 状态
→ Gerrit 添加 Reviewer
→ Jira 添加 Comment
12 个节点,全程 AI 驱动,无人工介入。最终 Gerrit MR 提交成功,Jira Bug 单自动回写了分析结果和处理记录。
有一个小瑕疵:Commit 阶段本应自动提交,但走进了 Human 确认流程。这是 Claude Code 的 Permission 系统在某些 Git 操作上触发了二次确认,后续通过调整 Hooks 配置解决。
Case 2:工具失败 → 等待人工处理
这次 UT 阶段失败了,原因是环境 JDK 版本不匹配。
工作流在检测到 UT 执行失败后,没有崩溃退出,而是触发了人工通知流程,暂停并等待人工处理。这正是设计时就预留的降级路径:
工具失败
→ 判断是否可自动重试
→ 不可重试 → 推送通知 → 等待人工介入 → 人工确认后续接
这个场景验证了系统的容错机制是有效的。
Case 3:任务中断 → 新 Session 中续接
执行中途系统通知打断了 Agent 运行。重新开一个 Session,给 Agent 发送相同的任务描述,Agent 自动读取了上次的 workflow_state.json 状态文件,从断点继续执行,而不是从头开始。
这依赖工作流在每个节点完成后都持久化一份状态文件:
json
{
"bug_id": "AE-33995",
"current_phase": 4,
"current_step": "4.3",
"completed_steps": ["0", "1", "2", "3", "4.1", "4.2"],
"artifacts": {
"log_path": "...",
"review_result": "review_r1.json",
...
}
}
Session 可以中断,任务不会丢失。 这个能力对于耗时长的自动化流程来说是必须的。
Case 4:Code Review 不通过 → 多轮重试机制
这是整个流程里最有意思的一段。
Code Review 失败(第一轮得了 57 分,存在 8 项强制违规),工作流没有直接走人工流程,而是启动了最多 3 轮的自动修复重试:
less
Round 1: CR → 不通过(57分,8条强制违规)
→ 启动 Step 4.1 修复子 Agent,针对 8 条违规逐一修复
→ Round 2 CR → 不通过(83分,2条违规)
→ 启动 Round 3 修复
→ Round 3 CR → 不通过(74分,4条违规)
→ 达到最大重试次数 → 触发人工确认门 B
每一轮修复,Agent 都会读取上一轮的 CR 结果,针对具体违规项定向修复,而不是全量重写。第一轮的修复摘要如下:
| 问题编号 | 违规内容 | 文件 |
|---|---|---|
| B2-01 | 裸 Thread → CoroutineScope | PerformanceInfoMonitor.kt |
| C1-01 | binding!! → 安全调用 | PerformanceFloatingView.kt |
| C1-02 | windowManager!! 5处 → ?.let | PerformanceFloatingView.kt |
| C5-01 | InterruptedException 单独捕获 | PerformanceInfoMonitor.kt |
| D1-01 | 接口命名 → ICloseClickCallback | PerformanceFloatingView.kt |
| ... | ... | ... |
Case 5:超过最大重试次数 → 人工确认门
继续上面的 Case 4。3 轮修复之后,Code Review 仍未通过。但这里暴露了一个非常值得深思的问题:
Round 3 的 4 项"强制违规"中,有 2 项在 Round 2 时被评为"推荐优化",本轮升级为了"强制"。
LLM 作为 Code Review 的裁判,存在轮次间的标准漂移。 同一个问题,在不同轮次的 Prompt 上下文中,被判定的严重程度不一致,导致循环无法收敛。
这是一个深层的工程问题,不是简单调整 Prompt 能解决的。
人工确认门 B 被触发后,Agent 展示了 3 轮修复的对比报告,并给出了两个选项:
css
A:接受当前代码,直接进入提交
(核心问题全部修复,剩余为代码风格问题,不影响功能)
B:人工修复剩余 4 项后告知 Agent,重跑质量检查后继续
此时人的角色是裁判,不是执行者。AI 做完了它能做的,人来拍板。
Case 6:CI 流水线 Verify 失败 → 人工确认
提交到 Gerrit 后,CI 流水线返回了失败投票:
| Reviewer | Verified | Compile | UT | Code-Check | Smoke-Test |
|---|---|---|---|---|---|
| icvsbgci | -1 | +1 | +1 | +1 | 0 |
| jenkins.dl | 0 | 0 | 0 | 0 | -1 |
Agent 读取了 Gerrit 的投票状态,判断存在流水线失败,进入人工确认门 C,给出三个处理选项:
css
A --- 流水线问题已知/可接受,继续推进
B --- 需要重新触发流水线
C --- 放弃此次提交,重新评估
工程深坑:我遇到的三个核心难题
难题一:长链路上下文爆炸
这是整个系统面临的最大技术挑战。
一次 Bug 处理包含:读 Jira、下载解压日志、分析大量日志文本、读多个源码文件、Code Review、Sonar 扫描报告......所有内容都在一个 Turn 里积累。在一次实测中,单个 Turn 跑了 117 个 tool calls 之后,在 Sonar 扫描结束准备继续下一步时,API 请求被直接 abort:
ini
seq=115: sonar poll 返回 ← 扫描结果拿到了
seq=117: stopReason="aborted", errorMessage="Request was aborted."
不是 Agent 不知道下一步做什么,是整个 Turn 的上下文太大,服务端直接拒绝了请求。
解法:Sub-Agent 架构。
把每个重量级 Phase 改造为独立的子 Agent 调用。主 Agent 只负责编排,子 Agent 负责执行具体任务并返回结构化结果。每次子 Agent 调用完成后,主 Agent 的上下文只接收摘要结果,而不是完整的执行过程。这样每个 Phase 的上下文是独立的,不会线性累积。
难题二:LLM Code Review 的标准漂移
在 Case 5 里已经描述过这个问题。核心矛盾是:LLM 作为 Judge 时,其判断受到上下文的影响。随着修复轮次的增加,Prompt 里的历史信息越来越多,LLM 的判断基准会偏移。
这个问题目前没有完美解法。几个方向在探索中:
- 每轮 Code Review 使用全新的 Session(清空历史上下文)
- 把"评分"逻辑从 LLM 中剥离,改为基于 AST 的静态规则检查,LLM 只负责解释说明
- 对"强制/推荐"的判定加入一致性校验层
难题三:跨 Session 的任务恢复
AI 的 Session 本质上是无状态的。企业环境里 Bug 修复可能跑十几分钟、甚至因为等 CI 而中断数小时,不可能要求一个 Session 始终存活。
解法是外部化状态 。工作流的每个节点完成后,都把当前状态序列化写入文件系统(workflow_state.json),记录:已完成的节点、关键产物路径、当前所在阶段。新 Session 启动时,首先读取这个文件,从断点续接。
这本质上是在模拟一个持久化的"任务队列",用文件系统作为状态存储。
现在能做什么、还缺什么
已经跑通的部分
- Jira 信息获取 + 日志下载/解压/分析
- 车载 Android 系统的 Bug 根因分析(基于
rnd-automotive-issue-analyzer) - 代码修复(Kotlin,Android 应用层)
- 基于自定义规范的 Code Review(多轮重试 + 人工确认)
- SonarQube 静态扫描(依赖 SonarQube 10.x,9.9 不支持)
- 代码提交到 Gerrit(带规范的 Commit Message)
- CI/CD 结果轮询 + 投票状态解读
- Gerrit 自动添加 Reviewer
- Jira 回写评论
仍在推进的部分
源码自动匹配是最大的未解问题。要从 Bug 描述里准确推断出代码仓库,需要一套"模块 → 代码仓"的映射维护机制,还需要 Bug 单本身的模块字段填写规范。这依赖跨团队协作推进,暂时还是人工指定仓库路径。
自动化回归测试节点需要测试团队参与设计,smoke test 的触发、执行环境、结果回写都需要流水线改造。
值得吗?
数千美金的 Token 成本,换来一套还在调试中的自动化流程,值得吗?
我的答案是:看你衡量的是什么。
从纯成本的角度,当然不划算------现在这套系统每次跑完整流程的 Token 消耗不低,仍需优化。
但从另一个角度来看:
-
这是一套真实企业系统上跑通的实证,不是 Toy Demo。它连接了 Jira、Gerrit、SonarQube、Jenkins 等真实的企业工具链。
-
它揭示了 AI Agent 在企业工程实践中的真实边界:哪些能自动化,哪些需要人工介入,哪些是工程难题而非 AI 能力限制。
-
Sub-Agent 架构、状态外部化、人工确认门------这三个工程模式,是在真实失败案例里磨出来的,对任何想在企业里落地 AI Agent 的团队都有参考价值。
-
最重要的是:这条路是通的。 虽然还有很多节点在完善中,但"一条 Bug 单进去,Gerrit MR 出来"这件事已经做到了。
总结
这不是一个月能做完的事。每个 Skill 背后都需要对企业工具的深度理解,每个工作流节点的调试都在反复暴露 AI Agent 在复杂工程环境里的边界。
但方向是对的。AI 不是来替代工程师的,是来替代工程师不想做、但又必须有人做的那部分重复劳动的。
如果你也在思考类似的问题,欢迎交流。
有问题或者想聊聊你们的 AI 自动化实践,欢迎评论区留言。