OpenAI Functions Agent
概述
某些OpenAI模型(如gpt-3.5-turbo-0613和gpt-4-0613)已经过微调,可以检测何时应该调用特定的函数,并应该将该函数的正确输入进行响应。在API调用中,您可以描述想要调用的函数,然后让模型智能地选择输出包含调用这些函数所需参数的JSON对象。
在LangChain中,create_openai_functions_agent
是一个便捷的函数,用于创建能够与OpenAI提供的函数交互的代理。这使得开发人员可以创建智能应用程序,通过代理与用户进行更自然、更有效的对话。
配置环境变量
访问Tavily(用于在线搜索)注册账号并登录,获取API 密钥
设置OpenAI和TAVILY的API密钥
python
import os
# 设置OpenAI的BASE_URL、API_Key
os.environ["OPENAI_BASE_URL"] = "https://xxx.com/v1"
os.environ["OPENAI_API_KEY"] = "sk-BGFnOL9Q4c1234fsfsdaf9b4813bc437B82c2"
# 设置tavily
os.environ["TAVILY_API_KEY"] = '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'
基本使用
python
from langchain import hub
from langchain.agents import create_openai_functions_agent, AgentExecutor
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.messages import HumanMessage, AIMessage
from langchain_openai import ChatOpenAI
# 初始化工具
tools = [TavilySearchResults(max_results=1)]
# 获取使用的提示
prompt = hub.pull("hwchase17/openai-functions-agent")
# 选择将驱动代理的LLM
llm = ChatOpenAI(model="gpt-3.5-turbo-1106")
# 构建OpenAI函数代理
agent = create_openai_functions_agent(llm, tools, prompt)
# 通过传入代理和工具创建代理执行器
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 执行
agent_executor.invoke(
{
"input":"我叫什么名字?",
"chat_history":[
HumanMessage(content="你好!我叫鲍勃"),
AIMessage(content="你好鲍勃!我今天能帮你什么?"),],
}
)
实际应用示例
创建一个代理,它能够处理用户的常见问题,并且能够根据用户的问题进行动态响应。
python
from langchain import hub
from langchain.agents import create_openai_functions_agent, AgentExecutor
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
from langchain_core.tools import Tool
# 定义查询订单状态的函数
def query_order_status(order_id):
if order_id == "12345":
return "订单 12345 的状态是:已发货,预计送达时间是 3-5 个工作日。"
else:
return f"未找到订单 {order_id} 的信息,请检查订单号是否正确。"
# 定义退款政策说明函数
def refund_policy(keyword):
print("keyword = ", keyword)
return "我们的退款政策是:在购买后30天内可以申请全额退款,需提供购买凭证。"
# 初始化工具
tools = [TavilySearchResults(max_results=1),
Tool(
name="queryOrderStatus",
func=query_order_status,
description="根据订单ID查询订单状态"
),
Tool(
name="refundPolicy",
func=refund_policy,
description="查询退款政策内容"
),
]
# 获取使用的提示
prompt = hub.pull("hwchase17/openai-functions-agent")
# 选择将驱动代理的LLM
llm = ChatOpenAI(model="gpt-3.5-turbo-1106")
# 构建OpenAI函数代理
agent = create_openai_functions_agent(llm, tools, prompt)
# 通过传入代理和工具创建代理执行器
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 定义一些测试询问
queries = [
"请问订单12345的状态是什么?",
"你们的退款政策是什么?"
]
# 运行代理并输出结果
for input in queries:
response = agent_executor.invoke({"input": input})
print(f"客户提问:{input}")
print(f"代理回答:{response}\n")
OpenAI Tools Agent
概述
某些OpenAI模型可以检测何时应该调用一个或多个函数,并使用应该传递给函数的输入进行响应。在API调用中,可以描述函数,并让模型智能地选择输出包含参数的JSON对象来调用这些函数。这与函数调用非常相似。
OpenAI将调用单个函数的能力称为函数,将调用一个或多个函数的能力称为工具。
基本使用
python
from langchain import hub
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
# 使用Tavily搜索工具
tools = [TavilySearchResults(max_results=1)]
# 获取要使用的提示
prompt = hub.pull("hwchase17/openai-tools-agent")
# 初始化大模型
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
# 构建 OpenAI 工具代理
agent = create_openai_tools_agent(llm, tools, prompt)
# 通过传入代理和工具创建代理执行程序
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 运行代理
agent_executor.invoke({"input": "目前市场上黄金的平均售价是多少?"})
实际应用示例
创建一个能帮助用户进行搜索与获取天气信息的智能代理。
python
import requests
from langchain_core.tools import Tool
from langchain import hub
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
# 获取天气信息的函数
def get_weather(city):
url = f"https://xxx.com/api/weather?city={city}"
response = requests.get(url)
if response.status_code == 200:
jsonData = response.json()
data = jsonData['data']
type = data['type']
low = data['low']
high = data['high']
return f"{city} 的天气是 {type},最低温度是 {low}°C,最高温度是 {high}°C。"
else:
return "无法获取天气信息,请检查城市名称。"
# 初始化工具
tools = [TavilySearchResults(max_results=1),
Tool(
name="getWeather",
func=get_weather,
description="根据城市名称查询天气情况"
)]
# 获取要使用的提示
prompt = hub.pull("hwchase17/openai-tools-agent")
# 初始化大模型
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
# 构建 OpenAI 工具代理
agent = create_openai_tools_agent(llm, tools, prompt)
# 通过传入代理和工具创建代理执行程序
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 定义一些测试询问
queries = [
"成都今天天气情况?",
"目前市场上黄金的平均售价是多少?"
]
# 运行代理并输出结果
for input in queries:
response = agent_executor.invoke({"input": input})
print(f"提问:{input}")
print(f"回答:{response}\n")
ReAct Agent
概述
ReAct (Reflective Agent) 是 LangChain 中的一种聊天代理(Agent)类型。它具有以下独特的特点:
反思能力:ReAct 代理在给出响应之前,会先对自己的行为和预测进行深入的反思和评估。它会检查自己是否遵循了预先设定的规则和指令,是否达到了预期的目标。
自我纠错:如果ReAct代理在反思过程中发现自己存在问题或疏漏,它会主动尝试对自己的行为进行纠正和改正,以修复错误,提高自身的表现。
迭代学习:通过不断的反思和自我纠错,ReAct 代理可以在与用户的交互中逐步学习和优化自己的行为方式,不断提高回答的质量和准确性。
可解释性:ReAct 代理在给出最终响应时,会同时提供自己的思考过程和决策依据,使得它的行为更加透明和可解释。
ReAct 代理具有更强的自我意识和自我管理能力。它可以主动思考自己的行为,发现问题并及时修正,从而提供更加可靠和合理的响应。
这种具备反思和自我纠错能力的 ReAct 代理,在需要较高可靠性和稳定性的应用场景中很有优势,例如智能客服、问答系统、任务执行等。它可以通过持续的自我学习和优化,为用户提供更加智能和可信的交互体验。
Google搜索API
访问 SerpApi ,注册账号,选择相应的订阅计划(Free),然后获取API Key,利用这个API为大模型提供Google搜索工具。
安装SerpAPI库
arduino
pip install google-search-results -i https://pypi.org/simple
设置好OpenAI和SerpAPI的API密钥
python
import os
os.environ["OPENAI_BASE_URL"] = "https://xxx.com/v1"
os.environ["OPENAI_API_KEY"] = "sk-BGFnOL9Q4c99B9Q4c1234fsfsdaf9b4813bc437B82c2"
os.environ["SERPAPI_API_KEY"] = 'a871b9e551299Q4c1234fsfsdaf9b4813bc47233d796de36'
initialize_agent
python
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain_openai import ChatOpenAI
import langchain
# 开启DEBUG 显示具体的日志信息
# langchain.debug = True
# langchain.verbose = True
# 初始化大模型:语言模型控制代理
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
# 设置工具:加载使用的工具,serpapi:调用Google搜索引擎 llm-math:通过LLM进行数学计算的工具
tools = load_tools(["serpapi", "llm-math"], llm=llm)
# 初始化Agent:使用工具、语言模型和代理类型来初始化代理
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# 让代理来回答提出的问题
agent.invoke({"input": "目前市场上苹果手机15的平均售价是多少?如果我在此基础上加价5%卖出,应该如何定价?"})
大模型成功遵循了ReAct框架,它输出的思考与行动轨迹如下:
python
> Entering new AgentExecutor chain...
I need to find the average selling price of the iPhone 15 on the market and then calculate a 5% markup.
Action: Search
Action Input: "average selling price of iPhone 15"
Observation: How much does an iPhone 15 cost? iPhone 15 prices start at $535 and cost $716 on average as of April 2024. iPhone 15 prices will continue to get cheaper over time. Apple phones hold their value well, but prices will continue to drop as time passes and new models are announced.
Thought:I need to calculate a 5% markup on the average selling price of $716.
Action: Calculator
Action Input: 716 * 1.05
Observation: Answer: 751.8000000000001
Thought: I now know that if I add a 5% markup to the average selling price of iPhone 15, I should price it at $751.80.
Final Answer: $751.80
> Finished chain.
执行发现有如下警告:
initialize_agent
在新版本中不推荐使用并在将来会删除,推荐使用create_react_agent, create_json_agent, create_structured_chat_agent
等初始化Agent
python
LangChainDeprecationWarning: The function `initialize_agent` was deprecated in LangChain 0.1.0 and will be removed in 0.2.0. Use Use new agent constructor methods like create_react_agent, create_json_agent, create_structured_chat_agent, etc. instead.
warn_deprecated(
create_react_agent
python
# 加载所需的库
from langchain.agents import load_tools, AgentExecutor
from langchain.agents import create_react_agent
from langchain_openai import ChatOpenAI
from langchain import hub
# 初始化大模型:语言模型控制代理
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
# 设置工具:加载使用的工具,serpapi:调用Google搜索引擎 llm-math:通过LLM进行数学计算的工具
tools = load_tools(["serpapi", "llm-math"], llm=llm)
# 获取使用提示
prompt = hub.pull("hwchase17/react")
print(prompt)
# 初始化Agent:使用工具、语言模型和代理类型来初始化代理
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 让代理来回答提出的问题
agent_executor.invoke({"input": "目前市场上苹果手机15的平均售价是多少?如果我在此基础上加价5%卖出,应该如何定价?"})
python
> Entering new AgentExecutor chain...
I need to find the average selling price of the iPhone 15 on the current market and then calculate a 5% markup.
Action: Search
Action Input: "average selling price of iPhone 15"How much does an iPhone 15 cost? iPhone 15 prices start at $535 and cost $724 on average as of April 2024. iPhone 15 prices will continue to get cheaper over time. Apple phones hold their value well, but prices will continue to drop as time passes and new models are announced.I need to calculate a 5% markup on the average selling price of $724.
Action: Calculator
Action Input: $724 * 1.05Answer: 760.2I now know the final answer.
Final Answer: The average selling price of the iPhone 15 on the current market is $724. To sell it with a 5% markup, I should price it at $760.20.
> Finished chain.
使用聊天记录
python
# 与聊天记录一起使用
agent_executor.invoke(
{
"input": "what's my name?",
"chat_history": "Human: My name is Bob\nAI: Hello Bob!",
}
)
Structured Chat Agent
create_structured_chat_agent
是 LangChain 提供的一个函数,用于创建结构化聊天代理。这种代理能够根据用户的输入调用预定义的工具函数,并将结果返回给用户。
python
# 使用 Tavily Search 测试代理
from langchain_community.tools.tavily_search import TavilySearchResults
tools = [TavilySearchResults(max_results=1)]
# 初始化大模型
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(temperature=0.5)
# 创建代理Agent
from langchain.agents import create_structured_chat_agent, AgentExecutor
from langchain import hub
# 获取使用提示,也可以自己写
prompt = hub.pull("hwchase17/structured-chat-agent")
# 初始化Agent
agent = create_structured_chat_agent(
llm,
tools,
prompt
)
# 输入代理和工具,创建代理执行器
agent_executor = AgentExecutor(
agent=agent, tools=tools, verbose=True, handle_parsing_errors=True
)
# 运行代理Agent
response = agent_executor.invoke({"input": "网站https://www.runoob.com中有哪些教程?"})
print(response)
python
> Entering new AgentExecutor chain...
{
"action": "tavily_search_results_json",
"action_input": {
"query": "site:runoob.com 教程"
}
}[{'url': 'https://www.runoob.com/', 'content': '菜鸟教程(www.runoob.com)提供了编程的基础技术教程, 介绍了HTML、CSS、Javascript、Python,Java,Ruby,C,PHP , MySQL等各种编程语言的基础知识。 同时本站中也提供了大量的在线实例,通过实例,您可以更好的学习编程。'}]{
"action": "Final Answer",
"action_input": "菜鸟教程(www.runoob.com)提供了编程的基础技术教程,介绍了HTML、CSS、Javascript、Python,Java,Ruby,C,PHP,MySQL等各种编程语言的基础知识。同时本站中也提供了大量的在线实例,通过实例,您可以更好地学习编程。"
}
> Finished chain.
{'input': '网站https://www.runoob.com中有哪些教程?', 'output': '菜鸟教程(www.runoob.com)提供了编程的基础技术教程,介绍了HTML、CSS、Javascript、Python,Java,Ruby,C,PHP,MySQL等各种编程语言的基础知识。同时本站中也提供了大量的在线实例,通过实例,您可以更好地学习编程。'}
Self-Ask with Search Agent
Self-Ask with Search是一个通过搜索自我询问的代理,通过
询问+答案
的机制来帮助大模型寻找事实性问题的过渡性答案,从而引出最终答案。
python
from langchain import hub
from langchain.agents import AgentExecutor, create_self_ask_with_search_agent
from langchain_community.tools.tavily_search import TavilyAnswer
# 将初始化工具,让它提供答案而不是文档
tools = [TavilyAnswer(max_results=1, name="Intermediate Answer", description="Answer Search")]
# 初始化大模型
llm = ChatOpenAI(temperature=0)
# 获取使用提示 可以修改此提示
prompt = hub.pull("hwchase17/self-ask-with-search")
# 使用搜索代理构建自助询问
agent = create_self_ask_with_search_agent(llm, tools, prompt)
# 通过传入代理和工具创建代理执行程序
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
# 运行代理
agent_executor.invoke({"input": "中国有哪些省份呢?"})