AgentDepthAgent 工程学习指南
输入概念或问题,检索正文和待编写目录。
第一次学习?从 L0 总览开始 →

Zero-shot 与 Few-shot:让例子教会模型边界

我的学习 →

正在读取学习记录…

Zero-shot(零示例)是在请求里只写任务,不附已做好的样例;Few-shot(少量示例)则在同一次请求里放几组“输入 → 期望输出”。这里的 shot 指示例数,不是重新训练模型。就像给新同事看几张已分流的工单,帮助他理解公司的分类约定。

比如,客户留言“我要退货”,客服需要把这条求助归到退款类。我们在请求里给模型看一组示例:“我要退货 → refund(退款类)”,再让它判断新的留言“物流到哪里了”。接下来比较有示例和没有示例时,请求分别怎样写。Google 的提示工程教材介绍了提示工程与微调的区别。

1. 先固定分类任务与标签

把客户求助按内容归类,便于客服找到负责处理的人。程序用三个英文标签记录分类结果:refund 表示退款或退货,shipping 表示物流、发货或到货,unknown 表示还需要确认。客户同时提出两类问题时,按这里的分类规则记录为 unknown,再请客服询问清楚。

客户说法正确队列依据易犯错误
“我要退货”refund明确退货意图按“货”字误分物流
“到哪儿了?”shipping只询问进度没有“物流”二字便判未知
“先别发货,我还要退款”unknown发货动作和退款诉求冲突按最近出现的词硬选一种
“在吗?”unknown没有业务意图为了凑标签猜测

unknown 是有意保留的输出,不是系统故障。Agent 若后续自动调用退款工具,路由错一次就可能触发错误副作用;分类器只能建议队列,不能直接授权退款。先把标签契约和人工交接规则写清,再考虑是否需要例子。

2. Zero-shot 与 Few-shot 究竟改变了什么

TXT
Zero-shot:按下述规则给工单分类……
客户:到哪儿了?
标签:

Few-shot:按下述规则给工单分类……
客户:我要退货       标签:refund
客户:物流到哪里了   标签:shipping
客户:先别发货还要退 标签:unknown
客户:到哪儿了?
标签:

前者依赖规则文本和模型已有能力;后者额外展示输出格式、边界与冲突处理。根据 Google 的术语说明,少样本提示包含多个示例,代价是更长的 prompt。示例不是训练样本的同义词:这些例子属于本次请求的上下文。下一次请求继续使用时,把它们重新放进消息中。

零样本先用规则测试,失败后诊断原因;只有示例能表达边界时才进入少样本试验,最终仍要独立校验输出
图1:沿箭头先查任务定义,再查格式和边界;只有缺少示范时才加例子。

给示例之前,先问三个问题:失败是因为标签定义含糊、输出格式含糊,还是任务知识缺失?标签含糊应修订规则;真实订单状态缺失要查系统;只有怎样套用既定规则仍不稳定,示例才可能有帮助。把“先别发货还要退”放进 Few-shot,是教冲突边界;把真实客户手机号放进去则是隐私泄漏。

3. 选择示例:覆盖边界,而非堆相似句

先放三条虚构短句,每条由输入和标签组成。退货、物流、冲突各有一条,比把同一句“我要退货”换十种说法更能展示规则边界。选择理由可以另记在自己的数据说明里。

示例选择策略收益代价或风险本任务建议
只放典型正例易读、token 少冲突和未知情形没被教到作为起点
每类一例并加边界例展示三类输出与冲突prompt 更长这里演示方案
按检索动态挑例可能贴近当前工单检索误差、泄漏、版本复杂有稳定评测后再考虑
无限追加失败案例短期修补方便偏置、成本、互相矛盾避免

三条例子分别处理退货、物流和双意图冲突。先逐条检查标签是否符合上面的规则;继续扩充时,记录例子的来源和顺序,因为顺序变化也可能影响模型回答。

4. 在 Windows 跟做:先验证示例集,再发模型

把 examples_lab.py、test_examples_lab.py 按下方代码逐个保存到同一个新文件夹。在资源管理器中打开该文件夹,地址栏输入 powershell,核对文件名后运行:

