Source code for langchain.agents.output_parsers.openai_functions

import json
from json import JSONDecodeError
from typing import List, Union

from langchain_core.agents import AgentAction, AgentActionMessageLog, AgentFinish
from langchain_core.exceptions import OutputParserException
from langchain_core.messages import (
    AIMessage,
    BaseMessage,
)
from langchain_core.outputs import ChatGeneration, Generation

from langchain.agents.agent import AgentOutputParser


[docs]class OpenAIFunctionsAgentOutputParser(AgentOutputParser): """将消息解析为代理动作/完成。 旨在与OpenAI模型一起使用,因为它依赖于OpenAI的特定function_call参数来传达要使用的工具。 如果传递了function_call参数,则将使用该参数获取工具和工具输入。 如果没有传递参数,则假定AIMessage是最终输出。""" @property def _type(self) -> str: return "openai-functions-agent" @staticmethod def _parse_ai_message(message: BaseMessage) -> Union[AgentAction, AgentFinish]: """解析一个AI消息。""" if not isinstance(message, AIMessage): raise TypeError(f"Expected an AI message got {type(message)}") function_call = message.additional_kwargs.get("function_call", {}) if function_call: function_name = function_call["name"] try: 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"], strict=False) except JSONDecodeError: raise OutputParserException( 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_input content_msg = f"responded: {message.content}\n" if message.content else "\n" log = f"\nInvoking: `{function_name}` with `{tool_input}`\n{content_msg}\n" return AgentActionMessageLog( tool=function_name, tool_input=tool_input, log=log, message_log=[message], ) return AgentFinish( return_values={"output": message.content}, log=str(message.content) )
[docs] def parse_result( self, result: List[Generation], *, partial: bool = False ) -> Union[AgentAction, AgentFinish]: if not isinstance(result[0], ChatGeneration): raise ValueError("This output parser only works on ChatGeneration output") message = result[0].message return self._parse_ai_message(message)
[docs] def parse(self, text: str) -> Union[AgentAction, AgentFinish]: raise ValueError("Can only parse messages")