字段速查的用法
治理争论经常卡在同一句话:“这个能力到底归谁、能用多少、跑的是哪个版本?”三个问题对应三类字段:目录字段回答归属,配额字段回答用量,版本矩阵回答可复现性。字段不齐,答案只能靠人记,人一换就断。
这份附录按“先条目、再契约、再配额、后矩阵”的顺序排列。每个字段给出类型、是否必填、示例与用途;第五节集中说明缺失后果与校验方式。示例全部来自“回声”案例,金额为整数微元,延迟为毫秒。
字段表不是数据库设计文档。它只保留治理必须的字段,其余信息通过引用或外部系统承接。字段越多,维护成本越高;字段太少,冲突又没有地方挂。
一、能力条目字段
一条能力条目是产品承诺的最小治理单位,不是模型,也不是接口地址。下面十八个字段是建议的最小集。
| 字段 | 类型 | 必填 | 示例 | 用途 |
|---|---|---|---|---|
id | string | 是 | chat.reply | 全局唯一标识 |
functionKey | string | 是 | reply | 判重,识别同一功能的多种实现 |
displayName | string | 是 | 私信回复 | 目录展示与工单引用 |
owner | string | 是 | team-support-ai | 质量、成本、退役的最终问责 |
ownerBackup | string | 是 | team-support-ai-backup | owner 缺席时的代偿 |
status | enum | 是 | active | active / deprecated / retired |
currentVersion | semver | 是 | 2.1.0 | 推荐版本,漂移判断基准 |
supersedes | string | 否 | chat.reply-legacy | 合并期的替代声明 |
riskLevel | enum | 是 | high | low / medium / high,决定评审路径 |
dataClass | enum | 是 | internal | public / internal / sensitive |
regions | string[] | 是 | ["cn-east"] | 允许处理的区域 |
contractRef | string | 是 | contract:chat.reply@2.1.0 | 契约与版本绑定 |
evalSetRef | string | 是 | eval:chat.reply:2026Q4 | 发布门禁使用的评测集 |
slaP95Ms | integer | 是 | 1800 | 延迟承诺,毫秒 |
callCeilingMicros | integer | 是 | 4200 | 单次调用上限,微元 |
retirementPlan | string | 否 | retire:2027-03-31 | 退役计划引用 |
updatedAt | date | 是 | 2026-11-05 | 目录时效 |
tags | string[] | 否 | ["客服","私信"] | 检索与分组 |
六个字段值得单独说明。
functionKey 是判重键。chat.reply 与 reply.chat 的 id 不同,功能键都是 reply;没有它,平台只能靠字符串相似度判重,既误报又漏报。
owner 必须是可联系的人或稳定团队别名,不能写“平台组”这种只负责网关的抽象部门。判定标准很直接:出事故时能找到人,模型退役时能列出清单。
status 用三态而不是布尔值。deprecated 表示仍可用但不推荐,retired 表示禁止新调用。只有布尔值,弃用窗口就没有地方表达。
dataClass 与 regions 共同决定数据能否出域。缺一个,安全只能按最保守假设拦截,业务会抱怨平台“什么都不让做”。
evalSetRef 把发布门禁钉在具体评测集上。没有它,发布评审只能看“最近跑过一次”,无法判断用的是哪一版样本。
callCeilingMicros 是单次上限,不是平均成本。它防的是一次异常请求打爆整个份额,与配额总额是三件事。
二、提供方与调用方契约字段
契约字段分请求、响应与错误三组。请求字段由调用方填写,响应字段由提供方返回,错误字段定义失败语义。
请求字段
| 字段 | 类型 | 必填 | 示例 | 说明 |
|---|---|---|---|---|
contractRef | string | 是 | contract:chat.reply@2.1.0 | 调用方锁定的契约 |
capabilityId | string | 是 | chat.reply | 能力标识 |
version | semver | 是 | 2.1.0 | 精确版本,不接受别名 |
callerId | string | 是 | caller-support-im | 调用方标识 |
tenantId | string | 是 | tenant-echo | 所属租户 |
requestId | string | 是 | req-7f3a91 | 单次请求幂等与对账 |
traceId | string | 是 | trace-2c8e10 | 跨节点追踪 |
idempotencyKey | string | 是 | idem-9b21 | 重试不产生第二次副作用 |
input.text | string | 是 | 订单什么时候发货? | 业务输入 |
input.locale | string | 否 | zh-CN | 语言与格式 |
contextRef | string | 否 | ctx:conv-123 | 共享上下文引用,不传全量 |
dataClass | enum | 是 | internal | 本次请求的数据级别 |
budgetMicros | integer | 是 | 4200 | 本次预算上限 |
deadlineMs | integer | 是 | 1200 | 端到端截止时间 |
expectedFormat | enum | 否 | text | text / json / streaming |
version 必须精确到 semver,不能写 latest。别名在不同时间指向不同契约,回放与审计无法复现。budgetMicros 与 deadlineMs 是调用方声明的约束,提供方不能悄悄突破;需要更多预算,走重新协商,而不是先花了再说。
响应字段
| 字段 | 类型 | 必填 | 示例 | 说明 |
|---|---|---|---|---|
status | enum | 是 | ok | ok / degraded / error |
output.text | string | 是 | 预计 48 小时内发出。 | 业务输出 |
evidence | array | 是 | [{docId, span}] | 结论依据,不能只给摘要 |
usage.tokensIn | integer | 是 | 1200 | 输入 token |
usage.tokensOut | integer | 是 | 180 | 输出 token |
usage.costMicros | integer | 是 | 3980 | 本次实际成本 |
versions.model | string | 是 | model-chat-pro@2026-09-18 | 模型版本 |
versions.prompt | string | 是 | prompt-chat-reply-v7 | 提示版本 |
versions.policy | string | 是 | policy-moderation-v4 | 策略版本 |
auditRef | string | 是 | audit:2026-11-05:7f3a91 | 审计记录引用 |
degraded.reason | string | 否 | rerank_timeout | 降级原因 |
versions 三件套是回放的前提。只记模型版本,提示一改就无法复现;只记提示版本,模型换代又无法解释差异。auditRef 让“谁在什么租户下用了哪份数据”可追溯,不能等到审计时才补。
错误字段
| 字段 | 类型 | 必填 | 示例 | 说明 |
|---|---|---|---|---|
error.code | enum | 是 | quota_exceeded | 稳定错误码,不随文案变化 |
error.retryable | boolean | 是 | false | 是否允许重试 |
error.retryAfterMs | integer | 否 | 2000 | 建议退避时间 |
error.detail | string | 否 | caller share 30,000,000 exhausted | 可读细节 |
error.quotaScope | enum | 否 | caller | tenant / team / caller / call |
error.requestId | string | 是 | req-7f3a91 | 与请求对账 |
retryable 必须由提供方明确给出,不能由调用方猜。配额超限、参数非法、数据越界都不可重试;超时、下游限流可以重试,但要有 retryAfterMs 和重试预算。把不可重试错误标成可重试,会把一次拒绝放大成一次重试风暴。
三、三层配额字段
配额分三层:租户总额、团队/调用方份额、单次上限。三层同时存在,才能既防超支,又防单点打爆。
| 层级 | 字段 | 类型 | 必填 | 示例 |
|---|---|---|---|---|
| 租户 | tenantId | string | 是 | tenant-echo |
| 租户 | period | string | 是 | 2026-11 |
| 租户 | monthlyQuotaMicros | integer | 是 | 100000000 |
| 租户 | reservedMicros | integer | 否 | 5000000 |
| 团队 | teamId | string | 是 | content |
| 团队 | shareMicros | integer | 是 | 40000000 |
| 调用方 | callerId | string | 是 | caller-content-publish |
| 调用方 | callerShareMicros | integer | 是 | 25000000 |
| 单次 | capabilityId | string | 是 | content.summarize |
| 单次 | ceilingMicros | integer | 是 | 6200 |
| 单次 | enforcement | enum | 是 | hard |
| 单次 | overagePolicy | enum | 是 | reject |
| 借用 | borrowedMicros | integer | 否 | 5000000 |
| 借用 | borrowWindow | string | 否 | 2026-11-01..2026-11-30 |
| 借用 | reclaimPolicy | enum | 否 | auto |
| 隔离 | isolationKey | string | 否 | tenant:echo |
| 计量 | usedMicros | integer | 是 | 32000000 |
示例口径:租户月度总额 1 亿微元;内容团队 4,000 万、客服团队 3,000 万、交易团队 3,000 万;单次上限为摘要 6,200、回复 4,200、下单 3,000 微元。三个份额相加正好 1 亿,是一个合法初始分配;新增份额必须同时调整总额或某个份额。
三层各自防一种风险:
- 总额防“整体超支”。没有总额,团队可以各自在份额内超用,月底账单才暴露。
- 份额防“团队争抢”。没有份额,一个团队可以把全部额度吃光,其他团队无法事前申请。
- 单次防“单点打爆”。没有单次上限,一个异常请求可以花掉一个团队整月份额。
usedMicros 是计量结果,不是目录字段。它应放在计量系统,通过 tenantId 与 callerId 聚合;写进能力条目会让目录变成时序数据库。reservedMicros 是预留,不是已用;预留用于大促或迁移窗口,到期必须释放。
配额校验的最小求和规则:
Σ team.shareMicros <= tenant.monthlyQuotaMicros
Σ caller.callerShareMicros <= team.shareMicros
Σ call.ceilingMicros <= caller.callerShareMicros
borrowedMicros <= lender.shareMicros - lender.usedMicros
borrowWindow 必须覆盖当前计费周期
求和用整数,不用浮点。微元是整数单位,浮点会在边界上产生“差一分钱”的对账争议。
四、版本矩阵字段
版本矩阵把契约、模型、提示、策略、评测集五个版本绑在一行。它回答的不是“有哪些版本”,而是“哪个组合被批准过”。
| 字段 | 类型 | 必填 | 示例 | 说明 |
|---|---|---|---|---|
matrixId | string | 是 | mx:chat.reply:2026Q4 | 矩阵行标识 |
capabilityId | string | 是 | chat.reply | 所属能力 |
contractSemver | semver | 是 | 2.1.0 | 契约版本 |
modelId | string | 是 | model-chat-pro | 模型标识 |
modelVersion | string | 是 | 2026-09-18 | 模型快照 |
promptVersion | string | 是 | prompt-chat-reply-v7 | 提示版本 |
policyVersion | string | 是 | policy-moderation-v4 | 策略版本 |
evalSetVersion | string | 是 | eval:chat.reply:2026Q4 | 评测集版本 |
status | enum | 是 | active | active / deprecated / retired |
releasedAt | date | 是 | 2026-10-01 | 发布日期 |
deprecatedAt | date | 否 | 2027-01-01 | 弃用开始 |
sunsetAt | date | 否 | 2027-03-31 | 禁止新调用 |
compatibleMajors | string | 是 | 1,2 | 兼容的主版本 |
migrationRef | string | 否 | mig:chat.reply:v2 | 迁移计划引用 |
owner | string | 是 | team-support-ai | 该行维护人 |
示例矩阵(示例值):
| 能力 | 契约 | 模型 | 提示 | 状态 | 弃用 | 下线 |
|---|---|---|---|---|---|---|
chat.reply | 2.1.0 | model-chat-pro@2026-09-18 | v7 | active | 2027-01-01 | 2027-03-31 |
chat.reply | 1.9.0 | model-chat-lite@2026-05-02 | v5 | deprecated | 2026-12-01 | 2027-01-31 |
content.summarize | 3.0.0 | model-sum-pro@2026-08-11 | v4 | active | — | — |
search.rerank | 1.4.0 | model-rank@2026-07-20 | v3 | active | — | — |
moderation.classify | 2.2.0 | model-mod@2026-09-01 | v6 | active | — | — |
support.assist | 1.6.0 | model-chat-pro@2026-09-18 | v2 | active | — | — |
矩阵的关键约束是“五个版本同时存在”。只升模型不升提示,行为变化无法归因;只升提示不升契约,调用方可能在不知情时收到不同格式;只升契约不升评测集,门禁仍在用旧样本。
sunsetAt 必须晚于 deprecatedAt,deprecatedAt 必须晚于 releasedAt。三个日期倒置,弃用窗口就失去意义。migrationRef 在 status 进入 deprecated 后必填,否则退役没有路径。
五、字段缺失的后果与校验
字段缺失不是“信息少一点”,而是某类治理动作直接失效。下表把后果与校验方式放在一起。
| 字段 | 缺失后果 | 校验方式 |
|---|---|---|
functionKey | 重复建设不可见,合并无依据 | 在役能力内唯一性检查 |
owner | 事故、退役、成本无人承接 | 非空 + 组织名录存在性 |
status | 已退役能力仍被新调用 | 三态枚举 + 状态机 |
currentVersion | 版本漂移无法判定 | semver 正则 + 版本表存在 |
contractRef | 同一版本被换契约 | 等于 contract:id@semver |
riskLevel | 高风险能力走错评审路径 | 枚举 + 高风险强制委员会 |
dataClass | 数据出域违规 | 枚举 + 安全策略匹配 |
regions | 跨区域处理无法拦截 | 非空 + 允许区域列表 |
evalSetRef | 无门禁发布,回归不可比 | 存在 + 未过期 |
callCeilingMicros | 单次请求打爆份额 | 整数 + 不超过调用方份额 |
shareMicros | 超分不可见 | 求和不超过租户总额 |
borrowedMicros | 借用无记录,归还无依据 | 有窗口、审批人与归还日 |
modelVersion | 回放不可复现 | 非空 + 矩阵行存在 |
promptVersion | 行为变化无法归因 | 非空 + 矩阵行存在 |
sunsetAt | 弃用没有终点 | 晚于 deprecatedAt |
migrationRef | 退役没有迁移路径 | deprecated/retired 时必填 |
缺失字段分五类影响:
- 不可见:缺
functionKey、owner,重复建设与责任悬空都发现不了。 - 不可控:缺
shareMicros、callCeilingMicros,额度只能在月底看账单。 - 不可复现:缺
modelVersion、promptVersion,同一输入无法解释不同输出。 - 不可审计:缺
dataClass、auditRef,谁在什么租户下用了什么数据说不清。 - 不可退:缺
sunsetAt、migrationRef,能力只能不断加版本,无法下线。
六、校验顺序与失败输出
校验按六层顺序执行。先语法,再存在,再一致,再求和,再时效,最后权限。顺序不能倒:引用一个不存在的对象时,先报“格式不对”只会误导修复方向。
1 语法层:类型、枚举、正则、非负整数
2 存在层:tenant / caller / capability / version / evalSet 必须存在
3 一致层:caller.tenant = call.tenant;version.capability = call.capability
contractRef = contract:capability@semver
4 求和层:Σ teamShare <= tenantTotal;Σ callerShare <= teamShare
Σ perCall <= callerShare
5 时效层:now < sunsetAt;evalSet 年龄 <= 90 天;borrowWindow 覆盖当前周期
6 权限层:call.dataClass <= tenant.allowedClass;region 在允许列表
失败输出要能直接进工单,至少包含对象、字段、代码与可读细节:
CAP-002 duplicate functionKey: reply(chat.reply / reply.chat)
QUOTA-011 share sum 105,000,000 > tenant 100,000,000
VER-004 sunsetAt 2026-10-31 < now 2026-11-05(chat.reply@1.9.0)
DATA-003 call dataClass sensitive > tenant allowed internal(caller-support-im)
一次返回全部问题,而不是修一个报一个。校验器的价值在于把“发布前发现”变成默认路径;如果每次只报第一条,团队会学会绕过校验,而不是修复字段。
七、一份最小可用条目
下面是一条能力条目的最小示例。字段值来自“回声”案例,均为示例值。
{
"id": "chat.reply",
"functionKey": "reply",
"displayName": "私信回复",
"owner": "team-support-ai",
"ownerBackup": "team-support-ai-backup",
"status": "active",
"currentVersion": "2.1.0",
"riskLevel": "high",
"dataClass": "internal",
"regions": ["cn-east"],
"contractRef": "contract:chat.reply@2.1.0",
"evalSetRef": "eval:chat.reply:2026Q4",
"slaP95Ms": 1800,
"callCeilingMicros": 4200,
"retirementPlan": "retire:2027-03-31",
"updatedAt": "2026-11-05"
}
这条条目能回答四个问题:谁负责(owner)、能不能用(status)、按哪份契约用(contractRef)、最多花多少(callCeilingMicros)。它不能回答“当前用了多少”,那是计量系统的职责;也不能回答“模型是哪个快照”,那在版本矩阵里。
最小可用不等于永远够用。能力进入高风险、跨区域或跨租户场景时,必须补 riskLevel、regions、dataClass 的细化值,并挂上对应评估记录。
常见错误与边界
- 把能力 id 当功能键用。id 是标识,功能键才是判重依据。
owner写部门名。部门会重组,责任不能跟着组织图消失。status只用布尔值。没有 deprecated,弃用窗口无法表达。- 版本字段允许
latest。同一引用在不同时间指向不同契约,回放必失败。 - 配额只记总额,不记份额。团队争抢时平台只能事后解释。
- 单次上限按平均值设定。平均值挡不住一次异常请求。
- 把
usedMicros写进目录。高频计量数据会污染目录,也会拖慢查询。 - 版本矩阵只记模型版本。提示一改,行为差异仍然无法归因。
- 校验只报第一个错。团队会陷入修一个报一个的循环。
- 把示例值当生产承诺。示例只说明字段形状,不说明线上表现。
小结
字段是治理角色的共同语言。目录字段回答“这是什么、归谁”,契约字段回答“怎么调、返回什么”,配额字段回答“能用多少”,版本矩阵回答“当时跑的是哪个组合”。四类字段齐全,跨团队讨论才能从形容词回到数字。
最小集不是越少越好,而是“缺了它,某类冲突就没有地方挂”。functionKey 挂重复建设,owner 挂责任,shareMicros 挂争抢,modelVersion 挂不可复现。每加一个字段,都应该能说出它承接哪类冲突。
字段填完只是开始。下一件事是评审:谁来看这些字段、按什么顺序问、什么算通过。附录 C 把这些问题组织成十三组六十五问,并给出四十五分钟流程与结论模板。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。