1.结构化工具
2023年初,LangChain 引入了“多操作”代理框架,允许代理计划执行多个操作。在此基础上,LangChain 推出了结构化工具对话代理,允许更复杂、多方面的交互。
通过指定AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION 这个代理类型,代理能够调用包含一系列复杂工具的“结构化工具箱”,组合调用其中的多个工具,完成批次相关的任务集合。
playwright
- 开源的自动化框架
- 可以模拟真实用户操作网页,帮助开发者和测试者自动化网页交互和测试
- 支持多种浏览器
安装
pip install playwright
安装Playwright工具
playwright install
安装三种常用的浏览器工具
demo调用
导航到指定的URL;获取页面标题并打印页面的标题;最后关闭浏览器。
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()
2. 使用结构化工具对话代理
PlayWrightBrowserToolkit:LangChain中基于PlayWrightBrowser包封装的工具箱
使用代理类型:
STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION
对话提问:询问某URL的信息
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())
模型会选择调用 PlayWrightBrowserToolkit中的navigate_browser和get_elements工具。
debug
-
报错1
URL scheme must be 'http' or 'https' (type=value_error)
解决:在question的url加上https
-
报错2
bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
解决:
pip install lxml
-
报错3
from playwright.sync_api import sync_playwright ImportError: cannot import name 'sync_playwright' from 'playwright.sync_api'
-
解决:
1.确保playwright的安装;
2.确保当前目录没有文件命名为playwright.py
-
3.Self-Ask with Search 代理
利用一种叫做 “Follow-up Question(追问)”加“Intermediate Answer(中间答案)”的技巧,来辅助大模型寻找事实性问题的过渡性答案,从而引出最终答案。
agent=AgentType.SELF_ASK_WITH_SEARCH
import os
os.environ["SERPAPI_API_KEY"] = (
"your key"
)
llm = ChatOpenAI(
model=os.environ["LLM_MODELEND"],
base_url=os.environ["OPENAI_BASE_URL"],
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("使用玫瑰作为国花的国家的首都是哪里?")
通过大模型的两次follow-up追问,搜索工具给出了两个中间答案,最后给出了问题的最终答案——伦敦
4.Plan and execute 代理
- 计划由一个大语言模型代理(负责推理)完成。
- 执行由另一个大语言模型代理(负责调用工具)完成。
提问:"在纽约,100美元能买几束玫瑰?"
报错:
ValueError: unknown format from LLM: There is no specific value provided for the average price of roses in New York, so it's not possible to provide a specific expression and output for this question.
debug
-
“平均价格测试”
这个问题在使用
ZERO_SHOT_REACT_DESCRIPTION
代理,直接调用["serpapi", "llm-math"]时是可以完成的:目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?而在plan&excute代理当前代码会报错
ValueError: unknown format from LLM: 请你明确一下“平均价格”具体是多少,以便我能完整地进行计算和回答。
改成“价格”偶尔能运行成功,但仍有失误。
说明不是“平均”难以理解,而是代理没有正确触发搜索工具调用。
-
多运行几次,最终有结果->当前调用的llm不稳定
> Entering new PlanAndExecute chain...
steps=[Step(value='确定纽约玫瑰的平均价格。'), Step(value='用 100 美元除以玫瑰的平均价格,得到能购买的玫瑰束数。'), Step(value='给定以上步骤,回答用户关于在纽约 100 美元能买几束玫瑰的问题。\n')]
> Entering new AgentExecutor chain...
{
"action": "Search",
"action_input": "纽约玫瑰的平均价格"
}
> Finished chain.
*****
Step: 确定纽约玫瑰的平均价格。
Response: {
"action": "Search",
"action_input": "纽约玫瑰的平均价格"
}
> Entering new AgentExecutor chain...
Question: 用 100 美元除以玫瑰的平均价格,得到能购买的玫瑰束数。
Thought: 第一步查询到纽约玫瑰的平均价格为 1.5 美元,现在需要用 100 美元除以 1.5 美元来计算能购买的玫瑰束数。
Action:
```
{
"action": "Calculator",
"action_input": "100 / 1.5"
}
```
> Entering new LLMMathChain chain...
100 / 1.5```text
100 / 1.5
```
...numexpr.evaluate("100 / 1.5")...
Answer: 66.66666666666667
> Finished chain.
Observation: Answer: 66.66666666666667
Thought:Action:
```
{
"action": "Final Answer",
"action_input": "用 100 美元除以纽约玫瑰的平均价格 1.5 美元,得到能购买的玫瑰束数约为 66.67 束。"
}
```
> Finished chain.
*****
Step: 用 100 美元除以玫瑰的平均价格,得到能购买的玫瑰束数。
Response: 用 100 美元除以纽约玫瑰的平均价格 1.5 美元,得到能购买的玫瑰束数约为 66.67 束。
> Entering new AgentExecutor chain...
Thought: The previous steps have already calculated that with $100, one can buy approximately 66.67 bundles of roses in New York.
Action:
```
{
"action": "Final Answer",
"action_input": "在纽约 100 美元大约能买 66.67 束玫瑰。"
}
```
> Finished chain.
*****
Step: 给定以上步骤,回答用户关于在纽约 100 美元能买几束玫瑰的问题。
Response: 在纽约 100 美元大约能买 66.67 束玫瑰。
> Finished chain.