Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOC: Custom Tool Error Handling is not Clear #10710

Closed
Hsgngr opened this issue Sep 17, 2023 · 4 comments
Closed

DOC: Custom Tool Error Handling is not Clear #10710

Hsgngr opened this issue Sep 17, 2023 · 4 comments
Labels
Ɑ: agent Related to agents module 🤖:docs Changes to documentation and examples, like .md, .rst, .ipynb files. Changes to the docs/ folder

Comments

@Hsgngr
Copy link

Hsgngr commented Sep 17, 2023

Issue with current documentation:

I cannot handle my custom_tool's raised errors.

I have this weatherTool:

class GetCurrentWeatherTool(BaseTool):
    name = "get_current_weather"
    description = "Get the current weather for a specified location"
    args_schema: Type[WeatherInput] = WeatherInput

    def _run(
        self, 
        location: str,
        run_manager: Optional[CallbackManagerForToolRun] = None
    ) -> str:
        """Use the tool."""
        return get_current_weather(location)

    async def _arun(
        self, 
        location: str,
        run_manager: Optional[AsyncCallbackManagerForToolRun] = None
    ) -> str:
        """Use the tool asynchronously."""
        # You can implement the async version of the method here or raise a NotImplementedError if async is not supported
        raise NotImplementedError("get_current_weather does not support async")

    def _handle_error(error: ToolException) -> str:
        return (
            "The following errors occurred during tool execution:"
            + error.args[0]
            + "Location couldn't be found, please try another tool."
        )

And I raise ToolException when the API call gets an error:
raise ToolException("location has been found.") inside of get_current_weather

Now I am adding this tool to my tools when I'm creating my agent:

self.weather = GetCurrentWeatherTool()
            Tool(
                 name="Weather",
                 func=self.weather.run,
                 description="useful for weather related questions",
                 return_direct=True,
             )

In the documentation Custom Tools it explains how to add it and gives an example:

    Tool.from_function(
        func=search_tool1,
        name="Search_tool1",
        description=description,
        handle_tool_error=True,
    ),

However I couldnt find the equal of that for Subclassing the BaseTool.

Idea or request for content:

It would be great to give an example for Subclassed CustomTool(BaseTool) when defining the tools.

@dosubot dosubot bot added Ɑ: agent Related to agents module 🤖:docs Changes to documentation and examples, like .md, .rst, .ipynb files. Changes to the docs/ folder labels Sep 17, 2023
@dosubot
Copy link

dosubot bot commented Sep 17, 2023

🤖

Hello,

Thank you for bringing this to our attention. I understand that you're having trouble handling errors for your custom tool that subclasses BaseTool. The handle_tool_error attribute is indeed used to handle exceptions that occur during the execution of a tool. It can be set to a boolean, a string, or a callable function.

Here's an example of how you can handle errors in your custom tool:

from langchain.tools.base import BaseTool, ToolException

class GetCurrentWeatherTool(BaseTool):
    name = "get_current_weather"
    description = "Get the current weather for a specified location"
    args_schema: Type[WeatherInput] = WeatherInput
    handle_tool_error = True  # or a string, or a callable

    def _run(
        self, 
        location: str,
        run_manager: Optional[CallbackManagerForToolRun] = None
    ) -> str:
        """Use the tool."""
        try:
            return get_current_weather(location)
        except Exception as e:
            # If an error occurs, raise a ToolException
            raise ToolException("An error occurred in GetCurrentWeatherTool") from e

    async def _arun(
        self, 
        location: str,
        run_manager: Optional[AsyncCallbackManagerForToolRun] = None
    ) -> str:
        """Use the tool asynchronously."""
        # You can implement the async version of the method here or raise a NotImplementedError if async is not supported
        raise NotImplementedError("get_current_weather does not support async")

In the run and arun methods of BaseTool, there is a try-except block that catches ToolException. If handle_tool_error is False, the exception is re-raised. If handle_tool_error is True, the first argument of the exception is used as the observation. If handle_tool_error is a string, that string is used as the observation. If handle_tool_error is a callable, it is called with the exception as an argument, and its return value is used as the observation.

If handle_tool_error is a callable, it should take one argument (the exception) and return the observation. Here's an example:

class GetCurrentWeatherTool(BaseTool):
    handle_tool_error = lambda e: f"An error occurred: {e}"
    # ... other methods and properties ...

In this example, if a ToolException is raised during the execution of the tool, the observation will be a string that includes the message of the exception.

I hope this helps! If you have any other questions, feel free to ask.

Best,
Dosu

Sources


This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.

@ahmadaii
Copy link

@Hsgngr How did you implemented this in pydantic based tool? I have similar question and till curious how to do that.

@greeshmaPremarajNathan
Copy link

I have added
except Exception as e:
# If an error occurs, raise a ToolException
raise ToolException("An error occurred") from e
except ValidationError as e:
# If an error occurs, raise a ToolException
raise ToolException("An error occurred") from e
and also put
handle_tool_error=True
but getting
File "/home/greeshma/anaconda3/envs/py3_10/lib/python3.10/site-packages/langchain_core/tools.py", line 262, in _parse_input
result = input_args.parse_obj(tool_input)
File "pydantic/main.py", line 526, in pydantic.main.BaseModel.parse_obj
File "pydantic/main.py", line 342, in pydantic.main.BaseModel.init
pydantic.error_wrappers.ValidationError: 4 validation errors for CreateCalenderEvent
start_date_time -> 1
invalid datetime format (type=value_error.datetime)
start_date_time -> 2
invalid datetime format (type=value_error.datetime)
end_date_time -> 1
invalid datetime format (type=value_error.datetime)
end_date_time -> 2
invalid datetime format (type=value_error.datetime)

@Abinandan314
Copy link

@Hsgngr Did you find any solution. If so, can you please post it here!

@dosubot dosubot bot added the stale Issue has not had recent activity or appears to be solved. Stale issues will be automatically closed label Jun 1, 2024
@dosubot dosubot bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 8, 2024
@dosubot dosubot bot removed the stale Issue has not had recent activity or appears to be solved. Stale issues will be automatically closed label Jun 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Ɑ: agent Related to agents module 🤖:docs Changes to documentation and examples, like .md, .rst, .ipynb files. Changes to the docs/ folder
Projects
None yet
Development

No branches or pull requests

4 participants