Implementation:Deepset ai Haystack ChatPromptBuilder
Appearance
Overview
ChatPromptBuilder is a Haystack component that renders chat prompt templates into lists of ChatMessage objects using Jinja2 syntax. It supports both list-of-ChatMessage templates and string templates with role-tagged message blocks, enabling structured multi-turn conversation prompts for chat-based LLMs.
Source Location
- File:
haystack/components/builders/chat_prompt_builder.py(Lines 33-360) - Class:
ChatPromptBuilder - Component decorator:
@component
Import
from haystack.components.builders import ChatPromptBuilder
Dependencies
- jinja2: Provides
SandboxedEnvironmentfor secure template rendering. - haystack.dataclasses.chat_message: Provides
ChatMessage,ChatRole, andTextContent. - haystack.utils.jinja2_chat_extension: Provides
ChatMessageExtensionfor the{% message %}block tag andtemplatize_partfilter. - arrow (optional): Enables time-related template functions via
Jinja2TimeExtension.
Constructor
def __init__(
self,
template: list[ChatMessage] | str | None = None,
required_variables: list[str] | Literal["*"] | None = None,
variables: list[str] | None = None,
)
Parameters
- template (
list[ChatMessage] | str | None): The template for rendering chat prompts. Can be:- A list of
ChatMessageobjects with Jinja2 syntax in their text content. - A string using
{% message role="..." %}block tags. Noneif the template will be provided at runtime.
- A list of
- required_variables (
list[str] | Literal["*"] | None): Variables that must be provided at runtime. If set to"*", all template variables are required. Defaults toNone(all variables optional). - variables (
list[str] | None): Explicit list of input variables instead of those inferred from the template.
Initialization Behavior
- Creates a
SandboxedEnvironmentwith theChatMessageExtensionJinja2 extension and registers thetemplatize_partfilter. - Optionally adds
Jinja2TimeExtensionif thearrowpackage is available. - Extracts template variables from user and system messages in the template (assistant messages are not scanned for variables).
- Validates that the
templatize_partfilter is not used in list-of-ChatMessage templates (it is only supported in string templates). - Registers each variable as a component input, with required variables having no default and optional variables defaulting to
"".
Run Method
@component.output_types(prompt=list[ChatMessage])
def run(
self,
template: list[ChatMessage] | str | None = None,
template_variables: dict[str, Any] | None = None,
**kwargs,
) -> dict: # Returns {"prompt": list[ChatMessage]}
Parameters
- template (
list[ChatMessage] | str | None): Optional template to override the default for this invocation. - template_variables (
dict | None): Optional dictionary of variables that overwrite pipeline-provided kwargs. - **kwargs: Pipeline variables used for rendering.
Returns
{"prompt": list[ChatMessage]}: A dictionary containing the rendered list ofChatMessageobjects.
Behavior
- Merges
kwargswithtemplate_variables(template_variables take precedence). - Falls back to the initialization template if no runtime template is provided.
- Raises
ValueErrorif no template is available or if the template list contains non-ChatMessage elements. - For list-of-ChatMessage templates:
- Iterates over each message. For user and system messages, renders Jinja2 variables in the text content. Assistant messages are passed through unmodified.
- Creates deep copies of messages to avoid mutating the original template objects.
- For string templates:
- Renders the full template string, then parses the output into
ChatMessageobjects by deserializing each line as JSON.
- Renders the full template string, then parses the output into
- Validates that all required variables are present; raises
ValueErrorif any are missing.
Serialization
def to_dict(self) -> dict[str, Any]
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "ChatPromptBuilder"
Supports full serialization and deserialization. When serializing, list-of-ChatMessage templates are converted to dictionaries via ChatMessage.to_dict(). When deserializing, they are reconstructed via ChatMessage.from_dict().
Usage Examples
Static ChatMessage Template
from haystack.components.builders import ChatPromptBuilder
from haystack.dataclasses import ChatMessage
template = [ChatMessage.from_user("Translate to {{ target_language }}. Context: {{ snippet }}; Translation:")]
builder = ChatPromptBuilder(template=template)
result = builder.run(target_language="spanish", snippet="I can't speak spanish.")
# result["prompt"] is a list with one ChatMessage containing the rendered text
Dynamic Template in a Pipeline
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack import Pipeline
prompt_builder = ChatPromptBuilder()
llm = OpenAIChatGenerator(model="gpt-5-mini")
pipe = Pipeline()
pipe.add_component("prompt_builder", prompt_builder)
pipe.add_component("llm", llm)
pipe.connect("prompt_builder.prompt", "llm.messages")
location = "Berlin"
language = "English"
system_message = ChatMessage.from_system("You are an assistant giving information to tourists in {{ language }}")
messages = [system_message, ChatMessage.from_user("Tell me about {{ location }}")]
res = pipe.run(data={
"prompt_builder": {
"template_variables": {"location": location, "language": language},
"template": messages,
}
})
String Template with Image Content
from haystack.components.builders import ChatPromptBuilder
from haystack.dataclasses.image_content import ImageContent
template = """
{% message role="system" %}
You are a helpful assistant.
{% endmessage %}
{% message role="user" %}
Hello! I am {{ user_name }}. What's the difference between the following images?
{% for image in images %}
{{ image | templatize_part }}
{% endfor %}
{% endmessage %}
"""
images = [
ImageContent.from_file_path("path/to/image1.jpg"),
ImageContent.from_file_path("path/to/image2.png"),
]
builder = ChatPromptBuilder(template=template)
result = builder.run(user_name="John", images=images)
Related Pages
Page Connections
Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment