
LlamaIndex Prompts 完全指南从 Jinja 模板到 PromptMixin 的深度定制【免费下载链接】llama_indexLlamaIndex is the document processing platform for AI项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index导读提示词Prompt是赋予大语言模型LLM表达能力的根本输入。在 LlamaIndex 中提示词贯穿索引构建、数据插入、查询时的遍历以及最终答案的合成等全流程构建 Agent 工作流时提示词的管理与定制更是开发的关键环节。本篇指南以 Prompts 模块文档 为主线结合llama-index-core的源码实现系统讲解RichPromptTemplate、PromptTemplate、ChatPromptTemplate三种模板的用法以及通过get_prompts/update_prompts定制查询引擎提示词的完整路径读完即可在 LlamaIndex 项目中灵活构建、注入和热替换各类提示词。概念提示词在 LlamaIndex 中的角色LlamaIndex 使用提示词完成四类关键任务构建索引build the index例如摘要提示词、树索引插入提示词执行插入insertion将新节点插入既有索引结构查询时的遍历traversal during querying例如树索引的选择提示词、关键词抽取提示词合成最终答案synthesize the final answer例如text_qa_template与refine_template。针对不同的任务LlamaIndex 提供三种风格各异的提示词模板模板类风格适用场景RichPromptTemplate基于 Jinja 语法支持变量、逻辑循环/条件、多模态内容块最新推荐风格可同时产出文本与聊天消息PromptTemplate单一 f-string 简单模板传统风格适用于 Completion APIChatPromptTemplate由多条ChatMessage组成的消息模板传统风格适用于 Chat APILlamaIndex 内置了一套开箱即用的默认提示词集中定义在 default_prompts.py涵盖摘要、树索引插入/选择、QA、refine、关键词抽取、Text-to-SQL、知识图谱三元组抽取等场景此外专为gpt-3.5-turbo等聊天模型编写的提示词位于 chat_prompts.py。最佳定制实践官方推荐的定制方式是先从上文链接中复制默认提示词再在其基础上修改这样可以确保新提示词与框架期望的输入变量如context_str、query_str保持一致。从源码看所有提示词模板均继承自 base.py 中的抽象基类BasePromptTemplate它声明了四个核心抽象方法partial_format部分格式化format格式化为字符串format_messages格式化为聊天消息列表get_template取回模板字符串。同时它内建了template_var_mappings与function_mappings两套变量映射机制详见后文“高级能力”这是理解 LlamaIndex 提示词体系的关键入口。使用模式一RichPromptTemplate与 Jinja 语法借助 Jinja 语法RichPromptTemplate可以构建带变量、逻辑判断、对象解析乃至多模态内容的模板。其源码位于 rich.py底层依赖banks库完成模板解析。基础用法双花括号变量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 }} ) # 格式化为字符串用于 Completion API prompt_str template.format(context_str..., query_str...) # 格式化为聊天消息列表用于 Chat API messages template.format_messages(context_str..., query_str...)Jinja 与 f-string 最直观的区别是变量从单花括号{ }变为双花括号{{ }}。format与format_messages内部会合并构造时传入的固定kwargs与调用时传入的变量再交给banks解析对于含聊天块的模板format会自动委托给format_messages再通过默认的messages_to_prompt转成字符串见 rich.py。循环与多模态{% chat %}、{% for %}与| image过滤器下面是一个利用循环生成多模态提示词的复杂示例from llama_index.core.prompts import RichPromptTemplate template RichPromptTemplate( {% chat rolesystem %} Given a list if images and text from each image, please answer the question to the best of your ability. {% endchat %} {% chat roleuser %} {% 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 %}块将内容格式化为带角色的聊天消息role可设为system、user等{% for %}循环迭代传入的images_and_texts列表可自由嵌套变量{{ image_path | image }}过滤器|对变量应用“过滤器”将其标记为图片内容块。从源码看format_messages会把banks解析出的内容块逐一转换为 LlamaIndex 的ContentBlock类型——文本映射为TextBlock图片映射为ImageBlock并同样支持AudioBlock、VideoBlock、DocumentBlock最后组装为ChatMessage列表见 rich.py。也就是说一份模板即可覆盖文本、图片、音频、视频、文档五种模态的提示词输入。对接检索器直接用节点填充模板RichPromptTemplate可以直接消费检索器返回的Node对象from llama_index.core.prompts import RichPromptTemplate template RichPromptTemplate( {% chat rolesystem %} You are a helpful assistant that can answer questions about the context provided. {% endchat %} {% chat roleuser %} {% for node in nodes %} {{ node.text }} {% endfor %} {% endchat %} ) nodes retriever.retrieve(What is the capital of the moon?) messages template.format_messages(nodesnodes)这里{{ node.text }}通过 Jinja 的对象属性访问能力直接取每个节点的文本省去了手动拼接上下文的样板代码。使用模式二f-string 风格的PromptTemplate目前许多旧组件与示例仍在使用 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) # 生成文本提示词用于 Completion API prompt qa_template.format(context_str..., query_str...) # 或转换为消息提示词用于 Chat API messages qa_template.format_messages(context_str..., query_str...)PromptTemplate的format在内部依次执行变量映射、f-string 格式化、输出解析器处理与completion_to_prompt包装见 base.pyformat_messages则通过prompt_to_messages将文本转换为单条用户消息。使用模式三基于消息的ChatPromptTemplateChatPromptTemplate适合需要精确控制多轮角色消息的场景。它由ChatMessage列表构成每条消息包含内容与角色from llama_index.core import ChatPromptTemplate from llama_index.core.llms import ChatMessage, MessageRole message_templates [ ChatMessage(contentYou are an expert system., roleMessageRole.SYSTEM), ChatMessage( contentGenerate a short story about {topic}, roleMessageRole.USER, ), ] chat_template ChatPromptTemplate(message_templatesmessage_templates) # 生成消息提示词用于 Chat API messages chat_template.format_messages(topic...) # 或转换为文本提示词用于 Completion API prompt chat_template.format(topic...)源码中ChatPromptTemplate.format_messages会遍历message_templates对每条消息执行format_vars完成变量填充见 base.py它还提供了from_messages类方法可直接从(role, content)元组列表构造模板。chat_prompts.py中面向聊天模型的内置提示词如CHAT_TEXT_QA_PROMPT正是这种风格的典型代表。获取与设置自定义提示词get_prompts与update_prompts由于 LlamaIndex 是多步骤流水线prompt 被用于响应合成器、检索器、索引构建等且合成器又嵌套在查询引擎内定制提示词的关键是定位到需要修改的模块并在正确的位置注入。最常用的提示词最常被定制的是以下两个text_qa_template使用检索到的节点对查询生成初始答案refine_template当检索文本无法在单次 LLM 调用内塞下默认的response_modecompact或使用response_moderefine检索到多个节点时使用。第一次查询的答案会被作为existing_answer插入LLM 需要基于新上下文更新或重复既有答案。这两个提示词的默认实现分别对应 default_prompts.py 中的DEFAULT_TEXT_QA_PROMPT与 default_prompts.py 中的DEFAULT_REFINE_PROMPT。读取提示词get_promptsLlamaIndex 中的许多模块都实现了get_prompts可以返回该模块及其嵌套子模块使用的提示词扁平化字典query_engine index.as_query_engine(response_modecompact) prompts_dict query_engine.get_prompts() print(list(prompts_dict.keys()))输出示例[response_synthesizer:text_qa_template, response_synthesizer:refine_template]注意提示词键会以其所属子模块作为“命名空间”前缀用:分隔。这一机制的底层是 mixin.py 中的PromptMixin抽象类get_prompts会先收集当前模块自身的提示词再递归合并所有_get_prompt_modules()返回的子模块提示词并以module_name:key拼接同时它会对键中的:进行合法性校验防止嵌套模块的键冲突。更新提示词update_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 RichPromptTemplate(qa_prompt_tmpl_str) query_engine.update_prompts( {response_synthesizer:text_qa_template: qa_prompt_tmpl} )从 mixin.py 的源码可见update_prompts会先把属于当前模块的提示词直接更新再将包含:的键按模块名拆分为子字典递归下发给对应子模块——因此你可以用一条update_prompts调用同时更新多层嵌套模块的提示词未涉及的提示词保持不变。查询时直接覆盖两种等价方式针对查询引擎还有两种在查询时覆盖提示词的等价方式1. 高层 API语法糖query_engine index.as_query_engine( text_qa_templatecustom_qa_prompt, refine_templatecustom_refine_prompt )2. 低层组合 API更细粒度控制retriever index.as_retriever() synth get_response_synthesizer( text_qa_templatecustom_qa_prompt, refine_templatecustom_refine_prompt ) query_engine RetrieverQueryEngine(retriever, response_synthesizer)两种方式完全等价——方式 1 本质上是方式 2 的语法糖把底层组装过程隐藏起来。想快速调整常见参数用方式 1需要对检索与合成进行精细编排时用方式 2。关于哪些类使用哪些提示词可查阅响应合成器相关参考文档提示词类的完整方法与参数可参考 Prompts 参考文档。高级能力函数映射、部分格式化与变量映射RichPromptTemplate还提供三项进阶能力可在 usage_pattern.md 的基础上配合源码深入理解。函数映射Function Mappings可以把函数作为模板变量传入而不是固定值——这为动态 few-shot 提示等场景提供了可能。下面示例对context_str做重排添加 bullet 前缀from llama_index.core.prompts import RichPromptTemplate def format_context_fn(**kwargs): # 用 bullet 点格式化上下文 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_strcontext, query_strquery)底层实现上BasePromptTemplate._map_function_vars会以当前 kwargs 调用每个映射函数用返回值覆盖对应变量见 base.py。部分格式化Partial Formatting先填充部分变量其余变量留待后续填充from llama_index.core.prompts import RichPromptTemplate template RichPromptTemplate( {{ foo }} {{ bar }} ) partial_prompt_tmpl template.partial_format(fooabc) fmt_str partial_prompt_tmpl.format(bardef)partial_format的实现方式是深拷贝模板对象并把已填充变量存入kwargs见 rich.py后续format时这些固定变量会自动与调用时变量合并。模板变量映射Template Variable MappingsLlamaIndex 的提示词抽象通常约定特定键名例如text_qa_prompt期望context_str表示上下文、query_str表示用户查询。当你希望复用一个变量名不同的既有模板时不必改写模板只需声明template_var_mappingsfrom 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_mappingstemplate_var_mappings, ) prompt_str prompt_tmpl.format(my_contextcontext, my_queryquery)映射逻辑位于BasePromptTemplate._map_template_vars见 base.py它把外部传入的my_context/my_query重写为模板内部的context_str/query_str。此外SelectorPromptTemplate还支持根据 LLM 类型在多个模板间条件选择见 base.pyLangchainPromptTemplate则用于桥接 LangChain 模板见 base.py。小结与进一步探索本文以文档为核心骨架完整覆盖了 LlamaIndex 提示词体系的三个层面模板层RichPromptTemplateJinja 语法、多模态内容块、PromptTemplatef-string、ChatPromptTemplate消息列表管理层通过get_prompts/update_prompts读取与热替换模块含嵌套子模块的提示词以及查询引擎的两种覆盖方式高级层函数映射、部分格式化、模板变量映射以及SelectorPromptTemplate、LangchainPromptTemplate等扩展模板。建议进一步阅读以下仓库资源加深理解完整用法细节见 usage_pattern.md全部内置默认提示词见 default_prompts.py含PromptType枚举定义的各类提示词类型见 prompt_type.py聊天模型专用提示词见 chat_prompts.py提示词混入机制PromptMixin源码见 mixin.py。从实践角度看建议优先采用RichPromptTemplate构建新模板它在不牺牲可读性的前提下把循环、条件、多模态与消息角色统一进一份模板配合template_var_mappings与function_mappings足以应对绝大多数 RAG 与 Agent 工作流的提示词定制需求。【免费下载链接】llama_indexLlamaIndex is the document processing platform for AI项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考