代理(下):结构化工具对话、Self-Ask with Search以及Plan and execute代理

在上一讲中,我们深入LangChain程序内部机制,探索了AgentExecutor究竟是如何思考(Thought)、执行(Execute/Act)和观察(Observe)的,这些步骤之间的紧密联系就是代理在推理(Reasoning)和工具调用过程中的“生死因果”。

现在我们趁热打铁,再学习几种更为复杂的代理:Structured Tool Chat(结构化工具对话)代理、Self-Ask with Search(自主询问搜索)代理、Plan and execute(计划与执行) 代理。

什么是结构化工具

LangChain的第一个版本是在 2022 年 11 月推出的,当时的设计是基于 ReAct 论文构建的,主要围绕着代理和工具的使用,并将二者集成到提示模板的框架中。

早期的工具使用十分简单,AgentExecutor引导模型经过推理调用工具时,仅仅能够生成两部分内容:一是工具的名称,二是输入工具的内容。而且,在每一轮中,代理只被允许使用一个工具,并且输入内容只能是一个简单的字符串。这种简化的设计方式是为了让模型的任务变得更简单,因为进行复杂的操作可能会使得执行过程变得不太稳定。

不过,随着语言模型的发展,尤其是出现了如 gpt-3.5-turbo 和 GPT-4 这样的模型,推理能力逐渐增强,也为代理提供了更高的稳定性和可行性。这就使得 LangChain 开始考虑放宽工具使用的限制。

2023年初,LangChain 引入了“多操作”代理框架,允许代理计划执行多个操作。在此基础上,LangChain 推出了结构化工具对话代理,允许更复杂、多方面的交互。通过指定AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION 这个代理类型,代理能够调用包含一系列复杂工具的“结构化工具箱”,组合调用其中的多个工具,完成批次相关的任务集合。

举例来说,结构化工具的示例包括:

  1. 文件管理工具集:支持所有文件系统操作,如写入、搜索、移动、复制、列目录和查找。
  2. Web 浏览器工具集:官方的 PlayWright 浏览器工具包,允许代理访问网站、点击、提交表单和查询数据。

下面,我们就以 PlayWright 工具包为例,来实现一个结构化工具对话代理。

先来看一看什么是 PlayWright 工具包。

什么是 Playwright

Playwright是一个开源的自动化框架,它可以让你模拟真实用户操作网页,帮助开发者和测试者自动化网页交互和测试。用简单的话说,它就像一个“机器人”,可以按照你给的指令去浏览网页、点击按钮、填写表单、读取页面内容等等,就像一个真实的用户在使用浏览器一样。

Playwright支持多种浏览器,比如Chrome、Firefox、Safari等,这意味着你可以用它来测试你的网站或测试应用在不同的浏览器上的表现是否一致。

下面我们先用 pip install playwright 安装Playwright工具。

不过,如果只用pip安装Playwright工具安装包,就使用它,还不行,会得到下面的信息。

因此我们还需要通过 playwright install 命令来安装三种常用的浏览器工具。

现在,一切就绪,我们可以通过Playwright浏览器工具来访问一个测试网页。

from playwright.sync_api import sync_playwrightdef run():# 使用Playwright上下文管理器with sync_playwright() as p:# 使用Chromium,但你也可以选择firefox或webkitbrowser = p.chromium.launch()# 创建一个新的页面page = browser.new_page()# 导航到指定的URLpage.goto('https://langchain.com/')# 获取并打印页面标题title = page.title()print(f"Page title is: {title}")# 关闭浏览器browser.close()if __name__ == "__main__":run()

这个简单的Playwright脚本,它打开了一个新的浏览器实例。过程是:导航到指定的URL;获取页面标题并打印页面的标题;最后关闭浏览器。

输出如下:

Page title is: LangChain

这个脚本展示了Playwright的工作方式,一切都是在命令行里面直接完成。它不需要我们真的去打开Chome网页,然后手工去点击菜单栏、拉动进度条等。

下面这个表,我列出了使用命令行进行自动化网页测试的优势。

现在你了解了Playwright这个工具包的基本思路,下面我们就开始使用它来作为工具集,来实现结构化工具对话代理。

使用结构化工具对话代理

