文档API 参考📓 教程🧑‍🍳 食谱🤝 集成💜 Discord🎨 Studio
文档

PromptBuilder

在 Generator 之前,在管道中使用此组件来渲染提示模板并填充变量值。

pipeline 中的最常见位置在查询管道中,在 Generator 之前
必需的初始化变量"template": 使用 Jinja2 语法的提示模板字符串
强制运行变量“**kwargs”:用于渲染提示模板的任何字符串。有关更多详细信息,请参阅变量部分。
输出变量“prompt”:表示渲染后的提示模板的字符串
API 参考Builders (构建器)
GitHub 链接https://github.com/deepset-ai/haystack/blob/main/haystack/components/builders/prompt_builder.py

概述

PromptBuilder 使用提示模板进行初始化,并通过填充通过关键字参数传递的参数来渲染它,kwargs。使用kwargs,您可以传递可变数量的关键字参数,以便提示模板中使用的任何变量都可以指定所需的值。提示模板中出现的所有变量的值都需要通过kwargs.

在初始化时提供给PromptBuilder 的模板需要符合Jinja2 模板语言。

变量

初始化模板中找到的模板变量用作组件的输入类型。如果没有设置required_variables,则默认情况下所有变量都被视为可选。在这种情况下,任何缺失的变量都将替换为空字符串,这可能导致意外行为,尤其是在复杂的管道中。

使用required_variablesvariables 用于指定输入类型和必需变量

  • required_variables

    • 定义在组件运行时必须提供的模板变量。
    • 如果缺少任何必需变量,组件将引发错误并停止执行。
    • 您可以
      • 传递必需变量名的列表(例如["query"]),或者
      • 使用"*" 将模板中的所有变量标记为必需。
  • variables

    • 列出模板中可能出现的所有变量,无论必需还是可选。
    • 未提供的可选变量将在渲染的提示中替换为空字符串。
    • 这允许在不引发错误的情况下构建部分提示,除非变量被标记为必需。
from haystack.components.builders import PromptBuilder

# All variables optional (default to empty string)
builder = PromptBuilder(
    template="Hello {{name}}! {{greeting}}",
    required_variables=[]  # or omit this parameter entirely
)

# Some variables required
builder = PromptBuilder(
    template="Hello {{name}}! {{greeting}}",
    required_variables=["name"]  # 'greeting' remains optional
)

组件在运行时只等待必需的输入。

Jinja2 时间扩展

PromptBuilder 支持 Jinja2 TimeExtension,它允许您使用日期时间格式。

Time Extension 提供了两个主要功能:

  1. 一个now 标签,让您可以访问当前时间,
  2. 通过 Python 的 datetime 模块进行日期/时间格式化功能。

要使用 Jinja2 TimeExtension,您需要安装一个依赖项,使用

pip install arrow>=1.3.0

now 标签

now 标签创建一个表示当前时间的 datetime 对象,然后您可以将其存储在变量中

{% now 'utc' as current_time %}
The current UTC time is: {{ current_time }}

您可以指定不同的时区

{% now 'America/New_York' as ny_time %}
The time in New York is: {{ ny_time }}

如果您不指定时区,将使用您系统的本地时区

{% now as local_time %}
Local time: {{ local_time }}

日期格式化

您可以使用 Python 的strftime 语法格式化 datetime 对象

{% now as current_time %}
Formatted date: {{ current_time.strftime('%Y-%m-%d %H:%M:%S') }}

常见的格式代码是:

  • %Y:4 位年份(例如,2025)
  • %m:月份(01-12)
  • %d:日期(01-31)
  • %H:小时(24 小时制,00-23)
  • %M:分钟(00-59)
  • %S:秒(00-59)

示例

from haystack.components.builders import PromptBuilder

# Define template using Jinja-style formatting
template = """
Current date is: {% now 'UTC' %}
Thank you for providing the date
Yesterday was: {% now 'UTC' - 'days=1' %}
"""

