promptbuilder.mdx
  1  ---
  2  title: "PromptBuilder"
  3  id: promptbuilder
  4  slug: "/promptbuilder"
  5  description: "Use this component in pipelines before a Generator to render a prompt template and fill in variable values."
  6  ---
  7  
  8  # PromptBuilder
  9  
 10  Use this component in pipelines before a Generator to render a prompt template and fill in variable values.
 11  
 12  <div className="key-value-table">
 13  
 14  |  |  |
 15  | --- | --- |
 16  | **Most common position in a pipeline** | In a querying pipeline, before a [Generator](../generators.mdx)                                                                      |
 17  | **Mandatory init variables**           | `template`: A prompt template string that uses Jinja2 syntax                                                                        |
 18  | **Mandatory run variables**            | `**kwargs`: Any strings that should be used to render the prompt template. See [Variables](#variables)  section for more details. |
 19  | **Output variables**                   | `prompt`: A string that represents the rendered prompt template                                                                     |
 20  | **API reference**                      | [Builders](/reference/builders-api)                                                                                                        |
 21  | **GitHub link**                        | https://github.com/deepset-ai/haystack/blob/main/haystack/components/builders/prompt_builder.py                                   |
 22  
 23  </div>
 24  
 25  ## Overview
 26  
 27  `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`.
 28  
 29  The template that is provided to the `PromptBuilder` during initialization needs to conform to the [Jinja2](https://palletsprojects.com/p/jinja/) template language.
 30  
 31  ### Variables
 32  
 33  The template variables found in the init template are used as input types for the component. If there are no `required_variables` set, all variables are considered optional by default. In this case, any missing variables are replaced with empty strings, which can lead to unintended behavior, especially in complex pipelines.
 34  
 35  Use `required_variables` and `variables` to specify the input types and required variables:
 36  
 37  - `required_variables`
 38    - Defines which template variables must be provided when the component runs.
 39    - If any required variable is missing, the component raises an error and halts execution.
 40    - You can:
 41      - Pass a list of required variable names (such as `["query"]`), or
 42      - Use `"*"` to mark all variables in the template as required.
 43  
 44  - `variables`
 45    - Lists all variables that can appear in the template, whether required or optional.
 46    - Optional variables that aren't provided are replaced with an empty string in the rendered prompt.
 47    - This allows partial prompts to be constructed without errors, unless a variable is marked as required.
 48  
 49  ```python
 50  from haystack.components.builders import PromptBuilder
 51  
 52  ## All variables optional (default to empty string)
 53  builder = PromptBuilder(
 54      template="Hello {{name}}! {{greeting}}",
 55      required_variables=[],  # or omit this parameter entirely
 56  )
 57  
 58  ## Some variables required
 59  builder = PromptBuilder(
 60      template="Hello {{name}}! {{greeting}}",
 61      required_variables=["name"],  # 'greeting' remains optional
 62  )
 63  ```
 64  
 65  The component only waits for the required inputs before running.
 66  
 67  ### Jinja2 Time Extension
 68  
 69  `PromptBuilder` supports the Jinja2 TimeExtension, which allows you to work with datetime formats.
 70  
 71  The Time Extension provides two main features:
 72  
 73  1. A `now` tag that gives you access to the current time,
 74  2. Date/time formatting capabilities through Python's datetime module.
 75  
 76  To use the Jinja2 TimeExtension, you need to install a dependency with:
 77  
 78  ```shell
 79  pip install arrow>=1.3.0
 80  ```
 81  
 82  #### The `now` Tag
 83  
 84  The `now` tag creates a datetime object representing the current time, which you can then store in a variable:
 85  
 86  ```jinja2
 87  {% now 'utc' as current_time %}
 88  The current UTC time is: {{ current_time }}
 89  ```
 90  
 91  You can specify different timezones:
 92  
 93  ```jinja2
 94  {% now 'America/New_York' as ny_time %}
 95  The time in New York is: {{ ny_time }}
 96  ```
 97  
 98  If you don't specify a timezone, your system's local timezone will be used:
 99  
100  ```jinja2
101  {% now as local_time %}
102  Local time: {{ local_time }}
103  ```
104  
105  #### Date Formatting
106  
107  You can format the datetime objects using Python's `strftime` syntax:
108  
109  ```jinja2
110  {% now as current_time %}
111  Formatted date: {{ current_time.strftime('%Y-%m-%d %H:%M:%S') }}
112  ```
113  
114  The common format codes are:
115  
116  - `%Y`: 4-digit year (for example, 2025)
117  - `%m`: Month as a zero-padded number (01-12)
118  - `%d`: Day as a zero-padded number (01-31)
119  - `%H`: Hour (24-hour clock) as a zero-padded number (00-23)
120  - `%M`: Minute as a zero-padded number (00-59)
121  - `%S`: Second as a zero-padded number (00-59)
122  
123  #### Example
124  
125  ```python
126  from haystack.components.builders import PromptBuilder
127  
128  ## Define template using Jinja-style formatting
129  template = """
130  Current date is: {% now 'UTC' %}
131  Thank you for providing the date
132  Yesterday was: {% now 'UTC' - 'days=1' %}
133  """
134  
135  builder = PromptBuilder(template=template)
136  
137  result = builder.run()["prompt"]
138  ```
139  
140  ## Usage
141  
142  ### On its own
143  
144  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:`.
145  
146  ```python
147  from haystack.components.builders import PromptBuilder
148  
149  template = "Translate the following context to {{ target_language }}. Context: {{ snippet }}; Translation:"
150  builder = PromptBuilder(template=template)
151  builder.run(target_language="spanish", snippet="I can't speak spanish.")
152  ```
153  
154  ### In a pipeline
155  
156  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.
157  
158  ```python
159  from haystack import Pipeline, Document
160  from haystack.utils import Secret
161  from haystack.components.generators import OpenAIGenerator
162  from haystack.components.builders.prompt_builder import PromptBuilder
163  
164  ## in a real world use case documents could come from a retriever, web, or any other source
165  documents = [
166      Document(content="Joe lives in Berlin"),
167      Document(content="Joe is a software engineer"),
168  ]
169  prompt_template = """
170      Given these documents, answer the question.\nDocuments:
171      {% for doc in documents %}
172          {{ doc.content }}
173      {% endfor %}
174  
175      \nQuestion: {{query}}
176      \nAnswer:
177      """
178  p = Pipeline()
179  p.add_component(instance=PromptBuilder(template=prompt_template), name="prompt_builder")
180  p.add_component(
181      instance=OpenAIGenerator(api_key=Secret.from_env_var("OPENAI_API_KEY")),
182      name="llm",
183  )
184  p.connect("prompt_builder", "llm")
185  
186  question = "Where does Joe live?"
187  result = p.run({"prompt_builder": {"documents": documents, "query": question}})
188  print(result)
189  ```
190  
191  #### Changing the template at runtime (Prompt Engineering)
192  
193  `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:
194  
195  ```python
196  documents = [
197      Document(content="Joe lives in Berlin", meta={"name": "doc1"}),
198      Document(content="Joe is a software engineer", meta={"name": "doc1"}),
199  ]
200  new_template = """
201      You are a helpful assistant.
202      Given these documents, answer the question.
203      Documents:
204      {% for doc in documents %}
205          Document {{ loop.index }}:
206          Document name: {{ doc.meta['name'] }}
207          {{ doc.content }}
208      {% endfor %}
209  
210      Question: {{ query }}
211      Answer:
212      """
213  p.run(
214      {
215          "prompt_builder": {
216              "documents": documents,
217              "query": question,
218              "template": new_template,
219          },
220      },
221  )
222  ```
223  
224  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.
225  
226  #### Overwriting variables at runtime
227  
228  In case you want to overwrite the values of variables, you can use `template_variables` during runtime, as shown below:
229  
230  ```python
231  language_template = """
232      You are a helpful assistant.
233      Given these documents, answer the question.
234      Documents:
235      {% for doc in documents %}
236          Document {{ loop.index }}:
237          Document name: {{ doc.meta['name'] }}
238          {{ doc.content }}
239      {% endfor %}
240  
241      Question: {{ query }}
242      Please provide your answer in {{ answer_language | default('English') }}
243      Answer:
244      """
245  p.run(
246      {
247          "prompt_builder": {
248              "documents": documents,
249              "query": question,
250              "template": language_template,
251              "template_variables": {"answer_language": "German"},
252          },
253      },
254  )
255  ```
256  
257  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".
258  The `template_variables` allows you to overwrite pipeline variables (such as documents) as well.
259  
260  ## Additional References
261  
262  🧑‍🍳 Cookbooks:
263  
264  - [Advanced Prompt Customization for Anthropic](https://haystack.deepset.ai/cookbook/prompt_customization_for_anthropic)
265  - [Prompt Optimization with DSPy](https://haystack.deepset.ai/cookbook/prompt_optimization_with_dspy)