Heads up This site is currently under heavy development.
← all tools
◆ AI Agent Frameworks

Haystack

v3.1.0 open-source

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.

Summary

Haystack is an open-source AI agent framework that allows for the construction of production-ready Retrieval Augmented Generation (RAG) pipelines and autonomous agents. It is free to use under its open-source license. Developers can integrate it as a library into their own applications, and the documentation describes its functionality in relation to other vector store frameworks. It is aimed at developers building LLM applications, and its materials indicate active development.

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.

What Haystack answers

What types of components can I connect in a pipeline?

it constructs Retrieval Augmented Generation (RAG) pipelines and autonomous agents

How do I use it within my existing application code?

developers can integrate it as a library into their own applications

What does it connect with regarding document storage?

its documentation describes its functionality in relation to other vector store frameworks

Where does its functionality stop?

it is designed for building RAG pipelines and autonomous agents

What programming model does it support?

it is an open-source AI agent framework

Does it require a central deployment?

it is free to use under its open-source license

Release history

  1. v3.1.0 Aug 24, 2026 · issue 007

    Haystack v3.1.0 adds context compaction hooks, token counters, AgentTool for multi-agent delegation, and a new HAYSTACK_UNSAFE_DESERIALIZATION env var.

    └──▷ GET THIS VERSION
    $ git clone --branch v3.1.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v3.1.0
    └──▷ USE IT
    Prevent context-window overflows in a long-running agent by sliding off old turns automatically.
    python
    from haystack.hooks.compaction import CompactionHook, SlidingWindowCompactor
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIResponsesChatGenerator
    
    hook = CompactionHook(
        compactor=SlidingWindowCompactor(),
        context_window=128_000,
        compact_at=0.8,
        compact_to=0.5,
    )
    agent = Agent(
        chat_generator=OpenAIResponsesChatGenerator(model="gpt-4o"),
        tools=[web_search],
        hooks={"before_llm": [hook]},
    )
    result = agent.run([ChatMessage.from_user("Summarize recent AI news.")])
    Estimate token usage before sending a request to decide whether compaction is needed, without any extra dependencies.
    python
    from haystack.token_counters import ApproximateTokenCounter, TiktokenCounter
    from haystack.dataclasses import ChatMessage
    
    messages = [ChatMessage.from_user("Explain quantum entanglement.")]
    
    # No extra install required
    approx_count = ApproximateTokenCounter(chars_per_token=4.0).count(messages)
    
    # Closer estimate for OpenAI models — requires: pip install tiktoken
    tiktoken_count = TiktokenCounter(encoding="o200k_base").count(messages)
    
    print(f"Approximate: {approx_count}, Tiktoken: {tiktoken_count}")
    Build a multi-agent system where a coordinator delegates web research to a specialist agent.
    python
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIResponsesChatGenerator
    from haystack.dataclasses import ChatMessage
    from haystack.tools import AgentTool
    
    researcher = Agent(
        chat_generator=OpenAIResponsesChatGenerator(model="gpt-4o-mini"),
        system_prompt="You are a research specialist. Investigate the task and report your findings.",
        tools=[web_search],
    )
    
    research_specialist = AgentTool(
        agent=researcher,
        name="research",
        description="Research a question on the web and report the findings",
    )
    
    coordinator = Agent(
        chat_generator=OpenAIResponsesChatGenerator(model="gpt-4o"),
        tools=[research_specialist],
        system_prompt="You coordinate specialists. Delegate research questions, then answer the user.",
    )
    
    result = coordinator.run([ChatMessage.from_user("What are the latest LLM benchmarks?")])
    print(result["last_message"].text)
    • Adds CompactionHook (from haystack.hooks.compaction) with context_window, compact_at, and compact_to parameters, wired into Agent via hooks={'before_llm': [hook]}, to automatically shorten conversation history before LLM calls.
    • Adds SlidingWindowCompactor (from haystack.hooks.compaction) that drops oldest full turns then individual steps, replacing removed content with an omission note.
    • Adds ToolResultPruningCompactor (from haystack.hooks.compaction) with min_keep_steps and min_tokens parameters that replaces older/large tool results with placeholders while preserving the most recent tool-calling steps.
    • Adds haystack.token_counters module with three classes: ApproximateTokenCounter (dependency-free, configurable via chars_per_token), TiktokenCounter (local estimation via encoding parameter, requires pip install tiktoken), and OpenAITokenCounter (calls OpenAI's counting API for exact model-specific counts), all exposing a .count(messages) method.
    • Adds AgentTool (from haystack.tools) to wrap any Agent as a Tool so an orchestrating agent can delegate to it; exposes name and description parameters and surfaces only the wrapped agent's final reply to the caller.
    +8 moreshow less
    • Adds Agent.clone() method that returns a new Agent with the same configuration, accepting keyword arguments to override init parameters (e.g., agent.clone(system_prompt='Answer in German.')).
    • Adds link_format parameter to PyPDFToDocument and PDFMinerToDocument components, parsing PDF annotation links and appending them to page content (matching existing DOCXToDocument behavior).
    • Adds exit_reason output to Agent.run(), returning 'text', the name of the tool that satisfied an exit condition, or 'max_agent_steps'; also accessible in hooks via state.get('exit_reason').
    • Adds close() and close_async() resource-release methods to AutoMergingRetriever, CacheChecker, DocumentWriter, FilterRetriever, and SentenceWindowRetriever.
    • Adds HAYSTACK_UNSAFE_DESERIALIZATION environment variable (truthy values: 1 or true) to bypass all deserialization safety checks process-wide for Pipeline.load, Pipeline.loads, Pipeline.from_dict, Tool.from_dict, State.from_dict, and the ConditionalRouter/OutputAdapter Jinja sandbox; value is read once and frozen for the process lifetime.
    • Adds agent.resolved_state_schema public attribute exposing the full effective runtime schema including internal keys (messages, step_count, token_usage, exit_reason).
    • Adds inputs_format field to PipelineSnapshot.pipeline_state to distinguish the new per-sender input shape {component: {socket: [{sender: ..., value: ...}]}} from the legacy flattened shape.
    • Adds a content-free haystack.agent.hook tracing span for every Agent hook invocation, recording hook point, hook name, hook type, compaction strategy, estimated context size, compaction trigger status, token target, and whether the compactor returned a replacement.
    └──▷ BREAKING ON UPGRADE
    • !OutputAdapter and ConditionalRouter components serialized with unsafe: true now raise DeserializationError on load unless Pipeline.load(..., unsafe=True) (or Pipeline.loads / Pipeline.from_dict with unsafe=True) is used.
    • !exit_reason is now a reserved key in Agent.state_schema; defining a custom state_schema key named exit_reason raises ValueError at Agent initialization.
    • !Agent.state_schema now contains only the user-provided schema, excluding internally managed keys (messages, step_count, token_usage, exit_reason); use agent.resolved_state_schema to get the full effective schema.
    • !PipelineSnapshot.pipeline_state.inputs and BreakpointException.inputs changed shape from {component: {socket: value}} to {component: {socket: [{sender: ..., value: ...}]}}; reading inputs['my_component']['my_socket'] must become inputs['my_component']['my_socket'][0]['value'].
    • !DocumentMAPEvaluator scores may change: average precision now uses all unique valid ground-truth values as the denominator and credits each value at most once; existing evaluation baselines must be recalculated.
    • !Passing window_size=0 to SentenceWindowRetriever.run or SentenceWindowRetriever.run_async now raises ValueError instead of silently falling back to the constructor value; pass None or omit the argument to use the constructor default.
    • !InMemoryDocumentStore.get_metadata_field_unique_values and its async counterpart now match search_term against the metadata field value (case-insensitive substring) instead of the document content; callers relying on content-matching must filter documents themselves.
    • !The Agent now calls warm_up() on hooks before every run (not only the first); hooks with expensive setup in warm_up() must guard against repeated calls (e.g., if self._client is not None: return).
    • !The internal _is_warmed_up flag that prevented repeated warm_up() calls on Toolset is removed; every call now reaches warm_up() directly, so custom Tool or Toolset subclasses with expensive setup in warm_up() must add their own guard.
  2. v3.1.0-rc3 Aug 21, 2026 · issue 004

    Haystack v3.1.0-rc3 adds context compaction for Agent, token counters, OpenAI token counting API, PDF link extraction, and a process-wide unsafe deserialization env var.

    └──▷ GET THIS VERSION
    $ git clone --branch v3.1.0-rc3 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v3.1.0-rc3
    └──▷ USE IT
    Count tokens in a message list before sending to an OpenAI model, to decide whether compaction is needed.
    python
    from haystack.dataclasses import ChatMessage
    from haystack.token_counters import OpenAITokenCounter
    
    counter = OpenAITokenCounter("gpt-5-mini")
    count = counter.count([ChatMessage.from_user("Summarize the quarterly report.")])
    print(count)
    Attach context compaction to an Agent so long conversations are automatically trimmed before each LLM call.
    python
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIResponsesChatGenerator
    from haystack.hooks.compaction import CompactionHook, SlidingWindowCompactor
    
    hook = CompactionHook(
        compactor=SlidingWindowCompactor(),
        context_window=400_000,
        compact_at=0.7,
        compact_to=0.4,
    )
    agent = Agent(
        chat_generator=OpenAIResponsesChatGenerator(model="gpt-5.4-nano"),
        tools=[web_search],
        hooks={"before_llm": [hook]},
    )
    Enable process-wide unsafe deserialization in a trusted deployment so every pipeline load skips safety checks without passing unsafe=True at each call site.
    $ export HAYSTACK_UNSAFE_DESERIALIZATION=1
    • Adds HAYSTACK_UNSAFE_DESERIALIZATION environment variable (truthy values: 1 or true) as a process-wide switch to skip all deserialization safety checks across Pipeline.load, Pipeline.loads, Pipeline.from_dict, Tool.from_dict, State.from_dict, ConditionalRouter, and OutputAdapter — read once on first deserialization and frozen for the process lifetime.
    • Adds haystack.token_counters module with a TokenCounter protocol and two implementations: ApproximateTokenCounter (no extra deps, estimates from chars_per_token) and TiktokenCounter (requires pip install tiktoken, uses the named encoding such as o200k_base) for sizing ChatMessage lists before a call.
    • Adds experimental CompactionHook and SlidingWindowCompactor in haystack.hooks.compaction, configurable via context_window, compact_at, and compact_to fractions, wired into an Agent through hooks={'before_llm': [hook]}; implements the Compactor protocol for custom strategies.
    • Adds exit_reason output to Agent, returning 'text', 'max_agent_steps', or the name of the exit-condition tool; also accessible in hooks via state.get('exit_reason').
    • Adds link_format parameter to PyPDFToDocument and PDFMinerToDocument, parsing links from PDF annotations and appending them at the bottom of page content.
    +1 moreshow less
    • Adds agent.resolved_state_schema public attribute for inspecting the full runtime state schema (including internally managed keys such as messages, step_count, token_usage, exit_reason).
    └──▷ BREAKING ON UPGRADE
    • !exit_reason is now a reserved key on Agent.state_schema; initializing an Agent with a custom state_schema containing exit_reason raises ValueError.
    • !Agent.state_schema now contains only the user-provided schema as passed to __init__; code that read agent.state_schema to inspect the full runtime schema must switch to agent.resolved_state_schema.
    • !PipelineSnapshot.pipeline_state.inputs (and BreakpointException.inputs) changed shape from {component: {socket: value}} to {component: {socket: [{"sender": ..., "value": ...}]}}; code reading these fields directly must index with [0]["value"]. A new inputs_format field records which shape a snapshot uses.
    • !Loading a serialized OutputAdapter or ConditionalRouter with unsafe: true in its init parameters now raises DeserializationError unless the pipeline is loaded with Pipeline.load(..., unsafe=True) (or the equivalent Pipeline.loads / Pipeline.from_dict option).
    • !SentenceWindowRetriever.run and SentenceWindowRetriever.run_async now raise ValueError when window_size=0 is passed at runtime; callers relying on 0 to mean 'use the constructor value' must omit the argument or pass None instead.
    • !InMemoryDocumentStore.get_metadata_field_unique_values (and its async counterpart) search_term parameter now matches against the metadata field value (case-insensitive substring) instead of document content.
    • !Toolset._is_warmed_up internal flag is removed; warm_up() is now called before every run rather than only the first, so custom Tool or Toolset implementations that do expensive setup there must add their own early-return guard.
    • !DocumentMAPEvaluator scores may change because average precision now uses all unique, valid ground-truth comparison values as its denominator and credits each value at most once; existing evaluation baselines should be recalculated.
    • !Serialized OutputAdapter and ConditionalRouter components containing Jinja custom_filters must now be loaded with Pipeline.load(..., unsafe=True) (or Pipeline.loads / Pipeline.from_dict with unsafe=True).
  3. v3.1.0-rc2 Aug 21, 2026 · issue 004

    Haystack v3.1.0-rc2 adds context compaction for Agents, token counters, OpenAI token counting API, PDF link extraction, and a process-wide unsafe deserialization env var.

    └──▷ GET THIS VERSION
    $ git clone --branch v3.1.0-rc2 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v3.1.0-rc2
    └──▷ USE IT
    Attach context compaction to an Agent so long conversations are automatically trimmed before hitting the model's context limit.
    python
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIResponsesChatGenerator
    from haystack.hooks.compaction import CompactionHook, SlidingWindowCompactor
    
    hook = CompactionHook(
        compactor=SlidingWindowCompactor(),
        context_window=400_000,
        compact_at=0.7,
        compact_to=0.4,
    )
    agent = Agent(
        chat_generator=OpenAIResponsesChatGenerator(model="gpt-5.4-nano"),
        tools=[web_search],
        hooks={"before_llm": [hook]},
    )
    Count tokens for a list of ChatMessages using OpenAI's exact token counting API before deciding whether to compact.
    python
    from haystack.dataclasses import ChatMessage
    from haystack.token_counters import OpenAITokenCounter
    
    counter = OpenAITokenCounter("gpt-5-mini")
    count = counter.count([ChatMessage.from_user("Hello!")])
    print(count)
    Enable unsafe deserialization process-wide when deploying with fully trusted pipelines and you cannot pass unsafe=True at every call site.
    $ HAYSTACK_UNSAFE_DESERIALIZATION=1 python my_pipeline_server.py
    • Adds HAYSTACK_UNSAFE_DESERIALIZATION environment variable (truthy values: 1 or true) as a process-wide switch to skip all deserialization safety checks across Pipeline.load, Pipeline.loads, Pipeline.from_dict, Tool.from_dict, State.from_dict, ConditionalRouter, and OutputAdapter Jinja sandbox flags — intended for deployments loading only fully trusted pipelines.
    • Adds haystack.token_counters module with a TokenCounter protocol and two implementations: ApproximateTokenCounter (no dependencies, estimates from text length via chars_per_token parameter) and TiktokenCounter (closer estimates for OpenAI models, requires pip install tiktoken, accepts an encoding parameter such as 'o200k_base').
    • Adds link_format parameter to PyPDFToDocument and PDFMinerToDocument components, parsing links from PDF annotations and appending them at the bottom of each page.
    └──▷ BREAKING ON UPGRADE
    • !exit_reason is now a reserved state key on Agent; if your state_schema defines a key named exit_reason, the Agent raises ValueError at initialization — rename the key.
    • !Agent.state_schema now contains only the user-provided schema as passed to __init__; code that read agent.state_schema to inspect the full runtime schema must switch to agent.resolved_state_schema.
    • !PipelineSnapshot.pipeline_state.inputs (and BreakpointException.inputs) changed shape from {component: {socket: value}} to {component: {socket: [{"sender": ..., "value": ...}]}}; code that reads these fields directly must be updated; inputs_format field records which shape a snapshot uses.
    • !Loading a serialized OutputAdapter or ConditionalRouter with unsafe: true in its init parameters now raises DeserializationError unless Pipeline.load, Pipeline.loads, or Pipeline.from_dict is called with unsafe=True.
    • !Serialized OutputAdapter and ConditionalRouter components containing Jinja custom_filters must now be loaded with Pipeline.load(..., unsafe=True) (or equivalent Pipeline.loads / Pipeline.from_dict option).
    • !Passing window_size=0 to SentenceWindowRetriever.run or SentenceWindowRetriever.run_async now raises ValueError instead of silently falling back to the constructor value; pass None or omit the argument to use the constructor's window_size.
    • !InMemoryDocumentStore.get_metadata_field_unique_values search_term parameter now matches against the metadata field value (case-insensitive substring) instead of document content; callers relying on content-matching must pre-filter documents themselves.
    • !The Toolset internal _is_warmed_up flag is removed; warm_up() is now called before every Agent run, so custom Tool or Toolset implementations doing expensive setup must guard with their own state (e.g. if self._client is not None: return).
    • !DocumentMAPEvaluator scores may change because average precision now uses all unique, valid ground-truth comparison values as its denominator and credits each value at most once — re-baseline any evaluations that depended on previous scores.
  4. v3.1.0-rc1 Aug 18, 2026 · issue 002

    Haystack v3.1.0-rc1 adds Agent context compaction, AgentTool, exit_reason output, OpenAITokenCounter, and PDF link extraction.

    └──▷ GET THIS VERSION
    $ git clone --branch v3.1.0-rc1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v3.1.0-rc1
    └──▷ USE IT
    Automatically compact an Agent's conversation when it fills 70% of the model's context window, keeping the most recent turns.
    python
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIResponsesChatGenerator
    from haystack.hooks.compaction import CompactionHook, SlidingWindowCompactor
    
    hook = CompactionHook(
        compactor=SlidingWindowCompactor(),
        context_window=400_000,
        compact_at=0.7,
        compact_to=0.4,
    )
    agent = Agent(
        chat_generator=OpenAIResponsesChatGenerator(model="gpt-4o"),
        tools=[web_search],
        hooks={"before_llm": [hook]},
    )
    Count tokens in a list of ChatMessages before sending them to an OpenAI model, including tool schemas, to check context headroom.
    python
    from haystack.dataclasses import ChatMessage
    from haystack.token_counters import TiktokenCounter
    
    counter = TiktokenCounter(encoding="o200k_base")
    messages = [ChatMessage.from_user("Summarize the last 10 CVEs.")]
    token_count = counter.count(messages, tools=[my_tool])
    print(token_count)
    Route Agent output downstream based on why it stopped — text reply, tool exit, or step budget exhausted.
    python
    from haystack.components.agents import Agent
    from haystack.components.routers import ConditionalRouter
    
    # Agent now includes exit_reason in its output
    result = agent.run(messages=[ChatMessage.from_user("Research CVE-2024-1234.")])
    print(result["exit_reason"])  # 'text', 'max_agent_steps', or a tool name
    • Adds CompactionHook and SlidingWindowCompactor (in haystack.hooks.compaction) to automatically shorten Agent conversation history before LLM calls, configured via context_window, compact_at, and compact_to parameters.
    • Adds experimental ToolResultPruningCompactor (in haystack.hooks.compaction) that reduces Agent context by replacing older large tool results with short placeholders, controlled by min_keep_steps and min_tokens parameters.
    • Adds OpenAITokenCounter in haystack.token_counters that uses OpenAI's token-counting API to return model-specific counts for ChatMessage objects and optional tool schemas.
    • Adds haystack.token_counters module with a TokenCounter protocol and two implementations: ApproximateTokenCounter (configurable chars_per_token, no dependencies) and TiktokenCounter (uses OpenAI's byte-pair encoder, requires pip install tiktoken); both accept an optional tools argument to account for tool schema tokens.
    • Adds Agent.clone() method to create a new Agent with the same configuration, optionally overriding init parameters (e.g. agent.clone(system_prompt='Answer in German.')).
    +5 moreshow less
    • Adds AgentTool, a Tool that wraps a Haystack Agent so it can be delegated to by another Agent, enabling multi-agent systems.
    • Adds exit_reason output to Agent runs — one of 'text', the name of the tool that satisfied an exit condition, or 'max_agent_steps' — also accessible to hooks via state.get('exit_reason').
    • Adds agent.resolved_state_schema public attribute exposing the full effective runtime schema, including internally managed keys.
    • Adds link_format parameter to both PyPDFToDocument and PDFMinerToDocument components to parse and append links from PDF annotations to page content, matching existing DOCXToDocument functionality.
    • Adds inputs_format field to PipelineState, recording whether a snapshot uses the legacy flattened shape or the new per-sender list shape {component: {socket: [{sender: ..., value: ...}]}}.
    └──▷ BREAKING ON UPGRADE
    • !exit_reason is now a reserved key in Agent state schema; initializing an Agent with a custom state_schema key named exit_reason raises ValueError.
    • !Agent.state_schema now contains only the user-provided schema (as passed to __init__), not the resolved runtime schema; use the new agent.resolved_state_schema to inspect the full effective schema.
    • !DocumentMAPEvaluator average precision scores have changed: the denominator is now all unique valid ground-truth comparison values and each value is credited at most once; re-baseline evaluations that relied on previous scores.
    • !PipelineSnapshot.pipeline_state.inputs (and BreakpointException.inputs) changed shape from {component: {socket: value}} to {component: {socket: [{sender: ..., value: ...}]}}; read values as inputs['my_component']['my_socket'][0]['value'].
    • !Loading a serialized OutputAdapter or ConditionalRouter with unsafe=True now raises DeserializationError unless the pipeline is loaded with Pipeline.load(..., unsafe=True) (or Pipeline.loads / Pipeline.from_dict with unsafe=True).
    • !Passing window_size=0 to SentenceWindowRetriever.run or SentenceWindowRetriever.run_async now raises ValueError; omit the argument or pass None to use the constructor's value.
    • !InMemoryDocumentStore.get_metadata_field_unique_values search_term parameter now matches against the metadata field's own value (case-insensitive substring) instead of the document's content.
    • !The Toolset._is_warmed_up internal flag is removed; warm_up() is now called before every Agent run on Tools, Toolsets, and hooks — guard expensive setup with your own state (e.g. if self._client is not None: return).
  5. v3.0.0 Jul 20, 2026 · issue -030

    Haystack 3.0 ships a hooks-driven Agent, unified async Pipeline, built-in introspection, safe deserialization, and mock test components.

    └──▷ GET THIS VERSION
    $ git clone --branch v3.0.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v3.0.0
    └──▷ USE IT
    Audit every tool call before execution — useful for compliance logging or human approval gates.
    python
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIChatGenerator
    from haystack.hooks import hook
    
    @hook
    def audit_tool_calls(state):
        pending = state.data['messages'][-1].tool_calls
        print(f'about to run: {[tc.tool_name for tc in pending]}')
    
    agent = Agent(
        chat_generator=OpenAIChatGenerator(),
        tools=[...],
        hooks={'before_tool': [audit_tool_calls]},
    )
    result = agent.run(messages=[{'role': 'user', 'content': 'Summarize recent alerts'}])
    Load a serialized pipeline from an untrusted source with a scoped allowlist to prevent arbitrary code execution.
    python
    from haystack import Pipeline
    
    with open('pipeline.yaml') as fp:
        pipeline = Pipeline.load(fp, allowed_modules=['mypkg.*'])
    • Adds a hooks system to Agent with lifecycle points before_run, before_llm, before_tool, after_tool, on_exit, and after_run — pass callables decorated with @hook via the hooks dict argument to enforce guardrails, audit tool calls, or inject human-in-the-loop checkpoints.
    • Adds ConfirmationHook (human-in-the-loop) and ToolResultOffloadHook (writes large tool results to a store, leaving a compact pointer in conversation) as built-in before_tool hooks.
    • Adds SkillToolset for first-class skill discovery via progressive disclosure — the model sees only names and one-line descriptions until a skill is loaded, keeping context window usage lean.
    • Adds dynamic tool selection at runtime: pass tools=... to Agent.run / Agent.run_async so one Agent instance can serve different teams, tenants, and tasks without re-initialization.
    • Adds native async tool support — @tool routes async def callables to a Tool's new async_function field.
    +10 moreshow less
    • Adds built-in Agent state keys step_count, token_usage, and tool_call_counts for run introspection — react to them in hooks to compact context, cap tool loops, or apply cost budgets.
    • Emits dedicated step-level tracing spans haystack.agent.step with nested .llm and .tool children tagged with tools actually used, enabling precise per-step observability.
    • Unifies Pipeline and AsyncPipeline into a single Pipeline class exposing run, run_async, run_async_generator, and stream methods — stream() yields StreamingChunks as produced and exposes final output on handle.result.
    • Adds symmetric warm_up / close lifecycle to Pipeline and components so long-running services can acquire and release connections, GPU memory, and file handles without leaks.
    • Adds pipeline deserialization allowlist via Pipeline.load(fp, allowed_modules=[...]), the HAYSTACK_DESERIALIZATION_ALLOWLIST environment variable, and allow_deserialization_module(...) — dangerous builtins (eval, exec, open, getattr) are blocked by default; trusted sources can pass unsafe=True.
    • Adds MockChatGenerator, MockTextEmbedder, and MockDocumentEmbedder test components — no API keys or network required; embedders return stable, hash-derived embeddings for deterministic CI.
    • Adds {% insert %} Jinja2 tag to Agent, PromptBuilder, and ChatPromptBuilder for interleaving runtime messages into templates.
    • Moves 30 components (Sentence Transformers, Hugging Face local/API, Whisper, spaCy/langdetect, Tika, Azure OCR, SerperDev/SearchApi, OpenAPI connectors, Datadog/OpenTelemetry tracers) to independently released packages in haystack-core-integrations, enabling releases independent of the core cycle.
    • All Chat Generators now accept a plain str for messages, easing migration from removed text-only generators.
    • Tracing is now explicit — add OpenTelemetryConnector or DatadogConnector or call tracing.enable_tracing(...) to activate; Haystack no longer auto-enables tracing or reconfigures structlog process-wide.
    └──▷ BREAKING ON UPGRADE
    • !AsyncPipeline is removed; replace all imports and instantiations with Pipeline. Note that Pipeline.run executes components sequentially and does not accept concurrency_limit; use await pipeline.run_async(...) in async contexts.
    • !Async pipeline tracing now uses the operation name haystack.pipeline.run (with tag haystack.pipeline.execution_mode=async) instead of the former haystack.async_pipeline.run.
    • !ToolInvoker (standalone) is removed; tool execution is now owned entirely by Agent.
    • !OpenAIGenerator, AzureOpenAIGenerator, HuggingFaceAPIGenerator, and HuggingFaceLocalGenerator are removed — use their Chat Generator counterparts (OpenAIChatGenerator, etc.).
    • !DALLEImageGenerator is renamed to OpenAIImageGenerator.
    • !Agent, PromptBuilder, and ChatPromptBuilder now treat every Jinja2 template variable as required by default (required_variables='*'); pass required_variables=None to restore the previous all-optional behavior.
    • !Tools must declare inputs_from_state explicitly to read a State value; implicit injection by parameter name no longer works.
    • !continue_run is now a reserved key in Agent.state_schema; passing it raises ValueError — rename conflicting keys (e.g. to my_continue_run).
    • !step_count, token_usage, and tool_call_counts are now reserved keys in Agent.state_schema; passing any of them raises ValueError — rename conflicting keys.
    • !Document.id is now computed from canonical, key-sorted JSON of meta, so documents with non-empty meta get different IDs than in 2.x.
    • !configure_logging now attaches only to Haystack's own loggers; importing Haystack no longer reconfigures structlog process-wide.
    • !Tracing is no longer auto-enabled; explicitly add an OpenTelemetryConnector or DatadogConnector or call tracing.enable_tracing(...) to activate.
    • !Components that use external resources now create them during warm_up rather than __init__; errors from missing API keys or other init-time checks now surface at warm_up time instead.
    • !Passing tools at runtime via run(tools=...) to a chat generator that does not support tools now raises TypeError instead of silently ignoring them.
    • !The 30 components moved to haystack-core-integrations require a new package install and import path change (e.g. pip install sentence-transformers-haystack and from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersTextEmbedder).
    • !haystack-experimental is no longer a core dependency.
    • !Confirmation hook strategies now receive model-requested tool arguments in tool_params rather than fully-prepared arguments (values injected from State are no longer included).
  6. v2.31.0 Jul 8, 2026 · issue -042

    Haystack v2.31.0 adds async evaluators, type-preserving routing, YAML frontmatter extraction, and expanded reference range support.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.31.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.31.0
    └──▷ USE IT
    Route a structured dataclass through a pipeline without losing its type — useful when downstream components expect a typed object, not a string.
    python
    from haystack.components.routers import ConditionalRouter
    
    routes = [
        {
            "condition": "{{query.intent == 'search'}}",
            "output": "query",
            "output_name": "search_query",
            "output_type": ParsedQuery,
            "output_passthrough": True,
        },
    ]
    router = ConditionalRouter(routes)
    result = router.run(query=ParsedQuery(text="What is Haystack?", intent="search", entities=[]))
    assert result["search_query"].intent == "search"  # type preserved
    Run multiple RAG evaluations concurrently in a FastAPI service without blocking the event loop.
    python
    from haystack.components.evaluators import FaithfulnessEvaluator
    import asyncio
    
    evaluator = FaithfulnessEvaluator()
    result = await evaluator.run_async(
        questions=["What is Haystack?"],
        contexts=[["Haystack is an AI framework."]],
        predicted_answers=["Haystack is an AI framework."]
    )
    • Adds output_passthrough: True field to ConditionalRouter route definitions, bypassing Jinja2 rendering so complex types like dataclasses and Pydantic models are passed through unchanged rather than silently stringified.
    • Adds extract_frontmatter=True parameter to MarkdownToDocument; when set, YAML frontmatter is stripped from converted content and stored in Document.meta.
    • Adds expand_reference_ranges parameter to AnswerBuilder; when enabled, citation ranges like [6-10] and [1-3,7-9] are expanded to individual document indices in RAG answers (disabled by default).
    • Adds document_comparison_field parameter to DocumentNDCGEvaluator, allowing document matching by 'content', 'id', or any 'meta.<key>' field when calculating NDCG scores, consistent with DocumentMAPEvaluator, DocumentMRREvaluator, and DocumentRecallEvaluator.
    • Adds native async support via run_async to LLMEvaluator, FaithfulnessEvaluator, and ContextRelevanceEvaluator, enabling concurrent evaluation in async applications like FastAPI or FastMCP without blocking the event loop.
    └──▷ BREAKING ON UPGRADE
    • !DocumentNDCGEvaluator now matches documents by content instead of id by default; existing pipelines may see changed NDCG scores. Pass document_comparison_field="id" to restore the previous behavior.
  7. v2.30.1 Jun 9, 2026 · issue -071

    AzureOpenAIChatGenerator now accepts Secret for azure_endpoint and api_version, enabling runtime env-var resolution.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.30.1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.30.1
    └──▷ USE IT
    Use a single serialized pipeline across dev and prod Azure OpenAI deployments by resolving the endpoint and API version from environment variables at runtime.
    python
    from haystack.components.generators.chat import AzureOpenAIChatGenerator
    from haystack.utils import Secret
    
    generator = AzureOpenAIChatGenerator(
        azure_deployment="gpt-4o",
        azure_endpoint=Secret.from_env_var("AZURE_OPENAI_ENDPOINT"),
        api_version=Secret.from_env_var("AZURE_OPENAI_API_VERSION"),
    )
    • Adds Secret type support to the azure_endpoint and api_version parameters of AzureOpenAIChatGenerator, allowing values to be resolved at runtime via Secret.from_env_var() so a single serialized pipeline can target different environments by swapping environment variables.
  8. v2.30.0 Jun 3, 2026 · issue -077

    Haystack v2.30.0 adds syntax-aware Python code splitting and plain-string input for all ChatGenerators.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.30.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.30.0
    └──▷ USE IT
    Split a Python source file for a code-RAG pipeline while keeping class definitions attached to their method chunks and docstrings in metadata.
    python
    from haystack.components.preprocessors import PythonCodeSplitter
    
    splitter = PythonCodeSplitter(
        max_effective_lines=80,
        strip_docstrings=True,
        preserve_class_definition=True,
    )
    result = splitter.run(documents=[doc])
    for chunk in result["documents"]:
        print(chunk.meta["start_line"], chunk.meta["unit_kinds"], chunk.content[:120])
    Quickly probe an OpenAI chat model with a one-liner string instead of constructing a ChatMessage list.
    python
    from haystack.components.generators.chat import OpenAIChatGenerator
    
    generator = OpenAIChatGenerator()
    response = generator.run("Summarize the OWASP Top 10 in three sentences.")
    print(response["replies"][0].text)
    • Introduces PythonCodeSplitter component (importable from haystack.components.preprocessors) that parses Python source files via the ast module and merges units — module docstrings, import blocks, top-level functions, class headers, methods, nested classes — into chunks of roughly max_effective_lines lines, keeping whole functions and methods intact.
    • Adds strip_docstrings=True parameter to PythonCodeSplitter to move docstrings into chunk metadata instead of inline content.
    • Adds preserve_class_definition=True parameter to PythonCodeSplitter to prepend the enclosing class signature to chunks whose members spill into a later chunk.
    • Adds oversized_factor parameter to PythonCodeSplitter to control the threshold at which an oversized function falls back to a line-based secondary split (delegating to DocumentSplitter) with overlap.
    • Each PythonCodeSplitter chunk carries metadata fields start_line, end_line, unit_kinds, include_classes, decorators, docstrings, source_id, and split_id for rich downstream filtering.
    +4 moreshow less
    • All ChatGenerator components now accept a plain str for the messages parameter, automatically wrapping it in a ChatMessage with the user role — applies to AzureOpenAIChatGenerator, AzureOpenAIResponsesChatGenerator, FallbackChatGenerator, HuggingFaceAPIChatGenerator, HuggingFaceLocalChatGenerator, OpenAIChatGenerator, and OpenAIResponsesChatGenerator.
    • Adds run_async to TextEmbeddingRetriever, MultiQueryEmbeddingRetriever, and MultiQueryTextRetriever, enabling native coroutine execution in AsyncPipeline with fallback to a thread executor.
    • Updates ToolsType so that any class inheriting from Tool or Toolset is accepted in any sequence type (list, tuple, etc.) for the tools parameter.
    • Pipeline.draw() and Pipeline.show() now validate the Mermaid server response against expected output formats (PNG, JPEG, WebP, SVG, PDF) via magic-byte signature and Content-Type header before writing to disk, raising PipelineDrawingError on mismatch.
    └──▷ BREAKING ON UPGRADE
    • !DALLEImageGenerator default model changed from dall-e-3 to gpt-image-2; accepted quality values changed from standard/hd to auto/high/medium/low; accepted size values changed to 1024x1024, 1024x1536, 1536x1024, or auto; the response_format parameter is now ignored and the component always returns base64-encoded JSON.
  9. v2.29.0 May 12, 2026 · issue -099

    Haystack v2.29.0 adds MultiRetriever and TextEmbeddingRetriever for hybrid search, plus async CacheChecker support.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.29.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.29.0
    └──▷ USE IT
    Build a hybrid BM25 + embedding search pipeline that lets you skip the embedding retriever for short keyword queries at runtime.
    python
    from haystack.components.retrievers import MultiRetriever, TextEmbeddingRetriever
    from haystack.components.retrievers.in_memory import InMemoryBM25Retriever, InMemoryEmbeddingRetriever
    from haystack.components.embedders import SentenceTransformersTextEmbedder
    
    retriever = MultiRetriever(
        retrievers={
            "bm25": InMemoryBM25Retriever(document_store=doc_store),
            "embedding": TextEmbeddingRetriever(
                retriever=InMemoryEmbeddingRetriever(document_store=doc_store),
                text_embedder=SentenceTransformersTextEmbedder(model="sentence-transformers/all-MiniLM-L6-v2"),
            ),
        },
        top_k=3,
    )
    
    # Full hybrid search
    result = retriever.run(query="green energy sources")
    
    # BM25 only for short/keyword queries
    result = retriever.run(query="solar", active_retrievers=["bm25"])
    Switch MultiRetriever from reciprocal rank fusion to simple concatenation when you want raw ranked lists joined in order rather than RRF-scored.
    python
    retriever = MultiRetriever(
        retrievers={
            "bm25": InMemoryBM25Retriever(document_store=doc_store),
            "embedding": TextEmbeddingRetriever(
                retriever=InMemoryEmbeddingRetriever(document_store=doc_store),
                text_embedder=SentenceTransformersTextEmbedder(model="sentence-transformers/all-MiniLM-L6-v2"),
            ),
        },
        join_mode="concatenate",
        top_k=5,
    )
    • Adds MultiRetriever component (importable from haystack.components.retrievers) that runs multiple text retrievers in parallel, merges results via reciprocal rank fusion by default, and accepts active_retrievers and top_k parameters at runtime to selectively enable/disable individual retrievers.
    • Adds join_mode parameter to MultiRetriever, supporting 'reciprocal_rank_fusion' (default) and 'concatenate' merge strategies.
    • Adds TextEmbeddingRetriever component (importable from haystack.components.retrievers) that wraps an embedding retriever with a text embedder into a single TextRetriever-protocol-compatible component, enabling use inside MultiRetriever.
    • Adds run_async method to CacheChecker, enabling non-blocking use in AsyncPipeline.
    • Adds two usage modes to the LLM component: template-variable mode (provide user_prompt with Jinja2 variables such as {{ query }} to expose them as pipeline inputs) and pass-through mode (omit user_prompt to make messages a required input accepting a fully-constructed ChatMessage list).
    +1 moreshow less
    • Extracts reciprocal rank fusion logic into shared utility _reciprocal_rank_fusion in haystack.utils.misc, now used by both MultiRetriever and DocumentJoiner.
    └──▷ BREAKING ON UPGRADE
    • !LLM.run and LLM.run_async no longer accept messages and streaming_callback as positional arguments — they must now be passed as keyword arguments (e.g. llm.run(messages=[message], streaming_callback=my_callback)).
  10. v2.28.0 Apr 20, 2026 · issue -121

    Haystack v2.28.0 lets tools and components receive the live agent State object directly, and adds async support to LLMMetadataExtractor and a header-depth filter to MarkdownHeaderSplitter.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.28.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.28.0
    └──▷ USE IT
    Split a Markdown document only on top-level and second-level headers, keeping deeper headers merged into their parent chunk.
    python
    from haystack.components.preprocessors import MarkdownHeaderSplitter
    
    splitter = MarkdownHeaderSplitter(header_split_levels=[1, 2], keep_headers=True)
    result = splitter.run(documents=[document])["documents"]
    Give a function-based tool read/write access to the full agent state without manually wiring individual keys.
    python
    from haystack.components.agents import State
    from haystack.tools import tool
    
    @tool
    def my_tool(query: str, state: State) -> str:
        """Search using context from agent state."""
        history = state.get("history")
        ...
    • Adds header_split_levels parameter (list of integers 1–6, default all levels) to MarkdownHeaderSplitter to control which header depths create split boundaries — e.g., header_split_levels=[1, 2] splits only on # and ## headers.
    • Adds run_async method to LLMMetadataExtractor; ChatGenerator requests now run concurrently using the existing max_workers init parameter.
    • Enables tools and components to declare a State (or State | None) parameter in their signature to receive the live agent State object at invocation time — no extra wiring needed; ToolInvoker automatically injects it and excludes it from the LLM-facing schema.
    • MarkdownHeaderSplitter now ignores # lines inside fenced code blocks (triple-backtick or triple-tilde), preventing hash-prefixed lines in code from being misidentified as Markdown headers.
    └──▷ BREAKING ON UPGRADE
    • !request_with_retry and async_request_with_retry in haystack.utils.requests_utils now raise httpx.HTTPError instead of requests.exceptions.RequestException on failure; code catching requests.exceptions.RequestException (including via HuggingFaceTEIRanker) must be updated to catch httpx.HTTPError.
    • !The LLM component now requires user_prompt to be provided at initialization and it must contain at least one Jinja2 template variable; required_variables now defaults to '*' and passing an empty list raises a ValueError.
    • !Agent.run() and Agent.run_async() now require messages as an explicit argument; code relying on the default None value from v2.26/v2.27 must pass an empty list instead: agent.run(messages=[], ...).
  11. v2.27.0 Apr 1, 2026 · issue -140

    Haystack v2.27.0 adds automatic list joining in pipelines, async document store helpers, and multimodal chat generator support.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.27.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.27.0
    └──▷ USE IT
    Inspect metadata value ranges in a local prototype store before moving to production — replaces manual document iteration.
    python
    from haystack.document_stores.in_memory import InMemoryDocumentStore
    
    store = InMemoryDocumentStore()
    # ... write documents ...
    print(store.get_metadata_field_min_max("year"))
    print(store.get_metadata_field_unique_values("category"))
    print(store.count_documents_by_filter({"field": "meta.category", "operator": "==", "value": "finance"}))
    Check which Azure OpenAI models Haystack recognises without consulting external docs.
    python
    from haystack.components.generators.chat import AzureOpenAIChatGenerator
    print(AzureOpenAIChatGenerator.SUPPORTED_MODELS)
    • Adds count_documents_by_filter, count_unique_metadata_by_filter, get_metadata_fields_info, get_metadata_field_min_max, and get_metadata_field_unique_values operations to InMemoryDocumentStore, matching the inspection and filtering API available in other document stores.
    • Adds async variants to InMemoryDocumentStore: update_by_filter_async(), count_documents_by_filter_async(), count_unique_metadata_by_filter_async(), get_metadata_fields_info_async(), get_metadata_field_min_max_async(), and get_metadata_field_unique_values_async().
    • Exposes SUPPORTED_MODELS class variable on AzureOpenAIChatGenerator, listing supported model IDs such as gpt-5-mini and gpt-4o, inspectable at runtime via AzureOpenAIChatGenerator.SUPPORTED_MODELS.
    • Adds partial support for the image-text-to-text task in HuggingFaceLocalChatGenerator, enabling use of multimodal models such as Qwen 3.5 or Ministral with text-only inputs.
    • Pipelines now automatically join multiple inputs into a list-typed input socket with type conversion, supporting T + T -> list[T], T + list[T] -> list[T], str + ChatMessage -> list[str], and str + ChatMessage -> list[ChatMessage] — eliminating the need for extra joining components.
    +1 moreshow less
    • Adds _to_trace_dict method to ImageContent and FileContent dataclasses, replacing large base64_image and base64_data fields with placeholder strings (e.g. 'Base64 string (N characters)') when tracing is enabled.
  12. v2.26.0 Mar 18, 2026 · issue -154

    Haystack v2.26.0 adds LLMRanker, Jinja2 agent system prompts, SUPPORTED_MODELS class variables, and async embedding splitting.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.26.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.26.0
    └──▷ USE IT
    Rerank retrieved documents semantically using an LLM rather than a cross-encoder, filtering out irrelevant results before stuffing context into a RAG prompt.
    python
    from haystack import Document
    from haystack.components.rankers import LLMRanker
    
    ranker = LLMRanker()
    documents = [
        Document(id="paris", content="Paris is the capital of France."),
        Document(id="berlin", content="Berlin is the capital of Germany."),
    ]
    result = ranker.run(query="capital of Germany", documents=documents)
    print(result["documents"][0].id)  # "berlin"
    Dynamically adapt agent behavior at runtime (e.g. response language) without redefining the prompt for each context.
    python
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIChatGenerator
    from haystack.dataclasses import ChatMessage
    
    agent = Agent(
        chat_generator=OpenAIChatGenerator(),
        tools=[weather_tool],
        system_prompt="""{% message role='system' %}
        You always respond in {{language}}.
        {% endmessage %}""",
        required_variables=["language"],
    )
    result = agent.run(
        messages=[ChatMessage.from_user("What is the weather in London?")],
        language="Italian",
    )
    print(result["last_message"].text)
    Tune the LLM-facing search tool metadata in a large toolset so a specific model finds tools more reliably.
    python
    from haystack.tools import SearchableToolset
    
    toolset = SearchableToolset(
        catalog=my_tools,
        search_tool_name="find_tools",
        search_tool_description="Find tools by keyword. Pass 1-3 words, not sentences.",
        search_tool_parameters_description={
            "tool_keywords": "Single words only, e.g. 'hotel booking'.",
        },
    )
    • Adds LLMRanker component in haystack.components.rankers that reranks documents using a ChatGenerator and PromptBuilder with JSON-formatted LLM output; supports configurable prompts, optional custom chat generators, runtime top_k overrides, and serialization.
    • Agent system_prompt parameter now accepts Jinja2 message template syntax (e.g. {% message role='system' %}...{% endmessage %}), with runtime variables passed at run time alongside a required_variables init parameter for validation.
    • OpenAIChatGenerator, OpenAIResponsesChatGenerator, and AzureOpenAIResponsesChatGenerator now expose a SUPPORTED_MODELS class variable listing supported model IDs (e.g. gpt-4o, gpt-5-mini).
    • SearchableToolset adds three new optional __init__ parameters — search_tool_name, search_tool_description, and search_tool_parameters_description — to customize the bootstrap search tool's LLM-facing metadata.
    • Adds run_async method to EmbeddingBasedDocumentSplitter enabling async embedding-based document splitting.
    +5 moreshow less
    • HuggingFaceAPIDocumentEmbedder.run_async gains a concurrency_limit parameter to control concurrent embedding inference requests, improving async throughput.
    • Components whose input types are a union of lists (e.g. list[str] | list[ChatMessage]) now support multiple input connections in pipelines, extending beyond the previous bare-list and optional-list limitation.
    • The messages runtime parameter to Agent.run is now optional, allowing the agent to execute with only a user_prompt.
    • Pipeline and AsyncPipeline now log a warning identifying misconfigured components when a component returns output keys not declared in its @component.output_types, replacing a previously confusing 'Pipeline Blocked' error.
    • Adds Python 3.14 support to Haystack.
  13. v2.25.1 Feb 27, 2026 · issue -171

    Haystack v2.25.1 extends auto variadic sockets to support Optional[list[...]] input types.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.25.1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.25.1
    • Auto variadic sockets now support Optional[list[...]] input types in addition to plain list[...], enabling nullable list inputs to participate in variadic connection fan-in.
  14. v2.25.0 Feb 26, 2026 · issue -172

    Haystack v2.25.0 adds SearchableToolset for BM25 tool discovery, a simplified LLM component, and Jinja2-templated Agent prompts.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.25.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.25.0
    └──▷ USE IT
    Let an agent search a large tool catalog at runtime instead of loading every tool into context upfront.
    python
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIChatGenerator
    from haystack.dataclasses import ChatMessage
    from haystack.tools import Tool, SearchableToolset
    
    catalog = [
        Tool(name="get_weather", description="Get weather for a city"),
        Tool(name="search_web", description="Search the web"),
        # ... hundreds more tools
    ]
    toolset = SearchableToolset(catalog=catalog)
    
    agent = Agent(chat_generator=OpenAIChatGenerator(), tools=toolset)
    result = agent.run(messages=[ChatMessage.from_user("What's the weather in Milan?")])
    Reuse a templated Agent prompt across multiple invocations — useful for translation or summarization pipelines where only the input variable changes.
    python
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIChatGenerator
    
    agent = Agent(
        chat_generator=OpenAIChatGenerator(),
        system_prompt="You are a helpful translation assistant.",
        user_prompt="""{% message role="user"%}
        Translate the following document to {{ language }}: {{ document }}
        {% endmessage %}""",
        required_variables=["language", "document"],
    )
    
    result = agent.run(language="French", document="The weather is lovely today.")
    Use the new LLM component for single-turn, tool-free generation with a templated prompt — ideal for document summarization steps inside a pipeline.
    python
    from haystack.components.generators.chat import LLM, OpenAIChatGenerator
    
    llm = LLM(
        chat_generator=OpenAIChatGenerator(),
        system_prompt="You are a helpful assistant.",
        user_prompt="""{% message role="user"%}
    Summarize the following document: {{ document }}
    {% endmessage %}""",
        required_variables=["document"],
    )
    
    result = llm.run(document="Haystack v2.25.0 introduces SearchableToolset and a new LLM component.")
    print(result["last_message"].text)
    • Adds SearchableToolset to haystack.tools, enabling agents to dynamically discover tools from large catalogs via BM25 keyword search; starts agents with a single search_tools function and supports configurable search threshold for automatic passthrough mode and top-k result limiting.
    • Adds user_prompt and required_variables parameters to the Agent component, enabling reusable Jinja2-templated user prompts that can be passed dynamic variables at runtime without manually constructing ChatMessage objects.
    • Adds new LLM component at haystack.components.generators.chat.LLM — a single-turn, tool-free text generation interface supporting system prompts, Jinja2-templated user_prompt, required_variables, streaming callbacks, and both run and run_async execution.
    • Adds link_format parameter to PPTXToDocument and XLSXToDocument converters, supporting hyperlink extraction in 'markdown' ([text](url)), 'plain' (text (url)), or 'none' (default, text only) formats.
    • Adds FileToFileContent component to convert local files into FileContent objects that can be embedded into ChatMessage for LLM input.
    +5 moreshow less
    • Adds document_comparison_field parameter to DocumentMRREvaluator, DocumentMAPEvaluator, and DocumentRecallEvaluator, enabling document comparison by fields other than content, including id and metadata keys via meta.<key> syntax.
    • Adds support for transformers v5, unlocking faster model loading, improved quantization support, and faster inference for selected models while retaining compatibility with v4.
    • Haystack now emits a Warning when dataclass instances (Document, ChatMessage, StreamingChunk, ByteStream, SparseEmbedding) are mutated in place, guiding users toward dataclasses.replace for safe copies.
    • LLMDocumentContentExtractor now extracts both content and metadata from image-based documents — when the LLM returns JSON, document_content fills the document body and other keys are merged into metadata; errors are now recorded in extraction_error metadata instead of content_extraction_error.
    • EmbeddingBasedDocumentSplitter and MultiQueryEmbeddingRetriever now automatically invoke warm_up() when run() is called if not yet warmed up.
    └──▷ BREAKING ON UPGRADE
    • !The PipelineTemplate and PredefinedPipeline classes and the Pipeline.from_template() method have been removed; migrate to YAML-based pipeline definitions.
    • !HuggingFaceLocalGenerator default task changed from text2text-generation to text-generation and default model changed from google/flan-t5-base to Qwen/Qwen3-0.6B; existing configs explicitly setting task='text2text-generation' must be updated to task='text-generation' or pin transformers<5.
  15. v2.24.0 Feb 12, 2026 · issue -186

    Haystack v2.24.0 eliminates adapter boilerplate with native type coercion, adds FileContent for PDF inputs, and introduces MarkdownHeaderSplitter.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.24.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.24.0
    └──▷ USE IT
    Attach a PDF to a chat message and send it to an OpenAI model for summarization — no file-parsing pipeline required.
    python
    from haystack.components.generators.chat.openai import OpenAIChatGenerator
    from haystack.dataclasses.chat_message import ChatMessage
    from haystack.dataclasses.file_content import FileContent
    
    file_content = FileContent.from_url("https://arxiv.org/pdf/2309.08632")
    chat_message = ChatMessage.from_user(content_parts=[file_content, "Summarize this paper in 100 words."])
    llm = OpenAIChatGenerator(model="gpt-4.1-mini")
    response = llm.run(messages=[chat_message])
    Wire two file-type converters directly to a DocumentWriter without a DocumentJoiner in an ingestion pipeline.
    python
    from haystack import Pipeline
    from haystack.components.converters import HTMLToDocument, TextFileToDocument
    from haystack.components.routers import FileTypeRouter
    from haystack.components.writers import DocumentWriter
    from haystack.dataclasses import ByteStream
    from haystack.document_stores.in_memory import InMemoryDocumentStore
    
    doc_store = InMemoryDocumentStore()
    pipe = Pipeline()
    pipe.add_component("router", FileTypeRouter(mime_types=["text/plain", "text/html"]))
    pipe.add_component("txt_converter", TextFileToDocument())
    pipe.add_component("html_converter", HTMLToDocument())
    pipe.add_component("writer", DocumentWriter(doc_store))
    
    pipe.connect("router.text/plain", "txt_converter.sources")
    pipe.connect("router.text/html", "html_converter.sources")
    pipe.connect("txt_converter.documents", "writer.documents")
    pipe.connect("html_converter.documents", "writer.documents")
    Build a query-rewriting RAG pipeline where the LLM's list[ChatMessage] output is automatically coerced to str for the BM25 retriever — no OutputAdapter needed.
    python
    from haystack import Pipeline
    from haystack.components.builders import ChatPromptBuilder
    from haystack.components.generators.chat import OpenAIChatGenerator
    from haystack.components.retrievers import InMemoryBM25Retriever
    from haystack.document_stores.in_memory import InMemoryDocumentStore
    
    p = Pipeline()
    p.add_component("prompt_builder", ChatPromptBuilder(template=template))
    p.add_component("llm", OpenAIChatGenerator(model="gpt-4.1-mini"))
    p.add_component("retriever", InMemoryBM25Retriever(document_store=document_store, top_k=3))
    
    # list[ChatMessage] from llm is auto-converted to str for retriever
    p.connect("prompt_builder", "llm")
    p.connect("llm", "retriever")
    • Introduces the FileContent dataclass (importable from haystack.dataclasses.file_content) enabling ChatMessage objects to carry file inputs (e.g. PDFs via FileContent.from_url(...)) for OpenAIChatGenerator and AzureOpenAIChatGenerator, with OpenAIResponsesChatGenerator and AzureOpenAIResponsesChatGenerator also supported.
    • Introduces the MarkdownHeaderSplitter component that splits documents at Markdown headers (#, ##, etc.), preserves header hierarchy as metadata, supports secondary splitting modes (word, passage, period, or line) via Haystack's DocumentSplitter, and handles edge cases such as no headers or empty content.
    • Adds delete_all_documents(), update_by_filter(), and delete_by_filter() operations to InMemoryDocumentStore, with corresponding standard DocumentStore tests for all three.
    • Adds run_async method to SearchApiWebSearch and SerperDevWebSearch components.
    • Pipelines now natively connect multiple list[T] outputs to a single list[T] input without a ListJoiner or DocumentJoiner, enabling direct multi-converter-to-writer wiring via pipe.connect().
    +4 moreshow less
    • Pipelines automatically convert between ChatMessage and str types on connection: str → user ChatMessage, and ChatMessagestr (via .text); raises PipelineRuntimeError if .text is None.
    • Pipelines support list wrapping (Tlist[T]) and list collapsing (list[T]T using first element, for str and ChatMessage only); raises PipelineRuntimeError on empty list.
    • Agent components now accept a tuple of tool names as a key in confirmation_strategies, allowing multiple tools to share a single BlockingConfirmationStrategy instead of requiring one entry per tool.
    • All Rankers (HuggingFaceTEIRanker, LostInTheMiddleRanker, MetaFieldRanker, MetaFieldGroupingRanker, SentenceTransformersDiversityRanker, SentenceTransformersSimilarityRanker, TransformersSimilarityRanker) now deduplicate documents by id before ranking, removing the need for a DocumentJoiner after hybrid retrieval.
    └──▷ BREAKING ON UPGRADE
    • !All Rankers (HuggingFaceTEIRanker, LostInTheMiddleRanker, MetaFieldRanker, MetaFieldGroupingRanker, SentenceTransformersDiversityRanker, SentenceTransformersSimilarityRanker, TransformersSimilarityRanker) now deduplicate documents by id before ranking; pipelines that relied on duplicate documents with the same user-defined id passing through the ranker will silently drop those duplicates.
    • !MultiQueryEmbeddingRetriever and MultiQueryTextRetriever now deduplicate by id instead of by document content; setups where multiple documents share identical content but different id values will no longer be deduplicated, and setups expecting content-based deduplication will behave differently.
    • !The deprecated deserialize_document_store_in_init_params_inplace function (deprecated in Haystack 2.23.0) has been removed.
  16. v2.23.0 Jan 27, 2026 · issue -202

    Haystack v2.23.0 adds human-in-the-loop agent confirmation strategies, image-returning tools, and automatic custom-component serialization.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.23.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.23.0
    └──▷ USE IT
    Return an image from a tool and let an agent describe it using a multimodal provider.
    python
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIResponsesChatGenerator
    from haystack.tools import ComponentTool
    from haystack.dataclasses import ChatMessage, ImageContent
    from haystack import component
    
    @component
    class ImageRetriever:
        @component.output_types(images=list[ImageContent])
        def run(self):
            return {"images": [ImageContent.from_file_path("/data/image.jpg")]}
    
    image_tool = ComponentTool(
        component=ImageRetriever(),
        outputs_to_string={"raw_result": True, "source": "images"}
    )
    
    agent = Agent(
        chat_generator=OpenAIResponsesChatGenerator(model="gpt-5-nano"),
        system_prompt="Retrieve images and describe them.",
        tools=[image_tool],
    )
    result = agent.run(messages=[ChatMessage.from_user("Retrieve the image and describe it.")])
    print(result["last_message"].text)
    Persist a pipeline snapshot to a database instead of disk by supplying a custom callback to Pipeline.run().
    python
    import json
    
    def save_to_db(snapshot: dict) -> None:
        db.snapshots.insert_one({"data": json.dumps(snapshot)})
    
    result = pipeline.run(
        data={"query": "What is RAG?"},
        snapshot_callback=save_to_db
    )
    • Adds confirmation_strategies parameter to Agent, accepting per-tool BlockingConfirmationStrategy instances driven by AlwaysAskPolicy, AskOncePolicy, or NeverAskPolicy, with pluggable UIs (RichConsoleUI, SimpleConsoleUI) — enabling agents to pause for human approval before executing tools.
    • Expands ToolCallResult.result to accept lists of TextContent and ImageContent objects, allowing tools to return images to providers such as OpenAIResponsesChatGenerator and AnthropicChatGenerator.
    • Adds raw_result key support to the outputs_to_string parameter of Tool, ComponentTool, and PipelineTool for returning image results without string conversion.
    • Adds outputs_to_string parameter to create_tool_from_function and the @tool decorator for additional customization of tool output formatting.
    • Adds snapshot_callback parameter to Pipeline.run() to handle pipeline snapshots with a custom function (e.g., saving to a database or remote service) instead of the default file-saving behavior.
    +4 moreshow less
    • Adds HAYSTACK_PIPELINE_SNAPSHOT_SAVE_ENABLED environment variable to explicitly enable saving pipeline snapshots to disk (disabled by default); custom snapshot_callback functions are invoked regardless of this setting.
    • component_from_dict() and component_to_dict() now automatically handle serialization of custom components containing DocumentStore, Secret, ComponentDevice, or any object with to_dict()/from_dict() — no manual override needed.
    • OpenAIResponsesChatGenerator now supports flattened generation_kwargs keys reasoning_effort, reasoning_summary, and verbosity directly, without nesting them in sub-objects.
    • Adds haystack.component.fully_qualified_type field to component tracing output, providing the full module path and class name (e.g., haystack.components.generators.chat.openai.OpenAIChatGenerator) alongside the existing haystack.component.type field.
    └──▷ BREAKING ON UPGRADE
    • !Pipeline snapshot file saving is now disabled by default; set HAYSTACK_PIPELINE_SNAPSHOT_SAVE_ENABLED=true to restore the previous behavior.
    • !Pipeline snapshots created before Haystack 2.22.0 that contain pipeline_outputs without the serialization_schema and serialized_data structure are no longer supported — recreate snapshots with the current version before upgrading.
    • !The return_empty_on_no_match parameter has been fully removed from RegexTextExtractor; passing it during component initialization now raises an error (it is silently ignored during pipeline deserialization).
  17. v2.22.0 Jan 8, 2026 · issue -221

    Haystack v2.22.0 adds semantic document splitting, auto warm-up, multi-output tools, and Qwen3 reranker support.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.22.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.22.0
    └──▷ USE IT
    Split a long document into semantically coherent chunks instead of fixed-size windows, so downstream retrievers see topically consistent passages.
    python
    from haystack.components.embedders import SentenceTransformersDocumentEmbedder
    from haystack.components.preprocessors import EmbeddingBasedDocumentSplitter
    
    embedder = SentenceTransformersDocumentEmbedder()
    splitter = EmbeddingBasedDocumentSplitter(
        document_embedder=embedder,
        sentences_per_group=2,
        percentile=0.95,
        min_length=50,
        max_length=1000
    )
    result = splitter.run(documents=[doc])
    Give an LLM agent formatted search results and a count summary from a single tool call, hiding raw debug data from the model.
    python
    from haystack.tools import Tool
    
    tool = Tool(
        name="search",
        description="Search for documents",
        parameters={...},
        function=search_func,
        outputs_to_string={
            "formatted_docs": {"source": "documents", "handler": format_documents},
            "summary":        {"source": "metadata",  "handler": format_summary}
            # 'debug_info' is omitted and will not be stringified
        }
    )
    Rerank retrieved passages with the Qwen3 reranker model, which requires custom prefix/suffix tokens around query and document text.
    python
    from haystack.components.rankers.sentence_transformers_similarity import SentenceTransformersSimilarityRanker
    
    ranker = SentenceTransformersSimilarityRanker(
        model="tomaarsen/Qwen3-Reranker-0.6B-seq-cls",
        query_prefix='<|im_start|>system\nJudge whether the Document meets the requirements...\n<Query>: ',
        query_suffix="\n",
        document_prefix="<Document>: ",
        document_suffix="<|im_end|>\n<|im_start|>assistant\n<think>\n\n</think>\n\n",
    )
    result = ranker.run(query="Which planet is known as the Red Planet?", documents=[...])
    • Adds EmbeddingBasedDocumentSplitter to haystack.components.preprocessors, splitting documents by semantic similarity using a pluggable embedder; constructor accepts document_embedder, sentences_per_group, percentile, min_length, and max_length parameters.
    • Adds outputs_to_string configuration to Tool, letting a single tool expose multiple named string outputs (each with a source and handler) so the LLM receives rich, selectively stringified context without additional tool calls.
    • Adds query_suffix and document_suffix parameters to SentenceTransformersSimilarityRanker, enabling compatibility with the Qwen3 reranker model family (e.g., tomaarsen/Qwen3-Reranker-0.6B-seq-cls).
    • Adds enable_thinking parameter to chat generators for thinking-capable models, allowing intermediate chain-of-thought reasoning steps before final responses.
    • Adds reasoning content support to HuggingFaceAPIChatGenerator, extracting chain-of-thought output (e.g., from DeepSeek R1) in both streaming and non-streaming modes; accessible via reply.reasoning.reasoning_text.
    +4 moreshow less
    • Components with a warm_up method now execute it automatically on first use, eliminating the need to call warm_up() manually before standalone usage.
    • Adds construction-time validation of inputs_from_state and outputs_to_state parameters in the Tool class, catching invalid state-mapping configuration early via function introspection and JSON schema checks.
    • Adds support for PEP 604 union type syntax (X | Y, X | None) in component type annotations alongside the existing Union[X, Y] / Optional[X] forms.
    • Agent tracing spans are now nested under the component span when an Agent runs inside a Pipeline, enabling proper hierarchical trace visualization in Datadog, Braintrust, and OpenTelemetry backends.
    └──▷ BREAKING ON UPGRADE
    • !Python 3.9 is no longer supported; Haystack now requires Python 3.10 or later.
    • !HuggingFaceLocalChatGenerator now defaults to Qwen/Qwen3-0.6B, replacing the previous default model — existing pipelines that relied on the old default will silently switch models on upgrade.
  18. v2.21.0 Dec 8, 2025 · issue -252

    Haystack v2.21.0 adds Multi-Query RAG components and async support for FilterRetriever and AutoMergingRetriever.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.21.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.21.0
    └──▷ USE IT
    Expand an ambiguous or short query into multiple variations and retrieve a broader set of relevant documents using BM25.
    python
    from haystack.components.query import QueryExpander
    from haystack.components.retrievers import InMemoryBM25Retriever, MultiQueryTextRetriever
    from haystack.document_stores.in_memory import InMemoryDocumentStore
    from haystack.components.writers import DocumentWriter
    from haystack import Document
    from haystack.document_stores.types import DuplicatePolicy
    
    store = InMemoryDocumentStore()
    writer = DocumentWriter(document_store=store, policy=DuplicatePolicy.SKIP)
    writer.run(documents=[Document(content="Renewable energy comes from wind and sunlight.")])
    
    expander = QueryExpander()
    retriever = InMemoryBM25Retriever(document_store=store, top_k=3)
    multi_retriever = MultiQueryTextRetriever(retriever=retriever)
    
    expanded = expander.run(query="renewable energy")
    results = multi_retriever.run(queries=expanded["queries"])
    for doc in results["documents"]:
        print(doc.content)
    • Adds QueryExpander component (importable from haystack.components.query) to generate semantically similar query variations for broader search coverage.
    • Adds MultiQueryTextRetriever (importable from haystack.components.retrievers) to run multiple queries in parallel against a text-based retriever (e.g., BM25) and merge results by score.
    • Adds MultiQueryEmbeddingRetriever (importable from haystack.components.retrievers) to perform multi-query retrieval using embeddings for richer semantic recall.
    • Adds return_empty_on_no_match parameter to RegexTextExtractor.__init__() (default True); set to False to return {'captured_text': ''} instead of {} when no regex match is found, ensuring consistent output structure for pipeline integration.
    • FilterRetriever and AutoMergingRetriever components now support asynchronous execution.
    └──▷ BREAKING ON UPGRADE
    • !The default model for AzureOpenAIGenerator and AzureOpenAIChatGenerator changed from gpt-4o-mini to gpt-4.1-mini, and the default API version changed from 2023-05-15 to 2024-12-01-preview.
    • !The default model for OpenAIChatGenerator and OpenAIGenerator changed from gpt-4o-mini to gpt-5-mini; explicitly pass model='gpt-4o-mini' at initialization to retain the previous behavior.
  19. v2.20.0 Nov 13, 2025 · issue -277

    Haystack v2.20.0 adds OpenAI Responses API components, async retriever support, and richer AnswerBuilder controls.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.20.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.20.0
    └──▷ USE IT
    Use OpenAI's Responses API with a reasoning model and built-in web search tool to get answers with low reasoning effort.
    python
    from haystack.components.generators.chat import OpenAIResponsesChatGenerator
    from haystack.dataclasses import ChatMessage
    
    chat_generator = OpenAIResponsesChatGenerator(
        model="o3-mini",
        generation_kwargs={"summary": "auto", "effort": "low"},
        tools=[{"type": "web_search"}],
    )
    response = chat_generator.run(messages=[ChatMessage.from_user("What's a positive news story from today?")])
    print(response["replies"][0].text)
    • Adds OpenAIResponsesChatGenerator component integrating OpenAI's Responses API, supporting reasoning summaries via generation_kwargs (e.g. summary, effort), native OpenAI/MCP tool formats, and Haystack Tool/Toolset objects.
    • Adds AzureOpenAIResponsesChatGenerator component bringing the same Responses API capabilities to Azure OpenAI deployments, configured via azure_endpoint and azure_deployment.
    • Returns logprobs in ChatMessage.meta for OpenAIChatGenerator and OpenAIResponsesChatGenerator when logprobs are enabled in generation_kwargs.
    • Adds extra field to ToolCall and ToolCallDelta dataclasses to store provider-specific information.
    • Adds run_async() method to SentenceWindowRetriever for use in async pipelines and workflows.
    +8 moreshow less
    • Adds warm_up() method to OpenAIChatGenerator, AzureOpenAIChatGenerator, HuggingFaceAPIChatGenerator, HuggingFaceLocalChatGenerator, and FallbackChatGenerator to initialize tools before pipeline execution without requiring an Agent component.
    • Adds return_only_referenced_documents parameter (default: True) to AnswerBuilder, plus source_index (1-based) and referenced (boolean) fields in returned document meta dictionaries.
    • Adds generation_kwargs parameter to the Agent component for run-time control over chat generation.
    • Adds revision parameter to SentenceTransformersDocumentEmbedder, SentenceTransformersTextEmbedder, SentenceTransformersSparseDocumentEmbedder, and SentenceTransformersSparseTextEmbedder for pinning a specific model version from the Hugging Face Hub.
    • Updates PipelineSnapshots serialization and deserialization to work with pydantic BaseModels.
    • Updates Agent, LLMMetadataExtractor, LLMMessagesRouter, and LLMDocumentContentExtractor to automatically call self.warm_up() at runtime if not already warmed up, removing the need for a manual pre-call.
    • Improves log-trace correlation for DatadogTracer using ddtrace.tracer.get_log_correlation_context().
    • Redesigns Toolset.warm_up() so the base method warms all tools by default, with subclasses able to override for custom initialization; simplifies warm_up_tools() to delegate to Toolset.warm_up().
  20. v2.19.0 Oct 20, 2025 · issue -301

    Haystack v2.19.0 adds FallbackChatGenerator, sparse embedders, RegexTextExtractor, and mixed Tool/Toolset support for agents.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.19.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.19.0
    └──▷ USE IT
    Build a resilient chat pipeline that automatically falls back through Anthropic, Google, and OpenAI when earlier providers fail.
    python
    from haystack.components.generators.chat.fallback import FallbackChatGenerator
    from haystack.components.generators.chat.openai import OpenAIChatGenerator
    from haystack_integrations.components.generators.anthropic import AnthropicChatGenerator
    from haystack.dataclasses import ChatMessage
    
    chat_generator = FallbackChatGenerator(chat_generators=[
        AnthropicChatGenerator(model="claude-sonnet-4-5", timeout=5),
        OpenAIChatGenerator(model="gpt-4o-mini"),
    ])
    response = chat_generator.run(messages=[ChatMessage.from_user("Summarize the OWASP Top 10.")])
    print(response["meta"]["successful_chat_generator_class"])
    print(response["replies"][0].text)
    Embed documents as sparse vectors for efficient inverted-index retrieval with QdrantDocumentStore.
    python
    from haystack.components.embedders import SentenceTransformersSparseTextEmbedder
    
    embedder = SentenceTransformersSparseTextEmbedder()
    embedder.warm_up()
    result = embedder.run("Detect lateral movement via SMB.")
    print(result["sparse_embedding"])  # SparseEmbedding(indices=[...], values=[...])
    Mix standalone tools and toolsets in a single Agent, and override the tool subset at runtime for a specific invocation.
    python
    from haystack.components.agents import Agent
    from haystack.tools import Tool, Toolset
    
    agent = Agent(
        chat_generator=generator,
        tools=[math_toolset, weather_toolset, calendar_tool],
    )
    # At runtime, restrict to only the tools needed for this task
    response = agent.run(
        messages=[ChatMessage.from_user("What is 42 * 7?")],
        tools=["multiply"],
    )
    • Adds FallbackChatGenerator in haystack.components.generators.chat.fallback that tries a list of chat generators sequentially and returns the first successful response, with meta['successful_chat_generator_class'] identifying which provider succeeded — handles timeouts, rate limits, and server errors transparently.
    • Adds conversion_mode='row' parameter to CSVToDocument, with optional content_column; each CSV row becomes a separate Document with remaining columns stored in meta (default 'file' mode preserved).
    • Adds pipeline_snapshot and pipeline_snapshot_file_path parameters to BreakpointException, and pipeline_snapshot_file_path to PipelineRuntimeError, for easier location and inspection of stored pipeline snapshots.
    • Introduces SentenceTransformersSparseTextEmbedder and SentenceTransformersSparseDocumentEmbedder components in haystack.components.embedders for sparse embedding models compatible with Sentence Transformers; output SparseEmbedding objects are compatible with QdrantDocumentStore.
    • Adds warm_up() method to the Tool dataclass and Toolset, automatically called by Agent and ToolInvoker during their warmup phase to support pre-execution initialization such as database connections or model loading.
    +6 moreshow less
    • Adds a new RegexTextExtractor component that extracts text from chat messages or string inputs based on a custom regex pattern.
    • Adds tools as a runtime parameter to Agent.run(), allowing callers to supply a subset of tool names or an entirely new set of Tool objects or a Toolset per invocation.
    • Extends the tools parameter on Agent, ToolInvoker, OpenAIChatGenerator, AzureOpenAIChatGenerator, HuggingFaceAPIChatGenerator, and HuggingFaceLocalChatGenerator to accept a mixed list of Tool and Toolset objects in the same list.
    • Enables resuming an Agent from an AgentSnapshot while simultaneously specifying a new breakpoint in the same run call, supporting stepwise debugging with precise control over chat generator and tool inputs.
    • Updates PipelineSnapshot serialization and deserialization to support Python Enum classes.
    • Adds raise_on_failure option to _save_pipeline_snapshot to control whether save failures raise an exception or are only logged.
    └──▷ BREAKING ON UPGRADE
    • !Requires openai>=1.99.2 due to use of ChatCompletionMessageCustomToolCall; installations with older OpenAI client versions will break.
  21. v2.18.1 Sep 29, 2025 · issue -321

    Haystack v2.18.1 lets agents accept a runtime tools parameter to swap or subset tools per invocation.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.18.1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.18.1
    • Adds tools to agent run parameters, allowing callers to pass a list of tool names (subset selection) or Tool objects / a Toolset (full replacement) at runtime.
  22. v2.18.0 Sep 22, 2025 · issue -328

    Haystack v2.18.0 adds pipeline error snapshots with resume support, PipelineTool, structured outputs for OpenAI generators, and runtime Agent system prompts.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.18.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.18.0
    └──▷ USE IT
    Recover a failed pipeline run and resume from the last successful checkpoint instead of restarting from scratch.
    python
    try:
        pipeline.run(data=input_data)
    except PipelineRuntimeError as exc_info:
        snapshot = exc_info.value.pipeline_snapshot
        intermediate_outputs = snapshot.pipeline_state.pipeline_outputs
        # inspect outputs, fix the issue, then resume
        pipeline.run(data={}, snapshot=snapshot)
    Wrap a retrieval pipeline as an LLM-callable tool for use inside an Agent multi-step reasoning workflow.
    python
    from haystack import Pipeline
    from haystack.tools import PipelineTool
    
    retrieval_pipeline = Pipeline()
    # ... add components ...
    
    retrieval_tool = PipelineTool(
        pipeline=retrieval_pipeline,
        input_mapping={"query": ["bm25_retriever.query"]},
        output_mapping={"ranker.documents": "documents"},
        name="retrieval_tool",
        description="Use to retrieve documents",
    )
    Extract structured data from unstructured text using a Pydantic model as the response format.
    python
    from pydantic import BaseModel
    from haystack.components.generators.chat import OpenAIChatGenerator
    from haystack.dataclasses import ChatMessage
    
    class CalendarEvent(BaseModel):
        event_name: str
        event_date: str
        event_location: str
    
    generator = OpenAIChatGenerator(
        model="gpt-4o-2024-08-06",
        generation_kwargs={"response_format": CalendarEvent}
    )
    result = generator.run([ChatMessage.from_user("The Open NLP Meetup is in Berlin on September 19.")])
    print(result["replies"][0].text)
    • Adds snapshot argument to pipeline.run() to resume a failed pipeline from its last successful checkpoint, and exposes pipeline_snapshot.pipeline_state.pipeline_outputs on the PipelineRuntimeError exception for mid-run inspection.
    • Adds PipelineTool class in haystack.tools to expose full Haystack Pipelines as LLM-compatible tools, with input_mapping and output_mapping arguments for fine-grained control over which pipeline inputs and outputs are visible to the LLM.
    • Adds response_format support (Pydantic model or JSON schema) in generation_kwargs for OpenAIChatGenerator and AzureOpenAIChatGenerator; Pydantic models are supported for non-streaming, JSON schema for streaming responses.
    • Adds request_headers parameter to LinkContentFetcher for custom per-request HTTP headers, with precedence order: httpx client defaults → component defaults → request_headers → rotating User-Agent.
    • Adds exclude_subdomains parameter to SerperDevWebSearch; when True, restricts results to exact domains in allowed_domains, filtering out subdomains (defaults to False for backward compatibility).
    +3 moreshow less
    • Adds reasoning field to StreamingChunk accepting an optional ReasoningContent dataclass for structured reasoning content in streaming responses.
    • Adds system_prompt to Agent run parameters, enabling dynamic runtime override of the agent's system prompt.
    • Adds HTTP/2 graceful fallback in LinkContentFetcher: if the h2 package is not installed, falls back to HTTP/1.1 with a warning instead of raising an error.
  23. v2.17.0 Aug 19, 2025 · issue -362

    Haystack v2.17.0 adds image support for 12 model providers, ReasoningContent in ChatMessage, and ByteStream routing in MetadataRouter.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.17.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.17.0
    └──▷ USE IT
    Store model reasoning output in an assistant message for providers that expose chain-of-thought or reasoning traces.
    python
    from haystack.dataclasses import ChatMessage
    
    msg = ChatMessage.from_assistant(
        text="The answer is 42.",
        reasoning="First I considered the problem domain, then narrowed down..."
    )
    print(msg.reasoning)
    Override the active tool set at runtime in a previously built pipeline without rebuilding it.
    python
    tool_invoker.run(
        messages=chat_history,
        tools=[search_tool, calculator_tool]  # overrides constructor tools
    )
    • Adds ReasoningContent as a new content part to ChatMessage, storable via the reasoning parameter in ChatMessage.from_assistant(), enabling assistant messages to carry model reasoning text and metadata.
    • Extends SentenceWindowRetriever's source_id_meta_field parameter to accept a list of strings, so only documents matching all specified meta fields are retrieved.
    • Adds raise_on_failure parameter to FileTypeRouter (default False); when set to True, always raises FileNotFoundError for non-existent files.
    • Extends ToolInvoker.run() to accept a tools list argument that overrides the tools set at construction time, enabling runtime tool switching in pre-built pipelines.
    • Adds support for the | union type operator (Python 3.10+) in serialize_type and Pipeline.connect(), alongside existing typing.Union support.
    +5 moreshow less
    • Expands multimodal image support to Amazon Bedrock, Anthropic, Azure, Google, Hugging Face API, Meta Llama API, Mistral, Nvidia, Ollama, OpenAI, OpenRouter, and STACKIT providers.
    • Adds multimodal support to HuggingFaceAPIChatGenerator for vision-language model usage, allowing both text and images to be sent via Hugging Face APIs.
    • Extends MetadataRouter to route list[ByteStream] objects in addition to list[Documents].
    • Adds serialization/deserialization methods for TextContent and ImageContent parts of ChatMessage.
    • Supports subclasses of ChatMessage in Agent state schema validation, checking issubclass(args[0], ChatMessage) instead of requiring exact type equality.
    └──▷ BREAKING ON UPGRADE
    • !MultiFileConverter now outputs a new failed key in its result dictionary containing files that failed to convert; the documents output is only included when at least one file is successfully converted (previously documents could be present but empty).
    • !HuggingFaceAPIChatGenerator now applies the updated finish_reason mapping consistently regardless of streaming mode: eos_tokenstop, stop_sequencestop, tool calls present → tool_calls. Previously this mapping was only applied when streaming was enabled.
  24. v2.16.0 Jul 29, 2025 · issue -364

    Haystack v2.16.0 adds Agent Breakpoints, multimodal image pipelines, HuggingFace TEI reranking, and parallel tool invocation.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.16.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.16.0
    └──▷ USE IT
    Pause an Agent mid-run to inspect its internal state during development — useful when debugging complex multi-step reasoning or tool chains.
    python
    from haystack.dataclasses.breakpoints import AgentBreakpoint, Breakpoint
    from haystack.dataclasses import ChatMessage
    
    chat_generator_breakpoint = Breakpoint(
        component_name="chat_generator",
        visit_count=0,
        snapshot_file_path="debug_snapshots"
    )
    agent_breakpoint = AgentBreakpoint(break_point=chat_generator_breakpoint, agent_name="calculator_agent")
    
    response = agent.run(
        messages=[ChatMessage.from_user("What is 7 * (4 + 2)?")],
        break_point=agent_breakpoint
    )
    Send an image URL to a vision-enabled LLM for description — the starting point for any multimodal RAG or agent pipeline.
    python
    from haystack.dataclasses import ImageContent, ChatMessage
    from haystack.components.generators.chat import OpenAIChatGenerator
    
    image_content = ImageContent.from_url("https://cdn.britannica.com/79/191679-050-C7114D2B/Adult-capybara.jpg")
    message = ChatMessage.from_user(
        content_parts=["Describe the image in short.", image_content]
    )
    
    llm = OpenAIChatGenerator(model="gpt-4o-mini")
    print(llm.run([message])["replies"][0].text)
    Build a multimodal prompt template that compares two images — enables dynamic prompt creation combining text and image inputs in a single ChatPromptBuilder call.
    python
    from haystack.components.builders import ChatPromptBuilder
    from haystack.dataclasses.chat_message import ImageContent
    
    template = """
    {% message role="user" %}
    Hello! I am {{user_name}}.
    What's the difference between the following images?
    {% for image in images %}
    {{ image | templatize_part }}
    {% endfor %}
    {% endmessage %}
    """
    
    builder = ChatPromptBuilder(template=template)
    result = builder.run(
        user_name="John",
        images=[
            ImageContent.from_file_path("apple-fruit.jpg"),
            ImageContent.from_file_path("apple-logo.jpg")
        ]
    )
    • Introduces AgentBreakpoint and Breakpoint classes (importable from haystack.dataclasses.breakpoints) to pause, inspect, and resume Agent execution mid-run; pass via the break_point argument to agent.run().
    • Adds ImageContent dataclass with base64_image, mime_type, detail, and metadata fields, plus convenience class methods ImageContent.from_url() and ImageContent.from_file_path().
    • Adds image input support to OpenAIChatGenerator via the new ImageContent dataclass embedded in ChatMessage content parts.
    • Adds PDFToImageContent, ImageFileToImageContent, DocumentToImageContent, and ImageFileToDocument converter components for building multimodal indexing and retrieval pipelines.
    • Adds LLMDocumentContentExtractor component to extract text from image-based documents using a vision-enabled LLM.
    +19 moreshow less
    • Adds SentenceTransformersDocumentImageEmbedder component to generate embeddings from image-based documents using models such as CLIP.
    • Adds DocumentLengthRouter component to route documents based on textual content length.
    • Adds DocumentTypeRouter component to route documents automatically based on MIME type metadata.
    • Extends ChatPromptBuilder to support special string templates (with {% message role='...' %} blocks and the templatize_part filter) enabling dynamic multimodal prompt creation with embedded images.
    • Adds tool_invoker_kwargs parameter to Agent to pass additional kwargs such as max_workers and enable_streaming_callback_passthrough through to ToolInvoker.
    • Adds enable_streaming_callback_passthrough parameter to ToolInvoker.__init__, run, and run_async; when True, forwards streaming_callback to any tool whose invoke method accepts it.
    • Adds new HuggingFaceTEIRanker component for reranking with the Text Embeddings Inference (TEI) API, supporting both self-hosted TEI services and Hugging Face Inference Endpoints.
    • Adds raise_on_failure boolean parameter to OpenAIDocumentEmbedder and AzureOpenAIDocumentEmbedder; defaults to False (preserving prior logging behavior); set to True to raise on API errors.
    • Adds source_id_meta_field, split_id_meta_field, and raise_on_missing_meta_fields parameters to SentenceWindowRetriever for customizable metadata field names and missing-field handling.
    • ToolInvoker now executes tool_calls in parallel in both sync and async modes.
    • Adds AsyncHFTokenStreamingHandler for async streaming support in HuggingFaceLocalChatGenerator.
    • Adds tool_calls, tool_call_result, index, and start fields to StreamingChunk for richer streaming callback formatting.
    • Adds ComponentInfo dataclass to haystack.dataclasses and passes it into StreamingChunk so callers can identify which component originated a stream; supported in OpenAIChatGenerator, AzureOpenAIChatGenerator, HuggingFaceAPIChatGenerator, and HuggingFaceLocalChatGenerator.
    • Adds to_dict and from_dict serialization methods to ByteStream, StreamingChunk, ToolCallResult, ToolCall, ComponentInfo, and ToolCallDelta.
    • Adds skip_empty_documents init parameter to DocumentSplitter (default True); set to False to retain non-textual documents for downstream components like LLMDocumentContentExtractor.
    • Adds return_embedding init parameter to InMemoryDocumentStore; bm25_retrieval and filter_documents now honor it to control whether embeddings are returned.
    • Adds guess_mime_type parameter to ByteStream.from_file_path().
    • Makes PipelineBase.validate_input a public method, allowing pre-runtime pipeline validation outside of Pipeline.run().
    • Raises a warning when all remaining pipeline components are blocked and no expected outputs (per Pipeline().outputs()) have been produced, aiding debugging of mutually exclusive branch pipelines.
    └──▷ BREAKING ON UPGRADE
    • !The deprecated async_executor parameter has been removed from ToolInvoker; use max_workers instead.
    • !The State class has been removed from haystack.dataclasses; import it from haystack.components.agents instead.
    • !The deserialize_value_with_schema_legacy function has been removed from base_serialization; objects serialized with Haystack 2.14.0 or older using the old State format can no longer be deserialized.
    • !All parameters of Pipeline.draw() and Pipeline.show() must now be passed as keyword arguments (positional arguments are no longer accepted).
    • !HuggingFaceAPIGenerator may no longer work with the Hugging Face Inference API; migrate to HuggingFaceAPIChatGenerator for generative models via the Hugging Face Inference API.
  25. v2.15.0 Jun 26, 2025 · issue -365

    Haystack v2.15.0 adds parallel tool calling, LLMMessagesRouter, HuggingFaceTEIRanker, and richer StreamingChunk fields.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.15.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.15.0
    └──▷ USE IT
    Route user messages through Llama Guard for content moderation before passing safe messages downstream.
    python
    from haystack.components.generators.chat import HuggingFaceAPIChatGenerator
    from haystack.components.routers.llm_messages_router import LLMMessagesRouter
    from haystack.dataclasses import ChatMessage
    
    chat_generator = HuggingFaceAPIChatGenerator(
        api_type="serverless_inference_api",
        api_params={"model": "meta-llama/Llama-Guard-4-12B", "provider": "groq"},
    )
    router = LLMMessagesRouter(
        chat_generator=chat_generator,
        output_names=["unsafe", "safe"],
        output_patterns=["unsafe", "safe"],
    )
    print(router.run([ChatMessage.from_user("How to rob a bank?")]))
    • Adds max_workers parameter to ToolInvoker.__init__ to configure the internal ThreadPoolExecutor used for parallel tool calling, replacing the deprecated async_executor parameter.
    • Adds enable_streaming_callback_passthrough parameter to ToolInvoker.init, ToolInvoker.run, and ToolInvoker.run_async; when True, passes the streaming_callback function to a tool's invoke method if the method accepts streaming_callback in its signature.
    • Adds raise_on_failure boolean parameter to OpenAIDocumentEmbedder and AzureOpenAIDocumentEmbedder; when True, raises an exception on API errors instead of logging and continuing (default is False).
    • Adds require_tool_call_ids parameter to ChatMessage.to_openai_dict_format; set to False to suppress errors when the id field is missing in a Tool Call, for compatibility with shallow OpenAI-compatible APIs (default is True).
    • Adds trust_remote_code parameter to SentenceTransformersSimilarityRanker; when True, enables execution of custom models and scripts hosted on the Hugging Face Hub.
    +10 moreshow less
    • Adds finish_reason field to StreamingChunk using a FinishReason type alias with values 'stop', 'length', 'tool_calls', 'content_filter', and Haystack-specific 'tool_call_results'; ToolInvoker sets finish_reason='tool_call_results' in the final chunk when tool execution completes.
    • Adds tool_calls, tool_call_result, index, and start fields to StreamingChunk, plus a new ToolCallDelta dataclass for StreamingChunk.tool_calls to represent argument string deltas.
    • Adds new ComponentInfo dataclass passed through StreamingChunk so streaming callbacks can identify which component produced each chunk; wired into OpenAIChatGenerator, AzureOpenAIChatGenerator, HuggingFaceAPIChatGenerator, HuggingFaceAPIGenerator, HuggingFaceLocalGenerator, and HuggingFaceLocalChatGenerator.
    • Introduces LLMMessagesRouter component (haystack.components.routers.llm_messages_router) that classifies and routes ChatMessage objects to named output connections using a generative LLM, supporting general-purpose and moderation-focused models like Llama Guard.
    • Introduces HuggingFaceTEIRanker component for end-to-end reranking via the Text Embeddings Inference (TEI) API, supporting both self-hosted TEI services and Hugging Face Inference Endpoints.
    • Adds AsyncHFTokenStreamingHandler for async streaming support in HuggingFaceLocalChatGenerator.
    • Makes PipelineBase.validate_input a public method so callers can validate pipeline connections before runtime without waiting for Pipeline.run.
    • Adds deserialize_component_inplace function for generic component deserialization that works with any component type.
    • All additional key-value pairs passed via api_params in HuggingFaceAPIGenerator and HuggingFaceAPIChatGenerator are now forwarded to the underlying Inference Client constructors, enabling parameters like timeout, headers, and provider (e.g., api_params={'provider': 'groq'} to route to a different inference provider).
    • Haystack's core modules now carry a py.typed marker and are fully type-annotated, enabling accurate static analysis in mypy and Pylance.
  26. v2.14.2 Jun 4, 2025 · issue -365

    Haystack v2.14.2 adds raise_on_failure to OpenAI document embedders for stricter API error handling.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.14.2 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.14.2
    └──▷ USE IT
    Fail fast during indexing pipelines when an OpenAI embedding API error occurs, so bad batches are never silently skipped.
    python
    from haystack.components.embedders import OpenAIDocumentEmbedder
    
    embedder = OpenAIDocumentEmbedder(raise_on_failure=True)
    • Adds raise_on_failure boolean parameter to OpenAIDocumentEmbedder and AzureOpenAIDocumentEmbedder: when set to True, the component raises an exception on API errors instead of silently logging and continuing; defaults to False to preserve existing behavior.
  27. v2.14.0 May 26, 2025 · issue -366

    Haystack v2.14.0 adds async tool streaming, a new SentenceTransformers ranker, SuperComponent pipeline visualization expansion, and agent last_message output.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.14.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.14.0
    └──▷ USE IT
    Stream tool call results in real time from an Agent using the updated streaming_callback parameter with print_streaming_chunk.
    python
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIChatGenerator
    from haystack.components.generators.utils import print_streaming_chunk
    from haystack.tools import ComponentTool
    from haystack.components.websearch import SerperDevWebSearch
    from haystack.dataclasses import ChatMessage
    
    web_search = ComponentTool(name="web_search", component=SerperDevWebSearch(top_k=5))
    
    agent = Agent(
        chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"),
        tools=[web_search],
        streaming_callback=print_streaming_chunk
    )
    
    result = agent.run(messages=[ChatMessage.from_user("What happened in AI news today?")])
    print(result["last_message"].text)
    Rank documents using the new SentenceTransformersSimilarityRanker with the ONNX backend for faster CPU inference.
    python
    from haystack.components.rankers import SentenceTransformersSimilarityRanker
    from haystack.utils.device import ComponentDevice
    from haystack.dataclasses import Document
    
    ranker = SentenceTransformersSimilarityRanker(
        model="sentence-transformers/all-MiniLM-L6-v2",
        device=ComponentDevice.from_str("cpu"),
        backend="onnx",
    )
    ranker.warm_up()
    docs = [Document(content="Berlin"), Document(content="Sarajevo")]
    output = ranker.run(query="City in Germany", documents=docs)
    print(output["documents"])
    Expand SuperComponents in a pipeline diagram to see all internal components when debugging or documenting complex pipelines.
    python
    from pathlib import Path
    from haystack import Pipeline
    from haystack.components.converters import MultiFileConverter
    from haystack.components.preprocessors import DocumentPreprocessor
    
    pipeline = Pipeline()
    pipeline.add_component("converter", MultiFileConverter())
    pipeline.add_component("preprocessor", DocumentPreprocessor())
    pipeline.connect("converter", "preprocessor")
    
    pipeline.draw(path=Path("expanded_pipeline.png"), super_component_expansion=True)
    • Adds streaming_callback parameter to ToolInvoker and Agent to emit tool results in real time during tool invocation (results emitted after tool execution completes, not incrementally).
    • Adds run_async method to ToolInvoker class to support asynchronous tool invocations, including streaming tool results.
    • Adds last_message output field to the Agent component for direct access to the final generated ChatMessage.
    • Adds last_message_only parameter to AnswerBuilder to process only the final reply while preserving full conversation history in metadata.
    • Adds all_messages key to the meta field of GeneratedAnswer objects in AnswerBuilder, storing all generated messages for traceability.
    +11 moreshow less
    • Adds super_component_expansion=True parameter to pipeline.draw() and pipeline.show() to expand SuperComponents into their constituent components in pipeline diagrams.
    • Introduces new SentenceTransformersSimilarityRanker component supporting PyTorch, ONNX, and OpenVINO inference backends via a backend parameter; requires sentence-transformers>=4.1.0.
    • Adds serialize_value and deserialize_value utility methods for consistent value serialization across modules.
    • Moves State class to agents.state module and adds serialization and deserialization capabilities.
    • Adds support for multiple outputs in ConditionalRouter.
    • Updates print_streaming_chunk to print ToolCall information when present in a chunk's metadata.
    • Adds a py.typed marker file to Haystack, enabling PEP 561 type information for downstream projects and type checkers such as mypy.
    • Adds token usage metadata (prompt and completion token counts) to ChatMessage returned by HuggingFaceAPIChatGenerator when streaming.
    • Adds a Protocol for TextEmbedder to simplify creation of custom components or SuperComponents that accept any TextEmbedder as an init parameter.
    • Adds Component signature validation method that reports mismatches between run and run_async method signatures to aid debugging of custom components.
    • Adds type hints to the component decorator, improving Pyright/Pylance support and IDE docstring display.
    └──▷ BREAKING ON UPGRADE
    • !The deprecated deserialize_tools_inplace utility function has been removed; replace all usages with deserialize_tools_or_toolset_inplace imported from haystack.tools.
  28. v2.13.0 Apr 22, 2025 · issue -367

    Haystack v2.13.0 adds async Agent support, a new Toolset class, the @super_component decorator, and broad http_client_kwargs proxy/SSL configuration.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.13.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.13.0
    └──▷ USE IT
    Run an async web-search agent — useful in async web servers or notebooks where blocking calls are not acceptable.
    python
    result = await web_search_agent.run_async(
        messages=[ChatMessage.from_user("Find information about Haystack by deepset")]
    )
    Group related tools into a Toolset and pass them to an Agent in one shot, simplifying tool management across large tool libraries.
    python
    from haystack.tools import Toolset
    from haystack.components.agents import Agent
    from haystack.components.generators.chat import OpenAIChatGenerator
    
    math_toolset = Toolset([tool_one, tool_two])
    agent = Agent(
        chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"),
        tools=math_toolset
    )
    Build a custom hybrid retriever SuperComponent with minimal boilerplate using the @super_component decorator.
    python
    from haystack import Pipeline, super_component
    from haystack.components.joiners import DocumentJoiner
    from haystack.components.embedders import SentenceTransformersTextEmbedder
    from haystack.components.retrievers import InMemoryBM25Retriever, InMemoryEmbeddingRetriever
    from haystack.document_stores.in_memory import InMemoryDocumentStore
    
    @super_component
    class HybridRetriever:
        def __init__(self, document_store: InMemoryDocumentStore):
            self.pipeline = Pipeline()
            self.pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder())
            self.pipeline.add_component("embedding_retriever", InMemoryEmbeddingRetriever(document_store))
            self.pipeline.add_component("bm25_retriever", InMemoryBM25Retriever(document_store))
            self.pipeline.add_component("document_joiner", DocumentJoiner(join_mode="reciprocal_rank_fusion"))
            self.pipeline.connect("text_embedder", "embedding_retriever")
            self.pipeline.connect("bm25_retriever", "document_joiner")
            self.pipeline.connect("embedding_retriever", "document_joiner")
    • Adds run_async method to Agent, calling the underlying ChatGenerator's run_async when available, enabling built-in async agent workflows.
    • Adds http_client_kwargs parameter to OpenAIChatGenerator, AzureOpenAIChatGenerator, AzureOpenAIGenerator, OpenAIGenerator, DALLEImageGenerator, OpenAIDocumentEmbedder, OpenAITextEmbedder, AzureOpenAITextEmbedder, AzureOpenAIDocumentEmbedder, and RemoteWhisperTranscriber for custom proxy and SSL configuration.
    • Introduces the Toolset class (importable from haystack.tools) for grouping, filtering, serializing, and reusing multiple Tool instances as a single unit passable to Agent, ChatGenerator, and ToolInvoker.
    • Adds @super_component decorator (importable from haystack) so any class with a pipeline attribute is automatically promoted to a full SuperComponent without manual wiring.
    • Adds two ready-made SuperComponents: MultiFileConverter and DocumentPreprocessor, encapsulating common indexing pipeline logic.
    +5 moreshow less
    • Adds run_async method to OpenAITextEmbedder, OpenAIDocumentEmbedder, AzureOpenAITextEmbedder, AzureOpenAIDocumentEmbedder, HuggingFaceAPIDocumentEmbedder, and HuggingFaceAPITextEmbedder for async embedding.
    • Agent tracing now captures inputs and outputs of each ChatGenerator and ToolInvoker call as dedicated child spans, enabling step-by-step visibility in tracers like Langfuse.
    • SuperComponents now support mapping non-leaf pipeline outputs to SuperComponent outputs via output_mapping.
    • Adds component_name and component_type attributes to PipelineRuntimeError, plus a new PipelineComponentsBlockedError subclass for pipelines where no components are unblocked.
    • Deprecates deserialize_tools_inplace utility function; deserialize_tools_or_toolset_inplace should be used instead (removal planned for Haystack 2.14.0).
    └──▷ BREAKING ON UPGRADE
    • !The api, api_key, and api_params parameters of LLMEvaluator, ContextRelevanceEvaluator, and FaithfulnessEvaluator have been removed; use the chat_generator parameter with a ChatGenerator configured for JSON output instead.
    • !The generator_api and generator_api_params parameters of LLMMetadataExtractor and the LLMProvider enum have been removed; use chat_generator instead.
  29. v2.12.0 Apr 2, 2025 · issue -367

    Haystack v2.12.0 adds an Agent component with state management, SuperComponent for reusable pipelines, AutoMergingRetriever, and Azure AD token support.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.12.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.12.0
    └──▷ USE IT
    Wrap an existing RAG pipeline as a SuperComponent to expose a single query input across a retriever and prompt builder.
    python
    from haystack import Pipeline, SuperComponent
    
    with open("rag_pipeline.yaml", "r") as f:
        pipeline = Pipeline.load(f)
    
    wrapper = SuperComponent(
        pipeline=pipeline,
        input_mapping={
            "query": ["retriever.query", "prompt_builder.query"],
        },
        output_mapping={"llm.replies": "replies"},
    )
    
    result = wrapper.run(query="What is the capital of France?")
    print(result["replies"])
    Split a CSV by individual rows instead of the default threshold, useful when each row is a self-contained record.
    python
    from haystack.components.preprocessors import CSVDocumentSplitter
    
    splitter = CSVDocumentSplitter(split_mode="row-wise")
    result = splitter.run(documents=docs)
    • Adds outputs_to_string parameter to Tool and ComponentTool to customize how tool output is converted into a string before being passed back to the ChatGenerator in a ChatMessage.
    • Adds split_mode parameter to CSVDocumentSplitter to control splitting mode; supports row-wise splitting in addition to the previous default threshold behavior.
    • Adds link_format parameter to DOCXToDocument (accepts 'markdown' or 'plain') to optionally include extracted hyperlink addresses in output Documents.
    • Adds azure_ad_token_provider parameter to AzureOpenAIGenerator, AzureOpenAIChatGenerator, AzureOpenAITextEmbedder, and AzureOpenAIDocumentEmbedder for Azure AD bearer-token authentication via a callable.
    • Introduces default_azure_token_provider utility function in haystack/utils/azure.py as a serializable default token provider for Azure AD authentication.
    +9 moreshow less
    • Adds run_async method to HuggingFaceLocalChatGenerator, using ThreadPoolExecutor internally to return awaitable coroutines.
    • Adds split_unit='token' support to RecursiveDocumentSplitter; uses the o200k_base tiktoken tokenizer (requires tiktoken installed).
    • Adds chat_generator initialization parameter to LLMEvaluator, ContextRelevanceEvaluator, and FaithfulnessEvaluator, enabling any ChatGenerator instance (not only OpenAI-compatible) for evaluation.
    • New Agent component in haystack.components.agents supports tool-calling with any chat model, streaming via streaming_callback, multiple exit_conditions, and a state_schema for shared state across tools.
    • New SuperComponent class in haystack.core.super_component.super_component wraps any Haystack Pipeline into a reusable component with input_mapping and output_mapping for simplified interfaces.
    • New AutoMergingRetriever retrieval technique, used together with HierarchicalDocumentSplitter, implements auto-merging retrieval.
    • Adds asynchronous functionality and HTTP/2 support to LinkContentFetcher.
    • New State dataclass with customizable schema for managing Agent state; ToolInvoker extended to work with the new State.
    • Supports date/time handling via arrow in ChatPromptBuilder, consistent with existing PromptBuilder behavior.
    └──▷ BREAKING ON UPGRADE
    • !ChatMessage.to_dict() now returns keys role, content, meta, and name — code that consumes the old dict format must be updated.
    • !The public generator attribute on LLMEvaluator, ContextRelevanceEvaluator, and FaithfulnessEvaluator is replaced by _chat_generator; code referencing .generator will break.
    • !to_pandas, comparative_individual_scores_report, and score_report are removed from EvaluationRunResult — use detailed_report, comparative_detailed_report, and aggregated_report instead.
    • !The Agent init parameter exit_condition is renamed to exit_conditions; existing code passing exit_condition= will break.
  30. v2.11.0 Mar 10, 2025 · issue -368

    Haystack v2.11.0 adds async run to all core chat generators and retrievers, a new MSGToDocument component, and ONNX/OpenVINO backend support for Sentence Transformers.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.11.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.11.0
    └──▷ USE IT
    Convert an Outlook email (with attachments) into Haystack Documents for ingestion into a pipeline.
    python
    from haystack.components.converters import MSGToDocument
    
    converter = MSGToDocument()
    result = converter.run(sources=["email.msg"])
    print(result["documents"][0].meta)  # sender, recipients, subject, etc.
    print(result["bytestream_outputs"])  # attachments as ByteStream objects
    Disable connection type validation when prototyping a pipeline that mixes Optional and non-Optional socket types.
    python
    from haystack import Pipeline
    
    pipeline = Pipeline(connection_type_validation=False)
    # Now connect Optional[str] -> str without a TypeError
    pipeline.connect("component_a.optional_output", "component_b.str_input")
    Run an async pipeline using OpenAIChatGenerator's new run_async method for concurrent throughput.
    python
    import asyncio
    from haystack import AsyncPipeline
    from haystack.components.generators.chat import OpenAIChatGenerator
    from haystack.dataclasses import ChatMessage
    
    pipeline = AsyncPipeline()
    pipeline.add_component("llm", OpenAIChatGenerator(model="gpt-4o"))
    
    async def main():
        result = await pipeline.run({"llm": {"messages": [ChatMessage.from_user("Hello")]}})
        print(result)
    
    asyncio.run(main())
    • Adds connection_type_validation parameter to Pipeline.__init__() (set to False to bypass type-checking on pipeline connections, e.g. connecting Optional[str] output to str input).
    • Adds run_async method to OpenAIChatGenerator, AzureOpenAIChatGenerator, HuggingFaceAPIChatGenerator, and HuggingFaceLocalChatGenerator, enabling native async chat completion inside an AsyncPipeline.
    • Adds run_async method to DocumentWriter, delegating to write_documents_async on the backing document store.
    • Adds async support to InMemoryDocumentStore, InMemoryBM25Retriever, and InMemoryEmbeddingRetriever.
    • Adds backend parameter to Sentence Transformers components supporting torch (default), onnx, and openvino inference backends.
    +10 moreshow less
    • New MSGToDocument component converts Microsoft Outlook .msg files into Haystack Document objects, extracting sender, recipients, CC, BCC, and subject metadata and exposing attachments as ByteStream objects.
    • Adds store_full_path init variable to XLSXToDocument to control whether the full source file path is stored in document metadata (defaults to False).
    • Exposes a configurable timeout parameter on Pipeline.show and Pipeline.draw methods (default raised to 30 seconds) for the Mermaid rendering server.
    • EvaluationRunResult can now export results as JSON, a pandas DataFrame, or a CSV file.
    • Updates ListJoiner so that list_type is now optional, defaulting to List[Any] to combine any incoming lists without requiring strict type annotation.
    • Haystack now officially supports Python 3.13.
    • Lazy importing reduces import haystack CPU time to 2–5% of its previous cost and cuts per-component import CPU time by ~50%.
    • FileTypeRouter now explicitly classifies .msg files with MIME type application/vnd.ms-outlook.
    • PDFMinerToDocument now detects and reports undecoded CID characters in extracted PDF text, flagging potential quality issues with non-standard fonts.
    • Deserialization now accepts standard typing shorthand without the typing. prefix (e.g., List[str] instead of typing.List[str]).
    └──▷ BREAKING ON UPGRADE
    • !The ExtractedTableAnswer dataclass and the dataframe field on the Document dataclass (deprecated in 2.10.0) have been removed; pandas is no longer a required Haystack dependency.
    • !AzureOCRDocumentConverter no longer produces Document objects with a dataframe field; detected tables are now represented as CSV-formatted text in the content field instead.
    • !Python 3.8 is no longer supported.
  31. v2.10.0 Feb 12, 2025 · issue -369

    Haystack v2.10.0 adds AsyncPipeline, universal tool calling, OpenAPIConnector, CSV document components, and local pipeline visualization.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.10.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.10.0
    └──▷ USE IT
    Invoke a REST API endpoint directly from a pipeline using an OpenAPI spec, without an LLM generating the payload.
    python
    from haystack.utils import Secret
    from haystack.components.connectors.openapi import OpenAPIConnector
    
    connector = OpenAPIConnector(
        openapi_spec="https://bit.ly/serperdev_openapi",
        credentials=Secret.from_env_var("SERPERDEV_API_KEY")
    )
    response = connector.run(operation_id="search", parameters={"q": "Who was Nikola Tesla?"})
    • Adds AsyncPipeline class enabling concurrent component execution for pipelines with parallel branches (e.g. hybrid retrieval), with significant speed improvements over synchronous Pipeline.run().
    • Adds OpenAPIConnector component accepting openapi_spec and credentials parameters for direct REST endpoint invocation from an OpenAPI spec without LLM-generated payloads.
    • Adds CSVDocumentSplitter component that recursively splits CSV documents into structured sub-tables by empty rows and columns, with a configurable threshold — useful for Excel files containing multiple tables per sheet.
    • Adds CSVDocumentCleaner component with remove_empty_rows, remove_empty_columns, and keep_id parameters for cleaning CSV documents while preserving specified ignored rows and columns.
    • Adds LLMMetadaExtractor component for use in indexing pipelines to extract and enrich document metadata using an LLM based on a user-given prompt.
    +7 moreshow less
    • Adds ListJoiner component that merges lists of values from multiple components into a single list.
    • Adds completion_start_time metadata field to track time-to-first-token (TTFT) in streaming responses from Hugging Face API and OpenAI (Azure).
    • Extends universal tool calling support to AzureOpenAIChatGenerator, HuggingFaceLocalChatGenerator, AnthropicChatGenerator, CohereChatGenerator, AmazonBedrockChatGenerator, and VertexAIGeminiChatGenerator with no additional configuration required.
    • Enables local pipeline visualization via draw() or show() using a local Mermaid server with Docker, removing the need for an internet connection or external service.
    • Enhances SentenceTransformersDocumentEmbedder and SentenceTransformersTextEmbedder to accept additional parameters passed directly to the underlying SentenceTransformer.encode method.
    • Adds jsonschema as a core dependency, used by Tool and JsonSchemaValidator.
    • Adds streaming callback run parameter support for Hugging Face chat generators.
    └──▷ BREAKING ON UPGRADE
    • !DOCXToDocument now returns DOCX metadata in Document.meta as a plain dictionary under the key docx instead of a DOCXMetadata dataclass.
    • !Removed the deprecated NLTKDocumentSplitter; use DocumentSplitter instead.
    • !Removed the deprecated FUNCTION role from ChatRole enum; use TOOL instead.
    • !Removed the deprecated ChatMessage.from_function class method; use ChatMessage.from_tool instead.
  32. v2.9.0 Jan 14, 2025 · issue -370

    Haystack v2.9.0 adds Tool/ToolInvoker abstractions, ComponentTool, RecursiveDocumentSplitter, XLSXToDocument, and StringJoiner.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.9.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.9.0
    └──▷ USE IT
    Wire an LLM to a live web search tool so the pipeline can answer questions requiring real-time information.
    python
    from haystack import Pipeline
    from haystack.tools import ComponentTool
    from haystack.components.websearch import SerperDevWebSearch
    from haystack.utils import Secret
    from haystack.components.tools.tool_invoker import ToolInvoker
    from haystack.components.generators.chat import OpenAIChatGenerator
    from haystack.dataclasses import ChatMessage
    
    search = SerperDevWebSearch(api_key=Secret.from_env_var("SERPERDEV_API_KEY"), top_k=3)
    tool = ComponentTool(
        component=search,
        name="web_search",
        description="Search the web for current information on any topic"
    )
    
    pipeline = Pipeline()
    pipeline.add_component("llm", OpenAIChatGenerator(model="gpt-4o-mini", tools=[tool]))
    pipeline.add_component("tool_invoker", ToolInvoker(tools=[tool]))
    pipeline.connect("llm.replies", "tool_invoker.messages")
    
    result = pipeline.run({"llm": {"messages": [ChatMessage.from_user("Who founded SpaceX?")]}})
    print(result)
    • Adds Tool dataclass (importable from haystack.tools) to represent callable tools for LLMs, plus a create_tool_from_function helper and @tool decorator for automatic name, description, and parameter generation.
    • Adds ToolInvoker component (haystack.components.tools.tool_invoker) that executes LLM-prepared tool calls and returns results as a List[ChatMessage] with tool role; connects directly to OpenAIChatGenerator and HuggingFaceAPIChatGenerator via llm.repliestool_invoker.messages.
    • Adds ComponentTool (haystack.tools) to wrap any Haystack component (web search, document processing, custom) as an LLM-callable tool with automatic schema generation and input type conversion, supporting basic types, dataclasses, and List[Document].
    • Adds RecursiveDocumentSplitter (haystack.components.preprocessors) with split_length, split_overlap, and separators parameters for recursive, separator-ordered text splitting.
    • Adds XLSXToDocument converter that loads Excel files via Pandas + openpyxl, converting each sheet into a separate Document in CSV format.
    +9 moreshow less
    • Adds store_full_path parameter to PyPDFToDocument and AzureOCRDocumentConverter __init__ methods — True stores the full file path in document metadata, False stores only the filename.
    • Adds StringJoiner component to collect strings from multiple pipeline components into a single list of strings.
    • Adds from_openai_dict_format class method to ChatMessage for constructing a ChatMessage from an OpenAI Chat API-format dictionary.
    • Adds default_headers parameter to AzureOpenAIDocumentEmbedder and AzureOpenAITextEmbedder.
    • Adds token argument to NamedEntityExtractor to support private Hugging Face models.
    • Merges NLTKDocumentSplitter functionality into DocumentSplitter: split_by='sentence' now uses NLTK-based sentence boundary detection; previous behaviour is available via split_by='period'.
    • Refactors ChatMessage dataclass to support multiple content types (text, tool calls, tool call results); the content attribute is replaced by the new text property.
    • Extends tool calling support to HuggingFaceAPIChatGenerator and OpenAIChatGenerator.
    • Improves callable serialization to support class methods and static methods; explicitly prohibits serialization of instance methods, lambdas, and nested functions.
    └──▷ BREAKING ON UPGRADE
    • !The content attribute of ChatMessage is removed; use the new text property to access textual content. Pipelines containing ChatPromptBuilder serialized with haystack-ai <= 2.9.0 may fail to deserialize.
    • !The converter init argument is removed from PyPDFToDocument; use the component's other init arguments or create a custom component.
    • !The store_full_path parameter default is changed to False in document converters — previously the full path was stored; now only the filename is stored unless store_full_path=True is set explicitly.
    • !The SentenceWindowRetriever output key context_documents now returns List[Document] (ordered by split_idx_start) instead of List[List[Document]].
  33. v2.8.0 Dec 5, 2024 · issue -371

    Haystack v2.8.0 adds DALLEImageGenerator, MetaFieldGroupingRanker, TTFT support, and new converter path controls.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.8.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.8.0
    └──▷ USE IT
    Generate an image from a text prompt using the new DALLEImageGenerator component.
    python
    from haystack.components.generators import DALLEImageGenerator
    
    image_generator = DALLEImageGenerator()
    response = image_generator.run("Show me a picture of a black cat.")
    print(response)
    Enforce that every variable in a prompt template must be supplied at pipeline run time.
    python
    from haystack.components.builders import PromptBuilder
    
    builder = PromptBuilder(
        template="Summarize the following: {{ text }} in {{ language }}",
        required_variables="*"
    )
    • Adds store_full_path parameter to __init__ of JSONConverter, CSVToDocument, DOCXToDocument, HTMLToDocument, MarkdownToDocument, PDFMinerToDocument, PPTXToDocument, TikaDocumentConverter, PyPDFToDocument, AzureOCRDocumentConverter, and TextFileToDocument; set to False to store only the file name instead of the full path in document metadata (defaults to True).
    • Adds required_variables='*' option to PromptBuilder and ChatPromptBuilder to automatically mark all prompt template variables as required.
    • Adds optional parameters to ConditionalRouter enabling default/fallback routing when certain inputs are absent at runtime.
    • New DALLEImageGenerator component brings OpenAI DALL-E image generation into Haystack pipelines.
    • New MetaFieldGroupingRanker component reorders documents by grouping them on metadata keys, useful for pre-processing before LLM ingestion.
    +6 moreshow less
    • Adds TTFT (Time-to-First-Token) support for OpenAI generators, capturing latency of first-token generation.
    • Adds Maximum Margin Relevance (MMR) strategy to SentenceTransformersDiversityRanker for query-relevance and diversity-balanced document selection.
    • Adds split-by-line support to DocumentSplitter.
    • Adds new initialization parameters to PyPDFToDocument for customizing text extraction from PDF files.
    • Adds SSL verification toggle and custom certificate authority support when making function calls via OpenAPI.
    • OpenAIDocumentEmbedder now continues processing remaining batches when a single batch fails embedding instead of stopping.
    └──▷ BREAKING ON UPGRADE
    • !The is_greedy argument has been removed from the @component decorator; replace Variadic inputs with GreedyVariadic in custom components.
  34. v2.7.0 Nov 11, 2024 · issue -372

    Haystack v2.7.0 adds LoggingTracer, StringJoiner, DOCX table extraction, and a reworked Pipeline.run() with better cycle support.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.7.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.7.0
    └──▷ USE IT
    Inspect every input and output flowing through a pipeline in real time during experimentation, without adding an external tracer.
    python
    import logging
    from haystack import tracing
    from haystack.tracing.logging_tracer import LoggingTracer
    
    logging.basicConfig(format="%(levelname)s - %(name)s -  %(message)s", level=logging.WARNING)
    logging.getLogger("haystack").setLevel(logging.DEBUG)
    tracing.tracer.is_content_tracing_enabled = True
    tracing.enable_tracing(LoggingTracer())
    
    # Now run your pipeline — all spans appear in the log output
    pipeline.run({"text_embedder": {"text": "What is RAG?"}})
    • Introduces LoggingTracer (importable from haystack.tracing.logging_tracer) that sends all pipeline traces to Python's logging system in real time; enable content tracing via tracing.tracer.is_content_tracing_enabled = True and activate with tracing.enable_tracing(LoggingTracer()).
    • Adds additional_mimetypes parameter to FileTypeRouter component, allowing users to supply extra MIME type mappings for correct file classification in environments like AWS Lambda.
    • Adds streaming_callback run-time parameter to HuggingFaceAPIGenerator and HuggingFaceLocalGenerator for per-chunk response callbacks.
    • Adds validate_output_type parameter to ConditionalRouter; setting it to True enables runtime type-checking of route outputs, raising ValueError on mismatch.
    • Adds config_kwargs parameter to SentenceTransformersDocumentEmbedder and SentenceTransformersTextEmbedder for passing additional options when loading model configuration.
    +6 moreshow less
    • Adds meta parameter to FileTypeRouter.run(), automatically converting sources to ByteStream objects with attached metadata for preprocessing/indexing pipelines.
    • Adds new StringJoiner component to join strings from multiple components into a list of strings.
    • Enhances DOCX converter to extract table content in addition to paragraphs, supporting both CSV and Markdown output formats.
    • Reworks Pipeline.run() internal logic for more reliable cycle handling and deterministic component execution order.
    • Makes window_size a run-time parameter on SentenceWindowRetriever, overriding the constructor value per run.
    • Attaches each component tracing span to its parent pipeline run span, enabling concurrent multi-run tracing.
    └──▷ BREAKING ON UPGRADE
    • !The debug_path init argument has been removed from Pipeline.
    • !The max_loops_allowed init argument has been removed from Pipeline; use max_runs_per_component instead.
    • !The PipelineMaxLoops exception has been removed; use PipelineMaxComponentRuns instead.
    • !The haystack.components.converters.pypdf.DefaultConverter class has been removed; pipeline YAMLs using it must be updated to reference haystack.components.converters.pdf.PDFToTextConverter with converter: null.
    • !Pipeline.connect() now raises PipelineConnectError when sender and receiver are the same component.
  35. v2.6.0 Oct 3, 2024 · issue -373

    Haystack v2.6.0 adds JSONConverter, NLTKDocumentSplitter, zero-shot classifier, NDCG evaluator, and GreedyVariadic input type.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.6.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.6.0
    └──▷ USE IT
    Extract structured fields from a nested JSON source into separate Documents using jq filtering — useful for ingesting datasets where each record should become its own Document.
    python
    from haystack.components.converters import JSONConverter
    from haystack.dataclasses import ByteStream
    import json
    
    data = {"laureates": [{"firstname": "Enrico", "surname": "Fermi", "motivation": "discovery of nuclear reactions"}]}
    source = ByteStream.from_string(json.dumps(data))
    converter = JSONConverter(jq_schema=".laureates[]", content_key="motivation", extra_meta_fields=["firstname", "surname"])
    results = converter.run(sources=[source])
    print(results["documents"][0].content)  # 'discovery of nuclear reactions'
    print(results["documents"][0].meta)     # {'firstname': 'Enrico', 'surname': 'Fermi'}
    Apply a domain-specific tokenization strategy (e.g., split on section headers) without subclassing DocumentSplitter.
    python
    from haystack.components.preprocessors import DocumentSplitter
    from haystack.dataclasses import Document
    
    def split_on_headers(text: str) -> list[str]:
        import re
        return [s for s in re.split(r'(?=^#{1,3} )', text, flags=re.MULTILINE) if s.strip()]
    
    splitter = DocumentSplitter(split_by="function", splitting_function=split_on_headers)
    result = splitter.run(documents=[Document(content="# Intro\nHello\n## Details\nMore info")])
    print([d.content for d in result["documents"]])
    • New JSONConverter component converts JSON files to Documents, with optional jq_schema filtering, content_key selection, and extra_meta_fields extraction.
    • New TransformersZeroShotDocumentClassifier component enables binary and multi-label zero-shot document classification into user-defined classes using Hugging Face pre-trained models.
    • New NLTKDocumentSplitter component splits documents by word count, sentence boundaries, and page breaks with multi-language support and configurable abbreviation handling.
    • New CSVToDocument component loads CSV files as byte objects and produces Documents compatible with DocumentSplitter.
    • New DocumentNDCGEvaluator component computes normalized discounted cumulative gain for retrieval evaluation when multiple ground-truth relevant documents exist and ranking order matters.
    +9 moreshow less
    • New GreedyVariadic input type replaces @component(is_greedy=True) — Pipeline runs the component as soon as any input arrives without waiting for all senders.
    • New max_runs_per_component init argument on Pipeline replaces max_loops_allowed with clearer semantics; adds companion PipelineMaxComponentRuns exception.
    • DocumentSplitter now accepts a custom splitting function via split_by='function' and splitting_function=<callable>, where the callable takes a string and returns a list of strings.
    • PromptBuilder templates now support dynamic date injection via {% now '<timezone>' %} syntax, with optional offset arithmetic and strftime format strings.
    • Adds azure_kwargs dictionary parameter to pass AzureOpenAI-supported parameters not explicitly defined in Haystack.
    • Exposes default_headers on Azure components to forward custom HTTP headers such as APIM subscription keys.
    • Adds usage meta field with prompt_tokens and completion_tokens keys to HuggingFaceAPIChatGenerator responses.
    • SentenceTransformersDocumentEmbedder and SentenceTransformersTextEmbedder now propagate model_max_length from tokenizer_kwargs to the underlying max_seq_length of the SentenceTransformer model.
    • Adds batching during inference in TransformerSimilarityRanker to prevent out-of-memory errors when ranking large document sets.
    └──▷ BREAKING ON UPGRADE
    • !The legacy Haystack v1 filter syntax and operators ($and, $or, $eq, $lt, etc.) are fully removed; only the new filter syntax is accepted.
    • !The default model for all OpenAI-backed components changes from gpt-3.5-turbo to gpt-4o-mini.
  36. v2.5.1 Sep 10, 2024 · issue -374

    Haystack v2.5.1 adds default_headers to Azure OpenAI generators for custom HTTP header injection.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.5.1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.5.1
    • Adds default_headers init argument to AzureOpenAIGenerator and AzureOpenAIChatGenerator to pass custom HTTP headers on every request.
  37. v2.5.0 Sep 4, 2024 · issue -374

    Haystack v2.5.0 adds explicit unsafe=True opt-in for dynamic code execution in routers and adapters, plus new min_top_k for TopPSampler and richer SentenceWindowRetriever output.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.5.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.5.0
    └──▷ USE IT
    Enable unsafe Jinja evaluation in a ConditionalRouter only when the template source is fully trusted, allowing ChatMessage or Document as output types.
    python
    from haystack.components.routers import ConditionalRouter
    
    router = ConditionalRouter(
        routes=[
            {"condition": "{{query | length > 50}}", "output": "{{chat_message}}", "output_type": "ChatMessage", "output_name": "long_query"}
        ],
        unsafe=True
    )
    Guarantee at least 3 documents from TopPSampler even when the probability-mass threshold would otherwise return fewer.
    python
    from haystack.components.samplers import TopPSampler
    
    sampler = TopPSampler(p=0.90, min_top_k=3)
    • Adds unsafe argument to ConditionalRouter and OutputAdapter; set unsafe=True to enable Jinja-template expressions that can return types such as ChatMessage, Document, and Answer — disabled by default to prevent unintended remote code execution.
    • Adds min_top_k parameter to TopPSampler to guarantee a minimum number of returned documents when top-p sampling selects fewer than desired, backfilling with next-highest-scored documents.
    • SentenceWindowRetriever now outputs a context_documents field alongside context_windows for each entry in retrieved_documents, exposing the individual Document objects within each context window.
    └──▷ BREAKING ON UPGRADE
    • !ChatMessage.to_openai_format method is removed; replace calls with haystack.components.generators.openai_utils._convert_message_to_openai_format.
    • !The debug parameter is removed from Pipeline.run; any code passing debug=True will break.
    • !SentenceWindowRetrieval is removed; replace with SentenceWindowRetriever.
  38. v2.4.0 Aug 15, 2024 · issue -375

    Haystack v2.4.0 adds local LLM support in evaluators, a new AnswerJoiner, and richer embedding controls via truncate_dim and precision.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.4.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.4.0
    └──▷ USE IT
    Run faithfulness evaluation against a local LLM endpoint instead of OpenAI, with custom generation parameters.
    python
    from haystack.components.evaluators import FaithfulnessEvaluator
    
    evaluator = FaithfulnessEvaluator(
        api_params={
            "api_base_url": "http://localhost:11434/v1",
            "generation_kwargs": {"temperature": 0.0, "max_tokens": 512},
        }
    )
    result = evaluator.run(questions=["What is RAG?"], contexts=[["RAG combines retrieval and generation."]], responses=["RAG is a retrieval-augmented generation approach."])
    Produce compact, quantized embeddings for a large document corpus to reduce memory usage during semantic search.
    python
    from haystack.components.embedders import SentenceTransformersDocumentEmbedder
    
    embedder = SentenceTransformersDocumentEmbedder(
        model="sentence-transformers/all-MiniLM-L6-v2",
        truncate_dim=128,
        precision="int8",
    )
    • Adds api_params init parameter to ContextRelevanceEvaluator and FaithfulnessEvaluator, enabling custom generation_kwargs and api_base_url for local LLM evaluation via any OpenAI-compatible endpoint.
    • Adds truncate_dim parameter to Sentence Transformers Embedders for truncating embeddings, especially useful for Matryoshka Representation Learning models.
    • Adds precision parameter to Sentence Transformers Embedders for quantized embeddings, enabling corpus size reduction for semantic search.
    • Adds model_kwargs and tokenizer_kwargs to TransformersSimilarityRanker, SentenceTransformersDocumentEmbedder, and SentenceTransformersTextEmbedder, supporting options like model_max_length and torch_dtype.
    • Adds unicode_normalization parameter to DocumentCleaner, supporting NFC, NFD, NFKC, and NFKD normalization modes.
    +6 moreshow less
    • Adds ascii_only parameter to DocumentCleaner to convert diacritic letters to ASCII equivalents and strip other non-ASCII characters.
    • Adds max_retries and timeout parameters to AzureOpenAIChatGenerator, AzureOpenAIDocumentEmbedder, and AzureOpenAITextEmbedder initializations.
    • Allows streaming_callback to be passed at pipeline run time to OpenAIGenerator and OpenAIChatGenerator, eliminating the need to recreate pipelines for streaming callbacks.
    • Enhanced filter application logic in retrievers to support merging of init-time and runtime filters with logical operators for complex metadata filtering combinations.
    • New AnswerJoiner component that combines multiple lists of Answer objects into a single list using Concatenate join mode.
    • Introduces a utility function to deserialize a generic Document Store from the init_parameters of a serialized component.
    └──▷ BREAKING ON UPGRADE
    • !ContextRelevanceEvaluator now returns only the list of relevant sentences per context (not all sentences), and scores 1 if any relevant sentence is found, 0 otherwise.
    • !DynamicPromptBuilder and DynamicChatPromptBuilder are removed; use PromptBuilder and ChatPromptBuilder instead.
    • !OutputAdapter and ConditionalRouter can no longer return user inputs.
    • !Multiplexer is removed; use BranchJoiner instead.
    • !Deprecated init parameters extractor_type and try_others are removed from HTMLToDocument.
    • !SentenceWindowRetrieval component is renamed to SentenceWindowRetriever.
    • !Utility functions serialize_callback_handler and deserialize_callback_handler are removed; use serialize_callable and deserialize_callable instead.
  39. v2.3.0 Jul 15, 2024 · issue -376

    Haystack v2.3.0 adds experimental package, five new components, and distribution-based rank fusion

    └──▷ GET THIS VERSION
    $ git clone --branch v2.3.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.3.0
    └──▷ USE IT
    Share a single in-memory document store between a writer pipeline and a retrieval pipeline without duplicating data.
    python
    from haystack.document_stores.in_memory import InMemoryDocumentStore
    from haystack.dataclasses import Document
    
    index = "shared_knowledge_base"
    store_writer = InMemoryDocumentStore(index=index)
    store_retriever = InMemoryDocumentStore(index=index)
    
    store_writer.write_documents([Document(content="Haystack is an LLM framework.")])
    print(store_retriever.count_documents())  # 1 — same memory
    Drop documents missing a ranking field instead of letting them pollute scored results.
    python
    from haystack.components.rankers import MetaFieldRanker
    
    ranker = MetaFieldRanker(meta_field="score", missing_meta="drop")
    result = ranker.run(documents=docs)
    print(result["documents"])  # only documents that have 'score' metadata
    • Introduces the haystack-experimental package (pip install haystack-experimental), importable via from haystack_experimental.component_type import Component, shipping three initial components: OpenAIFunctionCaller, OpenAPITool, and EvaluationHarness.
    • Adds OpenAIFunctionCaller (in haystack-experimental) to call LLM-returned functions after Chat Generators.
    • Adds OpenAPITool (in haystack-experimental) to translate natural-language instructions into structured payloads for RESTful OpenAPI endpoints.
    • Adds EvaluationHarness (in haystack-experimental) to wrap pipelines and complex evaluation tasks into a single runnable component.
    • Adds TransformersTextRouter component, which uses a Transformers text-classification pipeline to route text inputs to different output connections based on model labels.
    +17 moreshow less
    • Adds SentenceWindowRetrieval component for sentence-window retrieval, fetching surrounding context documents for a given chunk from the document store.
    • Adds DOCXToDocument converter component (uses python-docx) to convert Docx files into Haystack Documents.
    • Adds a PPTX-to-Document converter (uses python-pptx) that extracts text from each slide, separating slides with a page break \f so DocumentSplitter can split by slide.
    • Adds Distribution-Based Score Fusion (DBSF) as a new ranking mode in JoinDocuments.
    • Adds missing_meta parameter to MetaFieldRanker controlling handling of documents that lack the ranked meta field; supported values are 'bottom', 'top', and 'drop'.
    • Adds index parameter to InMemoryDocumentStore to enable memory sharing between multiple instances using the same index name.
    • Adds filter_policy init parameter to InMemoryBM25Retriever and InMemoryEmbeddingRetriever with 'replace' or 'merge' options for combining runtime and initial filters.
    • Adds custom Jinja2 filter callables support to ConditionalRouter via user-supplied filter callables accessible in condition expressions.
    • Adds split_id and split_overlap support to DocumentSplitter for finer control over the splitting process.
    • Adds save_to_disk and write_to_disk serialization methods to InMemoryDocumentStore.
    • Adds remove_component method to PipelineBase to delete components and their connections from a pipeline.
    • Adds max_retries and timeout parameters to AzureOpenAIGenerator, AzureOpenAIChatGenerator, AzureOpenAITextEmbedder, and AzureOpenAIDocumentEmbedder; values fall back to OPENAI_MAX_RETRIES (default 5) and OPENAI_TIMEOUT (default 30) environment variables.
    • Adds support for structlog context variables to structured logging.
    • Enables AnswerBuilder to accept ChatMessage objects as input in addition to strings, with metadata automatically added to the answer.
    • Expands LinkContentFetcher content-type support to include glob patterns for text, application, audio, and video types via a flexible handler resolution mechanism.
    • Pipeline serialization to YAML now supports tuples as field values.
    • Extends HuggingFace API components to accept both HF_API_TOKEN and HF_TOKEN environment variable names.
    └──▷ BREAKING ON UPGRADE
    • !trafilatura is no longer installed automatically; run pip install trafilatura manually to continue using HTMLToDocument.
    • !The converter_name parameter has been removed from PyPDFToDocument; use the converter init parameter with an instance implementing the PyPDFConverter protocol (convert, to_dict, from_dict) instead, or rely on the provided DefaultConverter class.
    • !HuggingFaceTEITextEmbedder and HuggingFaceTEIDocumentEmbedder have been removed; replace with HuggingFaceAPITextEmbedder and HuggingFaceAPIDocumentEmbedder.
    • !HuggingFaceTGIGenerator and HuggingFaceTGIChatGenerator have been removed; replace with HuggingFaceAPIGenerator and HuggingFaceAPIChatGenerator.
  40. v2.2.4 Jul 4, 2024 · issue -376

    Haystack v2.2.4 adds filter_policy to in-memory retrievers for flexible runtime filter control.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.2.4 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.2.4
    └──▷ USE IT
    Use filter_policy='merge' on an InMemoryBM25Retriever so that runtime filters are combined with the retriever's initial filters rather than overwriting them.
    python
    from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
    
    retriever = InMemoryBM25Retriever(
        document_store=document_store,
        filter_policy='merge'
    )
    • Introduces filter_policy init parameter for InMemoryBM25Retriever and InMemoryEmbeddingRetriever, accepting 'replace' or 'merge' to control how runtime filters interact with initial filters.
    • Adds apply_filter_policy function to standardize filter-policy application across all document store-specific retrievers, enabling consistent replace/merge behavior.
  41. v1.26.0 Jun 4, 2024 · issue -377

    Haystack 1.26 adds split-by-page chunking, new OpenAI embedding models, Llama3/Mistral/Claude 3 on Bedrock, and local OpenAI-compatible endpoint support.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.26.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.26.0
    └──▷ USE IT
    Run RAG against a local LM Studio endpoint instead of the OpenAI cloud, keeping data on-premises.
    python
    prompt_node = PromptNode(
        model_name_or_path='gpt-3.5-turbo',
        api_key='<your-key>',
        api_base='http://localhost:1234/v1'
    )
    Allow a large-batch document conversion job to skip bad files and continue rather than raising on the first failure.
    python
    converter = PDFToTextConverter(raise_on_failure=False)
    docs = converter.convert(file_paths=my_file_list)
    • Adds raise_on_failure flag to BaseConverter so large batch processes can continue past per-document exceptions instead of aborting.
    • Adds split_by='page' option to the preprocessor, enabling document chunking by page break.
    • Adds support for OpenAI embedding models text-embedding-3-large and text-embedding-3-small.
    • Adds API_BASE optional parameter to PromptNode and PromptModel, enabling RAG against any local OpenAI-compatible endpoint (e.g. http://localhost:1234/v1, LM Studio).
    • Supports Llama3 models on AWS Bedrock.
    +5 moreshow less
    • Supports MistralAI and new Claude 3 models on AWS Bedrock.
    • Supports Cohere Command R models via Transformers upgrade to version 4.39.3.
    • Supports Phi-2 and Qwen2 models and improved quantization via Transformers upgrade to version 4.37.2.
    • Supports gated repos for Hugging Face inference.
    • Adds a pre-flight check verifying that embedding dimensions in the FAISS Document Store and retriever match before running embedding calculations.
    └──▷ BREAKING ON UPGRADE
    • !The utility functions fetch_archive_from_http, build_pipeline, and add_example_data have been removed from Haystack.
    • !PDFToTextConverter no longer supports PyMuPDF; it now always uses xpdf by default. To keep using PyMuPDF you must create a custom node.
  42. v1.26.0-rc1 Jun 3, 2024 · issue -377

    Haystack v1.26.0-rc1 adds Llama3/MistralAI/Claude 3 on AWS Bedrock, Cohere Command R support, and page-based document splitting.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.26.0-rc1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.26.0-rc1
    └──▷ USE IT
    Chunk a multi-page PDF by page boundary rather than by word or sentence count.
    python
    from haystack.nodes import PreProcessor
    
    preprocessor = PreProcessor(split_by='page', split_length=1)
    pages = preprocessor.process(documents)
    • Adds raise_on_failure flag to BaseConverter class so large batch processes can continue past individual conversion exceptions.
    • Adds split_by='page' option to the preprocessor for chunking documents by page break.
    • Adds support for OpenAI embedding models text-embedding-3-large and text-embedding-3-small.
    • Adds API_BASE as an optional parameter to PromptNode and PromptModel, enabling RAG against any OpenAI-compatible local endpoint (e.g. http://localhost:1234/v1 via LM Studio).
    • Adds a dimension-mismatch check between the FAISS Document Store and retriever before running embedding calculations, surfacing misconfiguration early.
    +5 moreshow less
    • Adds support for Llama3 models on AWS Bedrock.
    • Adds support for MistralAI and new Claude 3 models on AWS Bedrock.
    • Adds support for Cohere Command R models via Transformers upgrade to 4.39.3.
    • Adds support for gated repos on Hugging Face inference.
    • Updates context windows for OpenAI GPT models to reflect current limits.
    └──▷ BREAKING ON UPGRADE
    • !The utility functions fetch_archive_from_http, build_pipeline, and add_example_data have been removed from Haystack; callers must replace them with alternatives.
    • !PDFToTextConverter no longer supports PyMuPDF — it now always uses xpdf by default. To retain PyMuPDF support you must implement a custom node.
  43. v2.2.0 Jun 3, 2024 · issue -377

    Haystack v2.2.0 adds BranchJoiner, runtime template swapping, OPENAI_TIMEOUT/OPENAI_MAX_RETRIES env vars, and DocumentSplitter threshold control.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.2.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.2.0
    └──▷ TRY IT
    Control OpenAI request timeout and retry budget without touching code — useful in flaky-network or rate-limited environments.
    $ export OPENAI_TIMEOUT=30
    export OPENAI_MAX_RETRIES=5
    python my_pipeline.py
    Avoid tiny trailing chunks when splitting long documents by setting a minimum viable chunk size.
    python
    from haystack.components.preprocessors import DocumentSplitter
    
    splitter = DocumentSplitter(
        split_by="word",
        split_length=200,
        split_threshold=50
    )
    Preserve original document IDs through a cleaning step so downstream deduplication or tracing still works.
    python
    from haystack.components.preprocessors import DocumentCleaner
    
    cleaner = DocumentCleaner(keep_id=True)
    • Adds OPENAI_TIMEOUT and OPENAI_MAX_RETRIES environment variables (also settable at __init__) to configure timeout and retry behaviour across OpenAI components.
    • Adds split_threshold parameter to DocumentSplitter — chunks smaller than the threshold are concatenated with the previous chunk to avoid meaninglessly small splits.
    • Adds keep_id optional attribute to DocumentCleaner — when True, document IDs are preserved unchanged after cleanup.
    • Adds top_k parameter to DocumentJoiner.run(), letting callers cap the number of returned documents at query time.
    • Introduces BranchJoiner as a new component with the same interface as the now-deprecated Multiplexer, with clearer semantics.
    +7 moreshow less
    • AzureOpenAIGenerator and AzureOpenAIChatGenerator now accept a timeout parameter for the underlying AzureOpenAI client.
    • ChatPromptBuilder now supports runtime template changes, superseding DynamicChatPromptBuilder.
    • PromptBuilder now supports runtime template changes, superseding DynamicPromptBuilder.
    • Re-implements InMemoryDocumentStore BM25 search with incremental indexing, eliminating full index rebuilds per query and removing the haystack_bm25 dependency.
    • LLM-based evaluators (e.g. Faithfulness, ContextRelevance) initialised with raise_on_failure=False now set the sample score to NaN and emit a warning instead of raising an exception when an LLM call fails or returns invalid JSON.
    • Switches HTMLToDocument HTML conversion backend from boilerpy3 to trafilatura for more robust and actively maintained parsing.
    • Improves MIME type handling by setting MIME types directly on ByteStream objects, making type data consistently accessible across document format routing.
    └──▷ BREAKING ON UPGRADE
    • !Multiplexer is renamed to BranchJoiner; existing code must rename all occurrences of Multiplexer to BranchJoiner and update imports accordingly.
  44. v2.1.0 May 7, 2024 · issue -378

    Haystack v2.1.0 adds 8 evaluator components, sparse embedding support, per-component output inspection, and new HuggingFace API generators.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.1.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.1.0
    └──▷ USE IT
    Inspect intermediate retriever and LLM outputs during a pipeline run without modifying the pipeline definition.
    python
    pipe.run(data, include_outputs_from={"prompt_builder", "llm", "retriever"})
    Evaluate retrieval quality with mean average precision across multiple queries.
    python
    from haystack.components.evaluators import DocumentMAPEvaluator
    from haystack import Document
    
    evaluator = DocumentMAPEvaluator()
    result = evaluator.run(
        ground_truth_documents=[
            [Document(content="France")],
            [Document(content="9th century"), Document(content="9th")],
        ],
        retrieved_documents=[
            [Document(content="France")],
            [Document(content="9th century"), Document(content="10th century"), Document(content="9th")],
        ],
    )
    print(result["score"])  # 0.9166666666666666
    Build a sparse embedding retrieval pipeline using SPLADE for improved keyword-sensitive semantic search.
    python
    from haystack import Pipeline
    from haystack_integrations.components.retrievers.qdrant import QdrantSparseEmbeddingRetriever
    from haystack_integrations.components.embedders.fastembed import FastembedSparseTextEmbedder
    
    sparse_text_embedder = FastembedSparseTextEmbedder(model="prithvida/Splade_PP_en_v1")
    sparse_retriever = QdrantSparseEmbeddingRetriever(document_store=document_store)
    
    query_pipeline = Pipeline()
    query_pipeline.add_component("sparse_text_embedder", sparse_text_embedder)
    query_pipeline.add_component("sparse_retriever", sparse_retriever)
    query_pipeline.connect("sparse_text_embedder.sparse_embedding", "sparse_retriever.query_sparse_embedding")
    • Adds include_outputs_from parameter to pipeline.run() accepting a set of component names, returning intermediate outputs for those components in the final pipeline output dictionary.
    • Adds truncate and normalize parameters to HuggingFaceTEITextEmbedder and HuggingFaceTEIDocumentEmbedder for controlling embedding truncation and normalization.
    • Adds trust_remote_code parameter to SentenceTransformersDocumentEmbedder and SentenceTransformersTextEmbedder to allow custom models and scripts.
    • Adds streaming_callback parameter to HuggingFaceLocalGenerator for handling streaming responses.
    • Adds try_others parameter (default True) to HTMLToDocument to attempt multiple extractors in priority order on extraction failure.
    +15 moreshow less
    • Adds dimensions parameter to AzureOpenAITextEmbedder and AzureOpenAIDocumentEmbedder to support new embedding models such as text-embedding-3-small and text-embedding-3-large.
    • Adds converter parameter to PyPDFToDocument for custom PDF converter classes implementing the PyPDFConverter protocol with convert, to_dict, and from_dict methods.
    • Adds support for pre-init hook callbacks during pipeline deserialization, allowing inspection and modification of component initialization parameters before __init__ is called.
    • Introduces AnswerExactMatchEvaluator, ContextRelevanceEvaluator, DocumentMAPEvaluator, DocumentMRREvaluator, DocumentRecallEvaluator, FaithfulnessEvaluator, LLMEvaluator, and SASEvaluator components for model-based and statistical RAG pipeline evaluation.
    • Introduces SparseEmbedding class for storing sparse vector representations of documents, enabling sparse embedding retrieval pipelines (e.g., SPLADE via QdrantSparseEmbeddingRetriever and FastembedSparseTextEmbedder).
    • Introduces HuggingFaceAPIChatGenerator, HuggingFaceAPIDocumentEmbedder, HuggingFaceAPIGenerator, and HuggingFaceAPITextEmbedder components supporting the free Serverless Inference API, paid Inference Endpoints, and self-hosted Text Generation Inference.
    • Adds SentenceTransformersDiversityRanker component that reorders documents to maximize semantic diversity using sentence-transformer embeddings.
    • Adds ZeroShotTextRouter component that uses a HuggingFace NLI model to classify and route texts based on user-provided labels.
    • Enhances FileTypeRouter with regex pattern support for MIME types, enabling granular file routing by broad categories or specific MIME type patterns.
    • Enhances PromptBuilder to specify and enforce required variables in prompt templates.
    • Enhances DynamicChatPromptBuilder to allow all user and system messages to be templated with provided variables.
    • Enhances AzureOCRDocumentConverter with advanced table and text handling: extracting preceding/following context for tables, merging multiple column headers, and single-column page layout for text.
    • Now DocumentSplitter adds a page_number field to the metadata of all output documents tracking the originating page of the source document.
    • Sets max_new_tokens default to 512 in HuggingFace generators.
    • In Jupyter notebooks, Pipeline now displays a textual representation by default; call the show method to display the pipeline image.
    └──▷ BREAKING ON UPGRADE
    • !The converter_name parameter in PyPDFToDocument is deprecated and will be removed in v2.3.0; use the converter parameter instead.
    • !HuggingFaceTGIChatGenerator is deprecated and will be removed in v2.3.0; use HuggingFaceAPIChatGenerator instead.
    • !HuggingFaceTGIGenerator is deprecated and will be removed in v2.3.0; use HuggingFaceAPIGenerator instead.
    • !HuggingFaceTEIDocumentEmbedder is deprecated and will be removed in v2.3.0; use HuggingFaceAPIDocumentEmbedder instead.
    • !HuggingFaceTEITextEmbedder is deprecated and will be removed in v2.3.0; use HuggingFaceAPITextEmbedder instead.
    • !In Jupyter notebooks, Pipeline no longer displays its image automatically on render; call pipeline.show() explicitly to display it.
  45. v2.1.0-rc2 May 6, 2024 · issue -378

    Haystack v2.1.0-rc2 adds 8 evaluator components, sparse embedding support, per-component output inspection, and new HuggingFace API generators.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.1.0-rc2 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.1.0-rc2
    └──▷ USE IT
    Inspect intermediate outputs from specific components after a pipeline run to debug retrieval or generation steps.
    python
    pipe.run(data, include_outputs_from=["prompt_builder", "llm", "retriever"])
    Evaluate retrieved documents against ground truth using mean average precision scoring.
    python
    from haystack.components.evaluators import DocumentMAPEvaluator
    
    evaluator = DocumentMAPEvaluator()
    result = evaluator.run(
        ground_truth_documents=[[Document(content="France")], [Document(content="9th century")]],
        retrieved_documents=[[Document(content="France")], [Document(content="9th century"), Document(content="10th century")]],
    )
    print(result["score"])
    Use sparse embedding retrieval (SPLADE) in a query pipeline with Qdrant and FastEmbed.
    python
    from haystack import Pipeline
    from haystack_integrations.components.retrievers.qdrant import QdrantSparseEmbeddingRetriever
    from haystack_integrations.components.embedders.fastembed import FastembedSparseTextEmbedder
    
    sparse_text_embedder = FastembedSparseTextEmbedder(model="prithvida/Splade_PP_en_v1")
    sparse_retriever = QdrantSparseEmbeddingRetriever(document_store=document_store)
    
    query_pipeline = Pipeline()
    query_pipeline.add_component("sparse_text_embedder", sparse_text_embedder)
    query_pipeline.add_component("sparse_retriever", sparse_retriever)
    query_pipeline.connect("sparse_text_embedder.sparse_embedding", "sparse_retriever.query_sparse_embedding")
    • Adds include_outputs_from parameter to pipeline.run() accepting a set of component names whose intermediate outputs are returned in the final pipeline output dictionary.
    • Adds trust_remote_code parameter to SentenceTransformersDocumentEmbedder and SentenceTransformersTextEmbedder for allowing custom models and scripts.
    • Adds truncate and normalize parameters to HuggingFaceTEITextEmbedder for truncation and normalization of embeddings.
    • Adds streaming_callback parameter to HuggingFaceLocalGenerator for handling streaming responses.
    • Adds dimensions parameter to AzureOpenAITextEmbedder and AzureOpenAIDocumentEmbedder to support new embedding models including text-embedding-3-small and text-embedding-3-large.
    +15 moreshow less
    • Adds try_others parameter to HTMLToDocument (default True) to attempt multiple extractors in priority order when one fails.
    • Introduces new HuggingFaceAPIChatGenerator, HuggingFaceAPIDocumentEmbedder, HuggingFaceAPIGenerator, and HuggingFaceAPITextEmbedder components supporting the free Serverless Inference API, paid Inference Endpoints, and self-hosted Text Generation Inference.
    • Adds 8 new evaluation components: AnswerExactMatchEvaluator, ContextRelevanceEvaluator, DocumentMAPEvaluator, DocumentMRREvaluator, DocumentRecallEvaluator, FaithfulnessEvaluator, LLMEvaluator, and SASEvaluator for model-based and statistical RAG pipeline evaluation.
    • Introduces new SparseEmbedding class for storing sparse vector representations of documents, enabling sparse embedding retrieval techniques such as SPLADE.
    • Adds SentenceTransformersDiversityRanker component that orders documents to maximize overall diversity using semantic embeddings.
    • Adds ZeroShotTextRouter component that uses a HuggingFace NLI model to classify and route texts based on provided labels.
    • Adds support for callbacks during pipeline deserialization, including a pre-init hook to inspect and modify component initialization parameters before __init__ is invoked.
    • Adds page_number field to the metadata of all output documents from DocumentSplitter to track the originating page.
    • Adds regex pattern support for MIME types in FileTypeRouter for granular file routing.
    • Enhances PromptBuilder to specify and enforce required variables in prompt templates.
    • Enhances AzureOCRDocumentConverter with advanced table and text handling including preceding/following context extraction for tables, merging multiple column headers, and single-column page layout support.
    • Enhances DynamicChatPromptBuilder to allow all user and system messages to be templated with provided variables.
    • Refactors PyPDFToDocument to support custom PDF converters via the converter parameter; converters implement the PyPDFConverter protocol with convert, to_dict, and from_dict methods.
    • Sets max_new_tokens default to 512 in HuggingFace generators.
    • In Jupyter notebooks, Pipeline now displays a textual representation by default; use the show method on the Pipeline object to render the image.
  46. v2.1.0-rc1 May 2, 2024 · issue -378

    Haystack v2.1.0-rc1 adds diversity ranking, six new evaluators, four unified HuggingFace API components, sparse embeddings, and a zero-shot text router.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.1.0-rc1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.1.0-rc1
    └──▷ USE IT
    Route files to different pipeline branches using regex MIME-type patterns, avoiding the need to enumerate every subtype explicitly.
    python
    from haystack.components.routers import FileTypeRouter
    from pathlib import Path
    
    router = FileTypeRouter(mime_types=[r"text/.*", r"application/(pdf|json)"])
    result = router.run(sources=[Path("report.pdf"), Path("notes.txt"), Path("data.json"), Path("image.png")])
    for mime_type, files in result.items():
        print(f"MIME Type: {mime_type}, Files: {[str(f) for f in files]}")
    Score faithfulness of RAG answers at evaluation time to detect hallucinations against retrieved context.
    python
    from haystack.components.evaluators import FaithfulnessEvaluator
    
    evaluator = FaithfulnessEvaluator()
    result = evaluator.run(
        questions=["What is the capital of France?"],
        contexts=[["Paris is the capital and largest city of France."]],
        predicted_answers=["The capital of France is Paris."]
    )
    print(result["score"])  # float between 0 and 1
    Stream tokens from a local Hugging Face model during generation instead of waiting for the full response.
    python
    from haystack.components.generators import HuggingFaceLocalGenerator
    
    def my_callback(token):
        print(token, end="", flush=True)
    
    generator = HuggingFaceLocalGenerator(
        model="google/flan-t5-large",
        streaming_callback=my_callback
    )
    generator.warm_up()
    generator.run(prompt="Summarize the OWASP Top 10 in three sentences.")
    • Adds truncate and normalize parameters to HuggingFaceTEITextEmbedder for controlling truncation and normalization of embeddings.
    • Adds trust_remote_code parameter to SentenceTransformersDocumentEmbedder and SentenceTransformersTextEmbedder to allow custom models and scripts.
    • Adds streaming_callback parameter to HuggingFaceLocalGenerator to handle streaming responses.
    • Adds dimensions parameter to AzureOpenAITextEmbedder and AzureOpenAIDocumentEmbedder to support newer embedding models such as text-embedding-3-small and text-embedding-3-large.
    • Adds try_others parameter to HTMLToDocument (default true) to fall back through multiple extractors in priority order on failure.
    +25 moreshow less
    • Introduces HuggingFaceAPIChatGenerator, a unified chat-format text-generation component supporting the free Serverless Inference API, paid Inference Endpoints, and self-hosted Text Generation Inference — intended to replace HuggingFaceTGIChatGenerator.
    • Introduces HuggingFaceAPIGenerator, a unified text-generation component supporting Serverless Inference API, Inference Endpoints, and self-hosted TGI — intended to replace HuggingFaceTGIGenerator.
    • Introduces HuggingFaceAPIDocumentEmbedder, a unified document-embedding component supporting Serverless Inference API, Inference Endpoints, and self-hosted Text Embeddings Inference — intended to replace HuggingFaceTEIDocumentEmbedder.
    • Introduces HuggingFaceAPITextEmbedder, a unified string-embedding component supporting Serverless Inference API, Inference Endpoints, and self-hosted Text Embeddings Inference — intended to replace HuggingFaceTEITextEmbedder.
    • Adds SentenceTransformersDiversityRanker, which reorders documents to maximize semantic diversity using sentence-transformer embeddings.
    • Adds ContextRelevanceEvaluator component that uses an LLM to score (0–1) how relevant retrieved documents are to a question in a RAG pipeline.
    • Adds FaithfulnessEvaluator component that scores (0–1) the proportion of statements in an LLM answer that can be inferred from retrieved documents.
    • Adds LLMEvaluator component that leverages the OpenAI API to evaluate pipeline outputs.
    • Adds DocumentMAPEvaluator component to calculate mean average precision of retrieved documents.
    • Adds DocumentMRREvaluator component to calculate mean reciprocal rank of retrieved documents.
    • Adds DocumentRecallEvaluator component to calculate single-hit or multi-hit recall for retrieved documents.
    • Adds SASEvaluator component to calculate Semantic Answer Similarity of LLM-generated answers.
    • Adds EvaluationRunResult dataclass to wrap, transform, and visualize results from an evaluation pipeline.
    • Introduces SparseEmbedding class for storing sparse vector representations of documents, laying groundwork for Sparse Embedding Retrieval.
    • Adds Zero Shot Text Router that uses an NLI model from Hugging Face to classify and route texts by label.
    • Extends FileTypeRouter with regex pattern matching for MIME types, enabling granular file routing such as r'text/.*' or r'application/(pdf|json)'.
    • Adds support for callbacks during pipeline deserialization, including a pre-init hook to inspect and modify component initialization parameters before __init__ is called.
    • Enables pipeline.run to accept a set of component names whose intermediate outputs are included in the final pipeline output dictionary.
    • Makes Pipeline.inputs and Pipeline.outputs optionally include connected component input/output sockets.
    • Refactors PyPDFToDocument to support custom PDF converters via the PyPDFConverter protocol (requiring convert, to_dict, and from_dict methods), with DefaultConverter as the built-in implementation.
    • Enhances PromptBuilder to specify and enforce required variables in prompt templates.
    • Enhances DynamicChatPromptBuilder to allow all user and system messages to be templated with provided variables.
    • Enhances AzureOCRDocumentConverter with advanced table and text handling: preceding/following context extraction for tables, merged multi-column headers, and single-column page layout for text.
    • Sets max_new_tokens default to 512 in Hugging Face generators.
    • Now DocumentSplitter adds a page_number field to the metadata of all output documents to track original page provenance.
  47. v1.25.3 Apr 23, 2024 · issue -379

    Haystack v1.25.3 adds Llama 3, Mistral AI, Claude 3, and Cohere Command R model support on AWS Bedrock.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.25.3 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.25.3
    • Supports Llama 3 models on AWS Bedrock.
    • Supports Mistral AI and new Claude 3 models on AWS Bedrock.
    • Upgrades transformers to version 4.39.3, enabling support for Cohere Command R models.
  48. v2.0.1 Apr 9, 2024 · issue -379

    Haystack v2.0.1 adds streaming support to HuggingFaceLocalGenerator and introduces a new SparseEmbedding class.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.0.1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.0.1
    • Adds streaming_callback parameter to HuggingFaceLocalGenerator to handle streaming responses.
    • Introduces new SparseEmbedding class for storing sparse vector representations of a Document, laying groundwork for Sparse Embedding Retrieval with forthcoming Sparse Embedders and Sparse Embedding Retrievers.
  49. v1.25.2 Apr 2, 2024 · issue -379

    Haystack v1.25.2 adds response_format, seed, and prompt-truncation toggle to OpenAI/Azure invocation layers.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.25.2 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.25.2
    • Adds response_format and seed parameters to the OpenAI and Azure OpenAI invocation layers, enabling structured output control and reproducible sampling.
    • Adds a boolean parameter to toggle prompt truncation in invocation layers, giving callers explicit control over whether long prompts are silently cut.
  50. v2.0.0 Mar 11, 2024 · issue -380

    Haystack 2.0 is a full rewrite introducing composable pipelines, typed components, and a new haystack-ai package.

    └──▷ GET THIS VERSION
    $ git clone --branch v2.0.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v2.0.0
    └──▷ USE IT
    Build a URL question-answering pipeline by chaining fetcher, converter, prompt, and LLM components with typed connections.
    python
    from haystack import Pipeline
    from haystack.components.fetchers import LinkContentFetcher
    from haystack.components.converters import HTMLToDocument
    from haystack.components.builders import PromptBuilder
    from haystack.components.generators import OpenAIGenerator
    from haystack.utils import Secret
    
    fetcher = LinkContentFetcher()
    converter = HTMLToDocument()
    prompt_builder = PromptBuilder(template="""{% for document in documents %}{{document.content}}{% endfor %} Answer: {{query}}""")
    llm = OpenAIGenerator(api_key=Secret.from_env_var("OPENAI_API_KEY"))
    
    pipeline = Pipeline()
    pipeline.add_component("fetcher", fetcher)
    pipeline.add_component("converter", converter)
    pipeline.add_component("prompt", prompt_builder)
    pipeline.add_component("llm", llm)
    pipeline.connect("fetcher.streams", "converter.sources")
    pipeline.connect("converter.documents", "prompt.documents")
    pipeline.connect("prompt.prompt", "llm.prompt")
    pipeline.run({"fetcher": {"urls": ["https://haystack.deepset.ai/overview/quick-start"]}, "prompt": {"query": "How should I install Haystack?"}})
    Spin up a predefined chat-with-website pipeline in one line using the new template factory.
    python
    from haystack import Pipeline, PredefinedPipeline
    
    pipeline = Pipeline.from_template(PredefinedPipeline.CHAT_WITH_WEBSITE)
    pipeline.run({"fetcher": {"urls": ["https://haystack.deepset.ai/overview/quick-start"]}, "prompt": {"query": "How should I install Haystack?"}})
    Create a custom embedder component with typed I/O and plug it into a retrieval pipeline.
    python
    from haystack import component, Pipeline
    from haystack.document_stores.in_memory import InMemoryDocumentStore
    from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
    import random
    from typing import List
    
    @component
    class MyEmbedder:
        def __init__(self, dim: int = 128):
            self.dim = dim
    
        @component.output_types(embedding=List[float])
        def run(self, text: str):
            return {"embedding": [random.uniform(-1.0, 1.0) for _ in range(self.dim)]}
    
    document_store = InMemoryDocumentStore()
    pipeline = Pipeline()
    pipeline.add_component("text_embedder", MyEmbedder())
    pipeline.add_component("retriever", InMemoryEmbeddingRetriever(document_store=document_store))
    pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
    pipeline.run({"text_embedder": {"text": "Who lives in Berlin?"}})
    • New haystack-ai package replaces farm-haystack for Haystack 2.0; both coexist but must be installed in separate virtual environments to avoid conflicts.
    • New Pipeline class supports dynamic computation graphs with conditional control flow, loops, typed data flow, pre-run validation, and serialization; built via add_component() and connect() methods, executed with run().
    • New @component decorator and @component.output_types() decorator enable custom components with typed inputs and outputs that slot directly into pipelines.
    • New Pipeline.from_template() factory method accepts PredefinedPipeline enum values (e.g., PredefinedPipeline.CHAT_WITH_WEBSITE) to instantiate ready-made pipelines in one line.
    • New PromptBuilder component (and DynamicPromptBuilder for advanced cases) accepts Jinja-templated prompts where {{ }} expressions become typed pipeline inputs.
    +4 moreshow less
    • New Secret.from_env_var() utility provides type-safe secret and API-key management to prevent accidental credential leaks.
    • Built-in components now span 20+ categories — including Generators, Embedders, Retrievers, Evaluators, Rankers, and Routers — with integrations for OpenAI, Cohere, Hugging Face, Amazon Bedrock, Google Vertex, Ollama, and many more.
    • Document Stores provide a unified interface for vector-database backends including Weaviate, Chroma, Pinecone, Astra DB, MongoDB, Qdrant, Pgvector, Elasticsearch, OpenSearch, Neo4j, and Marqo, each paired with a dedicated retriever component.
    • Structured logging system supports tracing correlation out of the box, with OpenTelemetry and Datadog instrumentation built in.
  51. v1.25.0 Mar 4, 2024 · issue -380

    Haystack v1.25.0 adds page-based document splitting, new OpenAI embedding models, and local endpoint support via API_BASE.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.25.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.25.0
    └──▷ USE IT
    Chunk a document corpus by page rather than word or sentence count — useful when downstream retrieval should respect PDF page boundaries.
    python
    preprocessor = PreProcessor(
        split_by='page',
        split_overlap=0
    )
    docs = preprocessor.process(raw_docs)
    • Adds split_by='page' option to the Preprocessor so documents can be chunked by page break.
    • Adds raise_on_failure flag to BaseConverter so large batch processes can continue past individual conversion exceptions.
    • Adds support for OpenAI embedding models text-embedding-3-large and text-embedding-3-small.
    • Adds API_BASE as an optional parameter to PromptNode and PromptModel, enabling RAG against any OpenAI-compatible local endpoint (e.g. LM Studio at http://localhost:1234/v1).
    • Upgrades Transformers to 4.37.2, adding support for Phi-2 and Qwen2 models and improved quantization support.
  52. v1.25.0-rc1 Feb 29, 2024 · issue -381

    Haystack v1.25.0-rc1 adds page-break chunking, new OpenAI embedding models, local endpoint support, and a fault-tolerant converter flag.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.25.0-rc1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.25.0-rc1
    └──▷ USE IT
    Chunk a document corpus by page boundaries rather than word or sentence count — useful when page layout carries semantic meaning.
    python
    preprocessor = PreProcessor(split_by="page", split_length=1)
    Point Haystack at a local LM Studio endpoint so your RAG pipeline runs entirely on-prem without changing any other pipeline code.
    python
    prompt_model = PromptModel(model_name_or_path="gpt-3.5-turbo", api_key="ignored", model_kwargs={"API_BASE": "http://localhost:1234/v1"})
    Keep a bulk conversion job alive even when individual files are malformed or unreadable.
    python
    converter = PDFToTextConverter(raise_on_failure=False)
    • Adds split_by="page" option to the preprocessor, enabling document chunking by page break.
    • Adds raise_on_failure flag to BaseConverter so large batch processes can continue past per-document exceptions instead of halting.
    • Adds support for OpenAI embedding models text-embedding-3-large and text-embedding-3-small.
    • Adds API_BASE as an optional parameter to PromptNode and PromptModel, enabling RAG against any OpenAI-compatible local endpoint (e.g. LM Studio at http://localhost:1234/v1).
    • Upgrades Transformers to 4.37.2, adding support for Phi-2 and Qwen2 models and improved quantization support.
  53. v1.24.0 Jan 25, 2024 · issue -382

    Haystack v1.24.0 adds Amazon Bedrock embedding models and configurable WebDriver support for the Crawler.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.24.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.24.0
    └──▷ USE IT
    Use a Titan embedding model hosted on Amazon Bedrock as a retriever in a Haystack pipeline.
    python
    from haystack.nodes import EmbeddingRetriever
    
    retriever = EmbeddingRetriever(
        embedding_model="amazon.titan-embed-text-v1",
        document_store=document_store,
        aws_config={
            "aws_access_key_id": "ACCESS_KEY",
            "aws_secret_access_key": "SECRET_KEY",
            "aws_session_token": "SESSION_TOKEN"
        }
    )
    • Adds EmbeddingRetriever support for Amazon Bedrock embedding models, including amazon.titan-embed-text-v1 and Cohere models, via an aws_config parameter accepting aws_access_key_id, aws_secret_access_key, and aws_session_token.
    • Adds an optional webdriver parameter to Crawler.__init__ to supply a pre-configured custom WebDriver instead of the default Chrome driver.
    • Adds model_kwargs argument to FARMReader to support loading the model in fp16 at inference time.
    • Adds model_kwargs argument to SentenceTransformersRanker to pass HuggingFace Transformers loading options.
    • Makes JoinDocuments sensitive to the weights parameter and adds score normalization when join_mode is reciprocal rank fusion.
    +1 moreshow less
    • Optimizes PineconeDocumentStore.write_documents upserts with asynchronous requests.
  54. v1.23.0 Dec 14, 2023 · issue -383

    Haystack v1.23.0 adds Amazon Bedrock and MongoDB Atlas support, plus new converters, token splitting, and embedding instructions.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.23.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.23.0
    └──▷ USE IT
    Use an Amazon Bedrock-hosted Llama 2 model in a PromptNode without any extra configuration beyond the model ID.
    python
    from haystack.nodes import PromptNode
    
    prompt_node = PromptNode(model_name_or_path="meta.llama2-13b-chat-v1")
    Connect Haystack to a MongoDB Atlas collection as a document store for indexing and retrieval.
    python
    from haystack.document_stores.mongodb_atlas import MongoDBAtlasDocumentStore
    
    document_store = MongoDBAtlasDocumentStore(
        mongo_connection_string="mongodb+srv://USER:PASSWORD@HOST/?retryWrites=true&w=majority",
        database_name="my_database",
        collection_name="my_collection",
    )
    document_store.write_documents(docs)
    • Adds MongoDBAtlasDocumentStore class (importable from haystack.document_stores.mongodb_atlas) with mongo_connection_string, database_name, and collection_name constructor parameters, providing MongoDB Atlas as a document store backend.
    • Adds Amazon Bedrock model support to PromptNode via model_name_or_path — pass a Bedrock model ID (e.g. meta.llama2-13b-chat-v1) to use models like Llama-2-70b-chat.
    • Adds timeout keyword argument to PromptNode for per-call timeout control over OpenAI invocations.
    • Adds batch_size parameter to the __init__ method of FAISSDocumentStore, serving as the default for all methods that accept batch_size.
    • Adds model_kwargs parameter to ExtractiveReader for passing HuggingFace loading options.
    +8 moreshow less
    • Adds split_length by token in PreProcessor.
    • Adds PptxConverter node to convert .pptx files to Haystack Documents.
    • Adds support for dense embedding instructions used in retrieval models such as BGE and LLM-Embedder.
    • Changes PromptModel constructor parameter invocation_layer_class to also accept a str (imported at runtime), easing YAML serialization.
    • Allows defining the number of pods and pod type directly when creating a PineconeDocumentStore instance.
    • Allows loading additional fields from SQUAD-format files into the meta field of Labels.
    • Adds token limit definition for the gpt-4-1106-preview model.
    • Upgrades Transformers to 4.35.2, adding support for DistilWhisper, Fuyu, Kosmos-2, SeamlessM4T, and Owl-v2 model families.
    └──▷ BREAKING ON UPGRADE
    • !Removes deprecated OpenAIAnswerGenerator, BaseGenerator, and GenerativeQAPipeline classes — pipelines using these must migrate to PromptNode.
  55. v1.22.1 Nov 9, 2023 · issue -384

    Haystack v1.22.1 adds token limit support for the gpt-4-1106-preview model.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.22.1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.22.1
    • Adds token limit support for the gpt-4-1106-preview model.
  56. v1.22.0 Nov 7, 2023 · issue -384

    Haystack v1.22.0 adds async Pipeline support, new Haystack 2.0 preview components, and expanded model/hardware compatibility.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.22.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.22.0
    └──▷ USE IT
    Save a Haystack 2.0 pipeline definition to YAML for version control or reproducible deployments.
    python
    with open('pipeline.yaml', 'w') as f:
        pipeline.dump(f)
    Pass a Google Custom Search engine ID through WebRetriever to scope web searches to a specific engine.
    python
    retriever = WebRetriever(search_engine_kwargs={'engine': '<your-engine-id>'})
    • Adds ByteStream type (with mime_type field) for passing binary raw data across pipeline components in Haystack 2.0.
    • Adds ChatMessage dataclass to PromptBuilder for structured chat LLM message handling in Haystack 2.0.
    • Adds AzureOCRDocumentConverter to convert documents via Azure's Document Intelligence Service in Haystack 2.0.
    • Adds HTMLToDocument component to convert HTML to a Document in Haystack 2.0.
    • Adds TransformersSimilarityRanker component (renamed from SimilarityRanker) that ranks Document lists by query similarity in Haystack 2.0.
    +23 moreshow less
    • Adds TopPSampler component that selects documents using top-p (nucleus) sampling on cumulative Document scores in Haystack 2.0.
    • Adds HuggingFaceLocalGenerator component to run Hugging Face models locally for text generation, with support for specifying stopwords in Haystack 2.0.
    • Adds dumps, dump, loads, and load methods to Haystack 2.0 pipelines for saving and loading pipeline definitions in YAML format.
    • Adds TextDocumentSplitter component to Haystack 2.0 for splitting long-text Documents into shorter ones matching model max-length constraints.
    • Adds DocumentCleaner component to remove extra whitespace, empty lines, and headers from text Documents as a preprocessing step in Haystack 2.0.
    • Adds TextLanguageClassifier component to route an input string to different components based on detected language in Haystack 2.0.
    • Adds FileTypeRouter (renamed from the previous router) with ByteStream handling support for improved file routing in Haystack 2.0.
    • Adds OpenAI Document Embedder that computes embeddings using OpenAI models and stores results in each Document's embedding field in Haystack 2.0.
    • Introduces StreamingChunk dataclass for handling streamed language model output chunks with content and metadata in Haystack 2.0.
    • Adds token parameter to ExtractiveReader and TransformersSimilarityRanker (replacing deprecated use_auth_token) to allow loading private Hugging Face models in Haystack 2.0.
    • Adds search_engine_kwargs parameter to WebRetriever to propagate options (e.g. Google Custom Search engine ID) to WebSearch.
    • Adds list_of_paths argument to utils.convert_files_to_docs, enabling a list of file paths as input alongside or instead of dir_path.
    • Adds experimental support for asynchronous Pipeline run in Haystack.
    • Adds asyncio support to the OpenAI invocation layer and arun method on PromptNode for asynchronous execution.
    • Adds on_final_answer callback support through Agent callback_manager.
    • Adds Apple Silicon GPU acceleration via mps PyTorch backend, improving performance on M1 hardware.
    • Adds basic telemetry to Haystack 2.0 pipelines.
    • Upgrades canals to 0.9.0, enabling variadic inputs for Joiner components and / in connection names (e.g. text/plain).
    • Upgrades Transformers to 4.34.1, adding support for Mistral, Persimmon, BROS, ViTMatte, and Nougat models.
    • Enables all Pinecone index types including Starter in PineconeDocumentStore (document fetching limited to Pinecone's 10,000-vector query limit for Starter).
    • Makes JoinDocuments return only the highest-scoring document when duplicates are present.
    • Document writer now returns the count of documents written.
    • Migrates RemoteWhisperTranscriber to the OpenAI SDK.
    └──▷ BREAKING ON UPGRADE
    • !The audio, ray, onnx, and beir extras are removed from the all extra group.
    • !MemoryDocumentStore is renamed to InMemoryDocumentStore; MemoryBM25Retriever is renamed to InMemoryBM25Retriever; MemoryEmbeddingRetriever is renamed to InMemoryEmbeddingRetriever.
    • !SimilarityRanker is renamed to TransformersSimilarityRanker in Haystack 2.0.
    • !The id_hash_keys field is removed from the Document dataclass and from DocumentCleaner, TextDocumentSplitter, PyPDFToDocument, AzureOCRDocumentConverter, HTMLToDocument, TextFileToDocument, and TikaDocumentConverter.
    • !The array field is removed from the Document dataclass.
    • !Document's embedding field type is changed from numpy.ndarray to List[float].
    • !ExtractiveReader's input is renamed from document to documents.
    • !The file-type router is renamed to FileTypeRouter in Haystack 2.0.
  57. v1.21.1 Oct 4, 2023 · issue -385

    Haystack v1.21.1 adds async Pipeline execution and an arun method on PromptNode for non-blocking LLM calls.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.21.1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.21.1
    └──▷ USE IT
    Run a PromptNode asynchronously inside an async function to avoid blocking the event loop during LLM calls.
    python
    import asyncio
    from haystack.nodes import PromptNode
    
    pn = PromptNode(model_name_or_path="gpt-3.5-turbo", api_key="<your-key>")
    
    async def main():
        result = await pn.arun(prompt="Summarize the following text: <text>")
        print(result)
    
    asyncio.run(main())
    • Adds arun method to PromptNode for asynchronous execution, enabling non-blocking LLM inference in async applications.
    • Adds experimental asyncio support to the OpenAI invocation layer, allowing OpenAI-backed components to participate in async pipelines.
    • Adds experimental support for asynchronous Pipeline run, enabling full async orchestration of pipeline components.
  58. v1.21.0 Sep 27, 2023 · issue -386

    Haystack v1.21.0 adds gpt-3.5-turbo-instruct support, a Haystack 2.0 preview install extra, and a revamped PineconeDocumentStore.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.21.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.21.0
    └──▷ TRY IT
    Try Haystack 2.0 preview components without pulling in the full core dependency set.
    $ pip install farm-haystack[preview]
    Migrate PineconeDocumentStore queries from namespaces to the new metadata-based API after upgrading.
    python
    from haystack.document_stores.pinecone import DOCUMENT_WITH_EMBEDDING
    
    # Retrieve documents that have an embedding
    docs_with_embedding = doc_store.get_all_documents(type_metadata=DOCUMENT_WITH_EMBEDDING)
    
    # Retrieve documents without an embedding
    docs_without_embedding = doc_store.get_all_documents(type_metadata="no-vector")
    • Adds support for OpenAI's gpt-3.5-turbo-instruct model via PromptNode, enabling use of OpenAI's latest instruct-tuned completion model in existing pipelines.
    • Introduces farm-haystack[preview] installation extra to try Haystack 2.0 components and pipeline design, while also making core dependencies leaner and speeding up installation.
    • Refactors PineconeDocumentStore to use metadata instead of namespaces for distinguishing document types; adds type_metadata parameter to get_all_documents() and exposes the DOCUMENT_WITH_EMBEDDING constant from haystack.document_stores.pinecone.
    • Adds AnswerBuilder component (Haystack 2.0 preview) that creates Answer objects from the string output of Generator components.
    • Adds LinkContentFetcher component (Haystack 2.0 preview) that fetches content from a URL and converts it into a Document object for use in pipelines.
    +14 moreshow less
    • Adds MetadataRouter component (Haystack 2.0 preview) that routes documents to different pipeline edges based on the content of their metadata fields.
    • Adds PDF file support to the Haystack 2.0 Document converter via the pypdf library.
    • Adds SerperDevWebSearch component (Haystack 2.0 preview) to retrieve URLs from the web using the Serper.dev API.
    • Adds TikaDocumentConverter component (Haystack 2.0 preview) to convert files of multiple types into Document objects.
    • Adds ExtractiveReader component (Haystack 2.0 preview) as a replacement for FARMReader for inference, with per-span binary classification confidence scoring.
    • Introduces GPTGenerator class (Haystack 2.0 preview) for generating completions using OpenAI Chat models such as GPT-3.5 and GPT-4.
    • Adds GPT4Generator component (Haystack 2.0 preview) as an LLM component based on GPT35Generator.
    • Adds embedding_retrieval method to MemoryDocumentStore (Haystack 2.0 preview), exposed as MemoryEmbeddingRetriever, which retrieves relevant documents given a query embedding.
    • Renames MemoryRetriever to MemoryBM25Retriever and adds MemoryEmbeddingRetriever (Haystack 2.0 preview) for embedding-based retrieval from MemoryDocumentStore.
    • Adds OpenAI Text Embedder component (Haystack 2.0 preview) that uses OpenAI models to embed strings into vectors.
    • Adds PromptBuilder component (Haystack 2.0 preview) to render prompts from template strings.
    • Adds prefix and suffix attributes to SentenceTransformersDocumentEmbedder (Haystack 2.0 preview) for prepending/appending text to documents before embedding, enabling full use of models such as E5.
    • Adds support for date values in document store filters (Haystack 2.0 preview).
    • Adds UrlCacheChecker component (Haystack 2.0 preview) that checks whether documents from given URLs are already present in the store, returning cached documents and unmatched URLs on a separate connection.
    └──▷ BREAKING ON UPGRADE
    • !SklearnQueryClassifier is removed; users must migrate to TransformersQueryClassifier.
    • !PineconeDocumentStore now uses metadata instead of namespaces to distinguish document types — the namespace parameter to get_all_documents() no longer works; callers must switch to the type_metadata parameter (e.g. type_metadata=DOCUMENT_WITH_EMBEDDING or type_metadata='no-vector').
  59. v1.20.0 Sep 4, 2023 · issue -386

    Haystack v1.20.0 adds LostInTheMiddleRanker, DiversityRanker, allowed_domains for WebRetriever, and dynamic filter support in custom OpenSearch/Elasticsearch queries.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.20.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.20.0
    └──▷ USE IT
    Build a RAG pipeline that diversifies retrieved documents and then reorders them with the Lost-in-the-Middle strategy before generation.
    python
    from haystack.nodes import WebRetriever, TopPSampler, DiversityRanker, LostInTheMiddleRanker
    from haystack.pipelines import Pipeline
    
    web_retriever = WebRetriever(api_key=search_key, top_search_results=5, mode="preprocessed_documents", top_k=50)
    sampler = TopPSampler(top_p=0.97)
    diversity_ranker = DiversityRanker()
    litm_ranker = LostInTheMiddleRanker(word_count_threshold=1024)
    
    pipeline = Pipeline()
    pipeline.add_node(component=web_retriever, name="Retriever", inputs=["Query"])
    pipeline.add_node(component=sampler, name="Sampler", inputs=["Retriever"])
    pipeline.add_node(component=diversity_ranker, name="DiversityRanker", inputs=["Sampler"])
    pipeline.add_node(component=litm_ranker, name="LostInTheMiddleRanker", inputs=["DiversityRanker"])
    pipeline.add_node(component=prompt_node, name="PromptNode", inputs=["LostInTheMiddleRanker"])
    Pass dynamic filters at query-time to a BM25Retriever using the new ${filters} placeholder in a custom OpenSearch query, without modifying the stored query template.
    python
    retriever = BM25Retriever(
        custom_query="""
        {
            "query": {
                "bool": {
                    "should": [{"multi_match": {
                        "query": ${query},
                        "type": "most_fields",
                        "fields": ["content", "title"]}}],
                    "filter": ${filters}
                }
            }
        }"""
    )
    
    retriever.retrieve(
        query="What is the meaning of life?",
        filters={"year": [2019, 2020], "quarter": [1, 2, 3], "date": {"$gte": "2019-03-01"}}
    )
    Scope a WebRetriever to specific domains to build a 'talk to your docs' pipeline without off-site noise.
    python
    web_retriever = WebRetriever(
        api_key=search_key,
        allowed_domains=["docs.haystack.deepset.ai", "haystack.deepset.ai"],
        top_search_results=10,
        mode="preprocessed_documents"
    )
    • Adds LostInTheMiddleRanker class, which reorders documents so the most relevant appear at the beginning and end of the context window, implementing the 'Lost in the Middle' strategy for RAG pipelines; accepts a word_count_threshold parameter.
    • Adds DiversityRanker class, which uses sentence-transformer models to rank documents so each successive result is maximally semantically dissimilar from already-selected ones; accepts a top_k parameter.
    • Adds ${filters} placeholder support in custom_query for BM25Retriever with OpenSearch and Elasticsearch, enabling dynamic query-time filters without modifying the stored query template.
    • Adds allowed_domains parameter to WebRetriever, enabling domain-scoped searches for 'talk to a website' and 'talk to docs' use cases.
    • Adds search_fields parameter to DeepsetCloudDocumentStore sparse queries, allowing BM25Retriever to search meta fields such as title alongside document content.
    +11 moreshow less
    • Adds FileExtensionClassifier to Haystack 2.0 preview components.
    • Adds SentenceTransformersDocumentEmbedder to Haystack 2.0 preview, storing computed embeddings in the embedding field of each Document.
    • Adds SentenceTransformersTextEmbedder to Haystack 2.0 preview for embedding arbitrary strings into vectors.
    • Adds Answer base class, GeneratedAnswer, and ExtractedAnswer types for Haystack v2.
    • Enhances FileTypeClassifier to detect media file types including mp3, mp4, mpeg, and m4a.
    • Adds PDF support and custom User-Agent header to LinkContentFetcher, plus a mechanism to register new content handlers dynamically.
    • Enables setting max_length when running PromptNode with local Hugging Face text2text-generation models.
    • Enables passing trust_remote_code=True to load tokenizers for prompt models not natively supported by Transformers.
    • Allows WebRetriever users to supply a custom LinkContentFetcher instance.
    • Refactors DocumentWriter to accept a generic DocumentStore instead of using DocumentStoreAwareMixin.
    • Refactors MemoryRetriever to require a MemoryDocumentStore directly instead of using DocumentStoreAwareMixin.
    └──▷ BREAKING ON UPGRADE
    • !The OpenSearch custom_query old per-field filter placeholders (e.g. ${years}, ${quarters}, ${date}) are no longer supported; replace all filter expressions with the single ${filters} placeholder.
    • !Custom PromptModelInvocationLayer subclasses: invoke() no longer receives prompt template parameters (such as query, documents) as keyword arguments; existing custom layers must be updated accordingly.
  60. v1.19.0 Jul 26, 2023 · issue -388

    Haystack v1.19 adds Elasticsearch 8 support, a RecentnessRanker, Anthropic Claude 2, and Llama 2 on SageMaker.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.19.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.19.0
    └──▷ TRY IT
    Use the new Elasticsearch 8 backend by installing the dedicated extra — auto-detection picks the right Document Store at import time.
    $ pip install farm-haystack[elasticsearch8]
    Run Llama 2 chat hosted on AWS SageMaker through PromptNode by supplying the endpoint name, AWS profile, and EULA acceptance attribute.
    python
    from haystack.nodes import PromptNode
    
    prompt_node = PromptNode(
        model_name_or_path="sagemaker-llama-2-chat-endpoint-name",
        model_kwargs={
            "aws_profile_name": "my_aws_profile_name",
            "aws_custom_attributes": {"accept_eula": True}
        }
    )
    chat = [[{"role": "user", "content": "Summarize CVE mitigations for Log4Shell."}]]
    print(prompt_node(chat))
    • Adds farm-haystack[elasticsearch8] install extra and ElasticsearchDocumentStore auto-detection that selects the correct backend based on the installed Elasticsearch client version (covers ES 8 and ES <=7.5).
    • Adds farm-haystack[elasticsearch7] install extra alongside the new elasticsearch8 extra for explicit version pinning.
    • Introduces RecentnessRanker in haystack.nodes with date_meta_field, ranking_mode, and weight parameters to blend document age with relevance scores.
    • Adds embed_meta_fields support to Ranker nodes, enabling metadata to be included in the text used for ranking.
    • Adds support for list-typed embed_meta_fields when embedding metadata fields in retrievers.
    +9 moreshow less
    • Extends Anthropic Claude support to Claude 2 models with updated context window sizes and a new streaming API via PromptNode.
    • Enables Llama 2 (including chat variant) on AWS SageMaker via PromptNode using aws_profile_name and aws_custom_attributes in model_kwargs.
    • Upgrades dependency to transformers v4.31.0, enabling Llama 2 support for local inference.
    • Adds global progress bar suppression capability to pipelines.
    • Adds OpenAI-Organization header support for OpenAI authentication.
    • Introduces LinkContentFetcher node by extracting link-retrieval logic from WebRetriever into a standalone component.
    • Adds BM25 retrieval support for MemoryDocumentStore.
    • Adds batch mode for MemoryRetriever (v2).
    • Introduces a Store protocol (v2) and extends pipeline.add_component to support stores.
  61. v1.18.0 Jun 29, 2023 · issue -389

    Haystack v1.18 adds AWS SageMaker LLM support, PromptHub integration, ConversationalAgent tools, and a new CohereRanker node.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.18.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.18.0
    └──▷ USE IT
    Pull a ready-made prompt from PromptHub by name to classify topics without writing a prompt from scratch.
    python
    import os
    from haystack.nodes import PromptNode, PromptTemplate
    
    template = PromptTemplate("deepset/topic-classification")
    prompt_node = PromptNode(
        model_name_or_path="text-davinci-003",
        api_key=os.environ.get("OPENAI_API_KEY")
    )
    result = prompt_node.prompt(
        prompt_template=template,
        documents="YOUR_DOCUMENTS",
        options=["sports", "politics", "technology"]
    )
    Equip a ConversationalAgent with a QA pipeline tool so it can answer domain-specific questions mid-conversation.
    python
    from haystack.agents import Tool
    from haystack.agents.conversational import ConversationalAgent
    
    search_tool = Tool(
        name="USA_Presidents_QA",
        pipeline_or_node=presidents_qa_pipeline,
        description="useful for when you need to answer questions about US presidents."
    )
    agent = ConversationalAgent(prompt_node=prompt_node, tools=[search_tool])
    agent.run("Who was the 35th president of the United States?")
    • Adds AWS SageMaker-hosted LLM support to PromptNode via model_kwargs keys aws_profile_name and aws_region_name, enabling open-source models deployed on SageMaker endpoints.
    • Introduces PromptHub integration: PromptTemplate now accepts a hub prompt name (e.g. 'deepset/topic-classification') directly, with local caching of fetched prompts.
    • Adds tools parameter to ConversationalAgent for attaching Tool instances (pipelines or nodes) to a chat agent.
    • Adds prompt_template parameter to ConversationalAgent.__init__ for customising the agent's prompt at construction time.
    • Adds CohereRanker node backed by the Cohere reranking endpoint.
    +8 moreshow less
    • Adds batch_size parameter to WeaviateDocumentStore query methods.
    • Adds batching support for querying in ElasticsearchDocumentStore and OpenSearchDocumentStore.
    • Adds current_datetime shaper function for use in pipeline prompt construction.
    • Adds max_chars_check hard document length limit to pipeline processing.
    • Adds optional content moderation for OpenAI PromptNode and OpenAIAnswerGenerator.
    • Supports passing model parameters to HFLocalInvocationLayer via model_kwargs for direct model usage.
    • Supports setting a custom api_base for OpenAI nodes.
    • New farm-haystack[inference] extra installs PyTorch and related dependencies for local model execution, keeping the base install lighter for API-only users.
    └──▷ BREAKING ON UPGRADE
    • !PromptTemplate no longer accepts name or prompt_text parameters; use prompt and output_parser instead.
    • !Seq2SeqGenerator and RAGenerator have been removed; use PromptNode instead.
    • !The deprecated PDFToTextOCRConverter node has been removed.
    • !The deprecated return_table_cell parameter has been removed.
    • !PyTorch and inference-related dependencies are no longer installed by default; run pip install farm-haystack[inference] to restore local model support.
    • !Weaviate authentication has been simplified (feat!: simplify weaviate auth); existing auth configuration may need to be updated.
  62. v1.17.0 May 30, 2023 · issue -390

    Haystack v1.17 adds ConversationalAgent with memory, Anthropic and Cohere LLM support, Weaviate auth, and streaming for HF Inference Endpoints.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.17.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.17.0
    └──▷ USE IT
    Build a chat application with summarized memory to stay within token limits.
    python
    from haystack.agents.memory import ConversationalSummaryMemory
    from haystack.agents import ConversationalAgent
    
    summary_memory = ConversationalSummaryMemory(prompt_node=prompt_node)
    agent = ConversationalAgent(prompt_node=prompt_node, memory=summary_memory)
    response = agent.run(user_input="What are the main causes of climate change?")
    Override generation parameters per pipeline run without changing the PromptNode definition.
    python
    pipeline.run(
        query="Summarize this document",
        params={
            "PromptNode": {
                "generation_kwargs": {"max_new_tokens": 200, "temperature": 0.7}
            }
        }
    )
    • Adds ConversationalAgent class for building chat applications, accepting a PromptNode and an optional memory argument for conversation history injection.
    • Adds ConversationSummaryMemory (also referenced as ConversationalSummaryMemory) to condense chat history before injecting into the prompt, keeping usage within model token limits.
    • Adds AnthropicInvocationLayer to support claude models from Anthropic as a PromptNode backend.
    • Adds CohereInvocationLayer to support command models from Cohere as a PromptNode backend.
    • Adds AuthBearerToken and AuthClientCredentials authentication options to WeaviateDocumentStore.
    +7 moreshow less
    • Adds max_tokens parameter to BaseGenerator params, exposing token-limit control across generator implementations.
    • Adds streaming support to HFInferenceEndpointInvocationLayer for token-by-token output from Hugging Face Inference Endpoints.
    • Adds streaming support to the HF local runtime invocation layer.
    • Enables passing generation_kwargs to PromptNode at pipeline.run() time, allowing per-run overrides of generation parameters.
    • Adds BLIP model support to TransformersImageToText component.
    • Adds Google API as a search engine provider option.
    • Introduces generalimport to defer missing-dependency errors from import time to actual usage time, reducing mandatory dependencies for a base pip install farm-haystack.
    └──▷ BREAKING ON UPGRADE
    • !MilvusDocumentStore is removed from core Haystack; it must now be installed separately from the haystack-extras repo.
    • !BaseKnowledgeGraph is removed from the library.
    • !The PDFToTextOCRConverter node is removed.
    • !Schema objects' to_dict, from_dict, to_json, and from_json methods have been updated to handle Dataframes, which may change serialization behavior for existing code.
  63. v1.16.0 Apr 27, 2023 · issue -391

    Haystack v1.16 adds GPT-4 and AzureChatGPT support, streaming, a Haystack CLI, and more flexible document routing.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.16.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.16.0
    └──▷ USE IT
    Use GPT-4 in a multi-turn chat pipeline — drop-in for existing ChatGPT workflows with higher capability.
    python
    from haystack.nodes import PromptModel, PromptNode
    
    prompt_model = PromptModel("gpt-4", api_key=api_key)
    prompt_node = PromptNode(prompt_model)
    messages = [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Summarize the attached document."},
    ]
    result = prompt_node(messages)
    • Adds PromptModel('gpt-4', api_key=...) support inside PromptNode and Agent, enabling chat-style multi-turn conversations with GPT-4.
    • Adds AzureChatGPT invocation layer for PromptNode, enabling Azure-hosted ChatGPT endpoints via the new invocation layer style.
    • Adds ChatGPT streaming support via PromptNode for real-time token-by-token output.
    • Adds a Hugging Face Inference API invocation layer for PromptNode, enabling remote HF-hosted model inference without local GPU.
    • Adds MemoryDocumentStore for the new Pipelines API.
    +6 moreshow less
    • Adds arbitrary crawler_depth parameter to the Crawler class, allowing configurable recursive web crawling depth.
    • Enhances RouteDocuments node to emit an extra route for unmatched Documents and adds List[List[str]] support for metadata_values, preventing silent document loss on missing metadata fields.
    • Adds filtering support for Weaviate when used for BM25 querying.
    • Adds a Haystack CLI (haystack) for command-line management.
    • Adds a load documents from remote helper function for fetching documents from remote sources.
    • Deprecates RAGenerator and Seq2SeqGenerator; both will be removed in v1.18 — PromptNode is the recommended replacement.
    └──▷ BREAKING ON UPGRADE
    • !Python 3.7 is no longer supported; upgrade to Python 3.8 or later.
    • !PreProcessor now requires farm-haystack[preprocessing]; installing the base package no longer pulls it in.
    • !DocxToTextConverter, TikaConverter, and LangdetectDocumentLanguageClassifier now require farm-haystack[file-conversion].
    • !ElasticsearchDocumentStore now requires farm-haystack[elasticsearch].
    • !TableCell replaces Span for indicating table cell coordinates.
    • !Default save_dir for FARMReader.train() changed to f'./saved_models/{self.inferencer.model.language_model.name}'.
    • !Using PreProcessor with split_respect_sentence_boundary=True may return a different set of Documents than in v1.15.
  64. v1.15.0 Mar 30, 2023 · issue -392

    Haystack v1.15.0 adds LLM Agents with Tools, ChatGPT support via gpt-3.5-turbo, AnswerParser, JsonConverter, Whisper node, and Azure OpenAI embeddings.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.15.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.15.0
    └──▷ USE IT
    Build a multi-hop web QA agent that loops over a search tool to answer complex questions.
    python
    web_qa_tool = Tool(
        name="Search",
        pipeline_or_node=WebQAPipeline(retriever=web_retriever, prompt_node=web_qa_pn),
        description="useful for when you need to Google questions.",
        output_variable="results",
    )
    
    agent = Agent(
        prompt_node=agent_pn,
        prompt_template=prompt_template,
        tools=[web_qa_tool],
        final_answer_pattern=r"Final Answer\s*:\s*(.*)",
    )
    agent.run(query="What is the capital of the country that won the 2022 FIFA World Cup?")
    Parse LLM answers directly into Haystack Answer objects using AnswerParser inside a PromptTemplate.
    python
    PromptTemplate(
        name="question-answering",
        prompt_text="Given the context please answer the question.\nContext: {join(documents)}\nQuestion: {query}\nAnswer: ",
        output_parser=AnswerParser(),
    )
    Chat with ChatGPT in a multi-turn conversation using PromptModel with gpt-3.5-turbo.
    python
    prompt_model = PromptModel("gpt-3.5-turbo", api_key=api_key)
    prompt_node = PromptNode(prompt_model)
    messages = [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Who won the world series in 2020?"},
        {"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
        {"role": "user", "content": "Where was it played?"},
    ]
    result = prompt_node(messages)
    • Adds Agent class and Tool wrapper, enabling LLM-driven agents that dynamically plan and execute multi-step actions using a list of Tool objects and a PromptNode; configured via prompt_node, prompt_template, tools, and final_answer_pattern arguments, and invoked with agent.run(query=...).
    • Adds output_parser parameter to PromptTemplate, with a built-in AnswerParser that converts raw LLM output into Haystack Answer, Document, or Label objects.
    • Adds function-call syntax inside prompt_text (e.g., {join(documents)}) to PromptTemplate, enabling in-template transformations of input documents.
    • Adds top_k parameter to PromptNode for controlling the number of outputs returned.
    • Adds JsonConverter node for converting pipeline outputs to JSON format.
    +7 moreshow less
    • Adds Whisper node for audio transcription within Haystack pipelines.
    • Adds Azure OpenAI embeddings support, enabling Azure as an OpenAI-compatible endpoint for embedding and prompt operations.
    • Adds support for ChatGPT (gpt-3.5-turbo) through PromptModel, including multi-turn chat via a message list with role and content fields.
    • Adds automatic OCR detection mechanism to PDF converters, improving performance by only invoking OCR when needed.
    • Adds execution time reporting for pipeline components in _debug output.
    • Exposes prompt text to Answer and EvaluationResult objects for traceability.
    • Extracts AnswerToSpeech and DocumentToSpeech into the separate haystack-extras repo, installable via pip install farm-haystack-text2speech.
    └──▷ BREAKING ON UPGRADE
    • !OpenDistroElasticsearchDocumentStore has been removed; any code referencing it will break on upgrade.
    • !AnswerToSpeech and DocumentToSpeech nodes have been removed from the main package; install farm-haystack-text2speech from the haystack-extras repo to continue using them.
    • !ElasticsearchRetriever and ElasticsearchFilterOnlyRetriever have been removed.
    • !The id_hash_keys parameter has been removed from the from_dict method.
    • !The REST API Dockerfile now uses uvicorn instead of gunicorn as the server; deployments that relied on gunicorn-specific behavior or config will need updating.
    • !Crawler standardization changes increase conformance with Pipeline conventions but may break existing Crawler configurations.
    • !PDFToTextConverter multiprocessing changes simplify installation but alter prior behavior; existing setups should be tested.
  65. v1.14.0 Feb 28, 2023 · issue -393

    Haystack v1.14.0 adds Shaper, PromptNode run_batch/model_kwargs/top_k, IVF+PQ for OpenSearch, JsonConverter, and more.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.14.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.14.0
    └──▷ USE IT
    Pass model-specific generation parameters to PromptNode at initialisation, such as temperature and stop sequences.
    python
    from haystack.nodes import PromptNode
    node = PromptNode('gpt-3.5-turbo', model_kwargs={'temperature': 0.2, 'stop': ['\n']})
    Initialise OpenSearchDocumentStore with IVF+Product Quantization so the index is trained automatically on first use.
    python
    from haystack.document_stores import OpenSearchDocumentStore
    store = OpenSearchDocumentStore(
        index='my_index',
        embedding_field='embedding',
        embedding_dim=768,
        ivf_train_size=10000
    )
    • Adds Shaper node to transform and reshape data between pipeline components, usable independently or as a PromptNode helper.
    • Adds run_batch method to PromptNode for batch inference.
    • Adds model_kwargs option to PromptNode for passing arbitrary model parameters.
    • Adds top_k parameter to PromptNode.
    • Exposes output_variable in PromptNode result.
    +15 moreshow less
    • Adds train_index method and ivf_train_size initialisation parameter to OpenSearchDocumentStore for IVF and IVF with Product Quantization index training.
    • Adds JsonConverter node for converting JSON inputs in pipelines.
    • Adds frontmatter-to-meta extraction in MarkdownConverter.
    • Adds page range support to PDF converters.
    • Adds use_prefiltering parameter to DeepsetCloudDocumentStore.
    • Adds BM25 support for tables in InMemoryDocumentStore.
    • Adds support for custom headers in document stores.
    • Adds support for multiple RayPipeline instances running concurrently.
    • Allows all training options for SentenceTransformers EmbeddingRetriever.
    • Adds user-configurable timeout for remote APIs.
    • Enables secure model loading by default.
    • Adds OpenAIError to the retry mechanism.
    • Warns users when max_tokens is too short for OpenAI models.
    • Includes testing facilities in the haystack package for downstream consumers.
    • Supports multiple document_ids in the Answer object for generative QA.
    └──▷ BREAKING ON UPGRADE
    • !The REST API schema for tables has been updated to be consistent with Document.to_dict; existing table schema integrations may require adjustment.
    • !The Answer object now supports multiple document_ids (previously a single value); code that assumes a single document_id field will need to be updated.
    • !Defaults for OpenAIAnswerGenerator have changed; existing pipelines relying on previous defaults may behave differently after upgrade.
  66. v1.13.2 Feb 9, 2023 · issue -393

    Haystack v1.13.2 adds use_prefiltering parameter to DeepsetCloudDocumentStore

    └──▷ GET THIS VERSION
    $ git clone --branch v1.13.2 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.13.2
    • Adds use_prefiltering parameter to DeepsetCloudDocumentStore to control whether pre-filtering is applied during document retrieval.
  67. v1.13.1 Feb 2, 2023 · issue -393

    Haystack v1.13.1 adds the Shaper component and frontmatter-to-meta extraction in MarkdownConverter.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.13.1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.13.1
    • Adds Shaper component for reshaping and transforming data between pipeline nodes.
    • Adds frontmatter extraction to meta in MarkdownConverter, surfacing YAML/TOML front matter as structured document metadata.
  68. v1.13.0 Jan 27, 2023 · issue -394

    Haystack v1.13 adds stop words for PromptNode, ImageToText and CsvTextConverter nodes, tiktoken support, and HA for Weaviate.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.13.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.13.0
    └──▷ USE IT
    Stop LLM output at a sentinel phrase to keep answers concise when using PromptNode.
    python
    from haystack.nodes import PromptNode
    
    pn = PromptNode(
        model_name_or_path='text-davinci-003',
        stop_words=['\nHuman:', 'END']
    )
    result = pn.run(prompt='Summarize the following document: ...')
    • Adds stop_words list parameter to PromptNode to halt LLM text generation when any stop word is encountered; stop words are excluded from the response.
    • Adds index parameter to TfidfRetriever to specify which index to query.
    • Adds knn_engine parameter to SearchEngineDocumentStore to make score_script a first-class citizen for KNN search.
    • New ImageToText node generates captions from image files and produces Haystack Document objects from them.
    • New CsvTextConverter node loads CSV files of FAQ question-answer pairs and sends them to a DocumentStore for FAQ matching pipelines.
    +10 moreshow less
    • Adds retry with exponential back-off to PromptNode's OpenAI model integrations.
    • Supports cl100k_base tokenization via OpenAI's tiktoken library for dramatically faster tokenization of GPT models; falls back to HuggingFace tokenizers on unsupported platforms (Python < 3.8, arm64, macOS).
    • Adds high-availability (HA) support for the Weaviate DocumentStore.
    • Enables text-embedding-ada-002 model for EmbeddingRetriever.
    • Updates Cohere embedding models support and adds use of Cohere's truncate option in Cohere.embed.
    • Stores id_hash_keys in Document objects to make documents clonable.
    • Adds async functionality support for Ray Serve pipelines.
    • Makes new sklearn models the default in QueryClassifier.
    • Adds PromptModel, PromptNode, and PromptTemplate to expand LLM support.
    • Raises a warning in Preprocessor when a document's length exceeds the configured threshold.
    └──▷ BREAKING ON UPGRADE
    • !Native PyTorch AMP replaces the previous AMP integration; existing code relying on the old AMP behaviour will break.
    • !invocation_context is moved from meta to its own pipeline variable; code reading meta['invocation_context'] will break.
    • !The batch_size parameter names in distillation are renamed for consistency; existing calls using the old names will break.
  69. v1.12.1 Dec 21, 2022 · issue -395

    Haystack v1.12.1 adds PromptNode for LLM integration, BM25 support in InMemoryDocumentStore, and parallel dense batch search for Elasticsearch/OpenSearch.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.12.1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.12.1
    └──▷ USE IT
    Use the latest OpenAI or Cohere embedding models in EmbeddingRetriever to get higher-quality dense retrieval without changing any other pipeline code.
    python
    from haystack.nodes import EmbeddingRetriever
    
    # OpenAI
    retriever = EmbeddingRetriever(
        embedding_model="text-embedding-ada-002",
        batch_size=32,
        api_key=api_key,
        max_seq_len=8191
    )
    
    # Cohere multilingual
    retriever = EmbeddingRetriever(
        embedding_model="multilingual-22-12",
        batch_size=16,
        api_key=api_key
    )
    • Introduces PromptNode (in haystack.nodes.prompt) with PromptModel and PromptTemplate, enabling LLM-powered NLP tasks via prompt templates; supports Google Flan-T5 and OpenAI GPT-3 models (e.g. google/flan-t5-base, text-davinci-003) standalone or chained in pipelines.
    • Adds all_terms_must_match parameter to BM25Retriever, configurable at runtime.
    • Adds query_by_embedding_batch to ElasticsearchDocumentStore and OpenSearchDocumentStore, enabling parallel dense searches via msearch — up to 49% faster for run_batch, eval_batch, and MostSimilarDocumentsPipeline.
    • Extends EmbeddingRetriever to support Cohere multilingual embedding models (e.g. multilingual-22-12) and OpenAI embedding models (e.g. text-embedding-ada-002 with max_seq_len=8191).
    • Adds BM25Retriever support to InMemoryDocumentStore, making it the first dependency-free document store to support all Haystack retrievers.
    +2 moreshow less
    • Adds offsets_in_context field to evaluation results.
    • Enables SQLDocumentStore to store metadata using JSON.
    └──▷ BREAKING ON UPGRADE
    • !Docker images deepset/haystack-cpu, deepset/haystack-gpu, and their tags are discontinued; Dockerfiles /Dockerfile, /Dockerfile-GPU, and /Dockerfile-GPU-minimal will be removed from the codebase after this release.
  70. v1.11.0 Nov 21, 2022 · issue -396

    Haystack v1.11.0 adds CohereEmbeddingEncoder, headline extraction from Markdown/PDF, TextIndexingPipeline, and document_store parameter on all retrievers.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.11.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.11.0
    └──▷ USE IT
    Extract structured headlines (with position and level) from a Markdown file when indexing, so downstream components can use document structure.
    python
    from haystack.nodes import MarkdownConverter
    
    converter = MarkdownConverter(extract_headlines=True)
    docs = converter.convert(file_path="report.md", meta=None)
    print(docs[0].meta['headlines'])
    # [{'headline': 'Introduction', 'start_idx': 0, 'level': 1}, ...]
    Pass a specific document store at query time instead of at retriever construction, enabling a single retriever instance across multiple stores.
    python
    results = retriever.retrieve(
        query="What is the capital of France?",
        document_store=alternate_document_store
    )
    • Adds CohereEmbeddingEncoder to EmbeddingRetriever, supporting Cohere models small, medium, and large for document and query embeddings via API key.
    • Adds extract_headlines parameter to MarkdownConverter and ParsrConverter; extracted headlines are stored in document.meta['headlines'] as a list of dicts with headline, start_idx, and level fields.
    • Adds document_store parameter to all BaseRetriever.retrieve() and BaseRetriever.retrieve_batch() implementations, allowing the document store to be specified at query time.
    • Introduces TextIndexingPipeline for straightforward text indexing workflows.
    • Adds __contains__ method to Span for membership testing.
    +2 moreshow less
    • Adds exponential backoff decorator applied to OpenAI requests to handle rate limiting automatically.
    • Adds indexing pipeline type support.
    └──▷ BREAKING ON UPGRADE
    • !Milvus1DocumentStore is removed; Milvus versions below 2.x are no longer supported. Milvus2DocumentStore has been renamed to MilvusDocumentStore — code referencing either old name will break.
    • !A duplicated meta name field that was previously added to document content before embedding in the update_embeddings workflow has been removed; embeddings generated before this change may differ.
  71. v1.10.0 Oct 25, 2022 · issue -397

    Haystack v1.10 adds OpenAI embeddings, multimodal retrieval, HNSW/OpenSearch support, and multi-platform Docker images.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.10.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.10.0
    └──▷ USE IT
    Perform text-to-image retrieval using a multimodal CLIP model across an image document store.
    python
    retriever = MultiModalRetriever(
        document_store=InMemoryDocumentStore(embedding_dim=512),
        query_embedding_model="sentence-transformers/clip-ViT-B-32",
        query_type="text",
        document_embedding_models={"image": "sentence-transformers/clip-ViT-B-32"}
    )
    • Adds OpenAIEmbeddingEncoder to EmbeddingRetriever, enabling document and query embeddings via OpenAI models ada, babbage, davinci, or curie using an API key.
    • Adds MultiModalRetriever supporting independent modalities for query and documents — enabling text-to-image, text-to-table, text-to-text, image similarity, and table similarity retrieval via configurable query_embedding_model, query_type, and document_embedding_models parameters.
    • Adds filters parameter to MostSimilarDocumentsPipeline.run() and run_batch() for filtered similarity searches.
    • Adds HNSW support for cosine similarity in FAISS-backed OpenSearch (FAISSDocumentStore with OpenSearch).
    • Adds support for Elasticsearch 7.16.2 in ElasticSearchDocumentStore.
    +3 moreshow less
    • Adds exponential backoff decorator applied to OpenAI requests to handle rate limiting.
    • Updates EntityExtractor to handle long texts with improved postprocessing.
    • Publishes deepset/haystack Docker images for both linux/amd64 and linux/arm64 platforms.
    └──▷ BREAKING ON UPGRADE
    • !The text argument in the embed_queries method for DensePassageRetriever and EmbeddingRetriever is renamed to queries; callers using the keyword argument text= will break.
  72. v1.9.0 Sep 21, 2022 · issue -398

    Haystack v1.9.0 adds a health-check endpoint, layout-based PDF extraction, MultipleNegativesRankingLoss for retriever training, and a unified Docker image.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.9.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.9.0
    └──▷ USE IT
    Train an EmbeddingRetriever with MultipleNegativesRankingLoss for better contrastive learning on in-batch negatives.
    python
    retriever.train(
        data_dir="training_data/",
        train_filename="train.json",
        loss_function="MultipleNegativesRankingLoss"
    )
    • Adds a health check endpoint to the REST API, enabling liveness probes and load-balancer integration.
    • Adds MultipleNegativesRankingLoss as a training loss option for EmbeddingRetriever when using sentence-transformers.
    • Adds public layout-based text extraction support to PDFToTextConverter, enabling structure-aware PDF parsing.
    • Adds exponential backoff with exponentially decreasing batch size for OpenSearch and Elasticsearch clients under load.
    • Publishes a new unified deepset/haystack Docker image with support for multiple flavors and versions via Docker tags.
    +3 moreshow less
    • Standardizes the devices parameter and device initialization across pipeline components.
    • Adds PineconeDocumentStore warnings when indexing metadata would cause filters to return no documents.
    • Updates language parameter documentation and types for PreProcessor, clarifying supported language values.
    └──▷ BREAKING ON UPGRADE
    • !Pre-Haystack-1.0 import paths are removed and no longer supported.
  73. v1.8.0 Aug 26, 2022 · issue -399

    Haystack v1.8.0 adds batch pipeline eval, early stopping for training, SQL-free PineconeDocumentStore, and FAISS support in OpenSearch.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.8.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.8.0
    └──▷ USE IT
    Stop reader training automatically when loss improvement drops below a threshold, saving GPU time on large training runs.
    python
    from haystack.nodes import FARMReader
    from haystack.utils.early_stopping import EarlyStopping
    
    reader = FARMReader(model_name_or_path="deepset/roberta-base-squad2-distilled")
    reader.train(
        data_dir="data/squad20",
        train_filename="dev-v2.0.json",
        early_stopping=EarlyStopping(min_delta=0.001),
        use_gpu=True,
        n_epochs=8,
        save_dir="my_model"
    )
    Use FAISS as the k-NN engine in OpenSearchDocumentStore for faster approximate nearest-neighbour search.
    python
    from haystack.document_stores import OpenSearchDocumentStore
    
    document_store = OpenSearchDocumentStore(knn_engine="faiss")
    • Adds pipeline.eval_batch() method to ExtractiveQAPipeline for GPU-accelerated batch evaluation over large datasets, reducing evaluation run time.
    • Adds EarlyStopping class (importable from haystack.utils.early_stopping) with min_delta parameter for FARMReader.train() and DensePassageRetriever training; monitors loss, EM, f1, top_n_accuracy (FARMReader) or loss, acc, f1, average_rank (DensePassageRetriever).
    • Adds knn_engine parameter to OpenSearchDocumentStore to select between nmslib and faiss approximate k-NN libraries; falls back to exact vector calculation if the loaded index was built with a different engine.
    • PineconeDocumentStore no longer requires a local SQL database — initialization now only needs a Pinecone API key.
    • Adds exact list matching support for field filters in ElasticsearchDocumentStore.
    +1 moreshow less
    • Adds progress bar to upload_files() in the deepset Cloud client.
  74. v1.7.1 Aug 19, 2022 · issue -399

    Haystack v1.7.1 lets you specify a configurable list of models to cache instead of a single hardcoded one.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.7.1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.7.1
    • Supports passing a configurable list of models to cache, replacing the previously hardcoded single-model approach.
  75. v1.7.0 Aug 15, 2022 · issue -399

    Haystack v1.7 adds OpenAI GPT-3 generation, zero-shot query classification, page-number metadata, gradient accumulation, and expanded Ray Serve support.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.7.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.7.0
    └──▷ USE IT
    Route queries to different pipeline branches based on semantic topic using zero-shot classification — no labelled training data required.
    python
    from haystack.nodes import TransformersQueryClassifier
    
    classifier = TransformersQueryClassifier(
        model_name_or_path="typeform/distilbert-base-uncased-mnli",
        use_gpu=True,
        task="zero-shot-classification",
        labels=["music", "cinema", "food"],
    )
    result = classifier.run(query="Who directed Pulp Fiction?")
    print(result)
    Control Ray Serve replica count and resource allocation per node directly in a Pipeline YAML for production Ray deployments.
    yaml
    pipelines:
      - name: ray_query_pipeline
        nodes:
          - name: EmbeddingRetriever
            replicas: 2
            inputs: [ Query ]
            serve_deployment_kwargs:
              num_replicas: 2
              version: Twenty
              ray_actor_options:
                num_gpus: 0.25
                num_cpus: 0.5
              max_concurrent_queries: 17
          - name: Reader
            inputs: [ EmbeddingRetriever ]
    • Adds OpenAIAnswerGenerator node with api_key, max_tokens, and temperature parameters for GPT-3-powered generative QA.
    • Adds task='zero-shot-classification' and labels parameters to TransformersQueryClassifier, enabling multi-class zero-shot query routing with any MNLI-style model.
    • Adds add_page_number=True parameter to ParsrConverter, AzureConverter, and PreProcessor, which populates a 'page' meta field on each document chunk.
    • Adds grad_acc_steps parameter to FARMReader.train() for gradient accumulation, enabling large-model fine-tuning on memory-constrained GPUs.
    • Adds serve_deployment_kwargs key to Pipeline YAML node definitions, supporting num_replicas, version, ray_actor_options (num_gpus, num_cpus), and max_concurrent_queries for Ray Serve deployments.
    +5 moreshow less
    • Adds tokenizer_model_folder parameter to PreProcessor to support custom domain-specific sentence tokenizer models.
    • Adds update_document_meta() method to InMemoryDocumentStore, aligning its interface with other document stores.
    • Adds BM25 retrieval support to the Weaviate document store.
    • Enables JoinDocuments node to handle documents with score=None.
    • Nearly 2x performance gain for Electra reader models by eliminating a double forward-pass in the language modeling module.
    └──▷ BREAKING ON UPGRADE
    • !Adding update_document_meta to InMemoryDocumentStore introduces an interface change that may affect subclasses or code relying on the previous BaseDocumentStore method signatures.
    • !BM25 support in the Weaviate document store changes Weaviate integration behavior in a way flagged as breaking.
    • !Extending the Ray Serve integration to allow serve_deployment_kwargs attributes in Pipeline YAMLs changes the YAML schema in a breaking way.
    • !MultiLabel IDs are now consistent across Python interpreters, changing previously generated ID values.
  76. v1.6.0 Jul 6, 2022 · issue -400

    Haystack v1.6.0 adds audio QA nodes, multi-hop dense retrieval, in-memory knowledge graphs, and remote model saving to HuggingFace Hub.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.6.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.6.0
    └──▷ USE IT
    Upload a fine-tuned QA reader model to the Hugging Face Model Hub as a private repo after training.
    python
    from haystack.nodes import FARMReader
    
    reader = FARMReader(model_name_or_path="roberta-base")
    reader.train(data_dir="my_squad_data", train_filename="squad2.json", n_epochs=1, save_dir="my_model")
    reader.save_to_remote(repo_id="your-user-name/roberta-base-squad2", private=True, commit_message="First version of my qa model trained with Haystack")
    Run multi-hop dense retrieval over an in-memory document store to answer complex open-domain questions requiring multiple document hops.
    python
    from haystack.nodes import MultihopEmbeddingRetriever
    from haystack.document_stores import InMemoryDocumentStore
    
    document_store = InMemoryDocumentStore()
    retriever = MultihopEmbeddingRetriever(
        document_store=document_store,
        embedding_model="deutschmann/mdr_roberta_q_encoder",
    )
    Load a knowledge graph from a TTL file into an in-memory store and query it with natural-language-to-SPARQL translation.
    python
    from pathlib import Path
    from haystack.nodes import Text2SparqlRetriever
    from haystack.document_stores import InMemoryKnowledgeGraph
    
    kg = InMemoryKnowledgeGraph(index="tutorial10")
    kg.create_index()
    kg.import_from_ttl_file(index="tutorial10", path=Path("data/tutorial10/triples.ttl"))
    
    kgqa_retriever = Text2SparqlRetriever(knowledge_graph=kg, model_name_or_path=Path("../saved_models/tutorial10/hp_v3.4"))
    print(kgqa_retriever.retrieve(query="In which house is Harry Potter?"))
    • Adds DocumentToSpeech node for indexing pipelines that generates an audio file per document and stores it in a SpeechDocument alongside text content (GPU recommended for indexing speed).
    • Adds AnswerToSpeech node for QA pipelines to generate audio of an answer on the fly from SpeechDocuments.
    • Adds save_to_remote(repo_id, private, commit_message) method to FARMReader for uploading trained models directly to the Hugging Face Model Hub; supports private=True and auth via use_auth_token=True on reload.
    • Adds MultihopEmbeddingRetriever node that applies iterative multi-hop dense retrieval with a shared encoder for query and documents, suited for complex open-domain questions requiring multiple document hops.
    • Adds InMemoryKnowledgeGraph document store for storing and querying knowledge graphs without a dedicated graph database, supporting create_index() and import_from_ttl_file() for loading triples from .ttl files.
    +1 moreshow less
    • Adds PyTorch 1.12 and Transformers 4.20.1 compatibility, enabling accelerated training and evaluation on Apple M1 (Apple silicon) GPUs.
  77. v1.5.0 Jun 2, 2022 · issue -401

    Haystack v1.5.0 adds Generative Pseudo Labeling, batch pipeline querying, advanced eval label scopes, and DeBERTa support.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.5.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.5.0
    └──▷ USE IT
    Generate pseudo labels from an unlabeled domain corpus and fine-tune an EmbeddingRetriever in one workflow — no human annotation required.
    python
    from haystack.nodes.retriever import EmbeddingRetriever
    from haystack.document_stores import InMemoryDocumentStore
    from haystack.nodes.question_generator.question_generator import QuestionGenerator
    from haystack.nodes.label_generator.pseudo_label_generator import PseudoLabelGenerator
    
    document_store = InMemoryDocumentStore()
    document_store.write_documents([...])
    
    retriever = EmbeddingRetriever(
        document_store=document_store,
        embedding_model="sentence-transformers/msmarco-distilbert-base-tas-b",
        max_seq_len=200
    )
    document_store.update_embeddings(retriever)
    
    qg = QuestionGenerator(model_name_or_path="doc2query/msmarco-t5-base-v1", max_length=64, split_length=200, batch_size=12)
    psg = PseudoLabelGenerator(qg, retriever)
    output, _ = psg.run(documents=document_store.get_all_documents())
    retriever.train(output["gpl_labels"])
    Run multiple queries through an ExtractiveQAPipeline in a single call to reduce overhead in batch evaluation or CI pipelines.
    python
    from haystack.pipelines import ExtractiveQAPipeline
    
    pipe = ExtractiveQAPipeline(reader, retriever)
    predictions = pipe.pipeline.run_batch(
        queries=["Who is the father of Arya Stark?", "Who is the mother of Arya Stark?"],
        params={"Retriever": {"top_k": 10}, "Reader": {"top_k": 5}}
    )
    Score pipeline evaluation only when a predicted answer appears within the correct surrounding context, not just as a string match.
    python
    eval_result = pipeline.eval(labels=eval_labels, params={"Retriever": {"top_k": 5}})
    metrics = eval_result.calculate_metrics(answer_scope="context")
    print(f'Reader - F1-Score: {metrics["Reader"]["f1"]}')
    • Adds PseudoLabelGenerator class in haystack.nodes.label_generator.pseudo_label_generator that automatically generates pseudo labels for dense retriever fine-tuning using a QuestionGenerator and a cross-encoder, enabling unsupervised domain adaptation without manual annotation.
    • Adds run_batch() method to every query pipeline and node (e.g. Pipeline.run_batch(), FARMReader.predict_batch()), accepting a list of queries and single or nested lists of documents to process multiple queries in one call.
    • Adds answer_scope and document_scope parameters to EvaluationResult.calculate_metrics(), enabling fine-grained correctness definitions such as answer_scope='context' for context-window-bounded answer matching.
    • Adds a sort argument to JoinAnswers node for controlling answer ordering.
    • Adds support for DeBERTa models (e.g. 'microsoft/deberta-v3-base', 'microsoft/deberta-v3-large') in FARMReader, delivering F1-score improvements up to ~92% on SQuAD 2.0.
    +2 moreshow less
    • Adds training checkpoint support in the retriever trainer.
    • Includes document metadata when computing embeddings in EmbeddingRetriever.
    └──▷ BREAKING ON UPGRADE
    • !Validation is now enforced for Ray pipelines, which may reject previously accepted but invalid pipeline configurations.
    • !Context matching support added to pipeline.eval() changes evaluation behaviour — existing eval workflows may see different metric results.
  78. v1.4.0 May 5, 2022 · issue -402

    Haystack v1.4.0 adds MLflow eval tracking, FARMReader confidence filtering, Milvus2 vector+metadata queries, and BM25Retriever rename.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.4.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.4.0
    └──▷ USE IT
    Log and compare eval results from multiple pipeline configurations to an MLflow tracking server.
    python
    eval_result = Pipeline.execute_eval_run(
        index_pipeline=index_pipeline,
        query_pipeline=query_pipeline,
        evaluation_set_labels=labels,
        corpus_file_paths=file_paths,
        corpus_file_metas=file_metas,
        experiment_tracking_tool="mlflow",
        experiment_tracking_uri="http://localhost:5000",
        experiment_name="my-query-pipeline-experiment",
        experiment_run_name="run_1",
        pipeline_meta={"name": "my-pipeline-1"},
        evaluation_set_meta={"name": "my-evalset"},
        corpus_meta={"name": "my-corpus"},
        add_isolated_node_eval=True,
        reuse_index=False
    )
    Filter out low-confidence reader predictions to reduce noise in QA pipeline answers.
    python
    from haystack.nodes import FARMReader
    model = "deepset/roberta-base-squad2"
    reader = FARMReader(model, confidence_threshold=0.5)
    • Adds MLflowTrackingHead and Pipeline.execute_eval_run() method with parameters experiment_tracking_tool, experiment_tracking_uri, experiment_name, experiment_run_name, pipeline_meta, evaluation_set_meta, corpus_meta, add_isolated_node_eval, and reuse_index to log evaluation metrics and pipeline artifacts to MLflow.
    • Adds confidence_threshold parameter to FARMReader (float between 0 and 1, disabled by default) to filter out low-confidence predictions at initialization time.
    • Adds devices parameter alongside existing use_gpu in FARMReader for explicit device assignment.
    • Adds alias support in ElasticsearchDocumentStore for querying via index aliases.
    • Adds conjunctive query support in sparse retrieval.
    +6 moreshow less
    • Adds a flag to disable scaling scores to probabilities in retrieval.
    • Introduces Milvus2DocumentStore (superseding the now-deprecated Milvus1DocumentStore) with support for filtering by scalar data types alongside vector similarity queries.
    • Renames ElasticsearchRetriever to BM25Retriever and ElasticsearchFilterOnlyRetriever to FilterRetriever; deprecated names remain functional until a future release.
    • Adds EvaluationSetClient for deepset Cloud to fetch evaluation sets.
    • Adds table linearization support in EmbeddingRetriever for table inputs.
    • Adds file content-based extension detection (extracts extension based on file content rather than filename).
    └──▷ BREAKING ON UPGRADE
    • !Return types of indexing pipeline nodes have changed.
    • !weaviate-client is upgraded to 3.3.3, which may affect existing Weaviate integrations.
    • !TransformersReader defaults are now aligned with FARMReader, changing previous default behavior.
    • !Default encoding for PDFToTextConverter changed from Latin 1 to UTF-8.
    • !YAML files are now validated without loading nodes, changing pipeline validation behavior.
  79. v1.3.0 Mar 23, 2022 · issue -404

    Haystack v1.3.0 adds PineconeDocumentStore, BEIR benchmarking integration, YAML pipeline validation, and new RouteDocuments/JoinAnswers nodes.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.3.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.3.0
    └──▷ USE IT
    Validate a pipeline YAML file before deployment to catch misconfigured components early in CI.
    python
    from pathlib import Path
    from haystack.pipelines.config import validate_yaml
    validate_yaml(Path('rest_api/pipeline/pipelines.haystack-pipeline.yml'))
    Connect to Pinecone's managed vector database as a DocumentStore for large-scale dense retrieval without self-hosting infrastructure.
    python
    import os
    from haystack.document_stores import PineconeDocumentStore
    document_store = PineconeDocumentStore(api_key=os.environ['PINECONE_API_KEY'])
    Benchmark a retrieval pipeline against the BEIR 'scifact' dataset for zero-shot evaluation of retrieval quality.
    python
    from haystack.pipelines import DocumentSearchPipeline, Pipeline
    from haystack.nodes import ElasticsearchRetriever
    from haystack.document_stores.elasticsearch import ElasticsearchDocumentStore
    
    document_store = ElasticsearchDocumentStore(search_fields=['content', 'name'], index='scifact_beir')
    retriever = ElasticsearchRetriever(document_store=document_store, top_k=1000)
    query_pipeline = DocumentSearchPipeline(retriever=retriever)
    
    ndcg, _map, recall, precision = Pipeline.eval_beir(
        index_pipeline=index_pipeline, query_pipeline=query_pipeline, dataset='scifact'
    )
    • Adds validate_yaml(Path(...)) from haystack.pipelines.config to programmatically validate pipeline YAML files, identifying erroneous components and parameters.
    • Adds PineconeDocumentStore to haystack.document_stores, backed by Pinecone's managed vector database for large-scale dense retrieval; requires only a PINECONE_API_KEY.
    • Adds Pipeline.eval_beir() for zero-shot benchmarking of retrieval pipelines against BEIR datasets in 17 languages; available via pip install farm-haystack[beir].
    • Adds RouteDocuments and JoinAnswers pipeline nodes to haystack.nodes.
    • Adds deploy and undeploy support for Pipelines on Deepset Cloud.
    +4 moreshow less
    • Adds *.haystack-pipeline.yml file suffix convention enabling IDE schema validation and autocompletion via SchemaStore; schema published at https://raw.githubusercontent.com/deepset-ai/haystack/master/haystack/json-schemas/haystack-pipeline.schema.json.
    • Supports version: 'unstable' in pipeline YAML files to bypass schema validation.
    • Reintroduces debug as a valid global key in Pipeline params.
    • Adds bulk insert support to SQL DocumentStores.
    └──▷ BREAKING ON UPGRADE
    • !Milvus2DocumentStore now requires pymilvus>=2.0.0; setups using older pymilvus versions will break.
    • !The device parameter in internal methods is now a torch.device; code passing plain strings for device in affected onnxruntime paths may break.
  80. v1.2.0 Feb 23, 2022 · issue -405

    Haystack v1.2.0 adds brownfield Elasticsearch import, scored Tapas QA, MongoDB-style metadata filters, and new pipeline/REST capabilities.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.2.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.2.0
    └──▷ USE IT
    Migrate an existing Elasticsearch index into a Haystack DocumentStore for immediate use in pipelines.
    python
    from haystack.document_stores import InMemoryDocumentStore
    from haystack.utils import es_index_to_document_store
    
    document_store = es_index_to_document_store(
        document_store=InMemoryDocumentStore(),
        original_index_name="existing_index",
        original_content_field="content",
        original_name_field="name",
        included_metadata_fields=["date_field"],
        index="new_index",
    )
    Use a scored Tapas model for table-based QA where answers are ranked by confidence.
    python
    from haystack.nodes import TableReader
    
    reader = TableReader(model_name_or_path="deepset/tapas-large-nq-reader", max_seq_len=512)
    • Adds es_index_to_document_store function to import existing Elasticsearch indices into any Haystack DocumentStore by converting records to Document objects, accepting parameters original_index_name, original_content_field, original_name_field, included_metadata_fields, and index.
    • Adds top_k_join parameter to JoinDocuments.run to control how many documents are returned by the join node.
    • Adds DELETE /feedback REST API endpoint for clearing feedback/labels during testing, with label IDs now generated server-side.
    • Adds pipeline.save_to_deepset_cloud() method to push pipelines to Deepset Cloud.
    • Adds pipeline.to_code() method to generate Python code from a pipeline definition.
    +15 moreshow less
    • Adds JSON Schema autogeneration for Pipeline YAML files, including a schema index for Schemastore.
    • Adds YAML versioning support for Pipeline configuration files.
    • Extends metadata filter syntax across document stores to support MongoDB-style nested boolean ($and, $or, $not) and comparison ($eq, $in, $gt, $gte, $lt, $lte) operators; defaults to $and / $eq when operators are omitted, keeping existing filter expressions valid.
    • Adds TapasForScoredQA model class enabling TableReader to load Tapas models that return confidence scores (e.g. deepset/tapas-large-nq-reader, deepset/tapas-large-nq-hn-reader); answers are auto-sorted by table score then answer span score.
    • Adds reciprocal rank fusion as an additional merging method in the join node.
    • Adds highlighting support in ElasticsearchDocumentStore.
    • Adds dot_product OpenSearch Script Scoring support in OpenSearchDocumentStore, including dot_product similarity via HNSW.
    • Introduces read-only DCDocumentStore (without labels support) for Deepset Cloud.
    • Adds pipeline.load_from_deepset_cloud() and pipeline listing via the Deepset Cloud SDK.
    • Autogenerates OpenAPI specs file (openapi.json) for the REST API, formatted as multiline for diff readability.
    • Introduces optional dependency groups for installation (e.g. farm-haystack, farm-haystack[colab,faiss], farm-haystack[all], farm-haystack[dev]) so only required packages are installed; pip 22+ recommended.
    • Adds extended metadata filtering support to WeaviateDocumentStore along with more supported data types.
    • Adds extended metadata filtering support to InMemoryDocumentStore and SQLDocumentStore.
    • Makes FileTypeClassifier more flexible for routing documents by file type in pipelines.
    • Distributes intermediate layer distillation loss calculation across multiple GPUs.
    └──▷ BREAKING ON UPGRADE
    • !Dependency management was restructured (farm-haystack now installs only a minimal subset by default); setups that relied on the previous all-inclusive install may be missing packages after upgrade.
    • !ui and rest are now proper packages; imports or references assuming their previous module structure will break.
    • !aiorwlock was added to the ray extra and maximum versions for some dependencies were pinned; environments using the ray extra may need to update their dependency pins.
  81. v1.1.0 Jan 20, 2022 · issue -406

    Haystack v1.1.0 adds model distillation, isolated pipeline eval, RCIReader for TableQA, ParsrConverter, and nDCG metrics.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.1.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.1.0
    └──▷ USE IT
    Compress a large reader into a smaller one to get near-equivalent accuracy at twice the speed.
    python
    # Step 1: augment training data
    python augment_squad.py --squad_path squad2.json --output_path augmented_squad2.json --multiplication_factor 20
    
    # Step 2: distil intermediate layers
    student.distil_intermediate_layers_from(teacher, data_dir="dataset", train_filename="augmented_squad2.json")
    
    # Step 3: distil prediction layer
    student.distil_prediction_layer_from(teacher, data_dir="dataset", train_filename="squad2.json")
    Identify whether the retriever or reader is the accuracy bottleneck in an ExtractiveQAPipeline.
    python
    eval_result = pipeline.eval(labels=eval_labels, add_isolated_node_eval=True)
    pipeline.print_eval_report(eval_result)
    Run TableQA on large tables with meaningful confidence scores using the new RCIReader.
    python
    from haystack.nodes import RCIReader
    
    reader = RCIReader(
        row_model_name_or_path="michaelrglass/albert-base-rci-wikisql-row",
        column_model_name_or_path="michaelrglass/albert-base-rci-wikisql-col"
    )
    • Adds student.distil_intermediate_layers_from(teacher, data_dir=..., train_filename=...) and student.distil_prediction_layer_from(teacher, data_dir=..., train_filename=...) methods to compress large reader models (teacher) into smaller models (student) via TinyBERT-style distillation, with a companion augment_squad.py --squad_path <your dataset> --output_path <output> --multiplication_factor 20 data-augmentation script.
    • Adds add_isolated_node_eval=True parameter to pipeline.eval() and pipeline.print_eval_report() to expose per-node upper-bound metrics alongside integrated metrics, enabling bottleneck identification in pipelines such as ExtractiveQAPipeline.
    • Adds nDCG to pipeline.eval()'s document metrics.
    • Adds RCIReader(row_model_name_or_path=..., column_model_name_or_path=...) for TableQA using Row-Column-Intersection models, supporting larger tables and returning meaningful confidence scores unlike TableReader.
    • Adds ParsrConverter (based on the open-source axa-group Parsr tool) for extracting text and tables from PDF and DOCX files in a format directly usable for TableQA.
    +4 moreshow less
    • Extends TranslationWrapper to work with QA Generation pipelines.
    • Enables batch mode for SAS cross encoders.
    • Adds support for custom headers per request in pipeline when talking to DocumentStores.
    • Raises an exception if Elasticsearch search_fields have a wrong datatype, surfacing misconfiguration early.
    └──▷ BREAKING ON UPGRADE
    • !Custom id hashing on DocumentStore level has changed; existing document IDs may differ after upgrade.
    • !Proper foreign keys are now implemented in MetaDocumentORM and MetaLabelORM, which may require a database migration when using PostgreSQL.
  82. v1.0.0 Dec 8, 2021 · issue -407

    Haystack 1.0 adds Table QA, pipeline-level evaluation, per-node debug propagation, and standardized primitive objects.

    └──▷ GET THIS VERSION
    $ git clone --branch v1.0.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v1.0.0
    └──▷ USE IT
    Run pipeline-level evaluation and print a summary report to identify whether your Retriever or Reader is the performance bottleneck.
    python
    eval_result = pipeline.eval(
        labels=labels,
        params={"Retriever": {"top_k": 5}},
    )
    metrics = eval_result.calculate_metrics()
    pipeline.print_eval_report(eval_result)
    Set up a Table QA pipeline to query structured table data using tri-encoder dense retrieval and TAPAS-based reading.
    python
    retriever = TableTextRetriever(
        document_store=document_store,
        query_embedding_model="deepset/bert-small-mm_retrieval-question_encoder",
        passage_embedding_model="deepset/bert-small-mm_retrieval-passage_encoder",
        table_embedding_model="deepset/bert-small-mm_retrieval-table_encoder",
        embed_meta_fields=["title", "section_title"]
    )
    reader = TableReader(
        model_name_or_path="google/tapas-base-finetuned-wtq",
        max_seq_len=512
    )
    • New TableTextRetriever class enables dense retrieval over mixed text and table corpora using three transformer encoders (query_embedding_model, passage_embedding_model, table_embedding_model).
    • New TableReader class built on TAPAS performs Question Answering over table Document objects, returning single-cell answers or aggregation results; accepts model_name_or_path and max_seq_len arguments.
    • New Pipeline.eval() method accepts Label or MultiLabel objects and returns an EvaluationResult containing per-node, per-sample predictions in a Pandas DataFrame.
    • New EvaluationResult.calculate_metrics() method computes retrieval and reader metrics from a stored EvaluationResult.
    • New Pipeline.print_eval_report() method prints a human-readable summary of an EvaluationResult.
    +4 moreshow less
    • Pipeline run() now accepts a top-level debug: True parameter that propagates each node's input and output into the pipeline result for inspection.
    • Introduces Document, Answer, Label, MultiLabel, and Span primitive classes as standardized inputs/outputs across all nodes, enabling IDE autocompletion and structured REST API responses.
    • New package layout exposes all Document Stores from haystack.document_stores, all node classes from haystack.nodes, all pipeline classes from haystack.pipelines, and utilities from haystack.utils.
    • FARM modeling code migrated into the new haystack/modeling package, removing the external FARM dependency.
    └──▷ BREAKING ON UPGRADE
    • !The Document field text is renamed to content; code writing or reading doc['text'] or Document(text=...) must switch to content.
    • !Reader nodes now return Answer objects instead of plain dicts; code unpacking keys like answer['score'] or answer['probability'] must be updated to the Answer object structure.
    • !Label constructor argument question is renamed to query, and answer now requires an Answer object instead of a plain string.
    • !The /query REST API response field names for offsets have changed to match the new Answer primitive format; clients parsing offset fields from v0.x responses must be updated.
    • !Import paths are reorganized: haystack.document_store (singular) becomes haystack.document_stores (plural), and haystack.pipeline (singular) becomes haystack.pipelines (plural); old-style imports still work but are deprecated.
  83. v0.10.0 Sep 16, 2021 · issue -410

    Haystack v0.10.0 adds RayPipeline for distributed scaling, SAS evaluation metric, and new FARMClassifier, SentenceTransformersRanker, and QuestionGenerator nodes.

    └──▷ GET THIS VERSION
    $ git clone --branch v0.10.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v0.10.0
    └──▷ USE IT
    Scale a retriever-reader pipeline across a Ray cluster by assigning independent replica counts to each node.
    python
    from haystack.pipeline import RayPipeline
    pipeline = RayPipeline.load_from_yaml(path="my_pipelines.yaml", pipeline_name="ray_query_pipeline")
    pipeline.run(query="What is the capital of Germany?")
    Use Semantic Answer Similarity scoring during evaluation to catch semantically correct answers missed by lexical metrics.
    python
    from haystack.nodes import EvalAnswers
    eval_reader = EvalAnswers(sas_model="sentence-transformers/paraphrase-multilingual-mpnet-base-v2")
    • Adds RayPipeline class (imported from haystack.pipeline) enabling distributed pipeline execution across a Ray cluster, with per-node replicas configured in YAML pipeline config.
    • Adds params dict argument to Pipeline.run() supporting node-targeted parameter routing such as params={"Retriever": {"top_k": 10}, "Reader": {"top_k": 5}}.
    • Adds sas_model parameter to EvalAnswers node enabling cross-encoder-based Semantic Answer Similarity (SAS) evaluation metric.
    • Adds ImageToTextConverter and PDFToTextOCRConverter classes providing OCR-based document conversion.
    • Adds language parameter to PreProcessor for optional language-specific preprocessing.
    +12 moreshow less
    • Adds MostSimilarDocumentsPipeline for similarity-based document retrieval pipelines.
    • Adds FARMClassifier node for document classification at indexing time or inline in inference pipelines.
    • Adds SentenceTransformersRanker node for re-ranking retrieved documents using sentence-transformer models.
    • Adds QuestionGenerator class for generating candidate questions from documents, supporting autosuggest and labeling acceleration use cases.
    • Adds Approximate Nearest Neighbour (ANN) search support to OpenSearchDocumentStore.
    • Adds filter integration with KNN queries in OpenDistroElasticsearchDocumentStore.
    • Adds multi-GPU inference support for DensePassageRetriever.
    • Adds id field support in write_labels() for SQLDocumentStore.
    • Adds Crawler support for use inside indexing pipelines.
    • Adds JSON serialization of Crawler output.
    • Supports connecting to Elasticsearch without authentication.
    • Adds docs2answer node enabling FAQ-style QA and document search via the API.
    └──▷ BREAKING ON UPGRADE
    • !The probability field is removed from answer and document results in both the Python API and REST API; only score (range [0,1]) remains, populated with the former probability value.
    • !The Finder class is removed entirely.
    • !Pipeline.run() no longer accepts keyword arguments like top_k_retriever or top_k_reader; all component params must be passed via a params dict (e.g. params={"Retriever": {"top_k": 10}, "Reader": {"top_k": 5}}).
    • !Custom pipeline nodes must no longer define **kwargs in their run() methods and should return only the data they produce themselves.
  84. v0.9.0 Jun 21, 2021 · issue -413

    Haystack v0.9.0 adds LFQA generative QA, a Ranker node, WeaviateDocumentStore, QueryClassifier, and ONNXRuntime support.

    └──▷ GET THIS VERSION
    $ git clone --branch v0.9.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v0.9.0
    └──▷ USE IT
    Use WeaviateDocumentStore to combine dense retrieval with scalar tag filtering.
    python
    from haystack.document_store import WeaviateDocumentStore
    
    document_store = WeaviateDocumentStore()
    document_store.write_documents(documents, duplicate_documents="overwrite")
    • Adds WeaviateDocumentStore class (from haystack.document_store) for combined vector search and scalar filtering, using Weaviate 1.4.0.
    • Adds FARMRanker node for document re-ranking via semantic similarity, composable with any retriever in a Pipeline.
    • Adds Seq2SeqGenerator and RetriBERT-based retriever for Long-Form Question Answering (LFQA), generating multi-document synthesized answers.
    • Adds QueryClassifier node to route keyword queries vs. natural-language questions to different pipeline branches.
    • Adds use_amp parameter to the DPR retriever train() method to enable mixed-precision training.
    +9 moreshow less
    • Adds ONNXRuntime inference support for the Reader node.
    • Adds options for handling duplicate documents on ingest: skip, fail, or overwrite.
    • Adds L2 distance support for FAISS HNSW index.
    • Adds OpenDistro document store initialisation support.
    • Adds AWS Elasticsearch IAM connection support.
    • Adds Pipeline YAML config export capability.
    • Adds evaluation nodes for Pipelines.
    • Adds file upload functionality and evaluation mode to the Streamlit UI.
    • Adds a web crawler connector to ingest text directly from websites.
    └──▷ BREAKING ON UPGRADE
    • !Python 3.6 is no longer supported; Python 3.7+ is required.
    • !REST APIs have been refactored to use Pipelines, which may require changes to existing API integrations.
    • !FARM bumped to 0.8.0, PyTorch to 1.8.1, and Transformers to 4.6.1 — existing environments must be updated.
    • !All document stores' delete_all_documents() method has been renamed to delete_documents().
  85. v0.8.0 Apr 13, 2021 · issue -415

    Haystack v0.8.0 adds MilvusDocumentStore, Knowledge Graph QA, YAML Pipeline config, confidence scores, and a Selenium web crawler.

    └──▷ GET THIS VERSION
    $ git clone --branch v0.8.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v0.8.0
    └──▷ TRY IT
    Query the new generic REST API endpoint to get answers with calibrated confidence scores from any Pipeline-backed deployment.
    $ curl -X POST http://localhost:8000/query \
      -H 'Content-Type: application/json' \
      -d '{"query": "Why did the revenue change?"}'
    • Adds MilvusDocumentStore class enabling embedding-based retrievers (DensePassageRetriever, EmbeddingRetriever) to use production-ready Milvus vector database servers for large-scale deployments.
    • Adds GraphDBKnowlegeGraph class for storing RDF Triples and executing SPARQL queries, integrable with the new Text2SparqlRetriever to convert natural language queries to SPARQL.
    • Introduces YAML-based Pipeline configuration via rest_api/pipeline.yaml, enabling shareable query and indexing configs, reproducible setups, and A/B testing of Pipelines.
    • Adds new generic POST /query endpoint to the REST API backed by Pipelines, replacing the former /doc-qa and /faq-qa endpoints; accepts a single query string and returns answers with a probability confidence score (range 0–1).
    • Adds new generic POST /feedback endpoint, replacing the former /doc-qa-feedback and /faq-qa-feedback endpoints.
    +15 moreshow less
    • Adds API endpoint to export accuracy metrics derived from user feedback.
    • Adds a probability field (0–1) to answers, providing a calibrated model-confidence score alongside the existing score field.
    • Adds a Selenium-based web crawler class that accepts a list of URLs and converts extracted text into Haystack Documents.
    • Adds MarkdownConverter file converter for ingesting Markdown files into Haystack document stores.
    • Adds evaluation nodes for Pipelines to measure retriever and reader performance end-to-end.
    • Adds support for parallel paths in Pipelines, enabling branching and merging of pipeline components.
    • Adds support for indexing Pipelines alongside existing query Pipelines.
    • Introduces incremental embedding updates in document stores, avoiding full re-indexing when only some documents change.
    • Adds a window-query flag to SQLDocumentStore for controlling passage retrieval behavior.
    • Allows non-standard tokenizers (e.g., CamemBERT) for DensePassageRetriever via a new argument.
    • Adds model versioning support to Haystack modeling components.
    • Adds a SQuAD-to-DPR dataset converter for training data preparation.
    • Adds a method to retrieve metadata values for a given key from ElasticsearchDocumentStore.
    • Upgrades FAISS to version 1.7.0.
    • Adds a created_at timestamp field for documents and labels across all document stores (SQLDocumentStore, FAISSDocumentStore, ElasticsearchDocumentStore).
    └──▷ BREAKING ON UPGRADE
    • !The /doc-qa and /faq-qa REST API endpoints are removed and replaced by a generic POST /query endpoint configured via rest_api/pipeline.yaml.
    • !The POST /query endpoint now expects a single query string per request instead of a list of query strings.
    • !The /doc-qa-feedback and /faq-qa-feedback REST API endpoints are removed and replaced by a generic POST /feedback endpoint.
    • !The created timestamp field on documents and labels in SQLDocumentStore and FAISSDocumentStore is replaced by created_at; ElasticsearchDocumentStore also now has created_at.
    • !The top_k_answers parameter in RAGenerator is renamed to top_k.
    • !Placeholder terms in the custom_query parameter for ElasticsearchDocumentStore must no longer have quotes around them.
  86. v0.7.0 Jan 21, 2021 · issue -418

    Haystack v0.7.0 adds summarization pipelines, a demo UI, batch/generator document streaming, and filter support for DensePassageRetriever.

    └──▷ GET THIS VERSION
    $ git clone --branch v0.7.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v0.7.0
    └──▷ USE IT
    Run a retrieve-then-summarize pipeline to display document summaries as search result previews.
    python
    from haystack.pipeline import SearchSummarizationPipeline
    from haystack.summarizer import TransformersSummarizer
    
    summarizer = TransformersSummarizer(model_name_or_path="google/pegasus-xsum")
    pipe = SearchSummarizationPipeline(summarizer=summarizer, retriever=retriever)
    results = pipe.run(query="What caused the California wildfires?")
    Update embeddings on a million-document corpus without exhausting RAM by processing in chunks.
    python
    document_store.update_embeddings(retriever=retriever, batch_size=10000)
    • Adds batch_size parameters to most DocumentStore methods (write_documents(), update_embeddings(), get_all_documents()) to load documents in chunks and reduce memory footprint on large datasets.
    • Adds get_all_documents_generator() method to stream documents one-by-one from a document store, enabling low-memory iteration over datasets exceeding 1 million documents.
    • Adds TransformersSummarizer class supporting models like PEGASUS, usable standalone via summarizer.predict(documents=docs, generate_single_summary=False) or as a pipeline node.
    • Adds SearchSummarizationPipeline predefined pipeline that chains retrieval and summarization in a single pipe.run() call.
    • Adds a simple demo UI for interactively testing search pipelines, inspecting API responses, and adjusting basic config params.
    +2 moreshow less
    • Adds filter support for DensePassageRetriever combined with InMemoryDocumentStore.
    • Adds support for a custom embedding field in InMemoryDocumentStore.
    └──▷ BREAKING ON UPGRADE
    • !The index_buffer_size argument is removed from FAISSDocumentStore.__init__(); replace it with the new batch_size argument on methods like write_documents(), update_embeddings(), and get_all_documents().
    • !The PreProcessor argument split_stride is renamed to split_overlap; any code passing split_stride=N must be updated to split_overlap=N.
  87. v0.6.0 Dec 17, 2020 · issue -419

    Haystack v0.6.0 introduces DAG-based Pipelines, an OpenDistro DocumentStore, and new QA pipeline types including Generative and FAQ.

    └──▷ GET THIS VERSION
    $ git clone --branch v0.6.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v0.6.0
    └──▷ USE IT
    Route incoming queries to different retrievers based on content type, then join and read — enabling conditional branching in a single pipeline.
    python
    from haystack.pipeline import Pipeline, JoinDocuments
    
    class QueryClassifier:
        outgoing_edges = 2
        def run(self, **kwargs):
            if '?' in kwargs['query']:
                return (kwargs, 'output_1')
            else:
                return (kwargs, 'output_2')
    
    pipe = Pipeline()
    pipe.add_node(component=QueryClassifier(), name='QueryClassifier', inputs=['Query'])
    pipe.add_node(component=es_retriever, name='ESRetriever', inputs=['QueryClassifier.output_1'])
    pipe.add_node(component=dpr_retriever, name='DPRRetriever', inputs=['QueryClassifier.output_2'])
    pipe.add_node(component=JoinDocuments(join_mode='concatenate'), name='JoinResults', inputs=['ESRetriever', 'DPRRetriever'])
    pipe.add_node(component=reader, name='QAReader', inputs=['JoinResults'])
    res = pipe.run(query='What did Einstein work on?', top_k_retriever=1)
    Run a generative QA pipeline with minimal setup using the new default pipeline classes.
    python
    from haystack.pipeline import GenerativeQAPipeline
    
    pipe = GenerativeQAPipeline(generator=rag_generator, retriever=retriever)
    res = pipe.run(query='What causes aurora borealis?', top_k_retriever=3)
    • Adds Pipeline class with add_node(), run(), draw(), and set_node() methods for composing search pipelines as Directed Acyclic Graphs (DAGs) with Retrievers, Readers, Generators, and custom nodes.
    • Adds JoinDocuments(join_mode=...) node with score aggregation support to merge results from multiple Retrievers in a single Pipeline.
    • Adds ExtractiveQAPipeline, DocumentSearchPipeline, GenerativeQAPipeline, and FAQPipeline default pipeline classes in haystack.pipeline, replacing the deprecated Finder class.
    • Adds OpenDistroElasticsearchDocumentStore to support Open Distro / AWS-hosted Elasticsearch deployments.
    • Adds refresh_type parameter to ElasticsearchDocumentStore.update_embeddings().
    +7 moreshow less
    • Adds return_embedding parameter to get_all_documents().
    • Adds update_existing_documents support to the SQL and FAISS DocumentStores.
    • Adds filters parameter to delete_all_documents().
    • Adds MAP (Mean Average Precision) retriever metric for open-domain evaluation.
    • Enables dynamic parameter updates for FARMReader at inference time.
    • Adds GPU support for the RAG generator.
    • Scales dot-product scores into probabilities in DocumentStore.
    └──▷ BREAKING ON UPGRADE
    • !All question parameters are renamed to query across Readers, Retrievers, and other components (including the predict() methods of Readers); any code passing question= keyword arguments will break.
  88. v0.5.0 Nov 6, 2020 · issue -420

    Haystack v0.5.0 adds RAG-based generative QA, DPR training, MySQL support, and an Elasticsearch Query DSL-compliant REST API.

    └──▷ GET THIS VERSION
    $ git clone --branch v0.5.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v0.5.0
    └──▷ USE IT
    Generate an answer from retrieved documents using RAG instead of extracting a span — useful when no single passage contains a clean answer.
    python
    retrieved_docs = retriever.retrieve(query="who got the first nobel prize in physics?")
    predicted_result = generator.predict(
        question="who got the first nobel prize in physics?",
        documents=retrieved_docs,
        top_k=1
    )
    Fine-tune a DPR retriever on domain-specific query/passage pairs to improve retrieval accuracy before production deployment.
    python
    dense_passage_retriever.train(
        data_dir="/data/dpr",
        train_filename="train.json",
        dev_filename="dev.json",
        batch_size=16,
        embed_title=True,
        num_hard_negatives=1,
        n_epochs=3
    )
    • Adds generator.predict(question=..., documents=..., top_k=...) for Retrieval Augmented Generation (RAG), enabling generative QA where answers are generated from retrieved documents rather than extracted.
    • Adds dense_passage_retriever.train(data_dir, train_filename, dev_filename, test_filename, batch_size, embed_title, num_hard_negatives, n_epochs) to train or fine-tune DPR models on custom domain data.
    • Adds save and load methods to DensePassageRetriever for persisting and reloading trained DPR models.
    • Adds use_fast_tokenizers and similarity_function parameters to DensePassageRetriever, and splits max_seq_len into independent max_seq_len_query and max_seq_len_passage parameters.
    • Adds faiss_index_factory_str and return_embedding parameters to FAISSDocumentStore, with new default index type 'Flat'.
    +11 moreshow less
    • Adds support for MySQL databases in DocumentStore.
    • Allows configuration of the Elasticsearch Analyzer in ElasticsearchDocumentStore (e.g. for non-English languages).
    • Adds filter support to get_document_count() in DocumentStore.
    • Adds Elasticsearch Query DSL-compliant Query API to the REST API.
    • Adds create_index and similarity metric configuration to the REST API config.
    • Allows configuration of log level in the REST API.
    • Makes filter values optional in the REST API.
    • Adds automatic mixed precision (AMP) support for FARMReader training.
    • Adds a preprocessing pipeline via PreProcessor.
    • Enables returning predictions in Finder and Retriever eval() calls.
    • Makes creation of the label index optional in DocumentStore.
    └──▷ BREAKING ON UPGRADE
    • !TransformersReader parameter model is replaced by model_name_or_path.
    • !FAISSDocumentStore parameter vector_size is renamed to vector_dim; faiss_index type changes from Optional[IndexHNSWFlat] to Optional[faiss.swigfaiss.Index]; default index type changes from HNSW to 'Flat'.
    • !DensePassageRetriever parameter max_seq_len is split into max_seq_len_query (default 64) and max_seq_len_passage (default 256); remove_sep_tok_from_untitled_passages parameter is removed.
  89. v0.4.0 Sep 21, 2020 · issue -422

    Haystack v0.4.0 adds FAISSDocumentStore for scalable dense retrieval, Apache Tika file conversion, and DPR support for InMemoryDocumentStore.

    └──▷ GET THIS VERSION
    $ git clone --branch v0.4.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout v0.4.0
    └──▷ USE IT
    Set up a FAISS-backed document store for dense retrieval over large corpora where Elasticsearch vector search would be too slow.
    python
    document_store = FAISSDocumentStore(sql_url="sqlite:///mydb.db", vector_size=768)
    Extract text from a non-PDF file format (e.g., .docx or .epub) to feed into a Haystack indexing pipeline.
    python
    tika_converter = TikaConverter(
        tika_url="http://localhost:9998/tika",
        remove_numeric_tables=False,
        remove_whitespace=False,
        remove_empty_lines=False,
        remove_header_footer=False,
        valid_languages=None,
    )
    result = tika_converter.convert(file_path="documents/report.docx")
    print(result["text"])
    Control multiprocessing during reader fine-tuning to maximise CPU utilisation on a multi-core machine.
    python
    reader.train(
        data_dir="data/squad",
        train_filename="train-v2.0.json",
        num_processes=8,
    )
    • Adds FAISSDocumentStore(sql_url, vector_size) for scalable approximate nearest-neighbour dense retrieval, using FAISS for embeddings and SQL for text/metadata storage.
    • Adds TikaConverter(tika_url, remove_numeric_tables, remove_whitespace, remove_empty_lines, remove_header_footer, valid_languages) with a .convert(file_path) method to extract text from docx, pptx, html, epub, odf, and other formats via Apache Tika.
    • Adds refresh_type argument to ElasticsearchDocumentStore.
    • Adds index argument to Finder.get_answers() and Finder._via_similar_questions().
    • Adds num_processes parameter to reader.train() to configure multiprocessing during training.
    +7 moreshow less
    • Adds unanswerable-question support and 'no answer' aggregation to TransformersReader.
    • Adds MultiLabel aggregation for no-answer labels across multiple passages.
    • Adds DPR (DensePassageRetriever) support for InMemoryDocumentStore.
    • Adds eval capability for DensePassageRetriever including refactored label/feedback handling.
    • Adds export-answers-to-CSV function.
    • Adds option to update existing documents when indexing in document stores.
    • Adds method to update meta fields for documents in ElasticsearchDocumentStore.
    └──▷ BREAKING ON UPGRADE
    • !The database module is renamed to document_store; imports must be updated accordingly.
    • !The indexing module is split into file_converter and preprocessor; imports must be updated.
    • !Document, Label, and Multilabel classes are moved to schema; update imports to from haystack import Document, Label, Multilabel.
    • !File converter interface changed: Fileconverter.extract_pages(file_path=Path('...')) (which returned pages and meta) is replaced by Fileconverter.convert(file_path='...', meta={...}), which returns a dict with text (using \f page-break symbols) and meta.
    • !DensePassageRetriever signature changed: now accepts query_embedding_model and passage_embedding_model (HuggingFace model hub strings) instead of the previous Facebook-codebase arguments.
    • !The tags field on Documents is removed; filtering must now use the meta field (e.g., {'text': 'some', 'meta': {'category': ['1', '2']}} instead of {'text': 'some', 'tags': ['category1', 'category2']}).
  90. 0.3.0 Jul 16, 2020 · issue -424

    Haystack 0.3.0 adds Dense Passage Retrieval, pipeline evaluation, PDF/DOCX indexing, ONNXRuntime support, and a file-upload REST endpoint.

    └──▷ GET THIS VERSION
    $ git clone --branch 0.3.0 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout 0.3.0
    └──▷ USE IT
    Use Dense Passage Retrieval to find semantically similar passages even when query and document share no overlapping tokens.
    python
    from haystack.retriever.dense import DensePassageRetriever
    
    retriever = DensePassageRetriever(
        document_store=document_store,
        embedding_model="dpr-bert-base-nq",
        do_lower_case=True,
        use_gpu=True
    )
    results = retriever.retrieve(query="What is cosine similarity?")
    Benchmark your full retriever-reader pipeline to identify whether the retriever is a bottleneck and how top_k affects accuracy.
    python
    document_store.add_eval_data("../data/nq/nq_dev_subset_v2.json")
    
    retriever.eval(top_k=10)
    reader.eval(document_store=document_store, device=device)
    finder.eval(top_k_retriever=10, top_k_reader=10)
    Index a PDF document into Haystack while stripping headers, footers, and numeric tables to improve retrieval quality.
    python
    from haystack.indexing.file_converters.pdf import PDFToTextConverter
    
    converter = PDFToTextConverter(
        remove_header_footer=True,
        remove_numeric_tables=True,
        valid_languages=["de", "en"]
    )
    pages = converter.extract_pages(file_path="report.pdf")
    • Adds DensePassageRetriever class with embedding_model, do_lower_case, and use_gpu arguments, enabling dual-encoder BERT-based retrieval that outperforms token-overlap methods when query and passage vocabulary differ.
    • Adds eval() methods to retriever, reader, and finder (via finder.eval(top_k_retriever=..., top_k_reader=...)) for end-to-end pipeline evaluation of recall, precision, and speed.
    • Adds document_store.add_eval_data() to load evaluation datasets (e.g. NQ-format JSON) directly into a DocumentStore for retriever and reader benchmarking.
    • Adds PDFToTextConverter (from haystack.indexing.file_converters.pdf) with remove_header_footer, remove_numeric_tables, and valid_languages arguments, plus DocxToTextConverter (from haystack.indexing.file_converters.docx), both exposing extract_pages(file_path=...) for ingesting PDF and DOCX documents.
    • Adds BaseConverter class with shared cleaning functions (header/footer removal, numeric table stripping) as a foundation for file-format-specific converters.
    +8 moreshow less
    • Adds ONNXRuntime support to the Reader, enabling CPU-optimised inference without GPU.
    • Adds a REST API endpoint to upload files for indexing.
    • Adds EMBEDDING_MODEL_FORMAT configuration key to the REST API config.
    • Adds a dummy retriever for benchmarking reader-only pipeline configurations.
    • Adds tag-based filtering to InMemoryDocumentStore.
    • Adds embedding query support to InMemoryDocumentStore.
    • Adds custom port configuration to ElasticsearchDocumentStore.
    • Makes the FAQ question field in DocumentStores customizable.
    └──▷ BREAKING ON UPGRADE
    • !The gpu initialisation argument on DensePassageRetriever and EmbeddingRetriever is renamed to use_gpu; existing code passing gpu=True will break.
  91. 0.2.1 May 5, 2020 · issue -426

    Haystack 0.2.1 debuts ElasticsearchDocumentStore, embedding-based retrieval, FAQ-style QA, and a FastAPI-based modular REST API.

    └──▷ GET THIS VERSION
    $ git clone --branch 0.2.1 https://github.com/deepset-ai/haystack.git
    # already have the repo? check out this version:
    $ git checkout 0.2.1
    • Adds ElasticsearchRetriever supporting Elasticsearch native BM25 scoring and custom queries (e.g. boosting and filters).
    • Adds EmbeddingRetriever that encodes texts into dense vectors (e.g. via Sentence-BERT) and retrieves via cosine similarity.
    • Adds FARMReader.train() method to fine-tune a reader on custom domain data.
    • Adds no_answer option to reader results, surfacing confidence that no answer exists in the passage.
    • Adds document_id and document_name fields to answer objects returned by both FARMReader and TransformersReader.
    +8 moreshow less
    • Adds TransformersReader as an alternative inference backend alongside the existing FARM-based reader.
    • Introduces ElasticsearchDocumentStore as the recommended production document store, with BM25 indexing and optional filter support.
    • Adds an in-memory document store for lightweight prototyping without an external database.
    • Adds FAQ-style QA: index existing question-answer pairs and match incoming user questions against them to return pre-written answers.
    • Migrates the REST API from Flask to FastAPI with modular endpoints for extractive QA, FAQ-style QA, user feedback collection/export, and APM-based request monitoring.
    • Adds a Feedback export API endpoint for collecting and exporting user feedback on answers to build domain-specific training data.
    • Adds Docker images (CPU and GPU variants) using Gunicorn for production deployment of the REST API.
    • Adds optional Elastic APM integration for logging and monitoring API responses.
my-toolchain — 0 tools
paste an install list to detect your tools

A brew list, a Brewfile, requirements.txt, a Dockerfile — or just the product names, free-form. Nothing leaves your browser.

    browse all tools →