基于大型语言模型的智能 Agent:发展历程、架构与 Langchain 实现
基于大型语言模型(LLM)的智能 Agent 是近年来的研究热点。文章介绍了 Agent 的定义及从符号、反应型到强化学习再到 LLM 驱动的发展阶段。详细阐述了包含记忆、规划、行动等核心模块的架构框架,并结合 LangChain 库提供了使用 ReAct 算法实现具备搜索能力的 Agent 的代码示例。最后探讨了 Agent 在社会科学、自然科学等领域的应用场景及未来挑战。

基于大型语言模型(LLM)的智能 Agent 是近年来的研究热点。文章介绍了 Agent 的定义及从符号、反应型到强化学习再到 LLM 驱动的发展阶段。详细阐述了包含记忆、规划、行动等核心模块的架构框架,并结合 LangChain 库提供了使用 ReAct 算法实现具备搜索能力的 Agent 的代码示例。最后探讨了 Agent 在社会科学、自然科学等领域的应用场景及未来挑战。

在大型语言模型(LLM)的时代,基于大型语言模型的智能 Agent 在过去一年中取得了显著进展。
Agent,又可以翻译为代理或者智能体。
Agent 的定义和性质因学科或文化背景而异。通常,Agent 是一个具有自主性的个体,能够行使自己的意志,做出决定并采取行动,而不仅仅是被动地响应外部刺激。人类是这个星球上最复杂的 Agent。
自 20 世纪 80 年代中期以来,人工智能领域关于 Agent 的研究显著增加。基于此,Wooldridge 将人工智能定义为旨在设计和构建表现出智能行为的计算机 Agent。
从本质上讲,人工智能 Agent 是对 Agent 概念的具体化。

如图 1 所示,人工智能 Agent 是一个通过传感器感知其环境、做出决策并相应地响应的人造实体。
人工智能 Agent 研究的技术演变历史主要包括以下几个阶段。
在人工智能研究的早期阶段,主要采用的方法是符号人工智能,它使用逻辑规则和符号表示来封装知识并促进推理过程。符号 Agent 的架构如图 2 所示:

以前的各种基于知识的专家系统就是最常见的符号 Agent。该类系统主要由知识库、推理引擎和解释器组成。
然而,正如决策引擎逐渐被 AI 模型所淘汰,人工构建的决策逻辑通常太过死板,难以具有应用价值。
与符号 Agent 不同,反应型 Agent 不采用复杂的符号推理。他们主要关注 Agent 与环境之间的互动,优先考虑快速和实时的反应。反应型 Agent 通常使用预定义的规则集来指导其行为,如图 3 所示:

相对于符号 Agent,反应型 Agent 所使用的策略更为简单。举个例子,符号 Agent 类似于编译器,决策引擎中有大量逻辑推演规则,而反应型 Agent 则就是一堆 if else,通过读取环境数据快速进行判断。
在 LLM 出现之前,基于强化学习的 Agent 属于是研究热点,最著名的应该就是 AlphaGo。这一领域的主要关注点是如何使 Agent 通过与环境的互动来学习,以在特定任务中获得最大的累积奖励。
深度学习出现后深度神经网络与强化学习整合。这使得 Agent 能够从高维输入中学习复杂的策略。如图 4 所示。

然而,强化学习的问题包括:长时间的训练周期、采样效率低、在复杂的现实世界环境中模型不稳定。
近年来,大型语言模型(LLM)非常火热,潜力巨大。因此,一个新的研究领域已经出现,使用 LLM 作为 Agent 的核心控制器,以让 Agent 拥有人类水平的决策能力。
这是文章的重点,接下来将详细说明。
基于 LLM 的 Agent 的架构形式各异。然而,所有架构的核心模块都包括记忆、规划和行动。
提出了一个统一框架,如图 5 所示。这个框架包括一个分析 (Profile) 模块、一个记忆 (Memory) 模块、一个规划 (Planning) 模块和一个行动 (Action) 模块。

