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
Continue reading this section for the full explanation and source context.
Related Pages
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 Pillar | Description |
|---|---|
| Built for context engineering | Explicit control over retrieval, ranking, filtering, combining, structuring, and routing before reaching the model. |
| Model- and vendor-agnostic | Integrations with OpenAI, Mistral, Anthropic, Cohere, Hugging Face, Azure OpenAI, AWS Bedrock, and local models. |
| Modular and customizable | Built-in components for retrieval, indexing, tool calling, memory, and evaluation, with hooks for loops, branches, and conditional logic. |
| Extensible ecosystem | Custom 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.idshould be a content fingerprint but in practice depends on the insertion order of keys in the metadata dictionary, so two semantically identicalDocumentobjects can end up with different IDs and silently break deduplication. Source: Issue #11445 - Async tool execution. Issue #9580 reports a
RuntimeWarning: coroutine ... was never awaitedwhen a tool defined with anasync defmethod 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
SuperComponentandAgentinternals. 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_callbackon 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
- Haystack Documentation — official user-facing guides
- haystack-cookbook — runnable examples and recipes
- haystack-core-integrations — third-party component integrations
- Hayhooks — wrap pipelines and agents as REST APIs or MCP servers
- Release notes v2.30.0, v2.29.0, v2.28.0, v2.27.0 — release history
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
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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
Documentgets 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
| Symptom | Likely cause | Reference |
|---|---|---|
PipelineConnectError at connect() | Incompatible socket types | creating-pipelines.mdx |
RuntimeWarning: coroutine was never awaited | Async tool's invoke is not async def | agent.py; issue #9580 |
Same content, different Document.id | meta dict iteration order affects the hash | issue #11445 |
requests.exceptions.RequestException after upgrade | HTTP utilities moved from requests to httpx | release v2.28.0 |
| Branching query yields wrong top-k | Inputs not joined into a list before the next stage | smart-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
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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 onidshould re-validate after upgrading. Source: docs-website/docs/concepts/metadata-filtering.mdx:1-30. - Lost chunk position after splitting: track and propagate the
metaoffsets 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
MultiRetrieverplus thesuper_componentagent 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_callbackdoes 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
- Pipeline Components: Preprocessors
- Concepts: Document Store
- Concepts: Metadata Filtering
- Haystack integrations: haystack-core-integrations
- Release notes: v2.30.0, v2.29.0
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
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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:
| Family | Typical inputs | Typical outputs | Streaming support |
|---|---|---|---|
Text generators (OpenAIGenerator, HuggingFaceAPIGenerator, etc.) | A prompt string | A single replies list of strings | Via streaming_callback |
Chat generators (OpenAIChatGenerator, AnthropicChatGenerator, AzureOpenAIChatGenerator, etc.) | A list of ChatMessage objects | A list of ChatMessage replies, optionally with tool_calls | Via 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:
- Define a tool schema and pass it to the generator through
generation_kwargsor a dedicatedtoolsparameter. - Let the model return
tool_callsrather than free-form text. - Route the
tool_callsto aToolInvokerto execute them and feed the results back asChatMessage(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 arun(messages, ...)method.tools— a list ofTooland/orToolset, or a singleToolset.system_promptanduser_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:
- Renders system and user prompts.
- Calls the chat generator, possibly with tools.
- If the response contains
tool_calls, hands them to theToolInvoker. - Appends tool results to the message history.
- Loops until an
exit_conditionis met ormax_agent_stepsis 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 --> GTool 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_callsfrom a chat message. - Matches each call to a
Toolby 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
awaitit, 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 mode | Symptom | Mitigation |
|---|---|---|
Generator does not support tools | Agent raises TypeError on construction | Use a chat generator that exposes tools in its run signature; check _chat_generator_supports_tools (Source: haystack/components/agents/agent.py) |
| Async tool not awaited | RuntimeWarning + handle = None | Make the tool sync, or await the coroutine inside the wrapper (Source: docs-website/docs/pipeline-components/tools/toolinvoker.mdx) |
| Structured output not honored | Model returns JSON in content instead of via .parse | Pass 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 sync | TypeError when using async def | Wrap in asyncio.run until issue #7231 is resolved |
| Agent loop never terminates | Step count keeps growing | Set 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 Agentreference —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 ToolInvokerreference —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.
May increase setup, validation, or first-run risk for the user.
Developers may expose sensitive permissions or credentials: Async tool not awaited
May increase setup, validation, or first-run risk for the user.
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.
Count of project-level external discussion links exposed on this manual page.
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.
- fix: make Document.id deterministic regardless of meta key order - github / github_issue
- Async tool not awaited - github / github_issue
- Pipeline breakpoints - github / github_issue
- Add pipeline breakpoint support for the internals of SuperComponent - github / github_issue
- v2.30.0 - github / github_release
- v2.29.0 - github / github_release
- v2.28.0 - github / github_release
- v2.27.0 - github / github_release
- Capability evidence risk requires verification - GitHub / issue
Source: Project Pack community evidence and pitfall evidence