OutputAdapter
Adapt the output of components using Jinja2 templates to connect components with different input or output types.
With smart connections, the pipeline automatically converts between String and ChatMessage in both directions. If you're using OutputAdapter just for this type conversion, you can remove it. For details, see Simplify Your Pipelines with Smart Connections.
Key Features
- Uses Jinja2 templates to transform component output into the expected input type of the next component
- Infers input variable names directly from the variables used in the template
- Supports custom Jinja2 filters for advanced transformations
- Safely restricts output to standard Python types by default
- Enables
unsafemode for using custom types such asChatMessage,Document, orAnswer - Works with any pair of components whose output and input types need bridging
Configuration
- Drag the
OutputAdaptercomponent onto the canvas from the Component Library. - Click the component to open the configuration panel.
- On the General tab:
- Enter the Jinja2 template that defines how to transform the input data. The variable names in the template determine the component's input names. For example,
{{ replies[0] }}makesrepliesan input. - Enter the output type as a Python type string, such as
strorList[haystack.Document].
- Enter the Jinja2 template that defines how to transform the input data. The variable names in the template determine the component's input names. For example,
- Go to the Advanced tab to configure
custom_filtersandunsafeif needed.
Connections
OutputAdapter accepts any inputs that match the variables used in the template. It outputs the adapted value in the type specified by output_type. It can connect to any component whose output type doesn't directly match the next component's input type. For details and examples, see the Incompatible Connection Types section.
Unsafe Setting
OutputAdapter renders the template using Jinja2, and by default, this is the safe behavior (safe: True). Safe behavior limits the allowed output types to strings, bytes, numbers, tuples, lists, dictionaries, sets, booleans, None, and Ellipsis (...) and their combinations. To use other types such as ChatMessage, Document, or Answer, set unsafe to True.
Use this setting with caution as it may lead to remote code execution.
Usage Example
Using the Component in a Pipeline
This is an example of a RAG chat pipeline where OutputAdapter converts LLM's replies into a single string that other components can accept.
components:
chat_summary_prompt_builder:
type: haystack.components.builders.prompt_builder.PromptBuilder
init_parameters:
template: |-
You are part of a chatbot.
You receive a question (Current Question) and a chat history.
Use the context from the chat history and reformulate the question so that it is suitable for retrieval augmented generation.
If X is followed by Y, only ask for Y and do not repeat X again.
If the question does not require any context from the chat history, output it unedited.
Don't make questions too long, but short and precise.
Stay as close as possible to the current question.
Only output the new question, nothing else!
{{ question }}
New question:
chat_summary_llm:
type: haystack.components.generators.openai.OpenAIGenerator
init_parameters:
api_key: {"type": "env_var", "env_vars": ["OPENAI_API_KEY"], "strict": False}
model: "gpt-4o"
generation_kwargs:
max_tokens: 650
temperature: 0.0
seed: 0
replies_to_query:
type: haystack.components.converters.output_adapter.OutputAdapter
init_parameters:
template: "{{ replies[0] }}"
output_type: str
bm25_retriever: # Selects the most similar documents from the document store
type: haystack_integrations.components.retrievers.opensearch.bm25_retriever.OpenSearchBM25Retriever
init_parameters:
document_store:
type: haystack_integrations.document_stores.opensearch.document_store.OpenSearchDocumentStore
init_parameters:
use_ssl: True
verify_certs: False
hosts:
- ${OPENSEARCH_HOST}
http_auth:
- "${OPENSEARCH_USER}"
- "${OPENSEARCH_PASSWORD}"
embedding_dim: 768
similarity: cosine
top_k: 20 # The number of results to return
query_embedder:
type: haystack.components.embedders.sentence_transformers_text_embedder.SentenceTransformersTextEmbedder
init_parameters:
model: "intfloat/e5-base-v2"
embedding_retriever: # Selects the most similar documents from the document store
type: haystack_integrations.components.retrievers.opensearch.embedding_retriever.OpenSearchEmbeddingRetriever
init_parameters:
document_store:
type: haystack_integrations.document_stores.opensearch.document_store.OpenSearchDocumentStore
init_parameters:
use_ssl: True
verify_certs: False
hosts:
- ${OPENSEARCH_HOST}
http_auth:
- "${OPENSEARCH_USER}"
- "${OPENSEARCH_PASSWORD}"
embedding_dim: 768
similarity: cosine
top_k: 20 # The number of results to return
document_joiner:
type: haystack.components.joiners.document_joiner.DocumentJoiner
init_parameters:
join_mode: concatenate
ranker:
type: haystack.components.rankers.transformers_similarity.TransformersSimilarityRanker
init_parameters:
model: "intfloat/simlm-msmarco-reranker"
top_k: 8
model_kwargs:
torch_dtype: "torch.float16"
qa_prompt_builder:
type: haystack.components.builders.prompt_builder.PromptBuilder
init_parameters:
template: |-
You are a technical expert.
You answer questions truthfully based on provided documents.
Ignore typing errors in the question.
For each document check whether it is related to the question.
Only use documents that are related to the question to answer it.
Ignore documents that are not related to the question.
If the answer exists in several documents, summarize them.
Only answer based on the documents provided. Don't make things up.
Just output the structured, informative and precise answer and nothing else.
If the documents can't answer the question, say so.
Always use references in the form [NUMBER OF DOCUMENT] when using information from a document, e.g. [3] for Document[3].
Never name the documents, only enter a number in square brackets as a reference.
The reference must only refer to the number that comes in square brackets after the document.
Otherwise, do not use brackets in your answer and reference ONLY the number of the document without mentioning the word document.
These are the documents:
{% for document in documents %}
Document[{{ loop.index }}]:
{{ document.content }}
{% endfor %}
Question: {{ question }}
Answer:
qa_llm:
type: haystack.components.generators.openai.OpenAIGenerator
init_parameters:
api_key: {"type": "env_var", "env_vars": ["OPENAI_API_KEY"], "strict": False}
model: "gpt-4o"
generation_kwargs:
max_tokens: 650
temperature: 0.0
seed: 0
answer_builder:
type: deepset_cloud_custom_nodes.augmenters.deepset_answer_builder.DeepsetAnswerBuilder
init_parameters:
reference_pattern: acm
connections: # Defines how the components are connected
- sender: chat_summary_prompt_builder.prompt
receiver: chat_summary_llm.prompt
- sender: chat_summary_llm.replies
receiver: replies_to_query.replies
- sender: replies_to_query.output
receiver: bm25_retriever.query
- sender: replies_to_query.output
receiver: query_embedder.text
- sender: replies_to_query.output
receiver: ranker.query
- sender: replies_to_query.output
receiver: qa_prompt_builder.question
- sender: replies_to_query.output
receiver: answer_builder.query
- sender: bm25_retriever.documents
receiver: document_joiner.documents
- sender: query_embedder.embedding
receiver: embedding_retriever.query_embedding
- sender: embedding_retriever.documents
receiver: document_joiner.documents
- sender: document_joiner.documents
receiver: ranker.documents
- sender: ranker.documents
receiver: qa_prompt_builder.documents
- sender: ranker.documents
receiver: answer_builder.documents
- sender: qa_prompt_builder.prompt
receiver: qa_llm.prompt
- sender: qa_prompt_builder.prompt
receiver: answer_builder.prompt
- sender: qa_llm.replies
receiver: answer_builder.replies
inputs: # Define the inputs for your pipeline
query: # These components will receive the query as input
- "chat_summary_prompt_builder.question"
filters: # These components will receive a potential query filter as input
- "bm25_retriever.filters"
- "embedding_retriever.filters"
outputs: # Defines the output of your pipeline
documents: "ranker.documents" # The output of the pipeline is the retrieved documents
answers: "answer_builder.answers" # The output of the pipeline is the generated answers
Parameters
Inputs
Input names and types depend on how you configure the template parameter.
| Parameter | Type | Default | Description |
|---|---|---|---|
| kwargs | Any | Must contain all variables used in the template string. |
Outputs
The output depends on the value of the output_type parameter.
Init Parameters
These are the parameters you can configure in Pipeline Builder:
| Parameter | Type | Default | Description |
|---|---|---|---|
| template | str | A Jinja2 template that defines how to adapt the input data. The variables in the template define the input of this instance. For example, with this template: {{ documents[0].content }} the component input will be documents. | |
| output_type | TypeAlias | The type of output this instance should return. | |
| custom_filters | Optional[Dict[str, Callable]] | None | A dictionary of custom Jinja2 filters used in the template. |
| unsafe | bool | False | Enable execution of arbitrary code in the Jinja2 template. This should only be used if you trust the source of the template as it can lead to remote code execution. |
Run Method Parameters
These are the parameters you can configure for the component's run() method. This means you can pass these parameters at query time through the API, in Playground, or when running a job. For details, see Modify Pipeline Parameters at Query Time.
| Parameter | Type | Default | Description |
|---|---|---|---|
| kwargs | Any | Must contain all variables used in the template string. |
Was this page helpful?