Pipeline
pipeline
PipelineStreamHandle
Handle returned by Pipeline.stream().
Async-iterable over StreamingChunks produced by streaming components in the pipeline. After iteration ends,
result holds the final pipeline output dict.
By default, iteration cleans up automatically: if the consumer abandons iteration, the underlying pipeline task is
cancelled. aclose() is also available for explicit cleanup.
result
Final pipeline output dict, available only after a successful, complete run.
Raises a RuntimeError if the pipeline has not finished or was cancelled. If the pipeline failed, re-raises the
original exception.
aclose
Cancel the underlying pipeline task.
Bounded by _CLEANUP_TIMEOUT_SECONDS so that components cannot block cleanup indefinitely.
Pipeline
Bases: PipelineBase
Orchestration engine that runs components according to the execution graph.
Supports both a synchronous run path (run) and an asynchronous run path
(run_async, run_async_generator, stream).
run
run(
data: dict[str, Any],
include_outputs_from: set[str] | None = None,
*,
break_point: Breakpoint | None = None,
pipeline_snapshot: PipelineSnapshot | None = None,
snapshot_callback: SnapshotCallback | None = None
) -> dict[str, Any]
Runs the Pipeline with given input data.
run executes synchronously and blocks the calling thread until the run completes. In an async context,
use run_async instead.
Usage:
from haystack import Pipeline, Document
from haystack.components.builders.answer_builder import AnswerBuilder
from haystack.components.builders.chat_prompt_builder import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.dataclasses import ChatMessage
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.utils import Secret
# Write documents to InMemoryDocumentStore
document_store = InMemoryDocumentStore()
document_store.write_documents([
Document(content="My name is Jean and I live in Paris."),
Document(content="My name is Mark and I live in Berlin."),
Document(content="My name is Giorgio and I live in Rome.")
])
retriever = InMemoryBM25Retriever(document_store=document_store)
prompt_template = """
Given these documents, answer the question.
Documents:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
Question: {{question}}
Answer:
"""
template = [ChatMessage.from_user(prompt_template)]
prompt_builder = ChatPromptBuilder(
template=template,
required_variables=["question", "documents"],
variables=["question", "documents"]
)
llm = OpenAIChatGenerator()
rag_pipeline = Pipeline()
rag_pipeline.add_component("retriever", retriever)
rag_pipeline.add_component("prompt_builder", prompt_builder)
rag_pipeline.add_component("llm", llm)
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
question = "Who lives in Paris?"
results = rag_pipeline.run(
{
"retriever": {"query": question},
"prompt_builder": {"question": question},
}
)
print(results["llm"]["replies"][0].text)
# Jean lives in Paris
Parameters:
- data (
dict[str, Any]) – A dictionary of inputs for the pipeline's components. Each key is a component name and its value is a dictionary of that component's input parameters:
data = {
"comp1": {"input1": 1, "input2": 2},
}
For convenience, this format is also supported when input names are unique:
data = {
"input1": 1, "input2": 2,
}
- include_outputs_from (
set[str] | None) – Set of component names whose individual outputs are to be included in the pipeline's output. For components that are invoked multiple times (in a loop), only the last-produced output is included. - break_point (
Breakpoint | None) – A breakpoint that pauses execution before the specified component runs by raising aBreakpointExceptioncarrying aPipelineSnapshotof the current pipeline state. - pipeline_snapshot (
PipelineSnapshot | None) – A snapshot of a previously interrupted pipeline execution to resume from. Can be combined withbreak_pointto step through a pipeline: resume from the snapshot and pause again at the next breakpoint. Thebreak_pointmust target a different component or visit count than the one the snapshot was created at, otherwise it would trigger again before any progress is made. - snapshot_callback (
SnapshotCallback | None) – Optional callback function that is invoked when a pipeline snapshot is created. The callback receives aPipelineSnapshotobject and can return an optional string (e.g., a file path or identifier). If provided, the callback is used instead of the default file-saving behavior, allowing custom handling of snapshots (e.g., saving to a database, sending to a remote service). If not provided, the default behavior saves snapshots to a JSON file.
Returns:
dict[str, Any]– A dictionary where each entry corresponds to a component name and its output. Ifinclude_outputs_fromisNone, this dictionary will only contain the outputs of leaf components, i.e., components without outgoing connections.
Raises:
ValueError– If invalid inputs are provided to the pipeline.PipelineRuntimeError– If the Pipeline contains cycles with unsupported connections that would cause it to get stuck and fail running. Or if a Component fails or returns output in an unsupported type.PipelineMaxComponentRuns– If a Component reaches the maximum number of times it can be run in this Pipeline.PipelineBreakpointException– When a pipeline_breakpoint is triggered. Contains the component name, state, and partial results.
run_async_generator
run_async_generator(
data: dict[str, Any],
include_outputs_from: set[str] | None = None,
concurrency_limit: int = 4,
) -> AsyncGenerator[dict[str, Any], None]
Executes the pipeline step by step asynchronously, yielding partial outputs when any component finishes.
Usage:
from haystack import Document
from haystack.components.builders import ChatPromptBuilder
from haystack.dataclasses import ChatMessage
from haystack.utils import Secret
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.builders.prompt_builder import PromptBuilder
from haystack import Pipeline
import asyncio
# Write documents to InMemoryDocumentStore
document_store = InMemoryDocumentStore()
document_store.write_documents([
Document(content="My name is Jean and I live in Paris."),
Document(content="My name is Mark and I live in Berlin."),
Document(content="My name is Giorgio and I live in Rome.")
])
prompt_template = [
ChatMessage.from_user(
'''
Given these documents, answer the question.
Documents:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
Question: {{question}}
Answer:
''')
]
# Create and connect pipeline components
retriever = InMemoryBM25Retriever(document_store=document_store)
prompt_builder = ChatPromptBuilder(template=prompt_template)
llm = OpenAIChatGenerator()
rag_pipeline = Pipeline()
rag_pipeline.add_component("retriever", retriever)
rag_pipeline.add_component("prompt_builder", prompt_builder)
rag_pipeline.add_component("llm", llm)
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
# Prepare input data
question = "Who lives in Paris?"
data = {
"retriever": {"query": question},
"prompt_builder": {"question": question},
}
# Process results as they become available
async def process_results():
async for partial_output in rag_pipeline.run_async_generator(
data=data,
include_outputs_from={"retriever", "llm"}
):
# Each partial_output contains the results from a completed component
if "retriever" in partial_output:
print("Retrieved documents:", len(partial_output["retriever"]["documents"]))
if "llm" in partial_output:
print("Generated answer:", partial_output["llm"]["replies"][0])
asyncio.run(process_results())
Parameters:
- data (
dict[str, Any]) – Initial input data to the pipeline. - concurrency_limit (
int) – The maximum number of components that are allowed to run concurrently. - include_outputs_from (
set[str] | None) – Set of component names whose individual outputs are to be included in the pipeline's output. For components that are invoked multiple times (in a loop), only the last-produced output is included.
Returns:
AsyncGenerator[dict[str, Any], None]– An async iterator containing partial (and final) outputs.
Raises:
ValueError– If invalid inputs are provided to the pipeline, or ifconcurrency_limitis less than 1.PipelineMaxComponentRuns– If a component exceeds the maximum number of allowed executions within the pipeline.PipelineRuntimeError– If the Pipeline contains cycles with unsupported connections that would cause it to get stuck and fail running. Or if a Component fails or returns output in an unsupported type.
run_async
run_async(
data: dict[str, Any],
include_outputs_from: set[str] | None = None,
concurrency_limit: int = 4,
) -> dict[str, Any]
Provides an asynchronous interface to run the pipeline with provided input data.
This method allows the pipeline to be integrated into an asynchronous workflow, enabling non-blocking execution of pipeline components.
Usage:
import asyncio
from haystack import Document
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack import Pipeline
from haystack.dataclasses import ChatMessage
from haystack.document_stores.in_memory import InMemoryDocumentStore
# Write documents to InMemoryDocumentStore
document_store = InMemoryDocumentStore()
document_store.write_documents([
Document(content="My name is Jean and I live in Paris."),
Document(content="My name is Mark and I live in Berlin."),
Document(content="My name is Giorgio and I live in Rome.")
])
prompt_template = [
ChatMessage.from_user(
'''
Given these documents, answer the question.
Documents:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
Question: {{question}}
Answer:
''')
]
retriever = InMemoryBM25Retriever(document_store=document_store)
prompt_builder = ChatPromptBuilder(template=prompt_template)
llm = OpenAIChatGenerator()
rag_pipeline = Pipeline()
rag_pipeline.add_component("retriever", retriever)
rag_pipeline.add_component("prompt_builder", prompt_builder)
rag_pipeline.add_component("llm", llm)
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
# Ask a question
question = "Who lives in Paris?"
async def run_inner(data, include_outputs_from):
return await rag_pipeline.run_async(data=data, include_outputs_from=include_outputs_from)
data = {
"retriever": {"query": question},
"prompt_builder": {"question": question},
}
results = asyncio.run(run_inner(data, include_outputs_from={"retriever", "llm"}))
print(results["llm"]["replies"])
# [ChatMessage(_role=<ChatRole.ASSISTANT: 'assistant'>, _content=[TextContent(text='Jean lives in Paris.')],
# _name=None, _meta={'model': 'gpt-5-mini', 'index': 0, 'finish_reason': 'stop', 'usage':
# {'completion_tokens': 6, 'prompt_tokens': 69, 'total_tokens': 75,
# 'completion_tokens_details': CompletionTokensDetails(accepted_prediction_tokens=0,
# audio_tokens=0, reasoning_tokens=0, rejected_prediction_tokens=0), 'prompt_tokens_details':
# PromptTokensDetails(audio_tokens=0, cached_tokens=0)}})]
Parameters:
- data (
dict[str, Any]) – A dictionary of inputs for the pipeline's components. Each key is a component name and its value is a dictionary of that component's input parameters:
data = {
"comp1": {"input1": 1, "input2": 2},
}
For convenience, this format is also supported when input names are unique:
data = {
"input1": 1, "input2": 2,
}
- include_outputs_from (
set[str] | None) – Set of component names whose individual outputs are to be included in the pipeline's output. For components that are invoked multiple times (in a loop), only the last-produced output is included. - concurrency_limit (
int) – The maximum number of components that should be allowed to run concurrently.
Returns:
dict[str, Any]– A dictionary where each entry corresponds to a component name and its output. Ifinclude_outputs_fromisNone, this dictionary will only contain the outputs of leaf components, i.e., components without outgoing connections.
Raises:
ValueError– If invalid inputs are provided to the pipeline, or ifconcurrency_limitis less than 1.PipelineRuntimeError– If the Pipeline contains cycles with unsupported connections that would cause it to get stuck and fail running. Or if a Component fails or returns output in an unsupported type.PipelineMaxComponentRuns– If a Component reaches the maximum number of times it can be run in this Pipeline.
stream
stream(
data: dict[str, Any],
*,
streaming_components: list[str] | None = None,
include_outputs_from: set[str] | None = None,
concurrency_limit: int = 4,
cancel_on_abandon: bool = True
) -> PipelineStreamHandle
Run the pipeline and return a handle that streams StreamingChunks as they arrive.
Iterate the handle with async for to consume chunks; after iteration ends, handle.result holds the final
pipeline output dict (same as run_async). By default, if iteration is abandoned, the underlying pipeline task
is cancelled automatically. Pass cancel_on_abandon=False to instead let the pipeline run to completion.
For every async-capable component that exposes a streaming_callback input socket, a forwarder is injected at
runtime that pushes chunks onto the handle's queue. If a streaming_callback is provided at component init or
at runtime (inside data, e.g. data={"llm": {"streaming_callback": cb}}), it is also invoked for each chunk.
Async callbacks are preferred; a sync callback is accepted but will run synchronously on the event loop and
may block it.
Usage:
import asyncio
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack import Pipeline
from haystack.dataclasses import ChatMessage
pipe = Pipeline()
pipe.add_component(
"prompt_builder",
ChatPromptBuilder(template=[ChatMessage.from_user("Tell me about {{topic}}")]),
)
pipe.add_component("llm", OpenAIChatGenerator())
pipe.connect("prompt_builder.prompt", "llm.messages")
async def main():
handle = pipe.stream(data={"prompt_builder": {"topic": "Italy"}})
async for chunk in handle:
print(chunk.content, end="", flush=True)
return handle.result
result = asyncio.run(main())
print(result["llm"]["replies"])
Parameters:
- data (
dict[str, Any]) – A dictionary of inputs for the pipeline's components. Each key is a component name and its value is a dictionary of that component's input parameters:
data = {
"comp1": {"input1": 1, "input2": 2},
}
For convenience, this format is also supported when input names are unique:
data = {
"input1": 1, "input2": 2,
}
- streaming_components (
list[str] | None) – Names of components to stream from. IfNone(default), every streaming-capable component is forwarded. If a list, only the listed components are forwarded; unknown names or names of components that do not support streaming raiseValueError. - include_outputs_from (
set[str] | None) – Set of component names whose individual outputs are to be included in the pipeline's output. For components that are invoked multiple times (in a loop), only the last-produced output is included. - concurrency_limit (
int) – The maximum number of components that should be allowed to run concurrently. - cancel_on_abandon (
bool) – IfTrue(default), the underlying pipeline task is cancelled when iteration is abandoned. IfFalse, the pipeline runs to completion even when the consumer stops reading.
Returns:
PipelineStreamHandle– APipelineStreamHandlethat is async-iterable overStreamingChunks. After iteration ends,handle.resultholds the final pipeline output dict (same shape asrun_async).
Raises:
ValueError– Ifstreaming_componentscontains unknown component names or components that do not support streaming, or if invalid inputs are provided to the pipeline, or ifconcurrency_limitis less than 1.PipelineRuntimeError– Surfaced during iteration. If the Pipeline contains cycles with unsupported connections that would cause it to get stuck and fail running, or if a Component fails or returns output in an unsupported type.PipelineMaxComponentRuns– Surfaced during iteration. If a Component reaches the maximum number of times it can be run in this Pipeline.