在这里,我们要使用的Agent类型是STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION。要使用的工具则是PlayWrightBrowserToolkit,这是LangChain中基于PlayWrightBrowser包封装的工具箱,它继承自 BaseToolkit类。

PlayWrightBrowserToolkit 为 PlayWright 浏览器提供了一系列交互的工具,可以在同步或异步模式下操作。

其中具体的工具就包括:

下面,我们就来看看结构化工具对话代理是怎样通过组合调用PlayWrightBrowserToolkit中的各种工具,自动完成我们交给它的任务。

from langchain.agents.agent_toolkits import PlayWrightBrowserToolkit
from langchain.tools.playwright.utils import create_async_playwright_browserasync_browser = create_async_playwright_browser()
toolkit = PlayWrightBrowserToolkit.from_browser(async_browser=async_browser)
tools = toolkit.get_tools()
print(tools)from langchain.agents import initialize_agent, AgentType
from langchain.chat_models import ChatAnthropic, ChatOpenAI# LLM不稳定,对于这个任务,可能要多跑几次才能得到正确结果
llm = ChatOpenAI(temperature=0.5)  agent_chain = initialize_agent(tools,llm,agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,verbose=True,
)async def main():response = await agent_chain.arun("What are the headers on python.langchain.com?")print(response)import asyncio
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

在这个示例中,我们询问大模型,网页python.langchain.com中有哪些标题目录?

很明显,大模型不可能包含这个网页的内部信息,因为ChatGPT完成训练的那一年(2021年9月),LangChain还不存在。因此,大模型不可避免地需要通过PlayWrightBrowser工具来解决问题。

第一轮思考

代理进入AgentExecutor Chain之后的第一轮思考如下:

这里,我对上述思考做一个具体说明。

I can use the "navigate_browser" tool to visit the website and then use the "get_elements" tool to retrieve the headers. Let me do that.

这是第一轮思考,大模型知道自己没有相关信息,决定使用PlayWrightBrowserToolkit工具箱中的 navigate_browser 工具。

Action:```{"action": "navigate_browser", "action_input": {"url": "python.langchain.com"}}```

行动:通过Playwright浏览器访问这个网站。

Observation: Navigating to python.langchain.com returned status code 200

观察:成功得到浏览器访问的返回结果。

在第一轮思考过程中,模型决定使用PlayWrightBrowserToolkit中的navigate_browser工具。

第二轮思考

下面是大模型的第二轮思考。

还是对上述思考做一个具体说明。

Thought:Now that I have successfully navigated to the website, I can use the "get_elements" tool to retrieve the headers. I will specify the CSS selector for the headers and retrieve their text.

第二轮思考:模型决定使用PlayWrightBrowserToolkit工具箱中的另一个工具 get_elements,并且指定CSS selector只拿标题的文字。

Action: ```{"action": "get_elements", "action_input": {"selector": "h1, h2, h3, h4, h5, h6", "attributes": ["innerText"]}}```

行动:用Playwright的 get_elements 工具去拿网页中各级标题的文字。

Observation: [{"innerText": "Introduction"}, {"innerText": "Get started​"}, {"innerText": "Modules​"}, {"innerText": "Model I/O​"}, {"innerText": "Data connection​"}, {"innerText": "Chains​"}, {"innerText": "Agents​"}, {"innerText": "Memory​"}, {"innerText": "Callbacks​"}, {"innerText": "Examples, ecosystem, and resources​"}, {"innerText": "Use cases​"}, {"innerText": "Guides​"}, {"innerText": "Ecosystem​"}, {"innerText": "Additional resources​"}, {"innerText": "Support"}, {"innerText": "API reference​"}]

观察:成功地拿到了标题文本。

在第二轮思考过程中,模型决定使用PlayWrightBrowserToolkit中的get_elements工具。

第三轮思考

下面是大模型的第三轮思考。

对上述思考做一个具体说明。

Thought:The headers on python.langchain.com are:  

  1. Introduction ... ...
  2. API reference

第三轮思考:模型已经找到了网页中的所有标题。

Action:

 

json

复制代码

AI练中学

{   "action": "Final Answer",   "action_input": "The headers on python.langchain.com are: 1. Introduction 2. Get started 3. Modules 4. Model I/O 5. Data connection 6. Chains 7. Agents 8. Memory 9. Callbacks 10. Examples, ecosystem, and resources 11. Use cases 12. Guides 13. Ecosystem 14. Additional resources 15. Support 16. API reference" }