macOS:先在 Python 篇的学习文件夹中打开终端,执行 source .venv/bin/activate。再输入 cd ,把当前例子的文件夹拖入终端并回车,运行下面的命令。

保存为 examples_lab.py:

Python
"""把分类规则、已标好答案的示例和新的客户留言组合成一份请求。"""
# refund:退款退货;shipping:物流发货;unknown:需要客服进一步确认。
LABELS = {"refund", "shipping", "unknown"}
RULES = ("把客户工单分到 refund、shipping、unknown。明确退款/退货给 refund;"
         "只询问物流/发货给 shipping;两种意图冲突或信息不足给 unknown。"
         "只输出一个标签,不执行退款或发货。")
EXAMPLES = [
    {"text": "我要退货", "label": "refund"},
    {"text": "物流到哪里了", "label": "shipping"},
    {"text": "先别发货还要退", "label": "unknown"},
]

def validate_examples(examples, query):
    if not isinstance(query, str) or not query.strip():
        raise ValueError("empty_query")
    seen = {query.strip()}
    for item in examples:
        if not isinstance(item, dict) or item.get("label") not in LABELS:
            raise ValueError("bad_label")
        value = item.get("text")
        if not isinstance(value, str) or not value.strip():
            raise ValueError("empty_example")
        key = value.strip()
        if key in seen:
            raise ValueError("duplicate_or_leak")
        seen.add(key)

def build_prompt(examples, query):
    # 先检查示例,再依次放入规则、示例问答和等待分类的新留言。
    validate_examples(examples, query)
    lines = [RULES]
    for item in examples:
        lines.append(f"客户:{item['text']}\n标签:{item['label']}")
    lines.append(f"客户:{query}\n标签:")
    return "\n\n".join(lines)

if __name__ == "__main__":
    query = "到哪儿了?"
    print("zero_shot_examples=0")
    print(build_prompt([], query))
    print("few_shot_examples=3")
    print(build_prompt(EXAMPLES, query))
完整代码:test_examples_lab.py
Python
# 核对Zero-shot 与 Few-shot的正常结果和错误分支;断言失败时会显示对应的测试。
import unittest
from examples_lab import EXAMPLES, build_prompt

class PromptTests(unittest.TestCase):
    def test_zero_and_few_shot(self):
        self.assertNotIn("我要退货", build_prompt([], "到哪儿了?"))
        self.assertIn("标签:unknown", build_prompt(EXAMPLES, "到哪儿了?"))

    def test_bad_label(self):
        with self.assertRaisesRegex(ValueError, "bad_label"):
            build_prompt([{"text": "你好", "label": "maybe"}], "到哪儿了?")

    def test_empty(self):
        with self.assertRaisesRegex(ValueError, "empty_query"):
            build_prompt([], " ")

    def test_duplicate_and_leak(self):
        with self.assertRaisesRegex(ValueError, "duplicate_or_leak"):
            build_prompt(EXAMPLES, "我要退货")
        with self.assertRaisesRegex(ValueError, "duplicate_or_leak"):
            build_prompt([EXAMPLES[0], EXAMPLES[0]], "到哪儿了?")

if __name__ == "__main__":
    unittest.main()
Bash
ls
python -B -X utf8 examples_lab.py
python -B -X utf8 -m unittest -v test_examples_lab.py

程序把标签契约、示例和待分类工单组成 prompt,并检查非法标签、重复输入和待分类输入混入示例。你会先看到 zero_shot_examples=0,再看到 few_shot_examples=3 和两份请求文本;build_prompt 返回的就是这些文本,预测标签是后续模型调用的任务。

Python
def build_prompt(examples, query):
    validate_examples(examples, query)
    lines = [RULES]
    for item in examples:
        lines.append(f"客户:{item['text']}\n标签:{item['label']}")
    lines.append(f"客户:{query}\n标签:")
    return "\n\n".join(lines)

