跳到主要内容

询问哪个模型产生了哪个输出的合规审计

· 阅读需 11 分钟
Tian Pan
Software Engineer

审计员的问题听起来很简单。她翻开你的申诉日志,指着八个月前的一行,询问是哪个模型决定了那个案例。你的工程师调出了 Schema:有一个 model 列,审计窗口内的每一条决策都显示为 v1。接着,平台团队的一位成员随口提到,在审计期间,v1 背后的别名(alias)轮换了四次——一次基础模型升级、一次微调刷新、一次供应商侧的容量迁移,以及一次在事故期间持续了六个小时的回滚。诚实的回答是,你无法确定是哪一个 Checkpoint 产出了那个决策。审计员记录下了一些内容。那个回答不是监管机构能接受的答案,而你刚刚意识到,你交付的系统未能满足一项它从未被设计去满足的审计要求。

这里的差距不在于缺失了一行日志,而在于对“模型”含义的两种不同理解。对于交付系统的工程师来说,v1 是一个 Endpoint——一个稳定的契约,调用者可以指向它,而其背后的东西则可以免费升级。对于审计员来说,“产生此决策的模型”是一个特定的 Artifact:一个权重 Checkpoint、一个哈希值,一个原则上你可以在相同的输入上重新运行并获得具有辩护一致性输出的东西。Endpoint 别名是为了向调用者隐藏 Checkpoint 的轮换而发明的。而审计级的溯源要求恰恰相反——每一项决策都必须能追溯到产出它的确切 Checkpoint。这两个想法从一开始就处于碰撞轨道上;审计只是它们相遇的地方。

Endpoint 不等于模型

别名的便利性是真实存在的。你发布的代码调用 model: "v1"model: "claude-sonnet-latest" 或内部的 risk-scoring-prod,这样当其背后的模型发生变化时,你不必每次都重新部署。在供应商侧,同样的便利性甚至更有价值:供应商可以轮换模型版本、弃用旧的快照并重新定向容量,而无需强制每个客户发布新版本。OpenAI 的别名 Endpoint 就是这样运作的,Anthropic 也因为同样的原因被要求提供类似的 -latest 别名。这种模式是行业标准;如果你发现一个生产环境中的 AI 系统完全没有在某处使用它,那才是不寻常的。

问题在于,“模型”是一个多义词,而别名在合规目的下悄悄选择了错误的含义。当数据团队构建仪表板并在每个决策旁存储 model = "v1" 时,他们存储的是 Endpoint 名称,而不是 Artifact。Endpoint 名称作为审计原语(primitive)几乎是毫无用处的,因为该 Endpoint 计算的函数在审计窗口内并不是恒定的。你并没有在 2 月份对客户的案例运行“v1”,然后在 5 月份对几乎相同的案例运行相同的“v1”——你运行的是通过同一个字符串可达的两个不同的 Checkpoint。在审计日志中存储 Endpoint 名称,大致相当于存储“生产数据库”而不是特定的行。

这是隐式版本控制问题最昂贵的形式。原本旨在将工程团队从协作税中解放出来的别名 Endpoint,结果变成了另一种形式的隐性协作税——这笔税必须由合规团队在审计员的注视下补缴。

审计级溯源(Provenance)的实际要求

监管框架正在迅速收敛为一个特定的形态。欧盟 AI 法案(EU AI Act)的第 10 条要求提供版本控制记录和溯源信息,以便在数据集和模型版本之间实现可追溯性;第 12 条要求自动记录事件,以便对输入、输出和决策点进行全流程追踪。美联储修订后的模型风险管理指南——即之前的 SR 11-7,并于 2026 年 4 月更新——保持了相同的核心要求:模型是一个 Artifact,而不是别名,机构必须能够指明产出任何给定决策的具体 Artifact。在 ECOA 和 FCRA 下的不利行为制度(Adverse-action regimes)使这一要求在消费者信贷领域变得具体化,如果你不知道是哪个模型生成的评分,就无法诚实地履行“主要原因”解释义务。

将监管语言翻译过来,要求是:对于你的 AI 系统做出的每一个对人产生下游影响的决策——信贷拒绝、理赔驳回、内容下架、福利认定——你都应该能够根据要求提供确切的 Checkpoint 标识符,以及一份能让第三方了解该 Checkpoint 行为的记录。“我们使用模型 v1”无法达到这个标准。而“这个决策是由 Checkpoint sha256:7b3f... 产出的,该 Checkpoint 已在我们的模型注册中心(model registry)登记,并附有其 Model Card 和评估概况”则可以。

一个有用的测试:假设审计员要求你在决定该案例的同一个模型上重新运行一遍。你能做到吗?如果诚实的回答涉及“我们需要询问供应商他们是否还托管着那个 Checkpoint”,那么你的溯源就低于审计级。如果诚实的回答是“我们不能,因为生产 Endpoint 之后已经轮换了”,那么你的溯源也低于审计级。这里的标准是“相对于 Checkpoint 的可复现性”,而不是“相对于 Endpoint 名称的可复现性”。

漂移是如何在无人察觉的情况下发生的

