少样本提示:用最少的例子撬动最大的效果

少样本提示(Few-shot Prompting),说白了就是给大模型喂几个例子,让它照着你的路子走。我刚开始接触这个技术时,总觉得例子越多越好,结果发现根本不是那么回事。

举个例子,你想让模型把中文句子翻译成英文。你给一个例子:「苹果 → apple」,模型就懂了。你给一百个例子,模型反而可能被带偏。为什么会这样?因为例子太多,模型会去「总结规律」,而不是「模仿格式」。

嗯,这里要注意:少样本提示的核心不是「教」模型新知识,而是「激活」它已有的能力。模型在训练时已经见过海量数据,你给的例子只是帮它定位到正确的「思维模式」。

设计原则:少即是多,精才是王道

我个人习惯遵循三条原则,你可以参考一下:

  • 一致性原则:所有例子的格式必须完全统一。比如你写「输入:xxx,输出:yyy」,那就别在第三个例子写成「问题:xxx,答案:yyy」。我在项目中遇到过,就因为格式不统一,模型输出变得乱七八糟。
  • 代表性原则:每个例子要覆盖一类典型场景。比如做情感分类,你给一个正面例子「这部电影太棒了 → 正面」,再给一个负面例子「剧情无聊透顶 → 负面」,就够了。别给两个正面例子,模型会以为所有输入都是正面的。
  • 边界性原则:最好包含一个「边界案例」。比如分类任务中,给一个模棱两可的例子「这部电影还行 → 中性」。这能告诉模型:不是所有东西都非黑即白。

核心要点:少样本提示不是「越多越好」,而是「越精越好」。3-5个高质量例子,往往比10个随意例子效果好得多。

示例选择策略:怎么挑出那「黄金三例」?

你想想看,如果你只有三个例子的名额,你会怎么选?我一般用下面这套策略:

  1. 多样性优先:覆盖不同的输入模式。比如做代码生成,一个例子是「循环」,一个是「条件判断」,一个是「函数调用」。别三个都是循环。
  2. 难度递进:第一个例子最简单,让模型「热身」。第二个中等,第三个稍微复杂。我试过上来就给复杂例子,模型直接懵了。
  3. 避免噪声:例子中不要包含无关信息。比如你让模型提取日期,例子就别写「今天天气不错,2024年3月15日我去公园了」。模型可能会以为「天气不错」也是输出的一部分。

我的小技巧:如果任务比较复杂,我会先用零样本试一次,看看模型「默认」会怎么输出。然后根据它的错误,针对性设计少样本例子来纠正。这比凭空想例子高效得多。

样本数量对效果的影响:3个?5个?还是10个?

这个问题我踩过不少坑。直接说结论:

样本数量 适用场景 效果特点
0(零样本) 简单任务、模型已熟练掌握的任务 速度快,但稳定性差
1-2个 格式引导、简单分类 够用,但容易过拟合到例子
3-5个 大多数任务(推荐) 效果和效率的最佳平衡点
6-10个 复杂推理、多步骤任务 效果提升有限,成本翻倍
10个以上 几乎不需要 边际效应递减明显,可能引入噪声

我曾经做过一个实验:让模型做数学应用题。用3个例子时,准确率78%。加到5个,准确率82%。加到10个,准确率83%。但输入长度翻了三倍,响应时间也慢了。说白了,第4个例子之后,收益就微乎其微了。

避坑指南:我曾经犯过一个错误——给模型太多例子,结果模型开始「总结」例子中的模式,而不是「模仿」格式。比如我给了5个情感分类例子,模型居然自己总结出「如果句子长度超过10个字,就是正面」。这完全不是我想要的。所以,例子数量控制在3-5个最安全。

实战代码:一个少样本提示的完整示例

下面是我常用的一个少样本提示模板,用于让模型做「文本转SQL」任务:

# 少样本提示模板
few_shot_prompt = """
请根据用户的问题,生成对应的SQL查询语句。

示例1:
用户问题:查询所有年龄大于30岁的员工
SQL语句:SELECT * FROM employees WHERE age > 30;

示例2:
用户问题:统计每个部门的员工数量
SQL语句:SELECT department, COUNT(*) FROM employees GROUP BY department;

示例3:
用户问题:找出工资最高的前5名员工
SQL语句:SELECT * FROM employees ORDER BY salary DESC LIMIT 5;

现在,请回答:
用户问题:{user_question}
SQL语句:
"""

你看,三个例子覆盖了三种不同的SQL模式:条件查询、聚合查询、排序查询。这就是我前面说的「多样性优先」。实际使用时,你只需要替换 {user_question} 即可。

进阶技巧:动态少样本选择

嗯,这里有个更高级的玩法。如果你有大量的历史数据,可以做一个「动态选择器」:每次根据用户输入,从数据库中挑选最相似的3个例子。怎么做?

  • 把每个历史例子编码成向量(用embedding模型)
  • 把用户输入也编码成向量
  • 计算相似度,挑出最相似的3个例子

我在一个客服系统中用过这个方案。效果比固定例子提升了15%左右。不过要注意,这个方案会增加一次embedding调用,成本会高一些。

我的建议:如果你的任务比较稳定,固定3-5个高质量例子就够了。如果任务变化频繁,再考虑动态选择。别为了炫技而增加不必要的复杂度。

最后总结一下:少样本提示的精髓在于「用最少的例子,传递最清晰的意图」。别贪多,别求全,把每个例子打磨到极致。你想想看,一个好的例子,胜过十个平庸的例子。这就是少样本提示的哲学。