提示词里的"约束"不是约束
提示词里常写"金额必须为正""日期格式必须是 YYYY-MM-DD""只能从这三个选项里选" ✔。
但模型只是"倾向"遵守 ✗ —— 它偶尔会不遵守 ✔,而下游如果直接信了,就出事 ✔。
能写成程序校验的约束,就不要只写在提示词里 ✔。
一、约束的三种去处(按可靠性排序)
| 位置 | 可靠性 | 适合 |
|---|---|---|
| 程序校验(拒绝/修正 ✔) | 最高 ✔ | 类型、范围、枚举、外键、业务规则 ✔ |
| schema/结构化输出 | 高 ✔ | 字段与结构的强约束 ✔ |
| 提示词说明 | 最低 ✗ | 风格、语气、偏好、难以形式化的要求 ✔ |
结论:提示词负责"倾向",程序负责"底线" ✔。
二、把提示词约束翻译成程序校验(对照表)
提示词里写:「金额必须为正数,不超过 10000」
程序里加:type=number, min=0.01, max=10000, 必填 ✔
提示词里写:「日期格式 YYYY-MM-DD」
程序里加:正则 + 真实日期校验(含闰年/月末 ✔)
提示词里写:「category 只能是 A/B/C」
程序里加:enum 校验 + 归一化(大小写/空格 ✔)
提示词里写:「不要编造」
程序里加:证据表 + 引用校验 + 该拒答却作答率监控(见证据表那篇 ✔)
关键:程序校验不仅"检查",还要给出可读的拒绝理由 ✔(回给模型让它只修那一处 ✔,见结构化输出那篇 ✔)。
三、校验失败后的三种处置
- 回喂重试(带错误原文 ✔,最多 1~2 次 ✔);
- 降级(换成更保守的输出:只给原文、不给结论 ✔);
- 拒绝并转人工(高风险场景 ✔,见转人工那篇 ✔)。
不要:静默修正 ✗(用户不知道被改了 ✔)或忽略错误继续 ✗(脏数据进库 ✔)。
四、三个常见坑
- 只校验最外层 ✗ → 嵌套对象里的字段类型必须逐层校验 ✔;
- 校验与提示词不一致 ✗(提示词说"最多 5 条",程序允许 20 条 ✔)→ 两边要同源 ✔(从同一份配置生成 ✔);
- 校验太严 ✗ → 正常输入被拒 ✔(要监控拒绝率,见长尾那篇 ✔)。
一条判据
把提示词里所有含"必须/只能/不超过"的句子列出来 ✔,
每一条是否都有对应的程序校验(而不是只有提示词) ✔?
有落空的,就是潜在的脏数据入口 ✗。