Skip to content

dspy.Tool

dspy.Tool(func: Callable, name: str | None = None, desc: str | None = None, args: dict[str, Any] | None = None, arg_types: dict[str, Any] | None = None, arg_desc: dict[str, str] | None = None)

基类:Type

工具类。

该类用于简化在LLM中创建工具调用(函数调用)的工具。目前仅支持函数。

初始化工具类。

用户可以选择指定namedescargsarg_types,或者让dspy.Tool 自动从函数中推断这些值。对于用户指定的值,将不会对它们执行自动推断。

参数:

名称 类型 描述 默认值
func Callable

被工具包装的实际函数。

必填
name Optional[str]

工具的名称。默认为 None。

None
desc Optional[str]

工具的说明。默认为None。

None
args Optional[dict[str, Any]]

工具的参数及其模式,表示为从参数名到参数json模式的字典。默认为None。

None
arg_types Optional[dict[str, Any]]

工具的参数字典类型,表示为从参数名到参数类型的映射。默认为None。

None
arg_desc Optional[dict[str, str]]

每个参数的描述,表示为从参数名到描述字符串的字典。默认为None。

None

示例:

def foo(x: int, y: str = "hello"):
    return str(x) + y

tool = Tool(foo)
print(tool.args)
# Expected output: {'x': {'type': 'integer'}, 'y': {'type': 'string', 'default': 'hello'}}
Source code in dspy/adapters/types/tool.py
def __init__(
    self,
    func: Callable,
    name: str | None = None,
    desc: str | None = None,
    args: dict[str, Any] | None = None,
    arg_types: dict[str, Any] | None = None,
    arg_desc: dict[str, str] | None = None,
):
    """Initialize the Tool class.

    Users can choose to specify the `name`, `desc`, `args`, and `arg_types`, or let the `dspy.Tool`
    automatically infer the values from the function. For values that are specified by the user, automatic inference
    will not be performed on them.

    Args:
        func (Callable): The actual function that is being wrapped by the tool.
        name (Optional[str], optional): The name of the tool. Defaults to None.
        desc (Optional[str], optional): The description of the tool. Defaults to None.
        args (Optional[dict[str, Any]], optional): The args and their schema of the tool, represented as a
            dictionary from arg name to arg's json schema. Defaults to None.
        arg_types (Optional[dict[str, Any]], optional): The argument types of the tool, represented as a dictionary
            from arg name to the type of the argument. Defaults to None.
        arg_desc (Optional[dict[str, str]], optional): Descriptions for each arg, represented as a
            dictionary from arg name to description string. Defaults to None.

    Example:

    ```python
    def foo(x: int, y: str = "hello"):
        return str(x) + y

    tool = Tool(foo)
    print(tool.args)
    # Expected output: {'x': {'type': 'integer'}, 'y': {'type': 'string', 'default': 'hello'}}
    ```
    """
    super().__init__(func=func, name=name, desc=desc, args=args, arg_types=arg_types, arg_desc=arg_desc)
    self._parse_function(func, arg_desc)

函数

__call__(**kwargs)

Source code in dspy/adapters/types/tool.py
@with_callbacks
def __call__(self, **kwargs):
    parsed_kwargs = self._validate_and_parse_args(**kwargs)
    result = self.func(**parsed_kwargs)
    if asyncio.iscoroutine(result):
        if settings.allow_tool_async_sync_conversion:
            return self._run_async_in_sync(result)
        else:
            raise ValueError(
                "You are calling `__call__` on an async tool, please use `acall` instead or set "
                "`allow_async=True` to run the async tool in sync mode."
            )
    return result

acall(**kwargs) async

Source code in dspy/adapters/types/tool.py
@with_callbacks
async def acall(self, **kwargs):
    parsed_kwargs = self._validate_and_parse_args(**kwargs)
    result = self.func(**parsed_kwargs)
    if asyncio.iscoroutine(result):
        return await result
    else:
        # We should allow calling a sync tool in the async path.
        return result

description() -> str classmethod

自定义类型的描述

Source code in dspy/adapters/types/base_type.py
@classmethod
def description(cls) -> str:
    """Description of the custom type"""
    return ""

extract_custom_type_from_annotation(annotation) classmethod

