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