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