我们在开发智能问答系统时,常常面临这样的挑战:如何让提示词既能灵活适配多轮对话,又能支持图像、音频等丰富内容?LlamaIndex 在 0.12.27 版本中推出的 RichPromptTemplate,正是解决这些问题的「瑞士军刀」。它基于 Jinja 语法,让我们可以用统一的方式构建包含变量、聊天角色、多模态内容甚至循环逻辑的复杂提示。今天我们就来看看如何用它打造「会说话的提示词」。

一、基础能力:从变量注入到聊天角色定义

1.1 变量插入:让提示「活起来」

RichPromptTemplate 最基础的能力是通过{{ }}语法注入动态变量。相比传统的 f-string 模板,它使用双括号避免了与 Python 原生字符串的冲突,同时支持更复杂的表达式。

python

运行

from llama_index.core.prompts import RichPromptTemplate
# 基础问候模板
greeting_prompt = RichPromptTemplate("你好,{{ name }}!今天想了解什么内容?")
# 格式化为文本提示
print(greeting_prompt.format(name="小明"))  # 输出:你好,小明!今天想了解什么内容?
# 格式化为聊天消息(自动识别用户角色)
messages = greeting_prompt.format_messages(name="小明")

1.2 聊天模板:一键生成多角色对话

通过{% chat %}块语法,我们可以在单个模板中定义系统提示、用户消息等不同角色的内容,这对构建聊天机器人非常关键。

python

运行

chat_template = RichPromptTemplate("""
{% chat role="system" %}
你是一位历史老师,擅长用生动案例讲解知识点
{% endchat %}
{% chat role="user" %}
{{ question }}
{% endchat %}
""")
# 生成包含系统提示和用户问题的聊天消息列表
messages = chat_template.format_messages(question="拿破仑的滑铁卢战役为何失败?")

输出效果

plaintext

[
  SystemMessage: 你是一位历史老师,擅长用生动案例讲解知识点,
  UserMessage: 拿破仑的滑铁卢战役为何失败?
]

二、多模态支持:让提示「有声有色」

当 LLM 支持多模态输入时(如 GPT-4o),RichPromptTemplate 可以直接在提示中嵌入图像、音频等内容,通过| image| audio过滤器标识特殊内容类型。

2.1 图像描述场景

python

运行

from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-4o-mini", api_key="your-key")
# 定义图像提示模板
image_prompt = RichPromptTemplate("""
请描述以下图片内容:
{{ image_path | image }}
""")
# 加载图片并生成消息
messages = image_prompt.format_messages(image_path="./dice.png")
response = llm.chat(messages)
print(response.content)  # 输出:画面中三个白色骰子位于方格木板上...(自动解析图像内容)

2.2 音频分析场景

python

运行

# 定义音频提示模板
audio_prompt = RichPromptTemplate("""
分析以下音频的历史背景:
{{ audio_path | audio }}
""")
messages = audio_prompt.format_messages(audio_path="./moon_landing.wav")
response = llm.chat(messages, model="gpt-4o-audio-preview")
print(response.content)  # 输出:音频中是阿波罗11号登月时的著名讲话...

注意事项

  • 图像路径会自动转换为 Base64 编码嵌入提示(需确保文件路径正确)
  • 音频支持需模型明确支持(如 gpt-4o-audio-preview),否则会被视为普通文本

三、高级技巧:循环处理与对象解析

当需要处理列表数据(如多轮对话历史、批量图片文本对)时,Jinja 的循环语法能大幅简化代码。

3.1 批量生成图文混合提示

python

运行

# 定义包含文本和图像的列表
media_list = [
    ("第一个实验结果", "./exp1.png"),
    ("第二个实验对比", "./exp2.png"),
]
# 使用{% for %}循环生成多块内容
media_prompt = RichPromptTemplate("""
{% for text, img_path in media_list %}
【内容】:{{ text }}
【图像】:{{ img_path | image }}
{% endfor %}
""")
messages = media_prompt.format_messages(media_list=media_list)

渲染结果

plaintext

- 内容:第一个实验结果
  图像:<Base64编码的PNG数据>
- 内容:第二个实验对比
  图像:<Base64编码的PNG数据>

3.2 对象解析与动态结构

通过 Jinja 的变量表达式,还可以直接解析对象属性,这对处理结构化数据(如 JSON)非常有用。

python

运行

from dataclasses import dataclass

@dataclass
class Product:
    name: str
    price: float

product = Product("Llama 2 Book", 49.99)
# 在模板中直接访问对象属性
shop_prompt = RichPromptTemplate("商品:{{ item.name }},价格:{{ item.price | currency }}元")
# 注册自定义过滤器(如货币格式化)
shop_prompt.env.filters["currency"] = lambda x: f"{x:.2f}"
print(shop_prompt.format(item=product))  # 输出:商品:Llama 2 Book,价格:49.99元

四、实战建议:从调试到落地的关键要点

  1. 模型兼容性测试

    • 多模态功能需确认 LLM 支持(如 gpt-4o 系列),普通模型会忽略| image等过滤器
    • 使用llm.metadata.context_window检查模型上下文限制,避免多模态内容超限
  2. 调试技巧

    • 先用format()生成纯文本提示,确认变量逻辑无误后再转多模态
    • 通过print(messages[0].blocks)查看渲染后的块结构,确保图像 / 音频路径正确解析
  3. 性能优化

    • 批量处理时优先使用format_messages()一次性生成所有块,减少 API 调用次数
    • 对重复使用的模板,可通过partial_format()预填充公共变量(如系统角色描述)

总结:重新定义提示词的「表达边界」

RichPromptTemplate 的出现,让提示词从简单的文本模板升级为支持多模态交互、复杂逻辑的智能载体。无论是构建聊天机器人的对话流程,还是开发支持图文分析的智能报告系统,它都能让我们用更简洁的代码实现更丰富的交互逻辑。

如果本文对你有帮助,别忘了点赞收藏,关注我,一起探索更高效的开发方式~

更多推荐