agents_api.md
  1  ---
  2  title: "Agents"
  3  id: agents-api
  4  description: "Tool-using agents with provider-agnostic chat model support."
  5  slug: "/agents-api"
  6  ---
  7  
  8  <a id="agent"></a>
  9  
 10  ## Module agent
 11  
 12  <a id="agent.Agent"></a>
 13  
 14  ### Agent
 15  
 16  A Haystack component that implements a tool-using agent with provider-agnostic chat model support.
 17  
 18  The component processes messages and executes tools until an exit condition is met.
 19  The exit condition can be triggered either by a direct text response or by invoking a specific designated tool.
 20  Multiple exit conditions can be specified.
 21  
 22  When you call an Agent without tools, it acts as a ChatGenerator, produces one response, then exits.
 23  
 24  ### Usage example
 25  ```python
 26  from haystack.components.agents import Agent
 27  from haystack.components.generators.chat import OpenAIChatGenerator
 28  from haystack.dataclasses import ChatMessage
 29  from haystack.tools import Tool
 30  
 31  # Tool functions - in practice, these would have real implementations
 32  def search(query: str) -> str:
 33      '''Search for information on the web.'''
 34      # Placeholder: would call actual search API
 35      return "In France, a 15% service charge is typically included, but leaving 5-10% extra is appreciated."
 36  
 37  def calculator(operation: str, a: float, b: float) -> float:
 38      '''Perform mathematical calculations.'''
 39      if operation == "multiply":
 40          return a * b
 41      elif operation == "percentage":
 42          return (a / 100) * b
 43      return 0
 44  
 45  # Define tools with JSON Schema
 46  tools = [
 47      Tool(
 48          name="search",
 49          description="Searches for information on the web",
 50          parameters={
 51              "type": "object",
 52              "properties": {
 53                  "query": {"type": "string", "description": "The search query"}
 54              },
 55              "required": ["query"]
 56          },
 57          function=search
 58      ),
 59      Tool(
 60          name="calculator",
 61          description="Performs mathematical calculations",
 62          parameters={
 63              "type": "object",
 64              "properties": {
 65                  "operation": {"type": "string", "description": "Operation: multiply, percentage"},
 66                  "a": {"type": "number", "description": "First number"},
 67                  "b": {"type": "number", "description": "Second number"}
 68              },
 69              "required": ["operation", "a", "b"]
 70          },
 71          function=calculator
 72      )
 73  ]
 74  
 75  # Create and run the agent
 76  agent = Agent(
 77      chat_generator=OpenAIChatGenerator(),
 78      tools=tools
 79  )
 80  
 81  result = agent.run(
 82      messages=[ChatMessage.from_user("Calculate the appropriate tip for an €85 meal in France")]
 83  )
 84  
 85  # The agent will:
 86  # 1. Search for tipping customs in France
 87  # 2. Use calculator to compute tip based on findings
 88  # 3. Return the final answer with context
 89  print(result["messages"][-1].text)
 90  ```
 91  
 92  <a id="agent.Agent.__init__"></a>
 93  
 94  #### Agent.\_\_init\_\_
 95  
 96  ```python
 97  def __init__(*,
 98               chat_generator: ChatGenerator,
 99               tools: ToolsType | None = None,
100               system_prompt: str | None = None,
101               exit_conditions: list[str] | None = None,
102               state_schema: dict[str, Any] | None = None,
103               max_agent_steps: int = 100,
104               streaming_callback: StreamingCallbackT | None = None,
105               raise_on_tool_invocation_failure: bool = False,
106               tool_invoker_kwargs: dict[str, Any] | None = None) -> None
107  ```
108  
109  Initialize the agent component.
110  
111  **Arguments**:
112  
113  - `chat_generator`: An instance of the chat generator that your agent should use. It must support tools.
114  - `tools`: A list of Tool and/or Toolset objects, or a single Toolset that the agent can use.
115  - `system_prompt`: System prompt for the agent.
116  - `exit_conditions`: List of conditions that will cause the agent to return.
117  Can include "text" if the agent should return when it generates a message without tool calls,
118  or tool names that will cause the agent to return once the tool was executed. Defaults to ["text"].
119  - `state_schema`: The schema for the runtime state used by the tools.
120  - `max_agent_steps`: Maximum number of steps the agent will run before stopping. Defaults to 100.
121  If the agent exceeds this number of steps, it will stop and return the current state.
122  - `streaming_callback`: A callback that will be invoked when a response is streamed from the LLM.
123  The same callback can be configured to emit tool results when a tool is called.
124  - `raise_on_tool_invocation_failure`: Should the agent raise an exception when a tool invocation fails?
125  If set to False, the exception will be turned into a chat message and passed to the LLM.
126  - `tool_invoker_kwargs`: Additional keyword arguments to pass to the ToolInvoker.
127  
128  **Raises**:
129  
130  - `TypeError`: If the chat_generator does not support tools parameter in its run method.
131  - `ValueError`: If the exit_conditions are not valid.
132  
133  <a id="agent.Agent.warm_up"></a>
134  
135  #### Agent.warm\_up
136  
137  ```python
138  def warm_up() -> None
139  ```
140  
141  Warm up the Agent.
142  
143  <a id="agent.Agent.to_dict"></a>
144  
145  #### Agent.to\_dict
146  
147  ```python
148  def to_dict() -> dict[str, Any]
149  ```
150  
151  Serialize the component to a dictionary.
152  
153  **Returns**:
154  
155  Dictionary with serialized data
156  
157  <a id="agent.Agent.from_dict"></a>
158  
159  #### Agent.from\_dict
160  
161  ```python
162  @classmethod
163  def from_dict(cls, data: dict[str, Any]) -> "Agent"
164  ```
165  
166  Deserialize the agent from a dictionary.
167  
168  **Arguments**:
169  
170  - `data`: Dictionary to deserialize from
171  
172  **Returns**:
173  
174  Deserialized agent
175  
176  <a id="agent.Agent.run"></a>
177  
178  #### Agent.run
179  
180  ```python
181  def run(messages: list[ChatMessage],
182          streaming_callback: StreamingCallbackT | None = None,
183          *,
184          generation_kwargs: dict[str, Any] | None = None,
185          break_point: AgentBreakpoint | None = None,
186          snapshot: AgentSnapshot | None = None,
187          system_prompt: str | None = None,
188          tools: ToolsType | list[str] | None = None,
189          **kwargs: Any) -> dict[str, Any]
190  ```
191  
192  Process messages and execute tools until an exit condition is met.
193  
194  **Arguments**:
195  
196  - `messages`: List of Haystack ChatMessage objects to process.
197  - `streaming_callback`: A callback that will be invoked when a response is streamed from the LLM.
198  The same callback can be configured to emit tool results when a tool is called.
199  - `generation_kwargs`: Additional keyword arguments for LLM. These parameters will
200  override the parameters passed during component initialization.
201  - `break_point`: An AgentBreakpoint, can be a Breakpoint for the "chat_generator" or a ToolBreakpoint
202  for "tool_invoker".
203  - `snapshot`: A dictionary containing a snapshot of a previously saved agent execution. The snapshot contains
204  the relevant information to restart the Agent execution from where it left off.
205  - `system_prompt`: System prompt for the agent. If provided, it overrides the default system prompt.
206  - `tools`: Optional list of Tool objects, a Toolset, or list of tool names to use for this run.
207  When passing tool names, tools are selected from the Agent's originally configured tools.
208  - `kwargs`: Additional data to pass to the State schema used by the Agent.
209  The keys must match the schema defined in the Agent's `state_schema`.
210  
211  **Raises**:
212  
213  - `BreakpointException`: If an agent breakpoint is triggered.
214  
215  **Returns**:
216  
217  A dictionary with the following keys:
218  - "messages": List of all messages exchanged during the agent's run.
219  - "last_message": The last message exchanged during the agent's run.
220  - Any additional keys defined in the `state_schema`.
221  
222  <a id="agent.Agent.run_async"></a>
223  
224  #### Agent.run\_async
225  
226  ```python
227  async def run_async(messages: list[ChatMessage],
228                      streaming_callback: StreamingCallbackT | None = None,
229                      *,
230                      generation_kwargs: dict[str, Any] | None = None,
231                      break_point: AgentBreakpoint | None = None,
232                      snapshot: AgentSnapshot | None = None,
233                      system_prompt: str | None = None,
234                      tools: ToolsType | list[str] | None = None,
235                      **kwargs: Any) -> dict[str, Any]
236  ```
237  
238  Asynchronously process messages and execute tools until the exit condition is met.
239  
240  This is the asynchronous version of the `run` method. It follows the same logic but uses
241  asynchronous operations where possible, such as calling the `run_async` method of the ChatGenerator
242  if available.
243  
244  **Arguments**:
245  
246  - `messages`: List of Haystack ChatMessage objects to process.
247  - `streaming_callback`: An asynchronous callback that will be invoked when a response is streamed from the
248  LLM. The same callback can be configured to emit tool results when a tool is called.
249  - `generation_kwargs`: Additional keyword arguments for LLM. These parameters will
250  override the parameters passed during component initialization.
251  - `break_point`: An AgentBreakpoint, can be a Breakpoint for the "chat_generator" or a ToolBreakpoint
252  for "tool_invoker".
253  - `snapshot`: A dictionary containing a snapshot of a previously saved agent execution. The snapshot contains
254  the relevant information to restart the Agent execution from where it left off.
255  - `system_prompt`: System prompt for the agent. If provided, it overrides the default system prompt.
256  - `tools`: Optional list of Tool objects, a Toolset, or list of tool names to use for this run.
257  - `kwargs`: Additional data to pass to the State schema used by the Agent.
258  The keys must match the schema defined in the Agent's `state_schema`.
259  
260  **Raises**:
261  
262  - `BreakpointException`: If an agent breakpoint is triggered.
263  
264  **Returns**:
265  
266  A dictionary with the following keys:
267  - "messages": List of all messages exchanged during the agent's run.
268  - "last_message": The last message exchanged during the agent's run.
269  - Any additional keys defined in the `state_schema`.
270  
271  <a id="state/state"></a>
272  
273  ## Module state/state
274  
275  <a id="state/state.State"></a>
276  
277  ### State
278  
279  State is a container for storing shared information during the execution of an Agent and its tools.
280  
281  For instance, State can be used to store documents, context, and intermediate results.
282  
283  Internally it wraps a `_data` dictionary defined by a `schema`. Each schema entry has:
284  ```json
285    "parameter_name": {
286      "type": SomeType,  # expected type
287      "handler": Optional[Callable[[Any, Any], Any]]  # merge/update function
288    }
289    ```
290  
291  Handlers control how values are merged when using the `set()` method:
292  - For list types: defaults to `merge_lists` (concatenates lists)
293  - For other types: defaults to `replace_values` (overwrites existing value)
294  
295  A `messages` field with type `list[ChatMessage]` is automatically added to the schema.
296  
297  This makes it possible for the Agent to read from and write to the same context.
298  
299  ### Usage example
300  ```python
301  from haystack.components.agents.state import State
302  
303  my_state = State(
304      schema={"gh_repo_name": {"type": str}, "user_name": {"type": str}},
305      data={"gh_repo_name": "my_repo", "user_name": "my_user_name"}
306  )
307  ```
308  
309  <a id="state/state.State.__init__"></a>
310  
311  #### State.\_\_init\_\_
312  
313  ```python
314  def __init__(schema: dict[str, Any], data: dict[str, Any] | None = None)
315  ```
316  
317  Initialize a State object with a schema and optional data.
318  
319  **Arguments**:
320  
321  - `schema`: Dictionary mapping parameter names to their type and handler configs.
322  Type must be a valid Python type, and handler must be a callable function or None.
323  If handler is None, the default handler for the type will be used. The default handlers are:
324      - For list types: `haystack.agents.state.state_utils.merge_lists`
325      - For all other types: `haystack.agents.state.state_utils.replace_values`
326  - `data`: Optional dictionary of initial data to populate the state
327  
328  <a id="state/state.State.get"></a>
329  
330  #### State.get
331  
332  ```python
333  def get(key: str, default: Any = None) -> Any
334  ```
335  
336  Retrieve a value from the state by key.
337  
338  **Arguments**:
339  
340  - `key`: Key to look up in the state
341  - `default`: Value to return if key is not found
342  
343  **Returns**:
344  
345  Value associated with key or default if not found
346  
347  <a id="state/state.State.set"></a>
348  
349  #### State.set
350  
351  ```python
352  def set(key: str,
353          value: Any,
354          handler_override: Callable[[Any, Any], Any] | None = None) -> None
355  ```
356  
357  Set or merge a value in the state according to schema rules.
358  
359  Value is merged or overwritten according to these rules:
360    - if handler_override is given, use that
361    - else use the handler defined in the schema for 'key'
362  
363  **Arguments**:
364  
365  - `key`: Key to store the value under
366  - `value`: Value to store or merge
367  - `handler_override`: Optional function to override the default merge behavior
368  
369  <a id="state/state.State.data"></a>
370  
371  #### State.data
372  
373  ```python
374  @property
375  def data()
376  ```
377  
378  All current data of the state.
379  
380  <a id="state/state.State.has"></a>
381  
382  #### State.has
383  
384  ```python
385  def has(key: str) -> bool
386  ```
387  
388  Check if a key exists in the state.
389  
390  **Arguments**:
391  
392  - `key`: Key to check for existence
393  
394  **Returns**:
395  
396  True if key exists in state, False otherwise
397  
398  <a id="state/state.State.to_dict"></a>
399  
400  #### State.to\_dict
401  
402  ```python
403  def to_dict()
404  ```
405  
406  Convert the State object to a dictionary.
407  
408  <a id="state/state.State.from_dict"></a>
409  
410  #### State.from\_dict
411  
412  ```python
413  @classmethod
414  def from_dict(cls, data: dict[str, Any])
415  ```
416  
417  Convert a dictionary back to a State object.
418