同一份提示词在两个模型上答得不一样时,建议先查参数,再看模型说明。参数是你在接入层能直接改、能直接打印出来的东西:系统消息、采样参数、最大输出长度、流式开关一旦不同,两个模型的输出本身就不具备可比性。等这些拉平之后,再把仍然存在的差异拿去对照模型说明里的输入长度上限、结构化输出与流式支持,通常更容易定位到底是请求写错,还是模型能力边界不同。
判断顺序建议:先在接入层打印两次请求的最终请求体,逐项确认系统消息、采样参数、最大输出长度和是否流式一致;再验证系统消息是否被同等对待;然后拿模型说明里的输入长度上限、结构化输出和流式支持三项,各用一次最小调用验证。只有参数拉平后仍存在的输出差异,才适合归因到模型本身,并写进团队的使用建议。若某条说明无法通过调用验证,就先记为待确认项,不要据此分配任务。
把两次请求的参数逐项摊开对比
先确认交给模型的输入条件是否一致。很多平台上两个模型的调用共用一段代码,但经常出现默认参数不同,或者某个模型走了旧封装的情况。把两次请求按同一张表填空,差异会立刻显出来。
| 检查项 | 模型A实际值 | 模型B实际值 | 是否一致 |
|---|---|---|---|
| 系统消息(内容与版本) | 填写 | 填写 | 是/否 |
| 采样参数 temperature / top_p | 填写 | 填写 | 是/否 |
| 最大输出长度 max_tokens | 填写 | 填写 | 是/否 |
| 是否流式 stream | 填写 | 填写 | 是/否 |
| 停止条件 stop | 填写 | 填写 | 是/否 |
| 工具或结构化输出开关 | 填写 | 填写 | 是/否 |
| 历史消息条数与拼接顺序 | 填写 | 填写 | 是/否 |
查看实际请求体的方式有三种,按你手头条件选:在接入层打印最终 payload;用 curl 或脚本重放一次;或使用平台提供的请求日志页面。打印时建议脱敏,不要把密钥和业务数据写进日志。
# 通用接入骨架:打印最终发给模型的请求体
payload = {
'model': model_name,
'messages': messages, # 含 system / user
'temperature': temperature,
'top_p': top_p,
'max_tokens': max_tokens,
'stream': stream,
}
print({k: v for k, v in payload.items() if k != 'messages'})
print('system:', messages[0].get('content') if messages else None)
print('history_len:', len(messages))
resp = client.chat(payload) # 按你所用接入方式替换
这段骨架放在调用模型之前执行,替换掉 client.chat 这一行即可。messages 只打印角色和长度,避免业务内容落盘。两次调用如果走了不同的重试路径,把重试次数也记下来。
确认系统消息在两个模型上是否被同等对待
系统消息是最容易被忽略的一层。有的接入层会把 system 拼进第一条 user 消息,有的直接丢弃 system 只保留 user,模型说明里对 system 的处理方式也可能有差别。这些都会表现为同一份提示词答得不一样。
验证方法:写一条可检查的约束放进系统消息,两个模型各调一次。
system: 你是格式检查助手。无论用户问什么,回答必须以“收到约束:”开头,正文只输出三个要点,每点不超过20字,不解释原因。
user: 说明一下如何整理会议记录。
观察三件事:开头是否出现指定前缀、要点数量是否受限、是否额外输出解释。三条都符合,说明系统消息生效;只有格式部分生效或完全不生效,就要回到接入层看 system 是否被拼接、覆盖或截断。同一约束建议连调两次,避免把偶发当成规律。
观察记录这样记:模型名、系统消息版本、用户消息、输出前若干字、前缀是否出现、要点条数、是否出现解释、接入层的拼接方式。记录表按行追加,不要只留一句“效果不好”。
在模型说明里核对三项关键信息
参数一致、系统消息确认生效之后,把剩下的差异对着模型说明核对。下面三项是差异最常见的来源,每项都可以用一次最小调用验证,不必等完整评测。
输入长度上限
按说明里给出的上下文长度准备输入,说明没有明确数字时,用保守长度逐次加长,记录从第几次开始报错或开始丢信息。重点看返回的是明确的长度报错,还是静默截断。报错原文要留下来,它比“答得不好”有用得多。
是否支持结构化输出
给一个最小 schema,要求返回可解析的 JSON,例如包含 name 和 count 两个字段。一次调用就能看出结果能否被解析、字段是否齐全。若一个模型返回 JSON、另一个返回带解释的自然语言,差异来源就清楚了。
是否支持流式
把 stream 设为 true 调用一次,观察是否返回增量分片、结尾是否有完整结束标记。若某个模型只在 stream 为 false 时正常,那么它在流式场景下的差异来自支持情况本身,而不是提示词写法。
说明里写的和实际调用对不上时,以你的调用观察为准,并在使用建议里标注为待确认项。
用固定任务做一次对齐后的复测
参数拉平后重新比较,看差异是否仍然存在。复测提示词要短、可判定,不要用开放式问题。
系统消息:你是格式检查助手,回答不要解释。
用户消息:用不超过5条、每条不超过20字,列出整理会议记录的步骤。
评判点:条数是否超过限制、每点字数是否超标、是否出现额外解释、输出是否被截断、两个模型是否都完整给出步骤。内容措辞不同不算错,格式和长度差异才算值得记录的差异。
复测记录表字段:轮次、模型名、参数快照(temperature、top_p、max_tokens、stream)、系统消息版本、提示词版本、输出原文、条数、单点最长字数、格式是否达标、是否截断、差异归属(参数、系统消息、模型说明、未定位)。归属为未定位的,下一轮优先查。
把残留差异写成使用建议
这一节不写哪个模型更好,只写什么任务交给哪个模型,并附上依据。
- 长文摘要与写作:交给复测中输出长度稳定、没有被截断的那个模型。依据是 max_tokens 相同、系统消息生效的前提下,输出是否在限定长度内完成。
- 结构化数据抽取:交给结构化输出验证通过的那个模型。依据是同一 schema 下返回可解析、字段齐全。
- 流式交互场景:交给流式验证通过的那个模型。依据是 stream 为 true 时能正常返回增量结果。
- 强格式约束任务:交给系统消息复述测试中约束生效的那个模型。依据是前缀、条数、字数三项都符合。
- 两个模型都没通过的任务:先不分配,标注待确认项,回到参数和模型说明继续定位。
每条建议后面附上复测条件:用了哪版提示词、哪些参数、观察到什么现象。这样团队下次改动接入层时,能直接知道该重跑哪一项。