Agent

Add reasoning and external tools to your pipelines through the Agent component.

📘

Beta Component

Agent is part of the Haystack experimental package, which means it may change in future releases. It’s intended for testing and exploration only—do not use it in production. Updates to the Agent component may break any pipelines that rely on it.

Currently, you can't view the Agent's prompt in Playground or Prompt Explorer.

Basic Information

  • Pipeline type: Query
  • Type: haystack_experimental.components.agents.agent.Agent
  • Components it can connect with:
    • To pass a query to an Agent, use OutputAdapter or DeepsetChatHistoryParser.
    • To make the Agent's response the final output of your pipeline, use an OutputAdapter to convert the Agent's messages into a list of strings and send them on to DeepsetAnswerBuilder.
    • The connections depend on the output and input types configured in the tools' state_schema.

Inputs

Required Inputs

NameTypeDescription
messagesList of ChatMessage objectsThe list of ChatMessages to process.
Required.
kwargsDictionaryAdditional inputs defined in the Agent's state_schema.
Required.

Optional Inputs

NameTypeDefaultDescription
streaming_callbackSyncStreamingCallbackNoneA callback function for streaming responses.

Outputs

TypeDescription
DictionaryDictionary containing messages and outputs matching the defined output types. If you want the Agent to product additional structured outputs (for example, retrieved documents), you define them in state_schema.

Overview

Agent is designed to help AI systems use tools to accomplish tasks. You can think of it like a coordinator that manages conversations and knows when and how to use different tools.

Key features:

  • Works with different chat models.
  • Can use external tools such as search engines and calculators.
  • Lets you define custom exit conditions (for example, stop after generating text or using a specific tool).
  • Maintains conversation history.
  • Allows real-time streaming responses.

Configuration

To configure an Agent, you need to provide:

  • A chat model: Supplied through an underlying ChatGenerator, which processes and generates text. The Agent is provider-agnostic, so it can work with any model.
  • A list of tools These can be custom tools for a specific use case, pipeline components, or pipelines.
  • An exit condition: Defined using exit_condition. The Agent runs iteratively—calling tools and feeding their outputs back to the model—until this condition is met. For example, you can configure it to stop after a tool is used or once the model returns a text response.

You configure the Agent in YAML.

How It Works

  1. The Agent receives a message from the user.
  2. It sends the message to its chat model (ChatGenerator), along with the list of tools.
  3. The model responds with either plain text or a tool call.
    1. If the response is just text, the Agent returns the current conversation and response, and exits (if exit_condition is set to text).
    2. If the response includes a tool call:
      1. The Agent calls the tool using ToolInvoker.
      2. ToolInvoker runs the tool and returns the result.
      3. The Agent adds the result to the conversation history.
  4. Then:
    1. If the tool name matches the exit_condition, the Agent exits and returns the conversation.
    2. If it doesn't match, teh Agent continues. It sends the updated conversation back to the model. This loop continues until the exit_condition is met or max_runs_per_component is reached.

Usage Example

Agent Configuration

In this example, the Agent:

  • Uses AnthropicChatGenerator. Note that you pass the generator's init parameters and type in the configuration.
  • Stops when the LLM generates text without tool calls (exit_condition: text).
  • Has streaming enabled using:streaming_callback: deepset_cloud_custom_nodes.callbacks.streaming.streaming_callback. Note that you enable the streaming for the Agent, not the ChatGenerator it uses.
  • Includes a system prompt with instructions on how to answer queries and use tools.
  • Defines a state_schemawith a list of Document objects. Tools can read from and write to these documents. For instance, if a web_search tool retrieves documents, they are saved under documents in the Agent’s state. These documents are then available as the Agent’s output and can be sent to the AnswerBuilder.
  • Uses the SerperDevWebSearch component as a tool. To use a pipeline component as a tool, set its type to haystack.tools.component_tool.ComponentTool. Then, wrap the tool init parameters in the data object. You configure the tools for the Agent the same way as you do for ToolInvoker. For details and examples of how to configure tools, see ToolInvoker documentation.
  • The Agent is connected to other components in the pipeline with its messages input and documents output (defined in state_schema).
