From dc4ffa8d9b174ee8a0d2fa0294f5b34b9e64eb34 Mon Sep 17 00:00:00 2001 From: Swapnil Sharma Date: Tue, 20 Jun 2023 01:06:20 -0400 Subject: [PATCH] Incorrect argument count handling (#5543) Throwing ToolException when incorrect arguments are passed to tools so that that agent can course correct them. # Incorrect argument count handling I was facing an error where the agent passed incorrect arguments to tools. As per the discussions going around, I started throwing ToolException to allow the model to course correct. ## Before submitting ## Who can review? Community members can review the PR once tests pass. Tag maintainers/contributors who might be interested: --------- Co-authored-by: Harrison Chase --- langchain/tools/base.py | 2 +- tests/unit_tests/agents/test_tools.py | 3 ++- tests/unit_tests/tools/test_base.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/langchain/tools/base.py b/langchain/tools/base.py index ca3bebb0..c3fab242 100644 --- a/langchain/tools/base.py +++ b/langchain/tools/base.py @@ -394,7 +394,7 @@ class Tool(BaseTool): # For backwards compatibility. The tool must be run with a single input all_args = list(args) + list(kwargs.values()) if len(all_args) != 1: - raise ValueError( + raise ToolException( f"Too many arguments to single-input tool {self.name}." f" Args: {all_args}" ) diff --git a/tests/unit_tests/agents/test_tools.py b/tests/unit_tests/agents/test_tools.py index dd1be32f..371e48b8 100644 --- a/tests/unit_tests/agents/test_tools.py +++ b/tests/unit_tests/agents/test_tools.py @@ -14,6 +14,7 @@ from langchain.agents.mrkl.base import ZeroShotAgent from langchain.agents.react.base import ReActDocstoreAgent, ReActTextWorldAgent from langchain.agents.self_ask_with_search.base import SelfAskWithSearchAgent from langchain.agents.tools import Tool, tool +from langchain.tools.base import ToolException from tests.unit_tests.callbacks.fake_callback_handler import FakeCallbackHandler @@ -63,7 +64,7 @@ def test_tool_no_args_specified_assumes_str() -> None: assert some_tool.args == expected_args assert some_tool.run("foobar") == "foobar" assert some_tool.run({"tool_input": "foobar"}) == "foobar" - with pytest.raises(ValueError, match="Too many arguments to single-input tool"): + with pytest.raises(ToolException, match="Too many arguments to single-input tool"): some_tool.run({"tool_input": "foobar", "other_input": "bar"}) diff --git a/tests/unit_tests/tools/test_base.py b/tests/unit_tests/tools/test_base.py index 9f05faa0..e486fcc9 100644 --- a/tests/unit_tests/tools/test_base.py +++ b/tests/unit_tests/tools/test_base.py @@ -231,7 +231,7 @@ def test_structured_args_decorator_no_infer_schema() -> None: assert isinstance(structured_tool_input, BaseTool) assert structured_tool_input.name == "structured_tool_input" args = {"arg1": 1, "arg2": 0.001, "opt_arg": {"foo": "bar"}} - with pytest.raises(ValueError): + with pytest.raises(ToolException): assert structured_tool_input.run(args)