LangChain学习笔记:四、代理Agent和工具Tools的使用

前言

官方文档:代理(Agents)

前面有说到“链”,那么在链的组装过程中,我们还可能遇到几个问题,比如:

  1. 过程中我需要使用其他功能而不是AI来作为链中的一环(例如数据库操作、计算器)怎么办
  2. 如果我的链是需要判断逻辑,依据当前情况来决定下一步的话怎么办?

看看示例

工具的加载

from langchain.agents import load_tools
from langchain.llms import OpenAI
llm = OpenAI(temperature=0)
tools = load_tools(["serpapi", "llm-math"], llm=llm)

这个示例代码里,是通过函数load_tools加载了一些langchain包里内置的工具类,其中llm-math这个工具类用到了AI,所以需要将llm参数传递进去。
然后进去这个load_tools函数里看看,发现其实是用名字映射到了各个工具。

_LLM_TOOLS: Dict[str, Callable[[BaseLanguageModel], BaseTool]] = {
    "llm-math": _get_llm_math,
    "open-meteo-api": _get_open_meteo_api,
}
def _get_llm_math(llm: BaseLanguageModel) -> BaseTool:
    return Tool(
        name="Calculator",
        description="Useful for when you need to answer questions about math.",
        func=LLMMathChain.from_llm(llm=llm).run,
        coroutine=LLMMathChain.from_llm(llm=llm).arun,
    )

到这里,就可以看出工具类的定义和使用方式了:自定义工具

  • 名称(str),是必需的,并且必须在提供给代理的一组工具中是唯一的
  • 描述(str),是可选的,但建议使用,因为代理用于确定工具使用
  • return_direct(bool),默认为False
  • args_schema(Pydantic BaseModel), 是可选的,但建议使用,可以用于提供更多信息或验证预期参数。

上面还有指定一个coroutine参数,使用的是工具类的异步处理方法,我这边没有试过所以先暂时略过。

代理的使用

代理也分为很多种类,这里使用最简单的一种:
ZERO_SHOT_REACT_DESCRIPTION 仅基于工具的描述来确定要使用的工具
文档:代理类型

  • zero-shot-react-description
    此代理使用ReAct框架,仅基于工具的描述来确定要使用的工具。可以提供任意数量的工具,需要为每个工具提供描述。
  • react-docstore
    这个代理使用ReAct框架与文档存储进行交互。必须提供两个工具:一个Search工具和一个Lookup工具(它们必须被命名为这样)。Search工具应该搜索文档,而Lookup工具应该查找最近找到的文档中的一个术语。
  • self-ask-with-search
    这个代理使用一个被命名为Intermediate Answer的工具。这个工具应该能够查找问题的事实性答案。
  • conversational-react-description
    这个代理程序旨在用于对话环境中。提示设计旨在使代理程序有助于对话。 它使用ReAct框架来决定使用哪个工具,并使用内存来记忆先前的对话交互。

先用示例的内置计算器工具来实践

import include
from langchain.agents import initialize_agent, AgentType, load_tools
from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI(
    model="gpt-35-turbo",
    model_kwargs={"deployment_id": "gpt-35-turbo"},
    temperature=0,
)
# 加载默认工具
tools = load_tools(["llm-math"], llm=llm)
# 创建代理,传入工具、模型、代理类型,开启调试
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# 提问
rs = agent.run("Assume you are 12 years old now, what's your age raised to the 0.43 power?")
print(rs)

> Entering new AgentExecutor chain...
I need to use a calculator to raise my age to the 0.43 power.
Action: Calculator
Action Input: 12 ^ 0.43
Observation: Answer: 2.911038409866027
Thought:I now know my age raised to the 0.43 power.
Final Answer: 2.911038409866027

> Finished chain.
2.911038409866027

Process finished with exit code 0

从结果来看,由于这里只定义了一个计算器工具,因此agent也只会使用这一个工具。

自定义工具并使用

为了尝试一下代理Agent的选择功能,这里自定义一个新工具,看是否会自动选择

import include
from langchain import LLMMathChain
from langchain.agents import initialize_agent, AgentType
from langchain.chat_models import ChatOpenAI
from langchain.tools import Tool

llm = ChatOpenAI(
    model="gpt-35-turbo",
    model_kwargs={"deployment_id": "gpt-35-turbo"},
    temperature=0,
)

# 简单定义函数作为一个工具
def personal_info(name: str):
    info_list = {
        "Artorias": {
            "name": "Artorias",
            "age": 18,
            "sex": "Male",
        },
        "Furina": {
            "name": "Furina",
            "age": 16,
            "sex": "Female",
        },
    }
    if name not in info_list:
        return None
    return info_list[name]

