梳理智能运维助手 3.0 的需求分层、总体架构、技术路线、流式输出、上下文管理、自动修复和可观测性设计。
本文由《智能运维助手设计文档 v3.0.0》整理而来,已移除目录前模板页、版本页和前置信息;正文、截图、表格与操作步骤按博客阅读方式重新排版,并拆成 AIOps 系列。
系列导航:总体架构 · LangGraph 与 MCP 编排 · 部署、评估与测试
文档引言
文档目的
本文档为智能运维助手的设计思路与实现过程,用于了解智能运维助手的组成与技术架构。
文档范围
章节2按照模块分层描述详细需求分析。
章节3包含软件总体架构设计和关键技术选型。
章节4详细描述每个模块的设计。
章节5包含内部和外部接口详细设计。
章节6包含部署和运维设计。
章节7列出目前已知的问题和处理方案。
术语与缩略语
| 术语 / 缩略语 | 中英文全称 | 说明 |
|---|---|---|
| MTTR | Mean Time To Recovery | 表示系统发生故障后,恢复服务平均花多久 |
需求描述
一级模块 智能运维
二级模块 Agent 核心控制与决策模块
三级模块 Agent 核心控制模块
智能运维 Agent 的核心控制单元,负责 Agent 的整体运行控制、任务调度及运维决策流程的统一管理。
功能点1名称:Agent 运行生命周期管理
功能点2名称:运维任务接收与调度控制
功能点3名称:运维决策流程控制
二级模块 运维感知与数据采集模块
三级模块 运维状态感知模块
负责感知运行环境与目标对象的状态, 为 Agent 的分析与决策提供基础数据支撑。
功能点1名称:运行状态与资源信息采集
功能点2名称:事件与异常信息感知
二级模块 运维分析与判断模块
三级模块 运维分析与判断模块
基于采集到的运维数据,对当前运行状态进行分析与判断, 形成可用于后续执行的运维结论或建议
功能点1名称:运维状态分析
功能点2名称:问题类型与影响范围判断
二级模块 运维能力与知识管理模块
三级模块 运维能力与知识管理模块
用于管理 Agent 所依赖的运维能力、经验规则及知识内容, 支撑 Agent 的持续决策与执行能力
功能点1名称:运维能力定义与管理
功能点2名称:运维经验与知识维护
总体架构设计
总体架构
问题挑战与技术路线
随着云原生技术、分布式系统及大规模集群的广泛应用,现代 IT 系统在规模、复杂度与动态性等方面持续提升,系统运行环境呈现出高度动态化、异构化与复杂化的特征。尤其在多集群、多云及边缘计算等场景下,系统运行状态变化频繁,故障模式复杂多样,传统依赖人工经验和静态规则的运维方式已难以满足对系统稳定性、可靠性与运维效率的要求。
在当前运维实践中,运维对象往往分布在不同环境和不同层级,运行状态与问题表现具有明显的碎片化特征。运维人员需要在多种监控系统、日志系统和管理工具之间频繁切换,依赖个人经验对问题进行分析与处置,不仅运维成本高,而且难以形成可复用、可演进的运维能力体系。
在此背景下,引入具备一定自主感知、分析与执行能力的智能运维 Agent,智能运维 Agent 以“感知—分析—决策—执行”的闭环运维流程为核心,通过对系统运行状态的感知与分析,辅助或替代人工完成问题定位、处置决策及建议的运维操作,从而降低运维复杂度与人工负担。
开发过程中提出构建一个面向云原生与分布式系统的智能运维 Agent(AIOps Agent)。该 Agent 以单体 Agent 为基本单位,围绕运维感知、分析判断与对问题进行分类了解。
在分析与判断方面,AIOps Agent 基于采集到的运行数据,包括集群硬件信息,以及安装的observibility相关组件如prometheus通过使用prometheus工具来执行指标查询
通过上述设计,AIOps Agent 在不依赖中心化平台的前提下,实现了面向单 Agent 的智能运维分析能力。降低了复杂系统运维过程中对人工经验的依赖,有助于将分散的运维知识与操作流程沉淀为可复用、可扩展的 Agent 能力单元,总体架构
图3-1是智能运维助手的总体架构,其包含的核心内容如下所述:
Robusta AIOps 平台整体采用分层解耦的架构设计,以 Kubernetes 运维诊断为核心场景,融合大语言模型推理能力与确定性规则引擎,构建了一套兼具灵活性与可解释性的智能诊断体系。系统从整体上划分为执行层、技能与规则层、推理编排层以及接口层,配置层五个核心层级,各层职责清晰
在架构设计理念上,分层实现能让每个模块专注于实现自己的功能。对于规则层来说,在运维诊断中,工具返回的原始数据通常是非结构化文本,直接把这些文本交给模型容易产生两个问题:一是模型可能忽略关键字段,二是后续无法稳定计算诊断质量。因此系统通过证据模型将工具结果抽象为可管理的证据项比如异常分层的层级Layer,提取出出的Fact:从证据中提取出的事实,EvidenceItem:单项证据。他的主要工作在于对agent输出的内容进行规则化处理包括中间内容传递的json化输出,结构化提取,作为后续的质量指标评分的重要信息来源。
在执行层方面,通过统一的工具抽象与 MCP 协议集成,实现对 Kubernetes 集群及外部系统的标准化访问。工具涵盖k8s get by kind,prometeus execute, fetch_runbook等多个维度用来支持agent执行工具采集系统信息用于判断和做出分析。Agent系统初步支持多集群联邦查询,通过并发聚合与智能路由两种模式,实现跨集群转发查询api,每个集群单独分析,将得到的报告传递给主集群,主集群根据每个集群单独的结果来做最后的汇总总结。
在推理编排方面,agent通过使用langgraph构建四节点工作流,节点分别是layer问题定位层节点,evidence证据采集节点,route case analysize层,用来将前面两层的信息汇总进行根因分析,conclusion根据前面的结构化输出输出一个人类可读的总结运维报告。
此外,系统采用“知识外置”的设计策略,将规则定义、系统级提示、额外的Runbook 知识库及提示词统一纳入配置层管理,使系统具备良好的可扩展性与演进能力。运维知识可以通过配置持续沉淀,无需修改核心代码,从而显著降低系统维护成本。
图3-1 智能运维助手架构图
接口层作为系统对外的统一入口,承担用户请求接入与结果输出的职责。系统基于 FastAPI 构建 Web 服务,对外提供标准的 RESTful API 接口,文本流适用于终端交互场景,能够直观展示诊断过程;而 SSE 更适合前端应用集成,支持实时事件驱动的 UI 更新。Text文本流适合本地验证时直观的输出,目前主要使用的接口逻辑有ask—用于单次请求问题,常见使用方式为/ask q=“我的集群有什么问题”,/query 查询模式,对于运维agent来说,我们有时候只想问一些简单的查询问题。使用方式如下:/query q=“查询下本机的cpu和memroy使用率。”/fedurate/ask,/feduate/query 接口,联邦查询时等价于单机群的ask和query接口。
在请求处理流程中,接口层首先对用户输入进行解析和基础校验,然后将请求转发至核心编排组件 HolmesService。接口层本身不参与任何业务推理或诊断逻辑,其设计原则是“轻逻辑、强转发”,确保系统结构清晰、职责单一。
此外,接口层还承担日志记录与异常处理职责,对所有请求进行标准化封装,并在发生错误时返回结构化的错误信息。这种设计保证了系统在面对复杂诊断流程时仍能提供稳定且一致的外部接口行为。
推理层是系统的核心决策引擎,负责理解用户意图、组织诊断流程以及生成最终分析结果。该层通过 HolmesService 进行统一编排,将用户的请求转发给后续的langgraph工作流。 并支持两种推理模式:基于 Agent 的动态推理模式以及基于 LangGraph 的结构化工作流模式。
在 Agent 模式下,系统采用类似循环推理(agentic loop)的方式运行。大语言模型根据当前上下文自主决定调用哪些工具、收集哪些信息,并逐步逼近问题的根因。这种方式具有较强的灵活性,适用于复杂或未知场景,能够动态调整诊断策略。
在工作流模式下,系统通过 LangGraph 将诊断过程拆分为多个明确阶段,包括问题定位、证据采集、根因分析以及结果汇总。每个阶段由独立节点执行,并通过状态对象进行数据传递。这种结构化设计显著提升了诊断流程的可控性与可观测性,便于调试与优化。每个节点有自己的提示词针对一个复杂运维问题的不同部分有这专门的处理方式。
问题定位阶段负责解析用户输入,识别问题类型及所属层级,并提取关键实体信息。这一阶段为后续诊断提供方向性指导,避免无效的数据采集。证据采集阶段根据定位结果动态制定采集策略,并调用底层工具获取相关信息,形成结构化证据集合。
根因分析阶段结合采集到的证据进行综合分析,既可以调用前面层级给出的结构化json输出进行行确定性判定,也可以由大语言模型进行补充推理。最终,汇总阶段将分析结果整合为统一的输出报告,包括问题描述、原因分析和建议措施。
该工作流模块已经完整实现,并通过状态管理机制记录整个诊断过程,使系统具备良好的可追溯性与调试能力。
执行层是系统与 Kubernetes 集群及外部系统交互的基础层,负责实际的数据采集与命令执行。该层通过工具抽象统一封装 kubectl、Prometheus、Helm 等能力,为上层提供标准化的调用接口。大模型得到工具的描述根据问题的需求会自主调用工具并且填入参数,最后将工具运行得到的结果附加在自己的上下文里面交回给LLM进行下一轮分析。
在架构设计上,执行层还支持通过 MCP(Model Context Protocol)协议扩展外部工具,使系统能够动态接入第三方能力,如日志系统或自定义诊断脚本。所有工具均以“只执行、不推理”为原则,确保职责边界清晰。
技能与规则层是把运维诊断经验从“自然语言经验”转成“可结构化、可评分、可复用、可验证”的中间能力层。它不直接等同于 LLM,也不直接等同于工具执行,而是位于工具结果和推理编排之间,为诊断过程提供结构化约束。常见为json格式输出和抓取处理。
规则引擎基于声明式规则定义,在多节点的推理过程中不同节点之间需要进行信息交互,通过设定固定的输出模板与规则形式,比如从layer1到Layer2必须有一个json格式的问题定位诊断,通过json格式结构化解析,在上一层中,agent定位到当前问题可能是处于那个层的运维问题等。
配置层负责管理系统的所有知识与运行参数,是实现“知识外置”的关键基础设施。该层统一管理规则配置、Runbook 知识库、提示词(Prompt)以及多集群配置等内容,使系统具备高度的可扩展性与可维护性。配置信息一方面是runbooks的额外运维知识以及整个系统的核心配置包括api token,节点信息,联邦集群信息,配置端口等。
在实现上,配置层支持通过文件或环境变量进行加载,并允许在不同环境下灵活调整参数。Runbook 知识库以文档形式存储运维经验,可被推理层动态检索与引用,从而增强系统的知识覆盖能力。
此外,系统提示词也通过配置进行统一管理,使得推理策略可以在不修改代码的情况下进行优化和迭代。这种设计使系统能够持续演进,并适应不同业务场景需求。
从整体流程来看,系统以接口层为入口,将用户请求传递至推理层进行处理。推理层根据模式选择(Agent 或工作流)组织诊断流程,并在需要时调用执行层获取数据,同时(在设计上)结合规则层进行确定性分析。最终结果经过整理后返回接口层输出给用户。
整体而言,该架构已经完成了推理层与接口层的核心实现,并初步具备执行能力与配置体系,未来通过补全技能层与执行层的能力,可以进一步演进为完整的企业级 AIOps 平台。
总体流程
图3-2 流程图
在流程图中,接口层作为统一入口,将请求传递至 HolmesService,由其负责模式路由与整体流程调度。推理层作为核心枢纽,根据配置选择进入 Agent 循环或工作流执行路径,并在过程中与执行层、规则层及配置层协同完成诊断。
其中,基于 LangGraph 的工作流诊断与多集群联邦查询是系统的核心实现路径,分别解决“单集群可控诊断”和“跨集群智能分析”问题。
单集群诊断流程当系统启用工作流模式时,诊断流程由 LangGraph 驱动,以结构化的四节点流程执行。这种方式将原本由 LLM 自主决定的诊断过程拆解为明确阶段,使整个流程具备更强的可控性与可观测性。
工作流以统一的状态对象(WorkflowState)为数据载体,在节点之间传递诊断上下文。初始状态仅包含用户问题,随着流程推进逐步补充层级判定、证据集合、分析结果等信息,形成完整的诊断链路。不同节点之间为了减少上下文的占用通过json结构化输出作为主要传递信息工具。
多集群诊断流程在多集群场景下,系统通过联邦机制将多个独立的诊断能力整合为统一入口,实现跨集群的分析与对比。
整体流程由 FederationCoordinator 或 FederationAgent 驱动,根据模式不同分为并发聚合(v1)和智能路由(v2)两种实现。
v2 引入 FederationAgent,实现基于 LLM 的动态决策路由,是多集群能力的核心实现。
在该模式下,多集群查询被建模为一个 Agent 推理过程。LLM 不再默认查询所有集群,而是根据用户问题自主决定查询策略。其核心能力包括:
首先,LLM 通过分析用户问题判断查询范围。如果问题明确指定集群,则直接调用对应集群;如果问题具有全局性质,则先获取集群列表,再逐步选择目标集群。
其次,系统内部实现多集群调用的2个专属工具接口(list_clusters 与 query_cluster),一个工具用于列出所有注册的集群列表,一个工具为转发查询。他会将用户的问题原封不动的转发给对应集群,通过nodeport的http协议进行转发。Query_cluster的接口形式包含cluster=xxx,question=xxxx通过大模型的能力将问题转化为,集群信息查询与跨集群调用抽象为可组合能力。LLM 可以像使用普通工具一样调用这些接口,从而实现灵活的查询路径。
在执行过程中,多个子集群查询可以并发执行,以降低整体延迟。同时,系统对返回结果进行压缩,仅保留关键结论供 LLM 使用,从而控制上下文长度。
最终,LLM 基于收集到的信息生成统一报告。这种方式使用户可以实时看到跨集群分析的生成过程。
多集群机制的核心在于“将集群作为可调用资源”,并通过 Agent 实现智能调度。相比传统聚合方式,该设计具备以下优势:
-
按需查询,减少不必要的调用开销
-
支持渐进式分析(逐步扩展查询范围)
-
能够进行跨集群对比与关联分析
-
与单集群诊断流程完全复用
整体来看,Robusta AIOps 的流程设计实现了从“用户自然语言输入”到“结构化诊断报告输出”的完整闭环。在单集群场景下,工作流模式通过四阶段拆解实现了可控且高质量的诊断;在多集群场景下,联邦机制通过并发与智能路由两种方式扩展了系统的分析边界。
两类流程在设计上共享统一的推理与执行能力,使系统既具备单点深度分析能力,又能够进行跨集群的全局洞察,形成完整的 AIOps 诊断体系。
图3-3 4节点工作流流程图
当用户向系统提出运维问题时,例如“Pod 为什么一直在重启?”,请求首先通过统一入口进入系统,并被初始化为一次完整的分析流程实例。系统将该问题作为原始输入交由工作流引擎处理,同时构建本次分析所需的上下文状态,
在第一阶段,系统进入问题识别与定性阶段。该阶段以 LangGraph 的节点调度能力为核心,由大模型推理引擎结合既有的运维 Runbooks,对问题进行语义理解与场景判定。系统会识别当前问题所属的运维层级和问题类型,例如将“Pod 不断重启”归类为工作负载层异常,并进一步识别为 OOMKilled 等典型场景。这一过程需要调用大量工具和fetch runbook来作为额外补充知识用来判定,当前的异常与那个阶段比较契合。比如layer阶段LLM调用了get pod的工具查看到有某个pod 被OOMKIlled了,他会继续调用describe pod工具来查看详细的event,在必要的时候他发现有个额外的知识库runbook有详细的诊断pod OOMkilled的内容,他会获取到这个runbook并且根据runbook里面的指导采集更为全面的信息,用来定性这确实是L2层级的问题。之后输出结构化json信息传递给下一节点。该阶段的目标是将模糊的自然语言问题转化为明确、可操作的分析场景,为后续证据采集提供方向。
完成问题定性后,系统进入第二阶段,即证据驱动的采集阶段。在该阶段,工作流节点根据前一阶段识别出的场景类型比如定位到L2,生成证据采集计划通过调用内置的todo工具生成一个明确的工作计划,计划内容可能包括明确需要采集的日志、指标或资源状态信息。系统随后通过循环调用的方式,这是agent的工具调用的逻辑,通过外部的一个while的loop循环,一直轮询直到ai的输出内容中不包括下一步的tool调用,调用另外的工具pod mcpstander底层工具能力,例如 kubectl、日志接口或 Prometheus 指标查询接口,逐项完成证据采集。所有采集到的数据均以原始文本或结构化 JSON 的形式返回,并被统一汇总为证据链,供后续分析使用。
在证据采集完成后,系统进入第三阶段, 根因分析节点的核心准测是自己检测出的结果必须要有真实数据作为支撑。并且需要json话结构输出,给出因果链的因果关系,通常来说会将evidence阶段采集的真实工具输出和layer阶段分析的异常情况进行逻辑性的关联,确保他们之间是有因果关系。并且根据模型自身的能力来进行分析,是什么原因导致的异常情况。详见核心功能验证的案例输出。
在完成确定性校验后,系统进入第四阶段,即结果收敛与报告生成阶段。该阶段由工作流节点对大模型推理结果与规则判定结果进行整合,形成最终一致的诊断结论。系统会自动生成结构化的诊断报告和修复建议,并以 Markdown 等统一格式输出,便于前端展示和人工阅读。
在整个流程中,LangGraph 负责各分析节点之间的调度与状态流转,大模型推理引擎提供语义理解与分析能力,确定性规则模块负责对结果进行校验和兜底,而底层工具模块则专注于与 Kubernetes 及监控系统交互获取真实运行数据。
核心技术选型与设计理念
在核心推理能力方面,系统选择大语言模型作为智能分析的基础引擎,用于处理用户的自然语言输入并参与诊断决策过程。相比传统依赖固定规则或脚本的运维系统,大语言模型具备更强的语义理解能力和泛化能力,同时,系统将提示词及相关参数统一外置至配置层,使推理策略具备可调节性,从而支持在不修改代码的情况下持续优化模型表现。
为了在智能性与稳定性之间取得平衡,系统在推理层引入了 query模式与工作流模式的双轨设计。query模式基于简单问答问题比如我的集群的cpu使用率是多少?这样的运维问题不需要复杂的信息收集他的功能可能很简单就完成了,系统进一步引入基于 LangGraph 的结构化工作流,将诊断过程拆分为问题定位、证据采集、根因分析与结果汇总四个阶段,并通过显式节点控制执行流程。通过这种方式,系统在关键路径上实现了对推理过程的约束,使整体行为更加稳定和可预测,同时仍保留在复杂场景下的智能扩展能力。
针对多集群场景,系统进一步引入联邦架构,将多个独立集群整合为统一的诊断体系。在设计上,每个集群保持独立的诊断能力也就是每个单集群是单独的agent工作流程,而联邦层负责调度与结果整合。系统提供了并发聚合与智能路由两种模式,其中智能路由模式通过引入 Agent to agent机制,使大语言模型能够根据用户问题动态选择查询目标集群,并逐步扩展分析范围。这种方式将“查询哪个集群”从固定策略转变为动态决策,
综合来看,本系统的技术选型与设计理念可以概括为:在以大语言模型为核心能力引擎的基础上,通过结构化工作流约束不确定性,结合规则引擎提升已知场景的稳定性,并借助联邦架构扩展系统分析范围。同时,通过状态驱动与配置外置实现系统的解耦与持续演进,使整体架构在复杂运维场景下既具备智能性,又保持良好的可控性与工程可落地性。
更新设计
由于后续只能使用本地32Bqwen模型,之前实现的过程中会导致大量的工具输出污染上下文,导致注意力漂移的现象。因此现在更新上下文处理架构。并且更新流式输出token级别开发设计。
背景在当前的业务场景下使用小模型会不可避免的遇到以下稳定性不足问题,
-
长上下文下容易注意力漂移,忘记当前 Pod、namespace、异常状态。
-
工具调用 loop 中容易过度探索、重复调用、按 runbook 全量巡检。
-
结构化输出容易失败,尤其是 JSON/Pydantic schema、RCAOutput、evidence_plan 这类合同。
-
同一种 Pod 异常类型下容易只判断大类,不区分精确根因。
-
最终报告会把次要信号写成主因,例如 Terminating 场景误写 finalizer、OOMKilled、kubelet。
因此有效方法不是继续堆更长 prompt,而是把任务拆成多个硬边界:
用户问题
-> layer:只定位当前异常对象和异常族
-> evidence:只围绕 layer_handoff 采集真实证据
-> rca:只基于 evidence 做因果收敛,不重新调用工具
-> conclusion:只渲染报告,关键指标以后端结构化结果为准
而小模型难以直接迁移大模型的架构的根本原因是小模型的有效注意力、指令遵循、复杂状态管理和结构化生成能力都更弱。Agent 诊断链路又天然包含长上下文、多工具、多阶段状态、多格式输出,因此小模型的问题会被放大。
切换模型遇到的问题与解决
在实际优化的过程中使用小模型进行运维诊断的时候遇到了主要问题乳如下:
| 问题 | 真实表现 | 影响 |
|---|---|---|
| evidence_plan 不稳定 | prompt 要求先写计划,但模型直接调用工具,或计划 JSON 不可解析 | 证据完整度无法可靠计算 |
| RCA 结构化失败 | evidence 已经采集成功,但 RCAOutput 没返回合法 Pydantic 对象 | RCA 走低置信度兜底 |
| 工具摘要缺关键字段 | describe summary 没暴露 preStop、terminationGracePeriodSeconds、finalizers | Terminating 根因误判 |
| 表格输出替代 YAML | 模型计划检查 finalizers/deletionTimestamp,却实际调用普通 get 表格 | 关键字段不可见 |
| runbook 过度执行 | VolumeMountFailed 明明事件显示 configmap not found,模型还继续查 PVC/PV/StorageClass | 耗时增加,根因漂移 |
| 中文语义匹配漏判 | 报告写“配置文件不存在”,自动 signature 只匹配 not found | 评测低估真实准确率 |
| 次要信号盖过主因 | Terminating 场景中看到 Exit Code 137 或 Killing,就写 OOM/kubelet/finalizer | 根因准确率下降 |
| 最终报告幻觉 | 工具输出 finalizers: <none>,conclusion 却写“存在 finalizers” | 用户结论错误 |
这些问题说明:如果只依赖“更详细 prompt”,小模型仍会在工具选择、证据排序和结构化合同上不稳定。
因此整体的架构优化方向上,讲原有的4节点职责进行更详细的划分,
Layer只做扫描当前异常 Pod、识别异常族、匹配 runbook、生成 handoff,这个handoff是下游后续agent消费的主要根因定位的结构化输出,里面包含了异常的pod所在的namespace,pod的状态,以及初步定位可能是什么方面的异常情况。还有一些必要工具,runbooks的匹配记录等。
Evidence节点 按 handoff 和 runbook guide 采集真实证据,在进行证据采集前会让agent输出一个采集计划,用来讲一个复杂的大型任务拆分为一个一个的小task,作为plan中的一个步骤去执行。并且按照前一个节点的结构化输出handoff来做特定方向的分析和探索而不是一个大而全的检查。
Rca节点,基于 evidence 做因果链和根因收敛,他的特点在于不使用工具进行数据采集,只考前面节点的输出进行根本原因的推理和因果关系的收敛。
Conclusion节点作为最后的总结节点渲染出总结报告,并且保留后续的修复计划,方便未来修复操作时候的扩展准备。
并且为了加强小模型的输出稳定性在layer节点和evidecen节点单独增加2个pydnamtic结构化输出中间过程,用于输出可被后续节点稳定消费的标准json形式内容通过这一系列的手段等于把小模型的任务从“全栈自由诊断”降解成多个局部任务。每个局部任务的输入更短、职责更窄、输出更容易校验。
结构化输出
旧的 layer_full_analysis 会把 layer 阶段完整分析和工具原始输出继续传给下游。对小模型来说,这会造成注意力漂移:
-
evidence 忘记主 Pod,去查其他 namespace。
-
RCA 被历史 event 影响,把已恢复的对象当当前故障。
-
conclusion 把 runbook 里的典型原因当真实原因。
```
展开代码片段(16 行)
{
"diagnosis_scope": "question_scope",
"layer": "L1",
"abnormal_pods": [
{"name": "rc-terminating-prestop", "namespace": "aiops-e2e", "status": "Terminating"}
],
"current_abnormal_summary": {
"status_counts": {"Terminating": 1},
"selected_rows": []
},
"pod_status_keyword": "Terminating",
"pod_abnormal_type": "TerminatingStuck",
"matched_runbooks": ["pod-terminating-stuck.md"],
"must_verify": [],
"do_not_change": []
}
```
通过使用pydnamtic包固定json字段的数据结构,确保输出字段的统一性和稳定性,例如上述的结构化输出包含核心信息,abnormal_pods 异常的pod结合,pod_status_keyword异常关键字,matched_runbooks匹配到的runbooks等。layer_handoff 的本质是把“从文本中寻找诊断目标”变成“读取固定字段”。这对小模型很重要,因为小模型在长文本检索和多实体保持上明显弱于大模型。
流式输出
图3-4 Aicall替换大模型调用捕获chunks实现token级别流式输出
详见章节4.1.2说明了为什么holmesgpt不支持高级的流式输出。在未来的实现过程中需要用langchain实现AI call模块替换holmesgpt的大模型调用模块,这样可以避免框架导致的无法对底层输出chunk精细控制的能力。
具体流程如下,通过workflow启动langgraph工作流,当具体任务到达某一个节点时,如 Evidence Node,底层调用的大模型接口需要使用自己开发的ai call模块而不是holmesgpt自带的框架,启用astream模式调用agent,该模式可以支持最细粒度的message chunk捕获,传统的ai call模式为invoke()(一次性等待)。所以无法获取到“token”级别的输出。
之后将原始的chunk打包为ai_token事件推送到event quene队列中。这部分为信息源的生产者。
接下来workflow executor持续的从event quene中获取到事件然后持续的yield为输出内容,后续没来一个token就直接输出实现按token级别的流式输出。
上下文管理设计
由于切换到小模型导致上下文太多产生了注意力漂移问题,现在详细的分析下之前的设计情况下为什么会导致大上下文内容,并且给出新的预计实现的上下文新的设计结构。
图3-5 大模型上下文详细分析
旧链路中有几个典型问题:
-
layer_full_analysis 会把 layer 阶段的完整分析和工具原始输出继续传给 evidence、RCA、conclusion。
-
同一份工具结果可能重复出现在 layer_full_analysis、下游 prompt、thinking_events、最终报告上下文里。
-
重型 K8s 工具如 kubectl_describe、kubectl_get_yaml、kubectl_get_by_kind_in_cluster 可能返回很长内容。
-
evidence 节点曾经把大量上游内容拼到 system prompt,导致模型容易忘记“必须调用工具”这类硬约束。
总体来说,之前上下文较多的关键因素在于,工具比较重型,执行一个kubectl describe pod 命令会有超过1000字符的内容输出,其次工具没有做任何处理就将全部内容附加到上下文中。这使得llm在后续循环中会被大量“噪音”影响而不知道自己的主线任务,同一份输出分析会在多个节点中同时出现提示词,think_evnet中。Evidence节点错误的将部分内容拼接到了system提示词,而不是user prompt中导致指令的权重影响性不同。
针对上述问题提出新的上下文管理规范设计
图3-6 新型上下文管理架构设计
主要是增加了一个中间的obetain中间件过程。他负责将所有大模型调用的工具在返回前截断,通过自己处理比如基于规则的匹配,基于条件的过滤。而得到少量的核心的高质量信息,并且生成3个文件一个是001-xxxtool-.raw 全量文件,代表工具执行的全部输出,一个structured.json文件,存储这通过特殊规则抓取到的结构化输出。下图展示了落盘的存储文件形式和内容。
图3-7 工具执行结果落盘文件划分
图3-8 基于规则抓取的信息文件
这样可以将大量无用的或者不重要的信息去除掉,只保留比较重要的异常信息。最后是summary.txt这是真实返回给llm的结果。通过全量数据被结构化规则抓取后的少量高质量信息的总结,反馈给大模型,极大的减少全量工具的无用信息返回。有效的减少了工具之间的上下文传递。
并且实现了read_context_archive工具,让llm在有必要的情况下去参考原始的文件信息。避免基于规则的过滤和抓取丢失了关键信息。经过初步测试。
每个工具结果都被 ObservationProcessor 处理成三类产物:
raw.txt 完整原始输出,供人工复盘
structured.json 规则提取出的结构化事实
summary.txt 回注给 LLM 的短摘要
按工具看:
kubectl_describe 90,134 -> 4,473 减少 95.0% kubectl_get_by_kind_in_cluster 495,949 -> 55,198 减少 88.9% kubectl_get_by_kind_in_namespace 52,145 -> 7,293 减少 86.0% kubectl_get_yaml 135,030 -> 20,897 减少 84.5% kubectl_run_image 28,757 -> 10,971 减少 61.8% kubectl_events 1,462 -> 833 减少 43.0% execute_prometheus_instant_query 6,195 -> 6,195 减少 0.0% kubectl_get_by_name 3,603 -> 3,603 减少 0.0%
后台根据不同的工具配置了不同的规则提取方式,经过单次测试有上述的结果。针对重型工具进行大量提取,针对中等或者小输出内容的工具还是会全量返回。
自动修复
修复能力没有侵入原有诊断链路。原有工作流仍然先完成只有在请求显式传入 remediate=true,并且后端配置 workflow.remediation.enabled=true 时,才会在 conclusion 之后追加修复执行阶段:
诊断报告
-> 从报告中解析结构化修复计划
-> 根据配置选择 deterministic executor 或 react agent executor
-> plan 审批
-> action 审批
-> kubectl dry-run / execute / verify
-> 输出 remediation_finished
- 两种执行器
deterministic 执行器
RemediationExecutor 是固定计划执行器。它不再询问 LLM 下一步,只按报告里的 actions 顺序执行:
plan approval
-> action approval
-> dry_run_command
-> execute_command
-> verify_command
-> 下一个 action
特点:
-
行为可预测,适合简单、确定的资源修复。
-
每个写动作前都可以人工审批。
-
verify_command 输出中如果仍包含 OOMKilled、CrashLoopBackOff、ImagePullBackOff、BackOff、0/1 等异常标记,会返回 needs_followup。
-
如果所有 action 都执行并验证通过,返回 success。
react/LLM Agent 执行器
RemediationAgentExecutor 是当前更灵活的修复执行器。它把报告中的计划当作初始约束和参考,然后多轮读取真实工具结果,由 LLM 决定下一步。
循环结构:
plan approval
-> iteration 1:
LLM 读取 report + remediation_plan + observations
LLM 输出 AgentDecision JSON
如为写命令,先 action approval
执行 dry_run / command / verify
记录 observation
-> iteration 2:
LLM 基于新 observation 决定继续验证、继续修复或结束
-> finish success/failed/timeout
Agent 每一轮必须输出 JSON:
通过在最后conclsuion节点输出 json 修复操作指南,进入到下一个执行修复的节点。这个节点的功能比较简单,他会根据上一部分输出的修复计划,将它通过userprompt的形式注入到agent中,agent配置了少量的k8s相关工具用来执行和处理k8s资源。但是由于模型能力较差,所有会有多段审阅模式,第一段是用户查看生成的计划,认可计划的修复方案才会进入的修复agent工作中。下面给出结构化的修复计划
以实际例子为例,比如现在我们有一个pod处于异常状态
然后运行我们的智能运维助手,在输出的报告后端会有一个交互场景。是否认可修复方案,是否执行修复,
人工审查同意后,agent会自动执行相应的命令。
然后我们就看到异常的pod被处理了,回复正常,完成了一次自动修复的能力。
Agent可观测性
在实际的使用过程中经常会遇到agent整体运行状态未知,传入的上下文具体插入的提示词,工具调用,返回,模型思考链路等每一步详细的过程不可感知的问题。特别引入langfuse可观测性模块来实现对agent调用全链路的解析。需要在开发的agent上为每一轮对话提交给ai的call加上特定的session参数,修改提交json构建为符合langfuse数据结构标准的内容时可以进行有效的观测。
之后agent发送的请求都可以在langfuse根据session串起来
可以观测到所有传入给大模型的提示词,选然后的注入内容,以及每一轮ai的思考和输出,工具调用,传入工具的参数,工具的返回值。
同时也可以看到详细的调用token以及相应延迟,全方位对agent应用的运行过程观测监控起来方便细致的优化和了解发展方向。
新的测试体系
在以往根因定位只需要匹配到异常所在的层级及所谓的根因确定,但是这样的定位方式过于宽松,因此这次真的pod的常见异常状态如volumemountfailed、pending、terminating、oomkilled、crashloopbackoff、imagepullbackoff、sandboxcreatefailed、configerror等状态,每个case中有1-5个根因场景如对于pod处于pending状态来说常见的场景是nodeselecor-丢失,insufficient-cpu,memory资源不够调度,还有missing-pvc丢失pvc导致无法调度到某个节点上。通过一个异常group多个常见的异常case的形式设计测试。并且输出的形式要包含核心的关键字。而不是之前简单的层级匹配,现在是关键case+关键字的精确匹配来区分ai是否可以定位到某个异常pod状态的本次根本原因(包含特定关键词)
目前测试覆盖的group为
| Group | 覆盖场景 |
|---|---|
| volumemount | ConfigMap/Secret/ConfigMap key/PVC/hostPath |
| pending | nodeSelector/CPU/Memory/PVC |
| imagepull | invalid registry/image not found/missing pull secret |
| crashloop | 非零退出码/命令不存在/配置文件缺失 |
| configerror | env 缺失/ConfigMap key 缺失/Secret key 缺失 |
| oomkilled | memory limit 过低 |
| notready | readiness/liveness probe |
| terminating | finalizer/preStop/long grace |
| sandbox | RuntimeClass handler 无效 |
| evicted | ephemeral-storage/emptyDir 驱逐 |
总结
在更新设计的时候做了非常多的尝试和多个方面的探索,总结下来以下的主要改动对小模型稳定消费结构书数据并且在有限上下文中保持性能的主要修改如下:
优化提示词,减少容易和多余的配置,简化提示词避免文本占用过多迷失目标,如果一个节点需要复杂的提示词那么就把它拆分成多个步骤来多个节点或者功能去实现,而不是做一个大而全的节点搞定全部的事情,这点在小模型使用场景中尤其重要。
结构化输出layer_handoff,节点之间的消费主要通过结构化的字段来通信和消费,而不是以往的大段文字中进行文本间的意图识别。而直接可以通过python进行代码层面的核心关键字段的提取和维护。
工具压缩,通过吧重型工具拆解, 过滤的方式只反馈回重要的部分比如pod的event事件,yaml中container,initcontainer的核心字段,并且工具文件过程落盘方便后续人工排查和优化处理逻辑。
Runbook guide化, 缩小搜索空间,减少泛化巡检。
rootcause E2E,减小根因定位的空间吗,通过特异性case与关键词匹配的方式定位根因准确性。
整个过程中最关键的反方论在于三层收敛:
第一层:收敛输入。
不要把所有信息都给模型。
只给当前节点完成任务所需的最小事实。
完整原文落盘,不进入默认 prompt。
第二层:收敛输出。
关键节点使用 Pydantic。
计划、证据、根因、查询结果都要有 schema。
下游只消费校验后的对象。
第三层:收敛评价。
用 E2E signature 测具体根因。
不只看模型说得像不像。
把低准确率 case 反向用于修 prompt、修工具摘要、修评测口径。
这轮小模型稳定化的核心工作量体现在三件事:
第一,重新定义了小模型 Agent 的工作边界。小模型不再被要求一次性完成“查全量上下文、理解所有 runbook、规划证据、调用工具、判断根因、写报告”的全流程,而是在四节点工作流中完成局部任务。
第二,建立了可审计的数据合同。工具结果有 raw/structured/summary,节点输出有 Pydantic schema,跨节点传递有 layer_handoff,评测有 rootcause signature。这样模型的每一步都可以被复盘,而不是只看最终自然语言。
第三,用真实 E2E 数据驱动迭代。1300 次诊断结果表明,工程约束能让 32B 小模型在多数 Pod 异常根因诊断中达到可用水平;
所以,这项工作的本质不是“把 prompt 写得更长”,而是把小模型放进一个受控诊断系统中:让它做擅长的语义理解和解释,让代码承担结构、上下文、证据、统计和可审计性。这样才能在小模型能力有限的情况下获得稳定输出。