Prompt Engineering 高级技巧:Few-Shot Learning 实战指南

在大语言模型(LLM)蓬勃发展的今天,如何有效地与模型交互成为了每个开发者必须面对的核心问题。Prompt Engineering(提示工程)作为一门新兴学科,专注于研究如何设计最优的提示词来引导模型产生期望的输出。可以说,掌握了提示工程,就等于拥有了在 AI 时代高效解决问题的能力。

Few-Shot Learning(少样本学习)是 Prompt Engineering 中最核心、最实用的技术之一。它允许我们在不进行模型微调的情况下,通过在提示中提供少量示例来显著提升模型的推理能力。这种方法既避免了耗时且需要大量 GPU 资源的微调过程,又能快速适配各种特定任务场景。

问题描述

许多开发者在使用 LLM 时会遇到这样的困境:模型虽然能力强大,但在处理特定领域任务时往往无法准确理解需求。即使提供了详细的指令,模型仍然会给出模棱两可或不准确的回答。

例如,假设你需要让模型对用户评论进行情感分类。如果你只是简单地说「判断下面文本的情感是正面还是负面」,模型可能会给出不一致的答案,有时甚至会误解某些表达方式。

为什么会这样?因为模型在预训练阶段学习的是通用语言模式,缺乏对特定任务格式和逻辑的深入理解。传统的解决方案是进行模型微调,但这需要大量的标注数据和计算资源,对于很多中小型团队来说并不现实。

Few-Shot Learning 提供了一个更优雅的解决方案:在提示中直接包含几个完成任务的示例,让模型通过这些示例来理解任务的本质和期望的输出格式。这种方法既避免了微调的高成本,又能快速适配各种任务场景。

详细步骤

环境准备

首先,我们需要安装必要的依赖:

pip install langchain langchain-openai chromadb

基础实现:使用 LangChain 构建 Few-Shot 提示

LangChain 提供了 FewShotPromptTemplate 类,专门用于构建少样本学习提示。让我通过完整的代码示例来演示。

from langchain.prompts import FewShotPromptTemplate, PromptTemplate
from langchain.prompts.example_selector import LengthBasedExampleSelector

# 定义训练示例 - 情感分类任务
examples = [
    {
        "input": "今天天气真好,阳光明媚!",
        "sentiment": "正面"
    },
    {
        "input": "这个产品太差了,完全浪费钱",
        "sentiment": "负面"
    },
    {
        "input": "今天吃了饭,没什么特别的感觉",
        "sentiment": "中性"
    }
]

# 创建示例模板
example_prompt = PromptTemplate(
    input_variables=["input", "sentiment"],
    template="文本: {input}\n情感: {sentiment}"
)

# 使用 LengthBasedExampleSelector 自动选择示例
example_selector = LengthBasedExampleSelector(
    examples=examples,
    example_prompt=example_prompt,
    max_length=100
)

# 创建少样本提示模板
few_shot_prompt_template = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    prefix="判断下面文本的情感倾向,只需要回答正面、负面或中性:",
    suffix="文本: {input}\n情感:",
    input_variables=["input"],
    example_separator="\n\n"
)

# 打印生成的提示
print("=== 生成的提示 ===")
print(few_shot_prompt_template.format(input="太棒了!"))

调用模型进行推理

from langchain_openai import ChatOpenAI

# 初始化模型
llm = ChatOpenAI(
    model="gpt-3.5-turbo",
    api_key="your-api-key"  # 替换为你的 API Key
)

# 创建完整的处理链
chain = few_shot_prompt_template | llm

# 测试不同的输入
test_inputs = [
    "太棒了,完全超出预期!",
    "有点失望,不太满意",
    "明天有会议",
    "这部电影是近年来最好的",
    "服务态度太差了,我要投诉"
]

print("\n=== 运行结果 ===")
for test_input in test_inputs:
    result = chain.invoke({"input": test_input})
    print(f"输入: {test_input}")
    print(f"情感: {result.content}")
    print("-" * 40)

