赞
踩
在大模型工程中,“Prompt”(提示)扮演着核心角色,它是与大型语言模型交互时使用的输入文本,旨在引导模型产生预期的响应或执行特定任务。Prompt 不仅是与大模型沟通的桥梁,也是发挥大模型效能的关键工具,其设计和优化是大模型工程实践中不可或缺的一环。
Prompt 是一种精心设计的输入信息,可以是问题、指令、描述、场景设定或是对话历史的一部分,其主要目标是清晰、精确地传达用户的意图,使得模型能够据此生成满足需求的高质量输出。
指令或问题:直接告诉模型你需要什么,比如询问一个问题或下达一个生成命令。
上下文:提供必要的背景信息,帮助模型理解请求的环境或前因后果,这对于连贯性和准确性至关重要。
输入参数:具体的数据或细节,模型可能需要这些来生成更加具体和个性化的输出。
示例:在某些情况下,给出一个或几个示例可以显著提升模型理解任务要求的能力,尤其是在需要特定格式或风格的输出时。
质量的重要性:Prompt 的质量直接影响模型输出的品质。一个清晰、具体、富含上下文的 Prompt 往往能引导模型产生更加精准、相关性强的回答。反之,模糊或不完整的 Prompt 可能导致模型输出偏离用户期望。
设计策略:设计 Prompt 时,需要考虑如何最有效地表达意图,这可能涉及使用特定的引导语、格式化输入、逐步细化问题或利用领域特定语言等技巧。
在大模型的各种应用场景中,如自动问答、文本生成、代码编写、创意设计等,Prompt 工程成为了确保模型高效、准确服务的基础。通过不断优化 Prompt,可以最大化大模型的潜力,实现更复杂的任务处理和更人性化的交互体验。
LangChain 提供了创建和使用 Prompt 的工具。LangChain 致力于创建与模型无关的模板,以便于在不同的语言模型中重用现有模板。通常情况下,语言模型的最佳Prompt 是字符串或聊天消息列表。
我们可以使用 PromptTemplate 为字符串提示创建模板。默认情况下,PromptTemplate 使用 Python 的 str.format 语法进行模板化。
python
复制代码
from langchain_core.prompts import PromptTemplate, AIMessagePromptTemplate
prompt_template = PromptTemplate.from_template(
"请讲一个关于{who}的{what}故事"
)
prompt_template.format(who="小狗", what="伤感")
# 输出如下:
# 请讲一个关于小狗的伤感故事
我们也可以不传任何变量
python
复制代码
from langchain_core.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template("给我讲一个笑话")
prompt_template.format()
# 输出
# 给我讲一个笑话
Chat Model 的 Prompt 是聊天消息列表。每条聊天消息都有 content 和一个名为 role 的附加参数相关联。例如,在 OpenAI 的chat completion API 中,聊天消息可以是 AI assistant、human 或者 system role。
python 复制代码 from langchain_core.prompts import ChatPromptTemplate chat_template = ChatPromptTemplate.from_messages( [ ("system", "You are a helpful AI bot. Your name is {name}."), ("human", "Hello, how are you doing?"), ("ai", "I'm doing well, thanks!"), ("human", "{user_input}"), ] ) messages = chat_template.format_messages(name="Bob", user_input="What is your name?") # [SystemMessage(content='You are a helpful AI bot. Your name is Bob.'), # HumanMessage(content='Hello, how are you doing?'), # AIMessage(content="I'm doing well, thanks!"), # HumanMessage(content='What is your name?')]
除了使用上面使用的(type,content)的元组表示形式外,还可以传入 MessagePromptTemplate 或 BaseMessage 的实例。
python 复制代码 from langchain_core.messages import SystemMessage from langchain_core.prompts import HumanMessagePromptTemplate from langchain_core.prompts import AIMessagePromptTemplate chat_template = ChatPromptTemplate.from_messages( [ SystemMessage( content=( "你是一个复述助手,擅长重复用户的输入。" ) ), HumanMessagePromptTemplate.from_template("我好喜欢你。"), AIMessagePromptTemplate.from_template("我好喜欢你。"), HumanMessagePromptTemplate.from_template("{text}"), ] ) messages = chat_template.format_messages(text="我不喜欢你。") # [SystemMessage(content='你是一个复述助手,擅长重复用户的输入。'), # HumanMessage(content='我好喜欢你。'), # AIMessage(content='我好喜欢你。'), # HumanMessage(content='我不喜欢你。')]
LangChain提供了不同类型的MessagePromptTemplate。最常用的是AIMessagePromptTemplate、SystemMessagePromptTemplate 和 HumanMessagePromptTemplate,它们分别创建 AI 消息、系统消息和用户消息。
如果聊天模型支持使用任意角色接收聊天消息,则可以使用 ChatMessagePromptTemplate,允许用户指定角色名称。
python
复制代码
from langchain_core.prompts import ChatMessagePromptTemplate
prompt = "May the {subject} be with you"
chat_message_prompt = ChatMessagePromptTemplate.from_template(
role="Jedi", template=prompt
)
chat_message_prompt.format(subject="force")
# ChatMessage(content='May the force be with you', role='Jedi')
LangChain 还提供了 MessagesPlaceholder,它可以完全控制在格式化过程中要呈现的消息。当我们不确定应为消息提示模板使用什么角色时,或者希望在格式化过程中插入消息列表时,就需要用到这个。
python 复制代码 from langchain_core.prompts import ( ChatPromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder, ) human_prompt = "Summarize our conversation so far in {word_count} words." human_message_template = HumanMessagePromptTemplate.from_template(human_prompt) chat_prompt = ChatPromptTemplate.from_messages( [MessagesPlaceholder(variable_name="conversation"), human_message_template] ) """ ChatPromptTemplate(input_variables=['conversation', 'word_count'], input_types={'conversation': typing.List[typing.Union[langchain_core.messages.ai.AIMessage, langchain_core.messages.human.HumanMessage, langchain_core.messages.chat.ChatMessage, langchain_core.messages.system.SystemMessage, langchain_core.messages.function.FunctionMessage, langchain_core.messages.tool.ToolMessage]]}, messages=[MessagesPlaceholder(variable_name='conversation'), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['word_count'], template='Summarize our conversation so far in {word_count} words.'))]) """
我们可以看到,占位字符串 conversation 的类型是xxxxxMessage的集合。
python 复制代码 from langchain_core.messages import AIMessage, HumanMessage human_message = HumanMessage(content="What is the best way to learn programming?") ai_message = AIMessage( content="""\ 1. Choose a programming language: Decide on a programming language that you want to learn. 2. Start with the basics: Familiarize yourself with the basic programming concepts such as variables, data types and control structures. 3. Practice, practice, practice: The best way to learn programming is through hands-on experience\ """ ) chat_prompt.format_prompt( conversation=[human_message, ai_message], word_count="10" ).to_messages() # [HumanMessage(content='What is the best way to learn programming?'), # AIMessage(content='1. Choose a programming language: Decide on a programming language that you want to learn.\n\n2. Start with the basics: Familiarize yourself with the basic programming concepts such as variables, data types and control structures.\n\n3. Practice, practice, practice: The best way to learn programming is through hands-on experience'), # HumanMessage(content='Summarize our conversation so far in 10 words.')]
这里我们动态添加了一条 HumanMessage 和一条 AIMessage。
Few-Shot 指的是使用少量示例数据(通常只有几个或几十个)来引导模型进行特定任务的学习或预测。这种方式是针对大规模预训练模型的一种高效应用方法,因为这些模型已经通过大量的无标注文本进行了预训练,具有强大的泛化能力。
Chat Model 中的 Few-Shot 输入和输出都是 xxxxxMessage,LLM 中的 Few-Shot 输入和输出都是字符串
LangChain 提供了 FewShotChatMessagePromptTemplate来设置 Few-Shot 。FewShotChatMessagePromptTemplate的目标是根据输入动态选择示例,然后在最终提示中设置示例的格式以提供模型。
Fixed Examples:不管examples中有多少示例,都放到 Prompt 中。
python 复制代码 from langchain_core.prompts import ( ChatPromptTemplate, FewShotChatMessagePromptTemplate, ) examples = [ {"input": "2+2", "output": "4"}, {"input": "2+3", "output": "5"}, ] example_prompt = ChatPromptTemplate.from_messages( [ ("human", "{input}"), ("ai", "{output}"), ] ) few_shot_prompt = FewShotChatMessagePromptTemplate( example_prompt=example_prompt, examples=examples, ) # FewShotChatMessagePromptTemplate(examples=[{'input': '2+2', 'output': '4'}, {'input': '2+3', 'output': '5'}], example_prompt=ChatPromptTemplate(input_variables=['input', 'output'], messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')), AIMessagePromptTemplate(prompt=PromptTemplate(input_variables=['output'], template='{output}'))]))
然后,我们可以将少样本提示模板插入到最终给到模型的模板中。
python
复制代码
final_prompt = ChatPromptTemplate.from_messages(
[
("system", "You are a wondrous wizard of math."),
few_shot_prompt,
("human", "{input}"),
]
)
# ChatPromptTemplate(input_variables=['input'], messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='You are a wondrous wizard of math.')), FewShotChatMessagePromptTemplate(examples=[{'input': '2+2', 'output': '4'}, {'input': '2+3', 'output': '5'}], example_prompt=ChatPromptTemplate(input_variables=['input', 'output'], messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')), AIMessagePromptTemplate(prompt=PromptTemplate(input_variables=['output'], template='{output}'))])), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}'))])
Dynamic few-shot prompting:如果examples中有很多的输入输出示例,并且多数示例场景不相关,这个时候就需要动态选择示例。表示从一堆示例中选择几个送入模型,让模型做输出。
怎么选?模型怎么知道选择哪个示例?
这里就要提一下 ExampleSelector,LangChain 默认提供了4种不同类型的示例选择器,包括根据长度、语义相似度、最大边际相关性等进行选择。
这里只介绍示例选择器的基本用法,不做展开详解,后续会单独开一篇文章解释说明。
用SemanticSimilarityExampleSelector做示例
python 复制代码 from langchain_community.vectorstores import FAISS from langchain_community.embeddings import HuggingFaceEmbeddings import torch from langchain_core.example_selectors import SemanticSimilarityExampleSelector # 示例数据 examples = [ {"input": "你好吗?", "output": "我挺好的!"}, {"input": "你现在在哪?", "output": "我在老家。"}, {"input": "你过的怎么样?", "output": "我过的还行,不算太差。"}, {"input": "明天天气怎样?", "output": "明天要下大雨,出门记得带伞。"}, {"input": "你大学文凭吗?","output": "我小学毕业"}, ] # 词嵌入模型 EMBEDDING_DEVICE = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu" embeddings = HuggingFaceEmbeddings(model_name='D:\models\m3e-base', model_kwargs={'device': EMBEDDING_DEVICE}) example_selector = SemanticSimilarityExampleSelector.from_examples( examples=examples, # 示例数据 embeddings=embeddings, # 词嵌入模型 vectorstore_cls=FAISS, # 向量数据库 k=2 # 从示例中选择2个最相关的示例 # ... 省略其他参数 ) user_input = "你家在哪?" selected_example = example_selector.select_examples({"input": user_input}) # [{'input': '你现在在哪?', 'output': '我在老家。'}, {'input': '你好吗?', 'output': '我挺好的!'}]
将示例选择器在最终 Prompt 中使用
python 复制代码 from langchain_core.prompts import ( ChatPromptTemplate, FewShotChatMessagePromptTemplate, ) 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", "你是智能聊天助手。"), few_shot_prompt, ("human", "{input}"), ] ) final_prompt.format(input="你家在哪?") # ChatPromptTemplate(input_variables=['input'], messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='你是智能聊天助手。')), FewShotChatMessagePromptTemplate(example_selector=SemanticSimilarityExampleSelector(vectorstore=<langchain_community.vectorstores.faiss.FAISS object at 0x0000027EBFD00040>, k=2, example_keys=None, input_keys=None, vectorstore_kwargs=None), input_variables=['input'], example_prompt=ChatPromptTemplate(input_variables=['input', 'output'], messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')), AIMessagePromptTemplate(prompt=PromptTemplate(input_variables=['output'], template='{output}'))])), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}'))])
Fixed Examples:不管examples中有多少示例,都放到 Prompt 中。
python 复制代码 from langchain_core.prompts import FewShotPromptTemplate # 示例数据 examples = [ {"input": "你好吗?", "output": "我挺好的!"}, {"input": "你现在在哪?", "output": "我在老家。"}, {"input": "你过的怎么样?", "output": "我过的还行,不算太差。"}, {"input": "明天天气怎样?", "output": "明天要下大雨,出门记得带伞。"}, {"input": "你大学文凭吗?","output": "我小学毕业"}, ] example_prompt = PromptTemplate( input_variables=["input", "output"], template="Question: {input}\n{output}" ) prompt = FewShotPromptTemplate( examples=examples, example_prompt=example_prompt, suffix="Question: {input}", input_variables=["input"], ) prompt.format(input="你家在哪?") # 输出 # 'Question: 你好吗?\n我挺好的!\n\nQuestion: 你现在在哪?\n我在老家。\n\nQuestion: 你过的怎么样?\n我过的还行,不算太差。\n\nQuestion: 明天天气怎样?\n明天要下大雨,出门记得带伞。\n\nQuestion: 你大学文凭吗?\n我小学毕业\n\nQuestion: 你家在哪?'
Dynamic few-shot prompting:如果examples中有很多的输入输出示例,并且多数示例场景不相关,这个时候就需要动态选择示例。表示从一堆示例中选择几个送入模型,让模型做输出。
python 复制代码 from langchain_community.vectorstores import FAISS from langchain_community.embeddings import HuggingFaceEmbeddings import torch from langchain_core.example_selectors import SemanticSimilarityExampleSelector # 示例数据 examples = [ {"input": "你好吗?", "output": "我挺好的!"}, {"input": "你现在在哪?", "output": "我在老家。"}, {"input": "你过的怎么样?", "output": "我过的还行,不算太差。"}, {"input": "明天天气怎样?", "output": "明天要下大雨,出门记得带伞。"}, {"input": "你大学文凭吗?","output": "我小学毕业"}, ] # 词嵌入模型 EMBEDDING_DEVICE = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu" embeddings = HuggingFaceEmbeddings(model_name='D:\models\m3e-base', model_kwargs={'device': EMBEDDING_DEVICE}) example_selector = SemanticSimilarityExampleSelector.from_examples( examples=examples, # 示例数据 embeddings=embeddings, # 词嵌入模型 vectorstore_cls=FAISS, # 向量数据库 k=2 # 从示例中选择2个最相关的示例 # ... 省略其他参数 ) prompt = FewShotPromptTemplate( example_selector=example_selector, example_prompt=example_prompt, suffix="Question: {input}", input_variables=["input"], ) # 输出PromptTemplate对象 print(prompt) """ input_variables=['input'] example_selector=SemanticSimilarityExampleSelector(vectorstore=<langchain_community.vectorstores.faiss.FAISS object at 0x0000027EBFE1C760>, k=2, example_keys=None, input_keys=None, vectorstore_kwargs=None) example_prompt=PromptTemplate(input_variables=['input', 'output'], template='Question: {input}\n{output}') suffix='Question: {input}' """ # 这里print后会把\n,\n\n换成空格 print(prompt.format(input="你家在哪?")) """ Question: 你现在在哪? 我在老家。 Question: 你好吗? 我挺好的! Question: 你家在哪? """
部分提示模板。通俗点说就是,一个 Prompt 中有多个占位变量需要设置,但是由于变量的替换值的获取不是同步的,我们一开始可能只能设置其中一个。这个时候就有两种处理方式:1. 等所有值都获取到了,一起设置;2. 先设置已经拿到的,后面的等获取到了在设置。
这就是 Partial Prompt,希望我解释的够通俗。
使用字符串进行部分占位值的设置
python 复制代码 from langchain_core.prompts import PromptTemplate prompt = PromptTemplate.from_template("{foo}{bar}") partial_prompt = prompt.partial(foo="foo") print(partial_prompt.format(bar="baz")) # 输出 # foobaz # 或者 prompt = PromptTemplate( template="{foo}{bar}", input_variables=["bar"], partial_variables={"foo": "foo"} ) print(prompt.format(bar="baz")) # 输出 # foobaz
使用函数进行部分占位值的设置
python 复制代码 from datetime import datetime def _get_datetime(): now = datetime.now() return now.strftime("%m/%d/%Y, %H:%M:%S") prompt = PromptTemplate( template="Tell me a {adjective} joke about the day {date}", input_variables=["adjective", "date"], ) partial_prompt = prompt.partial(date=_get_datetime) print(partial_prompt.format(adjective="funny")) # 输出 # Tell me a funny joke about the day 05/12/2024, 13:30:03
组合提示,目的是为了重用模板。
字符串模板组合
python 复制代码 from langchain_core.prompts import PromptTemplate prompt1 = PromptTemplate.from_template("Tell me a joke about {topic}") prompt2 = ( prompt1 + ", make it funny" + "\n\nand in {language}" ) print(prompt1) print(prompt2) # 输出 # input_variables=['topic'] template='Tell me a joke about {topic}' # input_variables=['language', 'topic'] template='Tell me a joke about {topic}, make it funny\n\nand in {language}' final_prompt = prompt2.format(topic="sports",language="spanish") print(final_prompt) # 输出 # Tell me a joke about sports, make it funny # # and in spanish
聊天模板组合
python
复制代码
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
# 原始prompt
prompt = SystemMessage(content="You are a nice pirate")
# 组合的prompt
new_prompt = (
prompt + HumanMessage(content="hi") + AIMessage(content="what?") + "{input}"
)
msg_list = new_prompt.format_messages(input="i said hi")
print(msg_list)
# 输出
# [SystemMessage(content='You are a nice pirate'), HumanMessage(content='hi'), AIMessage(content='what?'), HumanMessage(content='i said hi')]
管道模板提示,本质还是 Prompt 的组合,我们主要掌握如何使用。
python 复制代码 from langchain_core.prompts.pipeline import PipelinePromptTemplate from langchain_core.prompts.prompt import PromptTemplate # 完整模板 full_template = """{introduction} {example} {start}""" full_prompt = PromptTemplate.from_template(full_template) # 组合模板一 introduction_template = """You are impersonating {person}.""" introduction_prompt = PromptTemplate.from_template(introduction_template) # 组合模板二 example_template = """Here's an example of an interaction: Q: {example_q} A: {example_a}""" example_prompt = PromptTemplate.from_template(example_template) # 组合模板三 start_template = """Now, do this for real! Q: {input} A:""" start_prompt = PromptTemplate.from_template(start_template) # 组合模板 input_prompts = [ ("introduction", introduction_prompt), ("example", example_prompt), ("start", start_prompt), ] pipeline_prompt = PipelinePromptTemplate( final_prompt=full_prompt, pipeline_prompts=input_prompts ) # 打印需要的输入变量 print(pipeline_prompt.input_variables) # 格式化打印最终 Prompt print( pipeline_prompt.format( person="Elon Musk", example_q="What's your favorite car?", example_a="Tesla", input="What's your favorite social media site?", ) ) """ You are impersonating Elon Musk. Here's an example of an interaction: Q: What's your favorite car? A: Tesla Now, do this for real! Q: What's your favorite social media site? A: """
无论 LangChain 将 Prompt 封装的多么完美多么好,我门应该知道 Prompt 的本质就是:你在问模型问题的时候,多加一些输入,而不仅仅是问题本身。
至于这些输入怎么来的?是本地文件?是向量数据库?是网页数据?还是其他的数据来源?这些都不重要,再怎么天花乱坠,本质还是给模型多一点额外输入信息!
到这里,Prompt就基本介绍完了
作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。
但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的 AI大模型资料
包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
所有资料 ⚡️ ,朋友们如果有需要全套 《LLM大模型入门+进阶学习资源包》,扫码获取~
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/991480
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。