components:
  agent:
    type: haystack_experimental.components.agents.agent.Agent
    init_parameters:
      chat_generator:
        init_parameters: # here you configure the ChatGenerator
          api_key:
            env_vars:
            - ANTHROPIC_API_KEY
            strict: false
            type: env_var
          generation_kwargs:
            max_tokens: 8000
          ignore_tools_thinking_messages: true
          model: claude-3-7-sonnet-latest
        type: haystack_integrations.components.generators.anthropic.chat.chat_generator.AnthropicChatGenerator
      exit_condition: text # this tells the Agent to stop once it receives text from the LLM, without tool calls
      max_runs_per_component: 100
      raise_on_tool_invocation_failure: false
      streaming_callback: deepset_cloud_custom_nodes.callbacks.streaming.streaming_callback # enables streaming for the Agent
      system_prompt: |-
        You are a deep research assistant.
        You create comprehensive research reports to answer the user's questions.
        You use the 'search'-tool to answer any questions.
        You perform multiple searches until you have the information you need to answer the question.
        Make sure you research different aspects of the question.
        Use markdown to format your response.
        When you use information from the websearch results, cite your sources using markdown links.
        It is important that you cite accurately.
      state_schema: # define the data the components will have access to
        documents: # here, we're giving the web_search component access to the documents
          type: typing.List[haystack.dataclasses.Document]
      tools:
      - type: haystack_experimental.tools.component_tool.ComponentTool # this is the type you use to configure pipeline components as tools
        data: # wrap the component configuration in the data object
          component: # specify the tool type, for pipeline components, it's `component`
            type: haystack.components.websearch.serper_dev.SerperDevWebSearch # this is the component import path or type
            init_parameters: # pass the component configuration here
              api_key:
                type: env_var
                env_vars:
                - SERPERDEV_API_KEY
                strict: false
              top_k: 10
          name: web_search # give the tool a name, you can use this name as the exit condition
          description: Search the web for current information on any topic # describe what the tool does, this can help the model to decide when and if to use the tool

  answer_builder:
    init_parameters:
      pattern:
      reference_pattern:
    type: haystack.components.builders.answer_builder.AnswerBuilder
    
  history_parser:
    init_parameters: {}
    type: dc_custom_component.components.parsers.chat_history_parser.DeepsetChatHistoryParser
    
  adapter:
    init_parameters:
      custom_filters: {}
      output_type: typing.List[str]
      template: '{{ [(messages|last).text] }}'
      unsafe: false
    type: haystack.components.converters.output_adapter.OutputAdapter

connections:
- receiver: agent.messages # agent's input is always `messages`
  sender: history_parser.messages
- receiver: adapter.messages
  sender: agent.messages
- receiver: answer_builder.replies
  sender: adapter.output
- sender: agent.documents # this is because the Agent has `documents` defined in its state_schema
  receiver: answer_builder.documents

inputs:
  query:
  - answer_builder.query
  - history_parser.history_and_query

outputs:
  answers: answer_builder.answers

  documents: agent.documents

pipeline_output_type: chat

max_runs_per_component: 100

metadata: {}

Passing a Query to the Agent

The Agent expects a list of messages as input. However, the Query component outputs plain text. To bridge this gap, you can use the DeepsetChatHistoryParser component.

DeepsetChatHistoryParser takes the text from Query and converts it into a list of ChatMessage objects. Simply connect Query to DeepsetChatHistoryParser, and then connect its output to the Agent.

Agent receiving the query through deepsetchathistoryparser

Displaying the Agent Results

The Agent returns a list of ChatMessages, but in most cases, you only need the last message as the final output of your pipeline. To extract just the last message, use the OutputAdapter component. Configure it to:

  • Take the Agent's output (a list of ChatMessages)
  • Convert only the last message into a list of strings

