Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Deepset ai Haystack ChatPromptBuilder

From Leeroopedia

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 SandboxedEnvironment for secure template rendering.
  • haystack.dataclasses.chat_message: Provides ChatMessage, ChatRole, and TextContent.
  • haystack.utils.jinja2_chat_extension: Provides ChatMessageExtension for the {% message %} block tag and templatize_part filter.
  • 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 ChatMessage objects with Jinja2 syntax in their text content.
    • A string using {% message role="..." %} block tags.
    • None if the template will be provided at runtime.
  • required_variables (list[str] | Literal["*"] | None): Variables that must be provided at runtime. If set to "*", all template variables are required. Defaults to None (all variables optional).
  • variables (list[str] | None): Explicit list of input variables instead of those inferred from the template.

Initialization Behavior

  • Creates a SandboxedEnvironment with the ChatMessageExtension Jinja2 extension and registers the templatize_part filter.
  • Optionally adds Jinja2TimeExtension if the arrow package is available.
  • Extracts template variables from user and system messages in the template (assistant messages are not scanned for variables).
  • Validates that the templatize_part filter 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 of ChatMessage objects.

Behavior

  1. Merges kwargs with template_variables (template_variables take precedence).
  2. Falls back to the initialization template if no runtime template is provided.
  3. Raises ValueError if no template is available or if the template list contains non-ChatMessage elements.
  4. 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.
  5. For string templates:
    • Renders the full template string, then parses the output into ChatMessage objects by deserializing each line as JSON.
  6. Validates that all required variables are present; raises ValueError if 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