AI SRE Agent 的 ODD:护栏不该替模型思考

AI SRE Agent 的 ODD:护栏不该替模型思考

最近在思考 AI SRE / AI 运维 Agent 的工程化落地时,有一个问题很关键:

ODD 如果靠人工定义,那模型是不是会显得很笨?

这个问题非常尖锐。

如果所谓 ODD 只是人把每种告警、每条排障路径、每个根因判断都提前写好,那模型确实会显得很笨。这样的系统本质上不是 AI Agent,而是:

Runbook + LLM 外壳。

模型只负责把固定流程包装成自然语言,看起来很智能,实际没有太多自主推理能力。

但这并不意味着 ODD 不重要。恰恰相反,生产级 AI SRE Agent 必须有 ODD。问题在于:

ODD 不应该替模型思考,它应该只定义责任边界和安全底线。

一、什么是 AI SRE Agent 里的 ODD?

ODD 原本来自自动驾驶,全称是 Operational Design Domain,即设计运行域。

自动驾驶里的 ODD 会限定:

  • 哪些道路;
  • 什么天气;
  • 什么速度;
  • 哪些区域;
  • 哪些车辆状态。

对应到 AI SRE / AI 运维 Agent,ODD 可以理解成:

什么场景可以由 Agent 自主处理?
什么资源可以访问?
哪些工具可以调用?
哪些动作必须审批?
满足什么证据条件才能下结论?
什么情况下必须停止并交给人?

比如一个 Kubernetes 只读排障 ODD 可能限定:

支持:
- Pod CrashLoopBackOff
- Pod Pending
- OOMKilled
- ImagePullBackOff
- 探针失败

允许:
- 查询 Pod 状态
- 查询 Events
- 查询 Deployment
- 查询容器日志
- 查询 Prometheus 指标
- 查询最近发布记录

禁止:
- 删除 Pod
- 修改 Deployment
- 读取 Secret 明文
- 执行任意 kubectl exec
- 直接执行生产写操作

必须转人工:
- 目标不唯一
- 历史指标缺失
- 工具连续失败
- 证据互相矛盾
- 涉及生产写变更

这就是 ODD 的作用:定义 Agent 的运行边界。

二、错误做法:把 ODD 写成固定 Runbook

最容易犯的错误,是把 ODD 写成固定步骤。

例如磁盘告警:

