学习目标
学完本章你应该能够:
- 用一句话解释 AIOps 是什么,并讲清 Gartner 五阶段(Observe → Analyze → Engage → Act → Evolve)各自解决什么问题、为什么多数公司卡在 2-3 阶段。
- 写出一个"角色 + 上下文 + 约束“三段式 Prompt 模板,说清为什么
Context段的有无直接决定诊断准确率。 - 区分 Few-shot / CoT / 结构化输出 在运维场景的用处,并讲清 ReAct 与 Plan-and-Execute 的差异与各自适用场景。
- 画出 LLMOps 从数据 → 训练 → 评测 → 部署 → 监控的完整生命周期,说清反馈如何回流到数据准备。
- 在面试里把 Agent(感知/推理/执行)、Function Calling、Embedding/RAG 讲成一套落地方案,并点出"危险动作必须人工确认"这条红线。
前置知识:
- 基本的大模型使用经验(用过 ChatGPT 类对话工具即可)。
- 了解 Prometheus / K8s 等运维概念更好,但不强制;文中的运维例子都能当背景故事读。
- 能看懂简单的 Python 代码(不要求会写)。
本章你会动手做的事:
- 用文中的三段式 Prompt 模板,填一个真实故障现象,观察模型输出质量的变化。
- 给"日志分类"的 Few-shot 模板补几条你自己业务的样例,看分类准不准。
- 用 LangChain 跑最小运维 Agent,故意让它"建议重启数据库”,验证你加的红线约束是否拦得住。
AIOps 的定义与演进
AIOps 是将人工智能技术应用于 IT 运维领域的统称。Gartner 提出 AIOps 平台应能够摄取多源数据(指标、日志、链路、事件),利用机器学习和大数据分析实现异常检测、根因分析、容量预测和自动化修复。
随着大语言模型(LLM)的兴起,AIOps 正在从传统的"基于规则的自动化"和"基于统计的机器学习",演进到"具备理解、推理和执行能力的智能体(Agent)“阶段。
Gartner 五阶段:你在哪一级
Gartner 把 AIOps 演进划成五个阶段,我自己给每阶段加了个"人话版"描述:
| 阶段 | 含义 | 人话版 |
|---|---|---|
| 1. Observe | 采集数据,做可视化 | 监控大屏好看但没用,告警靠人盯 |
| 2. Analyze | 规则/统计做异常检测 | 阈值告警,5xx > 1% 报警,但噪声巨大 |
| 3. Engage | 自动聚类、关联、根因推荐 | 同一故障的多个告警合并,给出"可能根因 top 3” |
| 4. Act | 自动化响应、自愈 | 检测到 OOM 自动重启 Pod,磁盘满自动清理 |
| 5. Evolve | 闭环学习、持续优化 | 每次处置后回流数据,模型/规则自动迭代 |
白话:这五个阶段其实就是运维从"人盯屏幕"到"机器自治"的进化史。绝大多数公司停在 2-3,不是因为 4-5 做不到,而是自动执行动作风险太高——你敢让 AI 半夜自动重启数据库吗?所以现实里大家先把"告警降噪、根因推荐"做扎实,离"全自动闭环"还远。
下面把五个阶段画成一条递进的能力阶梯,注意它是一条"越往上越自动、也越危险"的路:
flowchart LR
S1[1 Observe
采集可视化] --> S2[2 Analyze
规则统计检测]
S2 --> S3[3 Engage
聚类关联根因]
S3 --> S4[4 Act
自动响应自愈]
S4 --> S5[5 Evolve
闭环学习]说实话大部分公司卡在 2-3 之间。第 4 阶段 Act 真正能跑起来的场景很少——主要是运维动作风险高,自动执行出错可能比故障本身还致命。我见过一个"自动重启"策略把数据库主节点重启了,业务直接挂 30 分钟。
实际落地场景
我亲手做过或者近距离看过的几个 AIOps 落地场景,按 ROI 排序:
- 告警降噪与合并:基于规则 + LLM 把同一故障的几十条告警合成 1 条工单,研发不再被飞书轰炸。ROI 最高。
- 日志摘要:故障发生时 LLM 自动读取近 10 分钟相关 Pod 日志,给出"问题摘要 + 可能原因"。值班同学处理速度提升 30%+。
- NL2Query:业务同学用自然语言查 PromQL / SQL,不用再求 SRE 写查询。
- 故障知识库 RAG:把历史复盘文档、SOP 入向量库,出问题时直接问"订单服务 500 怎么处理",召回相似故障的处置步骤。
- 自动扩缩容决策:LLM 不直接执行,而是给出"建议扩容到 N 副本"的方案,人工点确认后执行。这个不敢全自动,风险太高。
大模型基础与运维场景落地
大模型(如 GPT、Claude、Llama、Qwen 等)具备强大的语言理解、代码生成和推理能力。在运维场景中,其落地方式主要包括:
- 自然语言转查询(NL2Query):将运维人员的自然语言问题转换为 PromQL、SQL、KQL 等查询语句。
- 日志与事件摘要:对海量日志进行压缩、聚类,提取关键异常信息。
- 故障根因推理:结合可观测数据与知识库,辅助定位问题根因。
- 脚本与配置生成:自动生成 Shell、Python、YAML 等运维脚本。
- 智能问答与知识库:基于 RAG 技术构建运维知识助手。
运维 Prompt 模板:角色 + 上下文 + 约束
LLM 用得好不好,70% 看提示词。下面是我线上在用的一个"故障诊断助手"prompt 模板,拆成三段:
# 角色(Role)
你是一名有 10 年经验的资深 SRE,擅长 Kubernetes、Prometheus、Go 后端排障。
你的回答风格:直接、简洁、给可执行的命令,不要复述用户问题。
# 上下文(Context)
## 故障信息
- 服务:order-service(Go 1.22,K8s 集群 prod)
- 现象:5xx 错误率从 0.1% 涨到 15%,持续 8 分钟
- 告警时间:2025-11-01 14:32:00
## 相关指标(最近 10 分钟)
- CPU 使用率:85%(常态 40%)
- 内存使用率:92%,Pod OOMKilled 3 次
- P99 延迟:从 200ms 涨到 3.2s
- 错误日志样本:
"context deadline exceeded" x 432
"connection refused (db:3306)" x 128
## 架构信息
- order-service → MySQL(主从)+ Redis(哨兵)
- 上游:api-gateway,下游:payment-service
# 约束(Constraint)
1. 优先级最高的根因放第一条,不要列超过 3 条
2. 每个根因配 1 个验证命令(kubectl / mysql / redis-cli)
3. 不要建议重启数据库,这是生产主库
4. 如果信息不足,明确说"需要补充 XX 指标",不要瞎猜
这个模板我用了一个月,比之前那种"你是 SRE,请帮我分析故障"的弱 prompt 准确率高一截。关键是 Context 段——把告警、指标、日志样本全塞进去,模型不用猜,直接推理。
踩坑提示:约束段一定要写"不要建议重启数据库"这种红线。我有次没写,LLM 给的方案是"建议重启 MySQL 主库",差点被值班同学照做。生产库里任何"重启"动作都得人工审批。
提示词工程与任务规划
Prompt Engineering
提示词工程(Prompt Engineering)是引导大模型产生高质量输出的关键技术。常用技巧包括:
- 角色设定:让模型扮演"资深 SRE"或"K8s 专家"。
- 上下文示例(Few-shot):提供输入输出示例,提升输出稳定性。
- Chain-of-Thought(CoT):要求模型分步思考,提高复杂推理准确率。
- 结构化输出:指定 JSON、Markdown 等输出格式,便于下游系统解析。
- 约束与边界:明确限制回答范围,避免幻觉。
Few-shot 在运维的例子:日志分类
下面是个日志分类的 few-shot 示例,给 3 个正反例之后,模型对新日志的分类准确率从 60% 涨到 90%+。
# 任务
对下面的运维日志进行分类,从以下 4 类中选一个:
- NETWORK:网络相关(连接超时、拒绝、DNS 失败)
- RESOURCE:资源相关(CPU/内存/磁盘/文件句柄)
- DEPENDENCY:下游依赖故障(DB/Redis/MQ)
- APPLICATION:应用逻辑错误(panic、空指针、业务异常)
# 示例
日志:dial tcp 10.0.1.5:3306: connect: connection refused
分类:DEPENDENCY
日志:OOMKilled (exit code 137)
分类:RESOURCE
日志:panic: runtime error: invalid memory address or nil pointer dereference
分类:APPLICATION
日志:i/o timeout
分类:NETWORK
# 待分类
日志:{input_log}
分类:
CoT 在运维的例子:根因推理
简单一问"为啥 Pod 起不来",模型容易瞎猜。加一句"请按以下步骤分析"就靠谱很多:
# 任务
分析 Pod `order-service-abc123` 为什么起不来。请按以下步骤推理:
Step 1:列出可能的原因类别(镜像/资源/配置/依赖/权限)
Step 2:针对每个类别,给出对应的事件/指标验证方法
Step 3:根据下面提供的实际事件,排除不可能的类别
Step 4:得出最可能的根因,并给出修复命令
# 实际事件
Events:
- FailedScheduling 3m 0/3 nodes available: 3 Insufficient memory
- FailedScheduling 3m 0/3 nodes available: 3 Insufficient memory
模型输出大概会是这样:
Step 1:可能原因
- 资源:节点内存不足,无法满足 Pod requests
- 配置:resources.requests.memory 设得过大
- 调度:节点数太少
Step 2:验证方法
- kubectl describe node | grep -A5 Allocated resources # 看节点内存分配
- kubectl get pod -o yaml | grep -A3 resources # 看 Pod 资源请求
Step 3:根据事件排除
- 事件明确写 "3 Insufficient memory",所以是资源问题
- 不是镜像拉取失败(没有 ImagePullBackOff)
- 不是配置错误(资源配置是合法值,只是节点装不下)
Step 4:根因与修复
根因:3 个节点剩余内存都不够,Pod 一直 Pending
修复:
# 方案 A:临时扩节点
kubectl scale nodegroup prod-ng --size 5
# 方案 B:降低 Pod 资源请求(如果业务允许)
kubectl patch deployment order-service --type=json \
-p='[{"op":"replace","path":"/spec/template/spec/containers/0/resources/requests/memory","value":"256Mi"}]'
踩坑提示:CoT 推理的输出会很长,记得在 prompt 末尾加"只输出 Step 4 的最终结论给值班同学看,Step 1-3 放到 details 字段",否则飞书消息会刷屏。
Planning 在运维自动化中的应用
复杂运维任务往往需要多步执行。任务规划(Planning)模块负责将高层目标拆解为可执行的子任务。例如"自动扩容"可拆解为:
- 采集当前 CPU/内存/QPS 指标。
- 判断是否需要扩容。
- 调用 K8s API 修改 Deployment 副本数。
- 持续观察扩容效果。
- 若异常则回滚并告警。
规划能力可以通过 LLM 直接生成计划,也可以结合 ReAct、Reflexion 等 Agent 框架实现。
ReAct vs Plan-and-Execute
这两个是 Agent 规划的主流范式,我对比一下:
| 维度 | ReAct | Plan-and-Execute |
|---|---|---|
| 核心思想 | 思考→行动→观察,循环往复 | 先生成完整计划,再逐步执行 |
| 计划生成 | 每一步动态决策,没有全局计划 | 一次性生成所有步骤 |
| 错误恢复 | 自然,每步都能根据观察调整 | 需要 Re-plan,复杂 |
| Token 消耗 | 高(每步都要重新思考) | 低(计划只生成一次) |
| 适合场景 | 探索性任务、信息不确定 | 步骤明确、需要严格审计 |
| 运维例子 | 故障根因排查(每步结果决定下一步) | 标准化发布流程(步骤已知) |
白话:ReAct 像侦探办案——看到线索(Observation)就推理一步(Thought),推理出该查什么就去查(Action),查到新线索再推理,循环到能下定论。Plan-and-Execute 则像按 SOP 办事——先把所有步骤列好,再一步步执行,中途不灵活但好审计。
下面把 ReAct 的"思考→行动→观察"循环画成图:
flowchart TD
T[Thought 思考] --> A[Action 调用工具]
A --> O[Observation 观察结果]
O --> T
O -->|得出答案| F[Final Answer]举个故障排查的 ReAct 例子:
Thought: 用户报告 order-service 500 错误。先看 Pod 状态。
Action: kubectl get pods -n prod | grep order-service
Observation: 3/4 Running,1 个 CrashLoopBackOff
Thought: 有 Pod 在崩溃。看崩溃原因。
Action: kubectl logs <crashed-pod> -n prod --tail=100
Observation: panic: redis: connection refused
Thought: Redis 连不上。确认 Redis 是否正常。
Action: kubectl get pods -n infra | grep redis
Observation: redis-master-0 Running,但 READY 0/1
Thought: Redis 起来了但没就绪。看 Redis 事件。
Action: kubectl describe pod redis-master-0 -n infra
Observation: Liveness probe failed: NOAUTH Authentication required
Thought: 找到根因——Redis 密码变了但 order-service 没更新配置
Final Answer: 根因是 Redis 密码被修改,order-service 仍用旧密码连接。
修复:更新 order-service 的 Secret。
Plan-and-Execute 适合发布流程:
Plan:
1. 拉取最新镜像 v1.5.0
2. 在 staging 部署,跑冒烟测试
3. 生产灰度 10% 流量,观察 10 分钟
4. 全量发布
5. 监控 SLO 1 小时,无异常则完成
Execute step 1: ...
Execute step 2: ...
踩坑提示:ReAct 在运维场景里要小心"无限循环"——模型一直思考但永远给不出结论。要么在 prompt 里写"最多 5 步,超过则停止并给出当前推断",要么在代码层加 max_iterations=10 的硬限制。
LLMOps 完整流程体系
LLMOps 是指大模型应用从开发到运维的全生命周期管理。说白了就是把 DevOps 那套搬到 LLM 应用上,但比传统应用复杂——因为模型本身是个"黑盒",输出不确定性高。
完整流程:数据 → 训练 → 评测 → 部署 → 监控
┌────────────────────────────────────────────────────────────────┐
│ 1. 数据准备 │
│ - 原始数据采集(日志/告警/SOP/文档) │
│ - 清洗、去重、脱敏(密钥、PII 必须处理) │
│ - 标注:人工标注金标问答对 │
│ - 向量化:embedding 模型把文档转成向量 │
│ 工具:DVC / LakeFS / Unstructured / LangChain loaders │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ 2. 模型选择与训练 │
│ - 基座选型:GPT-4 / Claude / Qwen / Llama(看预算和合规) │
│ - Prompt 工程:写 system / few-shot │
│ - 微调(可选):SFT 监督微调、DPO 偏好优化 │
│ 工具:OpenAI SDK / vLLM / LLaMA-Factory / Axolotl │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ 3. 评测(Evaluation) │
│ - 离线评测:准确率 / 召回率 / BLEU / ROUGE │
│ - 业务评测:是否解决工单、是否被人工接管 │
│ - 红队测试:prompt 注入、越狱、敏感问题 │
│ 工具:RAGAS / DeepEval / Promptfoo / 自建 benchmark │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ 4. 部署推理 │
│ - 模型服务:vLLM / TGI / Triton / SGLang │
│ - 接入层:FastAPI + 限流 + 缓存 │
│ - 流量灰度:1% → 10% → 100% │
│ 工具:BentoML / Ray Serve / KServe / LiteLLM │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ 5. 监控与反馈 │
│ - 性能:延迟 P50/P99、吞吐、错误率 │
│ - 质量:用户点赞/踩、人工接管率、幻觉率 │
│ - 成本:token 消耗、API 费用 │
│ - 安全:prompt 注入次数、敏感输出 │
│ 工具:LangSmith / Phoenix / Langfuse / OpenLLMetry │
└────────────────────────────────────────────────────────────────┘
↓
反馈回流到数据准备阶段
白话:LLMOps 就是把 DevOps 那套"开发→测试→上线→监控"搬到 LLM 应用上,只是多了个绕不开的环节——评测。因为模型是黑盒、输出会飘,你不评测就不知道它退化了。上面那张 ASCII 图里的箭头最后"回流到数据准备",就是闭环学习的意思。
下面用更紧凑的流程图再画一遍,方便你记面试要点:
flowchart TD
D1[数据准备
采集/清洗/标注/向量化] --> D2[模型与训练
选型/Prompt/微调]
D2 --> D3[评测
离线/业务/红队]
D3 --> D4[部署推理
vLLM/灰度]
D4 --> D5[监控反馈
延迟/质量/成本/安全]
D5 -->|回流| D1LLMOps 工具链速查
| 阶段 | 主流工具 | 我用过的 |
|---|---|---|
| 数据版本 | DVC、LakeFS、Hugging Face Datasets | DVC(跟 git 配合,能 track 大文件) |
| 文档处理 | Unstructured、LangChain Loaders、LlamaIndex | Unstructured(PDF 解析最稳) |
| Embedding | bge-large-zh、text-embedding-3-small、Cohere | bge(中文场景首选,自部署免费) |
| 向量库 | Milvus、Qdrant、Weaviate、Chroma、pgvector | Milvus(大规模)、pgvector(小项目快) |
| 微调 | LLaMA-Factory、Axolotl、Unsloth | LLaMA-Factory(Qwen 微调最方便) |
| 推理服务 | vLLM、TGI、SGLang、Triton | vLLM(吞吐最高,Qwen/Llama 通吃) |
| 评测 | RAGAS、DeepEval、Promptfoo | RAGAS(专门评 RAG) |
| 可观测 | LangSmith、Langfuse、Phoenix、OpenLLMetry | Langfuse(开源自部署,省费用) |
| 网关 | LiteLLM、Portkey | LiteLLM(多模型统一接口) |
踩坑提示:评测阶段很多人跳过,直接看 demo 效果就上线,结果线上效果一塌糊涂。最低限度也得建个 50-100 条金标问答的 benchmark,每次改 prompt 都跑一遍,看准确率有没有倒退。我团队就这么干的,省了好几次回滚。
Agent、Function Calling、Embedding 运维落地原理
Agent
Agent 是具备感知、推理和行动能力的智能体。运维 Agent 通常包含:
- 感知层:读取指标、日志、事件、告警。
- 推理层:LLM 进行理解、规划、决策。
- 执行层:调用工具或 API 完成实际操作。
类比:运维 Agent 就像一个"带对讲机的抢修小组"。感知层是小组的眼睛耳朵(看监控、读日志);推理层是大脑(LLM 判断哪里坏了、下一步干啥);执行层是手(真去敲 K8s 命令、调 API)。三者形成一个"看→想→做→再看"的闭环。
下面把这三层的关系画出来:
flowchart LR
P[感知层
指标/日志/事件/告警] --> R[推理层
LLM 理解规划决策]
R --> X[执行层
工具/API 实际操作]
X -->|结果| P下面是个最小可用的运维 Agent 架构(Python + LangChain):
# ops_agent.py —— 最小运维 Agent
from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI
from langchain.tools import Tool
from kubernetes import client, config
# 加载 K8s 配置
config.load_kube_config()
def get_pod_status(namespace: str) -> str:
"""查询指定 namespace 下 Pod 状态"""
v1 = client.CoreV1Api()
pods = v1.list_namespaced_pod(namespace)
lines = []
for p in pods.items:
lines.append(f"{p.metadata.name}: {p.status.phase}")
return "\n".join(lines)
def scale_deployment(input_str: str) -> str:
"""扩容 Deployment,输入格式:namespace/dep_name:replicas"""
# 关键:解析参数要严格校验,防止 LLM 传奇怪值
try:
target, replicas = input_str.split(":")
namespace, dep_name = target.split("/")
replicas = int(replicas)
if replicas < 1 or replicas > 20:
return f"非法副本数 {replicas},允许范围 1-20" # 硬限制,防止 LLM 扩到 100
except Exception as e:
return f"参数解析失败: {e}"
apps = client.AppsV1Api()
body = {"spec": {"replicas": replicas}}
apps.patch_namespaced_deployment_scale(dep_name, namespace, body)
return f"已将 {dep_name} 扩容到 {replicas} 副本"
# 定义工具
tools = [
Tool(
name="get_pod_status",
func=get_pod_status,
description="查询 K8s Pod 状态,输入 namespace 名"
),
Tool(
name="scale_deployment",
func=scale_deployment,
description="扩容 Deployment,输入格式 namespace/dep_name:replicas"
),
]
# 初始化 Agent
llm = ChatOpenAI(model="gpt-4o", temperature=0) # temperature=0 保证稳定
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
max_iterations=5, # 硬限制,防止无限循环
early_stopping_method="generate"
)
# 跑起来
result = agent.run("查看 prod 命名空间 Pod 状态,如果有 Pod 不健康就扩容到 5 副本")
print(result)
踩坑提示:Agent 自动扩容这种危险动作,绝对不能直接执行。我生产里的做法是 Agent 给出建议,推到飞书让值班同学点"确认"按钮,回调之后才真正调 K8s API。全自动执行只在 staging 环境放开。
Function Calling
Function Calling 允许 LLM 根据用户意图生成结构化函数调用参数。例如模型可以输出:
{
"name": "scale_deployment",
"arguments": {
"namespace": "prod",
"deployment": "api-gateway",
"replicas": 5
}
}
系统解析后调用真实函数,并将结果返回给模型继续推理。
完整 JSON 工具定义
下面是一份完整的 OpenAI Function Calling 工具定义,运维场景常用:
{
"tools": [
{
"type": "function",
"function": {
"name": "query_prometheus",
"description": "查询 Prometheus 指标。仅支持已知的安全 PromQL,禁止使用子查询。",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "PromQL 表达式,例如 rate(http_requests_total[5m])"
},
"start": {
"type": "string",
"description": "起始时间,ISO 8601 格式"
},
"end": {
"type": "string",
"description": "结束时间,ISO 8601 格式"
}
},
"required": ["query"]
}
}
},
{
"type": "function",
"function": {
"name": "scale_deployment",
"description": "扩缩容 K8s Deployment。需要人工确认后才真正执行。",
"parameters": {
"type": "object",
"properties": {
"namespace": {
"type": "string",
"description": "命名空间"
},
"deployment": {
"type": "string",
"description": "Deployment 名称"
},
"replicas": {
"type": "integer",
"minimum": 1,
"maximum": 20,
"description": "目标副本数,范围 1-20"
}
},
"required": ["namespace", "deployment", "replicas"]
}
}
},
{
"type": "function",
"function": {
"name": "restart_pod",
"description": "重启指定 Pod。仅用于非数据库 Pod。",
"parameters": {
"type": "object",
"properties": {
"namespace": {
"type": "string"
},
"pod_name": {
"type": "string"
},
"reason": {
"type": "string",
"description": "重启原因,会记录到审计日志"
}
},
"required": ["namespace", "pod_name", "reason"]
}
}
},
{
"type": "function",
"function": {
"name": "search_knowledge_base",
"description": "搜索运维知识库,返回历史故障复盘、SOP 文档。",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词"
},
"top_k": {
"type": "integer",
"default": 3,
"minimum": 1,
"maximum": 10
}
},
"required": ["query"]
}
}
}
],
"tool_choice": "auto"
}
Python 侧调用示例:
# function_calling.py —— OpenAI Function Calling 示例
import json
from openai import OpenAI
client = OpenAI()
# 可用工具映射
AVAILABLE_FUNCTIONS = {
"query_prometheus": query_prometheus,
"scale_deployment": scale_deployment,
"restart_pod": restart_pod,
"search_knowledge_base": search_knowledge_base,
}
def run_agent(user_query: str):
messages = [
{"role": "system", "content": "你是运维助手,能调用工具处理 K8s/Prometheus 相关任务。"},
{"role": "user", "content": user_query}
]
# 第一轮:模型决定调哪个函数
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=TOOLS, # 上面那份 JSON
tool_choice="auto"
)
msg = response.choices[0].message
# 如果模型决定调用工具
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
func_name = call.function.name
args = json.loads(call.function.arguments)
# 关键:执行前校验权限和参数
if func_name in ("scale_deployment", "restart_pod"):
# 危险动作,必须人工确认
approved = ask_human_approval(func_name, args)
if not approved:
result = "用户拒绝执行该操作"
else:
result = AVAILABLE_FUNCTIONS[func_name](**args)
else:
result = AVAILABLE_FUNCTIONS[func_name](**args)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": str(result)
})
# 第二轮:模型基于工具结果生成最终回答
final = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=TOOLS
)
return final.choices[0].message.content
return msg.content
def ask_human_approval(action: str, args: dict) -> bool:
"""推飞书消息给值班同学,等点确认按钮"""
# 实际实现省略,返回 True/False
return True
踩坑提示:Function Calling 的 description 字段千万别省略,模型靠它判断该不该调这个函数。我有次只写 "scale_deployment",结果模型该扩容时不扩、不该扩时瞎扩。把 description 写成"扩缩容 K8s Deployment,需要人工确认"之后,调用准确率立刻上来。
Embedding
Embedding 将文本、日志、文档等转换为高维向量,用于语义检索。结合向量数据库(如 Milvus、Weaviate、Chroma),可实现运维知识库的语义搜索与 RAG。
RAG 完整架构
┌─────────────────────────────────┐
用户问题 │ Query Rewriting(查询改写) │
"订单 500" ────→ │ 改成检索友好的关键词 │
│ "订单服务 500 错误 故障排查" │
└──────────────┬──────────────────┘
↓
┌──────────────────────────────────┐
│ Embedding Model(bge-large-zh) │
│ 把 query 转成 1024 维向量 │
└──────────────┬──────────────────┘
↓
┌────────────────────┴────────────────────┐
↓ ↓
┌────────────────────┐ ┌──────────────────────┐
│ 向量检索(语义) │ │ BM25 检索(关键词) │
│ Milvus / pgvector │ │ Elasticsearch │
│ Top-K = 10 │ │ Top-K = 10 │
└─────────┬──────────┘ └──────────┬────────────┘
└────────────────────┬─────────────────────┘
↓
┌──────────────────────────────────┐
│ Reranker(bge-reranker-base) │
│ 精排,取 Top 3 │
└──────────────┬──────────────────┘
↓
┌──────────────────────────────────┐
│ LLM 生成回答 │
│ 上下文:召回文档 + 告警信息 │
│ 输出:根因 + 处置步骤 + 引用来源 │
└──────────────────────────────────┘
白话:RAG 就是给 LLM 配一个"开卷考试"的资料包。用户提问先改写成好检索的关键词,转成向量去资料库里找最像的几段,再用 Reranker 精排,最后把"问题 + 召回资料"一起喂给 LLM 生成答案,并附上引用来源。没有这个资料包,LLM 只能凭记忆瞎编(幻觉)。
下面把 RAG 的检索链路画成流程图:
flowchart TD
Q[用户问题] --> QW[Query 改写]
QW --> E[Embedding 向量化]
E --> V[向量检索 + BM25 混合]
V --> RR[Reranker 精排 Top3]
RR --> L[LLM 生成回答
根因+步骤+来源]文档入库流程:
# index_docs.py —— 文档入库
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain_milvus import Milvus
# 1. 加载文档(复盘 markdown、SOP、Confluence 导出)
from langchain.document_loaders import DirectoryLoader
loader = DirectoryLoader("./docs", glob="**/*.md")
docs = loader.load()
# 2. 切块:每块 500 字符,重叠 50,保证上下文不断
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n## ", "\n### ", "\n\n", "\n", "。", " "]
)
chunks = splitter.split_documents(docs)
# 3. Embedding:bge-large-zh,中文场景最稳
embeddings = HuggingFaceEmbeddings(
model_name="BAAI/bge-large-zh-v1.5",
model_kwargs={"device": "cpu"} # 没 GPU 就 CPU,慢点但能跑
)
# 4. 存 Milvus
vectorstore = Milvus.from_documents(
documents=chunks,
embedding=embeddings,
connection_args={"host": "milvus", "port": "19530"},
collection_name="ops_knowledge"
)
向量库选型对比
| 向量库 | 部署方式 | 性能 | 易用性 | 适合场景 |
|---|---|---|---|---|
| Milvus | 集群部署 | 高(亿级) | 中 | 大规模生产,千万级以上向量 |
| Qdrant | 单机/集群 | 高 | 高(Rust) | 中等规模,重视过滤查询 |
| Weaviate | 集群部署 | 中高 | 中 | 需要 GraphQL 接口 |
| Chroma | 嵌入式 | 低(万级) | 极高 | 原型、本地 demo |
| pgvector | PG 插件 | 中 | 高(SQL) | 已有 Postgres,向量量小(百万级以下) |
| Elasticsearch | 集群部署 | 中 | 高 | 已经在用 ES,不想引新组件 |
我自己的选型经验:
- 原型阶段:Chroma,几行代码就能跑,啥都不用配。
- 小规模生产(百万级向量):pgvector,跟业务库共用一套 Postgres,运维成本最低。
- 大规模生产(千万级以上):Milvus 集群,性能最稳但要配运维。
踩坑提示:Embedding 模型选型一定要看语言。一开始我用 text-embedding-ada-002 处理中文复盘文档,召回率惨不忍睹——英文模型对中文分词和语义理解都不行。换成 bge-large-zh-v1.5 之后立刻好转。中文场景 bge 系列真的是首选。
另一个坑:chunk_size 不是越小越好。我试过 200 字符的小块,召回很准但每块信息太少,LLM 拼不出完整答案。500 字符 + 50 重叠是我反复试出来的甜点值,你的数据可能不一样,多试几个。
AIOps 四大核心价值
- 运维自动化:将重复性、规则明确的操作交给智能体执行,降低 Toil。
- 排障预测:通过时序预测与异常检测,提前发现潜在故障。
- 资源优化:基于负载预测自动扩缩容,提升资源利用率。
- 业务创新:释放运维人力,支持更快速的业务迭代与实验。
总结
AIOps 不是简单的"AI + 运维工具",而是数据、算法、工程与组织流程的深度融合。掌握 LLM、Prompt Engineering、LLMOps、Agent 与 Function Calling 等知识栈,是后续开发智能运维系统的基础。
说真的学到这里你会发现一个矛盾:AIOps 想做的事情(自动决策、自动执行)和运维的本质诉求(稳定、可控)天然冲突。我现在的看法是——AIOps 在很长一段时间内都不会是"全自动",而是"人机协同":LLM 负责"想",人负责"批",工具负责"做"。能做到这一步就已经比纯人工强太多了。后面真正做 Operator、做 Agent 的时候,再回头品这章,你会发现每个设计都在回答同一个问题:怎么让 AI 帮你干活,但不让它闯祸。
自测题与动手练习
自测题(合上书能答出来,才算懂):
- Gartner 把 AIOps 分成哪五个阶段?为什么多数公司卡在 2-3,而上不到 4-5?
- “角色 + 上下文 + 约束"三段式 Prompt 里,哪一段对故障诊断准确率影响最大?约束段为什么要写"不要重启数据库"这类红线?
- Few-shot、CoT、结构化输出分别治大模型的什么毛病?ReAct 和 Plan-and-Execute 各自适合什么场景?
- LLMOps 的完整生命周期包含哪几步?监控反馈是怎么"回流"的?
- 运维 Agent 的感知层 / 推理层 / 执行层各做什么?为什么"自动扩容、重启 Pod"这类危险动作绝不能全自动执行?
动手练习(建议真做一遍):
- 用三段式模板,把文中 order-service 5xx 的例子填进去;再去掉
Context段跑一次,对比两次输出准确率的差异。 - 给"日志分类"的 Few-shot 模板补 2 条你自己业务的日志样例,观察分类是否更稳。
- 跑最小运维 Agent,把用户问题设成"重启 mysql 主库”,验证你加的红线约束是否拦下这个危险建议。
本章小结
- AIOps 是什么:AI + 运维的深度融合;Gartner 五阶段从 Observe 到 Evolve,多数公司卡在 2-3,因为自动执行风险太高。
- Prompt 工程:角色 + 上下文 + 约束三段式;
Context段决定准确率,约束段写红线(如禁止重启生产库)。 - 任务规划:Few-shot / CoT / 结构化输出提升稳定性;ReAct 适合探索性排查,Plan-and-Execute 适合步骤明确的审计场景。
- LLMOps:数据 → 训练 → 评测 → 部署 → 监控的完整生命周期,反馈回流形成闭环。
- 落地三件套:Agent(感知/推理/执行)= 让 AI 会想会做;Function Calling = 让模型调真实工具;Embedding + RAG = 给模型配开卷资料。核心红线:危险动作必须人工确认。
下一章可以深入"如何把 Agent 接进真实的告警与工单系统",以及"评测体系怎么搭",把这一章的知识栈真正跑成生产可用的智能运维。