Skip to content

Usage pattern

用法模式#

定义自定义提示#

定义自定义提示就像创建一个格式字符串一样简单

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=...)

注意:您可能会看到对于旧提示子类(如 QuestionAnswerPromptRefinePrompt)的引用。这些已经被弃用(现在是 PromptTemplate 的类型别名)。现在您可以直接指定 PromptTemplate(template) 来构建自定义提示。但是在替换默认的问题回答提示时,仍然需要确保模板字符串包含预期的参数(例如 {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)

# 您可以创建消息提示(用于聊天 API)
messages = chat_template.format_messages(topic=...)

# 或者轻松转换为文本提示(用于完成 API)
prompt = chat_template.format(topic=...)

获取和设置自定义提示#

由于 LlamaIndex 是一个多步骤的流水线,重要的是要确定您想要修改的操作,并在正确的位置传入自定义提示。

例如,提示被用于响应合成器、检索器、索引构建等;其中一些模块嵌套在其他模块中(合成器嵌套在查询引擎中)。

请参阅此指南以获取有关访问/自定义提示的完整详细信息。

常用提示#

最常用的提示将是 text_qa_templaterefine_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']

请注意,提示以其子模块作为前缀,作为 "命名空间"。

更新提示#

您可以使用 update_prompts 函数在任何实现了 get_prompts 的模块上自定义提示。只需传入与通过 get_prompts 获得的提示字典中的键相等的参数值。

例如,关于上面的示例,我们可以这样做

# 莎士比亚!
qa_prompt_tmpl_str = (
    "下面是上下文信息。\n"
    "---------------------\n"
    "{context_str}\n"
    "---------------------\n"
    "根据上下文信息而不是先前的知识,"
    "以莎士比亚戏剧的风格回答查询。\n"
    "查询:{query_str}\n"
    "答案:"
)
qa_prompt_tmpl = PromptTemplate(qa_prompt_tmpl_str)

query_engine.update_prompts(
    {"response_synthesizer:text_qa_template": qa_prompt_tmpl}
)

修改查询引擎中使用的提示#

对于查询引擎,您还可以在查询时直接传入自定义提示(即对索引执行查询并合成最终响应)。

还有两种等效的方法来覆盖提示:

  1. 通过高级 API
query_engine = index.as_query_engine(
    text_qa_template=custom_qa_prompt, refine_template=custom_refine_prompt
)
  1. 通过低级组合 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来实现更精细的控制。

有关哪些类使用哪些提示的更多详细信息,请访问查询类参考

查看参考文档以获取所有提示的完整集合。

修改用于索引构建的提示#

一些索引在构建过程中使用不同类型的提示(注意:最常见的VectorStoreIndexSummaryIndex不使用任何提示)。

例如,TreeIndex使用摘要提示对节点进行分层摘要,而KeywordTableIndex使用关键词提取提示来提取关键词。

有两种等效的方法来覆盖提示:

  1. 通过默认节点构造函数
index = TreeIndex(nodes, summary_template=custom_prompt)
  1. 通过文档构造函数
index = TreeIndex.from_documents(docs, summary_template=custom_prompt)

有关哪个索引使用哪些提示的更多详细信息,请访问索引类参考

[高级] 高级提示功能#

在本节中,我们展示了LlamaIndex中一些高级提示功能。

相关指南:

部分格式化#

部分格式化提示,填充一些变量,同时留下其他变量以便稍后填充。

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")

模板变量映射#

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
)

函数映射#

将函数作为模板变量传递,而不是固定值。

这是相当高级和强大的功能;允许您执行动态的few-shot提示等。

以下是重新格式化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")