PaperAgent 2024年07月18日
LangChain中的Prompt模板搭建|Prompt工程Few-Shot优化方案
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了在LangChain中应用和封装提示模板的方法,包括PromptTemplate、ChatPromptTemplate和MessagesPlaceholder三种类型的提示模板,以及如何使用FewShotPromptTemplate添加few-shot示例,以及如何使用SemanticSimilarityExampleSelector选择与输入问题最相似的示例作为few-shot示例。

🤔 **PromptTemplate**:该模板的输出为一个字符串,也可以转换为字符串或消息列表。此方法的存在是为了便于在字符串和消息之间切换。 例如:`prompt_template = PromptTemplate.from_template("回答下面问题:{question}")`,其中`question`是一个变量,可以被用户传入的实际问题替换,最终输出一个包含问题的字符串。

💬 **ChatPromptTemplate**:该模板用于格式化消息列表,由模板本身的列表组成。 例如:`chat_prompt_template = ChatPromptTemplate.from_messages([("system", "You are a helpful assistant"), ("user", "回答下面问题:{question}")])`,其中`question`是一个变量,可以被用户传入的实际问题替换,最终输出一个包含系统消息和用户消息的列表。

📥 **MessagesPlaceholder**:该模板负责在特定位置添加消息列表。 例如:`chat_prompt_template = ChatPromptTemplate.from_messages([("system", "You are a helpful assistant"), MessagesPlaceholder("msgs")])`,其中`msgs`是一个变量,可以被用户传入的消息列表替换,最终输出一个包含系统消息和用户消息的列表。

💡 **FewShotPromptTemplate**:该模板用于在Prompt中添加few-shot示例,以提升模型的表现。 例如:`prompt = FewShotPromptTemplate(examples=examples, example_prompt=example_prompt, suffix="Question: {input} Answer: ", input_variables=["input"])`,其中`examples`是一个示例列表,`example_prompt`是一个用于格式化示例的模板,`input`是一个变量,可以被用户传入的实际问题替换,最终输出一个包含few-shot示例和问题的字符串。

🎯 **SemanticSimilarityExampleSelector**:该模板用于选择与输入问题最相似的示例作为few-shot示例。 例如:`example_selector = SemanticSimilarityExampleSelector.from_examples(examples, OpenAIEmbeddings(), Chroma, k=1)`,其中`examples`是一个示例列表,`OpenAIEmbeddings()`是一个向量模型,`Chroma`是一个向量数据库,`k`表示要检索的示例数量,最终输出一个与输入问题最相似的示例。

🚀 **应用场景**:提示模板可以应用于各种任务,例如问答、文本摘要、代码生成等。通过合理地设计提示模板,可以提高模型的理解能力和生成能力。

🧠 **提示模板设计技巧**: * 尽量使用清晰简洁的语言,避免使用过于复杂的语法。 * 针对不同的任务,选择合适的提示模板类型。 * 使用few-shot示例可以提高模型的表现。 * 使用SemanticSimilarityExampleSelector选择与输入问题最相似的示例作为few-shot示例。

🔮 **未来展望**:随着大模型技术的不断发展,提示模板的设计也将变得更加重要。未来,我们可以期待更多更强大的提示模板,以及更智能的提示模板设计工具。

🚀 **总结**:本文介绍了LangChain中提示模板的应用和封装,并提供了一些提示模板设计技巧。希望本文能帮助您更好地理解和应用提示模板,提升大模型的使用效率。

🚀 **推荐**: * RAG:Langchain中使用自己的LLM大模型 * RAG:在LangChain中使用本地向量embedding模型 * 大模型Prompt提示优化(3)| GLM中的结构化prompt

🚀 **问题**: * 如何选择合适的提示模板类型? * 如何设计高效的few-shot示例? * 如何使用SemanticSimilarityExampleSelector选择与输入问题最相似的示例作为few-shot示例?

🚀 **未来方向**: * 研究更强大的提示模板设计方法。 * 开发更智能的提示模板设计工具。

🚀 **个人观点**: * 提示模板是提高大模型使用效率的关键。 * 随着大模型技术的不断发展,提示模板的设计将变得更加重要。

🚀 **结论**: * 提示模板可以有效地提高大模型的理解能力和生成能力。 * 在使用LangChain时,应合理地选择和设计提示模板。

🚀 **建议**: * 关注大模型技术的发展趋势。 * 积极探索和尝试新的提示模板设计方法。

