tools_api.md
  1  ---
  2  title: Tools
  3  id: tools-api
  4  description: Unified abstractions to represent tools across the framework.
  5  slug: "/tools-api"
  6  ---
  7  
  8  <a id="tool"></a>
  9  
 10  # Module tool
 11  
 12  <a id="tool.Tool"></a>
 13  
 14  ## Tool
 15  
 16  Data class representing a Tool that Language Models can prepare a call for.
 17  
 18  Accurate definitions of the textual attributes such as `name` and `description`
 19  are important for the Language Model to correctly prepare the call.
 20  
 21  **Arguments**:
 22  
 23  - `name`: Name of the Tool.
 24  - `description`: Description of the Tool.
 25  - `parameters`: A JSON schema defining the parameters expected by the Tool.
 26  - `function`: The function that will be invoked when the Tool is called.
 27  - `outputs_to_string`: Optional dictionary defining how a tool outputs should be converted into a string.
 28  If the source is provided only the specified output key is sent to the handler.
 29  If the source is omitted the whole tool result is sent to the handler.
 30  Example:
 31  ```python
 32  {
 33      "source": "docs", "handler": format_documents
 34  }
 35  ```
 36  - `inputs_from_state`: Optional dictionary mapping state keys to tool parameter names.
 37  Example: `{"repository": "repo"}` maps state's "repository" to tool's "repo" parameter.
 38  - `outputs_to_state`: Optional dictionary defining how tool outputs map to keys within state as well as optional handlers.
 39  If the source is provided only the specified output key is sent to the handler.
 40  Example:
 41  ```python
 42  {
 43      "documents": {"source": "docs", "handler": custom_handler}
 44  }
 45  ```
 46  If the source is omitted the whole tool result is sent to the handler.
 47  Example:
 48  ```python
 49  {
 50      "documents": {"handler": custom_handler}
 51  }
 52  ```
 53  
 54  <a id="tool.Tool.tool_spec"></a>
 55  
 56  #### Tool.tool\_spec
 57  
 58  ```python
 59  @property
 60  def tool_spec() -> dict[str, Any]
 61  ```
 62  
 63  Return the Tool specification to be used by the Language Model.
 64  
 65  <a id="tool.Tool.invoke"></a>
 66  
 67  #### Tool.invoke
 68  
 69  ```python
 70  def invoke(**kwargs: Any) -> Any
 71  ```
 72  
 73  Invoke the Tool with the provided keyword arguments.
 74  
 75  <a id="tool.Tool.to_dict"></a>
 76  
 77  #### Tool.to\_dict
 78  
 79  ```python
 80  def to_dict() -> dict[str, Any]
 81  ```
 82  
 83  Serializes the Tool to a dictionary.
 84  
 85  **Returns**:
 86  
 87  Dictionary with serialized data.
 88  
 89  <a id="tool.Tool.from_dict"></a>
 90  
 91  #### Tool.from\_dict
 92  
 93  ```python
 94  @classmethod
 95  def from_dict(cls, data: dict[str, Any]) -> "Tool"
 96  ```
 97  
 98  Deserializes the Tool from a dictionary.
 99  