程序第一次调用已使用空列表运行零样本,你可以先核对那一段是否只有规则和当前工单;第二次调用使用三条示例。示例是已经带答案的参考工单,当前待分类工单单独放在请求末尾。若测试报 duplicate_or_leak,检查是不是复制了相同文本或把评测句放进示例;若报 bad_label,检查标签拼写;若找不到 Python,先按Python 环境篇检查命令。测试覆盖正常、非法标签、空输入、重复和泄漏边界。

三栏数据边界:可进入提示词的示例集、仅用于修改提示的开发集、锁定后用于最终评测的测试集
图2:示例集、开发集和测试集分开;测试集不能倒灌回示例集。

再加一个合法边界例。新建 add_example.py,粘贴完整程序并运行 python -X utf8 add_example.py:

Python
from examples_lab import EXAMPLES, build_prompt

examples = [dict(item) for item in EXAMPLES]
examples.append({"text": "在吗?", "label": "unknown"})
print(f"few_shot_examples={len(examples)}")
print(build_prompt(examples, "到哪儿了?"))

应先看到 few_shot_examples=4,请求里多出“在吗? / unknown”。只把新增示例的 text 改为 到哪儿了?,再运行,应得到 ValueError: duplicate_or_leak:待分类问题已被放进答案示范,比较会失去意义。恢复“在吗?”后重跑。

5. 真正比较模型时,该怎样记录

实际比较前,把数据分为可进入 Prompt 的示例集、供改写定位的开发集、最后检查的测试集。测试句倒灌回示例再报告成绩,叫数据泄漏。真实用户资料先脱敏;来源和顺序随示例集保存,便于复现。

判断 Few-shot 是否值得增加 token 时,另取未用于挑例的工单,固定模型版本、系统指令、温度和输出校验器,对相同输入请求两份 Prompt。比较真实回答与期望标签,按 refund、shipping、unknown 分开看错分,再看延迟与 token 用量。这样能发现总正确率提高却冲突类退步的情况。

现象先查证据下一步
输出 refund. 等非法格式原始输出与解析器明确输出契约
总准确率升了但冲突类变差逐类混淆表检查示例分布和冲突规则
只在测试集中好看数据分区和示例来源锁定独立留出集重测
延迟、成本显著增加token 与耗时日志减少冗余例子,评估收益

当前输出用于检查示例装配与标签规则;Few-shot对模型效果的提升,需要真实请求和同一组评测问题来比较。最新订单事实、权限和工具状态则由业务系统提供。下一篇 采样参数 讨论输出波动,之后 结构化输出 检查标签能否被程序安全接收。

自查与继续学习

Zero-shot=指令与输入,无完成示例;Few-shot=在上下文里增加少量输入/输出例子。先修清任务契约,再选覆盖边界的脱敏示例;示例集、开发集、测试集分开。离线 prompt 构建成功不等于模型准确。

自查:组成零示例和三示例请求;加入“在吗?”后观察示例数变为4;把当前问题混进示例,解释 duplicate_or_leak。费用、延迟和准确率等到真实模型对照时再记录。

课后练习展开习题收起习题

4 道练习 · 客观题规则评分 · 其余题目待批改

正在读取本地记录…

不调用模型,不执行代码。简答、代码和场景题仅保存答案并展示自查标准,不生成评分、徽章或认证。输入内容不会自动保存,请点击提交;不要填写个人信息或密钥。

练习 1 / 4 · v1.0.1

选择题 · 先判断边界

关于“Zero-shot 与 Few-shot 示例”,哪种做法更稳妥?

对应知识点:L1-examples

选择一个答案
练习 2 / 4 · v1.0.0

简答题 · 解释失败

写出一个失败输入并说明记录字段。

对应知识点:L1-examples

练习 3 / 4 · v1.0.0

代码题 · 边界测试

补充正常、边界、失败三组输入和预期结果。

对应知识点:L1-examples

练习 4 / 4 · v1.0.0

场景题 · 结果未知

证据不足时如何设计状态和人工接管?

对应知识点:L1-examples

进一步阅读:Google 提示工程教材介绍提示与微调;Google 机器学习术语表解释 zero/one/few-shot。

图片查看器
100%

文章配图 · 按 Esc 关闭