Zero-shot、Few-shot 和思维链提示分别适合什么场景?

进阶高频对比约 7 分钟读完

一句话回答

Zero-shot 只给指令、不给示例,适合模型本来就擅长、说清楚就能做好的任务;Few-shot 在 Prompt 里放几个"输入 → 输出"的示例,适合输出格式、分类标准、写作风格这类难以用语言描述清楚的要求;思维链提示让模型先写推理步骤再给答案,适合数学、逻辑这类多步推理。三者可以组合,比如给带推理过程的示例;对推理模型,一般不需要再要求分步思考,示例也要少用。

详细解析

三种方式对比

方式 做法 适合 代价
Zero-shot 只写指令 翻译、摘要、通用问答等常见任务 最省 token
Few-shot 指令加若干示例 自定义的输出格式、分类标准、写作风格、领域术语 示例占 token;模型可能照抄示例
思维链 要求先推理再回答,或者给带推理过程的示例 数学、逻辑、多条件判断 输出更长,延迟和成本更高

一般从 Zero-shot 开始,效果不够再加示例,涉及多步推理再加思维链。

Few-shot 示例怎么选

  1. 覆盖不同情况:每个类别都要有,包括边界情况和"都不属于"的情况
  2. 格式完全一致:示例的格式就是模型会模仿的输出格式
  3. 贴近真实输入:长度、口语化程度、错别字这类噪声要和线上数据接近
  4. 注意比例和顺序:模型容易偏向示例里出现最多的类别,也更容易受最后几个示例的影响,各类别的数量要均衡、顺序要打乱
  5. 和真实输入区分开:用 <example> 这类标签包住示例,避免模型把示例当成要处理的内容

示例很多时可以动态选择:把示例库向量化,每次检索和当前输入最相似的几个放进 Prompt。示例不要和评测集重复,否则评测结果会偏高。

文本
把用户反馈分到以下类别之一:物流、质量、售后、其他。同时涉及多个问题时,按用户最主要的诉求归类。只输出类别名。

<examples>
<example>
反馈:下单五天了还显示未发货
类别:物流
</example>
<example>
反馈:衣服洗了一次就掉色
类别:质量
</example>
<example>
反馈:退货寄回去一周了,钱还没退
类别:售后
</example>
<example>
反馈:App 什么时候出夜间模式?
类别:其他
</example>
</examples>

反馈:{用户反馈}
类别:

思维链提示和 Self-Consistency

  • Zero-shot CoT:在问题后面加一句"请先一步一步分析,再给出答案"
  • Few-shot CoT:示例里写出完整的推理过程,模型会模仿这种推理方式
  • 要求把推理和答案分开输出(比如分别放在 <thinking> 和 <answer> 标签里),程序只取答案部分

Self-Consistency(自洽性):同一个问题用较高的 temperature 采样多次,每次得到不同的推理路径,最后对答案做多数投票。思路是:正确的推理路径虽然各不相同,但往往殊途同归;错误的答案则比较分散。它适合有确定答案的任务(计算、分类、判断),代价是成本随采样次数成倍增加。

推理模型下的变化

推理模型在回答前会自己思考,上面的做法要相应调整:不需要再写"一步一步思考",也不必自己设计"推理 + 答案"的输出格式;先试 Zero-shot,示例主要用来固定输出格式。思维链为什么有效、推理模型怎么用,见 思维链和推理模型。

代码示例

Self-Consistency 的实现(llm.chat 是通用伪接口):

TypeScript
async function selfConsistency(question: string, n = 5) {
  const prompt = `${question}\n\n先在 <thinking> 标签中逐步推理,再把最终答案写在 <answer> 标签中。`
  const runs = await Promise.all(
    Array.from({ length: n }, () =>
      // temperature 不能为 0,否则每次的推理路径几乎一样,投票就没有意义
      llm.chat({ temperature: 0.8, messages: [{ role: 'user', content: prompt }] }),
    ),
  )

  const votes = new Map<string, number>()
  for (const run of runs) {
    // 实际使用时要先归一化答案(去掉单位、统一格式),再计票
    const answer = run.content.match(/<answer>([\s\S]*?)<\/answer>/)?.[1]?.trim()
    if (answer) votes.set(answer, (votes.get(answer) ?? 0) + 1)
  }
  const top = [...votes].sort((a, b) => b[1] - a[1])[0]
  // 一致率低说明模型没把握,可以转人工或换更强的模型
  return { answer: top?.[0] ?? null, agreement: (top?.[1] ?? 0) / n }
}

面试官可能追问

Few-shot 示例放几个合适?

没有固定的数字,常见的建议是 3~5 个,能覆盖主要情况就够了。示例越多,token 和延迟越高,收益却越来越小。可以在评测集上比较不同数量的效果。

模型照抄示例里的内容,怎么办?

让示例在内容、长度、措辞上更多样;在指令里说明"示例只用于展示格式";必要时用占位内容代替具体的值。动态选择和当前输入相似的示例,也能减少生搬硬套。

思维链一定能提升效果吗?

不一定。对简单的分类、抽取任务,它的提升有限,还会增加延迟和成本。最初的研究也发现,思维链在规模足够大的模型上才有明显收益,小模型写出的推理链可能是错的,反而把答案带偏。要用评测数据来验证。

Few-shot 和微调怎么选?

Few-shot 不用训练,改了示例立即生效,但每次调用都要为示例付费,能放的数量也有限。示例越加越多、效果仍不稳定,或者调用量很大、想省掉示例的 token,可以把这些数据拿去微调,见 微调、RAG 和 Prompt 工程怎么选。

易错点

  • 示例只覆盖一种情况,模型会把它当成唯一的模式
  • 示例的格式和要求的输出格式不一致,模型会跟着示例走
  • 对推理模型还写"一步一步思考"、塞大量示例
  • 用思维链时直接把整段输出当答案,没有把推理和答案分开

AI 模拟面试官

用自己的话回答,AI 对照参考答案打分、指出遗漏,再追问,最多 3 轮

登录后就可以和 AI 面试官对练,面试记录也会保存下来。登录

这道题你掌握了吗?

选一个最接近的状态,没掌握的题会出现在"我的进度 · 待复习"里。

学习记录暂存在本机浏览器。登录后自动同步到账号,换设备也能看到。