100  **Arguments**:
101  
102  - `data`: Dictionary to deserialize from.
103  
104  **Returns**:
105  
106  Deserialized Tool.
107  
108  <a id="from_function"></a>
109  
110  # Module from\_function
111  
112  <a id="from_function.create_tool_from_function"></a>
113  
114  #### create\_tool\_from\_function
115  
116  ```python
117  def create_tool_from_function(
118          function: Callable,
119          name: Optional[str] = None,
120          description: Optional[str] = None,
121          inputs_from_state: Optional[dict[str, str]] = None,
122          outputs_to_state: Optional[dict[str, dict[str,
123                                                    Any]]] = None) -> "Tool"
124  ```
125  
126  Create a Tool instance from a function.
127  
128  Allows customizing the Tool name and description.
129  For simpler use cases, consider using the `@tool` decorator.
130  
131  ### Usage example
132  
133  ```python
134  from typing import Annotated, Literal
135  from haystack.tools import create_tool_from_function
136  
137  def get_weather(
138      city: Annotated[str, "the city for which to get the weather"] = "Munich",
139      unit: Annotated[Literal["Celsius", "Fahrenheit"], "the unit for the temperature"] = "Celsius"):
140      '''A simple function to get the current weather for a location.'''
141      return f"Weather report for {city}: 20 {unit}, sunny"
142  
143  tool = create_tool_from_function(get_weather)
144  
145  print(tool)
146  >>> Tool(name='get_weather', description='A simple function to get the current weather for a location.',
147  >>> parameters={
148  >>> 'type': 'object',
149  >>> 'properties': {
150  >>>     'city': {'type': 'string', 'description': 'the city for which to get the weather', 'default': 'Munich'},
151  >>>     'unit': {
152  >>>         'type': 'string',
153  >>>         'enum': ['Celsius', 'Fahrenheit'],
154  >>>         'description': 'the unit for the temperature',
155  >>>         'default': 'Celsius',
156  >>>     },
157  >>>     }
158  >>> },
159  >>> function=<function get_weather at 0x7f7b3a8a9b80>)
160  ```
161  
162  **Arguments**:
163  
164  - `function`: The function to be converted into a Tool.
165  The function must include type hints for all parameters.
166  The function is expected to have basic python input types (str, int, float, bool, list, dict, tuple).
167  Other input types may work but are not guaranteed.
168  If a parameter is annotated using `typing.Annotated`, its metadata will be used as parameter description.
169  - `name`: The name of the Tool. If not provided, the name of the function will be used.
170  - `description`: The description of the Tool. If not provided, the docstring of the function will be used.
171  To intentionally leave the description empty, pass an empty string.
172  - `inputs_from_state`: Optional dictionary mapping state keys to tool parameter names.
173  Example: `{"repository": "repo"}` maps state's "repository" to tool's "repo" parameter.
174  - `outputs_to_state`: Optional dictionary defining how tool outputs map to state and message handling.
175  Example:
176  ```python
177  {
178      "documents": {"source": "docs", "handler": custom_handler},
179      "message": {"source": "summary", "handler": format_summary}
180  }
181  ```
182  
183  **Raises**:
184  
185  - `ValueError`: If any parameter of the function lacks a type hint.
186  - `SchemaGenerationError`: If there is an error generating the JSON schema for the Tool.
187  
188  **Returns**:
189  
190  The Tool created from the function.
191  
192  <a id="from_function.tool"></a>
193  
194  #### tool
195  
196  ```python
197  def tool(
198      function: Optional[Callable] = None,
199      *,
200      name: Optional[str] = None,
201      description: Optional[str] = None,
202      inputs_from_state: Optional[dict[str, str]] = None,
203      outputs_to_state: Optional[dict[str, dict[str, Any]]] = None
204  ) -> Union[Tool, Callable[[Callable], Tool]]
205  ```
206  
207  Decorator to convert a function into a Tool.
208  
209  Can be used with or without parameters:
210  @tool  # without parameters
211  def my_function(): ...
212  
213  @tool(name="custom_name")  # with parameters
214  def my_function(): ...
215  
216  ### Usage example
217  ```python
218  from typing import Annotated, Literal
219  from haystack.tools import tool
220  
221  @tool
222  def get_weather(
223      city: Annotated[str, "the city for which to get the weather"] = "Munich",
224      unit: Annotated[Literal["Celsius", "Fahrenheit"], "the unit for the temperature"] = "Celsius"):
225      '''A simple function to get the current weather for a location.'''
226      return f"Weather report for {city}: 20 {unit}, sunny"
227  
228  print(get_weather)
229  >>> Tool(name='get_weather', description='A simple function to get the current weather for a location.',
230  >>> parameters={
231  >>> 'type': 'object',
232  >>> 'properties': {
233  >>>     'city': {'type': 'string', 'description': 'the city for which to get the weather', 'default': 'Munich'},
234  >>>     'unit': {
235  >>>         'type': 'string',
236  >>>         'enum': ['Celsius', 'Fahrenheit'],
237  >>>         'description': 'the unit for the temperature',
238  >>>         'default': 'Celsius',
239  >>>     },
240  >>>     }
241  >>> },
242  >>> function=<function get_weather at 0x7f7b3a8a9b80>)
243  ```
244  
245  **Arguments**:
246  
247  - `function`: The function to decorate (when used without parameters)
248  - `name`: Optional custom name for the tool
249  - `description`: Optional custom description
250  - `inputs_from_state`: Optional dictionary mapping state keys to tool parameter names
251  - `outputs_to_state`: Optional dictionary defining how tool outputs map to state and message handling
252  
253  **Returns**:
254  
255  Either a Tool instance or a decorator function that will create one
256  
257  <a id="component_tool"></a>
258  
259  # Module component\_tool
260  
261  <a id="component_tool.ComponentTool"></a>
262  
263  ## ComponentTool
264  
265  A Tool that wraps Haystack components, allowing them to be used as tools by LLMs.
266  
267  ComponentTool automatically generates LLM-compatible tool schemas from component input sockets,
268  which are derived from the component's `run` method signature and type hints.
269  
270  
271  Key features:
272  - Automatic LLM tool calling schema generation from component input sockets
273  - Type conversion and validation for component inputs
274  - Support for types:
275  - Dataclasses
276  - Lists of dataclasses
277  - Basic types (str, int, float, bool, dict)
278  - Lists of basic types
279  - Automatic name generation from component class name
280  - Description extraction from component docstrings
281  
282  To use ComponentTool, you first need a Haystack component - either an existing one or a new one you create.
283  You can create a ComponentTool from the component by passing the component to the ComponentTool constructor.
284  Below is an example of creating a ComponentTool from an existing SerperDevWebSearch component.
285  
286  ## Usage Example:
287  
288  ```python
289  from haystack import component, Pipeline
290  from haystack.tools import ComponentTool
291  from haystack.components.websearch import SerperDevWebSearch
292  from haystack.utils import Secret
293  from haystack.components.tools.tool_invoker import ToolInvoker
294  from haystack.components.generators.chat import OpenAIChatGenerator
295  from haystack.dataclasses import ChatMessage
296  
297  # Create a SerperDev search component
298  search = SerperDevWebSearch(api_key=Secret.from_env_var("SERPERDEV_API_KEY"), top_k=3)
299  
300  # Create a tool from the component
301  tool = ComponentTool(
302      component=search,
303      name="web_search",  # Optional: defaults to "serper_dev_web_search"
304      description="Search the web for current information on any topic"  # Optional: defaults to component docstring
305  )
306  
307  # Create pipeline with OpenAIChatGenerator and ToolInvoker
308  pipeline = Pipeline()
309  pipeline.add_component("llm", OpenAIChatGenerator(model="gpt-4o-mini", tools=[tool]))
310  pipeline.add_component("tool_invoker", ToolInvoker(tools=[tool]))
311  
312  # Connect components
313  pipeline.connect("llm.replies", "tool_invoker.messages")
314  
315  message = ChatMessage.from_user("Use the web search tool to find information about Nikola Tesla")
316  
317  # Run pipeline
318  result = pipeline.run({"llm": {"messages": [message]}})
319  
320  print(result)
321  ```
322  
323  <a id="component_tool.ComponentTool.__init__"></a>
324  
325  #### ComponentTool.\_\_init\_\_
326  
327  ```python
328  def __init__(
329      component: Component,
330      name: Optional[str] = None,
331      description: Optional[str] = None,
332      parameters: Optional[dict[str, Any]] = None,
333      *,
334      outputs_to_string: Optional[dict[str, Union[str, Callable[[Any],
335                                                                str]]]] = None,
336      inputs_from_state: Optional[dict[str, str]] = None,
337      outputs_to_state: Optional[dict[str, dict[str, Union[str,
338                                                           Callable]]]] = None
339  ) -> None
340  ```
341  
342  Create a Tool instance from a Haystack component.
343  
344  **Arguments**:
345  
346  - `component`: The Haystack component to wrap as a tool.
347  - `name`: Optional name for the tool (defaults to snake_case of component class name).
348  - `description`: Optional description (defaults to component's docstring).
349  - `parameters`: A JSON schema defining the parameters expected by the Tool.
350  Will fall back to the parameters defined in the component's run method signature if not provided.
351  - `outputs_to_string`: Optional dictionary defining how a tool outputs should be converted into a string.
352  If the source is provided only the specified output key is sent to the handler.
353  If the source is omitted the whole tool result is sent to the handler.
354  Example:
355  ```python
356  {
357      "source": "docs", "handler": format_documents
358  }
359  ```
360  - `inputs_from_state`: Optional dictionary mapping state keys to tool parameter names.
361  Example: `{"repository": "repo"}` maps state's "repository" to tool's "repo" parameter.
362  - `outputs_to_state`: Optional dictionary defining how tool outputs map to keys within state as well as optional handlers.
363  If the source is provided only the specified output key is sent to the handler.
364  Example:
365  ```python
366  {
367      "documents": {"source": "docs", "handler": custom_handler}
368  }
369  ```
370  If the source is omitted the whole tool result is sent to the handler.
371  Example:
372  ```python
373  {
374      "documents": {"handler": custom_handler}
375  }
376  ```
377  
378  **Raises**:
379  
380  - `ValueError`: If the component is invalid or schema generation fails.
381  
382  <a id="component_tool.ComponentTool.to_dict"></a>
383  
384  #### ComponentTool.to\_dict
385  
386  ```python
387  def to_dict() -> dict[str, Any]
388  ```
389  
390  Serializes the ComponentTool to a dictionary.
391  
392  <a id="component_tool.ComponentTool.from_dict"></a>
393  
394  #### ComponentTool.from\_dict
395  
396  ```python
397  @classmethod
398  def from_dict(cls, data: dict[str, Any]) -> "ComponentTool"
399  ```
400  
401  Deserializes the ComponentTool from a dictionary.
402  
403  <a id="component_tool.ComponentTool.tool_spec"></a>
404  
405  #### ComponentTool.tool\_spec
406  
407  ```python
408  @property
409  def tool_spec() -> dict[str, Any]
410  ```
411  
412  Return the Tool specification to be used by the Language Model.
413  
414  <a id="component_tool.ComponentTool.invoke"></a>
415  
416  #### ComponentTool.invoke
417  
418  ```python
419  def invoke(**kwargs: Any) -> Any
420  ```
421  
422  Invoke the Tool with the provided keyword arguments.
423  
424  <a id="toolset"></a>
425  
426  # Module toolset
427  
428  <a id="toolset.Toolset"></a>
429  
430  ## Toolset
431  
432  A collection of related Tools that can be used and managed as a cohesive unit.
433  
434  Toolset serves two main purposes:
435  
436  1. Group related tools together:
437  Toolset allows you to organize related tools into a single collection, making it easier
438  to manage and use them as a unit in Haystack pipelines.
439  
440  **Example**:
441  
442     ```python
443     from haystack.tools import Tool, Toolset
444     from haystack.components.tools import ToolInvoker
445  
446     # Define math functions
447     def add_numbers(a: int, b: int) -> int:
448         return a + b
449  
450     def subtract_numbers(a: int, b: int) -> int:
451         return a - b
452  
453     # Create tools with proper schemas
454     add_tool = Tool(
455         name="add",
456         description="Add two numbers",
457         parameters={
458             "type": "object",
459             "properties": {
460                 "a": {"type": "integer"},
461                 "b": {"type": "integer"}
462             },
463             "required": ["a", "b"]
464         },
465         function=add_numbers
466     )
467  
468     subtract_tool = Tool(
469         name="subtract",
470         description="Subtract b from a",
471         parameters={
472             "type": "object",
473             "properties": {
474                 "a": {"type": "integer"},
475                 "b": {"type": "integer"}
476             },
477             "required": ["a", "b"]
478         },
479         function=subtract_numbers
480     )
481  
482     # Create a toolset with the math tools
483     math_toolset = Toolset([add_tool, subtract_tool])
484  
485     # Use the toolset with a ToolInvoker or ChatGenerator component
486     invoker = ToolInvoker(tools=math_toolset)
487     ```
488  
489    2. Base class for dynamic tool loading:
490    By subclassing Toolset, you can create implementations that dynamically load tools
491    from external sources like OpenAPI URLs, MCP servers, or other resources.
492  
493  
494  **Example**:
495  
496     ```python
497     from haystack.core.serialization import generate_qualified_class_name
498     from haystack.tools import Tool, Toolset
499     from haystack.components.tools import ToolInvoker
500  
501     class CalculatorToolset(Toolset):
502         '''A toolset for calculator operations.'''
503  
504         def __init__(self):
505             tools = self._create_tools()
506             super().__init__(tools)
507  
508         def _create_tools(self):
509             # These Tool instances are obviously defined statically and for illustration purposes only.
510             # In a real-world scenario, you would dynamically load tools from an external source here.
511             tools = []
512             add_tool = Tool(
513                 name="add",
514                 description="Add two numbers",
515                 parameters={
516                     "type": "object",
517                     "properties": {"a": {"type": "integer"}, "b": {"type": "integer"}},
518                     "required": ["a", "b"],
519                 },
520                 function=lambda a, b: a + b,
521             )
522  
523             multiply_tool = Tool(
524                 name="multiply",
525                 description="Multiply two numbers",
526                 parameters={
527                     "type": "object",
528                     "properties": {"a": {"type": "integer"}, "b": {"type": "integer"}},
529                     "required": ["a", "b"],
530                 },
531                 function=lambda a, b: a * b,
532             )
533  
534             tools.append(add_tool)
535             tools.append(multiply_tool)
536  
537             return tools
538  
539         def to_dict(self):
540             return {
541                 "type": generate_qualified_class_name(type(self)),
542                 "data": {},  # no data to serialize as we define the tools dynamically
543             }
544  
545         @classmethod
546         def from_dict(cls, data):
547             return cls()  # Recreate the tools dynamically during deserialization
548  
549     # Create the dynamic toolset and use it with ToolInvoker
550     calculator_toolset = CalculatorToolset()
551     invoker = ToolInvoker(tools=calculator_toolset)
552     ```
553  
554    Toolset implements the collection interface (__iter__, __contains__, __len__, __getitem__),
555    making it behave like a list of Tools. This makes it compatible with components that expect
556    iterable tools, such as ToolInvoker or Haystack chat generators.
557  
558    When implementing a custom Toolset subclass for dynamic tool loading:
559    - Perform the dynamic loading in the __init__ method
560    - Override to_dict() and from_dict() methods if your tools are defined dynamically
561    - Serialize endpoint descriptors rather than tool instances if your tools
562    are loaded from external sources
563  
564  <a id="toolset.Toolset.__post_init__"></a>
565  
566  #### Toolset.\_\_post\_init\_\_
567  
568  ```python
569  def __post_init__()
570  ```
571  
572  Validate and set up the toolset after initialization.
573  
574  This handles the case when tools are provided during initialization.
575  
576  <a id="toolset.Toolset.__iter__"></a>
577  
578  #### Toolset.\_\_iter\_\_
579  
580  ```python
581  def __iter__() -> Iterator[Tool]
582  ```
583  
584  Return an iterator over the Tools in this Toolset.
585  
586  This allows the Toolset to be used wherever a list of Tools is expected.
587  
588  **Returns**:
589  
590  An iterator yielding Tool instances
591  
592  <a id="toolset.Toolset.__contains__"></a>
593  
594  #### Toolset.\_\_contains\_\_
595  
596  ```python
597  def __contains__(item: Any) -> bool
598  ```
599  
600  Check if a tool is in this Toolset.
601  
602  Supports checking by:
603  - Tool instance: tool in toolset
604  - Tool name: "tool_name" in toolset
605  
606  **Arguments**:
607  
608  - `item`: Tool instance or tool name string
609  
610  **Returns**:
611  
612  True if contained, False otherwise
613  
614  <a id="toolset.Toolset.add"></a>
615  
616  #### Toolset.add
617  
618  ```python
619  def add(tool: Union[Tool, "Toolset"]) -> None
620  ```
621  
622  Add a new Tool or merge another Toolset.
623  
624  **Arguments**:
625  
626  - `tool`: A Tool instance or another Toolset to add
627  
628  **Raises**:
629  
630  - `ValueError`: If adding the tool would result in duplicate tool names
631  - `TypeError`: If the provided object is not a Tool or Toolset
632  
633  <a id="toolset.Toolset.to_dict"></a>
634  
635  #### Toolset.to\_dict
636  
637  ```python
638  def to_dict() -> dict[str, Any]
639  ```
640  
641  Serialize the Toolset to a dictionary.
642  
643  **Returns**:
644  
645  A dictionary representation of the Toolset
646  Note for subclass implementers:
647  The default implementation is ideal for scenarios where Tool resolution is static. However, if your subclass
648  of Toolset dynamically resolves Tool instances from external sources—such as an MCP server, OpenAPI URL, or
649  a local OpenAPI specification—you should consider serializing the endpoint descriptor instead of the Tool
650  instances themselves. This strategy preserves the dynamic nature of your Toolset and minimizes the overhead
651  associated with serializing potentially large collections of Tool objects. Moreover, by serializing the
652  descriptor, you ensure that the deserialization process can accurately reconstruct the Tool instances, even
653  if they have been modified or removed since the last serialization. Failing to serialize the descriptor may
654  lead to issues where outdated or incorrect Tool configurations are loaded, potentially causing errors or
655  unexpected behavior.
656  
657  <a id="toolset.Toolset.from_dict"></a>
658  
659  #### Toolset.from\_dict
660  
661  ```python
662  @classmethod
663  def from_dict(cls, data: dict[str, Any]) -> "Toolset"
664  ```
665  
666  Deserialize a Toolset from a dictionary.
667  
668  **Arguments**:
669  
670  - `data`: Dictionary representation of the Toolset
671  
672  **Returns**:
673  
674  A new Toolset instance
675  
676  <a id="toolset.Toolset.__add__"></a>
677  
678  #### Toolset.\_\_add\_\_
679  
680  ```python
681  def __add__(other: Union[Tool, "Toolset", list[Tool]]) -> "Toolset"
682  ```
683  
684  Concatenate this Toolset with another Tool, Toolset, or list of Tools.
685  
686  **Arguments**:
687  
688  - `other`: Another Tool, Toolset, or list of Tools to concatenate
689  
690  **Raises**:
691  
692  - `TypeError`: If the other parameter is not a Tool, Toolset, or list of Tools
693  - `ValueError`: If the combination would result in duplicate tool names
694  
695  **Returns**:
696  
697  A new Toolset containing all tools
698  
699  <a id="toolset.Toolset.__len__"></a>
700  
701  #### Toolset.\_\_len\_\_
702  
703  ```python
704  def __len__() -> int
705  ```
706  
707  Return the number of Tools in this Toolset.
708  
709  **Returns**:
710  
711  Number of Tools
712  
713  <a id="toolset.Toolset.__getitem__"></a>
714  
715  #### Toolset.\_\_getitem\_\_
716  
717  ```python
718  def __getitem__(index)
719  ```
720  
721  Get a Tool by index.
722  
723  **Arguments**:
724  
725  - `index`: Index of the Tool to get
726  
727  **Returns**:
728  
729  The Tool at the specified index