Aklman · Library

18 / 第十八章

治理与控制平面 · 审计、熔断与多租户.

企业问的不是「它做对了吗」,是「它做的每件事能不能被授权、被追溯、被叫停」—— 这层能力长在平台上,不长在单个 agent 里。


前两章给了 agent 身份、给它套了对抗防线。这一章问的是另一类问题:它做的每一件事,能不能被授权、被追溯、被叫停、被限住成本 —— 而且这套能力不该长在单个 agent 里,得长在一个平台上,让所有 agent 共享。第十、十一章埋过 trace 和预算闸;这一章把它们收进一个控制平面的形状:审计链、急停开关、多租户隔离。企业不问「它做对了吗」,问「它做的一切留没留下账」。

I

治理是贯穿式的,不是发布前盖一个章.

很多人把「治理」想成上线前的一次合规评审 —— 盖个章,放行。这是把它当成一道门。真正的治理是一层,渗进每一步。 NIST 的 AI 风险管理框架把这件事说得最清楚。它有四个核心功能:GOVERN「在设计、开发、部署、评估、采购 AI 系统的组织内培育并落实风险管理的文化」;MAP 建立情境、框住风险;MEASURE 用定量与定性方法分析、基准、监控;MANAGE 分配资源、执行响应与恢复计划。关键在 GOVERN 的定性 —— 它是「一个贯穿式功能,渗透进整个 AI 风险管理、并使其他功能得以运转」,不是并列的第一步,是渗进另外三步里的那一层。1注 1NIST · AI Risk Management Framework 1.0(NIST AI 100-1,2023-01-26)—— 四个核心功能:GOVERN「在设计/开发/部署/评估/采购 AI 系统的组织内培育并落实风险管理的文化」,且被描述为「一个贯穿式功能,渗透进整个 AI 风险管理、并使其他功能得以运转」;MAP 建立情境框住风险;MEASURE 用定量/定性方法分析、基准、监控风险;MANAGE 分配资源、执行响应/恢复/沟通计划。框架「供自愿使用」。 为什么这层这么要紧?因为生产 agent 的事故大多不是技术事故。有一份工程观察说得直接:多数生产 agent 的失败是治理失败,不是技术失败 —— 没人定义「成功长什么样」、没有熔断、没有触发人审的点;而光维持一个 agent 正常跑,据其观察能吃掉三到五成工程预算。5注 5Composio ·「Why AI Agent Pilots Fail in Production」(2026)—— 观察:多数生产 agent 事故是治理失败,不是技术失败 —— 没定义成功、没熔断、没人审的触发点;维持 agent 运行据观察可吃掉三到五成工程预算。作为工程观察引用,非标准。(这是一手工程观察,不是标准,也不是普查数字 —— 当经验之谈看,别当定论。)它和 OWASP Agentic Top 10 里 ASI10「Rogue Agents」、ASI08「Cascading Failures」指的是同一类东西:不受控、会传染的失败。2注 2OWASP · Top 10 for Agentic Applications 2026 —— ASI10 Rogue Agents、ASI08 Cascading Failures、ASI03 Identity and Privilege Abuse 是治理层最相关的三条:失控 agent、级联失败、身份与权限滥用。条目名以官方 PDF 目录为准。

II

审计轨迹与急停:留得下账,停得下来.

治理落到最硬的两样:每个行动可归因、可追溯(审计),和任何时候能一键全停(kill switch)。这两样都得土 —— 土到断网、面板挂了照样成立。 先分清审计和 trace(第十章)的不同。trace 是给你 debug 的:决策、工具、token、延迟,尽可能详。审计是给事后追责的:谁(哪个 principal)、干了什么、判定是什么(allow / deny / gated)、结果如何 —— 少而准,且不可篡改。两者受众不同,别塞一个文件。工程里 audit.py 用一条 append-only 的 JSONL,每行带上一行的哈希成链:改任何一行,链在那里断,verify_chain() 能指出第几行断的。这就是最小可用的防篡改 —— 不接区块链、不接外部服务,一个哈希链就把「日志被人删了一行」变成看得见的。
def record(self, **event) -> None:
    row = {"ts": ..., "prev": self._prev, **event}      # prev 串起上一行
    line = json.dumps(row, ensure_ascii=False, sort_keys=True)
    self._prev = _digest(line)                          # 本行摘要,喂给下一行
    with self.path.open("a", encoding="utf-8") as f:    # append-only
        f.write(line + "\n")
 
def verify_chain(path) -> tuple[bool, int]:
    prev = "genesis"
    for i, line in enumerate(Path(path).read_text("utf-8").splitlines()):
        if json.loads(line).get("prev") != prev:
            return False, i        # 链在第 i 行断 —— 有人改过/删过
        prev = _digest(line)
    return True, len(lines)

