最近有朋友问我一个特别常见的问题:“我完全没训练过模型,怎么让它帮我干活?”这问题背后其实藏着一个很有意思的误解——很多人以为只有“喂了数据、调了参数”的模型才会做事,可大模型偏偏打破了这套认知。你给一段指令,甚至不给任何例子,它也能把任务干得八九不离十,这就是今天想聊的Zero-Shot和Few-Shot。
先说清楚,这篇文章不是给算法工程师看的推导讲义,而是给所有“零基础但想上手AI大模型”的人准备的。我会从最简单的现象出发,讲明白零样本(Zero-Shot)和少样本(Few-Shot)到底是怎么回事,为什么模型不训练也能听懂人话,以及你在实际使用中最容易踩的坑。全文不涉及复杂公式,你只需要打开任何一个主流大模型对话工具,就能跟着一起验证。
1. 零训练直接干活:Zero-Shot为什么一点也不“神奇”
如果你第一次接触大模型,可能会被Zero-Shot这个术语吓到。其实它描述的场景朴素得很:你给模型一条指令,描述清楚任务是什么,它直接给出结果——整个过程里你没有提供任何“标准答案”作为示例,它也没针对这个任务做过额外训练。这就是“零样本”三个字的来源:样本数量为零。
我拿自己最早试过的一个例子来演示。当时我随便打开一个对话模型,输入:
把下面这句话翻译成英文:这个周末我们去看电影吧。它立刻输出了一句地道的英文翻译。这里就有个值得琢磨的点:我从头到尾没给它任何中英对照的例句,也没告诉它“翻译的格式是左边中文、右边英文”,它就自己完成了。在传统机器学习时代,同样的事情几乎不可想象——你至少得准备几千条平行语料,训练一个专门的翻译模型,才能得到可用结果。而大模型只需要一句指令就做到了。
为什么会这样?答案在“预训练”三个字里。大模型在训练阶段读过的文本量非常庞大,相当于一个人把图书馆里几乎所有语言的书都翻过一遍。在这个过程里,它积累了大量的语言规律、常识知识和跨语言映射关系。当你用中文下指令时,它并不是真的“第一次学习翻译”,而是在自己庞大的知识储备里“回忆”出翻译应该长什么样。
那Few-Shot又是什么?它比Zero-Shot多走了一步:你在给模型下达任务时,附带几个“输入-输出”的示例对,让模型照着示例的模式去做。比如我想让模型把电影评论分为“正面”和“负面”,我会先这样写:
判断下面的评论情绪是“正面”还是“负面”。 “这家餐厅服务很好,上菜也快。” → 正面 “等了一个小时还没上菜,服务员也不理人。” → 负面 “电影画面很美,但剧情很拖沓。” →模型看到前两个示例后,会模仿这个“识别情绪并归类”的模式,对最后一条新评论给出自己的判断。你可能会问:这跟训练有什么区别?区别很大——模型的参数一个都没变,它只是根据上下文里的示例,调用了已有的理解能力。“示例”在这里起的不是训练作用,而是“定位”作用,相当于告诉模型:你现在要做的是这件事,照这个格式来。
对零基础的人来说,理解这两者最关键的一步,就是放下“必须训练才能用”的旧观念。大模型时代,很多任务靠提示词就能直接驱动;而你补充的示例越多、越精准,模型的输出就越接近你想要的样子。
2. 藏在模型里的临时记忆:上下文学习到底是怎么运作的
前面说了,模型不是“临时学会”,而是“回忆知识”。这里有个更底层的机制值得展开,工业界管它叫上下文学习。这个术语听起来高级,但本质一句话:模型在生成回答时,会把你输入的所有内容当作临时的参考依据。
想象一下你公司来了位经验丰富的老员工,他在上一家公司做过各种各样的活。今天你给他布置一个新任务,不安排培训,也不给他写详细手册,就是口头说了两句要求,他就能干活了。他靠的是多年积累的通用能力,而不是重新学习。大模型就是这样一位老员工——预训练相当于它过去十几年的工作经验,提示词里的指令和示例,相当于你口头交代的“这次具体要求”。
不过模型不是人,它没有真正的“意图理解”,它只有一种能力:预测下一个词。这个机制的厉害之处在于,它会根据你给的全部上下文,来判断“接下来最合理的输出是什么”。当你在提示词里写了“判断情绪:×××→正面,×××→负面”,模型在生成“电影画面很美,但剧情很拖沓。”后面的内容时,已经从前面两行示例中提取到了一条规律:收集评论、判断倾向、输出标签。于是它输出的就不再是“这是一部电影”之类的话,而是“负面”这个判断。
这里面还有个容易被忽视的细节——注意力机制。Transformer架构里有一个核心模块,会让模型在生成每个词时,自动去“关注”输入里那些相关的词。当模型看到“正面”这个词时,它会把注意力同时投向示例里的“服务很好”“上菜也快”,也会注意到反例里的“等了一个小时”“不理人”。这种词与词之间的关联加权,让模型能识别出示例之间的一致性模式。你可以把它理解成:模型会在输入文本里画很多条看不见的关联线,把相似含义的词串在一起。
这个机制解释了一个现象:示例的写法和顺序会影响效果。如果你的两个示例分别是“好评→正面”和“差评→负面”,模型更容易提取出“按情绪分类”的规律;如果你给的示例本身逻辑混乱,比如第一条是“好评→正面”,第二条是“差评→正面”,模型就会困惑,因为它从上下文里找不到稳定的模式。
还要澄清一个常见误区:上下文学习不是“模型把示例记住了”。模型没有记忆存储,每次请求都是独立计算。你这次给它的示例,只存在于这一次对话的输入上下文里,下次重新提问,它不会记得上次你是谁、你给了什么例子。这也是为什么“上下文窗口”很重要——模型一次能处理的输入长度有限,示例太长、太多,可能超出它能参考的范围。
3. 两个例子就够了:Few-Shot示例提示的实操法则
看完机制,我们来上手。Few-Shot的核心不是“给很多例子”,而是“给对例子”。很多人第一次用Few-Shot时容易犯一个毛病:恨不得给模型二十个示例,觉得例子越多越准。实测下来未必如此,示例过多反而可能让模型无所适从,或者被其中某几个不统一的例子带偏。我自己调提示词的经验是:大多数任务,两到八个高质量示例就能达到不错的稳定效果。
先看一个我最近在做的邮件分类场景。原始需求是让模型把收到的邮件自动分成“任务类”“通知类”“闲聊类”。先试Zero-Shot,指令写的是“给邮件分类”,结果模型输出五花八门,有的给出一段解释,有的把“任务”写成“待办”。后来我改成Few-Shot,提示词长这样:
把下面的邮件内容分类,类别只有三种:任务类、通知类、闲聊类。只输出类别名称。 “请在本周五前提交项目进度报告。” → 任务类 “会议室已经预订好了,随时可以开会。” → 通知类 “最近想约大家周末一起爬山,有人去吗?” → 闲聊类 “财务部提醒大家,报销系统将在月底关闭。”模型输出“通知类”,而且稳定多了。这个案例里,示例的关键作用不是教会模型“什么是通知”,而是锁定了输出格式——每个回答都只有三个字,没有废话。后面我再批量处理几十封邮件,格式都是干净的。
选示例的时候,我建议你遵守几条经验法则。第一,覆盖正反两面。如果做分类,正例和反例都要有,别只给同一类示例,否则模型容易产生偏向。第二,保证格式完全一致。示例里的输入、分隔符、输出之间,写法要统一,让模型能提取出清晰的模板。第三,示例要贴合真实场景。你想让模型处理客服投诉,示例就该用客服话术,而不是从新闻里随便摘几句。第四,示例顺序有讲究,把最典型的一对放在开头和结尾,中间可以放一些边界模糊的样本,这样模型会先抓住核心规律,再学会处理边缘情况。
还有一类任务是“信息抽取”,Few-Shot同样好用。比如从招聘信息里抽取公司名和职位名:
从下面文本中抽取“公司名称”和“职位名称”,输出为两行。 张三在星辰科技有限公司担任高级算法工程师。 公司名称:星辰科技有限公司 职位名称:高级算法工程师 李四在云端数据服务股份有限公司担任交付经理。 公司名称:云端数据服务股份有限公司 职位名称:交付经理 王五在蓝海生物科技有限公司担任市场专员。模型会照着前两个示例的抽取格式,输出:
公司名称:蓝海生物科技有限公司 职位名称:市场专员这个过程中,模型并不是靠“理解招聘信息”来抽取,它更多是靠模仿示例的格式和字段位置。所以你会发现,示例里字段的排列顺序都会被模型学走。如果想让输出变成“职位名称在前,公司名称在后”,那就得在示例里把顺序反过来。
给示例时还有一个容易被忽视的实战细节:分隔符。示例之间、指令与示例之间,最好用清晰的标记隔开,比如“---”或者换行加编号。模型虽然能处理自由文本,但分隔越明确,它提取规律越顺。我自己习惯用“样例1:”“样例2:”这样的编号,效果比全部挤在一起好很多。
4. Zero-Shot的翻车现场与修复策略
Few-Shot这么好用,是不是所有任务都该堆示例?也不是。Zero-Shot的优势是省事、自然、不需要准备样本,适合快速验证想法;但它也有明显的坑。我在实际项目里翻过好几次车,把最常见的几种情况和修复思路一起列出来。
第一个坑是输出格式不稳定。你让模型“用JSON返回结果”,它可能在JSON外面加一句“好的,这是你要的JSON如下:”,直接把下游程序搞崩。修复办法是在指令里把边界写死,比如“只输出JSON,不要输出任何多余文字”,或者干脆用Few-Shot给一个JSON示例,让模型照着样例格式输出。对于程序对接场景,Few-Shot几乎是必须的,因为格式对齐这件事,光靠措辞兜不牢。
第二个坑是任务描述太含混。我经历过一个案例,让模型“总结一下”一份会议纪要,结果显示给了一段比较长的复述,而不是要点。问题出在“总结”这个词本身就有歧义,压缩到多少算总结?保留什么丢弃什么?Zero-Shot模式下模型会自动选择一个它认为合理的理解。修复方式是把指令改得可度量:“用三句话总结这份会议纪要,分别对应议程、决议、待办事项。”把模糊的动词变成具体的约束条件,Zero-Shot的稳定性立刻提升。
第三个坑是模型被示例外的语言风格带偏。做文本分类时,如果输入文本里有一堆情绪强烈的词汇,Zero-Shot模式下模型很容易被这些词汇本身带跑,输出“这句话表达了愤怒”而不是分类标签。举个我踩过的例子,输入“这个破软件闪退了三次,真想把电脑砸了”,我让它判断“用户反馈类型”,它输出的是“用户情绪:愤怒”。可我实际想要的是“技术问题:软件闪退”。修复方法是把分类维度写得更具体,比如“判断反馈属于以下类型的哪一种:软件缺陷、网络问题、使用疑问。”如果能给Few-Shot示例,效果会更好。
第四个坑是“幻觉式自信”。没有示例参考时,模型为了完成你的指令,可能凭空造出一些看起来合理但实际不存在的内容。早期我让一个模型抽取客户邮件里的订单号,结果模型输出了一串完全编造的号码——因为这个任务需要它理解特定格式,而Zero-Shot条件下它没有参照物可循,就只能靠猜。后来我给了两个含真实订单号格式的示例,它立刻不再编造了。
这些坑背后其实有一个共性:Zero-Shot适合“模型已经非常熟悉、知识边界清晰”的任务,比如通用翻译、常识问答、简单改写;一旦任务涉及特定格式、特定领域术语、多选一标签,或者输出需要被程序精确解析,那务必加几个示例,哪怕只有两三个。
我还会用一招叫“自检式修正”。有时候任务复杂,既想利用Zero-Shot的灵活,又怕它跑偏,我会在后面补一句:“如果以上内容不符合要求,请重新严格按照指定格式输出。”这相当于给模型一个回头纠错的机会,实测对格式问题有一定改善,但它不解决知识缺失问题——模型不知道的东西,再自检也编不出来。
5. 什么时候该用哪个:选择策略与能力边界
讲到这里,你应该能感觉到,Zero-Shot和Few-Shot不是谁替代谁的关系,而是同一套能力的两个档位。实际使用中,我一般按四步来判断选哪个:先看任务复杂度,再看格式要求,三看领域陌生度,四看成本和延迟。
如果任务简单且模型见过大量类似数据,比如翻译、润色、常识问答,Zero-Shot完全够用。如果任务返回结果要对接程序、是严格的标签集合、或者涉及公司特有名词和缩写,那就切到Few-Shot。领域陌生度也很关键,比如让模型判断医疗器械注册证的某种特殊编号格式,这种很可能在预训练语料里很少出现,Zero-Shot大概率懵,给几个示例它能立刻模仿格式。至于成本和延迟,Few-Shot每次请求都会携带示例文本,输入token变多,费用和响应时间也随之上升,所以批量任务里不能无限制堆示例。
就我自己的体感,可以大致给出一个参考表:
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 通用翻译、改写、头脑风暴 | Zero-Shot | 任务通用、输出自由度大,不需要示例约束 |
| 情感分类、主题打标 | Few-Shot(2~4个示例) | 需要精确匹配标签,示例能稳定输出格式 |
| 结构化信息抽取、JSON输出 | Few-Shot(3~6个示例) | 格式必须被程序解析,示例是不可或缺的模板 |
| 复杂推理任务 | 进阶方案,不止Few-Shot | 需要更长的推理链路,见下文 |
| 大批量低成本处理 | Zero-Shot + 严格指令 | 节省token,靠约束词提升稳定度 |
表格最后一栏提到的复杂推理任务,我是真心建议你不要只停留在Few-Shot。比如让模型做多步数学题、写一段需要前后呼应严谨的长文,几个示例往往不够。这时候更有效的方法是在提示词里要求模型“逐步思考”,或者先给一个解决问题的思路示例,让模型先计划再动手。这些东西整体叫高阶提示工程,是在Few-Shot之后很自然的下一站。
另外要泼一盆冷水:Few-Shot不是万能的,它有一个明确边界——它无法真正给模型注入“它从未见过的新知识”。示例里的信息,模型能模仿形式、风格和规则,但如果示例涉及的知识点完全不在模型的预训练范围里,比如某个非常小众的行业黑话、某个你们公司内部的私有系统名称,那么就算给几十个例子,模型也可能只是生硬地模仿表面格式,内在仍会出错。这时候该考虑的不再是提示词,而是把背景知识写进示例里,或者走微调路线。判断依据也很简单:如果 Examples 里的信息换个说法模型就认不出来,说明它没有真正理解,那就要考虑换方案。
还有一个容易误解的点:Few-Shot的示例数量上限。上下文窗口就像一张桌子的面积,示例越多,留给最终答案的桌面就越小,而且中间的示例可能会把模型的注意力稀释。在实测中,超过八个示例以后,收益通常不再增长,有时甚至下降。真正决定效果的不是示例数量,而是示例的代表性。一个覆盖核心规律的示例,顶得上十个重复泛泛的例子。
写完这篇,最后分享一点具体的使用心得
我平时起步特别喜欢先用Zero-Shot快速探路。任务还没摸清时,写一条最简单的指令看模型怎么反应,这一步成本极低,却能帮你发现任务里的隐藏歧义。比如你发现模型总在输出解释而不是标签,那就说明词义没对齐;发现它编造信息,那就说明知识有缺口。根据这些信号,再决定要不要上Few-Shot,以及示例该侧重格式还是该侧重知识补充。
给示例的时候,我会专门留出两到三对“边界样本”——不是最典型的正面例子,而是那些模棱两可、人也要犹豫一下的输入。这类样本能有效约束模型在边缘地带的表现,比多给同类典型示例管用得多。我自己在分类任务里试过,加入一条边界样本后,误判率肉眼可见地下降。另外我习惯把最重要的示例放在提示词的开头,因为模型在读取长文本时,对开头内容的注意力往往更强。
如果你现在手头正好有个对话模型,可以立刻做个小实验:先输入“给一句话:今天天气很好,适合出去玩。它的情绪是正面还是负面?”看看Zero-Shot的输出;再加一个示例“今天下雨,堵车半小时。负面。”重新试一次,你会发现第二次的输出明显更干脆。这种亲自操作带来的体感,比读十篇概念讲解都有用。
先把Zero-Shot和Few-Shot用熟,你再往回看那些五花八门的提示词技巧,会发现其实都是在同一根轴上做文章——如何更好地说清楚“我要你干什么”。这个东西,确实是所有零基础学习者最值得先弄明白的第一课。