一条提示词里同时塞长材料、多轮追问和输出格式要求,输出飘了,最难定位的是哪一项拖的。可行的路径是先冻住其余变量,只让一个因素变化:先测轮数,再测输入长度,最后测输出格式,各自记下第一次出问题的位置,再回到混合场景里按最弱的那一项设边界。
先固定系统提示、素材和问题,只让轮数、输入长度、输出格式三者之一发生变化。多轮测到复述开始丢前轮结论的轮次,长文测到要点开始缺失的字数档,结构化输出测到不能直接解析的那一档。然后据此分出哪类任务可放手、哪类必须人工校对、哪类暂不适用。单轮单变量跑通,不等于混合场景可用;边界按最弱的一项取,并留一轮或一档余量。
把一条混合提示词拆成三个单变量任务
三条测试共用同一份基线:系统提示、素材、问题一字不改,只在各自标注处产生差异。把 <材料> 换成你自己的那份固定素材,长度控制在 600 字上下,三条测试共用同一份。
[系统] 你是资料整理助手。只依据用户给出的材料回答,不引入材料之外的事实。
[用户] 以下是同一份项目笔记,请阅读后回答末尾的问题。
<材料>
(粘贴同一份固定素材,约 600 字,三条测试共用)
</材料>
问题:这份笔记里列出的三个待办分别是什么?
任务一只变动轮数:素材、问题、格式要求都与基线相同,只在末尾追加到第 4 轮。
[第 2 轮] 先原样复述你上一轮的全部结论,再回答:每个待办的负责人是谁?
[第 3 轮] 先原样复述你上一轮的全部结论,再回答:每个待办的截止时间是什么?
[第 4 轮] 先原样复述你上一轮的全部结论,再回答:哪些待办之间有依赖?
任务二只变动输入长度:仍是单轮,不加任何格式要求,只把 <材料> 换成后面第 3 节的分档版本。任务三只变动输出格式:素材和问题与基线一致,单轮,只把末尾一行换成下面三种要求之一。
列表:用无序列表输出这三个待办,一条一行,不要额外说明文字。
表格:用 Markdown 表格输出,三列:待办 | 负责人 | 截止时间。
固定字段:只输出 JSON,不要代码围栏,不要任何解释文字:
{"todos":[{"task":"","owner":"","due":""}]}
三类测试不要放在同一个会话里连着跑,历史上下文会互相污染,建议每换一个变量就开一个新会话,并保留每次请求的完整入参与返回,便于回看。
多轮追问测试:看第几轮开始丢前文
多轮的写法是每轮固定追加一个问题,并且先要求原样复述上一轮的全部结论,再看新增答案是否与前文冲突。不要求复述,衰减通常看不出来。
[第 2 轮] 先原样复述你上一轮的全部结论,再回答:每个待办的负责人是谁?
[第 3 轮] 先原样复述你上一轮的全部结论,再回答:每个待办的截止时间是什么?
[第 4 轮] 先原样复述你上一轮的全部结论,再回答:哪些待办之间有依赖?
[第 5 轮] 先原样复述你上一轮的全部结论,再回答:只能先做一件的话选哪件,一句话理由。
丢信息的判定:复述里少一条前轮结论、把结论换了说法、把两条待办合并成一条,或者补出材料里没有的负责人和时间,都记为丢。第一次出问题的轮次记进下表,它就是日常使用时的安全轮数。
| 轮次 | 复述是否完整 | 丢失或改写的内容 | 备注 |
|---|---|---|---|
| 第 2 轮 | |||
| 第 3 轮 | |||
| 第 4 轮 | |||
| 第 5 轮 |
长文输入测试:分段加长看输出是否走样
长文测试只改长度。把同一份素材按段落切开,做成分档:约 600 字、约 1500 字、约 3000 字、约 6000 字。每档的系统提示、问题、是否要求格式完全一致,只替换 <材料> 部分。为了让每个档位可比,在素材的开头、中部、结尾各放一个要点,例如三条待办,每档都问「材料中提到的待办有哪些」。
输出是否走样,按这四种情况判断:
- 齐全:三条要点都在,顺序与素材一致,没有素材之外的内容,该档可以继续用。
- 缺项:少一条及以上要点,把这一档的字数记下来,作为需要人工复核的起点。
- 走样:出现素材里没有的负责人或时间,或把两条要点合并成一条、把结论改写成别的意思,这一档不能直接进下游。
- 结构塌陷:原本要求分点输出,返回变成一整段散文,按走样处理。
还有一种容易被忽略的情况:输出开始整段复述素材原文来凑长度,要点并没有增加。出现这种返回时也按缺项记。
结构化输出测试:换格式要求看稳定性
结构化输出只改格式要求,素材和问题保持不动。三种要求写成:
列表:用无序列表输出这三个待办,一条一行,不要额外说明文字。
表格:用 Markdown 表格输出,三列:待办 | 负责人 | 截止时间。
固定字段:只输出 JSON,不要代码围栏,不要任何解释文字:
{"todos":[{"task":"","owner":"","due":""}]}
解析验证放在本地脚本里做,列表比对行数,表格按 | 切列看每行列数是否一致,固定字段直接走一次解析:
import json
raw = open("model_out.txt", encoding="utf-8").read()
try:
data = json.loads(raw)
print("ok", len(data["todos"]))
except Exception as e:
print("need_fix", e)
| 格式要求 | 是否夹带解释或围栏 | 能否直接解析 | 不稳定表现 | 处理动作 |
|---|---|---|---|---|
| 列表 | ||||
| 表格 | ||||
| 固定字段 |
三种里固定字段最容易在 JSON 前后多出一两句收尾说明。遇到这种情况直接记不可解析,不要在前端正则去剥,改成提示词里再收紧一次,并在服务端保留一次解析失败的兜底。
把三类结果合成一张选型参考表
把三张记录表放在一起看,结论只留三行,每行都要能对应到一类具体任务。
| 结论 | 适用任务 | 触发条件 |
|---|---|---|
| 可放心用 | 单轮整理、摘要、抽取,输出要求是列表或表格这类宽松格式;或多轮追问的轮数在你测出的丢信息轮次以内 | 素材长度在你测出的走样档以内 |
| 必须人工校对 | 达到或接近丢信息轮次的多轮追问;素材接近走样档;固定字段输出偶尔夹带解释文字 | 出现过一次缺项或改写 |
| 暂不适用 | 一次输入超过你测出的走样档;下游直接消费严格字段、不允许解析失败;需要在长材料里跨段落精确引用原文且不许改写 | 该档位已出现过走样或结构塌陷 |
【可放心用】把列表格式下跑出的前三行原始返回贴在这里,用于以后比对是否退化。
【必须人工校对】把固定字段那档夹带了说明文字的那次返回原样贴在这里。
【暂不适用】把超过走样档那次返回里缺项或编造的那一两句原样贴在这里。
三处片段留空,填入你自己的原始返回,不要照抄任何示例内容,这样下次模型或配置变化时才有可比的基线。