builder = PromptBuilder(template=template)

result = builder.run()["prompt"]

now = f"Current date is: {arrow.now('UTC').strftime('%Y-%m-%d %H:%M:%S')}"
yesterday = f"Yesterday was: {(arrow.now('UTC').shift(days=-1)).strftime('%Y-%m-%d %H:%M:%S')}"

用法

单独使用

以下是使用PromptBuilder 渲染提示模板并填充target_languagesnippet 的示例。PromptBuilder 返回一个包含字符串的提示:将以下上下文翻译成西班牙语。上下文:我不会说西班牙语;翻译.

from haystack.components.builders import PromptBuilder

template = "Translate the following context to {{ target_language }}. Context: {{ snippet }}; Translation:"
builder = PromptBuilder(template=template)
builder.run(target_language="spanish", snippet="I can't speak spanish.")

在 pipeline 中

下面是一个 RAG 管道的示例,我们在其中使用PromptBuilder 来渲染自定义提示模板,并用检索到的文档的内容和查询来填充它。然后将渲染后的提示发送给 Generator。

from haystack import Pipeline, Document
from haystack.utils import Secret
from haystack.components.generators import OpenAIGenerator
from haystack.components.builders.prompt_builder import PromptBuilder

# in a real world use case documents could come from a retriever, web, or any other source
documents = [Document(content="Joe lives in Berlin"), Document(content="Joe is a software engineer")]
prompt_template = """
    Given these documents, answer the question.\nDocuments:
    {% for doc in documents %}
        {{ doc.content }}
    {% endfor %}

    \nQuestion: {{query}}
    \nAnswer:
    """
p = Pipeline()
p.add_component(instance=PromptBuilder(template=prompt_template), name="prompt_builder")
p.add_component(instance=OpenAIGenerator(api_key=Secret.from_env_var("OPENAI_API_KEY")), name="llm")
p.connect("prompt_builder", "llm")

question = "Where does Joe live?"
result = p.run({"prompt_builder": {"documents": documents, "query": question}})
print(result)

运行时更改模板(提示工程)

PromptBuilder 允许您切换现有管道的提示模板。下面的示例基于上一节中的现有管道。我们使用新的提示模板调用现有管道,

documents = [
    Document(content="Joe lives in Berlin", meta={"name": "doc1"}), 
    Document(content="Joe is a software engineer", meta={"name": "doc1"}),
]
new_template = """
    You are a helpful assistant.
    Given these documents, answer the question.
    Documents:
    {% for doc in documents %}
        Document {{ loop.index }}:
        Document name: {{ doc.meta['name'] }}
        {{ doc.content }}
    {% endfor %}

    Question: {{ query }}
    Answer:
    """
p.run({
      "prompt_builder": {
          "documents": documents, 
          "query": question, 
          "template": new_template,
      },
  })

如果您希望在提示工程中使用与默认模板不同的变量,可以通过设置PromptBuilder 的变量初始化参数来实现。

运行时覆盖变量

如果您想覆盖变量的值,可以在运行时使用template_variables,如下所示:

language_template = """
    You are a helpful assistant.
    Given these documents, answer the question.
    Documents:
    {% for doc in documents %}
        Document {{ loop.index }}:
        Document name: {{ doc.meta['name'] }}
        {{ doc.content }}
    {% endfor %}

    Question: {{ query }}
    Please provide your answer in {{ answer_language | default('English') }}
    Answer:
    """
p.run({
      "prompt_builder": {
          "documents": documents, 
          "query": question, 
          "template": language_template, 
          "template_variables": {"answer_language": "German"},
      },
  })

请注意,language_template 引入了answer_language 变量,该变量未绑定到任何管道变量。如果未另行设置,它将使用其默认值“English”。在此示例中,我们将它的值覆盖为“German”。
template_variables 允许您覆盖管道变量(例如文档)。

其他参考资料

🧑‍🍳食谱