LangChain 提示模板之少样本示例(一)
https://python.langchain.com.cn/docs/modules/model_io/prompts/prompt_templates/few_shot_examples
一、先懂原文核心:什么是“少样本示例(Few-Shot Examples)”?
原文开篇就解释了:
少样本示例就是“在给LLM的提示里,先加几个‘正确的输入→输出’例子”,让LLM照着例子的格式/逻辑来回答。
比如你想让LLM把“句子拆成单词”,直接说“拆单词”它可能乱拆,但先给它例子:
- 输入:“Hello world” → 输出:“Hello, world”
- 输入:“LangChain is cool” → 输出:“LangChain, is, cool”
 LLM看了例子就知道“要按逗号分隔单词”——这就是少样本示例的作用,原文说它能“让LLM输出更符合预期的结果”。
二、原文第一步:手动写少样本提示(最基础的方式)
原文先讲“不用LangChain模板,自己手动拼带例子的提示”,核心是“把例子当文本,和问题一起传给LLM”。
原文完整案例(代码+解释)
比如想让LLM“给动物起英文名”,先加2个例子,再提问题:
# 原文代码:手动拼接带少样本示例的提示
from langchain.llms import OpenAI# 1. 初始化LLM(原文用的OpenAI模型)
llm = OpenAI(model_name="text-davinci-003", temperature=0)# 2. 手动写提示:先加2个“输入→输出”例子,再提当前问题
prompt = """
给下面的动物起一个简短的英文名,格式是“动物:英文名”。
例子:
动物:猫 → 英文名:Cat
动物:狗 → 英文名:Dog现在请给以下动物起名:
动物:熊猫 → 英文名:
"""# 3. 调用LLM生成结果
print(llm(prompt))
原文预期输出
Panda
原文关键说明
- 手动方式的优点:简单直接,不用学新模板;
- 缺点:如果例子多、要改格式(比如加“中文名”),得手动删改提示文本,很麻烦——这也是后面要学“少样本模板”的原因。
三、原文核心:用 LangChain 的“少样本提示模板”(解决手动的麻烦)
原文重点讲了2个LangChain模板,专门用来管理少样本示例,不用手动拼提示——分别对应“纯文本提示”和“聊天提示”。
1. 第一个模板:FewShotPromptTemplate(纯文本少样本模板)
原文说它的作用是“把‘例子列表’和‘提示模板’分开管理”,改例子或格式时不用动整体提示。
原文完整流程(4步,代码对应原文)
步骤1:准备“少样本示例列表”(原文示例)
先把所有例子写成“字典列表”,每个字典是一个“输入→输出”对:
# 原文代码:少样本示例列表(给动物起名的例子)
examples = [{"动物": "猫", "英文名": "Cat"},{"动物": "狗", "英文名": "Dog"},{"动物": "鸟", "英文名": "Bird"}
]
步骤2:定义“单个例子的模板”(原文叫 example_prompt)
告诉模板“每个例子要怎么显示”(比如“动物:X → 英文名:Y”):
# 原文代码:单个例子的模板(用PromptTemplate定义格式)
from langchain.prompts import PromptTemplateexample_prompt = PromptTemplate(input_variables=["动物", "英文名"],  # 对应例子字典里的keytemplate="动物:{动物} → 英文名:{英文名}\n"  # 单个例子的显示格式
)
- 原文说明:这个模板会把每个例子字典(比如{“动物”:“猫”,“英文名”:“Cat”})转成“动物:猫 → 英文名:Cat”的文本。
步骤3:创建“少样本提示模板”(核心,原文代码)
把“例子列表”“单个例子模板”和“最终问题模板”拼起来:
# 原文代码:创建FewShotPromptTemplate
from langchain.prompts import FewShotPromptTemplatefew_shot_prompt = FewShotPromptTemplate(examples=examples,  # 步骤1准备的例子列表example_prompt=example_prompt,  # 步骤2定义的单个例子模板suffix="现在请给以下动物起名:\n动物:{新动物} → 英文名:",  # 最终要问的问题(原文叫suffix)input_variables=["新动物"]  # 问题里的占位符(要用户传的参数)
)
- 原文关键参数解释:
- suffix:就是“例子之后的问题”,对应手动提示里“例子结束后要问的内容”;
- input_variables:用户需要传的参数(这里是“新动物”,比如“熊猫”)。
 