运行结果

运行上述代码后,我们得到了以下结果:

=== 运行结果 ===
输入: 太棒了,完全超出预期!
情感: 正面
----------------------------------------
输入: 有点失望,不太满意
情感: 负面
----------------------------------------
输入: 明天有会议
情感: 中性
----------------------------------------
输入: 这部电影是近年来最好的
情感: 正面
----------------------------------------
输入: 服务态度太差了,我要投诉
情感: 负面
----------------------------------------

可以看到,Few-Shot Learning 展现出了强大的能力。模型不仅能正确识别明显带有情感倾向的文本(如「太棒了」、「太差了」),还能处理一些较为隐晦的表达(如「不太满意」、「近年来最好的」)。

进阶技巧

1. 动态示例选择

固定示例并不总是最优选择。LangChain 提供了基于语义相似度的示例选择器,可以根据输入自动选择最相关的示例:

from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings

# 扩展示例库
examples_extended = [
    {"input": "今天天气真好", "sentiment": "正面"},
    {"input": "太喜欢这个了", "sentiment": "正面"},
    {"input": "非常满意", "sentiment": "正面"},
    {"input": "产品太差了", "sentiment": "负面"},
    {"input": "非常失望", "sentiment": "负面"},
    {"input": "不推荐购买", "sentiment": "负面"},
    {"input": "今天吃了饭", "sentiment": "中性"},
    {"input": "明天有会议", "sentiment": "中性"},
    {"input": "这是什么意思", "sentiment": "中性"},
    # 添加复杂案例
    {"input": "这个产品好是好,就是太贵了", "sentiment": "中性"},  # 转折句
    {"input": "简直无语了", "sentiment": "负面"},  # 网络用语
]

# 基于语义相似度选择示例
example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples_extended,
    OpenAIEmbeddings(),
    Chroma,
    k=3  # 选择最相似的3个示例
)

2. 示例格式规范化

为了让模型输出更稳定,我们可以在示例中明确指定输出格式:

# 更规范的示例格式
examples_formatted = [
    {
        "input": "今天天气真好",
        "sentiment": "正面",
        "reason": "包含积极的表达词汇"
    },
    {
        "input": "这个产品太差了",
        "sentiment": "负面",
        "reason": "包含消极的评价词汇"
    }
]

example_prompt_formatted = PromptTemplate(
    input_variables=["input", "sentiment", "reason"],
    template="文本: {input}\n情感: {sentiment}\n原因: {reason}"
)

3. 思维链提示

对于需要推理的任务,可以在示例中加入推理过程:

# 思维链示例
cot_examples = [
    {
        "input": "我有3个苹果,妈妈又给了2个,我吃了1个,还剩几个?",
        "reasoning": "3 + 2 = 5,5 - 1 = 4",
        "answer": "4个"
    },
    {
        "input": "小明有10本书,借给小红3本,又买了5本,现在有多少本?",
        "reasoning": "10 - 3 = 7,7 + 5 = 12",
        "answer": "12本"
    }
]

cot_prompt = PromptTemplate(
    input_variables=["input", "reasoning", "answer"],
    template="问题: {input}\n思考过程: {reasoning}\n答案: {answer}"
)

总结

Few-Shot Learning 是 Prompt Engineering 中最强大的技术之一,它通过在提示中提供少量示例,让模型能够快速理解任务需求并给出准确的回答。本文通过 LangChain 的完整代码示例,展示了如何构建企业级的少样本学习提示系统。

关键要点总结:

  • Few-Shot Learning 的核心优势:无需微调,快速适配新任务,效果显著
  • 示例选择很重要:使用语义相似度选择器可以显著提升效果
  • 格式规范化:明确的输入输出格式可以让模型输出更稳定
  • 思维链提示:对于复杂推理任务,在示例中加入推理过程可以提升准确率

通过合理运用 Few-Shot Learning 技术,我们可以充分发挥大语言模型的潜力,在各种实际应用场景中取得出色的效果。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