
做运维的人应该都有过这种冲动半夜告警响了爬起来看一眼发现只是某个服务抖动了一下自己恢复了或者收到一堆日志排查半天定位到一个早就该有人处理的配置项。那时候就在想这些事能不能让机器自己干了说实话传统的脚本和自动化能做不少事但遇到“需要判断、需要协同、需要临时改策略”的场景脚本就僵住了。最近我在折腾 AI 运维 Agent试了一套多智能体协同的方案让几个 Agent 自己分工、自己干活、自己汇报效果比预期好不少。这篇就聊聊这个系统是怎么搭的、里面的 Agent 怎么协作、以及实测下来的真实表现踩过的坑也一并写出来。这适合已经在用自动化脚本、但想往智能化走一步的运维同学也适合对 Agent 概念感兴趣、想看看它在运维场景里到底能干啥的人。不需要你有大模型训练基础但得对 Linux、API、工作流编排有点概念。1. AI 运维 Agent 的“自主做事”靠的不是大模型本身先说一个容易误会的点AI 运维 Agent 不是把大模型接进来就完事了。大模型本身只能理解语言、生成文本它不会执行命令、拉取指标、改配置。真正让它“自己做事”的是一套把它跟运维系统连起来的执行链路。1.1 从“聊天”到“干活”隔着一个完整的工具链我见过不少人说“接入大模型之后能让它帮我查日志吗”。实际上大模型返回的只是一段文本甚至可能是一段“我建议你执行 xxx 命令”的文字。要让它真的去查日志、去重启服务需要做三件事第一给大模型提供工具。每个运维动作都得封装成一个可调用的函数或接口比如“查 CPU 使用率”“拉取最近 1 小时错误日志”“重启某个 Pod”“回滚某个版本”。这一步很像把所有常用运维操作做成 REST APIAgent 通过调用函数来执行动作。第二给大模型观察结果的能力。一次调用可能不够Agent 得能连续多轮“观察-思考-行动”。比如先查指标指标异常再查日志日志里看到某个错误码再决定下一步动作。这个循环是 Agent 能做决策的基础。第三设置边界和审批机制。自主不等于不受控尤其是生产环境。初期部署时每台机器都配了白名单命令和操作风控超过阈值的操作会转人工确认。所以“自己做事”的本质是大模型负责推理、规划和拆解任务工具层负责执行编排层负责控制节奏和风险。三者缺一不可。1.2 我的第一个最小闭环 Demo我最开始跑通的版本很简单一台测试服务器部署了一个大模型接口通过 Python 写了一个执行器脚本封装了三个函数get_cpu()、get_disk()、restart_service()。然后给模型一个目标“检查 CPU 持续 5 分钟高于 80% 时重启应用服务”。这次跑通过程让我理解了关键的机制Agent 不是一次性生成答案而是进入了循环模式。第一轮调用模型模型返回“先执行 get_cpu()”执行器去查系统指标把结果塞回对话上下文模型看到 CPU 确实高继续执行restart_service()然后再检查一次 CPU 是否回落。整个过程没有人工参与。心跳定时器驱动了这个循环。每检查一次算一个 step通常任务要 3~6 个 step 才能完成。为了不把上下文撑爆我给对话历史做了截断只保留最近的 10 轮往返。这也是后面很多问题的根源后面会细说。2. 多智能体协同不是“一堆模型开会”而是“流水线 分工”单 Agent 能做的事很有限。真正想覆盖“监控发现、根因定位、止损恢复、通知响应”这条完整链路得让不同 Agent 各管一段互相配合。2.1 每个 Agent 的角色画像和能力边界我最终部署的这套环境里定义了四个 Agent每个都有自己的职责和工具集Monitor Agent 专职盯告警和指标。它定时轮询监控系统一旦触发阈值就生成一条结构化事件。它不负责修复只负责“发现问题并发出信息”。Diagnose Agent 专职分析。它拿到 Monitor 的事件后去拉日志、查依赖关系、看最近变更记录输出一份带置信度的根因判断。它不直接操作只给结论。Executor Agent 专职执行动作。它接收 Diagnose 的判断结果匹配预案库里的操作步骤执行重启、回滚、扩缩容等操作。它需要最严格的风控。Notify Agent 专职通报。所有阶段性结论、执行结果、人工确认请求都由它发出发到企业微信或钉钉机器人。它不做决策只是保持信息透明。四者协作按照标准的三个阶段推进——发现、诊断、处置——构成完整闭环。2.2 关键在于Agent 之间如何交换信息多 Agent 架构里最常见的坑是各说各话。每个 Agent 都接了大模型如果不做结构化管理它们之间传的就是一堆自然语言段落结果后面的 Agent 根本没法稳定地把关键信息提取出来。我用的办法是所有 Agent 之间只通过 JSON 结构传消息。Monitor 输出的事件格式固定{ event_id: evt_001, type: cpu_high, severity: P2, target: order-service, metrics: { cpu_usage: 92.5, load1: 18.3 }, timestamp: 2025-01-10T14:23:00Z }Diagnose 拿到这个消息后解析target和type决定拉哪些数据源输出根因判断也走固定格式{ event_id: evt_001, root_cause: jvm_old_gc, confidence: 0.87, evidence: [gc log count12, heap usage95%], suggested_actions: [restart_service, increase_heap] }这样做的好处是每个 Agent 都不需要理解其他 Agent 的“思维过程”只需要消费结构化的输入、产出结构化的输出。大模型的不稳定性被锁在了各自的处理流程里Agent 间的通信反而是稳定的。这一步我强烈建议不要省略。早期版本试过直接传自然语言Diagnose 经常把 Monitor 的意思理解偏甚至会自己脑补出不存在的问题。2.3 协同编排一个轻量的任务状态机四个 Agent 不是并行随便跑的它们得按一个流程走同时允许异常分支。我用了很轻量的状态机来做编排没有引入重型工作流框架就维护一张任务状态表状态负责 Agent流转条件detectedMonitor指标越限diagnosingDiagnose收到事件root_causedDiagnose输出根因置信度 0.6executingExecutor收到建议动作recoveredExecutor恢复命令返回成功notifiedNotify消息发送成功wait_approvalExecutor置信度低或超阈值操作每个 Agent 异步处理处理完就更新状态。状态一旦更新会触发现有定义的下一跳。这套模型足够简单但也踩了不少坑。后面遇到的最多问题都是状态没流转到、事件卡死这类细节让我意识到编排层和 Agent 一样重要。3. 部署实践从零搭一个能自主处置告警的 Agent 系统如果你也想搭一套类似的系统我这里把可复制的步骤整理一遍假设环境是一台 Linux 服务器、Docker、Python 3.9、已经有大模型 API 的访问权限。监控数据源我们先拿 Prometheus 的 API 来测。3.1 环境准备和必要的组件清单系统拆四个模块部署用 Docker Compose 管理。四个模块分别是事件总线用轻量消息队列、Agent 执行器Python 进程、编排引擎带状态表的小服务用 FastAPI 写的、管理面板只用来查日志和状态。实际部署过程中有几件事要提醒第一大模型 API 一定要走内网或代理地址不然每次 Agent 调用都走公网延迟不可控。后面排查问题的时候就遇到过一次因为外网不稳定导致 Diagnose 响应超时整体任务状态卡了十几分钟。第二所有 Agent 需要共享一套时钟。最开始排查一个“事件顺序错乱”的问题发现是不同容器的系统时间偏差了十几秒诊断 agent 读到的日志时序是反的。第三日志必须全部带结构化字段。最好不要只靠打印字符串。后面调试多 Agent 协作时一篇混乱的日志根本没法快速定位是哪个环节出了问题。Docker Compose 的 service 定义大致长这样单机玩法够用了version: 3.8 services: queue: image: valkey/valkey:7.2 ports: [6379:6379] executor: build: ./executor environment: - MODEL_ENDPOINThttp://llm-gateway:8080/v1 - TOOL_WHITELISTrestart_service,get_cpu,get_mem volumes: - /var/run/docker.sock:/var/run/docker.sock orchestrator: build: ./orchestrator ports: [8081:8080] depends_on: - queue第一版跑起来之后建议不要一次启用四个 Agent。我是先用假的告警数据流把事件总线拆通再逐个开启 Agent 验证。3.2 编写 Executor Agent 的工具封装一个关键动作是封装给大模型调用的工具函数。这里最容易踩的坑是模型“乱发明工具”。第一次跑我让大模型输出工具名模型自己编了个restart_nginx_if_cpu_high()的函数名执行器当然找不到。解决办法是工具调用不用自然语言输出而是用 function calling。大模型结构化返回调用的工具名和参数。执行器里注册所有合法工具模型只能从白名单里选。以查 CPU 为例def get_cpu_usage(host: str) - float: # 调用 Prometheus API 获取瞬时 CPU 使用率 resp requests.get( fhttp://prometheus:9090/api/v1/query, params{query: favg(rate(node_cpu_seconds_total{{mode!idle,instance{host}}}[5m])) * 100} ) return float(resp.json()[data][result][0][value][1])封装完这一个函数后需要在 OpenAI 兼容格式的 tools 列表里描述它{ type: function, function: { name: get_cpu_usage, description: 获取指定主机的 CPU 使用率百分比, parameters: { type: object, properties: { host: {type: string} }, required: [host] } } }tools 描述就像是给大模型的“说明书”。说明书写得好不好直接影响后面的诊断准确率。3.3 配置定时巡检与拟人化反馈机制Monitor Agent 不需要大模型纯规则就行。它的巡检频率我设为 30 秒一次查询最近 5 分钟的平均负载。触发条件设置了两级超过 70% 写一条 warning 日志超过 85% 进入诊断流程。巡检本身是死逻辑但反馈要拟人化。我特意给每个 Agent 设置了不同的“人设”描述和措辞模板。比如 Notify Agent 发消息时会写“CPU 持续高位已排查 XX 服务的 GC 日志判断为堆内存不足已进行重启操作”而不是只发一个“CPU 高”。这个细节的效果非常好——因为最终看消息的还是人措辞越接近人话响应效率越高。而且如果通知周末凌晨发过来一眼能看清发生了什么值班的人也不需要再重新拉一堆日志核实可以直接决定要不要介入。3.4 配置权限控制和人工确认环节自动化程度越高越要想清楚控制边界。对外面常见的做法是“全自动或者全手动”其实中间应该有一层灰度策略。我按操作风险分级操作类型风险等级执行方式查询指标、拉日志低自动执行重启服务、清理缓存中自动执行写审计日志回滚版本、变更配置高自动准备命令人工确认后执行这个表格是按实际经验总结的。初期谁都不想让机器直接改生产配置但全手动又失去了 Agent 的意义。折中下来把“查询和常规重启”交给 Agent 自动做把“回滚、扩容等有长期影响的动作”设为待确认状态。通知 Agent 会把预执行的命令和变更原因发出来人工点确认之后Executor 才真正执行。有一点很值得说人工确认不能只在流程末尾加那样 Agent 可能会在决策过程中做出错误行为。正确做法是把人工确认作为独立的状态节点嵌入流程中间。例如高风险的变更在 Executor 生成命令后必须等待确认不允许先执行后补审批。权限上还要区分不同 Agent 能访问的主机范围Monitor 和 Diagnose 可以看所有机器Executor 默认只能操作测试环境的机器生产环境机器要额外授权。整套权限体系跑通了之后我才敢让它处理一部分低风险告警。4. 实战场景实测从“告警产生”到“自动恢复”的完整链路整个系统搭建完成后我用三个典型故障场景做了压测模拟了真实环境中容易遇到的告警类型。这几个场景能比较全面地暴露问题。4.1 场景一CPU 持续飙高Executor 自动重启服务我模拟了某订单业务服务 CPU 打满的情况。用stress-ng在容器里持续占 CPU让其超过 85% 阈值并保持。Monitor 首次检测到该指标生成告警事件写入队列。Diagnose 收到事件后先去拉该服务的 CPU 监控曲线确认不是瞬时尖峰是持续攀升。然后拉日志翻到大量线程阻塞信息结合最近变更记录判断根因疑似“连接池配置过小导致请求堆积”最终输入根因结论和建议动作restart_service和increase_pool_size。由于restart_service属于中风险操作Executor 执行脚本完成重启。重启过程中Notice Agent 每步更新进度避免中间状态无人知晓。最终查到 CPU 负载回落。Notify Agent 发出完整报告包含触发时间、根因、处置动作、当前状态、后续建议字段。这套联动从告警发生到恢复用了大约 4 分 40 秒。其中大部分耗时在大模型多次推理上。如果继续优化可以把 Diagnose 的日志分析改成先做关键词预筛再让大模型判断总耗时能压缩到 3 分钟以内。4.2 场景二误判差点酿错人工确认拦住了第二个场景专门测人工确认机制。我模拟的是磁盘使用率报警。Monitor 发现某台主机的磁盘超过 90%触发诊断。Diagnose 分析后发现目录/data/logs占用最多判断为“日志文件膨胀”建议动作是“清理 7 天前的日志文件”。这个动作本身没问题但磁盘上其实还跑着一个数据分析任务正准备读取/data/logs/archive下的旧文件直接清理会破坏这个任务。因为清理动作被列入高风险操作Executor 生成了命令但没有执行而是通过 Notify 发给我确认。我看到命令涉及删除文件手动检查了一下目录内容发现旧文件还有用否掉了这个操作改成让 Diagnose 重新给方案最终换成了“按文件大小和最后访问时间只清 tmp 目录”。这个案例很有价值。证明“慢一点确认一下”不是拖后腿反而可能是真正的保护。也正因如此我强烈建议人工确认的阈值设置得偏保守宁多不少。4.3 场景三长任务执行中上下文丢失的惊人后果第三个场景是暴露问题最狠的。我模拟了一个复杂故障一个业务依赖了三个组件状态全部异常一个组件磁盘满一个组件 OOM一个组件网络延迟高。Diagnose 在同一轮上下文里要分析三个组件的日志。但对话历史经过截断较早的组件 A 信息被挤出上下文Diagnose 分析到最后只报告了组件 B 和 C 的问题组件 A 的问题被漏掉。结果 Executor 只处理了 B 和 CA 的故障未被处置。最终告警主链路没有恢复。这个案例敲响的警钟远超预期让我意识到单 Agent 大模型上下文的局限多组件、多关联任务的情景个人的记忆窗口就是瓶颈。后续优化方案是拆分解耦。让 Diagnose 做两级分析先由一个粗筛 Agent 把所有组件异常汇总成一张清单再拆成独立子任务分别诊断。每个子任务都是独立上下文互不污染。现在这个新架构上线后再次模拟同样的场景三个组件异常都能被正确识别和处置没有出现“高并发的多问题互相挤掉”的现象。上下文丢失的问题算是解决了。5. 多智能体协同系统跑起来之后的优化经验与避坑指南整个系统从能跑到能用中间经历了大量调整。下面写几个我认为最有价值的优化点和最容易踩的坑。5.1 大模型返回不稳定怎么办大模型不是每次都听话的。偶尔会给出越界建议偶尔会漏掉函数调用偶尔会生成乱码。我的处理思路是给所有 Agent 加一个输出校验层。校验层做两件事一是格式校验解析大模型输出的 JSON、工具调用是否合法二是逻辑校验——比如 Executor 要执行重启但当前 CPU 负载只有 10%明显不合理就拒绝执行并要求重新诊断。这个校验层也帮我拦下了一次比较危险的操作某个模型在分析了一句错误日志时建议“重装操作系统”被校验层直接拦截并标记为异常输出。所以不要把所有判断权都交给大模型工具层该有的理智还是要用代码写死。5.2 消息队列选型和事件幂等设计多 Agent 系统里的消息队列一开始选型很随意直接用最简单的 Redis 列表。结果在并发告警多的时候多个 Executor 同时消费同一个任务重复执行了操作。原因是消息没有做幂等。后来换成了 Stream 类型每条事件带event_id消费端维护一个已处理集合。遇到相同的event_id直接跳过。这个改动虽然小但效果非常明显大量因为消息重复触发的误操作消失了。另外Agent 的执行入口必须是幂等的。例如restart_service被调两次第二次要判断服务状态已经是 running就跳过。这也是一种保护。5.3 记忆持久化与上下文管理是保证长任务稳定性的基石前文提到的上下文丢失问题除了拆分解耦还需要在架构层面做记忆持久化。我引入了一个向量库用于存历史故障处置案例。当 Diagnose 遇到某个事件时会先检索相似历史案例把检索结果拼进 prompt 里供大模型参考。这个机制的效果出乎意料地好——第二次遇到同类故障时Diagnose 的根因置信度明显提高建议的动作也更贴合之前验证过的方案。这有点像给团队加了一份“历史经验存档”每次处置完故障之后整个链路都会自动归档摘要。现在每次工单结束我都尽可能地保证归档动作是自动完成的并且会把最终的根因、处置动作、验证结果都写成结构化摘要。长期跑下来这套系统会越来越懂这个环境越用越精准。6. 这套模式在落地时实际运维团队应该如何适配很多朋友看完上面可能会问我这边没有大模型开发和编排能力怎么落地这套东西我觉得核心不是非得自研而是把现有的工具链和团队分工重新理顺。6.1 大模型基座用成熟平台比什么都重要我尝试过本地部署开源模型也试过各种微调。最后稳定下来的方案反而最简单——用成熟的大模型 API 服务作为底座。主要原因有三个稳定性、工具调用的成熟度、持续迭代能力。部署一个私有模型要处理显存、推理速度、上下文长度这些问题很影响体验。而成熟服务在 function calling 上做得比较完善对 Agent 场景支持好。甚至到现在我的 Agent 系统接入的大模型 API 已经在不同版本间切换了好几次业务代码几乎没有改动。建议如果要试不必纠结必须完全私有化部署先用成熟 API 把流程跑通再评估后续需要调整的部分。6.2 运维人员的角色转型从“操作员”到“策略制定者”当 Agent 真的开始接管低风险操作后运维人员的工作内容会发生变化。团队里最明显的体会是一线工单少了许多例如重启、日志清理这些重复操作基本不需要人参与了。但提出问题、制定安全策略、审核 Agent 操作合理性的工作量却变多了。我现在主要做的一件事就是不断给工具白名单补充和修正操作边界以及对 Agent 的决策逻辑给出校验规则。比如某些命令只在特定目录可用某些环境只允许在维护窗口期执行变更全部要靠人提前定义清楚。如果团队里没有这样一个“策略制定者”Agent 系统很容易暴走。这块需要尽早重视哪怕初期一个人专职盯控也比全自动裸奔强。6.3 灰度发布和评估机制这套系统从 Demo 走到生产用了一个还算稳妥的灰度策略先让 Monitor 和 Diagnose 全量上线但 Executor 只接入一台测试机跑了两周确认没有逻辑错乱再逐步扩大到低风险操作每一步都留有人工复核通道。我个人的判断是评估机制的关键不在于“自动化率有多高”而在于“人工介入次数是否逐步下降”。如果今天自动执行了 100 次但其中 40 次都需要人工干预纠偏那说明 Agent 的学习和判断能力还没到位。反之如果人工介入频率逐月降低说明系统进入了良性循环新增的自动恢复能力是值得信任的。7. 一些最后想说的话折腾这套系统大半年我最大的感受是“AI 运维 Agent”并不是一个成品而是一个需要持续调教的协作过程。多智能体协同也不是把多个 Agent 丢在一起就能成事关键还是清晰的角色分工、稳定的信息流转以及严格的边界控制。最让我欣慰的时刻是它在一次真实故障里成功识别出根因并自动处置完毕值班同事第二天早上看了一眼报告发现处理记录比人工写的还要清晰。那种“机器真的在帮忙分担压力”的成就感很难用语言表达。它不能替代所有判断但确实把不少重复的、低价值的劳动接了过去。让做运维的人可以去做更复杂、更值得思考的事这大概就是这套系统最大的价值。