DocumentationAPI Reference📓 Tutorials🧑‍🍳 Cookbook🤝 Integrations💜 Discord🎨 Studio (Waitlist)
Documentation

PromptBuilder

Use this component in pipelines before a Generator to render a prompt template and fill in variable values.

Most common position in a pipelineIn a querying pipeline, before a Generator
Mandatory init variables"template": A prompt template string that uses Jinja2 syntax
Mandatory run variables“**kwargs”: Any strings that should be used to render the prompt template
Output variables“prompt”: A string that represents the rendered prompt template
API referenceBuilders
GitHub linkhttps://github.com/deepset-ai/haystack/blob/main/haystack/components/builders/prompt_builder.py

Overview

PromptBuilder is initialized with a prompt template and renders it by filling in parameters passed through keyword arguments, kwargs. With kwargs, you can pass a variable number of keyword arguments so that any variable used in the prompt template can be specified with the desired value. Values for all variables appearing in the prompt template need to be provided through the kwargs.

The template that is provided to the PromptBuilder during initialization needs to conform to the Jinja2 template language.

Usage

On its own

Below is an example of using the PromptBuilder to render a prompt template and fill it with target_language and snippet. The PromptBuilder returns a prompt with the string Translate the following context to spanish. Context: I can't speak spanish.; Translation:.

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

In a pipeline

Below is an example of a RAG pipeline where we use a PromptBuilder to render a custom prompt template and fill it with the contents of retrieved documents and a query. The rendered prompt is then sent to a 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)

Changing the template at runtime (Prompt Engineering)

PromptBuilder allows you to switch the prompt template of an existing pipeline. The example below builds on top of the existing pipeline in the previous section. We are invoking the existing pipeline with a new prompt template:

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,
      },
  })

If you want to use different variables during prompt engineering than in the default template, you can do so by setting PromptBuilder's variables init parameter accordingly.

Overwriting variables at runtime

In case you want to overwrite the values of variables, you can use template_variables during runtime, as shown below:

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

Note that language_template introduces answer_language variable which is not bound to any pipeline variable. If not set otherwise, it would use its default value, "English". In this example, we overwrite its value to "German".
The template_variables allows you to overwrite pipeline variables (such as documents) as well.

Additional References

🧑‍🍳 Cookbooks: