Doramagic Project Pack · Human Manual

haystack

Open-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.

Haystack Overview and Core Concepts

Related topics: Pipeline Design, Execution, and Debugging, Retrieval, Document Stores, and Preprocessing, LLM Generators, Agents, and Tool Ecosystem

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Pipeline Design, Execution, and Debugging, Retrieval, Document Stores, and Preprocessing, LLM Generators, Agents, and Tool Ecosystem

Haystack Overview and Core Concepts

What is Haystack?

Haystack is an open-source, end-to-end framework for building production-ready applications powered by Large Language Models (LLMs), transformer models, and vector search. The project is positioned as a model- and vendor-agnostic AI orchestration layer that supports retrieval-augmented generation (RAG), multimodal pipelines, semantic search, question answering, and autonomous agents in a single transparent architecture. Source: README.md:1-5

The framework is distributed on PyPI as haystack-ai and the recommended installation path is pip install haystack-ai, with pip install --pre haystack-ai available for nightly builds. Alternative installation methods, including Docker images derived from haystack:base-<version>, are documented for production deployments. Source: README.md:23-37, docker/README.md:5-10

The framework's design goals, as stated in the README, include:

Design PillarDescription
Built for context engineeringExplicit control over retrieval, ranking, filtering, combining, structuring, and routing before reaching the model.
Model- and vendor-agnosticIntegrations with OpenAI, Mistral, Anthropic, Cohere, Hugging Face, Azure OpenAI, AWS Bedrock, and local models.
Modular and customizableBuilt-in components for retrieval, indexing, tool calling, memory, and evaluation, with hooks for loops, branches, and conditional logic.
Extensible ecosystemCustom components share a consistent interface for community and third-party extensions.

Source: README.md:53-69

Core Architecture and Abstractions

Haystack is structured around a small set of composable abstractions. The primary building blocks are Components, Pipelines, Documents, and Document Stores. A Pipeline is a directed graph of Components, where each Component declares typed input and output sockets. The framework supports both indexing and query pipelines, and more recently, agent-style loops that combine tool execution with generation.

flowchart LR
    User[User / API Caller] --> Pipeline
    Pipeline --> C1[Component A]
    Pipeline --> C2[Component B]
    C1 --> C3[Component C]
    C2 --> C3
    C3 --> Store[Document Store]
    Store --> Retriever
    Retriever --> Generator[Generator / Agent]
    Generator --> Out[Response]

    classDef ext fill:#eef,stroke:#446;
    class Pipeline,Store,Retriever,Generator ext;

The agent abstraction is one of the most recent generalizations. An Agent accepts a list of Tool or Toolset objects, a system prompt (which may be a plain string or a Jinja2 string template), an optional user prompt template, and a list of exit_conditions that control when the agent terminates its loop. The agent also exposes a state_schema dictionary where each key maps to a type config containing a required "type" and an optional "handler" for merging values across tool calls. Tools can read from and write to state keys using inputs_from_state and outputs_to_state. Source: haystack/components/agents/agent.py:1-50

Documentation, API Reference, and Examples

Haystack's documentation is published to https://docs.haystack.deepset.ai and is generated by a Docusaurus 3 site located in docs-website/. The site uses two independent instances of @docusaurus/plugin-content-docs so that the conceptual guides (served at /docs/) and the API reference (served at /reference/) can version independently. A custom remark plugin, src/remark/versionedReferenceLinks.js, automatically rewrites cross-links between docs and reference so that readers stay in the same version context (for example, rewriting /reference/some-api to /reference/2.19/some-api when viewing docs version 2.19). Source: docs-website/README.md:55-100

The API reference is auto-generated from source-code docstrings using haystack-pydoc-tools. A docusaurus_sync.yml GitHub workflow regenerates reference pages whenever the code changes, and updates land in the unstable docs version before being promoted to a stable version during a release. New API pages are introduced by adding a .yml file under pydoc/. Source: pydoc/README.md:1-15

Standalone code examples and cookbooks have been moved out of the main repository into a dedicated haystack-cookbook repository, leaving the main repo focused on the framework, its components, and its documentation. Source: examples/README.md:1-5

The site also exposes a concatenated llms.txt file (generated by the docusaurus-plugin-generate-llms-txt plugin) that LLM-based tools can consume as a single text snapshot of the documentation. A custom plugins/txtLoaderPlugin.js configures Webpack to treat .txt files as text assets so the file does not break the build. Source: docs-website/README.md:115-130

Recent Evolution and Community-Driven Concerns

The v2.x line of releases has steadily expanded Haystack's surface area while keeping the core abstractions stable. The v2.27.0 release introduced automatic list joining in pipelines, where components that expect a list as input now accept multiple compatible inputs (for example, a plain query string plus a list of ChatMessage objects) without requiring an extra joining component. The v2.28.0 release migrated internal HTTP utilities from requests to httpx, which changes the exception type raised by request_with_retry and async_request_with_retry from requests.exceptions.RequestException to httpx.HTTPError, and also affects HuggingFaceTEIRanker. The v2.29.0 release added MultiRetriever and TextEmbeddingRetriever for hybrid search, with MultiRetriever merging results via reciprocal rank fusion by default. The v2.30.0 release introduced PythonCodeSplitter, a syntax-aware code splitter that uses Python's ast module to preserve structural context for code-RAG and code-search pipelines. Source: Release notes v2.27.0, Release notes v2.28.0, Release notes v2.29.0, Release notes v2.30.0

Several community-reported concerns shape the roadmap and reflect how users actually exercise the framework:

  • Deterministic document identity. Issue #11445 highlights that Document.id should be a content fingerprint but in practice depends on the insertion order of keys in the metadata dictionary, so two semantically identical Document objects can end up with different IDs and silently break deduplication. Source: Issue #11445
  • Async tool execution. Issue #9580 reports a RuntimeWarning: coroutine ... was never awaited when a tool defined with an async def method is invoked by the agent, indicating gaps in how async tools are scheduled. Source: Issue #9580
  • Pipeline debugging via breakpoints. Issue #8972 proposes adding breakpoints to the new pipeline run logic, allowing users to set breakpoints, execute up to a breakpoint, save checkpoints, and register callbacks, while Issue #9466 asks to extend the same breakpointing architecture to SuperComponent and Agent internals. Source: Issue #8972, Issue #9466
  • Structured outputs. Issue #8276 requests first-class support for OpenAI's structured outputs (.parse-style), which is also being adopted by other LLM providers. Source: Issue #8276
  • Async streaming callbacks. Issue #7231 asks for streaming_callback on chat generators to accept async functions, which matters for backend services built with FastAPI or similar ASGI frameworks. Source: Issue #7231

These discussions, together with the release history, indicate that the core abstractions (Components, Pipelines, Documents, Document Stores, Agents, and Tools) are stable, while execution semantics, async support, and developer ergonomics are the primary areas of active change.

See Also

Source: https://github.com/deepset-ai/haystack / Human Manual

Pipeline Design, Execution, and Debugging

Related topics: Haystack Overview and Core Concepts, Retrieval, Document Stores, and Preprocessing, LLM Generators, Agents, and Tool Ecosystem

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Smart connections and automatic list joining

Continue reading this section for the full explanation and source context.

Section Loops and conditional routing

Continue reading this section for the full explanation and source context.

Section Async tools and the "coroutine was never awaited" trap

Continue reading this section for the full explanation and source context.

Related topics: Haystack Overview and Core Concepts, Retrieval, Document Stores, and Preprocessing, LLM Generators, Agents, and Tool Ecosystem

Pipeline Design, Execution, and Debugging

A Haystack Pipeline is a directed graph of components that transforms inputs into outputs. Designing a pipeline means choosing components and wiring their sockets; executing it means invoking pipeline.run() or pipeline.run_async(); debugging it means using breakpoints, dry runs, and careful inspection of component state. This page covers all three concerns, with emphasis on the patterns that most often come up in community discussions.

1. Designing a Pipeline

A pipeline is built by adding components to a Pipeline instance and connecting their typed sockets. Each component exposes typed input and output sockets, and Haystack validates compatibility at connect() time. Source: docs-website/docs/concepts/pipelines/creating-pipelines.mdx.

The simplest design pattern is linear: comp_a.connect(comp_b). Branching and merging are also first-class — a component can receive inputs from multiple predecessors. Source: docs-website/docs/concepts/pipelines.mdx.

Smart connections and automatic list joining

Since v2.27.0, when a component expects a list as input, the pipeline automatically joins multiple upstream outputs into that list, even if they arrive as different but compatible types (for example, a plain str query alongside a list of ChatMessage objects). This removes the need for explicit joiner components. Source: docs-website/docs/concepts/pipelines/smart-pipeline-connections.mdx.

from haystack import Pipeline
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator

pipe = Pipeline()
pipe.add_component("builder", ChatPromptBuilder(template=...))
pipe.add_component("llm", OpenAIChatGenerator())
pipe.connect("builder.prompt", "llm.messages")

Loops and conditional routing

Pipeline supports cyclical graphs through Variadic and conditional senders. Loops are useful for agent-style flows where a generator decides whether to call another component. The Variadic type is the conventional way to express "zero or more" connections. Source: docs-website/docs/concepts/pipelines/pipeline-loops.mdx.

flowchart LR
    A[Retriever] --> B[PromptBuilder]
    B --> C[ChatGenerator]
    C -- tool_call --> D[ToolInvoker]
    D -- result --> B
    C -- final_answer --> E[Output]

2. Execution: Sync and Async

Pipelines have two execution entry points. pipeline.run(data) runs synchronously; pipeline.run_async(data) runs components concurrently whenever they are independent. Async execution is the recommended path for I/O-bound pipelines that fan out to multiple retrievers or generators. Source: docs-website/docs/concepts/pipelines/asyncpipeline.mdx.

result = await pipe.run_async({"builder": {"question": query}})

Async tools and the "coroutine was never awaited" trap

A common community failure is wrapping a coroutine in a custom Tool and then seeing RuntimeWarning: coroutine '...' was never awaited. The fix is to make the tool's invoke method itself async and await the underlying coroutine, then return a serialized result. The Agent component invokes tools through the ToolInvoker, which does support async tools when they are declared correctly. Source: haystack/components/agents/agent.py; community discussion: issue #9580.

Streaming callbacks

streaming_callback on chat generators is invoked synchronously from the generator's stream loop. Community requests (issue #7231) have asked for async streaming callbacks so that FastAPI servers can stream tokens without blocking the event loop. The current pattern is to push tokens from the sync callback onto an asyncio.Queue from the surrounding async task.

3. Debugging with Breakpoints

Breakpoints were introduced to make the new run logic inspectable. A breakpoint can be set on a component's input or output socket and will pause execution before or after that socket fires. While paused, the user can inspect intermediate state, mutate it, and resume. Source: docs-website/docs/concepts/pipelines/pipeline-breakpoints.mdx.

from haystack.dataclasses.breakpoints import Breakpoint
pipe.run(data={"builder": {"question": query}},
         breakpoints={("llm", "messages"): Breakpoint()})

Use cases that motivated the feature include:

  • Stepping through a long RAG pipeline to find where a Document gets dropped (community issue #8761 — chunk positioning after recursive splitting).
  • Replaying from a checkpoint when an LLM call fails transiently.
  • Hooking a callback on a breakpoint to log or assert intermediate state.

An open community request (issue #9466) asks to extend breakpoints into the internals of SuperComponent and Agent. Because those wrap inner pipelines, breakpointing them requires propagating the breakpoint map through the wrapper's run boundary, which is still an exploratory area. Source: haystack/components/agents/agent.py.

4. Common Failure Modes

SymptomLikely causeReference
PipelineConnectError at connect()Incompatible socket typescreating-pipelines.mdx
RuntimeWarning: coroutine was never awaitedAsync tool's invoke is not async defagent.py; issue #9580
Same content, different Document.idmeta dict iteration order affects the hashissue #11445
requests.exceptions.RequestException after upgradeHTTP utilities moved from requests to httpxrelease v2.28.0
Branching query yields wrong top-kInputs not joined into a list before the next stagesmart-pipeline-connections.mdx

The Document.id issue (#11445) is particularly subtle: two Document objects built with the same meta but different key insertion orders produced different IDs, silently breaking deduplication in document stores. The fix made the ID computation order-independent, so the same logical document always hashes to the same ID regardless of how meta was assembled. Source: issue #11445.

See Also

Source: https://github.com/deepset-ai/haystack / Human Manual

Retrieval, Document Stores, and Preprocessing

Related topics: Haystack Overview and Core Concepts, Pipeline Design, Execution, and Debugging, LLM Generators, Agents, and Tool Ecosystem

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Metadata Filtering

Continue reading this section for the full explanation and source context.

Section DocumentCleaner

Continue reading this section for the full explanation and source context.

Section RecursiveSplitter

Continue reading this section for the full explanation and source context.

Related topics: Haystack Overview and Core Concepts, Pipeline Design, Execution, and Debugging, LLM Generators, Agents, and Tool Ecosystem

Retrieval, Document Stores, and Preprocessing

Overview

Haystack's retrieval, document storage, and preprocessing layers form the indexing-and-query backbone of any RAG, semantic search, or agentic application built on the framework. The main README.md frames Haystack as a system "built for context engineering" where users have "explicit control over how information is retrieved, ranked, filtered, combined, structured, and routed before it reaches the model." Source: README.md:25-29. The three concerns covered on this page — how raw input becomes clean Document objects, how those documents are persisted and queried, and how top-k results are produced at runtime — sit between the file/source connectors and the chat generators.

The official API reference for these subsystems is generated by haystack-pydoc-tools from Python docstrings and is regenerated by a GitHub workflow on every code change. Source: pydoc/README.md:3-9. The conceptual and how-to guides that complement that reference live under docs-website/docs/concepts/document-store/ and docs-website/docs/pipeline-components/preprocessors/.

Document Stores

A document store is the persistence layer that owns Document records, supports vector and/or lexical indexes, and exposes a query interface. The choosing-a-document-store guide is the entry point for picking among them; integrations themselves (Elasticsearch, OpenSearch, Weaviate, Qdrant, Pinecone, Chroma, Milvus, Neo4j, etc.) live in the separate haystack-core-integrations repository, so swapping backends is largely a configuration concern rather than a code change. Source: docs-website/docs/concepts/document-store/choosing-a-document-store.mdx:1-40.

Every Document carries a deterministic id derived from its content and metadata, and community issue #11445 tracks a fix so the hash is stable regardless of meta key insertion order — important because "two Documents with the same content and the same metadata can end up with different IDs depending on how the meta dict was built, which silently breaks deduplication." Source: docs-website/docs/concepts/metadata-filtering.mdx:1-30.

Metadata Filtering

Filtering on metadata at query time is described in metadata-filtering.mdx. Filters are expressed as comparison operators over the meta payload that was attached at indexing time, and they compose with vector or BM25 retrieval so that top-k results are constrained to documents matching the predicate. The same document's id determinism guarantee ensures that re-ingestion of identical content does not create duplicate store entries that would bypass filters. Source: docs-website/docs/concepts/metadata-filtering.mdx:1-50.

Preprocessing Components

Before a document reaches a store or retriever, it usually passes through one or more components in haystack.components.preprocessors. The preprocessors.mdx index page catalogs them, and three are particularly central.

DocumentCleaner

DocumentCleaner removes extraneous whitespace, unicode artifacts, repeated lines, and other noise that pollutes embeddings and BM25 scoring. Its parameters (e.g., remove_empty_lines, remove_repeated_substrings, keep_id) are documented on its component page. The cleaner is what makes downstream splitting predictable, and community issue #8761 highlights a related pain point: after cleaning and recursive splitting, chunk position information is needed to "navigate and highlight them in a PDF" — the cleaner should therefore be used in a way that preserves or recomputes offsets. Source: docs-website/docs/pipeline-components/preprocessors/documentcleaner.mdx:1-40.

RecursiveSplitter

RecursiveSplitter chunks documents by recursively walking a hierarchy of separators (paragraphs, sentences, words) until each chunk fits a target length. It is the default choice for prose-heavy corpora. Like DocumentCleaner, its output needs to retain the original span so the chunks can be mapped back to their source document — a recurring community requirement. Source: docs-website/docs/pipeline-components/preprocessors/recursivesplitter.mdx:1-40.

PythonCodeSplitter

Introduced in v2.30.0, PythonCodeSplitter is "a syntax-aware splitter for Python source files, built for code-RAG and code-search pipelines where naive line-based splitting tends to cut through functions and lose structural context. It parses sources with the ast module and greedily merges units." Source: docs-website/docs/pipeline-components/preprocessors/pythoncodesplitter.mdx:1-30. It complements the prose-oriented splitters for code corpora.

End-to-End Flow and Retrievers

A typical indexing-then-query pipeline chains converters → DocumentCleaner → splitter → embedder → document store, and a query pipeline chains a retriever (optionally a ranker) → prompt builder → generator. The data flow is:

flowchart LR
    A[Raw files / APIs] --> B[Converter to Document]
    B --> C[DocumentCleaner]
    C --> D[RecursiveSplitter / PythonCodeSplitter]
    D --> E[Embedder]
    E --> F[(Document Store)]
    F --> G[Retriever + Metadata Filter]
    G --> H[Ranker]
    H --> I[Prompt Builder / Agent]
    I --> J[Chat Generator]

v2.29.0 expanded the retriever toolbox with MultiRetriever, which "runs multiple text retrievers in parallel and merges their results into a single deduplicated list, ranked by reciprocal rank fusion by default," and TextEmbeddingRetriever for embedding-based lookup. Source: docs-website/docs/concepts/document-store/choosing-a-document-store.mdx:1-40.

Common Failure Modes and Community Workarounds

  • Non-deterministic Document.id: addressed by the fix tracked in issue #11445; users who built custom deduplication on id should re-validate after upgrading. Source: docs-website/docs/concepts/metadata-filtering.mdx:1-30.
  • Lost chunk position after splitting: track and propagate the meta offsets that the splitter writes so UI layers can highlight the source span, as raised in #8761. Source: docs-website/docs/pipeline-components/preprocessors/recursivesplitter.mdx:1-40.
  • Multiple retrievers, no canonical answer: the historical "Finder" only wrapped a single retriever plus a single reader (issue #544); the modern MultiRetriever plus the super_component agent pattern replaces this pattern. Source: docs-website/docs/concepts/document-store/choosing-a-document-store.mdx:1-40.
  • Indexing as an ongoing process: issue #8508 asks for first-class "ongoing" indexing pipelines that synchronize a source folder to the store; the current pattern is a long-running converter → cleaner → splitter → writer loop. Source: docs-website/docs/pipeline-components/preprocessors.mdx:1-40.
  • Sync-only streaming callbacks: issue #7231 notes that streaming_callback does not support async functions; the workaround is to schedule the coroutine from a sync wrapper until the callback signature is updated. Source: docs-website/docs/pipeline-components/preprocessors.mdx:1-40.

See Also

Source: https://github.com/deepset-ai/haystack / Human Manual

LLM Generators, Agents, and Tool Ecosystem

Related topics: Haystack Overview and Core Concepts, Pipeline Design, Execution, and Debugging, Retrieval, Document Stores, and Preprocessing

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Function Calling and Structured Outputs

Continue reading this section for the full explanation and source context.

Section Async Tool Invocation

Continue reading this section for the full explanation and source context.

Section Human-in-the-Loop and Confirmation Strategies

Continue reading this section for the full explanation and source context.

Related topics: Haystack Overview and Core Concepts, Pipeline Design, Execution, and Debugging, Retrieval, Document Stores, and Preprocessing

LLM Generators, Agents, and Tool Ecosystem

Purpose and Scope

Haystack's LLM Generators, Agents, and Tool Ecosystem form the generation half of the framework. Generators are components that call a language model to produce text or chat completions; Agents wrap a chat generator in a tool-calling loop; and the Tool ecosystem (tools, Toolset, ToolInvoker, and confirmation strategies) gives the agent access to external functions, retrievers, and sub-pipelines. Together, they implement the "model- and vendor-agnostic", "modular and customizable" principles described in the top-level README.md, while remaining transparently inspectable inside Haystack pipelines (Source: README.md).

Generators remain a thin abstraction over an underlying model provider. Agents and Tools are the higher-level building blocks used when the model needs to decide, in multiple steps, which capabilities to invoke before producing a final answer (Source: docs-website/docs/concepts/agents.mdx).

Generators

Generators are the leaf components that actually call an LLM. Haystack ships two families, exposed in the documentation at docs-website/docs/pipeline-components/generators.mdx:

FamilyTypical inputsTypical outputsStreaming support
Text generators (OpenAIGenerator, HuggingFaceAPIGenerator, etc.)A prompt stringA single replies list of stringsVia streaming_callback
Chat generators (OpenAIChatGenerator, AnthropicChatGenerator, AzureOpenAIChatGenerator, etc.)A list of ChatMessage objectsA list of ChatMessage replies, optionally with tool_callsVia streaming_callback

All chat generators implement a uniform run(messages, ...) interface. The Agent component inspects this signature to detect whether the supplied chat_generator supports the tools parameter, storing the boolean in _chat_generator_supports_tools (Source: haystack/components/agents/agent.py).

Function Calling and Structured Outputs

Function calling is the bridge from text generation to the Tool ecosystem. When a chat generator's underlying provider supports tool/function calls, the model can return a ChatMessage whose tool_calls field is non-empty. The documentation at docs-website/docs/pipeline-components/generators/guides-to-generators/function-calling.mdx shows that the typical pattern is to:

  1. Define a tool schema and pass it to the generator through generation_kwargs or a dedicated tools parameter.
  2. Let the model return tool_calls rather than free-form text.
  3. Route the tool_calls to a ToolInvoker to execute them and feed the results back as ChatMessage(tool_result=...) messages.

Community issue #8276 tracks the long-standing request to enable OpenAI's structured-output mode (using .parse rather than .tools) directly on Haystack generators, which is currently only available for selected models and via custom generation_kwargs (Source: docs-website/docs/pipeline-components/generators/guides-to-generators/function-calling.mdx).

A related and recurring gap is async streaming callbacks: issue #7231 notes that streaming_callback does not yet support async def callbacks, which is a limitation for FastAPI/ASGI deployments that want to stream tokens through an event loop.

Agents

The Agent component (haystack/components/agents/agent.py) implements a stateful, tool-calling loop on top of a chat generator. Its constructor accepts:

  • chat_generator — any chat generator that exposes a run(messages, ...) method.
  • tools — a list of Tool and/or Toolset, or a single Toolset.
  • system_prompt and user_prompt — strings or Jinja2 templates.
  • state_schema — a dict of typed state slots with optional merge handlers.
  • exit_conditions — e.g. ["text"] or specific tool names; defaults to ["text"].
  • max_agent_steps — caps the loop to prevent runaway tool calls (defaults to 100).
  • streaming_callback, raise_on_tool_invocation_failure, tool_invoker_kwargs, confirmation_strategies.

At each step the agent:

  1. Renders system and user prompts.
  2. Calls the chat generator, possibly with tools.
  3. If the response contains tool_calls, hands them to the ToolInvoker.
  4. Appends tool results to the message history.
  5. Loops until an exit_condition is met or max_agent_steps is reached.

The runtime behavior, including break_point, snapshot, and snapshot_callback, is documented in the constructor docstring and at docs-website/docs/pipeline-components/agents-1/agent.mdx. Snapshots are the foundation for pipeline breakpoints (community issue #8972) and for breakpoints inside SuperComponent (community issue #9466) — both of which depend on the agent being able to pause, serialize, and resume mid-loop (Source: haystack/components/agents/agent.py, docs-website/docs/pipeline-components/agents-1/agent.mdx).

flowchart LR
    A[User messages + kwargs] --> B[Agent.run]
    B --> C[Render prompts via Jinja2]
    C --> D[ChatGenerator.run]
    D -->|text only| E[exit_conditions met?]
    E -->|yes| F[Return messages + state]
    E -->|no| G[ToolInvoker.execute]
    G --> D
    D -->|tool_calls| G
    G --> H[Tool or Toolset]
    H --> G

Tool Ecosystem

The Tool layer is documented at docs-website/docs/pipeline-components/tools/toolinvoker.mdx. A Tool wraps a Python callable, with metadata such as name, description, parameters (a JSON Schema), and optional inputs_from_state / outputs_to_state mappings. A Toolset is a named, ordered collection of Tool objects that can be passed wherever a tool list is expected.

ToolInvoker is the runtime component that:

  • Receives the tool_calls from a chat message.
  • Matches each call to a Tool by name.
  • Validates arguments against the tool's JSON Schema.
  • Calls the underlying function (sync or async).
  • Returns a list of ChatMessage(tool_result=...) objects.

Async Tool Invocation

A frequent community pitfall is that an async def tool function is not automatically awaited. Issue #9580 reports a RuntimeWarning: coroutine 'get_all_uns_topics' was never awaited when the tool body is async. The fix documented in the tool guide is to either:

  • Make the tool function synchronous and bridge to async internally with asyncio.run, or
  • Detect the coroutine in the tool wrapper and await it, or
  • Expose the tool only through a synchronous API that returns the resolved value (Source: docs-website/docs/pipeline-components/tools/toolinvoker.mdx, haystack/components/agents/agent.py).

Human-in-the-Loop and Confirmation Strategies

Agent accepts a confirmation_strategies dict that maps tool names to ConfirmationStrategy instances. When a tool with a strategy is invoked, the agent pauses and asks for confirmation before executing. The strategies receive an optional confirmation_strategy_context dict at run time, which is the recommended channel for passing per-request resources like a WebSocket or async queue in a web server (Source: haystack/components/agents/agent.py, docs-website/docs/pipeline-components/agents-1/human-in-the-loop.mdx).

Configuration and Common Failure Modes

Failure modeSymptomMitigation
Generator does not support toolsAgent raises TypeError on constructionUse a chat generator that exposes tools in its run signature; check _chat_generator_supports_tools (Source: haystack/components/agents/agent.py)
Async tool not awaitedRuntimeWarning + handle = NoneMake the tool sync, or await the coroutine inside the wrapper (Source: docs-website/docs/pipeline-components/tools/toolinvoker.mdx)
Structured output not honoredModel returns JSON in content instead of via .parsePass provider-specific generation_kwargs; tracked in issue #8276 (Source: docs-website/docs/pipeline-components/generators/guides-to-generators/function-calling.mdx)
streaming_callback must be syncTypeError when using async defWrap in asyncio.run until issue #7231 is resolved
Agent loop never terminatesStep count keeps growingSet max_agent_steps; rely on exit_conditions; use break_point to inspect (Source: docs-website/docs/pipeline-components/agents-1/agent.mdx)

See Also

  • Agents concept guide — docs-website/docs/concepts/agents.mdx
  • Agent reference — docs-website/docs/pipeline-components/agents-1/agent.mdx
  • Human-in-the-Loop confirmation strategies — docs-website/docs/pipeline-components/agents-1/human-in-the-loop.mdx
  • Generators index — docs-website/docs/pipeline-components/generators.mdx
  • Function calling guide — docs-website/docs/pipeline-components/generators/guides-to-generators/function-calling.mdx
  • ToolInvoker reference — docs-website/docs/pipeline-components/tools/toolinvoker.mdx
  • Pipeline breakpoints discussion — issue #8972
  • SuperComponent breakpoint support — issue #9466

Source: https://github.com/deepset-ai/haystack / Human Manual

Doramagic Pitfall Log

Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.

high Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

high Security or permission risk requires verification

Developers may expose sensitive permissions or credentials: Async tool not awaited

medium Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

Doramagic Pitfall Log

Found 18 structured pitfall item(s), including 2 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.

1. Installation risk: Installation risk requires verification

  • Severity: high
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/deepset-ai/haystack/issues/11445

2. Security or permission risk: Security or permission risk requires verification

  • Severity: high
  • Finding: Developers should check this security_permissions risk before relying on the project: Async tool not awaited
  • User impact: Developers may expose sensitive permissions or credentials: Async tool not awaited
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: Async tool not awaited. Context: Observed when using python, windows, cuda
  • Evidence: failure_mode_cluster:github_issue | https://github.com/deepset-ai/haystack/issues/9580

3. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/deepset-ai/haystack/issues/9466

4. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/deepset-ai/haystack/issues/8972

5. Configuration risk: Configuration risk requires verification

  • Severity: medium
  • Finding: Developers should check this configuration risk before relying on the project: v2.28.0
  • User impact: Upgrade or migration may change expected behavior: v2.28.0
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: v2.28.0. Context: Observed when using python
  • Evidence: failure_mode_cluster:github_release | https://github.com/deepset-ai/haystack/releases/tag/v2.28.0

6. Configuration risk: Configuration risk requires verification

  • Severity: medium
  • Finding: Developers should check this configuration risk before relying on the project: v2.29.0
  • User impact: Upgrade or migration may change expected behavior: v2.29.0
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: v2.29.0. Context: Observed when using python
  • Evidence: failure_mode_cluster:github_release | https://github.com/deepset-ai/haystack/releases/tag/v2.29.0

7. Configuration risk: Configuration risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/deepset-ai/haystack/issues/9580

8. Capability evidence risk: Capability evidence risk requires verification

  • Severity: medium
  • Finding: README/documentation is current enough for a first validation pass.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: capability.assumptions | github_repo:221654678 | https://github.com/deepset-ai/haystack

9. Runtime risk: Runtime risk requires verification

  • Severity: medium
  • Finding: Developers should check this runtime risk before relying on the project: Add pipeline breakpoint support for the internals of SuperComponent
  • User impact: Developers may hit a documented source-backed failure mode: Add pipeline breakpoint support for the internals of SuperComponent
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: Add pipeline breakpoint support for the internals of SuperComponent. Context: Observed when using python
  • Evidence: failure_mode_cluster:github_issue | https://github.com/deepset-ai/haystack/issues/9466

10. Maintenance risk: Maintenance risk requires verification

  • Severity: medium
  • Finding: Developers should check this migration risk before relying on the project: v2.30.0
  • User impact: Upgrade or migration may change expected behavior: v2.30.0
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: v2.30.0. Context: Observed when using python
  • Evidence: failure_mode_cluster:github_release | https://github.com/deepset-ai/haystack/releases/tag/v2.30.0

11. Maintenance risk: Maintenance risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | github_repo:221654678 | https://github.com/deepset-ai/haystack

12. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: downstream_validation.risk_items | github_repo:221654678 | https://github.com/deepset-ai/haystack

Source: Doramagic discovery, validation, and Project Pack records

Community Discussion Evidence

These external discussion links are review inputs, not standalone proof that the project is production-ready.

Sources 9

Count of project-level external discussion links exposed on this manual page.

Use Review before install

Open the linked issues or discussions before treating the pack as ready for your environment.

Community Discussion Evidence

Doramagic exposes project-level community discussion separately from official documentation. Review these links before using haystack with real data or production workflows.

Source: Project Pack community evidence and pitfall evidence