# 自定义工具字典
tools = (
	# 这个就是上面的llm-math工具
    Tool(
        name="Calculator",
        description="Useful for when you need to answer questions about math.",
        func=LLMMathChain.from_llm(llm=llm).run,
        coroutine=LLMMathChain.from_llm(llm=llm).arun,
    ),
    # 自定义的信息查询工具,声明要接收用户名字,并会给出用户信息
    Tool(
        name="Personal Assistant",
        description="Useful for when you need to answer questions about somebody, input person name then you will get name and age info.",
        func=personal_info,
    )
)

agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

# 提问,询问Furina用户的年龄的0.43次方
rs = agent.run("What's the person Furina's age raised to the 0.43 power?")
print(rs)

可以看到代理会先思考说,首先需要获取Furina的年龄,因此要先使用能够查询用户信息的工具。
获取了用户信息后,代理发现已经获得了年龄信息,这时候需要使用计算器进行计算,于是调用了Calculator,得出最终结果。

> Entering new AgentExecutor chain...
I need to use the Personal Assistant tool to get Furina's age first.
Action: Personal Assistant
Action Input: Furina
Observation: {'name': 'Furina', 'age': 16, 'sex': 'Female'}
Thought:Now that I have Furina's age, I can use the calculator to raise it to the 0.43 power.
Action: Calculator
Action Input: 16^0.43
Observation: Answer: 3.2943640690702924
Thought:I now know the final answer.
Final Answer: 3.2943640690702924

> Finished chain.
3.2943640690702924

Process finished with exit code 0

到这里可以基本反映出来,非AI功能操作和AI功能操作可以通过工具+代理抉择的方式进行组装,从而形成一个以LLM为驱动核心的模块化处理应用,其效果的好坏完全取决于提示工程,也就是Prompts的好坏。

bad case

例如,如果我在工具描述里描述得模糊一些,不说明接收的参数,我们看看会发生什么

# 这是上面示例的自定义工具,现在我们去掉后面关于输入的描述,看看会发生什么
Tool(
	name="Personal Assistant",
    description="Useful for when you need to answer questions about somebody, input person name then you will get name and age info.",
    func=personal_info,
)

# 改成这样 
Tool(
	name="Personal Assistant",
    description="Useful for when you need to answer questions about somebody.",
    func=personal_info,
)

最终发生了报错,这是因为AI不知道工具输入的情况下,它直接对工具进行了提问“What is Furina’s age?”,而我们简易的自定义工具无法处理这种提问,因此没有给出回复,因此进一步的,代理不知道计算器该用什么数值进行计算。

> Entering new AgentExecutor chain...
I need to use the Personal Assistant tool to find out Furina's age.
Action: Personal Assistant
Action Input: "What is Furina's age?"
Observation: None
Thought:I need to use the Calculator tool to raise Furina's age to the 0.43 power.
Action: Calculator
Action Input: Furina's age ^ 0.43
Traceback (most recent call last):
……………………………………
……………………………………
各种报错
……………………………………
……………………………………
    raise ValueError(f"unknown format from LLM: {llm_output}")
ValueError: unknown format from LLM: I'm sorry, but the question is incomplete. Please provide the age of Furina or any other necessary information to form a complete mathematical expression.

Process finished with exit code 1
  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您可以在以下地址找到langchain的课程笔记:https://learn.deeplearning.ai/langchain-chat-with-your-data/lesson/1/introduction [1。在开始之前,您需要创建一个名为langchain的虚拟环境,并安装langchain和openai的包。首先,使用以下命令创建虚拟环境:conda create -n langchain python。然后激活该虚拟环境:conda activate langchain。接下来,安装langchain和openai的包:pip install langchain和pip install openai -i https://pypi.tuna.tsinghua.edu.cn/simple [2。在笔记中,您还需要调用llm的api。您可以使用以下代码进行调用: from langchain.agents import load_tools from langchain.agents import initialize_agent from langchain.agents import AgentType from langchain.llms import OpenAI from langchain.chat_models import ChatOpenAI from langchain.chains.conversation.memory import ConversationBufferWindowMemory OPENAI_API_KEY = '***********' llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY, temperature=0, model_name="gpt-3.5-turbo") [3。 通过这些步骤,您将能够开始学习langchain课程并使用llm的api进行聊天。祝您学习愉快!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [吴恩达ChatGPT《LangChain Chat with Your Data》笔记](https://blog.csdn.net/weixin_39653948/article/details/131874862)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Langchain学习笔记](https://blog.csdn.net/weixin_38226321/article/details/131062424)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值