audit.py:哈希链 + 校验(每行 prev = 上一行的摘要)

审计的字段可以直接复用现成标准,不必另造:OpenTelemetry 的 GenAI 语义约定给了 LLM/agent 调用一套标准 trace/span 字段(模型、token、工具调用),你的审计条目对齐它,就能接进现有监控体系。4注 4OpenTelemetry · GenAI 语义约定 —— 为 LLM/agent 调用定义标准的 trace/span 字段(模型、token、工具调用等),让可观测性可移植、可对接现有监控。审计与追踪可以复用这套字段,不必另造。截至 2026-07。 另一样是急停(kill switch)。它的唯一要求是「一定停得下来」,所以它必须土:工程里就是一个文件哨兵 —— 该文件存在,循环每一步开头 kill.check() 抛异常,一步都不执行。为什么用文件而不是一个 API?因为出事的时候,你的服务可能正是挂掉的那个 —— 一个 touch .kill_switch 不依赖任何在跑的东西,SRE 半夜从跳板机就能拉。急停停的是「继续」,不是「已经在途的那一步」——所以它要配第十一章的幂等:停下来能恢复、恢复不重放动手动作。

III

控制平面:这层能力属于平台,不属于 agent.

前两节的东西,你可能想「加进我的 agent 就好」。别。身份、鉴权、审计、急停、限速、成本 —— 这些是每个 agent 都要的横切能力。把它们塞进每个 agent,你就有了 N 份实现、N 个会漏的地方。它们该在一个共享的控制平面里,agent 从它经过。 控制平面就是把这些横切关注点分层,堆成一条每个动作都要穿过的管道。从下往上:身份(agent 是谁、替谁)→ 运行时(沙箱、隔离)→ 上下文(带权限的检索,第四章)→ 网关(换模型不改工作流)→ 工具(scope 鉴权、白名单)→ 评测与追踪(回归门禁、trace、审计)→ 审批与降级(人闸、熔断、fallback)。一个动作从上到下穿过每一层,任何一层都能拦。这张分层图不是装饰 —— 它是下一章 capstone 参考架构的骨架。
  一个 agent 动作


  ① 审批 / 降级   人闸(ch9) · 熔断 · 模型 fallback
  ② 评测 / 追踪   回归门禁(ch10) · trace · 审计链(本章)
  ③ 工具         scope 鉴权(身份章) · 白名单(ch9) · 污点/出网(对抗章)
  ④ 网关         model gateway —— 换模型不改工作流 · 成本/限速
  ⑤ 上下文       带权限的检索(ch4) —— 先过滤再检索
  ⑥ 运行时       沙箱 · 一次性工作区(ch7) · 多租户隔离
  ⑦ 身份         workload identity · 委托(身份章) · 每租户凭据


     执行(或被某一层拦下,进审计)

控制平面的七层:每个动作从上到下穿过,任一层可拦

最后一根支柱是多租户。同一套 agent 服务多个租户(客户、团队、部门)时,最硬的一条是数据隔离:租户 A 的检索永远不能碰到租户 B 的数据 —— 这条线要划在检索层(第四章讲的「带权限的检索」正是为此),而不是指望 prompt 里写一句「别串租户」。除隔离外,还有每租户的配额与限速(防噪声邻居:一个租户跑飞的循环不该拖垮其他所有人 —— 对应 OWASP LLM10 Unbounded Consumption3注 3OWASP · Top 10 for LLM Applications 2025 · LLM10:2025 Unbounded Consumption —— agent 循环天然会失控烧钱/算力;预算与上限是生产前的必备(官方条目名逐字)。),和每租户的配置。工程里 Principal 带了 tenant_id,就是这条线的锚点:审计按它归因、检索按它过滤、配额按它计。 动手 · 把治理的三样接一次:
01

开审计,跑一遍,改一行,验一次

--audit audit.jsonl 跑一遍,手改中间某一行的 decision,再跑 verify_chain() —— 确认它精确指出链在第几行断。
02

半路拉一次急停

touch .kill_switch 再跑 —— 确认 0 步执行、审计里记了一条 kill_switch。删掉文件,恢复正常。这就是你半夜能依赖的那个开关。
03

画出你自己 agent 的控制平面

照上面七层,对着你自己的 agent 逐层问:这一层我有没有?没有的那几层,就是你离企业级还差的距离 —— 也是下一章要你一次搭齐的。

能停得下来、留得下账的 agent, 才配放进一家公司。.

An agent you can stop and that leaves a record is one fit to place inside a company..

Aklman Library

讨论

讨论.

评论区初始化中…