提示词使用模式
使用 RichPromptTemplate 和 Jinja 语法
Section titled “Using RichPromptTemplate and Jinja Syntax”通过利用Jinja语法,您可以构建包含变量、逻辑、解析对象等功能的提示模板。
让我们来看几个示例:
from llama_index.core.prompts import RichPromptTemplate
template = RichPromptTemplate( """We have provided context information below.---------------------{{ context_str }}---------------------Given this information, please answer the question: {{ query_str }}""")
# format as a stringprompt_str = template.format(context_str=..., query_str=...)
# format as a list of chat messagesmessages = template.format_messages(context_str=..., query_str=...)Jinja 模板与 f-strings 的主要区别在于变量现在使用双花括号 {{ }} 而非单花括号 { }。
让我们来看一个更复杂的示例,它使用循环生成多模态提示。
from llama_index.core.prompts import RichPromptTemplate
template = RichPromptTemplate( """{% chat role="system" %}Given a list if images and text from each image, please answer the question to the best of your ability.{% endchat %}
{% chat role="user" %}{% for image_path, text in images_and_texts %}Here is some text: {{ text }}And here is an image:{{ image_path | image }}{% endfor %}{% endchat %}""")
messages = template.format_messages( images_and_texts=[ ("page_1.png", "This is the first page of the document"), ("page_2.png", "This is the second page of the document"), ])在这个示例中,你可以看到几个特性:
{% chat %}代码块用于将消息格式化为聊天消息并设置角色{% for %}循环用于遍历传入的images_and_texts列表- 使用
{{ image_path | image }}语法将图像路径格式化为图像内容块。此处,|用于对变量应用“过滤器”以帮助将其识别为图像。
让我们来看另一个示例,这次是关于使用检索器中的节点创建模板:
from llama_index.core.prompts import RichPromptTemplate
template = RichPromptTemplate( """{% chat role="system" %}You are a helpful assistant that can answer questions about the context provided.{% endchat %}
{% chat role="user" %}{% for node in nodes %}{{ node.text }}{% endfor %}{% endchat %}""")
nodes = retriever.retrieve("What is the capital of the moon?")
messages = template.format_messages(nodes=nodes)使用 f-string 提示模板
Section titled “Using f-string Prompt Templates”截至本文撰写时,许多旧版组件和示例仍将使用 f-string 提示。
定义自定义提示就像创建一个格式化字符串一样简单
from llama_index.core import PromptTemplate
template = ( "We have provided context information below. \n" "---------------------\n" "{context_str}" "\n---------------------\n" "Given this information, please answer the question: {query_str}\n")qa_template = PromptTemplate(template)
# you can create text prompt (for completion API)prompt = qa_template.format(context_str=..., query_str=...)
# or easily convert to message prompts (for chat API)messages = qa_template.format_messages(context_str=..., query_str=...)您也可以从聊天消息中定义一个模板
from llama_index.core import ChatPromptTemplatefrom llama_index.core.llms import ChatMessage, MessageRole
message_templates = [ ChatMessage(content="You are an expert system.", role=MessageRole.SYSTEM), ChatMessage( content="Generate a short story about {topic}", role=MessageRole.USER, ),]chat_template = ChatPromptTemplate(message_templates=message_templates)
# you can create message prompts (for chat API)messages = chat_template.format_messages(topic=...)
# or easily convert to text prompt (for completion API)prompt = chat_template.format(topic=...)由于LlamaIndex是一个多步骤的流水线,识别您想要修改的操作并在正确位置传入自定义提示非常重要。
例如,提示词被用于响应合成器、检索器、索引构建等模块;其中部分模块嵌套在其他模块中(合成器嵌套在查询引擎中)。
查看本指南了解访问/自定义提示的完整详情。
最常用的提示词将是 text_qa_template 和 refine_template。
text_qa_template- 用于通过检索到的节点获取查询的初始答案refine_template- 当检索到的文本无法通过单次LLM调用(使用默认的response_mode="compact")容纳时,或当使用response_mode="refine"检索到多个节点时使用。第一个查询的答案将作为existing_answer插入,LLM必须根据新上下文更新或重复现有答案。
您可以在LlamaIndex的许多模块上调用get_prompts,以获取该模块及嵌套子模块中使用的扁平化提示列表。
例如,请看以下代码片段。
query_engine = index.as_query_engine(response_mode="compact")prompts_dict = query_engine.get_prompts()print(list(prompts_dict.keys()))您可能会得到以下键:
['response_synthesizer:text_qa_template', 'response_synthesizer:refine_template']请注意,提示词会以其子模块作为“命名空间”进行前缀标识。
您可以在任何实现 get_prompts 的模块上使用 update_prompts 函数自定义提示词。只需传入参数值,其键名与通过 get_prompts 获取的提示词字典中显示的键名保持一致。
例如,针对上述示例,我们可能会执行以下操作
# shakespeare!qa_prompt_tmpl_str = ( "Context information is below.\n" "---------------------\n" "{{ context_str }}\n" "---------------------\n" "Given the context information and not prior knowledge, " "answer the query in the style of a Shakespeare play.\n" "Query: {{ query_str }}\n" "Answer: ")qa_prompt_tmpl = RichPromptTemplate(qa_prompt_tmpl_str)
query_engine.update_prompts( {"response_synthesizer:text_qa_template": qa_prompt_tmpl})修改查询引擎中使用的提示词
Section titled “Modify prompts used in query engine”对于查询引擎,您也可以在查询时直接传入自定义提示(即针对索引执行查询并合成最终响应)。
还有两种等效的方式来覆盖提示词:
- 通过高级API
query_engine = index.as_query_engine( text_qa_template=custom_qa_prompt, refine_template=custom_refine_prompt)- 通过底层组合API
retriever = index.as_retriever()synth = get_response_synthesizer( text_qa_template=custom_qa_prompt, refine_template=custom_refine_prompt)query_engine = RetrieverQueryEngine(retriever, response_synthesizer)以上两种方法是等效的,其中方法1本质上是方法2的语法糖,隐藏了底层的复杂性。您可能希望使用方法1来快速修改某些常见参数,而使用方法2来进行更细粒度的控制。
有关哪些类使用哪些提示的更多详细信息,请访问 查询类参考。
查看参考文档获取完整提示词及其方法/参数的全套信息。
在本节中,我们将展示LlamaIndex中的一些高级提示功能。
相关指南:
将函数作为模板变量传入,而非固定值。
这相当先进且功能强大;允许您进行动态少样本提示等操作。
以下是一个重新格式化 context_str 的示例。
from llama_index.core.prompts import RichPromptTemplate
def format_context_fn(**kwargs): # format context with bullet points context_list = kwargs["context_str"].split("\n\n") fmtted_context = "\n\n".join([f"- {c}" for c in context_list]) return fmtted_context
prompt_tmpl = RichPromptTemplate( "{{ context_str }}", function_mappings={"context_str": format_context_fn})
prompt_str = prompt_tmpl.format(context_str="context", query_str="query")部分格式化提示,填充部分变量,同时保留其他变量供后续填充。
from llama_index.core.prompts import RichPromptTemplate
template = RichPromptTemplate( """{{ foo }} {{ bar }}""")
partial_prompt_tmpl = template.partial_format(foo="abc")
fmt_str = partial_prompt_tmpl.format(bar="def")LlamaIndex 提示抽象通常期望特定的键。例如,我们的 text_qa_prompt 期望 context_str 作为上下文,query_str 作为用户查询。
但如果你试图将一个字符串模板适配到LlamaIndex中使用,更换模板变量可能会很麻烦。
相反,定义 template_var_mappings:
from llama_index.core.prompts import RichPromptTemplate
template_var_mappings = {"context_str": "my_context", "query_str": "my_query"}
prompt_tmpl = RichPromptTemplate( "Here is some context: {{ context_str }} and here is a query: {{ query_str }}", template_var_mappings=template_var_mappings,)
prompt_str = prompt_tmpl.format(my_context="context", my_query="query")