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 *, 99 chat_generator: ChatGenerator, 100 tools: ToolsType | None = None, 101 system_prompt: str | None = None, 102 exit_conditions: list[str] | None = None, 103 state_schema: dict[str, Any] | None = None, 104 max_agent_steps: int = 100, 105 streaming_callback: StreamingCallbackT | None = None, 106 raise_on_tool_invocation_failure: bool = False, 107 tool_invoker_kwargs: dict[str, Any] | None = None, 108 confirmation_strategies: dict[str, ConfirmationStrategy] | None = None 109 ) -> None 110 ``` 111 112 Initialize the agent component. 113 114 **Arguments**: 115 116 - `chat_generator`: An instance of the chat generator that your agent should use. It must support tools. 117 - `tools`: A list of Tool and/or Toolset objects, or a single Toolset that the agent can use. 118 - `system_prompt`: System prompt for the agent. 119 - `exit_conditions`: List of conditions that will cause the agent to return. 120 Can include "text" if the agent should return when it generates a message without tool calls, 121 or tool names that will cause the agent to return once the tool was executed. Defaults to ["text"]. 122 - `state_schema`: The schema for the runtime state used by the tools. 123 - `max_agent_steps`: Maximum number of steps the agent will run before stopping. Defaults to 100. 124 If the agent exceeds this number of steps, it will stop and return the current state. 125 - `streaming_callback`: A callback that will be invoked when a response is streamed from the LLM. 126 The same callback can be configured to emit tool results when a tool is called. 127 - `raise_on_tool_invocation_failure`: Should the agent raise an exception when a tool invocation fails? 128 If set to False, the exception will be turned into a chat message and passed to the LLM. 129 - `tool_invoker_kwargs`: Additional keyword arguments to pass to the ToolInvoker. 130 - `confirmation_strategies`: A dictionary mapping tool names to ConfirmationStrategy instances. 131 132 **Raises**: 133 134 - `TypeError`: If the chat_generator does not support tools parameter in its run method. 135 - `ValueError`: If the exit_conditions are not valid. 136 137 <a id="agent.Agent.warm_up"></a> 138 139 #### Agent.warm\_up 140 141 ```python 142 def warm_up() -> None 143 ``` 144 145 Warm up the Agent. 146 147 <a id="agent.Agent.to_dict"></a> 148 149 #### Agent.to\_dict 150 151 ```python 152 def to_dict() -> dict[str, Any] 153 ``` 154 155 Serialize the component to a dictionary. 156 157 **Returns**: 158 159 Dictionary with serialized data 160 161 <a id="agent.Agent.from_dict"></a> 162 163 #### Agent.from\_dict 164 165 ```python 166 @classmethod 167 def from_dict(cls, data: dict[str, Any]) -> "Agent" 168 ``` 169 170 Deserialize the agent from a dictionary. 171 172 **Arguments**: 173 174 - `data`: Dictionary to deserialize from 175 176 **Returns**: 177 178 Deserialized agent 179 180 <a id="agent.Agent.run"></a> 181 182 #### Agent.run 183 184 ```python 185 def run(messages: list[ChatMessage], 186 streaming_callback: StreamingCallbackT | None = None, 187 *, 188 generation_kwargs: dict[str, Any] | None = None, 189 break_point: AgentBreakpoint | None = None, 190 snapshot: AgentSnapshot | None = None, 191 system_prompt: str | None = None, 192 tools: ToolsType | list[str] | None = None, 193 snapshot_callback: SnapshotCallback | None = None, 194 confirmation_strategy_context: dict[str, Any] | None = None, 195 **kwargs: Any) -> dict[str, Any] 196 ``` 197 198 Process messages and execute tools until an exit condition is met. 199 200 **Arguments**: 201 202 - `messages`: List of Haystack ChatMessage objects to process. 203 - `streaming_callback`: A callback that will be invoked when a response is streamed from the LLM. 204 The same callback can be configured to emit tool results when a tool is called. 205 - `generation_kwargs`: Additional keyword arguments for LLM. These parameters will 206 override the parameters passed during component initialization. 207 - `break_point`: An AgentBreakpoint, can be a Breakpoint for the "chat_generator" or a ToolBreakpoint 208 for "tool_invoker". 209 - `snapshot`: A dictionary containing a snapshot of a previously saved agent execution. The snapshot contains 210 the relevant information to restart the Agent execution from where it left off. 211 - `system_prompt`: System prompt for the agent. If provided, it overrides the default system prompt. 212 - `tools`: Optional list of Tool objects, a Toolset, or list of tool names to use for this run. 213 When passing tool names, tools are selected from the Agent's originally configured tools. 214 - `snapshot_callback`: Optional callback function that is invoked when a pipeline snapshot is created. 215 The callback receives a `PipelineSnapshot` object and can return an optional string. 216 If provided, the callback is used instead of the default file-saving behavior. 217 - `confirmation_strategy_context`: Optional dictionary for passing request-scoped resources 218 to confirmation strategies. Useful in web/server environments to provide per-request 219 objects (e.g., WebSocket connections, async queues, Redis pub/sub clients) that strategies 220 can use for non-blocking user interaction. 221 - `kwargs`: Additional data to pass to the State schema used by the Agent. 222 The keys must match the schema defined in the Agent's `state_schema`. 223 224 **Raises**: 225 226 - `BreakpointException`: If an agent breakpoint is triggered. 227 228 **Returns**: 229 230 A dictionary with the following keys: 231 - "messages": List of all messages exchanged during the agent's run. 232 - "last_message": The last message exchanged during the agent's run. 233 - Any additional keys defined in the `state_schema`. 234 235 <a id="agent.Agent.run_async"></a> 236 237 #### Agent.run\_async 238 239 ```python 240 async def run_async(messages: list[ChatMessage], 241 streaming_callback: StreamingCallbackT | None = None, 242 *, 243 generation_kwargs: dict[str, Any] | None = None, 244 break_point: AgentBreakpoint | None = None, 245 snapshot: AgentSnapshot | None = None, 246 system_prompt: str | None = None, 247 tools: ToolsType | list[str] | None = None, 248 snapshot_callback: SnapshotCallback | None = None, 249 confirmation_strategy_context: dict[str, Any] 250 | None = None, 251 **kwargs: Any) -> dict[str, Any] 252 ``` 253 254 Asynchronously process messages and execute tools until the exit condition is met. 255 256 This is the asynchronous version of the `run` method. It follows the same logic but uses 257 asynchronous operations where possible, such as calling the `run_async` method of the ChatGenerator 258 if available. 259 260 **Arguments**: 261 262 - `messages`: List of Haystack ChatMessage objects to process. 263 - `streaming_callback`: An asynchronous callback that will be invoked when a response is streamed from the 264 LLM. The same callback can be configured to emit tool results when a tool is called. 265 - `generation_kwargs`: Additional keyword arguments for LLM. These parameters will 266 override the parameters passed during component initialization. 267 - `break_point`: An AgentBreakpoint, can be a Breakpoint for the "chat_generator" or a ToolBreakpoint 268 for "tool_invoker". 269 - `snapshot`: A dictionary containing a snapshot of a previously saved agent execution. The snapshot contains 270 the relevant information to restart the Agent execution from where it left off. 271 - `system_prompt`: System prompt for the agent. If provided, it overrides the default system prompt. 272 - `tools`: Optional list of Tool objects, a Toolset, or list of tool names to use for this run. 273 - `snapshot_callback`: Optional callback function that is invoked when a pipeline snapshot is created. 274 The callback receives a `PipelineSnapshot` object and can return an optional string. 275 If provided, the callback is used instead of the default file-saving behavior. 276 - `kwargs`: Additional data to pass to the State schema used by the Agent. 277 The keys must match the schema defined in the Agent's `state_schema`. 278 - `confirmation_strategy_context`: Optional dictionary for passing request-scoped resources 279 to confirmation strategies. Useful in web/server environments to provide per-request 280 objects (e.g., WebSocket connections, async queues, Redis pub/sub clients) that strategies 281 can use for non-blocking user interaction. 282 283 **Raises**: 284 285 - `BreakpointException`: If an agent breakpoint is triggered. 286 287 **Returns**: 288 289 A dictionary with the following keys: 290 - "messages": List of all messages exchanged during the agent's run. 291 - "last_message": The last message exchanged during the agent's run. 292 - Any additional keys defined in the `state_schema`. 293 294 <a id="state/state"></a> 295 296 ## Module state/state 297 298 <a id="state/state.State"></a> 299 300 ### State 301 302 State is a container for storing shared information during the execution of an Agent and its tools. 303 304 For instance, State can be used to store documents, context, and intermediate results. 305 306 Internally it wraps a `_data` dictionary defined by a `schema`. Each schema entry has: 307 ```json 308 "parameter_name": { 309 "type": SomeType, # expected type 310 "handler": Optional[Callable[[Any, Any], Any]] # merge/update function 311 } 312 ``` 313 314 Handlers control how values are merged when using the `set()` method: 315 - For list types: defaults to `merge_lists` (concatenates lists) 316 - For other types: defaults to `replace_values` (overwrites existing value) 317 318 A `messages` field with type `list[ChatMessage]` is automatically added to the schema. 319 320 This makes it possible for the Agent to read from and write to the same context. 321 322 ### Usage example 323 ```python 324 from haystack.components.agents.state import State 325 326 my_state = State( 327 schema={"gh_repo_name": {"type": str}, "user_name": {"type": str}}, 328 data={"gh_repo_name": "my_repo", "user_name": "my_user_name"} 329 ) 330 ``` 331 332 <a id="state/state.State.__init__"></a> 333 334 #### State.\_\_init\_\_ 335 336 ```python 337 def __init__(schema: dict[str, Any], data: dict[str, Any] | None = None) 338 ``` 339 340 Initialize a State object with a schema and optional data. 341 342 **Arguments**: 343 344 - `schema`: Dictionary mapping parameter names to their type and handler configs. 345 Type must be a valid Python type, and handler must be a callable function or None. 346 If handler is None, the default handler for the type will be used. The default handlers are: 347 - For list types: `haystack.agents.state.state_utils.merge_lists` 348 - For all other types: `haystack.agents.state.state_utils.replace_values` 349 - `data`: Optional dictionary of initial data to populate the state 350 351 <a id="state/state.State.get"></a> 352 353 #### State.get 354 355 ```python 356 def get(key: str, default: Any = None) -> Any 357 ``` 358 359 Retrieve a value from the state by key. 360 361 **Arguments**: 362 363 - `key`: Key to look up in the state 364 - `default`: Value to return if key is not found 365 366 **Returns**: 367 368 Value associated with key or default if not found 369 370 <a id="state/state.State.set"></a> 371 372 #### State.set 373 374 ```python 375 def set(key: str, 376 value: Any, 377 handler_override: Callable[[Any, Any], Any] | None = None) -> None 378 ``` 379 380 Set or merge a value in the state according to schema rules. 381 382 Value is merged or overwritten according to these rules: 383 - if handler_override is given, use that 384 - else use the handler defined in the schema for 'key' 385 386 **Arguments**: 387 388 - `key`: Key to store the value under 389 - `value`: Value to store or merge 390 - `handler_override`: Optional function to override the default merge behavior 391 392 <a id="state/state.State.data"></a> 393 394 #### State.data 395 396 ```python 397 @property 398 def data() 399 ``` 400 401 All current data of the state. 402 403 <a id="state/state.State.has"></a> 404 405 #### State.has 406 407 ```python 408 def has(key: str) -> bool 409 ``` 410 411 Check if a key exists in the state. 412 413 **Arguments**: 414 415 - `key`: Key to check for existence 416 417 **Returns**: 418 419 True if key exists in state, False otherwise 420 421 <a id="state/state.State.to_dict"></a> 422 423 #### State.to\_dict 424 425 ```python 426 def to_dict() 427 ``` 428 429 Convert the State object to a dictionary. 430 431 <a id="state/state.State.from_dict"></a> 432 433 #### State.from\_dict 434 435 ```python 436 @classmethod 437 def from_dict(cls, data: dict[str, Any]) 438 ``` 439 440 Convert a dictionary back to a State object. 441