disk_alert:
  step1: run df -h
  step2: run du -sh /*
  step3: run lsof +L1
  decision:
    if_deleted_file_found:
      root_cause: deleted_file_held_by_process

这种写法看起来很清晰,但问题是:人已经把所有事情都决定完了。

人决定了:

  • 先查什么;
  • 后查什么;
  • 用什么命令;
  • 看到什么输出对应什么根因;
  • 最终应该怎么总结。

模型在里面只剩下一个作用:

把结果说得像人话。

这就会让模型显得很笨。

因为它不是在推理,而是在执行预设流程。

这种系统更像传统自动化脚本:

告警类型
→ 固定命令
→ 固定判断
→ 固定回复

它可以有价值,但它不是一个真正的 AI Agent。

三、正确做法:ODD 定义边界,模型负责推理

更合理的 ODD 应该长这样:

scope:
  target_type:
    - linux_host
  access:
    - readonly
  asset_source:
    - cmdb

constraints:
  forbidden:
    - filesystem_write
    - process_kill
    - service_restart
    - arbitrary_network_access

quality_gate:
  diagnosis_requires:
    - at_least_one_historical_signal
    - at_least_one_direct_system_evidence
    - no_unresolved_evidence_conflict

handoff:
  when:
    - target_ambiguous
    - evidence_unavailable
    - suspected_data_corruption
    - action_requires_write

这里没有规定:

  • 必须先执行 df
  • 必须再执行 du
  • 必须最后查 lsof
  • 最终根因必须是什么。

它只规定:

你在哪个范围内可以行动;
哪些动作绝对不能做;
下结论需要哪些最低证据;
什么时候必须停下来。

在这个边界内,模型仍然可以动态推理。

例如同样是磁盘告警,Agent 可以根据现场情况选择不同路径。

一种情况:

历史指标显示磁盘突然上涨
→ 当前 df 确认磁盘仍高
→ du 没找到大文件
→ 怀疑 deleted-open-file
→ 查 lsof +L1
→ 发现 Java 进程持有已删除日志文件
→ 得出结论

另一种情况:

历史指标显示磁盘缓慢增长
→ du 发现 backup 目录持续增大
→ 查最近备份任务
→ 发现保留策略失效
→ 得出结论

这才是 Agent 的价值:

ODD 不替模型走路,只规定它不能开出悬崖。

四、模型显得笨,很多时候不是因为 ODD

很多 AI 运维 Agent 表现得笨,不是因为有 ODD,而是因为系统给模型的感知和工具太差。

最常见的低质量工具是:

{
  "name": "execute_command",
  "arguments": {
    "command": "..."
  }
}

这等于让模型同时负责:

  • 选择命令;
  • 编写 shell;
  • 处理转义;
  • 理解内部环境;
  • 保证安全;
  • 从大段文本输出里找证据。

这不是高级抽象,而是把太多脏活都丢给模型。

更好的工具接口应该是结构化的:

resolve_asset
query_metric
search_logs
inspect_workload
get_k8s_events
get_recent_changes
lookup_topology
search_similar_cases
request_handoff

例如:

{
  "tool": "query_metric",
  "input": {
    "target": "payment-api",
    "metric": "error_rate",
    "start": "2026-07-31T10:00:00+08:00",
    "end": "2026-07-31T10:30:00+08:00",
    "aggregation": "rate_5m"
  }
}

工具返回也不应该只是一段原始文本:

{
  "status": "success",
  "evidence": [
    {
      "type": "metric_anomaly",
      "signal": "error_rate",
      "before": "0.2%",
      "after": "18.4%",
      "started_at": "10:03"
    }
  ],
  "limitations": []
}

这样模型才能把推理资源用于:

  • 假设生成;
  • 证据选择;
  • 因果判断;
  • 根因排序;
  • 结论表达。

而不是浪费在 shell 语法和文本清洗上。

五、生产级 Agent 的三层结构

一个比较合理的 AI SRE Agent 架构,可以分成三层:

┌─────────────────────────────────────┐
│ 第一层:Policy / ODD                │
│ 判断是否在支持范围内,限制工具和动作 │
└─────────────────┬───────────────────┘
                  ↓
┌─────────────────────────────────────┐
│ 第二层:Agent Reasoning             │
│ 形成假设、选择工具、关联证据、判断根因 │
└─────────────────┬───────────────────┘
                  ↓
┌─────────────────────────────────────┐
│ 第三层:Execution Runtime           │
│ 执行、超时、审计、幂等、状态恢复、回滚 │
└─────────────────────────────────────┘

模型位于中间。

上层 Policy 决定:

当前能做什么?
不能做什么?
需要审批吗?
是否超出 ODD?

下层 Runtime 保证:

动作如何安全执行?
执行失败如何处理?
状态如何持久化?
日志如何审计?
是否可以恢复?

模型负责:

应该查什么?
为什么查?
查完后说明了什么?
下一步假设是什么?
证据是否足够?

一句话:

模型负责思考,工程系统负责边界。

六、不要用巨大 Prompt 代替工程边界

很多系统会把安全规则都塞进 system prompt:

你不能执行危险命令。
你不能访问未授权系统。
你不能读取 Secret。
你不能修改生产环境。
磁盘告警应该先查 df。
CPU 告警应该查 top。
K8s 告警应该查 pod events。
...

这样做有两个问题。

第一,prompt 越来越长,模型注意力被大量禁令占用。

第二,prompt 不是可靠安全边界。

真正应该做的是:

Policy Engine
  → 在模型调用前过滤可用工具

Typed Tools
  → 用 Schema 限制参数

Risk Engine
  → 判断是否需要审批

State Machine
  → 控制当前允许的状态转换

Execution Gateway
  → 统一执行、审计、回查

模型看到的应该是当前状态下可用的少量安全工具,而不是一万字禁令。

例如只读调查阶段,模型只看到:

query_metrics
search_logs
inspect_k8s
get_recent_changes
lookup_topology
request_handoff

进入建议动作阶段,才允许它提出:

propose_restart
propose_rollback
propose_scale

至于能不能执行,不由模型决定,而由系统决定。

这叫:

通过能力暴露限制行为,而不是通过文字命令限制行为。

七、ODD 不应该完全靠人从零手写

这里还有一个关键点。

ODD 的最终责任需要人确认,但 ODD 不应该完全靠人从零手写。

更好的方式是:

历史 Case
+ Agent Trace
+ 工单
+ 复盘报告
+ 人工接管记录
+ 最终根因
→ 模型聚类
→ 模型生成候选 ODD
→ SRE 审核
→ 自动评测
→ 灰度上线

例如系统可以从历史事故中发现:

过去 240 个 Pod 启动失败 Case 中:
- 65% 是配置或 Secret 问题
- 20% 是镜像问题
- 10% 是存储问题
- 5% 超出当前工具能力

然后模型生成一个候选 ODD:

name: k8s_pod_startup_failure

scope:
  alert_types:
    - CrashLoopBackOff
    - ImagePullBackOff
    - CreateContainerConfigError
    - Pending

required_context:
  - cluster
  - namespace
  - pod_or_workload
  - incident_time_window

allowed_actions:
  - k8s.get_pod
  - k8s.get_events
  - k8s.get_logs
  - k8s.get_previous_logs
  - k8s.get_deployment
  - metrics.query
  - changes.get_recent_deploys

forbidden:
  - k8s.delete_pod
  - k8s.patch_deployment
  - k8s.read_secret_value
  - shell.exec

handoff:
  - target_ambiguous
  - secret_value_required
  - storage_backend_unknown
  - production_write_required

SRE 不需要从空白 YAML 开始,只需要审核:

这个范围是否太大?
哪些动作应该禁止?
哪些证据是必须的?
哪些情况必须转人工?

这就变成了:

模型发现规律,人确认责任边界,系统持续评测。

八、动态 ODD:扩大和收缩都应该由数据驱动

ODD 不应该一旦定义就不变。

上线后应该持续统计:

  • 目标识别准确率;
  • 工具选择准确率;
  • 关键证据覆盖率;
  • 根因判断准确率;
  • 人工推翻率;
  • 接管率;
  • 工具失败率;
  • 越权请求拦截率;
  • 执行后验证成功率。

如果某类场景表现稳定,可以扩大 ODD:

过去 500 次 CrashLoopBackOff 调查中:
- 目标识别准确率 99.6%
- 关键证据覆盖率 97.8%
- 人工推翻率 1.1%

建议将“上一容器日志可用”的场景加入自主诊断范围。

如果错误率升高,就应该自动收缩 ODD。

这和自动驾驶类似。

不是一开始就让车上所有路,而是先限定区域,然后根据验证结果逐步扩大。

九、智能程度不等于自由度

一个常见误区是:

Agent 权限越大
能执行的命令越多
越能自由发挥
= 越智能

实际上,生产系统里常常相反。

一个真正成熟的 Agent,应该知道:

  • 什么能做;
  • 什么不能做;
  • 什么时候证据不足;
  • 什么时候必须停止;
  • 什么时候需要人接管;
  • 什么结论不能说得太满;
  • 什么动作不能直接执行。

所以:

知道什么时候不做,比什么都会做更接近生产级智能。

如果一个 Agent 可以随便执行 shell、访问主目录、继承 SSH agent、读取云凭据、调用所有 MCP 工具,这不叫智能,这叫风险暴露。

十、AI SRE 产品的启示

如果要做一个可信的 AI SRE Agent,不应该把重点放在:

再加一个大模型
再写一段 prompt
再堆一个 Runbook
再开放更多命令

而应该建设这些底座:

Case Context
Policy / ODD Engine
Typed Tool Gateway
Evidence Store
Approval Service
Audit Ledger
State Machine
Evaluation Harness

Agent 的主链路应该是:

飞书/告警输入
→ 创建 Case
→ 解析上下文
→ 判断 ODD
→ 暴露当前允许工具
→ Agent 动态调查
→ 工具结果进入 Evidence Store
→ 结论引用证据
→ 不足则转人工
→ 动作进入 Approval
→ 执行后回查
→ 全过程审计

在这个架构里:

人:定义责任和风险
模型:发现规律并动态推理
工程系统:强制边界并验证结果

十一、总结

ODD 如果被人工写成固定步骤,模型一定会显得很笨。

但问题不在 ODD,而在于把 ODD 做错了。

正确的 ODD 不应该替模型思考。

它应该定义:

边界
权限
风险
证据要求
退出条件
责任范围

模型则负责:

理解问题
提出假设
选择工具
关联证据
判断根因
解释结论

最终可以总结成一句话:

ODD 是护栏,不是司机。

或者换成 AI SRE 的说法:

工程系统负责不让 Agent 越界,模型负责在边界内把问题查明白。

真正聪明的 AI SRE Agent,不是没有护栏,而是:

护栏只限制危险行为,不替它思考。

所以生产级 AI SRE 的方向不是“手写一堆 ODD 让模型照着做”,而是:

模型从历史 Case 中发现候选 ODD
人类审核责任边界
系统用评测和线上数据持续验证
Agent 在 ODD 内动态推理
超出 ODD 时可靠交还给人

这才是从“会说话的 Runbook”走向真正 AI SRE Agent 的关键。

快速参考

  • ODD 是运行边界,不是固定排障流程。
  • 不要把 ODD 写成 Runbook,否则模型只剩润色能力。
  • 模型看起来笨,往往是因为工具抽象和上下文质量太差。
  • 安全边界不要靠 prompt,应该靠 Policy Engine、Typed Tool 和 Execution Gateway。
  • ODD 最好由历史 Case 自动发现候选,人类审批责任边界,系统持续评测。
  • 生产级 Agent 的关键能力不是“什么都能做”,而是“知道什么时候不能做”。
posted @ 2026-07-31 20:19  Hello_worlds  阅读(10)  评论(0)    收藏  举报