diff --git a/libs/langchain/langchain/agents/output_parsers/openai_functions.py b/libs/langchain/langchain/agents/output_parsers/openai_functions.py index 9e6aa315e8..c6b4aadb71 100644 --- a/libs/langchain/langchain/agents/output_parsers/openai_functions.py +++ b/libs/langchain/langchain/agents/output_parsers/openai_functions.py @@ -44,7 +44,12 @@ class OpenAIFunctionsAgentOutputParser(AgentOutputParser): if function_call: function_name = function_call["name"] try: - _tool_input = json.loads(function_call["arguments"]) + if len(function_call["arguments"].strip()) == 0: + # OpenAI returns an empty string for functions containing no args + _tool_input = {} + else: + # otherwise it returns a json object + _tool_input = json.loads(function_call["arguments"]) except JSONDecodeError: raise OutputParserException( f"Could not parse tool input: {function_call} because " diff --git a/libs/langchain/tests/unit_tests/agents/output_parsers/test_openai_functions.py b/libs/langchain/tests/unit_tests/agents/output_parsers/test_openai_functions.py index d07d4775a0..613a486a4b 100644 --- a/libs/langchain/tests/unit_tests/agents/output_parsers/test_openai_functions.py +++ b/libs/langchain/tests/unit_tests/agents/output_parsers/test_openai_functions.py @@ -46,6 +46,22 @@ def test_func_call() -> None: assert result.message_log == [msg] +# Test: Model response with a function call for a function taking no arguments +def test_func_call_no_args() -> None: + parser = OpenAIFunctionsAgentOutputParser() + msg = AIMessage( + content="LLM thoughts.", + additional_kwargs={"function_call": {"name": "foo", "arguments": ""}}, + ) + result = parser.invoke(msg) + + assert isinstance(result, AgentActionMessageLog) + assert result.tool == "foo" + assert result.tool_input == {} + assert result.log == ("\nInvoking: `foo` with `{}`\nresponded: LLM thoughts.\n\n") + assert result.message_log == [msg] + + # Test: Model response with a function call (old style tools). def test_func_call_oldstyle() -> None: parser = OpenAIFunctionsAgentOutputParser()