提示词使用模式#
使用 RichPromptTemplate 和 Jinja 语法#
通过利用 Jinja 语法,您可以构建包含变量、逻辑、解析对象等功能的提示词模板。
让我们看几个示例:
from llama_index.core.prompts import RichPromptTemplate
template = RichPromptTemplate(
"""我们提供了以下上下文信息。
---------------------
{{ context_str }}
---------------------
根据这些信息,请回答问题:{{ query_str }}
"""
)
# 格式化为字符串
prompt_str = template.format(context_str=..., query_str=...)
# 格式化为聊天消息列表
messages = template.format_messages(context_str=..., query_str=...)
Jinja 提示词与 f-string 的主要区别在于变量现在使用双括号 {{ }} 而不是单括号 { }。
让我们看一个更复杂的示例,使用循环生成多模态提示词:
from llama_index.core.prompts import RichPromptTemplate
template = RichPromptTemplate(
"""
{% chat role="system" %}
给定一组图像及其对应的文本描述,请尽可能准确地回答问题。
{% endchat %}
{% chat role="user" %}
{% for image_path, text in images_and_texts %}
以下是文本内容:{{ text }}
这是对应的图像:
{{ image_path | image }}
{% endfor %}
{% endchat %}
"""
)
messages = template.format_messages(
images_and_texts=[
("page_1.png", "这是文档的第一页"),
("page_2.png", "这是文档的第二页"),
]
)
在这个示例中,您可以看到几个特性:
{% chat %}块用于将消息格式化为聊天消息并设置角色{% for %}循环用于遍历传入的images_and_texts列表{{ image_path | image }}语法用于将图像路径格式化为图像内容块。这里的|用于对变量应用"过滤器"以标识其为图像
再看一个示例,这次是为检索器节点创建模板:
from llama_index.core.prompts import RichPromptTemplate
template = RichPromptTemplate(
"""
{% chat role="system" %}
您是一个能够根据提供的上下文回答问题的助手。
{% endchat %}
{% chat role="user" %}
{% for node in nodes %}
{{ node.text }}
{% endfor %}
{% endchat %}
"""
)
nodes = retriever.retrieve("月亮的首都是什么?")
messages = template.format_messages(nodes=nodes)
使用 f-string 提示词模板#
截至本文撰写时,许多旧组件和示例仍会使用 f-string 提示词。
定义自定义提示词就像创建格式化字符串一样简单:
from llama_index.core import PromptTemplate
template = (
"我们提供了以下上下文信息。\n"
"---------------------\n"
"{context_str}"
"\n---------------------\n"
"根据这些信息,请回答问题:{query_str}\n"
)
qa_template = PromptTemplate(template)
# 可以创建文本提示词(用于补全API)
prompt = qa_template.format(context_str=..., query_str=...)
# 或轻松转换为消息提示词(用于聊天API)
messages = qa_template.format_messages(context_str=..., query_str=...)
您也可以从聊天消息定义模板:
from llama_index.core import ChatPromptTemplate
from llama_index.core.llms import ChatMessage, MessageRole
message_templates = [
ChatMessage(content="您是一个专家系统。", role=MessageRole.SYSTEM),
ChatMessage(
content="生成一个关于{topic}的短篇故事",
role=MessageRole.USER,
),
]
chat_template = ChatPromptTemplate(message_templates=message_templates)
# 可以创建消息提示词(用于聊天API)
messages = chat_template.format_messages(topic=...)
# 或轻松转换为文本提示词(用于补全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 获得的提示词字典中的键。
例如,对于上面的示例,我们可以这样做:
# 莎士比亚风格!
qa_prompt_tmpl_str = (
"上下文信息如下。\n"
"---------------------\n"
"{{ context_str }}\n"
"---------------------\n"
"根据上下文信息而非先验知识,"
"以莎士比亚戏剧的风格回答问题。\n"
"查询:{{ query_str }}\n"
"回答:"
)
qa_prompt_tmpl = RichPromptTemplate(qa_prompt_tmpl_str)
query_engine.update_prompts(
{"response_synthesizer:text_qa_template": qa_prompt_tmpl}
)
修改查询引擎中使用的提示词#
对于查询引擎,您也可以在查询时(即对索引执行查询并合成最终响应时)直接传入自定义提示词。
有两种等效的方法可以覆盖提示词:
- 通过高级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):
# 用项目符号格式化上下文
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(
"这是上下文:{{ context_str }} 这是查询:{{ query_str }}",
template_var_mappings=template_var_mappings,
)
prompt_str = prompt_tmpl.format(my_context="context", my_query="query")