This format is compatible with downstream components like the AnswerBuilder. Simply connect the Agent to the OutputAdapter, and then connect the adapter's output to the AnswerBuilder.

Agent sending its output messages to an OutputAdapter which converts them into a list of strings and sends to AnswerBuilder

This is how to configure OutputAdapter for this scenario:

  adapter:
    init_parameters:
      output_type: typing.List[str] # this is the output type an AnswerBuilder accepts
      template: '{{ [(messages|last).text] }}' # here you're pointing to the last message the Agent returned
    type: haystack.components.converters.output_adapter.OutputAdapter

Adding Sources to Agent Results

To show the sources or documents the Agent used to generate it answer, configure the Agent to output those documents. You do this by adding documents to the Agent's state_schema:

      state_schema: 
        documents: # this becomes the name of the output connection
          type: typing.List[haystack.dataclasses.Document] # here you define what's sent there
The state schema configuration window in builder

The Agent then outputs the documents through its output connection called documents. You can connect an AnswerBuilder to the Agent's documents to add documents to the final answer:

connections:
- receiver: agent.messages
  sender: history_parser.messages
- receiver: adapter.messages
  sender: agent.messages
- receiver: answer_builder.replies
  sender: adapter.output
- sender: agent.documents # we're sending the documents to DeepsetAnswerBuilder
  receiver: answer_builder.documents

inputs:
  query:
  - answer_builder.query
  - history_parser.history_and_query

outputs:
  answers: answer_builder.answers 

  documents: agent.documents # the final output also includes the Agent's documents

Parameters

Init Parameters

These are the parameters you can configure in Pipeline Builder:

ParameterTypePossible ValuesDescription
chat_generatorOpenAIChatGenerator,
AnthropicChatGenerator (check usage examples for details)
The chat generator that the agent will use. Currently, OpenAIChatGenerator and AnthropicChatGenerator are supported. You configure the generator by passing its init parameters and type to the Agent. Check the Usage Example section for details.
Required.
toolsList of Tool objectsDefault: NoneThe external tools that the agent can invoke.
Optional
system_promptString System-level prompt to guide the agent's behavior.
Optional.
exit_conditionStringDefault:"text" Defines when the agent stops processing messages. Pass text to stop the Agent when it generates a message without tool calls.
Pass the name of a tool to stop the Agent after it runs this tool.
Required.
state_schemaDictionaryDefault: NoneOptional schema for managing the runtime state used by tools. It defines extra information—such as documents or context—that tools can read from or write to during execution. You can use this schema to pass parameters that tools can both produce and consume during a call. This means that when a pipeline runs, tools can read from the Agent's state (for example, the current set of retrieved documents) and write into or update this state as they run.
Optional
max_runs_per_componentIntegerDefault: 100Maximum number of execution cycles per component. The Agent raises an exception if a component exceeds the maximum number of runs.
Required.
raise_on_tool_invocation_failureBooleanTrue or False
Default: False
Whether to raise an error when a tool call fails. If set to False, the exception is turned into a chat message and passed to the LLM.
Required.
streaming_callbackdeepset_cloud_custom_nodes.callbacks.streaming.streaming_callback
Default: None
Function invoked for streaming responses. To enable streaming, set streaming_callback to deepset_cloud_custom_nodes.callbacks.streaming.streaming_callback.
To learn more about streaming, see Enable Streaming.
Optional.

Run Method Parameters

These are the parameters you can configure for the component's run() method. This means you can pass these parameters at query time through the API, in Playground, or when running a job. For details, see Modify Pipeline Parameters at Query Time.


ParameterTypePossible ValuesDescription
messagesList of ChatMessage objectsThe conversation history to process.
Required.
streaming_callbackSyncStreamingCallbackDefault: NoneFunction to handle streamed responses.
Optional.
kwargsDictionaryAdditional parameters to pass to the Agent's state_schema. The keys must match the schema defined in the Agent's state_schema.
Required.