[docs]classOpenAIFunctionsAgentOutputParser(AgentOutputParser):"""Parses a message into agent action/finish. Is meant to be used with OpenAI models, as it relies on the specific function_call parameter from OpenAI to convey what tools to use. If a function_call parameter is passed, then that is used to get the tool and tool input. If one is not passed, then the AIMessage is assumed to be the final output. """@propertydef_type(self)->str:return"openai-functions-agent"@staticmethoddef_parse_ai_message(message:BaseMessage)->Union[AgentAction,AgentFinish]:"""Parse an AI message."""ifnotisinstance(message,AIMessage):raiseTypeError(f"Expected an AI message got {type(message)}")function_call=message.additional_kwargs.get("function_call",{})iffunction_call:function_name=function_call["name"]try:iflen(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"],strict=False)exceptJSONDecodeError:raiseOutputParserException(f"Could not parse tool input: {function_call} because "f"the `arguments` is not valid JSON.")# HACK HACK HACK:# The code that encodes tool input into Open AI uses a special variable# name called `__arg1` to handle old style tools that do not expose a# schema and expect a single string argument as an input.# We unpack the argument here if it exists.# Open AI does not support passing in a JSON array as an argument.if"__arg1"in_tool_input:tool_input=_tool_input["__arg1"]else:tool_input=_tool_inputcontent_msg=f"responded: {message.content}\n"ifmessage.contentelse"\n"log=f"\nInvoking: `{function_name}` with `{tool_input}`\n{content_msg}\n"returnAgentActionMessageLog(tool=function_name,tool_input=tool_input,log=log,message_log=[message],)returnAgentFinish(return_values={"output":message.content},log=str(message.content))
[docs]defparse_result(self,result:List[Generation],*,partial:bool=False)->Union[AgentAction,AgentFinish]:ifnotisinstance(result[0],ChatGeneration):raiseValueError("This output parser only works on ChatGeneration output")message=result[0].messagereturnself._parse_ai_message(message)
[docs]defparse(self,text:str)->Union[AgentAction,AgentFinish]:raiseValueError("Can only parse messages")