AI Agents (Agents) are advanced AI systems that combine large language models (LLMs) with tools, enabling them to perceive and interact with the external environment to perform complex tasks autonomously.
Mind Map
클릭해서 펼치기
클릭해서 인터랙티브 마인드맵 전체 보기
今天我们来聊聊Agent
它也叫AI Agent
这是一个随着大模型热潮而兴起的重要概念
虽然Agent这个词现在被频繁地提起
但它究竟是什么
是如何运作的
很多人其实并不清楚
所以在这个视频里面
我会带你彻底搞明白这两个问题
在正式开始前
我需要先提醒一下
视频前半部分的一些内容
和我之前发过的MCP终极指南
番外篇有所重合
如果你已经看过那一篇了
这个视频就建议从Agent代码的实现部分开始观看
大家都知道现在的大模型
比如GPT-4o、DeepSeek之类的
它们回答问题很厉害
逻辑也很强
但平时我们用它们的时候会发现一个限制
它们无法感知或者是改变外界环境
这句话是什么意思呢
我举一个例子来给你说明一下
比如
你想让GPT-4o帮你写一个贪吃蛇游戏
它确实可以给你代码
但是写完之后
像把代码写入到文件这种事情
还是得你自己动手
也就是说大模型无法改变外界环境
而且有没有一种可能
你其实已经有一些贪吃蛇的代码了
你只是想让模型帮你基于这些代码来改写
增加一些功能
在这种情况下
你就必须把你已有的代码复制给GPT-4o才行
我们不主动告诉GPT-4o的话
它是无法自己查到这些代码的
换句话说
这就是大模型无法感知外界环境的体现
所以综合来看
大模型是无法感知或者是改变外界环境的
那有没有办法解决掉这个问题呢
其实是有的
我们给它接上对应的工具就可以了
比如说是读写文件内容的工具
查看文件列表的工具
运行终端命令的工具
工具就像是大模型的感官和四肢
有了它
大模型就可以自己查询已有文件
自己写入代码
自己运行程序
整个过程不需要我们插手
完全自动化
像这样
把一个大模型和一堆工具组装起来
变成一个能感知和改变外界环境的智能程序
我们就称它为Agent
通常Agent用一个机器人来表示
这与大模型的大脑图标形成了鲜明的对比
毕竟Agent有了感官和四肢嘛
能自己独立做事了
就像一个机器人一样
Agent有很多类型
前面举的是编程类的Agent
它可以用来开发程序
除此之外
还有一些Agent可以做PPT
有一些Agent可以深度搜索
等等等等
总的来说
Agent的类型有很多
擅长的领域也各不相同
下面我们来举几个具体点的例子
第一个例子便是大名鼎鼎的Cursor
相信即使你没有使用过它
也多多少少听说过它的存在
Cursor是一个用于编程的Agent
我们只需要给它提交任务
它便会调用大模型和各种工具
来帮我们写代码
直至完成任务
整个过程中
你顶多点个确定按钮
别的基本上什么也不用动
再举一个例子
前一阵子比较火的Manus
它也是一个Agent
在这个例子中
用户希望Manus帮它比较几个手机的性能
照相等能力
为了解决用户的问题
Manus会生成执行计划
搜索并浏览相关网页
最后把报告整理成一个页面
展示给用户看
整个过程基本上也不需要用户插手
Manus利用大模型和一些工具
就可以解决掉用户的问题
好
相信到这里
你对Agent就有一个大致的了解了
下面我们就来讲讲Agent的运行模式
Agent的运行有很多种模式
其中最有名的一种是ReAct
ReAct本身是一个缩写
它的全称是Reasoning and Acting
也就是思考与行动
ReAct可能是目前使用最为广泛的Agent运行模式
如果你要学习Agent的实现原理
那你就绝对绕不开ReAct
这个模式最初由2022年10月份的一篇论文提出
虽然距离现在已经有接近三年的时间了
但是它所提出的Agent的运行模式
仍然有着非常广泛的使用
说它是目前使用最为广泛的Agent的运行模式
也不为过
在这种模式下
用户先提交任务
然后Agent先做思考
英文是Thought
它思考后会决定是否调用工具
如果是的话
它便会去调用合适的工具
比如读取文件写入文件内容之类的
ReAct称这一步是行动
英文是Action
在行动后
Agent会去查看工具的执行结果
比如所读取的文件内容
写入是否成功等等
ReAct称这一步是观察
也就是观察工具执行结果
英文是Observation
在观察之后
ReAct会继续思考
它会再次判断是否需要调用工具
如果还是需要的话
它就会继续重复之前所说的行动
观察思考的流程
直到某个时刻
它认为不需要再调用工具了
可以直接给出结论了
此时它就输出了最终答案
英文是Final Answer
整个流程到此结束
所以从这个流程图里面也可以看出
ReAct流程的核心步骤是
Thought
Action
Observation
和Final Answer
记住这几个词
我们后面会用到
了解了ReAct模式的流程之后
下一个问题就是
这种ReAct模式是如何实现的
为什么模型拿到用户问题之后
会先思考
再行动
它为什么不直接行动
是因为模型就这么训练的吗
不是的
这跟模型的训练过程关系不大
大部分奥秘其实都集中在系统提示词上
系统提示词是跟用户问题
一起送给模型的提示词
它规定了模型的角色
运行时要遵守的规则
以及各种环境的信息等等
比如我们在系统提示词里面写
你的回答必须包含两个XML标签
一个叫做Question
用于存放用户的问题
一个叫做Answer
用于存放你的回答
你把这个系统提示词和用户问题
一起发给大模型
在这种情况下
大模型便会遵循这种规范
来输出答案
上面举的是一个简单的例子
如果你想要模型按照ReAct模式返回答案的话
你的系统提示词就会更加复杂一些
我这里就有一个具体的例子
这个系统提示词大致有五个部分
分别是职责描述
示例
可用工具
注意事项
和环境信息
我们来仔细读一下
首先看职责描述部分
你需要解决一个任务
为此你需要将任务分解为多个步骤
对于每个步骤
首先使用thought思考要做什么
然后使用action调用一个工具
工具的执行结果会通过observation返回给你
持续这个思考和行动的过程
直到你有足够多的信息来提供final answer
这段话其实就是在描述我们刚才的
那个ReAct执行流程图
我们希望大模型按照ReAct这个标准来运作
后面则是专门说明了每个标签的功能
紧接着我举了几个例子
比如说第一个用户的问题是
埃菲尔铁塔有多高
模型就先用thought标签做了一些思考
然后再使用action调用了get height工具
传入的参数是埃菲尔铁塔
工具的返回结果通过observation返回给了模型
模型接到结果之后
他再做了一些思考
然后就给出了最终的答案
这个就是一个非常典型的ReAct流程
后面的例子2其实也是类似
只不过是他调用工具调了两遍
这个我们就不细说了
再往后我这里列举了一些可用的工具
分别用于读取文件内容
写入文件内容和运行终端命令
都是非常常用的功能
然后我们列举了一些注意事项
就是在这里
而且告诉了大模型相关的一些环境信息
比如说是当前的操作系统
目录和目录下的文件列表等等
下面我们就来演示一下如何使用这个系统提示词
我们用DeepSeek来举例
我们先把我们的系统提示词复制一下
然后粘贴进来
作为用户输入的一部分
之后再在后面加上具体要完成的任务
写一个贪吃蛇游戏
使用html、css和js实现
代码分别放在不同的文件中
有一点需要提一下
按照规范的做法
系统提示词和用户任务应该分开传给模型
但DeepSeek并没有提供单独提交系统提示词的地方
所以我们就把系统提示词和用户任务合在一起
当成一条消息提交给它
这样的处理方式在大多数的情况下也是没有问题的
模型依然能够按照预期运行
好 让我们提交任务
可以看到DeepSeek开始运行了
让我们稍等一下 让它运行完毕
可以看出它按照我们的要求
先在thought标签里面思考了一下
然后它使用action标签请求调用write_to_file工具
来写入index.html文件
这后面就是具体的文件内容了
大家注意我的措辞啊
大模型请求调用工具
这里体现的是请求两个字
大模型本身是不能调用工具的
调用工具的是Agent的工具调用组件
这里大模型只能是请求
现在如果运行的是一个真的Agent的话
它便会去调用工具背后的write_to_file函数
写入html文件内容
不过我们现在在模拟嘛
我们就假设调用已经完成了
并且假设工具的返回结果是写入成功
所以我们回复observation写入成功
拿到这个结果后
DeepSeek又开始运行了
这次它还是先用thought标签思考了一下
然后再使用action标签请求写入css文件的内容
我们照例回复写入成功
DeepSeek又开始返回了
让我们稍等一下
可以看出DeepSeek还是先用thought思考
再用action请求写入js文件的内容
我们还是回复写入成功
然后DeepSeek的返回就有了些变化
因为三个必要的文件都已经写入完成了
不需要再调用工具了
因此DeepSeek在thought之后
返回了一个final answer
整个回答就彻底结束了
你看这就是ReAct模式真正运行时的节奏
每一步都按照系统提示词的要求来
thought action observation
一直到任务完成
此时会输出thought和final answer
系统提示词就相当于
给模型安排了一个迷你剧本
它会严格按照这个剧本一步一步的走完
前面我们用DeepSeek演示了一个Agent的运行流程
可以看到整个流程的关键在于系统提示词
它决定了模型该如何一步步运行
其实在这个系统提示词的基础上
再加上一些配套的代码
我们就可以搭建出一个真正可用的ReAct Agent
实际上我已经把这个Agent写好了
就放在我的github仓库里
有需要的同学可以自行获取
接下来我先演示一下这个Agent的使用过程
随后再带大家一起看一遍它的代码
我已经进入到这个Agent所处的项目目录了
我们先执行一下tree命令
看一下这个项目目录里面都有什么文件
这里文件很多
但实际上你只有两个文件需要留意一下
第一个是agent.py文件
这个文件里面就写了我们的Agent的代码
我们等会儿要运行的就是这个文件
另外一个是snake文件夹
它里面什么也没有
我用tree命令给你证实一下
可以看出确实没有任何文件
等会儿我就会让Agent把代码写入到这个文件夹里面
好介绍完毕
下面我们来执行一下这个Agent
让你看看它是如何运作的
首先我们启动一下这个Agent
我们用的命令是
uv run agent.py snake
前面的uv run agent.py
就是用来启动agent.py文件的
后面的snake是agent.py这个脚本的第一个参数
意思是告诉agent.py
它要操作的项目目录是snake
代码就写在那里面
agent.py首先向我们询问需要完成的任务
我们的任务就是
写一个贪吃蛇游戏
使用html、css和js实现
代码分别放在不同的文件中
回车
agent.py已经开始运行了
它现在正在请求大模型
我这里采用了同步返回的机制
所以需要等模型把所有内容都生成完毕之后
才能看到结果
其实也可以用流式返回的
模型返回几个字就能看到几个字
这样可能效果更好一点
不过代码的复杂度会增加
所以综合权衡之后
我就没有使用流式返回
好
看到第一轮的结果了
我们的结果一共是包含三个部分
Thought
Action
Observation
跟我们之前在DeepSeek那里看到的一模一样
这里的Action是请求调用
write_to_file工具写入
index.html文件
后面的Observation显示的就是具体的调用结果了
写入成功
注意啊
这个写入成功可不是模拟的
这是真的执行了write_to_file工具
工具也真的返回了写入成功这几个字
好
这个呢是第一部分
我们把滚动条往下拉一拉
看一下剩下的返回是个什么样子的
后面的流程呢也基本类似
可以看到在Observation之后
Agent会再次请求模型
然后Agent就又进行了一段Thought
Action
Observation
这一轮写入的是CSS
我们再把滚动条往下拖一拖
在这里我们就可以看到第三轮的Thought
Action
Observation
这次写入的是JS
最后所有文件都写完之后
它会给出Thought
和FinalAnswer
整个流程就结束了
再看看snake文件夹
确实三个文件都有了
执行index.html
看看游戏能不能玩
可以看到界面出来了
我们动一下
确实也是能动的
然后吃一个红色的方块呢
也是可以吃的
左上角是分数
看来运转的非常顺畅
从这个结果中也可以判断出
我们这个Agent做的非常成功
完全可以作为一个简化版的 Claude Code 来使用
下面我们来看一下这个Agent的具体代码
我们首先从入口处看起
这里面的project_directory
就是我们传给Agent.py文件的第一个参数
也就是snake那个文件夹
tools代表可用的工具列表
我们这里给出了三个
分别用于读取文件
写入文件和运行终端命令
这些都是很实用的函数
我们可以大体看一下
这个是读取文件
这个是写入文件函数
这个是运行终端命令
从这里可以看出工具确实就是函数
让我们回到原来的主链路继续往下看
这里的ReActAgent便是这个文件的核心了
它是一个类
构造这个类的时候需要提供三个参数
第一个是工具列表
这个我们前面已经构建好了
这里直接传了进来
第二个是我们要用的模型
我们这里用的是GPT-4o
第三个是项目目录
也就是snake文件夹
传好了这三个参数之后
我们便获取到了一个agent变量
之后我们会提示用户输入任务内容
然后我们把用户任务传入
agent.run函数
这个函数是ReActAgent的核心
调用它就相当于是启动了这个Agent
之前提到的Thought
Action Observation和FinalAnswer
都是在这个函数内部依次处理的
它处理好了之后
会给出一个最终答案
并且把这个final_answer输出到屏幕上
到这里主链路就结束了
可以看到这段代码的核心是ReActAgent
我们来看一下它里面写了些什么
首先它这里定义了一些自身的属性
分别是工具列表
项目目录和模型调用客户端
到这里
构造函数就结束了
后面我们要看的函数便是这个Agent的重点
Run函数
这个函数的参数是用户输入的任务
在函数的内部
它先构建了一个Message列表
里面有两个元素
分别是系统提示词
和用户问题
系统提示词是用render_system_prompt这个函数来渲染的
它接受一个参数是系统提示词模板
模板里面的内容是这个样子的
跟我们之前讲的那个系统提示词
基本上是一样的
只不过这个模板里面有一些占位符
比如说是工具列表
操作系统
当前目录下的文件列表等等
这些占位符都是render_system_prompt函数
在运行的时候填进去的
在拼接好了Message列表之后
我们使用call_model函数
调用了模型
拿到了模型的执行结果
然后我们提取出返回结果中的thought部分
并且打印了出来
然后代码会检测thought之后的内容
是不是final answer
如果是的话
我们返回这个final answer
函数执行到此结束
如果不是的话
那content里面一定就包含action了
我们此时就把action给解析出来
提取出其中的函数名和参数列表
然后判断了下当前工具
是不是运行终端命令的工具
如果是的话
我们会提示用户是否继续
因为运行终端命令比较危险
所以现在一般用于编程的Agent
都会在运行终端命令之前
主动询问用户是否要执行
之后没有问题的话
我们就会去执行工具背后的函数了
并且把执行结果放到observation里面
再把observation放到message列表里面
因为我们在一个while循环里面
所以我们下一步还会来到循环的开头这里
继续请求模型
我们给call model这个函数
传了message列表作为参数
工具执行结果不是作为observation
放到了message列表里面了吗
而message又传给了模型
这样模型就可以拿到工具的执行结果了
它进而就可以根据工具的执行结果
推测下一步要干什么
所以总结一下这个while循环做的事情
请求模型
提取thoughts
检测final answer
提取action并执行其中的工具
这个过程会一直重复下去
直到模型返回了final answer为止
回想一下
这正是我们之前所提到的ReAct运行流程
为了确保你彻底明白这其中发生了什么
我们来画个Agent的流程图
整个流程图里面有两个角色
用户和Agent
而Agent又可以分成三个部分
分别是模型
工具
也就是函数
还有Agent主程序
Agent主程序这个词我们之前没有提过
其实就是Agent里面负责串联整个流程的代码逻辑
它会在合适的时候
调用工具或者是模型等等
你可以大致理解为我们刚才代码里面的那个run函数
下面我们就来画个流程图
看看这四个角色之间是怎么沟通的
在用户提交任务之后
任务先到了Agent主程序这里
Agent主程序会先去调用模型
模型返回thought和action
Agent主程序把thought和action打印给用户看
然后去调用action里面的指定工具
工具执行完毕之后返回结果
Agent主程序把结果发回给用户看
然后把这个工具执行结果加入到历史消息列表里面
然后再次重复这个框中的流程
也就是请求模型
并处理thought,action和observation的逻辑
直到某个时刻
在请求模型后
模型认为用户的任务已经完成了
不需要再调用工具了
它就会返回thought和final answer
Agent主程序把thought和final answer展示给用户看
整个流程就结束了
这就是一个完整的ReAct Agent的问答流程
前面我们讲了如何使用ReAct模式
来构建一个Agent
ReAct是目前最常见
使用最广泛的Agent构建模式
但它不是唯一的方案
除了ReAct之外
还有很多其他的运行模式
其中很多Agent的运行过程
就是先规划再执行
比如我们之前演示过的Manus
如果你仔细看的话
就会发现它在一开始回答的时候
会构建一个待办列表
后面的执行过程
都是遵循这个待办列表来
而Claude Code中
也会经常看到这种先创建TODO
再去执行的情况
这种先规划再执行的模式
目前并没有一个统一的名字
而且每个Agent的实现多多少少
也会有一些差别
我们今天来讲一个其中比较有名的实现
是LangChain提出来的Plan-and-Execute模式
从总体上来看
它也是遵循了先规划再执行的流程
只不过它的流程引入了一些动态修改规划的环节
这使得它的方案有了很大的灵活性
我们先用时序图来画一下Plan-and-Execute模式的运行流程
首先我们要搞清楚这个时序图里面有多少个角色
粗分下来的话那肯定只有两个了
一个是用户
另外一个是Plan-and-Execute Agent
不过既然要研究Plan-and-Execute Agent的运行流程
我们就肯定要搞清楚这个Agent的组成部分
首先它里面有一个负责出执行计划的模型
我们称它为Plan模型
我们在运行的过程中
还需要根据每一步的执行结果来动态的调整计划
因此我们还需要一个负责修改执行计划的模型
我们称它为Re-Plan模型
Plan和Re-Plan模型可以是同一个
也可以分成两个
都是可以的
我们暂且将它们列为两个
除了这两个模型之外
我们还需要一个负责执行这个计划中每一个步骤的Agent
我们称它为执行Agent
对你没看错
这个Plan-and-Execute Agent内部还有一个Agent
这种Agent套Agent的设计方案其实也是比较常见的
最后跟ReAct那个流程一样
我们还需要一个Agent的主程序
负责串联整个流程
这就是Plan-and-Execute Agent的全部模块了
下面我们就把它们放在流程图里面
看看各个模块之间是如何运作的
首先用户会把问题提给Agent的主程序
比如我们的问题就可以是
今年澳网男子冠军的家乡是哪里
这里的澳网指的是每年举办的澳大利亚网球公开赛
也就是个体育赛事了
Agent的主程序接到这个问题之后
会把这个问题发给Plan模型
让它给出具体的执行步骤
比如一个可能的执行步骤就是这样的
先查询当前日期
然后查询在当前年份下澳网男子冠军的名字
比如当前时间是2025年的话
就查询2025年的澳网男子冠军的名字
如果当前年份是2024年的话
那就查询2024年的澳网男子冠军的名字
查出名字后
我们再根据这个名字来查询这个冠军的家乡
没错
这就是一个非常合理的执行步骤
那计划有了之后
Agent的主程序便会把这个计划传给执行Agent
让它去执行这个计划中的第一步
也就是查询当前日期的那个步骤
这个执行Agent可以用我们之前讲的ReAct模式来运行
它内置一个网络搜索工具
这样它就可以通过搜索网络来查询当前日期了
当然执行Agent也完全可以用别的模式来运行
Plan-and-Execute模式
只要求执行Agent能够完成指定的步骤就行
至于它的运行模式是不是ReAct
内置工具有哪些
它完全不关心
执行Agent内部一顿操作之后
就吐出了一个执行结果并返回回去
然后Agent的主程序会把用户问题
执行计划和执行记录都发给Re-Plan模型
让它生成一个新的执行计划
毕竟我们拿到了第一步的执行结果了
多了一些信息
情况可能会发生些变化
把原计划改改实在正常不过的事情了
那Agent的主程序接到新的执行计划之后
它便会回头再重复这个框中的流程
在我们这个例子中
这个框中的流程一共会运行三轮
对应了执行计划里面的三步
每一轮都包含两个环节
一个是执行环节
一个是Re-Plan环节
为了能够让你彻底明白
我们模拟一下这个循环中的三轮
让你看看每一轮的执行环节和Re-Plan环节
都具体发生了一些什么事情
在模拟开始前
我先打个预防针
为了节省时间
我在模拟时讲解的速度会稍微快一些
如果你听不懂
建议在合适的时候稍微停一下
好让我们开始
首先是第一轮
在执行阶段
我们把执行计划发给执行Agent
让他处理其中的第一步
执行Agent返回之后
我们把他给出的执行结果
加入到历史执行记录里
然后把用户问题
第一个执行计划和历史执行记录
一起发给Re-Plan模型
让他给出第二个执行计划
第一个执行计划和第二个执行计划
有两点不同
这里我专门说一下
首先原来查询当前日期的那一步
就不用出现在第二个执行计划里面了
毕竟已经执行完了
不用再执行了
另外查询澳网男子冠军名字的这一步
也发生了一些变化
在第一个执行计划中
他叫做查询对应日期的澳网男子冠军名字
在第二个执行计划中
他叫做查询2025年的澳网男子冠军名字
毕竟日期已经查出来了
因此我们可以直接把具体的年份
放到执行计划里
这样执行Agent接到的任务
就更加精确了
然后进入到第二轮
在这一轮中
我们同样先取出最新的执行计划
发给执行Agent
让他执行其中的第一步
拿到执行结果后
我们再把执行结果加入到历史执行记录中
然后在Re-Plan阶段把用户问题
执行计划和历史执行记录
发给Re-Plan模型
拿到第三个执行计划
在第三轮中
我们还是先取出执行计划
让执行Agent处理其中的第一步
当然现在也只剩一步了
执行之后
我们就可以拿到一个执行结果
把执行结果加入到历史执行记录里
然后再把用户问题
执行计划和历史执行记录
都发给Re-Plan模型
让他再生成一个......
哎,好像所有的任务都已经完成了
没有步骤要做了吧
没错
在最后一轮中
Re-Plan模型会发现
所有的步骤都已经做完了
用户的问题可以回答出来了
此时Re-Plan模型返回的
就不是最新的执行计划了
而是最终的答案
所以在流程图里面
我们也要把执行计划
换成最终答案
Agent主程序
接到这个最终答案之后
便会把这个答案转发给用户
整个流程也就结束了
所以回头看一下这个流程图
我们之前说Agent主程序
请求Re-Plan模型
给出一个新的执行计划
这个说法其实并不准确
更准确的说法是
Agent主程序请求Re-Plan模型
给出一个新的执行计划
或者是返回最终答案
如果还有步骤要执行的话
那就给出一个新的计划
如果没有步骤要做了
用户的问题已经回答出来了
那Re-Plan模型就返回最终答案就好了
因此Re-Plan模型的返回
也有两种可能性
新的执行计划
或者是最终答案
这样才是一个准确的流程图
相信到这里为止
你对Plan-and-Execute流程
就有一个非常清晰的认识了
不过有些人可能想要
Plan-and-Execute的具体实现代码
LangChain官方提供了一份
你可以到这个页面里面自行获取
今天的视频就到此结束了
别忘了点赞
关注
我们下次再见
拜拜
텍스트나 타임스탬프를 클릭하면 동영상의 해당 장면으로 바로 이동합니다
공유:
대부분의 자막은 5초 이내에 준비됩니다
원클릭 복사125개 이상의 언어내용 검색타임스탬프로 이동
YouTube URL 붙여넣기
YouTube 동영상 링크를 입력하면 전체 자막을 가져옵니다
자막 추출 양식
대부분의 자막은 5초 이내에 준비됩니다
Chrome 확장 프로그램 설치
YouTube를 떠나지 않고 자막을 즉시 가져오세요. Chrome 확장 프로그램을 설치하면 동영상 시청 페이지에서 바로 자막에 원클릭으로 접근할 수 있습니다.