使用模式(Usage Pattern)
定义自定义提示(Defining a Custom Prompt)
定义自定义提示非常简单,只需创建一个格式化字符串即可。以下是一个示例:
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)
# 你可以创建文本提示(用于 completion API)
prompt = qa_template.format(context_str="上下文信息", query_str="问题")
# 或者轻松转换为消息提示(用于 chat 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="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)
# 你可以创建消息提示(用于 chat API)
messages = chat_template.format_messages(topic="主题")
# 或者轻松转换为文本提示(用于 completion API)
prompt = chat_template.format(topic="主题")
获取和设置自定义提示(Getting and Setting Custom Prompts)
由于 LlamaIndex 是一个多步骤的管道,重要的是要识别你想要修改的操作,并在正确的位置传递自定义提示。
例如,提示用于响应合成器、检索器、索引构建等;其中一些模块嵌套在其他模块中(合成器嵌套在查询引擎中)。
常用提示(Commonly Used Prompts)
最常用的提示是 text_qa_template
和 refine_template
。
text_qa_template
- 用于使用检索到的节点获取查询的初始答案refine_template
- 当检索到的文本无法在一个 LLM 调用中使用response_mode="compact"
(默认)时,或者当使用response_mode="refine"
检索到多个节点时使用。第一个查询的答案作为existing_answer
插入,LLM 必须根据新的上下文更新或重复现有答案。
访问提示(Accessing Prompts)
你可以在 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']
注意,提示以其子模块为“命名空间”作为前缀。
更新提示(Updating Prompts)
你可以在任何实现了 get_prompts
的模块上使用 update_prompts
函数来自定义提示。只需传入键值对,键等于通过 get_prompts
获得的提示字典中的键。
例如:
# 莎士比亚风格!
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 = PromptTemplate(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)
这两种方法在功能上是等效的,第一种方法本质上是对第二种方法的语法糖,隐藏了底层的复杂性。你可能想使用第一种方法快速修改一些常见参数,使用第二种方法进行更细粒度的控制。
修改索引构建中使用的提示
一些索引在构建过程中使用不同类型的提示(注意:最常见的 VectorStoreIndex 和 SummaryIndex 不使用任何提示)。
例如,TreeIndex 使用摘要提示来层次化地总结节点,KeywordTableIndex 使用关键词提取提示来提取关键词。
有两种等效的方法可以覆盖提示:
- 通过默认节点构造函数
index = TreeIndex(nodes, summary_template=custom_prompt)
- 通过文档构造函数
index = TreeIndex.from_documents(docs, summary_template=custom_prompt)
[高级] 高级提示功能(Advanced Prompt Capabilities)
在本节中,我们将展示 LlamaIndex 中的一些高级提示功能。
部分格式化(Partial Formatting)
部分格式化一个提示,填充一些变量,同时保留其他变量以便稍后填充。
from llama_index.core import PromptTemplate
prompt_tmpl_str = "{foo} {bar}"
prompt_tmpl = PromptTemplate(prompt_tmpl_str)
partial_prompt_tmpl = prompt_tmpl.partial_format(foo="abc")
fmt_str = partial_prompt_tmpl.format(bar="def")
模板变量映射(Template Variable Mappings)
LlamaIndex 提示抽象通常期望某些键。例如,我们的 text_qa_prompt
期望 context_str
用于上下文,query_str
用于用户查询。
但如果你试图适应一个字符串模板以用于 LlamaIndex,更改模板变量可能会很麻烦。
相反,定义 template_var_mappings
:
template_var_mappings = {"context_str": "my_context", "query_str": "my_query"}
prompt_tmpl = PromptTemplate(
qa_prompt_tmpl_str, template_var_mappings=template_var_mappings
)
函数映射(Function Mappings)
将函数作为模板变量传递,而不是固定值。
这是一个非常高级且强大的功能;允许你进行动态少样本提示等。
以下是一个示例,重新格式化 context_str
:
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 = PromptTemplate(
qa_prompt_tmpl_str, function_mappings={"context_str": format_context_fn}
)
prompt_tmpl.format(context_str="context", query_str="query")