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: Optional[ToolsType] = None,
100               system_prompt: Optional[str] = None,
101               exit_conditions: Optional[list[str]] = None,
102               state_schema: Optional[dict[str, Any]] = None,
103               max_agent_steps: int = 100,
104               streaming_callback: Optional[StreamingCallbackT] = None,
105               raise_on_tool_invocation_failure: bool = False,
106               tool_invoker_kwargs: Optional[dict[str, Any]] = 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: Optional[StreamingCallbackT] = None,
183          *,
184          generation_kwargs: Optional[dict[str, Any]] = None,
185          break_point: Optional[AgentBreakpoint] = None,
186          snapshot: Optional[AgentSnapshot] = None,
187          system_prompt: Optional[str] = None,
188          tools: Optional[Union[ToolsType, list[str]]] = 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  - `RuntimeError`: If the Agent component wasn't warmed up before calling `run()`.
214  - `BreakpointException`: If an agent breakpoint is triggered.
215  
216  **Returns**:
217  
218  A dictionary with the following keys:
219  - "messages": List of all messages exchanged during the agent's run.
220  - "last_message": The last message exchanged during the agent's run.
221  - Any additional keys defined in the `state_schema`.
222  
223  <a id="agent.Agent.run_async"></a>
224  
225  #### Agent.run\_async
226  
227  ```python
228  async def run_async(messages: list[ChatMessage],
229                      streaming_callback: Optional[StreamingCallbackT] = None,
230                      *,
231                      generation_kwargs: Optional[dict[str, Any]] = None,
232                      break_point: Optional[AgentBreakpoint] = None,
233                      snapshot: Optional[AgentSnapshot] = None,
234                      system_prompt: Optional[str] = None,
235                      tools: Optional[Union[ToolsType, list[str]]] = None,
236                      **kwargs: Any) -> dict[str, Any]
237  ```
238  
239  Asynchronously process messages and execute tools until the exit condition is met.
240  
241  This is the asynchronous version of the `run` method. It follows the same logic but uses
242  asynchronous operations where possible, such as calling the `run_async` method of the ChatGenerator
243  if available.
244  
245  **Arguments**:
246  
247  - `messages`: List of Haystack ChatMessage objects to process.
248  - `streaming_callback`: An asynchronous callback that will be invoked when a response is streamed from the
249  LLM. The same callback can be configured to emit tool results when a tool is called.
250  - `generation_kwargs`: Additional keyword arguments for LLM. These parameters will
251  override the parameters passed during component initialization.
252  - `break_point`: An AgentBreakpoint, can be a Breakpoint for the "chat_generator" or a ToolBreakpoint
253  for "tool_invoker".
254  - `snapshot`: A dictionary containing a snapshot of a previously saved agent execution. The snapshot contains
255  the relevant information to restart the Agent execution from where it left off.
256  - `system_prompt`: System prompt for the agent. If provided, it overrides the default system prompt.
257  - `tools`: Optional list of Tool objects, a Toolset, or list of tool names to use for this run.
258  - `kwargs`: Additional data to pass to the State schema used by the Agent.
259  The keys must match the schema defined in the Agent's `state_schema`.
260  
261  **Raises**:
262  
263  - `RuntimeError`: If the Agent component wasn't warmed up before calling `run_async()`.
264  - `BreakpointException`: If an agent breakpoint is triggered.
265  
266  **Returns**:
267  
268  A dictionary with the following keys:
269  - "messages": List of all messages exchanged during the agent's run.
270  - "last_message": The last message exchanged during the agent's run.
271  - Any additional keys defined in the `state_schema`.
272  
273  <a id="state/state"></a>
274  
275  ## Module state/state
276  
277  <a id="state/state.State"></a>
278  
279  ### State
280  
281  State is a container for storing shared information during the execution of an Agent and its tools.
282  
283  For instance, State can be used to store documents, context, and intermediate results.
284  
285  Internally it wraps a `_data` dictionary defined by a `schema`. Each schema entry has:
286  ```json
287    "parameter_name": {
288      "type": SomeType,  # expected type
289      "handler": Optional[Callable[[Any, Any], Any]]  # merge/update function
290    }
291    ```
292  
293  Handlers control how values are merged when using the `set()` method:
294  - For list types: defaults to `merge_lists` (concatenates lists)
295  - For other types: defaults to `replace_values` (overwrites existing value)
296  
297  A `messages` field with type `list[ChatMessage]` is automatically added to the schema.
298  
299  This makes it possible for the Agent to read from and write to the same context.
300  
301  ### Usage example
302  ```python
303  from haystack.components.agents.state import State
304  
305  my_state = State(
306      schema={"gh_repo_name": {"type": str}, "user_name": {"type": str}},
307      data={"gh_repo_name": "my_repo", "user_name": "my_user_name"}
308  )
309  ```
310  
311  <a id="state/state.State.__init__"></a>
312  
313  #### State.\_\_init\_\_
314  
315  ```python
316  def __init__(schema: dict[str, Any], data: Optional[dict[str, Any]] = None)
317  ```
318  
319  Initialize a State object with a schema and optional data.
320  
321  **Arguments**:
322  
323  - `schema`: Dictionary mapping parameter names to their type and handler configs.
324  Type must be a valid Python type, and handler must be a callable function or None.
325  If handler is None, the default handler for the type will be used. The default handlers are:
326      - For list types: `haystack.agents.state.state_utils.merge_lists`
327      - For all other types: `haystack.agents.state.state_utils.replace_values`
328  - `data`: Optional dictionary of initial data to populate the state
329  
330  <a id="state/state.State.get"></a>
331  
332  #### State.get
333  
334  ```python
335  def get(key: str, default: Any = None) -> Any
336  ```
337  
338  Retrieve a value from the state by key.
339  
340  **Arguments**:
341  
342  - `key`: Key to look up in the state
343  - `default`: Value to return if key is not found
344  
345  **Returns**:
346  
347  Value associated with key or default if not found
348  
349  <a id="state/state.State.set"></a>
350  
351  #### State.set
352  
353  ```python
354  def set(key: str,
355          value: Any,
356          handler_override: Optional[Callable[[Any, Any], Any]] = None) -> None
357  ```
358  
359  Set or merge a value in the state according to schema rules.
360  
361  Value is merged or overwritten according to these rules:
362    - if handler_override is given, use that
363    - else use the handler defined in the schema for 'key'
364  
365  **Arguments**:
366  
367  - `key`: Key to store the value under
368  - `value`: Value to store or merge
369  - `handler_override`: Optional function to override the default merge behavior
370  
371  <a id="state/state.State.data"></a>
372  
373  #### State.data
374  
375  ```python
376  @property
377  def data()
378  ```
379  
380  All current data of the state.
381  
382  <a id="state/state.State.has"></a>
383  
384  #### State.has
385  
386  ```python
387  def has(key: str) -> bool
388  ```
389  
390  Check if a key exists in the state.
391  
392  **Arguments**:
393  
394  - `key`: Key to check for existence
395  
396  **Returns**:
397  
398  True if key exists in state, False otherwise
399  
400  <a id="state/state.State.to_dict"></a>
401  
402  #### State.to\_dict
403  
404  ```python
405  def to_dict()
406  ```
407  
408  Convert the State object to a dictionary.
409  
410  <a id="state/state.State.from_dict"></a>
411  
412  #### State.from\_dict
413  
414  ```python
415  @classmethod
416  def from_dict(cls, data: dict[str, Any])
417  ```
418  
419  Convert a dictionary back to a State object.
420