
如何快速实现REST API集成以优化业务流程
Agent的推理引擎是其规划和决策制定过程以及调用工具执行行动的核心。
在各种论文中,研究人员提出了多种智能Agent的推理逻辑(也称认知框架或框架),如CoT、ToT、LLM+P等。其中,ReAct框架脱颖而出,被LangChain和LlamaIndex等多种AI应用开发工具作为推理引擎。它提供了一个强大而灵活的结构,用于开发能够进行复杂推理和有效行动的Agent。
ReAct框架是围绕理解和回应用户输入的基本思想构建的。这种方法着重于让大模型在收到任务后进行思考,然后决定采取的行动。
它不是那个流行的前端开发框架React。这里的ReAct是指导大模型推理和行动的一种认知框架,2023年刚刚在一篇论文中被提出。
ReAct框架的核心在于将推理和行动紧密结合起来。在动态和不确定的环境中,有效的决策需要持续的学习和适应,以及快速将推理转化为行动的能力,即形成有效的观察—思考—行动—再观察的循环。
1. 思考(Thought):涉及对下一个行动进行推理。在这一步骤中需要评估当前情况并考虑可能的行动方案。
2. 行动(Action):基于思考的结果,决定采取什么行动。这一步骤是行动计划的选择过程。
3. 观察(Observation):执行行动后,需要观察并收集反馈。这一步骤将对行动结果进行评估。它可能影响或改变下一轮次思考的方向。
不难发现,ReAct框架精髓就在于通过循环来实现一个连续的学习和适应过程,即制定流程、进行决策并解决问题。如下图所示,Agent首先接到任务,然后自动进行推理,最后自主调用工具来完成任务。
1. 任务:Agent的起点是一个任务,如一个用户查询、一个目标或一个需要解决的特定问题。
2. 大模型:任务被输入大模型中。大模型使用训练好的模型进行推理。这个过程涉及理解任务、生成解决方案的步骤或其他推理活动。
3. 工具:大模型可能会决定使用一系列的工具来辅助完成任务。这些工具可能是API调用、数据库查询或者任何可以提供额外信息和执行能力的资源。
4. 行动:Agent根据大模型的推理结果采取行动。例如与环境直接交互、发送请求、操作物理设备或更改数据等。
5. 环境:行动会影响环境,而环境将以某种形式响应这些行动。这个响应被称为结果,它可能是任务的完成、一个新的数据点或其他类型的输出。
6. 结果:将行动导致的结果反馈给Agent。这个结果可能会影响Agent未来的行为,因为Agent执行任务是一个不断学习和适应的过程,直至目标任务完全解决。
LangChain强调,大模型的推理能力加上工具的功能,形成了Agent的能力内核。在Agent内部,大模型被用作推理引擎以确定采取哪些操作以及按什么顺序执行这些操作。
这也体现了大模型应用开发的核心理念:操作的序列并非硬编码在代码中,而是使用大模型来选择执行的操作序列。这凸显了大模型作为AI自主决定应用程序逻辑这个编程新范式的价值。
空谈误国,实干兴邦。下面通过开源AI应用开发框架LangChain,用不到50行代码来实现一个会自主搜索并总结目前Agent科研领域最新进展的Agent。
这里说一下,因为黄佳老师在国外,用OPENAI的API_KEY比较方便,我们在国内使用为了免除科学上网和OPENAI充值的麻烦,这里选择了用KIMI的API_KEY代替,所用的接口基本一样。
在开始之前,我们需要做一些准备工作。首先在KIMI官网和SerpApi网站分别注册账号,并获取KIMI_API_KEY和SERPAPI_API_KEY(此处需要科学上网)。
然后需要安装好以下这些依赖库:
pip install langchain
pip install langchainhub
pip install langchain-openai
pip install OpenAI
pip install google-search-results
接下来,我们先给出完整的代码,再分步拆解一下:
import os
# 设置API_KEY
os.environ['KIMI_API_KEY'] = '您的KIMI的API_KEY或者其他公司的API_KEY也行'
os.environ['SERPAPI_API_KEY'] = '您的serpapi的API_KEY'
# 导入LangChain Hub
from langchain import hub
# 从LangChain Hub中获取ReAct的提示
prompt = hub.pull("hwchase17/react")
print(prompt)
from langchain_openai import ChatOpenAI # 修改导入语句
llm = ChatOpenAI(
model_name="moonshot-v1-8k", # KIMI的模型名称
api_key=os.getenv('KIMI_API_KEY'), # 使用环境变量获取API_KEY
base_url="https://api.moonshot.cn/v1", # 修复了base_url字符串的引号问题
temperature=0.7
)
# 导入SerpAPIWrapper即工具包
from langchain_community.utilities import SerpAPIWrapper
from langchain.agents import Tool
# 实例化SerpAPIWrapper,不要传递 api_key 参数
search = SerpAPIWrapper()
# 准备工具列表
tools = [
Tool(
name="Search",
func=search.run,
description="当大模型没有相关知识时,用于搜索知识"
),
]
# 导入create_react_agent功能
from langchain.agents import create_react_agent
# 构建ReAct Agent
agent = create_react_agent(llm, tools, prompt)
# 导入AgentExecutor
from langchain.agents import AgentExecutor
# 创建Agent执行器并传入Agent和工具
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 调用AgentExecutor
agent_executor.invoke({"input": "当前Agent最新研究进展是什么?"})
通过以上的一个小例子,已经可以跑通啦。那么接下来,再来拆解一下其中的核心。
模型的输出质量与提供给它的输入信息的质量和结构密切相关。我们先来看看这段代码是如何导入提示的——正是这个提示指导大模型遵循ReAct框架。
(提示就是你输入大模型的信息,可以是语言、代码,可以是图像、语音等多媒体信息,也可以是人类读不懂的编码(只要大模型能理解就行))
这里,我们的大模型之所以遵从ReAct框架去思考并行动,主要取决于提示的准确性。
接下来我们对上述代码做一个分解:
from langchain import hub
prompt = hub.pull("hwchase17/react")
print(prompt)
上面的代码中,我们从LangChain的Hub(可以理解成一个社区)中直接将hwchase17这个大佬设计好的ReAct提示导入进来。
> 这里这个langchain hub有点类似于下载开源大模型的那个huggingface hub,感兴趣的朋友可以科学上网去探索一下。
运行上述代码会形成如下的输出:
PromptTemplate(
input_variables=['agent_scratchpad', 'input', 'tool_names', 'tools'],
template='Answer the following questions as best you can.
You have access to the following tools:\n\n{tools}\n\n
Use the following format:\n\n
Question: the input question you must answer\n
Thought: you should always think about what to do\n
Action: the action to take, should be one of [{tool_names}]\n
Action Input: the input to the action\n
Observation: the result of the action\n...
(this Thought/Action/Action Input/Observation can repeat N times)\n
Thought: I now know the final answer\n
Final Answer: the final answer to the original input question\n\nBegin!\n\n
Question: {input}\n
Thought:{agent_scratchpad}')
PromptTemplate类是一个带有输入变量和模板字符串的结构,用于生成文本提示。相关参数介绍如下:
1. input_variables:是一个变量名的列表,这些变量名会在提示中被实际数据替换。
2. template:是定义提示格式的字符串,其中包含多个占位符,这些占位符会被input_variables中对应的数据替换。
在实例化过程中,这个提示会引导一个大模型或Agent使用特定的格式来回答问题。这个过程包括思考、行动、行动输入、观察,并根据需要重复这个过程直到得出最终答案。
书中把这一过程翻译成如下的形式,以便更好的理解:
尽你所能回答以下问题。你可以访问以下工具:
{工具}
请使用以下格式回答
问题:你必须回答的输入问题
思考:你每次都应该思考接下来怎么做
行动:要采取的行动,应该是[{工具名称}]中的一个
行动输入:行动的输入
观察:行动的结果
……(这个思考—行动—行动输入—观察过程可以重复N次)
思考:我现在知道最终答案了
最终答案:原始输入问题的最终答案
开始!
问题:{输入}
思考:{Agent记事本}
这个提示就是Agent的规划和决策指南,也就是我们所谓的提示工程的价值所在。没有这个提示,大模型将随意输出。
from langchain_openai import ChatOpenAI # 修改导入语句
llm = ChatOpenAI(
model_name="moonshot-v1-8k", # KIMI的模型名称
api_key=os.getenv('KIMI_API_KEY'), # 使用环境变量获取API_KEY
base_url="https://api.moonshot.cn/v1",
temperature=0.7
)
在上述代码中,首先从langchain_openai包(这个包含有各种各样的大模型)中导入ChatOpenAI类。然后创建一个名为llm的ChatOpenAI类的实例。如果您使用的是OPENAI的API_KEY,您可以使用以下的代码:
# 导入OpenAI
from langchain_openai import OpenAI
# 选择要使用的大模型
llm = OpenAI()
接下来,需要配置一下工具Tools
# 导入SerpAPIWrapper即工具包
from langchain_community.utilities import SerpAPIWrapper
from langchain.agents import Tool
# 实例化SerpAPIWrapper
search = SerpAPIWrapper()
# 准备工具列表
tools = [
Tool(
name="Search",
func=search.run,
description="当大模型没有相关知识时,用于搜索知识"
),
]
在上述代码中,SerpAPIWrapper是一个包装器,其中封装了与SerpApi的交互,以便通过编程方式访问SerpApi提供的搜索服务。SerpApi是一个服务,它提供了对多个搜索引擎(如Google、Bing等)的查询接口。
Tool类则是LangChain Agent可以使用的工具的基础类。一个Tool实例代表Agent可以访问的一个外部功能或服务。列表tools中包含Tool类的实例。列表中的每个元素都代表一个工具,Agent可以利用这些工具来执行任务。
至此,大模型实例、工具的定义以及ReAct框架提示都已经设置完成,接下来就是要构建一个ReAct Agent的实例。
# 导入create_react_agent功能
from langchain.agents import create_react_agent
# 构建ReAct Agent
agent = create_react_agent(llm, tools, prompt)
在上述代码中,首先从langchain.agents模块导入create_react_agent。然后通过create_react_agent函数创建一个ReAct Agent。
这个函数需要传递的参数包括:llm是之前实例化的大模型,tools是之前定义的SerpApi搜索工具,而prompt则是包含ReAct框架的提示,用来定义Agent的行为和任务。
最后,执行执行ReAct Agent:
# 导入AgentExecutor
from langchain.agents import AgentExecutor
# 创建Agent执行器并传入Agent和工具
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 调用AgentExecutor
agent_executor.invoke({"input": "当前Agent最新研究进展是什么?"})
通过以上代码,调用了agent_executor,输出结果。以上就是我们已经跟着书中的内容,实现了一个简单的Agent。
这里还有很多其他框架,方便大家使用,大家可以根据自身需求,慢慢探索:
函数调用(Function Calling):是由OpenAI公司提出的一种AI应用开发框架。在这种框架中,大模型被用作调用预定义函数的引擎。这里的预定义函数可以用于API调用、数据库查询或其他程序化任务。对于需要与现有系统集成或执行具体技术任务的应用,如自动化脚本或数据分析,此框架非常合适。
计划与执行(Plan-and-Execute):侧重于先规划一系列的行动,然后执行。这种框架使大模型能够先综合考虑任务的多个方面,然后按计划行动。在复杂的项目管理或需要多步骤决策的场景中,这种处理方式尤为有效,如自动化工作流程管理。
自问自答(Self-Ask):允许大模型对自己提出问题并回答,以此来深化理解和提高回答质量。这种框架在需要深入分析或创造性解决方案的应用中非常有用,例如创意写作或复杂查询。
批判修正(Critique Revise):也叫作Self-Refection架构。在人工智能和机器学习领域中,这种框架主要用于模拟和实现复杂决策过程。这种框架基于“批判”和“修正”两个核心步骤,通过不断迭代改进来提高系统的性能和决策质量。
思维链(CoT):是指在解决问题过程中形成的一系列逻辑思考步骤。在AI领域,尤其是在自然语言处理和机器理解任务中,CoT通过模拟人类的思考过程来提高模型的理解和推理能力。通过明确展示解决问题的逻辑步骤,CoT有助于增强大模型的透明度和可解释性。
思维树(ToT):可以被视为CoT的升级版。在ToT中,问题解决过程被结构化为一系列逻辑步骤。ToT通过树搜索来增强大模型解决复杂问题的能力,旨在提高大模型在处理复杂任务时的效能,特别是那些需要探索或战略性前瞻的任务。这种框架允许大模型自我评估中间思维对解决问题的贡献,并通过有意识的推理过程来选择下一步的方向。
本文章转载微信公众号@DA随想随笔