行动:给出最终答案。

AgentExecutor Chain结束之后,成功输出python.langchain.com这个页面中各级标题的具体内容。

在这个过程中,结构化工具代理组合调用了Playwright工具包中的两种不同工具,自主完成了任务。

使用 Self-Ask with Search 代理

讲完了Structured Tool Chat代理,我们再来看看Self-Ask with Search代理。

Self-Ask with Search 也是LangChain中的一个有用的代理类型(SELF_ASK_WITH_SEARCH)。它利用一种叫做 “Follow-up Question(追问)”加“Intermediate Answer(中间答案)”的技巧,来辅助大模型寻找事实性问题的过渡性答案,从而引出最终答案。

这是什么意思?让我通过示例来给你演示一下,你就明白了。在这个示例中,我们使用SerpAPIWrapper作为工具,用OpenAI作为语言模型,创建Self-Ask with Search代理。

from langchain import OpenAI, SerpAPIWrapper 
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentTypellm = OpenAI(temperature=0)
search = SerpAPIWrapper()
tools = [Tool(name="Intermediate Answer", func=search.run,description="useful for when you need to ask with search",)
]self_ask_with_search = initialize_agent(tools, llm, agent=AgentType.SELF_ASK_WITH_SEARCH, verbose=True
)
self_ask_with_search.run("使用玫瑰作为国花的国家的首都是哪里?"  
)

该代理对于这个问题的输出如下:

其实,细心的你可能会发现,“使用玫瑰作为国花的国家的首都是哪里?”这个问题不是一个简单的问题,它其实是一个多跳问题——在问题和最终答案之间,存在中间过程

多跳问题(Multi-hop question)是指为了得到最终答案,需要进行多步推理或多次查询。这种问题不能直接通过单一的查询或信息源得到答案,而是需要跨越多个信息点,或者从多个数据来源进行组合和整合。

也就是说,问题的答案依赖于另一个子问题的答案,这个子问题的答案可能又依赖于另一个问题的答案。这就像是一连串的问题跳跃,对于人类来说,解答这类问题可能需要从不同的信息源中寻找一系列中间答案,然后结合这些中间答案得出最终结论。

“使用玫瑰作为国花的国家的首都是哪里?”这个问题并不直接询问哪个国家使用玫瑰作为国花,也不是直接询问英国的首都是什么。而是先要推知使用玫瑰作为国花的国家(英国)之后,进一步询问这个国家的首都。这就需要多跳查询。

为什么 Self-Ask with Search 代理适合解决多跳问题呢?有下面几个原因。

  1. 工具集合:代理包含解决问题所必须的搜索工具,可以用来查询和验证多个信息点。这里我们在程序中为代理武装了SerpAPIWrapper工具。
  2. 逐步逼近:代理可以根据第一个问题的答案,提出进一步的问题,直到得到最终答案。这种逐步逼近的方式可以确保答案的准确性。
  3. 自我提问与搜索:代理可以自己提问并搜索答案。例如,首先确定哪个国家使用玫瑰作为国花,然后确定该国家的首都是什么。
  4. 决策链:代理通过一个决策链来执行任务,使其可以跟踪和处理复杂的多跳问题,这对于解决需要多步推理的问题尤为重要。

在上面的例子中,通过大模型的两次follow-up追问,搜索工具给出了两个中间答案,最后给出了问题的最终答案——伦敦。

使用 Plan and execute 代理

在这节课的最后,我再给你介绍一种比较新的代理类型:Plan and execute 代理。

计划和执行代理通过首先计划要做什么,然后执行子任务来实现目标。这个想法是受到 Plan-and-Solve 论文的启发。论文中提出了计划与解决(Plan-and-Solve)提示。它由两部分组成:首先,制定一个计划,并将整个任务划分为更小的子任务;然后按照该计划执行子任务。

这种代理的独特之处在于,它的计划和执行不再是由同一个代理所完成,而是:

  • 计划由一个大语言模型代理(负责推理)完成。
  • 执行由另一个大语言模型代理(负责调用工具)完成。

因为这个代理比较新,它隶属于LangChain的实验包langchain_experimental,所以你需要先安装langchain_experimental这个包。

pip install -U langchain langchain_experimental

