LangChain里的Agent实现
官方模块介绍文档:Agents — 🦜🔗 LangChain 0.0.191
官网API文档:Agents — 🦜🔗 LangChain 0.0.191
核心要点:
(1)需要依赖于用户输入的未知链。——区别于预先定义的调用链
(2)端到端方式
可参考资料:
问题迭代过程讲解博客1:ChatGPT|LangChain Agent原理介绍 - 掘金
问题迭代过程讲解博客2(感觉说的更加清楚明白):LangChain Agent 执行过程解析 OpenAI_YezIwnl的博客-CSDN博客
关键组件
AgentExecutor(执行者)
文档:Agent Executor | 🦜️🔗 LangChain
源代码:langchain.agents.agent — 🦜🔗 LangChain 0.0.191
说明:AgentExecutor
在很大程度上可以被认为是一个使用SingleActionAgent
循环(详见函数_take_next_step):
- 将用户输入和任何先前的步骤传递给代理
- 如果代理返回一个
AgentFinish
,则直接将其返回给用户 - 如果 Agent 返回一个(或者多个)
AgentAction
,则使用它来调用一个工具并获得一个Observation
(如果是多个,则多轮调用 将得到的Observation放入Result的List中) - 重复,将
AgentAction
和传递Observation
回代理,直到AgentFinish
发出
核心函数:_take_next_step
def _take_next_step(self,name_to_tool_map: Dict[str, BaseTool],color_mapping: Dict[str, str],inputs: Dict[str, str],intermediate_steps: List[Tuple[AgentAction, str]],) -> Union[AgentFinish, List[Tuple[AgentAction, str]]]:"""Take a single step in the thought-action-observation loop.Override this to take control of how the agent makes and acts on choices."""# Call the LLM to see what to do.output = self.agent.plan(intermediate_steps, **inputs)# If the tool chosen is the finishing tool, then we end and return.if isinstance(output, AgentFinish):return outputactions: List[AgentAction]if isinstance(output, AgentAction):actions = [output]else:actions = outputresult = []for agent_action in actions:self.callback_manager.on_agent_action(agent_action, verbose=self.verbose, color="green")# Otherwise we lookup the toolif agent_action.tool in name_to_tool_map:tool = name_to_tool_map[agent_action.tool]return_direct = tool.return_directcolor = color_mapping[agent_action.tool]tool_run_kwargs = self.agent.tool_run_logging_kwargs()if return_direct:tool_run_kwargs["llm_prefix"] = ""# We then call the tool on the tool input to get an observationobservation = tool.run(agent_action.tool_input,verbose=self.verbose,color=color,**tool_run_kwargs,)else:tool_run_kwargs = self.agent.tool_run_logging_kwargs()observation = InvalidTool().run(agent_action.tool,verbose=self.verbose,color=None,**tool_run_kwargs,)result.append((agent_action, observation))return result
循环跳出条件(满足一项即可):
(1)self._take_next_step()返回AgentFinish类型,代表agent已经判定当前active可以finish,
(2)self._get_tool_return()返回一个AgentFinish,代表调用的工具已被标记直接返回结果(name_to_tool_map[agent_action.tool].return_direct)
llm = OpenAI(temperature=0)
tools = [SearchTool(), CalculatorTool()]
agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)
print("问题:")
print("答案:" + agent.run("告诉我'鸡你太美'是什么意思"))
- react-docstore 使用react框架, 和docstore交互, 使用Search和Lookup工具, 前者用来搜, 后者寻找term, 举例: Wipipedia工具
- self-ask-with-search 此代理只使用一个工具: Intermediate - Answer, 它会为问题寻找事实答案(指的非gpt生成的答案, 而是在网络中,文本中已存在的), 如 Google search API 工具
- conversational-react-description 为会话设置而设计的代理, 它的prompt会被设计的具有会话性, 且还是会使用 ReAct框架来决定使用来个工具, 并且将过往的会话交互存入内存.
使用过程:
可以直接调用langchain.agents.initialize(https://python.langchain.com/en/latest/_modules/langchain/agents/initialize.html?highlight=initialize_agent#)
from langchain.agents import initialize_agent
from langchain.llms import OpenAI
from CustomTools import WeatherTool
from CustomTools import CustomCalculatorToolllm = OpenAI(temperature=0)tools = [WeatherTool(), CustomCalculatorTool()]agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)agent.run("Query the weather of this week,And How old will I be in ten years? This year I am 28")
Agent类型-预置的Agent
zero-shot-react-description
(1)最常用 基于React
(2)根据工具的描述, 和请求的string 来决定使用哪个工具(最基础的Aagent流程)
llm = OpenAI(temperature=0) tools = [SearchTool(), CalculatorTool()] agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)print("问题:") print("答案:" + agent.run("告诉我'鸡你太美'是什么意思"))
react-docstore
使用react框架, 和docstore交互, 使用Search
和Lookup
工具, 前者用来搜, 后者寻找term, 举例: Wipipedia工具
self-ask-with-search
此代理只使用一个工具: Intermediate Answer, 它会为问题寻找事实答案(指的非gpt生成的答案, 而是在网络中,文本中已存在的), 如 Google search API
工具
conversational-react-description
为会话设置而设计的代理, 它的prompt会被设计的具有会话性, 且还是会使用 ReAct框架来决定使用来个工具, 并且将过往的会话交互存入内存.
使用过程:可以直接调用langchain.agents.initialize(langchain.agents.initialize — 🦜🔗 LangChain 0.0.191)
from langchain.agents import initialize_agent
from langchain.llms import OpenAI
from CustomTools import WeatherTool
from CustomTools import CustomCalculatorToolllm = OpenAI(temperature=0)tools = [WeatherTool(), CustomCalculatorTool()]agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)agent.run("Query the weather of this week,And How old will I be in ten years? This year I am 28")
initialize_agent内部调用agent_cls.from_llm_and_tools,返回一个AgentExecutor(默认为zero-shot-react-description
)