47.llama_index-jinja2多模态提示词(让模型识别图片)和默认提示词 内容参考于图灵AI大模型全栈我们用的模型都是大语言模型LLM但是我肯定会要加载一些图片数据给到大模型的下方是一个带图片的jinja2模版这个{{ loop.index }}是可以获取到当前第几次循环loop是jinja2内置的变量index是当前第几次循环的数字然后{{ image_path | image }}中的image_path是图片的目录image是过滤器这个|竖杠是管道连起来就是image_path这个路径会传递给image这个方法这个image方法是固定的传递图片的方式有流式传输、二进制传输、base64传输给大模型的是把图片数据转成base64编码然后大模型会自己解析{% chat rolesystem %} 你是一个专业的图像理解专家。请仔细观察图片内容并回答用户的问题。 {% endchat %} {% chat roleuser %} {% for image_path in image_list %} 图片 {{ loop.index }} {{ image_path | image }} {% endfor %} 用户问题{{ query_str }} 请用中文回答并分别描述每张图片的关键内容最后总结它们的共同点。 {% endchat %}它实现图片二进制转base64的方式如下它是通过调用ImageBlock里的方法来实现的from llama_index.core.base.llms.types import ImageBlockImageBlock的说明可以在LLamaIndex官网里找到官网地址https://developers.llamaindex.ai/python/framework-api-reference/llms/通过下图红框位置搜索ImageBlock就可以找到它的说明了如果还是看不懂那就去问ai可以把下图的链接给大模型然后让大模型给你用小白的方式详细说明如下图红框可以看到image_to_base64也就是图片转base64上方{{ image_path | image }}就是把一个图片路径给到方法然后方法转成base64如下图红框图片转成base64然后拼接到提示词中注意要用format_messages方法才能看到如下图format是看不到base64的图片转成了base64可以给大模型了这里有一个问题如下图访问的是千问的qwen3.7-plus模型它回答的是无法直接查看图片这个原因是并不是所有模型都支持多模态要找支持多模态的模型才可以如下图红框qwen3.7-plus模型的说明但看着它也是支持图片的为什么不行换一个模型如下图红框点击全模态找全模态的模型下图蓝框的模型可以确定是肯定支持图片解析的如下图红框看它的介绍它支持图片理解和交互但是如下图它还是不行还是有问题LLamaIndex中各个厂商会有单独的SDK我们使用的是DashScope来调用的大模型DashScope中并没有实现转换这就需要我们自己写国外的模型LLamaIndex是可以无法衔接的我们国内的模型LLamaIndex现在还兼容的不好如下图我们使用OpenAILike的方式就可以了但前提也是要模型支持图片分析所以要注意模型是否支持图片解析、厂商的SDK是否支持图片转换如果SDK不支持就需要使用OpenAILike的方式代码# 从 LlamaIndex 核心提示词模块导入富提示词模板类 # 核心能力支持 Jinja2 完整语法、结构化聊天消息、多模态内容过滤器是构建复杂多模态提示词的标准组件 from llama_index.core.prompts import RichPromptTemplate # 导入图片内容块类 # 类全称ImageBlock # 核心作用LlamaIndex 多模态体系的标准图片数据封装类用于在聊天消息中承载图片内容 # 设计原因多模态消息的内容是「文本图片」混合结构不能直接用字符串表示图片路径 # 必须用 ImageBlock 对象封装大模型适配层才能识别这是图片、而非普通文本 # 生成方式既可手动实例化也可通过模板中的 |image 过滤器自动从路径生成 from llama_index.core.base.llms.types import ImageBlock # 定义多模态提示词模板字符串 # 模板语法Jinja2 标准语法 LlamaIndex 扩展的 chat 标签 image 多模态过滤器 # 整体结构系统人设 → 循环插入多张图片 → 用户问题与回答要求 # 核心亮点通过循环 image 过滤器实现批量图片自动注入支持任意数量的图片输入 multi_modal_template_str {% chat rolesystem %} 你是一个专业的图像理解专家。请仔细观察图片内容并回答用户的问题。 {% endchat %} {% chat roleuser %} {# 循环遍历图片路径列表批量生成图片内容 #} {# loop.index 是 Jinja2 内置循环变量代表当前循环的序号从1开始用于标注第几张图 #} {% for image_path in image_list %} 图片 {{ loop.index }} {# 核心语法| image 是 LlamaIndex 内置的多模态过滤器 #} {# 作用将图片路径字符串自动转换为 ImageBlock 对象让模型识别为图片输入而非普通文本 #} {# 支持输入本地文件路径、网络图片URL底层会自动读取/加载图片数据 #} {{ image_path | image }} {% endfor %} 用户问题{{ query_str }} 请用中文回答并分别描述每张图片的关键内容最后总结它们的共同点。 {% endchat %} # 实例化多模态富提示词模板 # 入参模板字符串内部包含 image 过滤器与循环逻辑 # 渲染后输出多模态结构化聊天消息列表消息内容为「文本块图片块」的混合结构 multi_modal_template RichPromptTemplate(multi_modal_template_str) # 渲染模板生成结构化多模态消息 # 调用 format_messages 方法传入图片路径列表与用户问题 # 入参说明 # image_list列表类型存放所有图片的路径本地路径或URL均可 # query_str字符串类型用户的提问内容 # 执行流程 # 1. 遍历 image_list 中的每个路径 # 2. 通过 image 过滤器将每个路径转为 ImageBlock 对象 # 3. 与文本内容拼接生成完整的用户多模态消息 # 4. 最终返回 List[ChatMessage] 结构化消息列表 # 注意渲染后的用户消息 content 不是纯字符串而是「文本段 ImageBlock」的混合列表 messages multi_modal_template.format_messages( image_list[ ./data_file/img.png, ./data_file/img_1.png ], query_str这些图片里有什么共同点 ) # 打印消息结构可查看 ImageBlock 对象调试时打开 # print(messages) # OpenAILike 通用适配当前启用 # 导入操作系统模块用于读取环境变量 import os # 导入 OpenAI 兼容格式的通用大模型适配类 # 类全称OpenAILike # 核心作用通用适配所有兼容 OpenAI 接口协议的大模型服务 # 适用场景只要模型服务提供了兼容 OpenAI 的 API 格式都可以用这个类对接 # 比如通义千问、DeepSeek、本地 Ollama、各类私有化部署的模型服务 # 优势通用性强切换兼容接口的模型时只改地址和模型名即可代码结构不变 from llama_index.llms.openai_like import OpenAILike # 导入环境变量加载工具 from dotenv import load_dotenv # 加载 .env 配置文件到系统环境变量 load_dotenv() # 初始化 OpenAILike 大模型实例对接通义千问服务 llm OpenAILike( # 指定要调用的模型名称必须和服务端支持的模型名完全一致 # 注意处理图片必须用多模态模型如 qwen-omni 系列纯文本模型会报错 modelqwen3.7-plus, # 从环境变量读取 API 密钥对应 .env 中 DASHSCOPE_API_KEY api_keyos.getenv(DASHSCOPE_API_KEY), # 从环境变量读取接口基础地址 # 必要性非官方 OpenAI 服务必须手动指定接口地址否则会默认请求 OpenAI 官方地址 api_baseos.getenv(DASHSCOPE_BASE_URL), # 标记当前模型为聊天对话模型 # 作用告知 LlamaIndex 该模型支持多轮聊天消息格式内部按聊天接口协议发起请求 # 取值True聊天模型主流大模型均为此类False纯补全模型老式模型 is_chat_modelTrue, # 是否是 聊天模型 ) # 调用聊天接口传入多模态结构化消息列表获取模型回复 # 入参List[ChatMessage]包含文本与图片的混合多模态消息 # 底层逻辑OpenAILike 会自动识别消息中的 ImageBlock按 OpenAI 多模态消息格式组装请求 # 返回值ChatResponse 对象包含模型的文本回复内容 res llm.chat(messages) # 打印模型回复结果默认输出纯文本回答内容 print(res)上方的提示词都是我们自己写的在LLamaIndex中有写好的默认提示词下图红框里都是LLamaIndex写好的提示词注意LLamaIndex默认提示词都是英文的用英文写提示词是比较好的中文翻译这些默认的提示词lamaindex自己会用我们不需要使用只需要知道llamaindex有默认提示这回事就行代码# 从 LlamaIndex 核心默认提示词模块导入 4 个官方预置的标准提示词模板 # 模块定位框架内置的官方默认提示词仓库是各类索引、响应模式的默认配置 # 设计逻辑提供一套经过通用场景优化的默认提示词无需手动编写即可直接开箱使用 # 也可以基于默认模板修改或完全替换为自定义业务模板 # 四个模板分别对应不同的检索响应模式与业务场景 # 1. DEFAULT_TEXT_QA_PROMPT标准问答模板Stuff 响应模式默认使用 # 2. DEFAULT_REFINE_PROMPT迭代优化模板Refine 响应模式默认使用 # 3. DEFAULT_SUMMARY_PROMPT单段文本总结模板摘要索引默认使用 # 4. DEFAULT_TREE_SUMMARIZE_PROMPT树状合并总结模板Tree Summarize 响应模式默认使用 from llama_index.core.prompts.default_prompts import ( DEFAULT_TEXT_QA_PROMPT, DEFAULT_REFINE_PROMPT, DEFAULT_SUMMARY_PROMPT, DEFAULT_TREE_SUMMARIZE_PROMPT, ) print( 标准问答模板 ) # .template 属性获取提示词模板对象的原始字符串本体 # 模板作用Stuff 响应模式的核心问答模板是查询引擎最基础、最常用的默认模板 # 工作机制将检索召回的所有文档上下文一次性全部填入提示词让大模型基于完整上下文一次性生成回答 # 特点逻辑简单、回答连贯性好适合上下文窗口充足、检索结果数量少的场景 # 内置固定占位符框架自动填充自定义时必须保留 # - {context_str}检索召回的全部上下文文档内容 # - {query_str}用户的原始查询问题 print(DEFAULT_TEXT_QA_PROMPT.template) print(\n 迭代优化答案模板 ) # 模板作用Refine精炼响应模式的核心提示词 # 工作机制逐个串行处理检索到的文档块而非一次性全部塞入上下文 # 1. 先用第一个文档块生成初始回答 # 2. 依次将后续每个新文档块 上一轮的已有回答一起传给大模型 # 3. 让大模型基于新的上下文补充、修正、优化已有答案逐轮迭代得到最终结果 # 适用场景检索结果多、模型上下文窗口不足以一次性放下所有内容的场景 # 内置固定占位符 # - {existing_answer}上一轮迭代生成的当前回答 # - {context_msg}当前新拿到的单段上下文文档内容 # - {query_str}用户的原始查询问题 print(DEFAULT_REFINE_PROMPT.template) print(\n 总结模板 ) # 模板作用单段文本总结的默认提示词主要供 SummaryIndex摘要索引使用 # 工作机制对单段独立文本进行概括提炼生成对应摘要 # 适用场景文档入库时生成片段摘要、长文本分段总结等纯总结场景 # 内置固定占位符 # - {context_str}待总结的原始文本内容 print(DEFAULT_SUMMARY_PROMPT.template) print(\n 树状总结模板 ) # 模板作用Tree Summarize树状总结响应模式的核心提示词 # 工作机制分层递归式合并总结自底向上生成最终答案 # 1. 先将所有检索到的文档块分批每批生成一个小总结 # 2. 再将多个小总结继续分批合并生成更大层级的总结 # 3. 层层递归合并直到最终生成一个完整的总回答 # 适用场景长文档、大量检索结果的场景相比 Refine 合并效率更高、更节省上下文 # 内置固定占位符 # - {context_str}当前批次待合并的多段总结/上下文内容 # - {query_str}用户的原始查询问题 print(DEFAULT_TREE_SUMMARIZE_PROMPT.template)