下面我们来使用一下这个代理。在这里,我们创建了Plan and execute代理,这个代理和之前看到的代理不同,它有一个Planner,有一个Executor,它们可以是不同的模型。

当然,在这个示例中,我们都使用了ChatOpenAI模型。

from langchain.chat_models import ChatOpenAI
from langchain_experimental.plan_and_execute import PlanAndExecute, load_agent_executor, load_chat_planner
from langchain.llms import OpenAI
from langchain import SerpAPIWrapper
from langchain.agents.tools import Tool
from langchain import LLMMathChainsearch = SerpAPIWrapper()
llm = OpenAI(temperature=0)
llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=True)
tools = [Tool(name = "Search",func=search.run,description="useful for when you need to answer questions about current events"),Tool(name="Calculator",func=llm_math_chain.run,description="useful for when you need to answer questions about math"),
]
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美元能买几束玫瑰?")

输出如下:

 

在上面输出中,PlanAndExecute 链的调用流程以及代理的思考过程,我就留给你来做分析了,相信你可以把握住Plan and execute代理解决问题的基本脉络。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/18398.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

RPC-路由策略

为什么选择路由策略? 每次上线应用的时候都不止一台服务器会运行实例,那上线就涉及到变更,只要变更就可能导致原本正常运行的程序出现异常,尤其是发生重大变动的时候,导致应用不稳定的因素就变得很多。 灰度发布应用…

ctf日常

8&#xff0c; [NISACTF 2022]easyssrf 跨目录读取 NSSCTF{c42d6e04-f7cb-4ac4-925b-efd9b90c76ff} 9&#xff0c; [SWPUCTF 2021 新生赛]hardrce <?php header("Content-Type:text/html;charsetutf-8"); error_reporting(0); highlight_file(__FILE__); if(is…

Linux笔记---调试工具GDB(gdb)

1. gdb的概念 GDB&#xff0c;全称GNU Debugger&#xff0c;是一个功能强大的开源调试工具&#xff0c;广泛用于Unix和类Unix系统&#xff0c;以及Microsoft Windows和macOS平台。GDB允许开发者在程序执行过程中查看内部运行情况&#xff0c;帮助定位和修复程序中的错误。 gd…

服务架构的演进:从单体到微服务的探索之旅

服务架构的演进&#xff1a;从单体到微服务的探索之旅 一 . 服务架构演变1.1 单体架构1.2 分布式架构1.3 微服务1.4 小结 二 . 微服务技术对比2.1 微服务系统架构图2.2 微服务技术对比2.3 企业需求 三 . Spring Cloud 随着企业业务的不断拓展和复杂度的提升&#xff0c;对软件系…

【论文笔记】LLaMA-VID: An Image is Worth 2 Tokens in Large Language Models

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: LLaMA-VID: An Image is W…

leetcode_二叉树最大深度

对二叉树的理解 对递归调用的理解 对内存分配的理解 基础数据结构&#xff08;C版本&#xff09; - 飞书云文档 每次函数的调用 都会进行一次新的栈内存分配 所以lmax和rmax的值不会混在一起 /*** Definition for a binary tree node.* struct TreeNode {* int val;* …

【模拟仿真】基于区间观测器的故障诊断与容错控制

摘要 本文提出了一种基于区间观测器的故障诊断与容错控制方法。该方法通过构建区间观测器&#xff0c;实现对系统状态的上下边界估计&#xff0c;从而在存在不确定性和外部噪声的情况下进行高效的故障诊断。进一步地&#xff0c;本文设计了一种容错控制策略&#xff0c;以保证…

Ubuntu24.04LTS在线安装Docker引擎

Ubuntu24.04LTS在线安装Docker引擎 文章目录 Ubuntu24.04LTS在线安装Docker引擎1. 官网教程2. 安装Docker引擎1. 卸载旧版本2. 使用存储库apt安装1. 设置Docker的APT仓库(官网)2. 设置Docker的APT仓库(阿里云-推荐) 3. 安装1. 安装最新版2. 安装指定的版本 1. 官网教程 官网安…

directed-map cache简单示例

这张图的地址映射是基于直接映射缓存的策略进行的&#xff0c;以下是详细解释&#xff1a; 直接映射缓存的映射方式 缓存块号 (Cache Block Number): 使用公式 Cache块号 主存块号 % 缓存块总数 来决定主存地址在哪个缓存块中存储。比如&#xff0c;这里 Cache块总数 4&#…