从注解中提取所有自定义类型。

这用于从字段的注解中提取所有自定义类型,而注解可以具有任意层级的嵌套。例如,我们检测到Toollist[dict[str, Tool]]中。

Source code in dspy/adapters/types/base_type.py
@classmethod
def extract_custom_type_from_annotation(cls, annotation):
    """Extract all custom types from the annotation.

    This is used to extract all custom types from the annotation of a field, while the annotation can
    have arbitrary level of nesting. For example, we detect `Tool` is in `list[dict[str, Tool]]`.
    """
    # Direct match. Nested type like `list[dict[str, Event]]` passes `isinstance(annotation, type)` in python 3.10
    # while fails in python 3.11. To accommodate users using python 3.10, we need to capture the error and ignore it.
    try:
        if isinstance(annotation, type) and issubclass(annotation, cls):
            return [annotation]
    except TypeError:
        pass

    origin = get_origin(annotation)
    if origin is None:
        return []

    result = []
    # Recurse into all type args
    for arg in get_args(annotation):
        result.extend(cls.extract_custom_type_from_annotation(arg))

    return result

format()

Source code in dspy/adapters/types/tool.py
def format(self):
    return str(self)

format_as_litellm_function_call()

Source code in dspy/adapters/types/tool.py
def format_as_litellm_function_call(self):
    return {
        "type": "function",
        "function": {
            "name": self.name,
            "description": self.desc,
            "parameters": {
                "type": "object",
                "properties": self.args,
                "required": list(self.args.keys()),
            },
        },
    }

from_langchain(tool: BaseTool) -> Tool classmethod

从LangChain工具构建一个DSPy工具。

参数:

名称 类型 描述 默认值
tool BaseTool

要转换的LangChain工具。

必填

返回:

类型 描述
Tool

一个工具对象。

示例:

import asyncio
import dspy
from langchain.tools import tool as lc_tool

@lc_tool
def add(x: int, y: int):
    "Add two numbers together."
    return x + y

dspy_tool = dspy.Tool.from_langchain(add)

async def run_tool():
    return await dspy_tool.acall(x=1, y=2)

print(asyncio.run(run_tool()))
# 3
Source code in dspy/adapters/types/tool.py
@classmethod
def from_langchain(cls, tool: "BaseTool") -> "Tool":
    """
    Build a DSPy tool from a LangChain tool.

    Args:
        tool: The LangChain tool to convert.

    Returns:
        A Tool object.

    Example:

    ```python
    import asyncio
    import dspy
    from langchain.tools import tool as lc_tool

    @lc_tool
    def add(x: int, y: int):
        "Add two numbers together."
        return x + y

    dspy_tool = dspy.Tool.from_langchain(add)

    async def run_tool():
        return await dspy_tool.acall(x=1, y=2)

    print(asyncio.run(run_tool()))
    # 3
    ```
    """
    from dspy.utils.langchain_tool import convert_langchain_tool

    return convert_langchain_tool(tool)

from_mcp_tool(session: mcp.client.session.ClientSession, tool: mcp.types.Tool) -> Tool classmethod

基于MCP工具和ClientSession构建一个DSPy工具。

参数:

名称 类型 描述 默认值
session ClientSession

要使用的MCP会话。

必填
tool Tool

要转换的MCP工具。

必填

返回:

类型 描述
Tool

一个工具对象。

Source code in dspy/adapters/types/tool.py
@classmethod
def from_mcp_tool(cls, session: "mcp.client.session.ClientSession", tool: "mcp.types.Tool") -> "Tool":
    """
    Build a DSPy tool from an MCP tool and a ClientSession.

    Args:
        session: The MCP session to use.
        tool: The MCP tool to convert.

    Returns:
        A Tool object.
    """
    from dspy.utils.mcp import convert_mcp_tool

    return convert_mcp_tool(session, tool)

serialize_model()

Source code in dspy/adapters/types/base_type.py
@pydantic.model_serializer()
def serialize_model(self):
    formatted = self.format()
    if isinstance(formatted, list):
        return f"{CUSTOM_TYPE_START_IDENTIFIER}{formatted}{CUSTOM_TYPE_END_IDENTIFIER}"
    return formatted

:::