本篇主要用于记忆Agent相关代码,不对各个类型Agent的功能和原理进行描述。
文章目录
- 代理类型
- react
- plan&execute
- structured-chat
- 自定义代理
代理类型
react
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.llms import OpenAIllm = OpenAI(temperature=0)
tools = load_tools(["serpapi", "llm-math"], llm=llm)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?")
plan&execute
model = ChatOpenAI(temperature=0)
planner = load_chat_planner(model)
executor = load_agent_executor(model, tools, verbose=True)
agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)agent.run("在纽约,100美元能买几束玫瑰?")
structured-chat
结构化工具聊天代理能够使用多输入工具。
旧代理配置为将动作输入指定为单个字符串,但是该代理可以使用提供的工具的args_schema来填充动作输入。
这个功能可以使用代理类型 structured-chat-zero-shot-react-description 或 AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION 来实现
自定义代理
tools = get_tools("What is today weather")# Set up the base template
template = """Answer the following questions as best you can, but speaking as a pirate might speak. You have access to the following tools:{tools}Use the following format:Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input questionBegin! Remember to speak as a pirate when giving your final answer. Use lots of "Arg"sQuestion: {input}
{agent_scratchpad}"""from typing import Callable
# Set up a prompt template
class CustomPromptTemplate(StringPromptTemplate):# The template to usetemplate: str############## NEW ####################### The list of tools availabletools_getter: Callabledef format(self, **kwargs) -> str:# Get the intermediate steps (AgentAction, Observation tuples)# Format them in a particular wayintermediate_steps = kwargs.pop("intermediate_steps")thoughts = ""for action, observation in intermediate_steps:thoughts += action.logthoughts += f"\nObservation: {observation}\nThought: "# Set the agent_scratchpad variable to that valuekwargs["agent_scratchpad"] = thoughts############## NEW ######################tools = self.tools_getter(kwargs["input"])# Create a tools variable from the list of tools providedkwargs["tools"] = "\n".join([f"{tool.name}: {tool.description}" for tool in tools])# Create a list of tool names for the tools providedkwargs["tool_names"] = ", ".join([tool.name for tool in tools])return self.template.format(**kwargs)prompt = CustomPromptTemplate(template=template,tools_getter=tools,# This omits the `agent_scratchpad`, `tools`, and `tool_names` variables because those are generated dynamically# This includes the `intermediate_steps` variable because that is neededinput_variables=["input", "intermediate_steps"]
)class CustomOutputParser(AgentOutputParser):def parse(self, llm_output: str) -> Union[AgentAction, AgentFinish]:# Check if agent should finishif "Final Answer:" in llm_output:return AgentFinish(# Return values is generally always a dictionary with a single `output` key# It is not recommended to try anything else at the moment :)return_values={"output": llm_output.split("Final Answer:")[-1].strip()},log=llm_output,)# Parse out the action and action inputregex = r"Action\s*\d*\s*:(.*?)\nAction\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)"match = re.search(regex, llm_output, re.DOTALL)if not match:raise ValueError(f"Could not parse LLM output: `{llm_output}`")action = match.group(1).strip()action_input = match.group(2)# Return the action and action inputreturn AgentAction(tool=action, tool_input=action_input.strip(" ").strip('"'), log=llm_output)output_parser = CustomOutputParser()llm = ChatOpenAI(temperature=0)
# LLM chain consisting of the LLM and a prompt
llm_chain = LLMChain(llm=llm, prompt=prompt)tool_names = [tool.name for tool in tools]
agent = LLMSingleActionAgent(llm_chain=llm_chain, output_parser=output_parser,stop=["\nObservation:"], allowed_tools=tool_names
)
agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True)
agent_executor.run("What's the weather in SF?")
如果想将plan&execute中的Agent执行器替换为上面自己定义的Agent,可以使用下面代码:
model = ChatOpenAI(temperature=0)
planner = load_chat_planner(model)
executor = load_agent_executor(model, tools, verbose=True)
executor.chain.agent = agent_executor
agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)