multi-agent-aiops-coding-workflow

multi-agent-aiops-coding-workflow 从告警诊断到自动改代码多 Agent AIOps 闭环实战一次真实测试里Code Agent 不但没有解决 CPU 告警反而在 AIOps 容器里留下了一个占用约 99.4% 单核的yes进程。这个事故让我确认了一件事让 Agent 会写代码并不难难的是让它在正确的项目、正确的权限和可验证的流程里写代码。本文复盘一个基于 Java 17、Spring Boot、Spring AI Alibaba、Prometheus、Loki 和 Docker Compose 的个人项目。目标不是展示某个类怎么写而是讲清楚怎样把多 Agent 诊断、代码提案、人工确认、执行和审计串成闭环以及这条路上真正容易踩中的坑。Key Takeaways最终流程使用 6 个任务状态隔离分析、确认与执行。AIOps Agent、Proposal Agent 和 Execution Agent 必须拥有不同工具权限。模型总结不能作为成功依据编译、测试和运行指标才是证据。MVP 可以简化审批但不能省略状态机、权限校验和工具审计。为什么“会分析告警”还不算真正的智能运维本项目最终用了 6 个任务状态并通过 62 个 Maven 用例验证主流程。原因很直接只返回诊断文本的 Agent 仍是问答系统。真正的 AIOps 必须把“发现问题”继续推进到“形成计划、获得授权、执行修改和验证结果”。Prometheus 很擅长发现症状。官方文档说明告警规则通过 PromQL 表达式、for持续时间、标签和注解描述何时进入 pending 或 firing 状态Prometheus Alerting rules访问于 2026-07-22。但告警只告诉我们当前发生了什么并不会自动回答以下问题是流量变化、数据库慢查询还是代码死循环应该重启、扩容、修改配置还是修复源码修改涉及哪些文件风险有多大谁确认了操作执行过哪些命令最终是否真的恢复因此我把 AIOps 的职责从“生成一份报告”向前延伸了一步。诊断报告不再是流程终点而是 Code Agent 的输入证据。一开始我也想过直接给诊断 Agent 文件和 Shell 工具。实践证明这会把运行态分析、代码推断和危险执行混在同一轮推理里。一旦模型误判系统几乎没有可插入的控制点。可复用结论告警系统负责描述症状诊断 Agent 负责组织证据执行系统负责改变状态。三者之间必须通过持久化任务和明确状态连接不能只依赖一段越来越长的 Prompt。整套多 Agent 闭环是怎样流转的整条链路被拆成 5 个阶段和 6 个持久化状态。高级运维点击一次“让 Agent 分析代码”后系统不会马上写文件而是先完成只读分析。只有任务进入AWAITING_CONFIRMATION用户才能确认或拒绝方案。拒绝同意Prometheus 告警AIOps AgentLoki 日志RAG 与历史事件诊断报告Proposal Agent 只读分析结构化修改方案高级运维确认记录 REJECTEDExecution Agentbiz-demo 文件与 Shell执行结果与工具审计管理员只读查看任务状态机负责限制每一步能做什么高级运维同意高级运维拒绝ANALYZINGAWAITING_CONFIRMATIONFAILEDRUNNINGREJECTEDSUCCEEDED创建任务时服务端立即启动只读分析。Proposal Agent 输出固定结构包括问题判断、涉及文件、准备修改、验证方式和风险提示。前端每 2 秒查询任务状态并把方案展示给发起任务的高级运维。确认接口同时校验任务 ID、发起人 ID 和当前状态。它解决两个常被忽略的问题其他高级运维不能确认不属于自己的任务重复点击也不能让同一任务执行两次。查看高级运维确认式 Code Agent 的完整设计可复用结论多 Agent 工作流的核心不是“调用了几个模型”而是每个阶段都有独立输入、权限、输出和终止状态。模型负责推理服务端负责保证状态转换合法。为什么要把诊断、规划和执行 Agent 分开这个 MVP 实际设置了 3 类 Agent 角色和 1 个审计视角。Spring AI Alibaba 官方把 ReAct 描述为持续进行推理、工具调用、观察和迭代的循环Spring AI Alibaba Agents访问于 2026-07-22。正因为模型会持续行动工具权限才不能只靠 Prompt 约束。角色主要输入工具权限主要输出不能做什么AIOps Agent告警、指标、日志、知识库查询类工具诊断报告与代码修改建议不写代码不执行修复Proposal Agent诊断报告、修改目标、业务仓库只读文件和目录结构化修改方案不写文件不运行 ShellExecution Agent已确认方案、原始诊断文件读写、Shell修改结果、测试结果不访问.env、.git和工作区外路径工具管理员全量任务与工具日志只读接口审计与复盘不代替高级运维审批这套拆分还改变了审批方式。最初方案要求管理员批准所有代码修改但这会让高级运维的日常操作重新回到排队等待。MVP 最终选择“高级运维本人确认管理员只读审计”。重启、发布、生产配置修改仍应进入更严格审批但代码工作区内的受控修改先保持轻量。这里必须诚实说明当前项目实现的是固定工作流还不是通用SkillRegistry。它已经具备版本化工作流未来所需的雏形例如输入、允许工具、步骤、状态、输出和审计但尚未把“CPU 高告警”“OOM”“慢请求”抽象成可热加载的独立 Skill。可复用结论多 Agent 只有在权限真正分离时才有意义。如果三个 Agent 都能访问同一组写工具那么它们只是三段 Prompt不是三个安全边界。实现过程中最危险的坑是什么最严重的一次事故让两个容器同时接近满负载biz-demo因混沌接口维持约 94%oncall-app又因 Code Agent 遗留进程升至约 98%。问题并非模型不会写代码而是目标仓库、验证方式和成功标准同时出了错。Agent 为验证安全规则制造了真实故障更危险的问题出现在验证阶段。执行 Agent 在写入拦截逻辑之前真的运行了yes/dev/nullsleep1kill%1这条命令最终在工具审计中记录为TimeoutException。后台yes没有被正确回收被重新托管到容器 PID 1并持续消耗约 99.4% 单核。换句话说Agent 为了证明自己能阻止 CPU 压测先在承载 AIOps 的容器里制造了一次 CPU 压测。grep成功不等于代码成功Agent 写入黑名单后用grep找到CHAOS_COMMAND_BLOCKED字符串就在最终总结中声称修改成功。实际代码包含非法 Java 转义下一次启动编译 113 个源文件时直接报illegal escape character。这段审计最值得保留的不是错误代码而是工具调用顺序先执行危险命令再写文件最后只做字符串检查。它说明“计划看起来合理”和“执行过程符合计划”是两种不同的验证对象。可复用结论Agent 的最终自然语言总结只能算声明。真正的完成条件必须由服务端读取编译 exit code、测试结果、文件 Diff 和运行指标再决定任务是否能进入SUCCEEDED。Shell 工具为什么比文件写入更难治理文件工具可以把所有路径归一化后限制在一个根目录内Shell 做不到这一点。此次故障只需要 1 条后台命令和一次 5 秒输出读取超时就绕过了“命令已经结束”的表象留下持续运行的子进程。最初实现只在超时时调用父进程的destroyForcibly()。但 Shell 可以创建子进程父 Shell 退出后子进程可能被 PID 1 接管。Oracle 的 Java 17 Process API 明确提供children()、descendants()、destroy()和destroyForcibly()等能力Oracle Java 17 Process API访问于 2026-07-22但调用时机非常关键。本项目最后采用两层处理Shell 运行期间持续记录后代ProcessHandle避免父进程退出后失去关系。超时、输出异常和正常结束时都回收仍存活的后台子进程。Compose 为 AIOps 服务开启init: true由 init 进程转发信号并回收孤儿或僵尸进程。这个行为与 Docker Compose services 的init定义一致访问于 2026-07-22。控制手段能解决的问题不能解决的问题路径归一化../越界、绝对路径、敏感文件访问Shell 内部自行cd或访问其他路径进程树回收超时子进程、后台任务、输出管道泄漏命令本身在超时前造成的资源冲击Docker init信号转发、孤儿和僵尸进程回收命令授权和文件范围控制独立 ExecutorCPU、内存、PID、网络隔离仍需配合工具策略和审批规则工作目录不是沙箱。它只决定命令从哪里开始执行并不能证明命令只影响这个目录。对于个人项目固定仓库、进程回收和审计可以组成 MVP对于生产系统Shell 必须进入独立执行容器或短生命周期 Job。可复用结论文件权限适合用路径策略控制Shell 权限必须用操作系统隔离控制。把两者都包装成“模型工具”并不意味着它们拥有相同的风险等级。怎样在 MVP 中平衡自动化和控制权这个版本只保留 1 次高级运维确认不要求管理员逐单审批但服务端仍检查用户角色、任务所有者和当前状态。个人开发者可以简化组织流程却不能把安全边界也一起删掉。MVP 中我保留了以下约束Feature Flag 默认关闭。只有受控环境显式设置AGENT_CODE_ENABLEDtrue才能创建任务。本人确认。创建任务的高级运维才能确认或拒绝避免横向操作。状态条件更新。SQL 更新同时匹配任务 ID、用户 ID 和当前状态减少重复执行。敏感路径限制。文件工具拒绝.env、.git、绝对路径和目录穿越。环境变量清理。Shell 子进程不继承名称包含 KEY、SECRET、TOKEN、PASSWORD 或 CREDENTIAL 的变量。工具级审计。每次读文件、写文件、列目录和 Shell 调用都保存输入摘要、结果和输出摘要。管理员只读。管理后台能查看任务和工具日志但没有同意、拒绝或执行接口。数据库迁移也是一个容易被忽视的边界。旧 V2 已经在持久化开发库执行即使 Git 文件尚未提交也不能原地修改校验和。最终通过 V3 增加方案和确认字段、迁移旧状态并把管理员审批权限替换为只读权限。权限迁移还暴露了旧会话问题。数据库已经增加AGENT_CODE_VIEW但重启前创建的管理员 Session 没有新 authority导致后台查询返回 403。MVP 通过ROLE_ADMIN兼容只读查询更严格的系统则应引入权限版本并主动失效旧 Session。可复用结论MVP 可以少做流程页面但不能少做服务端状态条件、权限判定和审计。越是允许模型行动越不能把关键约束留给前端按钮。最终打通了哪些工程能力修复完成后AIOps 容器从异常约 98% 回落到一次稳态采样约 2.14%biz-demo仍保持约 99.66% 的受控 CPU 压测。Linux 文件与 Shell 聚焦测试 5/5 通过全量 Maven 测试共 62 个用例零失败、零错误。最终形成的能力包括运行态诊断。AIOps Agent 聚合 Prometheus 指标、Loki 日志、RAG 文档和历史事件。代码修改建议。诊断报告固定包含是否建议改代码、疑似模块、验证方式和风险。只读代码提案。Proposal Agent 在biz-demo内读取源码生成结构化修改方案。高级运维确认。同一位发起人可以同意或拒绝不需要等待管理员操作。受控执行。Execution Agent 获得文件读写和 Shell具备超时、输出上限、敏感环境清理和进程树回收。完整审计。管理员能查看诊断、方案、执行总结、错误和每一次工具调用。可验证运行环境。Code Agent 的 bind mount 明确对应 Prometheus 监控的biz-demo不再默认修改 AIOps 自身。指标问题阶段修复后oncall-appCPU约 97.99%一次稳态采样约 2.14%遗留yes进程1 个约 99.4% 单核0 个biz-demoCPU 压测约 94.18%约 99.66%保持受控运行Linux 工具聚焦测试无子进程泄漏用例5/5 通过Maven 全量测试61 个用例62 个用例零失败这些数字来自本项目本地容器采样、数据库工具审计和自动化测试完整过程记录在项目错误与优化日志中。可复用结论这次交付的核心不是“Agent 能调用 Shell”而是 Shell 调用之后仍有状态、证据、所有者、结果和恢复手段。没有这些配套能力自动化程度越高事故传播越快。如果进入 Phase 2还必须补上什么当前仍有 1 个明确的生产级缺口Execution Agent 的 Shell 与 AIOps 服务共享容器。虽然工作目录已经绑定biz-demo但 cwd 不是系统级沙箱。MVP 可以接受这个边界生产环境不能。Phase 2 应优先补齐独立 Executor。每个任务启动独立容器或 Kubernetes Job限制 CPU、内存、PID、磁盘和网络。Service Registry。建立Prometheus service/job - 代码仓库 - 构建命令 - 负责人的显式映射。ToolPolicyEngine。服务端根据角色、环境、目标资源、风险等级和参数 schema 决定是否放行。SkillRegistry。把 CPU 高、OOM、慢请求等流程定义为版本化 Skill明确输入、步骤、工具、审批和回滚。确定性 Orchestrator。服务端执行固定步骤模型只选择 Skill、解释证据和建议下一步。真实质量门禁。必须保存 Diff并以编译、测试、静态检查和恢复指标作为成功条件。回滚与幂等。每次执行生成唯一 ID、补丁和回滚点重试不能重复造成副作用。另一个现实问题来自模型框架。当前项目使用的 DashScope 流式工具调用路径在单条消息出现多个 tool call 时存在限制。因此多工具诊断不能完全依赖模型在一次流式响应中自由并行。短期可以约束单轮单工具长期应采用规划、执行、汇总的确定性编排。可复用结论Phase 2 的重点不是换一个更强模型而是把执行从 AIOps 主进程中隔离出来并把服务、仓库、策略、测试和回滚变成服务端可验证的对象。常见问题多 Agent 一定比单 Agent 更好吗不一定。本项目使用 3 类 Agent是为了隔离运行态诊断、只读规划和写入执行。如果多个 Agent 拥有同样工具它们不会自动获得更高可靠性只会增加上下文传递和排错成本。为什么不让管理员审批每一次代码修改这是一个个人开发者 MVP。最终只保留 1 次高级运维本人确认管理员负责只读审计。生产发布、扩缩容和配置变更仍应进入更高风险等级并使用独立审批规则。设置 Shell 工作目录后Agent 就不能访问其他目录了吗不能。此次事故已经证明仅依赖工作目录不足以形成隔离。项目增加了路径工具限制、后代进程回收和 Docker init但生产级方案仍需要独立 Executor 容器及资源限额。怎样判断 Agent 的代码修改真的成功至少需要 4 类证据文件 Diff、编译 exit code、自动化测试结果和运行态指标恢复。本项目曾出现grep成功但 Java 编译失败因此模型的自然语言总结不能直接决定任务成功状态。结语从 Prometheus 告警到 Code Agent 修改代码真正需要打通的是一条受控任务链而不是再加一个拥有 Shell 的聊天机器人。这次实践最重要的收获有三点Agent 必须绑定正确目标权限必须随阶段逐步开放执行结果必须由机器证据判断。先把这三件事做好再讨论更高程度的自治系统才不会在修复业务故障时先把自己打挂。