步骤4:使用模板+调用LLM(原文代码)
# 1. 生成完整提示(把例子和问题拼起来)
final_prompt = few_shot_prompt.format(新动物="熊猫")
print(final_prompt)  # 先看生成的提示长什么样# 2. 调用LLM
print(llm(final_prompt))
原文预期输出(分两步)
第一步打印完整提示(能看到例子自动拼好了):
动物:猫 → 英文名:Cat
动物:狗 → 英文名:Dog
动物:鸟 → 英文名:Bird现在请给以下动物起名:
动物:熊猫 → 英文名:
第二步打印LLM结果:
Panda
原文优势说明
- 改例子:直接改examples列表(比如加“动物:猪 → 英文名:Pig”),不用动模板;
- 改格式:改example_prompt的template(比如改成“动物{动物}的英文名是{英文名}”),所有例子会自动变格式。
2. 第二个模板:FewShotChatMessagePromptTemplate(聊天少样本模板)
原文说这个模板是“给聊天模型用的”——比如GPT-3.5/4,因为聊天模型需要“分角色”(系统消息、用户消息、助手消息),例子也要按角色来写。
原文完整流程(4步,代码对应原文)
步骤1:准备“聊天格式的少样本示例”(原文示例)
每个例子是“用户消息→助手消息”的对(符合聊天模型的输入习惯):
# 原文代码:聊天格式的例子列表(给电影推荐的例子)
from langchain.schema import HumanMessage, AIMessageexamples = [# 第一个例子:用户说喜欢A电影→助手推荐类似电影[HumanMessage(content="我喜欢《盗梦空间》,推荐类似的电影"),AIMessage(content="推荐《星际穿越》《黑客帝国》《蝴蝶效应》")],# 第二个例子:用户说喜欢B电影→助手推荐类似电影[HumanMessage(content="我喜欢《泰坦尼克号》,推荐类似的电影"),AIMessage(content="推荐《罗马假日》《傲慢与偏见》《乱世佳人》")]
]
- 原文说明:每个例子是“[用户消息, 助手消息]”的列表,对应一次“用户问→助手答”的对话。
步骤2:定义“聊天例子的模板”(原文叫 example_prompt)
告诉模板“聊天例子要怎么组合”(这里直接用例子本身的格式,不用额外改):
# 原文代码:聊天例子的模板
from langchain.prompts import FewShotChatMessagePromptTemplateexample_prompt = FewShotChatMessagePromptTemplate(example_messages=examples  # 直接传入聊天格式的例子列表
)
步骤3:创建“聊天少样本提示模板”(核心,原文代码)
把“聊天例子”和“系统消息、最终用户消息”组合起来:
# 原文代码:创建完整的聊天提示模板
from langchain.prompts import ChatPromptTemplate# 1. 先定义系统消息(告诉LLM角色,原文叫system prompt)
system_prompt = "你是电影推荐专家,根据用户喜欢的电影,推荐3部类似的电影。"# 2. 组合成聊天模板:系统消息 + 例子 + 最终用户消息
chat_prompt = ChatPromptTemplate.from_messages([("system", system_prompt),  # 第一步:系统消息example_prompt,             # 第二步:少样本例子(自动拼进去)("human", "我喜欢《肖申克的救赎》,推荐类似的电影")  # 第三步:用户当前的问题
])
步骤4:使用模板+调用聊天LLM(原文代码)
# 1. 初始化聊天模型(原文用ChatOpenAI)
from langchain.chat_models import ChatOpenAI
chat_llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)# 2. 生成完整聊天提示(转成模型能识别的消息列表)
final_messages = chat_prompt.format_messages()
# 打印看格式(原文没打印,但加了更易理解)
for msg in final_messages:print(f"角色:{msg.type},内容:{msg.content}")# 3. 调用聊天模型
print(chat_llm(final_messages).content)
原文预期输出(分两步)
第一步打印完整聊天提示(分角色,符合聊天模型要求):
角色:system,内容:你是电影推荐专家,根据用户喜欢的电影,推荐3部类似的电影。
角色:human,内容:我喜欢《盗梦空间》,推荐类似的电影
角色:ai,内容:推荐《星际穿越》《黑客帝国》《蝴蝶效应》
角色:human,内容:我喜欢《泰坦尼克号》,推荐类似的电影
角色:ai,内容:推荐《罗马假日》《傲慢与偏见》《乱世佳人》
角色:human,内容:我喜欢《肖申克的救赎》,推荐类似的电影
第二步打印LLM结果:
推荐《阿甘正传》《当幸福来敲门》《楚门的世界》
原文优势说明
- 符合聊天模型习惯:不用手动拼“角色标签”,模板自动按“system→例子→human”的顺序组合;
- 例子可复用:同一个example_prompt能给不同的用户问题用(比如换“我喜欢《复仇者联盟》”,例子不用改)。
四、原文补充:动态选择少样本示例(Optional: Dynamic Few-Shot Prompting)
原文最后讲了个进阶功能:不是每次都用所有例子,而是“根据用户的问题,选和问题最像的几个例子”——比如用户问“给科幻电影推荐”,就只选“科幻相关的例子”,减少提示长度。
原文核心逻辑(代码对应原文)
比如用“相似度匹配”选例子:
# 原文代码:动态选择例子(以电影推荐为例)
from langchain.prompts import FewShotChatMessagePromptTemplate, ChatPromptTemplate
from langchain.llms import OpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS# 1. 准备更多例子(有科幻、爱情、动画等类型)
examples = [[HumanMessage(content="喜欢《盗梦空间》(科幻)"), AIMessage(content="推《星际穿越》")],[HumanMessage(content="喜欢《泰坦尼克号》(爱情)"), AIMessage(content="推《罗马假日》")],[HumanMessage(content="喜欢《寻梦环游记》(动画)"), AIMessage(content="推《飞屋环游记》")]
]# 2. 把例子转成文本,用embedding(嵌入)计算相似度
example_texts = [str(example) for example in examples]  # 例子转字符串
embeddings = OpenAIEmbeddings()  # 用OpenAI的embedding模型
vectorstore = FAISS.from_texts(example_texts, embeddings)  # 把例子存成“向量库”# 3. 定义“选例子的函数”:根据用户问题,找最像的1个例子
def select_examples(user_query):similar_examples = vectorstore.similarity_search(user_query, k=1)  # 找Top1相似例子similar_examples = [eval(example.page_content) for example in similar_examples]  # 转成原格式return similar_examples# 4. 动态创建例子模板(每次调用时选例子)
def create_prompt(user_query):selected_examples = select_examples(user_query)example_prompt = FewShotChatMessagePromptTemplate(example_messages=selected_examples)# 组合聊天模板prompt = ChatPromptTemplate.from_messages([("system", "你是电影推荐专家"),example_prompt,("human", user_query)])return prompt# 5. 使用:用户问科幻相关问题,只选科幻例子
user_query = "我喜欢《流浪地球》(科幻),推荐类似的"
prompt = create_prompt(user_query)
final_messages = prompt.format_messages()# 6. 调用LLM
chat_llm = ChatOpenAI()
print(chat_llm(final_messages).content)
原文预期结果
- 因为用户问的是科幻电影,模板会自动选“《盗梦空间》的例子”,只把这个例子放进提示;
- LLM会根据科幻例子的逻辑,推荐《星际穿越》《火星救援》等科幻电影。
原文关键说明
- 核心工具:用FAISS(向量数据库)存例子的“embedding”,用similarity_search找和用户问题最像的例子;
- 优势:减少提示长度(不用带所有例子),让LLM更聚焦于“相关例子”,推荐更准。
五、原文核心总结(3句话说清)
- 少样本示例是什么:给提示加“输入→输出”例子,让LLM照例子输出,原文说这能“提升输出准确性”;
- LangChain怎么实现:用FewShotPromptTemplate(纯文本)和FewShotChatMessagePromptTemplate(聊天)管理例子,不用手动拼提示;
- 进阶功能:动态选例子(比如按相似度),只带相关例子,减少提示长度。