SpringBoot配置相关的内容

依赖Starter和Parent 查依赖坐标网站&#xff1a;Maven Repository: Search/Browse/Explorehttps://mvnrepository.com/ 设置配置文件 配置文件相关的配置 yml多个数据的书写 配置文件的读取

基于Python的仓库管理系统设计与实现

背景&#xff1a; 基于Python的仓库管理系统功能介绍 本仓库管理系统采用Python语言开发&#xff0c;利用Django框架和MySQL数据库&#xff0c;实现了高效、便捷的仓库管理功能。 用户管理&#xff1a; 支持员工和管理员角色的管理。 用户注册、登录和权限分配功能&#x…

使用tauri + naiveAdmin 构建桌面应用程序

非常好的如何部署naiveAdmin的文档笔记: 非常详细的 https://sx-code.github.io/wiki/adminpro/02_project_prepare/04_%E9%A1%B9%E7%9B%AE%E8%AE%BE%E7%BD%AE.html 阅读原码ing 前端框架 NaiveUiAdmin Rust 数据处理 ing … Mysql 数据库使用 ing …

RGB与YCbCr转换算法

目录 RGB与YCbCr转换算法RGB与YCbCr色域介绍RGB模型YCbCr色域简介YCbCr的应用YUV 和 YCbCr 的区别 色彩转换公式 RGB 转 YCbCr 实现RGB 转 YCbCr 的 Matlab 实现RGB 转 YCbCr 的 FPGA 实现 YCbCr 转 RGB 实现YCbCr 转 RGB 的 Matlab 实现YCbCr 转 RGB 的 FPGA 实现 RGB与YCbCr转…

【STM32】I2C通信协议

文章目录 I2C通信协议简介I2C协议硬件规定I2C协议软件规定I2C时序基本单元I2C典型时序 参考 STM32硬件I2C与软件模拟I2C超详解 I2C通信协议简介 I2C 也叫 IC、IIC (Inter-Integrated Circuit) &#xff0c;集成电路总线是由 Phiilps 公司开发的两线式串行总线&#xff0c;用于…

大数据挖掘

大数据挖掘 数据挖掘 数据挖掘定义 技术层面&#xff1a; 数据挖掘就是从大量的、不完全的、有噪声的、模糊的、随机的实际应用数据中&#xff0c;提取隐含在其中、人们事先不知道的、但又潜在有用的信息的过程。 数据准备环节 数据选择 质量分析 数据预处理 数据仓库 …

leetcode101:对称二叉树

给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false提示&#xff1a; 树中节点数目在范围…

湘潭大学软件工程算法设计与分析考试复习笔记(一)

文章目录 前言随机类&#xff08;第七章&#xff09;随机概述数值随机化舍伍德拉斯维加斯蒙特卡罗 模拟退火遗传人工神经网络 回溯&#xff08;第五章&#xff09;动态规划&#xff08;第四章&#xff09;后记 前言 考试还剩十一天&#xff0c;现在准备开始复习这门课了。好像全…

Win11专业版Docker安装、配置记录

零&#xff0c;系统环境配置 首先&#xff0c;安装Docker需要系统支持开启硬件虚拟化及Hyper-V功能&#xff0c;所以这里需要Win10/11的专业版&#xff0c;这样才能进行Docker for Windows软件安装。 1&#xff0c;硬件虚拟化 至于如何开启硬件虚拟化&#xff0c;自行百度即…

【Android】线程池的初见

引言 在Android当中根据用途分为主线程与子线程&#xff0c;主线程当中主要处理与界面相关的操作&#xff0c;子线程主要进行耗时操作。除了Thread本身以外&#xff0c;在Android当中还有很多扮演者线程的角色&#xff0c;比如AsyncTask&#xff08; 底层为线程池&#xff0c;…

春秋云镜-2022网鼎杯

flag1 进入网站&#xff0c;发现是wordpress&#xff0c;这种一般都不会有啥直接漏洞&#xff0c;应该是插件漏洞&#xff0c;或者弱口令 fscan扫描ip 好像没扫出啥东西 wp-login进入后台 爆破密码&#xff0c;弱口令admin&#xff0c;123456&#xff0c;之前lazysysadmin好…