令人沮丧的是,没有任何单一的变更看起来像是违反了合规性。平台工程师升级了 v1 背后的底层模型,因为供应商弃用了旧快照 —— 他们别无选择。供应商在不同模型版本之间轮换容量以平衡负载 —— 他们一直以来都是这么做的。MLOps 团队在同一个内部端点后换入了一个新鲜微调的变体,因为他们想在不与每个调用方协调的情况下发布 —— 这正是端点抽象的用途。在一次事故中持续六小时的回滚,在公司大多数人还没看到页面之前就已经被撤销了。

这些操作中的每一个单独来看都是合理的。它们的叠加导致了这样一个结果:“v1 在同一个审计窗口内意味着四个不同的检查点”。而且,由于每次轮换在调用端都是不可见的 —— 请求仍然显示 model: "v1",并返回一个与之前响应结构相同的响应 —— 因此在应用程序代码、请求日志或决策日志中,没有任何内容会标记这种漂移。审计日志记录了端点,而端点什么也没记录。

有一种次要的失效模式值得一提:即使团队知道他们应该固定版本,他们也经常固定在错误的地方。固定操作发生在控制下一个请求的配置文件或环境变量中,而不是发生在记录上一个决策的审计日志中。如果配置在请求时间和审计时间之间发生了轮换,审计日志继承的是今天的配置内容,而不是做出决策时的内容。溯源信息(Provenance)必须在决策时捕获并随决策一起存储,而不是稍后从已经发生变化的配置中推导出来。

在决策时固定检查点

这种架构上的修复虽然平淡无奇,但却非常值得去做。在产生决策的那一刻,系统捕获供应商实际提供的检查点标识符,并将该标识符与决策一起持久化在同一次写入、同一个事务中。不是端点名称,不是别名,而是具体的检查点。

对于自托管模型,这很简单:你控制推理服务器,你知道加载的是哪个检查点,并且可以将权重哈希附加到每个响应中。对于托管 API,这需要更多的规范。大多数供应商会在响应中返回某种形式的版本标识符 —— OpenAI 返回系统指纹(system fingerprint)和特定的模型名称,Anthropic 在响应中返回解析后的模型,主要的推理网关也暴露了类似的字段。规范的做法是读取该字段,而不是调用方请求的字段,并记录供应商返回的那个字段。

以下是直接得出的一些实践:

  • 将请求 model 字段和响应 model 字段视为不同的列。 请求字段记录了你想要什么。响应字段记录了你得到了什么。审计查询读取响应字段。如果你的模式(schema)只有一列,那么你的审计回答的是错误的问题。
  • 能哈希的就哈希,不能哈希的就引用。 对于自托管权重,存储权重哈希。对于托管 API,存储供应商提供的任何稳定标识符,加上该模型卡(model card)的快照或供应商当天发布的行为说明。目标是让未来的审计员在原则上能够推断出标识符背后的产物 —— 而不是要求你自己拥有权重数据。
  • 在网关层固定别名,而不是在应用程序代码中。 如果你的平台提供 v1 作为内部别名,那么从 v1 到具体检查点的解析应该发生在一个受控的网关中,并由该网关记录解析过程,而不是在调用服务中随意处理。统一的解析点为你提供了一个统一的审计位置。
  • 将轮换视为一个带有记录的事件。 当别名背后的检查点发生变化时,该变化应该产生持久的记录 —— 谁轮换的、什么时候轮换的、从什么轮换到什么、有哪些评估证据。这样,任何决策的审计故事都有两个层面:每个决策对应的检查点标识符,以及让你能够解释为什么那天在使用该检查点的轮换历史。

决策日志的写入会稍微变重,模式也会增加几列。这就是全部的代价。而不这样做的代价,就是审计员在开头提到的那种谈话。

架构变动背后的组织行动

更深层次的变化是将模型注册表视为合规性的记录系统,而不是 ML 团队的工具。一个记录了每一个曾被推向生产环境的检查点的注册表 —— 包括其哈希、评估概况、训练数据血缘、生产使用日期范围,以及将流量切入和切出的轮换事件 —— 才是让公司能够毫不退缩地回答审计员问题的产物。注册表是索引;逐条决策日志是指针;它们共同构成了一个可查询的历史记录,说明“哪个产物决定了什么,以及在那个时刻,该产物是基于什么证据在生产环境中被信任的”。

这也是这项工作在组织归属上的意义所在。决策日志是应用层的关注点,但检查点身份是平台层的关注点。平台团队拥有解析别名的网关。平台团队拥有记录检查点的注册表。应用团队负责将解析后的标识符写入决策日志的规范。合规团队拥有对这些标识符可查询的要求。这些参与方中没有任何一方能独立完成这项工作,而审计正是揭示了哪条缝隙被漏掉了。

大多数团队留下的缝隙是最简单的一个:没有人规定决策日志中的模型字段指的是检查点(checkpoint)而不是端点(endpoint)。没有这个规定,该字段就默认采用了最简单的方式,即端点,因为端点是调用代码所知道的内容。审计级的修复很小,审计级的规范是选择在记录“模型”的每一层都捕获产物身份,并拒绝在监管机构提问时用别名代替产物。审计员最终会问的,你希望答案已经存在于模式(schema)中。

References:Let's stay in touch and Follow me for more thoughts and updates