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