从零开始学 LangChain(13) | 豆包MarsCode AI刷题

90 阅读6分钟

Agent代理

仅仅应用思维链推理并不能解决大模型的固有问题:无法主动更新自己的知识,导致出现事实幻觉。因为缺乏和外部世界的接触,大模型只拥有训练时见过的知识,以及提示信息中作为上下文提供的附加知识。如果你问的问题超出它的知识范围,要么大模型说不知道,要么它就会开始一本正经地胡说。

问题二解决办法:先让大模型先在本地知识库中进行搜索,检查一下提示中的信息的真实性,如果真实,再进行输出;如果不真实,则进行修正。如果本地知识库找不到相应的信息,可以调用工具进行外部搜索,来检查提示信息的真实性。

https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/048bf1370ada40abaa26685c18436bcc~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5bCP5p2o5ZCM5a2mNzY2:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjEzNzU0MDc2NzM4MDMwIn0%3D&rk3s=e9ecf3d6&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1732244911&x-orig-sign=GPBVREyZL2Mui06qwHhbfRBinZI%3D

上面所说的无论本地知识库还是搜索引擎,都不是封装在大模型内部的知识,我们把它们称为“外部工具”

代理的作用

每当你遇到这种需要模型做自主判断、自行调用工具、自行决定下一步行动的时候,Agent(也就是代理)就出场了。

代理就像一个多功能的接口,它能够接触并使用一套工具。根据用户的输入,代理会决定调用哪些工具。它不仅可以同时使用多种工具,而且可以将一个工具的输出数据作为另一个工具的输入数据。

在LangChain中使用代理,我们只需要理解下面三个元素。

  • 大模型:提供逻辑的引擎,负责生成预测和处理输入。

  • 与之交互的外部工具:可能包括数据清洗工具、搜索引擎、应用程序等。

  • 控制交互的代理:调用适当的外部工具,并管理整个交互过程的流程。

  • ReAct框架

    代理自主行动的驱动力—— ReAct框架。

    通过ReAct框架,大模型将被引导生成一个任务解决轨迹,即观察环境-进行思考-采取行动。 观察和思考阶段被统称为推理(Reasoning),而实施下一步行动的阶段被称为行动(Acting)。这个框架,也是大模型能够作为“智能代理”,自主、连续、交错地生成推理轨迹和任务特定操作的理论基础。在每一步推理过程中,都会详细记录下来,这也改善了大模型解决问题时的可解释性和可信度。

  • 在推理阶段,模型对当前环境和状态进行观察,并生成推理轨迹,从而使模型能够诱导、跟踪和更新操作计划,甚至处理异常情况。

  • 在行动阶段,模型会采取下一步的行动,如与外部源(如知识库或环境)进行交互并收集信息,或给出最终答案。

    ReAct框架的这些优点,使得它在未来的发展中具有巨大的潜力。随着技术的进步,我们可以期待ReAct框架将能够处理更多、更复杂的任务。特别是随着具身智能的发展,ReAct框架将能够使智能代理在虚拟或实际环境中进行更复杂的交互。例如,智能代理可能会在虚拟环境中进行导航,或者在实际环境中操作物理对象。这将大大扩展AI的应用范围,使得它们能够更好地服务于我们的生活和工作。

    示例:

    下面让我们用一个具体的示例来说明这一点。比如我给出大模型这样一个任务:在一个虚拟环境中找到一个胡椒瓶并将其放在一个抽屉里。

    在这个任务中,没有推理能力的模型不能够在房间的各个角落中进行寻找,或者在找到胡椒瓶之后不能够判断下一步的行动,因而无法完成任务。如果使用ReAct,这一系列子目标将被具体地捕获在每一个思考过程中。

    https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/9471b114abf64f6797bbf5534f8fabc4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5bCP5p2o5ZCM5a2mNzY2:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjEzNzU0MDc2NzM4MDMwIn0%3D&rk3s=e9ecf3d6&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1732244911&x-orig-sign=ZmTZvITk8bMpG3Q0yZZWLPqXfaU%3D

    现在,让我们回到开始的时候我们所面临的问题。仅仅使用思维链(CoT)提示,LLMs能够执行推理轨迹,以完成算术和常识推理等问题,但这样的模型因为缺乏和外部世界的接触或无法更新自己的知识,会导致幻觉的出现。

    https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/6f35faf655784e7aa5958b7cb10b3aec~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5bCP5p2o5ZCM5a2mNzY2:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjEzNzU0MDc2NzM4MDMwIn0%3D&rk3s=e9ecf3d6&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1732244911&x-orig-sign=MP8SE1d0oELRdQgHpB02oIw1z%2FA%3D

    而将 ReAct框架和思维链(CoT)结合使用,则能够让大模型在推理过程同时使用内部知识和获取到的外部信息,从而给出更可靠和实际的回应,也提高了 LLMs 的可解释性和可信度。

    LangChain正是通过Agent类,将ReAct框架进行了完美封装和实现,这一下子就赋予了大模型极大的自主性(Autonomy),你的大模型现在从一个仅仅可以通过自己内部知识进行对话聊天的 Bot,飞升为了一个有手有脚能使用工具的智能代理

    ReAct框架会提示 LLMs 为任务生成推理轨迹和操作,这使得代理能系统地执行动态推理来创建、维护和调整操作计划,同时还支持与外部环境(例如Google搜索、Wikipedia)的交互,以将额外信息合并到推理中。

    通过代理实现ReAct框架

    ZEROSHOTREACT_DESCRIPTION ——常用代理类型。

    ZEROSHOTREACT_DESCRIPTION类型的智能代理在LangChain中,自动形成了一个完善的思考与行动链条,而且给出了正确的答案。

    https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/6061ff7ea7f54f7fab349057b595e813~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5bCP5p2o5ZCM5a2mNzY2:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjEzNzU0MDc2NzM4MDMwIn0%3D&rk3s=e9ecf3d6&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1732244912&x-orig-sign=BaErenDGC4u%2BfNbohq9PxUmiVRg%3D

    这个思维链条中,智能代理有思考、有观察、有行动,成功通过搜索和计算两个操作,完成了任务。

    输入
# 导入所用库
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.llms import OpenAI

# 设置OpenAI和SERPAPI的API密钥
import os
os.environ["OPENAI_API_KEY"] = 'Your OpenAI API Key'
os.environ["SERPAPI_API_KEY"] = 'Your SerpAPI API Key'

#加载将用于控制代理的语言模型
llm = OpenAI(temperature=0)

加载一些要使用的工具,包括serpapi(这是调用Google搜索引擎的工具)以及llm-math(这是通过LLM进行数学计算的工具)。

tools = load_tools(["serpapi", "llm-math"], llm=llm)

使用工具、语言模型和代理类型来初始化代理。

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

运行代理。

agent.run("目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?")
输出:

https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/35eaedc8f99a4eceb03138f9a0c01d94~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5bCP5p2o5ZCM5a2mNzY2:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjEzNzU0MDc2NzM4MDMwIn0%3D&rk3s=e9ecf3d6&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1732244911&x-orig-sign=Y4%2FtDl5Uf7UaHPXkZQi1KdTTyCk%3D