Agent 在执行任务时通常会预定义一个身份,比如教师、某领域的专家等。分析模块的作用是定义这些 agent 所扮演的角色的详细档案,这些档案会被写入到提示中,用以影响大型语言模型(LLM)的行为。
Agent 档案一般包含基本信息(如年龄、性别、职业)、个性相关的心理学信息,以及描述 Agent 间社交关系的信息。选择哪些信息主要取决于应用的具体场景。
基于 LLM(大型语言模型)的 Agent 的记忆机制仿照了人类记忆。人类记忆可以分为短期记忆(短暂保持信息)和长期记忆(在较长时间内巩固信息)。
而在 LLM 中,短期记忆指 transformer 架构限制的上下文窗口内的输入信息。长期记忆类似于外部向量存储,Agent 可以根据需要快速查询和检索。
面对复杂任务时,人类倾向于将其分解为更简单的子任务并分别解决它们。规划模块的目标是赋予 Agent 这种人类能力,使 Agent 的行为更加强大。思维链就是一种常见的规划策略。
行动模块将 Agent 的决策转化为具体的输出。这个模块直接与环境互动。它受到分析、记忆和规划模块的影响。行动模块可以分为 4 部分:
此外也有一些其他的框架,提出了一个基于 LLM 的 Agent 的一般概念框架,由三个关键部分组成:大脑(brain)、感知(perception)和行动(action) ,如图 6 所示。

大脑模块作为控制器,处理基本任务,如记忆、思考和决策。感知模块解释和处理来自外部环境的多模态信息,而行动模块则执行响应并使用工具与环境互动。
举个例子来说明工作流程:假设有人问今天是否会下雨。感知模块将这个查询转换成 LLM 可以理解的格式。然后,大脑模块根据当前的天气情况和在线天气报告进行推断。最后,行动模块作出响应并给这个人递一把伞。通过这一过程,Agent 能够持续接收反馈并与环境互动。
根据领域的不同,基于 LLM 的 Agent 的应用可以分为三类:社会科学、自然科学和工程,如图 7 所示。

根据应用场景的不同,基于 LLM 的 Agent 的应用又可以分为:单一 Agent、多重 Agent 和人机交互 Agent,如图 8 所示。

单一 Agent 具有多样化的能力。当多个 Agent 互动时,它们可以通过合作或对抗性互动加强性能。人与 Agent 的互动中,人类的反馈可以使 Agent 更有效地执行任务。
接下来我们将用 Langchain 和 python 实现一个 Agent 的 demo,demo 的整体架构图如下:

这里我用了 anaconda 来配置环境,命令如下:
conda create -n agent python=3.11
conda activate agent
pip install langchain
pip install langchain_openai
pip install duckduckgo-search
最终所用库的版本如下:
langchain 0.1.15
langchain-community 0.0.32
langchain-core 0.1.41
langchain-openai 0.1.2
langchain-text-splitters 0.0.1
duckduckgo_search 5.3.0
import os
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"
from langchain.agents import AgentExecutor, Tool, ZeroShotAgent
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory
from langchain_openai import OpenAI
from langchain_community.utilities import DuckDuckGoSearchAPIWrapper
这里,我使用 DuckDuckGo 库作为 Agent 可以使用的工具,从而为 Agent 赋予搜索能力。
tools 定义了一个工具列表,其中包含一个名为"Search"的工具,该工具使用 search.run 函数。
search = DuckDuckGoSearchAPIWrapper()
tools = [
Tool(
name="Search",
func=search.run,
description="useful for when you need to answer questions about current events",
)
]
如前所述,计划模块和行动模块是一个 Agent 的核心,这里我使用算法,构建计划模块和行动模块。该算法如下图所示:
以做一道菜为例,切好菜和打开煤气之间,有一个这样的推理,或者说内心独白:"现在我切好菜了,后面要煮菜了,我需要打开煤气。"在做菜过程中,如果发生意外,发现没有盐时,有这样一个推理:"没有盐了,今天我就用胡椒粉调味",然后我们就会去拿胡椒粉。
通过这个洞察,作者提出一个方法:
让 LLM 把内心独白说出来,然后再根据独白做相应的动作,来提高 LLM 答案的准确性。
以下面这个问题为例:
除了 Apple 遥控器,还有什么其他设备可以控制相关软件?相关软件指的是,Apple 遥控器最早可以控制的软件。
说明:
ReAct 方法,即推理 + 动作。得到结果:
想法 1:我需要搜索 Apple 遥控器,并找到 Apple 遥控器最早可以控制的软件。 动作 1:搜索【Apple 遥控器】 结果 1:Apple 遥控器是一种遥控器……最早可以控制'Front Row'……
想法 2:Apple 遥控器最早可以控制 Front Row。我需要搜索 Front Row 下一步,找出还有什么其他设备可以控制他 动作 2:搜索【Front Row】 结果 2:无结果,可以试试'Front Row Seat to Earth'和'Front Row 软件'
想法 3:Front Row 没有找到,我可以搜索'Front Row 软件' 动作 3:搜索【Front Row 软件】 结果 3:FrontRow 是一种过时软件……可以被 Apple 遥控器和键盘功能键控制。
想法 4:现在我知道答案了。 动作 4:完成【键盘功能键】
答案正确。通过显式推理,加上动作,LLM Agent 自主找到了答案。整个过程感觉就像是个不是特别聪明的孩子,要把想法写出来,然后去综合所有想法和观察,接着再做出相应的动作。但显然这个方法很有效,它最终找到了答案。
prefix = """Have a conversation with a human, answering the following questions as best you can. You have access to the following tools:"""
suffix = """Begin!
{chat_history}
Question: {input}
{agent_scratchpad}"""
# 使用 `ZeroShotAgent.create_prompt` 方法创建一个提示,该提示将用于与 LLM 交互。
prompt = ZeroShotAgent.create_prompt(
tools,
prefix=prefix,
suffix=suffix,
input_variables=["input", "chat_history", "agent_scratchpad"],
)
这里定义了对话的前缀和后缀,以及对话历史、用户输入和 Agent 的思考过程的占位符。使用 ZeroShotAgent.create_prompt 方法创建一个 prompt。
这里可能有读者疑惑,ReAct 算法在哪使用呢————在 prompt 里!
这里展示下内容:
Have a conversation with a human, answering the following questions as best you can.
You have access to the following tools:
Search: useful for when you need to answer questions about current events
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [Search]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!"
{chat_history}
Question: {input}
{agent_scratchpad}
prompt 将使用一个定义好的 [search] 工具,并且 prompt 末尾有三个变量:
langchain 已经提供了默认的记忆模块的函数:
memory = ConversationBufferMemory(memory_key="chat_history")
创建一个 ConversationBufferMemory 实例,用于存储对话历史。
#创建一个 `LLMChain` 实例,它将使用 OpenAI 模型和之前创建的提示。
llm_chain = LLMChain(llm=OpenAI(temperature=0), prompt=prompt)
#创建一个 `ZeroShotAgent` 实例,它将使用 LLM 链和工具列表。
agent = ZeroShotAgent(llm_chain=llm_chain, tools=tools, verbose=True)
#创建一个 `AgentExecutor` 实例,它将用于运行 agent。
agent_executor = AgentExecutor.from_agent_and_tools(
agent=agent, tools=tools, verbose=True, memory=memory
)
agent_executor.run(input="How many people live in canada?")
agent_executor.run(input="what is their national anthem called?")
agent_executor.run(input="what is their capital?")
这里连续运行了三次 agent 执行器,每次处理一个不同的输入。第二次和第三次测试了 agent 的记忆功能,即 agent 能否利用之前交互中的信息来回答后续问题。
import os
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"
from langchain.agents import AgentExecutor, Tool, ZeroShotAgent
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory
from langchain_openai import OpenAI
from langchain_community.utilities import DuckDuckGoSearchAPIWrapper
search = DuckDuckGoSearchAPIWrapper()
tools = [
Tool(
name="Search",
func=search.run,
description="useful for when you need to answer questions about current events",
)
]
prefix = """Have a conversation with a human, answering the following questions as best you can. You have access to the following tools:"""
suffix = """Begin!
{chat_history}
Question: {input}
{agent_scratchpad}"""
prompt = ZeroShotAgent.create_prompt(
tools,
prefix=prefix,
suffix=suffix,
input_variables=["input", "chat_history", "agent_scratchpad"],
)
memory = ConversationBufferMemory(memory_key="chat_history")
llm_chain = LLMChain(llm=OpenAI(temperature=0), prompt=prompt)
agent = ZeroShotAgent(llm_chain=llm_chain, tools=tools, verbose=True)
agent_executor = AgentExecutor.from_agent_and_tools(
agent=agent, tools=tools, verbose=True, memory=memory
)
agent_executor.run(input="How many people live in canada?")
# To test the memory of this agent, we can ask a followup question that relies on information in the previous exchange to be answered correctly.
agent_executor.run(input="what is their national anthem called?")
agent_executor.run(input="what is their capital?")
这里我用了个 gpt-3.5 的 api,输出如下:
> Entering new AgentExecutor chain...
Thought: I should use the Search tool to find the most recent population data for Canada.
Action: Search
Action Input: "Population of Canada"
Observation: Canada population density map (2014) Top left: The Quebec City-Windsor Corridor is the most densely inhabited and heavily industrialized region accounting for nearly 50 percent of the total population Canada ranks 37th by population among countries of the world, comprising about 0.5% of the world's total, with 40 million Canadians. Despite being the second-largest country by total area ... As of July 1, 2023, NPRs were estimated to represent 5.5% of the population of Canada. Among provinces, this proportion was highest in British Columbia (7.3%) and Ontario (6.3%) and lowest in Newfoundland and Labrador (2.4%) and Saskatchewan (2.5%). The 2.2 million NPRs now outnumber the 1.8 million Indigenous people enumerated during the 2021 ... Historical population of Canada. Statistics Canada conducts a country-wide census that collects demographic data every five years on the first and sixth year of each decade. The 2021 Canadian census enumerated a total population of 36,991,981, an increase of around 5.2 percent over the 2016 figure. It is estimated that Canada's population surpassed 40 million in 2023 and 41 million in 2024. Canada's population reaches 40 million. On June 16, 2023, Statistics Canada announced that Canada's population passed the 40 million mark according to the Canada's population clock (real-time model). Today's release of total demographic estimates and related data tables for a reference date of July 1, 2023, is the first since reaching that ... Canada's population was estimated at 40,528,396 on October 1, 2023, an increase of 430,635 people (+1.1%) from July 1. This was the highest population growth rate in any quarter since the second quarter of 1957 (+1.2%), when Canada's population grew by 198,000 people. At the time, Canada's population was 16.7 million people, and this rapid population growth resulted from the high number of ...
Thought: Based on the data, I can see that the population of Canada is estimated to be around 40 million as of October 1, 2023.
Final Answer: The estimated population of Canada as of October 1, 2023 is 40 million.
> Finished chain.
> Entering new AgentExecutor chain...
Thought: I should use the search tool to find the answer.
Action: Search
Action Input: "Canada national anthem"
Observation: O Canada, national anthem of Canada.It was proclaimed the official national anthem on July 1, 1980. "God Save the Queen" remains the royal anthem of Canada. The music, written by Calixa Lavallée (1842-91), a concert pianist and native of Verchères, Quebec, was commissioned in 1880 on the occasion of a visit to Quebec by John Douglas Sutherland Campbell, marquess of Lorne (later 9th ... Learn about the history and lyrics of Canada's national anthem , has both French and English versions. The song was composed by Calixa Lavallée 1880 and was proclaimed the official anthem 1980. It replaced , is CanadaO Canadas fourth largest city. It lies some 250 miles (400 km) northeast of Toronto and 125 miles (200 km) west of Montreal, respectively Canadas location, climate, terrain, natural resources, and major lakes and rivers. Find out the population distribution, ethnic , languages, and religions of Canada. The national capital, Ottawa, is prominently marked the province of Ontario. Where is Canada? Canada is the largest country North America. Canada is bordered by non-contiguous US state of Alaska the northwest and by 12 other US states the south. The border of Canada with the US is the longest bi-national land border the world.
Thought: I now know the final answer.
Final Answer: The capital of Canada is Ottawa.
> Finished chain.
尽管基于 LLM 的 Agent 展现了强大的能力,但在实际落地中仍面临诸多挑战:
未来,随着模型能力的提升和评估体系的完善,Agent 将在自动化运维、个性化助手、科研辅助等领域发挥更大作用。开发者应关注如何优化规划算法、增强记忆检索精度以及建立安全护栏,以确保 Agent 系统的可靠性和可用性。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online