哎呀AIYA 2024-07-18 16:55 湖北

最近几篇文章介绍了Prompt的基本原则和不同任务的推荐Prompt模板,在实际的应用中比较有用,本

    最近几篇文章介绍了Prompt的基本原则和不同任务的推荐Prompt模板,在实际的应用中比较有用,本篇文章将介绍,在LangChain中怎么应用和封装模板。


提示模板的类型

    提示模板有助于将用户输入和参数转换为语言模型的指令。用于指导模型的响应,帮助其理解上下文并生成相关且连贯的基于语言的输出。

    一般提示模板以字典作为输入,其中每个key代表提示模板中要填写的变量。下面介绍两种提示模板:

from langchain_core.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template("回答下面问题:{question}")
pt = prompt_template.invoke({"question""今天是几号?"})print(pt.to_string())
# result# '回答下面问题:今天是几号?'

    这个提示模板用于格式化消息列表,由模板本身的列表组成。构建和使用 ChatPromptTemplate 的常见方法如下:

from langchain_core.prompts import ChatPromptTemplate
chat_prompt_template = ChatPromptTemplate.from_messages([ ("system", "You are a helpful assistant"), ("user", "回答下面问题:{question}")])
cpt = chat_prompt_template.invoke({"question": "今天是几号?"})print(cpt.to_messages())
# result# [SystemMessage(content='You are a helpful assistant'), HumanMessage(content='回答下面问题:今天是几号?')]

    在上面的例子中,这个 ChatPromptTemplate 在调用时会构造两个消息。第一个是系统消息,没有要格式化的变量。第二个是 HumanMessage,将由用户传入的question替代。结果在上面代码最后已展示。

    此提示模板负责在特定位置添加消息列表。在上面的 ChatPromptTemplate 中,我们看到了如何格式化两条消息,每条消息都是一个字符串。如果我们希望将用户传过来的消息插入到消息列表的特定位置,该怎么办?这可以用 MessagesPlaceholder 来实现:

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholderfrom langchain_core.messages import HumanMessage
chat_prompt_template = ChatPromptTemplate.from_messages([ ("system", "You are a helpful assistant"), MessagesPlaceholder("msgs") # ("placeholder", "{msgs}")])
print(chat_prompt_template.invoke({"msgs": pt.to_messages()}))
# result# messages=[SystemMessage(content='You are a helpful assistant'), HumanMessage(content='回答下面问题:今天是几号?')]

例子的结果可以看出,把上面PromptTemplate生成的消息也传进去了,这在消息传输中非常有用,以后构建ChatBot会用到。当然MessagesPlaceholder也可以不显示表示,使用("placeholder","{msgs}")占位。

PromptTemplate中Few-Shot

    在prompt中添加few-shot是提升模型的表现的有效方法,如何添加、怎么有效添加是文章后面要将的重点,先看代码:

from langchain_core.prompts import PromptTemplate
example_prompt = PromptTemplate.from_template("Question: {question}\nAnswer: {answer}")

下面给出few-shot的候选集:

examples = [    {"question": "这组数中的奇数加起来是偶数:4、8、9、15、12、2、1。",     "answer": "将所有奇数相加(9、15、1)得到25。答案为False。"},    {"question": "这组数中的奇数加起来是偶数:17、10、19、4、8、12、24。",     "answer": "将所有奇数相加(17、19)得到36。答案为True。"},    {"question": "这组数中的奇数加起来是偶数:16、11、14、4、8、13、24。",     "answer": "将所有奇数相加(11、13)得到24。答案为True。"},    {"question": "这组数中的奇数加起来是偶数:17、9、10、12、13、4、2。",     "answer""将所有奇数相加(17、9、13)得到39。答案为False。"},    {"question""中国首都是哪里?",     "answer": "北京"}]
print(example_prompt.invoke(examples[0]).to_string())
# resultQuestion: 这组数中的奇数加起来是偶数:4、8、9、15、12、2、1。Answer: 将所有奇数相加(9、15、1)得到25。答案为False

上面打印出了第一个样例放入prompt后的输出。后面展示使用FewShotPromptTemplate方法拼接完整few-shot到模板中:

from langchain_core.prompts import FewShotPromptTemplate
prompt = FewShotPromptTemplate( examples=examples, example_prompt=example_prompt,    suffix="Question: {input}\nAnswer: ", input_variables=["input"],)
print( prompt.invoke({"input": "这组数中的奇数加起来是偶数:15、32、5、13、82、7、1。"}).to_string())

结果如下:

Question: 这组数中的奇数加起来是偶数:4、8、9、15、12、2、1。Answer: 将所有奇数相加(9、15、1)得到25。答案为False。Question: 这组数中的奇数加起来是偶数:17、10、19、4、8、12、24。Answer: 将所有奇数相加(17、19)得到36。答案为True。Question: 这组数中的奇数加起来是偶数:16、11、14、4、8、13、24。Answer: 将所有奇数相加(11、13)得到24。答案为True。Question: 这组数中的奇数加起来是偶数:17、9、10、12、13、4、2。Answer: 将所有奇数相加(17、9、13)得到39。答案为False。Question: 中国首都是哪里?Answer: 北京Question: 这组数中的奇数加起来是偶数:15、32、5、13、82、7、1。Answer:

    这样我们就把提供的例子都按格式拼接到Prompt中了;可以看出上面答案都用到了思维链的方式(Chain-of-Thought Prompting)这也是有用的prompt优化方案,目前大模型微调数据都采用了此方法。

添加更好的few-shot

    上面的例子中,我们可以看到,“中国的首都是哪里?”这个问题完全没有必要出现在示例中,选择一个意思和结构相近的示例放入few-shot中往往会事半功倍,我们该怎么实现呢?在LangChain中有一个方法能帮我们实现这个功能“SemanticSimilarityExampleSelector”,下面会用到向量模型(没有api-key可以看这篇文章RAG:在LangChain中使用本地向量embedding模型)和向量数据库。

from langchain_chroma import Chromafrom langchain_core.example_selectors import SemanticSimilarityExampleSelectorfrom langchain_openai import OpenAIEmbeddings
example_selector = SemanticSimilarityExampleSelector.from_examples( # 候选示例集. examples, # 向量模型,用于计算相似度. OpenAIEmbeddings(), # 向量数据库,用于储存向量和检索. Chroma, # 检索k个示例. k=1,)
# Select the most similar example to the input.question = "这组数中的奇数加起来是偶数:15、32、5、13、82、7、1。"selected_examples = example_selector.select_examples({"question": question})print(f"Examples most similar to the input: {question}")for example in selected_examples: print("\n") for k, v in example.items(): print(f"{k}: {v}")
Examples most similar to the input: 这组数中的奇数加起来是偶数:15、32、5、13、82、7、1。

answer: 将所有奇数相加(11、13)得到24。答案为True。
question: 这组数中的奇数加起来是偶数:16、11、14、4、8、13、24。

    下面我来构建FewShotPrompt,prefix可以输入问题的描述,suffix可以输入问题的前缀(上篇文章有介绍,挺重要的。大模型Prompt提示设计简介(2):有效的建议

prompt = FewShotPromptTemplate(    example_selector=example_selector,    example_prompt=example_prompt,    suffix="\n待判断问题:\nQuestion: {input}\nAnswer: ",    prefix="判断下面句子的对错,按下面例子的格式进行输出:\n例子:",    input_variables=["input"],)
print( prompt.invoke({"input": "这组数中的奇数加起来是偶数:15、32、5、13、82、7、1。"}).to_string())
判断下面句子的对错,按下面例子的格式进行输出:例子:Question: 这组数中的奇数加起来是偶数:16、11、14、4、8、13、24。Answer: 将所有奇数相加(11、13)得到24。答案为True。
待判断问题:Question: 这组数中的奇数加起来是偶数:15、32、5、13、82、7、1。Answer:

    这样我们很好的召回了相似的示例作为上下文,这样可以准确的约束模型进行推理,也能对输出的格式进行约束。


如果对内容有什么疑问和建议可以私信和留言,也可以添加我加入大模型交流群,一起讨论大模型在创作、RAG和agent中的应用。


好了,这就是我今天想分享的内容。如果你对大模型应用感兴趣,别忘了点赞、关注噢~



往期推荐



RAG:Langchain中使用自己的LLM大模型

RAG:在LangChain中使用本地向量embedding模型

大模型Prompt提示优化(3)| GLM中的结构化prompt

  一文读懂token到底是什么鬼,消耗那么多钱?



Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

LangChain 提示模板 PromptTemplate ChatPromptTemplate MessagesPlaceholder FewShotPromptTemplate SemanticSimilarityExampleSelector 大模型 应用 封装
相关文章