权限放开这件事,比较稳的做法不是一次给到位,而是按“读、判断、写”三个阶段依次开,每一阶段都留一个能独立验证的观察点。VM0 在这里承担的角色是一个没有写权限的执行实例(名字可以换成你自己的预发机、影子实例或独立账号),它先把数据链路跑通,只输出建议。等建议和人工判断对得上、偏差集中的环节也收紧了,再把写操作按一条记录、一个白名单字段的粒度放进去。这样每一步出错都能定位在具体阶段,而不是混在“整条链路有问题”里。每阶段放行前,先确认这一阶段的验证方式、回滚方式和不可回滚的边界,再决定是否进下一阶段。
先给 VM0 只读凭据,跑通读取与判断并输出建议,用审计日志确认没有写调用;再把建议与人工实际决定逐条比对,偏差集中在哪就收紧哪条判断条件;之后才开写回,并限定单条记录、字段白名单;写操作要先有确认点或回滚路径,并写清不可回滚的部分;批量放开前用小批量试运行核对条数与结果,出现比例之外的异常就退回上一阶段。
第一阶段只做读取和判断,输出建议但不写回任何系统
这一阶段要验证的不是“判断准不准”,而是数据拿得全不全、拿得对不对。读取范围建议按链路需要反推:先把完成一次判断所必需的数据源列成清单,写明每项的库表、接口、目录或文件前缀,然后给 VM0 创建一个只覆盖这份清单的凭据。宁可清单写窄一点,先跑通一条窄链路,也不要一上来给全库只读——全库只读虽然不带写副作用,但一旦判断出错,你分不清是数据源缺失还是逻辑写错。
- 读取范围:按“完成一次判断所需”列清单,逐项写明数据源与字段,凭据只授权这些项。
- 建议输出形式:写到独立的建议表、独立输出目录或日志文件,字段里带上输入标识、判断结果、判断依据和生成时间,不要写进业务表。
- 不写回的确认方式:三层都看一遍——凭据是否只是只读角色、链路出口权限是否禁写、运行日志里能否找到任何写调用记录。
# 通用接入骨架,按实际环境替换字段名与路径
mode: read_only
dry_run: true
output:
target: file # 或独立建议表
path: /var/log/vm0/suggestions/
input_scope:
- source: orders_view # 只映射到视图或只读副本
fields: [id, status, updated_at]
write_capability: false
像 dry_run 这类开关只能当作流程约束,不能当作权限隔离——真正的防线是账号权限和出口白名单。建议跑完一段时间后,用审计日志或数据库通用日志反查一次,确认这张只读凭据确实没有产生过写语句。
记录每条建议与实际人工决定的差异,找出偏差集中的环节
这一阶段决定“要不要进入写回”。做法是把每条建议和人工最终处理结果并排放在一张差异记录表里。人工先不看建议处理一遍,处理完再对照,避免被建议带偏。表里至少保留下面这些列,后面判断哪类问题需要收紧才有依据。
| 字段 | 用途 |
|---|---|
| 建议ID / 输入标识 | 唯一对应一条样本,便于回查原始输入 |
| 建议结论 / 建议依据 | 记录 VM0 给出的结论和它所依据的字段 |
| 人工决定 | 人工实际采取的动作 |
| 是否一致 / 偏差分类 | 量化偏差,口径统一 |
| 处理人 / 时间 | 便于回溯与复核 |
偏差分类口径建议固定成几类:一致(结论和动作都相同)、漏判(本该处理却未给出建议)、误判(不该处理却建议处理)、条件偏差(方向对但阈值或范围不对)、表述偏差(结论相同但字段或对象写错)、依据不足(输入数据缺失导致无法判断)。统计时按类别看集中度,而不是只看总数。如果偏差集中在某一类,就在那一类上加前置条件:提高进入判断的字段完整性要求、对某类样本直接转人工、把触发条件从“满足一条”改成“满足两条”,这些都是可验证的收紧动作。
第二阶段开放写回,但限定单条记录、限定可写字段
写回配置通常放在链路的写操作配置里,而不是散落在代码中。落成一份可评审的配置,让字段白名单、单条限制、目标表一眼可见,改动走配置变更而不是改代码。可写字段只列业务上允许被自动修改的那几个,其余字段(状态机关键位、金额、负责人、时间戳等)一律不写。单条限制用“每次运行只处理一条 → 幂等键 → 目标表唯一约束”组合实现,防止重复写。
write:
enabled: true
max_records_per_run: 1
target_table: orders
allowed_fields:
- remark
- tag
idempotency_key: suggestion_id
require_confirmation: true
白名单之外的字段,即使判断环节给出了也直接丢弃,并在日志里记一条“字段被拒绝写入”,这条日志是后面排查问题的主要线索。max_records_per_run 建议先从 1 开始,跑几条确认无误后,再按每阶段只上调一档的节奏放开,不要一次从 1 跳到很大的批量。
给写操作加确认点或回滚方式,说明可回滚的边界
确认点的触发条件要写具体:判断置信度低于设定阈值时暂停、目标记录处于关键状态时暂停、涉及白名单外字段或跨表联动时暂停、连续两次写入失败时暂停。触发后进入待确认队列,由人工确认或驳回,不要静默跳过。
回滚能覆盖多少,取决于写入前有没有做准备。写入前把原值一并存下来(原字段值、写入值、建议ID、时间),这类字段级修改通常可以还原;单条记录、单表内、有原值留存的写入,回滚路径比较清楚。不可回滚的情况也要提前写进配置说明:已经发出去的外部通知、已经触发的下游任务、被覆盖且没有留原值的数据、已经产生外部副作用的接口调用。这几类要么在确认点拦住,要么在写入前就避免自动触发。
第三阶段放开批量前,用一次小批量试运行核对条数与结果
小批量条数设定建议从 5~10 条起步,并且这 10 条里混入上一阶段人工已经确认过结论的样本,这样结果好坏有参照。条数与结果比对方法:先看“输入条数 = 通过校验条数 + 被拒绝条数 + 被暂停待确认条数”,三边对不上,说明有记录在链路中被吞掉;再逐条核对实际写入结果与预期是否一致,不要只看汇总数。
放行或退回的判断依据:条数守恒、可写字段没有越界、被暂停记录的比例和原因在预期范围内,可以进入更大批量;一旦出现条数不守恒、白名单外字段被写、异常集中在某一类数据上,就退回单条模式,把判断条件收紧后重跑,不要在同一次运行里调参硬跑。