如何建立一套 Token 感知的 Prompt 审查流程

如何建立一套 Token 感知的 Prompt 审查流程
一份 Prompt 可以通过文字审查,却仍然给生产环境留下风险。
修改后的指令可能更清楚,但当应用加入对话历史、检索文档、工具 Schema、输出规则和多语言内容后,它也可能额外增加数千个 Token。切换模型可能改变分词结果。看似很小的 Prompt Diff 可能挤占回答所需的空间。API 网关报告的 Usage 也可能与团队直接测试模型供应商时不同。
Token 感知的 Prompt 审查流程,就是在 Prompt 上线前发现这些问题。它把 Token 使用量视为一种可审查的工程属性,与正确性、安全性、延迟和成本一起进入发布判断。
目标并不是把每个 Prompt 压缩到最短,而是在保留有效指令的同时,证明最终请求处于预算内,并验证真实端点报告的 Usage 值得信任。
什么是 Token 感知的 Prompt 审查?
普通 Prompt 审查通常会问:
- 指令是否清楚?
- 模型是否返回要求的格式?
- 是否覆盖边界情况?
- 修改后输出质量是否提升?
Token 感知审查还会增加一组问题:
- 应用加入所有 Wrapper 后,模型实际收到的完整请求是什么?
- System Prompt、用户输入、检索内容、工具和输出预留各占多少 Token?
- 这次修改是否引入 Token 回归?
- 请求是否仍为完整回答保留了足够空间?
- 英文、中文和其他本地化版本是否都在预算内?
- 目标端点是否一致地报告 Input、Output、Cache 和 Reasoning Usage?
这些是发布问题,不只是文案问题。
第一步:审查最终请求,而不是单独的 Prompt 片段
最常见的 Token 计数错误,是只统计刚刚修改的文本。
应用实际发送的内容通常更多:
最终请求
= System 与策略指令
+ 用户消息
+ 对话历史
+ 检索上下文
+ 工具定义
+ 输出 Schema
+ 应用 Wrapper
如果审查者只计算 System Prompt,结果可能显著低估真实输入。
在审查前建立一份有代表性的请求 Fixture。它应使用与生产一致的消息角色、工具、检索格式、结构化输出 Schema 和 Wrapper 字段,并使用现实中的长输入,而不是一句话的理想样例。
对于 RAG 工作流,至少保留三类 Fixture:
- 典型请求: 使用平均检索量的常规输入。
- 高负载请求: 接近预期运行上限,但仍然合法的长输入。
- 对抗请求: 重复、多语言、分段较差或工具较多的输入,用来暴露 Prompt 膨胀。
真正被审查的单元是这份 Fixture;修改后的 Prompt 只是其中一个组成部分。
第二步:按组件拆分 Token 预算
总 Token 数很重要,但它无法告诉审查者到底哪里发生了变化,也无法指出应该从哪里优化。
建议使用组件预算:
请求预算
= System 指令
+ 用户输入
+ 对话历史
+ 检索上下文
+ 工具和 Schema 开销
+ 输出预留
+ 安全缓冲
可以使用下面的审查表:
| 组件 | 基线 | 修改后 | 变化 | 审查规则 |
|---|---|---|---|---|
| System 指令 | 1,180 | 1,340 | +160 | 增幅超过 10% 时必须解释 |
| 用户 Fixture | 620 | 620 | 0 | 两次测试使用同一 Fixture |
| 检索内容 | 3,400 | 3,400 | 0 | 按相关性设置上限 |
| 工具 Schema | 1,050 | 1,260 | +210 | 删除未使用字段与工具 |
| 输出预留 | 1,500 | 1,500 | 0 | 不允许被输入占用 |
| 安全缓冲 | 800 | 800 | 0 | 明确保留余量 |
| 计划总量 | 8,550 | 8,920 | +370 | 需要审查者确认 |
这些数字只是示例,不是通用限制。团队应根据目标模型、请求结构、质量目标和成本范围设置自己的阈值。
组件拆分可以避免一种常见失败:因为输入今天仍能放进上下文窗口,就批准更长的 Prompt,却没有意识到它正在消耗完整回答所需的输出空间。
第三步:使用目标模型支持的计数方法
Tokenization 与模型相关。字符数、单词数和文件大小可以用于粗略筛选,但不能替代目标模型使用的 tokenizer 或 Token 计数方法。
当前供应商的流程并不相同:
- OpenAI 文档提供了针对受支持编码的
tiktoken本地计数方法,也提供了针对 Responses API 请求体的服务端 Input Token 计数方式。 - Anthropic 为 Messages 请求提供 Token Counting 接口,可在生成前估算输入。
- Google 为 Gemini 请求提供
countTokens,并在生成后返回运行时 Usage Metadata。
不要把这些差异简化成一个永久有效的换算公式。更换模型、供应商、消息格式、工具 Schema 或语言后,同一任务的 Tokenization 都可能变化。
每次审查都应保存:
- 供应商与端点;
- 请求的 Model ID;
- 可用时保存返回的 Model ID;
- tokenizer 或计数方法;
- Fixture 版本;
- Input Token 估算;
- Output Token 预留;
- 测试时间。
这样得到的结果才可复现,而不是一次性的口头判断。
如需查看更多 Token 计数与 Prompt 预算内容,可浏览 TokenTest 中文博客。
第四步:审查 Token Diff,而不只看新总量
审查者应在文字 Diff 旁边看到 Token 影响:
基线 Input Tokens:7,050
修改后 Input Tokens:7,420
绝对变化:+370
百分比变化:+5.25%
Output 预留:1,500
预算状态:通过
然后解释变化来自哪里:
- 重复的策略文本;
- 新增示例;
- 扩大的 JSON Schema;
- 新增工具;
- 更长的检索上下文;
- 本地化扩展;
- 应用 Wrapper 变化。
并不是所有增长都不好。增加 5% Token,如果能修复代价很高的分类错误,可能值得;如果只是把同一条规则重复三次,则属于 Prompt 债务。
建议设置两种阈值:
- 警告阈值: Pull Request 中必须解释。
- 失败阈值: 除非预算负责人批准,否则阻止合并。
同时使用绝对值和百分比。只看百分比会对极短 Prompt 反应过度;只看绝对值则可能掩盖小型工作流中的显著增长。
第五步:保护输出余量
Input Token 与 Output Token 会竞争请求可用的上下文空间。部分模型系列还可能使用 Reasoning Token 或其他不可见 Token,并影响上下文与 Usage 统计。
因此,“输入可以放进去”并不代表审查通过。
团队应定义输出契约:
- 预期回答长度;
- 最大回答长度;
- 必需的 JSON 或 Tool Call 结构;
- 回答必须包含的最少信息;
- 可接受的 Stop Reason;
- 适用时为 Reasoning 或不可见输出保留空间。
然后验证最长合法输入是否仍能生成完整回答。
如果 Prompt 修改额外使用 800 个 Input Token,不要悄悄从回答预算中扣除。应该减少其他组件、在模型允许时提高批准预算,或证明较小的输出余量仍能通过质量测试。
如需更完整的预算模型,可阅读生产级 LLM 应用的上下文窗口规划开发者指南。
第六步:分别测试多语言 Prompt
翻译后的 Prompt 不保证 Token 数量一致。
英文与中文即使表达相同指令,也可能使用不同的 Token 预算。差异方向和大小取决于具体文本与 tokenizer,因此不能依赖“字符数除以四”之类的固定规则。
把每种生产语言都视为独立 Fixture:
| 检查项 | 英文 | 中文 |
|---|---|---|
| System Prompt Tokens | 实测 | 实测 |
| 典型用户输入 | 实测 | 实测 |
| 高负载用户输入 | 实测 | 实测 |
| 检索模板 | 实测 | 实测 |
| 工具与 Schema 开销 | 实测 | 实测 |
| Output 预留 | 验证 | 验证 |
本地化审查还要检查行为。为了减少 Token 而弱化安全规则,并不是优化。
更多说明可参考为什么中文 Prompt 的 Token 预算可能和英文不同。
第七步:用真实端点验证估算
本地或供应商计数解决的是预检问题:这个请求大概有多大?
生产端点解决的是第二个问题:系统实际上报告了什么 Usage?
将批准后的 Fixture 发送到目标端点,并比较:
- 估算 Input Token 与报告值;
- 可见输出与报告的 Output Token;
- Total Token 是否一致;
- 预期使用缓存时是否存在 Cache 字段;
- 端点声称支持推理时是否有 Reasoning 或 Thought 字段;
- Stop Reason 与 Token Limit 行为;
- 请求模型与返回模型是否一致。
这正是 TokenTest 的适用场景。TokenTest 将自己定位为生产参考级评测控制台,用于测试模型能力、路由协议、Token Usage、安全边界和渠道可靠性。当前检查项包括 Usage Integrity、Cache Token Evidence、Thinking/Reasoning Tokens、Token Total Consistency、Input Monotonicity、Tokenizer 行为、Truncation 和 Max Output 边界。
这让审查者能够验证的不只是一个本地估算值,还能检查 OpenAI-compatible 端点、中转服务或网关是否表现得足够一致,值得在上线前信任。
第八步:让审查流程进入 CI
手动审查是一个起点,版本化检查更可靠。
建议把下面的文件与 Prompt 一起保存:
prompts/
support-classifier.md
fixtures/
support-classifier.typical.json
support-classifier.heavy.json
support-classifier.zh.json
budgets/
support-classifier.json
预算文件示例:
{
"workflow": "support-classifier",
"model": "target-model-id",
"warning_delta_percent": 5,
"failure_delta_percent": 12,
"max_input_tokens": 9000,
"reserved_output_tokens": 1500,
"required_checks": [
"typical",
"heavy",
"zh"
]
}
当缺少必需 Fixture、计数方法未经审查就发生变化、输入超过预算,或输出预留低于批准值时,CI 应阻止合并。
CI 还应保存基线与修改后结果,让审查者能够调查回归原因,而不是只看到一个无法解释的红色状态。
可在 TokenTest 中测试的 Prompt 审查示例
将下面两组内容作为基线与修改后 Prompt,用同一用户消息、同一模型和同一端点运行测试,然后比较 Usage 与回答完整性。
基线 Prompt
你负责对客服请求进行分类。
返回 JSON,包含:
- intent
- urgency
- needs_human
用户消息:
“我被重复扣费,第二笔费用目前仍显示处理中。”
修改后 Prompt
你负责对订阅制软件的客服请求进行分类。
规则:
1. 只返回有效 JSON。
2. intent 只能是 billing、access、bug、cancellation 或 other。
3. 如果用户提到重复扣费、账号锁定或数据丢失,将 urgency 设为 high。
4. 如果涉及付款争议、威胁或法律行动请求,将 needs_human 设为 true。
5. 不提供金融或法律建议。
返回:
{
"intent": "billing|access|bug|cancellation|other",
"urgency": "low|medium|high",
"needs_human": true,
"reason": "不超过 20 个字的一句话"
}
用户消息:
“我被重复扣费,第二笔费用目前仍显示处理中。”
不要只问修改后的版本是否使用了更多 Token。还要判断新增指令是否带来足够的一致性提升,以及输出余量是否仍然成立。
Token 感知 Prompt 审查清单
请求构造
- [ ] 测试使用最终生产请求结构。
- [ ] 已包含 System、User、History、Retrieval、Tools、Schema 与 Wrapper。
- [ ] 典型、高负载和对抗 Fixture 已版本化。
计数与预算
- [ ] 使用目标模型支持的计数方法。
- [ ] 可看到基线、修改后、绝对变化和百分比变化。
- [ ] 每个组件都有明确预算。
- [ ] Output 余量与安全缓冲仍然完整。
质量与本地化
- [ ] 修改通过任务质量测试,而不只是 Token 测试。
- [ ] 每种生产语言都单独计数。
- [ ] 精简没有删除必要规则或示例。
端点验证
- [ ] 对比估算 Usage 与端点报告值。
- [ ] 适用时检查 Cache、Reasoning、Total、Stop 和 Model 字段。
- [ ] 所有异常 Usage 差异都在批准前得到解释。
最终原则:像审查代码一样审查 Prompt
Prompt 是应用的一部分。它的 Token 体积会影响成本、延迟、上下文适配,以及正确回答可用的空间。
一套可靠的 Token 感知 Prompt 审查流程应完成四件事:
- 构造模型实际收到的完整请求。
- 使用目标模型支持的方法,测量组件预算与 Token Diff。
- 保护输出余量,并测试每种生产语言。
- 使用真实端点验证批准后的 Fixture。
先从一个高流量 Prompt 开始。保存基线,设置警告阈值,加入高负载 Fixture,并在下一次发布前通过 TokenTest 运行测试。当团队能够在审查阶段看见 Prompt Token 回归,Token 预算就不再是上线前的临时估算,而会成为可重复执行的工程控制。