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

news2024/9/21 11:14:25

13|代理(下):结构化工具对话、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 工具安装包,就使用它,还不行,会得到下面的信息。

img

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

img

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

from playwright.sync_api import sync_playwright

def run():
    # 使用Playwright上下文管理器
    with sync_playwright() as p:
        # 使用Chromium,但你也可以选择firefox或webkit
        browser = p.chromium.launch()
        
        # 创建一个新的页面
        page = browser.new_page()
        
        # 导航到指定的URL
        page.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 网页,然后手工去点击菜单栏、拉动进度条等。

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

img

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

使用结构化工具对话代理

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

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

其中具体的工具就包括:

img

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

from langchain.agents.agent_toolkits import PlayWrightBrowserToolkit
from langchain.tools.playwright.utils import create_async_playwright_browser

async_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 之后的第一轮思考如下:

img

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

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”: “[https://python.langchain.com](https://python.langchain.com/)”}}

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

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

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

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

第二轮思考

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

img

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

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 工具。

第三轮思考

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

img

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

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

  1. Introduction
  2. … …
  3. API reference

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

Action:

{
  "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 这个页面中各级标题的具体内容。

img

在这个过程中,结构化工具代理组合调用了 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 AgentType

llm = 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(
    "使用玫瑰作为国花的国家的首都是哪里?"  
)

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

img

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

多跳问题(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 LLMMathChain

search = 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美元能买几束玫瑰?")

输出如下:

img

img

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

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

相关文章

2024美赛数学建模常用数学建模模型之——层次分析法

一、层次分析法的基本原理与步骤 人们在进行社会的、经济的以及科学管理领域问题的系统分析中,面临的常常是 一个由相互关联、相互制约的众多因素构成的复杂而往往缺少定量数据的系统。层次 分析法为这类问题的决策和排序提供了一种新的、简洁而实用的建模方法。 …

GPU的硬件架构

SM: streaming Multiprocessor 流多处理器 sm里面有多个(sp)cuda core 32个线程称为一个warp,一个warp是一个基本执行单元 抽象概念:grid 网格 block 块 thread 线程 块中的线程大小是有讲究的,关乎到资源的调度,一般是128&#x…

macbook电脑2024免费好用的系统清理优化软件CleanMyMac X4.14.7

CleanMyMac X2024来帮助你找到和删除不需要的文件。CleanMyMac X是一款专业的mac清理软件,它可以智能地扫描你的磁盘空间,找出并删除大型和旧文件,系统垃圾,iTunes垃圾,邮件附件,照片库垃圾等,让…

【Vue2+3入门到实战】(22)VUE3之组合式API - setup、reactive和ref函数、computed、watch、生命周期函数详细讲解

目录 一、组合式API - setup选项1. setup选项的写法和执行时机2. setup中写代码的特点3. <script setup>语法糖 二、组合式API - reactive和ref函数1. reactive2. ref3. reactive 对比 ref 三、组合式API - computed四、组合式API - watch1. 侦听单个数据2. 侦听多个数据…

Java学习,一文掌握Java之SpringBoot框架学习文集(3)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

electron进程通信之预加载脚本和渲染进程对主进程通信

主进程和预加载脚本通信 主进程 mian,js 和预加载脚本preload.js,在主进程中创建预加载脚本, const createWindow () > {// Create the browser window.const mainWindow new BrowserWindow({width: 300,height: 300,// 指定预加载脚本webPreferences: {preload: path.j…

数据结构【查找篇】

数据结构【查找篇】 文章目录 数据结构【查找篇】前言为什么突然想学算法了&#xff1f;为什么选择码蹄集作为刷题软件&#xff1f; 目录一、顺序查找二、折半查找三、 二叉排序树的查找四、红黑树 结语 前言 为什么突然想学算法了&#xff1f; > 用较为“官方”的语言讲&am…

22 闪烁按钮

效果演示 实现了一个按钮的样式&#xff0c;包括背景颜色、边框、圆角、点击效果等。当鼠标悬停在按钮上时&#xff0c;按钮的背景颜色和文字颜色会发生变化&#xff0c;同时按钮会出现闪烁的效果。 Code <button class"btn"><svg height"24" wi…

UDP通信(服务器-客户端)

一、 UDP服务器-客户端通信 UDP&#xff08;User Datagram Protocol&#xff09;是一种面向无连接的传输层协议&#xff0c;它提供了一种简单的、不可靠的数据传输服务。与TCP&#xff08;Transmission Control Protocol&#xff09;不同&#xff0c;UDP不建立连接&#xff0c;…

奈奎斯特定理

奈奎斯特定理是通信领域中重要的理论基础之一&#xff0c;它对于数字通信系统中的信号采样和重构具有至关重要的作用。在数字信号处理和通信技术中&#xff0c;奈奎斯特定理的应用不仅具有理论意义&#xff0c;还对通信系统的设计、优化和性能提升起着重要的指导作用。本文将以…

MySQL8.0主从复制实现及遇到的个人问题

文章目录 1、准备两个服务器或者虚拟机2、主库配置3、从库配置4、配置过程中使用到的命令5、遇到的问题 1、准备两个服务器或者虚拟机 这里使用的VM虚拟机的Centos、MySQL版本是8.0.26、使用FinalShell进行远程操作。 2、主库配置 修改MySQL配置文件(/etc/my.cnf) #启用二进…

leetcode:1464. 数组中两元素的最大乘积(python3解法)

难度&#xff1a;简单 给你一个整数数组 nums&#xff0c;请你选择数组的两个不同下标 i 和 j&#xff0c;使 (nums[i]-1)*(nums[j]-1) 取得最大值。 请你计算并返回该式的最大值。 示例 1&#xff1a; 输入&#xff1a;nums [3,4,5,2] 输出&#xff1a;12 解释&#xff1a;如…

麒麟Kylin服务器版-破解root密码

一、单用户模式修改root密码 1.重启服务器系统后&#xff0c;将光标移动到第二项&#xff0c;按【e】键进入用户登录页面。 2.在【username】下方所在行输入root名称&#xff0c;【password】下方所在行输入密码Kylin123123后&#xff0c;进入编辑模式。代码如下&#xff1a; …

芯课堂 | MCU之TIMER精准延时

引言 华芯微特公司SWM系列单片机提供的TIMER个数和功能有些微差别&#xff0c;为了让您更加简单的使用这一功能&#xff0c;下面小编将以SWM190为例&#xff0c;给大家展示如何使用SWM系列产品的TIMER功能。 TIMER精准延时 一、TIMER简介 TIMER是一种定时器工具&#xff0c;…

C# 全屏label控件实现的贪吃蛇。

C# 全屏label控件实现的贪吃蛇。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using stat…

神经网络:激活函数的介绍

神经网络的激活函数是一种非线性函数&#xff0c;它被应用于每个神经元的输出&#xff0c;以引入非线性性质到网络中。 激活函数的目的是将输入转换为输出&#xff0c;并且将输出限制在特定的范围内。它们非常重要&#xff0c;因为线性变换&#xff08;例如加法和乘法&#xf…

七夕祭

title: 七夕祭 date: 2024-01-03 22:47:05 tags: 传送门 题目大意 解题思路 行的感兴趣的摊点或者列的感兴趣的摊点的数量能被行数或者列数整除&#xff0c;则能够实现要求。“均分”思想&#xff0c;设总感兴趣摊点数 T T T 和行数列数 n n n&#xff0c;当前感兴趣的摊点数…

ansible 配置jspgou商城上线(MySQL版)

准备环境 准备两台纯净的服务器进行&#xff0c;在实验之前我们关闭防火墙和selinux systemctl stop firewalld #关闭防火墙 setenforce 0 #临时关闭selinux hosts解析(两台服务器都要去做) [rootansible-server ~]# vim /etc/hosts 10.31.162.24 ansible-ser…

某和医院招采系统web端数据爬取, 逆向js

目标网址:https://zbcg.sznsyy.cn/homeNotice 测试时间: 2024-01-03 1 老规矩,打开Chrome无痕浏览,打开链接,监测网络,通过刷新以及上下翻页可以猜测出数据的请求是通过接口frontPageAnnouncementList获取的,查看返回可以看出来数据大概率是经过aes加密的,如图: 通过查看该请…

Spark Streaming的DStream与窗口操作

实时数据处理已经成为当今大数据时代的一个重要领域&#xff0c;而Spark Streaming是Apache Spark生态系统中的一个关键模块&#xff0c;用于处理实时数据流。本文将深入探讨Spark Streaming中的DStream&#xff08;离散流&#xff09;概念以及如何使用窗口操作来处理实时数据。…