0:00 今天我们来聊聊Agent
0:01 它也叫AI Agent
0:03 这是一个随着大模型热潮而兴起的重要概念
0:06 虽然Agent这个词现在被频繁地提起
0:09 但它究竟是什么
0:10 是如何运作的
0:12 很多人其实并不清楚
0:14 所以在这个视频里面
0:15 我会带你彻底搞明白这两个问题
0:18 在正式开始前
0:19 我需要先提醒一下
0:21 视频前半部分的一些内容
0:22 和我之前发过的MCP终极指南
0:25 番外篇有所重合
0:26 如果你已经看过那一篇了
0:29 这个视频就建议从Agent代码的实现部分开始观看
0:36 大家都知道现在的大模型
0:38 比如GPT-4o、DeepSeek之类的
0:41 它们回答问题很厉害
0:42 逻辑也很强
0:44 但平时我们用它们的时候会发现一个限制
0:47 它们无法感知或者是改变外界环境
0:51 这句话是什么意思呢
0:53 我举一个例子来给你说明一下
0:55 比如
0:56 你想让GPT-4o帮你写一个贪吃蛇游戏
0:59 它确实可以给你代码
1:01 但是写完之后
1:02 像把代码写入到文件这种事情
1:05 还是得你自己动手
1:07 也就是说大模型无法改变外界环境
1:11 而且有没有一种可能
1:12 你其实已经有一些贪吃蛇的代码了
1:15 你只是想让模型帮你基于这些代码来改写
1:18 增加一些功能
1:19 在这种情况下
1:21 你就必须把你已有的代码复制给GPT-4o才行
1:24 我们不主动告诉GPT-4o的话
1:26 它是无法自己查到这些代码的
1:29 换句话说
1:30 这就是大模型无法感知外界环境的体现
1:33 所以综合来看
1:35 大模型是无法感知或者是改变外界环境的
1:40 那有没有办法解决掉这个问题呢
1:42 其实是有的
1:44 我们给它接上对应的工具就可以了
1:46 比如说是读写文件内容的工具
1:49 查看文件列表的工具
1:51 运行终端命令的工具
1:53 工具就像是大模型的感官和四肢
1:56 有了它
1:57 大模型就可以自己查询已有文件
2:00 自己写入代码
2:01 自己运行程序
2:02 整个过程不需要我们插手
2:04 完全自动化
2:06 像这样
2:06 把一个大模型和一堆工具组装起来
2:10 变成一个能感知和改变外界环境的智能程序
2:14 我们就称它为Agent
2:16 通常Agent用一个机器人来表示
2:20 这与大模型的大脑图标形成了鲜明的对比
2:23 毕竟Agent有了感官和四肢嘛
2:26 能自己独立做事了
2:27 就像一个机器人一样
2:29 Agent有很多类型
2:31 前面举的是编程类的Agent
2:33 它可以用来开发程序
2:35 除此之外
2:36 还有一些Agent可以做PPT
2:38 有一些Agent可以深度搜索
2:40 等等等等
2:41 总的来说
2:42 Agent的类型有很多
2:43 擅长的领域也各不相同
2:46 下面我们来举几个具体点的例子
2:48 第一个例子便是大名鼎鼎的Cursor
2:50 相信即使你没有使用过它
2:53 也多多少少听说过它的存在
2:55 Cursor是一个用于编程的Agent
2:58 我们只需要给它提交任务
3:00 它便会调用大模型和各种工具
3:02 来帮我们写代码
3:03 直至完成任务
3:05 整个过程中
3:06 你顶多点个确定按钮
3:07 别的基本上什么也不用动
3:10 再举一个例子
3:11 前一阵子比较火的Manus
3:13 它也是一个Agent
3:14 在这个例子中
3:16 用户希望Manus帮它比较几个手机的性能
3:19 照相等能力
3:20 为了解决用户的问题
3:21 Manus会生成执行计划
3:23 搜索并浏览相关网页
3:25 最后把报告整理成一个页面
3:28 展示给用户看
3:29 整个过程基本上也不需要用户插手
3:32 Manus利用大模型和一些工具
3:34 就可以解决掉用户的问题
3:36 好
3:37 相信到这里
3:37 你对Agent就有一个大致的了解了
3:40 下面我们就来讲讲Agent的运行模式
3:46 Agent的运行有很多种模式
3:49 其中最有名的一种是ReAct
3:51 ReAct本身是一个缩写
3:53 它的全称是Reasoning and Acting
3:56 也就是思考与行动
3:57 ReAct可能是目前使用最为广泛的Agent运行模式
4:01 如果你要学习Agent的实现原理
4:04 那你就绝对绕不开ReAct
4:07 这个模式最初由2022年10月份的一篇论文提出
4:10 虽然距离现在已经有接近三年的时间了
4:13 但是它所提出的Agent的运行模式
4:16 仍然有着非常广泛的使用
4:18 说它是目前使用最为广泛的Agent的运行模式
4:20 也不为过
4:22 在这种模式下
4:23 用户先提交任务
4:25 然后Agent先做思考
4:27 英文是Thought
4:27 它思考后会决定是否调用工具
4:30 如果是的话
4:31 它便会去调用合适的工具
4:34 比如读取文件写入文件内容之类的
4:37 ReAct称这一步是行动
4:38 英文是Action
4:40 在行动后
4:41 Agent会去查看工具的执行结果
4:44 比如所读取的文件内容
4:46 写入是否成功等等
4:47 ReAct称这一步是观察
4:50 也就是观察工具执行结果
4:52 英文是Observation
4:54 在观察之后
4:55 ReAct会继续思考
4:56 它会再次判断是否需要调用工具
4:59 如果还是需要的话
5:01 它就会继续重复之前所说的行动
5:04 观察思考的流程
5:06 直到某个时刻
5:07 它认为不需要再调用工具了
5:09 可以直接给出结论了
5:11 此时它就输出了最终答案
5:13 英文是Final Answer
5:14 整个流程到此结束
5:16 所以从这个流程图里面也可以看出
5:19 ReAct流程的核心步骤是
5:21 Thought
5:22 Action
5:22 Observation
5:23 和Final Answer
5:24 记住这几个词
5:25 我们后面会用到
5:31 了解了ReAct模式的流程之后
5:33 下一个问题就是
5:34 这种ReAct模式是如何实现的
5:36 为什么模型拿到用户问题之后
5:38 会先思考
5:39 再行动
5:40 它为什么不直接行动
5:42 是因为模型就这么训练的吗
5:44 不是的
5:45 这跟模型的训练过程关系不大
5:48 大部分奥秘其实都集中在系统提示词上
5:51 系统提示词是跟用户问题
5:53 一起送给模型的提示词
5:55 它规定了模型的角色
5:57 运行时要遵守的规则
5:58 以及各种环境的信息等等
6:00 比如我们在系统提示词里面写
6:03 你的回答必须包含两个XML标签
6:06 一个叫做Question
6:07 用于存放用户的问题
6:09 一个叫做Answer
6:10 用于存放你的回答
6:11 你把这个系统提示词和用户问题
6:14 一起发给大模型
6:16 在这种情况下
6:17 大模型便会遵循这种规范
6:19 来输出答案
6:21 上面举的是一个简单的例子
6:22 如果你想要模型按照ReAct模式返回答案的话
6:25 你的系统提示词就会更加复杂一些
6:28 我这里就有一个具体的例子
6:31 这个系统提示词大致有五个部分
6:33 分别是职责描述
6:35 示例
6:36 可用工具
6:37 注意事项
6:38 和环境信息
6:39 我们来仔细读一下
6:41 首先看职责描述部分
6:43 你需要解决一个任务
6:44 为此你需要将任务分解为多个步骤
6:47 对于每个步骤
6:48 首先使用thought思考要做什么
6:50 然后使用action调用一个工具
6:52 工具的执行结果会通过observation返回给你
6:56 持续这个思考和行动的过程
6:58 直到你有足够多的信息来提供final answer
7:02 这段话其实就是在描述我们刚才的
7:04 那个ReAct执行流程图
7:06 我们希望大模型按照ReAct这个标准来运作
7:09 后面则是专门说明了每个标签的功能
7:14 紧接着我举了几个例子
7:16 比如说第一个用户的问题是
7:18 埃菲尔铁塔有多高
7:19 模型就先用thought标签做了一些思考
7:25 然后再使用action调用了get height工具
7:28 传入的参数是埃菲尔铁塔
7:31 工具的返回结果通过observation返回给了模型
7:36 模型接到结果之后
7:37 他再做了一些思考
7:39 然后就给出了最终的答案
7:42 这个就是一个非常典型的ReAct流程
7:45 后面的例子2其实也是类似
7:47 只不过是他调用工具调了两遍
7:49 这个我们就不细说了
7:52 再往后我这里列举了一些可用的工具
7:54 分别用于读取文件内容
7:57 写入文件内容和运行终端命令
8:01 都是非常常用的功能
8:03 然后我们列举了一些注意事项
8:07 就是在这里
8:07 而且告诉了大模型相关的一些环境信息
8:11 比如说是当前的操作系统
8:13 目录和目录下的文件列表等等
8:17 下面我们就来演示一下如何使用这个系统提示词
8:20 我们用DeepSeek来举例
8:22 我们先把我们的系统提示词复制一下
8:27 然后粘贴进来
8:28 作为用户输入的一部分
8:30 之后再在后面加上具体要完成的任务
8:33 写一个贪吃蛇游戏
8:34 使用html、css和js实现
8:37 代码分别放在不同的文件中
8:39 有一点需要提一下
8:40 按照规范的做法
8:42 系统提示词和用户任务应该分开传给模型
8:45 但DeepSeek并没有提供单独提交系统提示词的地方
8:48 所以我们就把系统提示词和用户任务合在一起
8:52 当成一条消息提交给它
8:53 这样的处理方式在大多数的情况下也是没有问题的
8:56 模型依然能够按照预期运行
8:59 好 让我们提交任务
9:00 可以看到DeepSeek开始运行了
9:02 让我们稍等一下 让它运行完毕
9:05 可以看出它按照我们的要求
9:07 先在thought标签里面思考了一下
9:09 然后它使用action标签请求调用write_to_file工具
9:13 来写入index.html文件
9:16 这后面就是具体的文件内容了
9:18 大家注意我的措辞啊
9:20 大模型请求调用工具
9:22 这里体现的是请求两个字
9:23 大模型本身是不能调用工具的
9:26 调用工具的是Agent的工具调用组件
9:29 这里大模型只能是请求
9:30 现在如果运行的是一个真的Agent的话
9:34 它便会去调用工具背后的write_to_file函数
9:37 写入html文件内容
9:39 不过我们现在在模拟嘛
9:41 我们就假设调用已经完成了
9:43 并且假设工具的返回结果是写入成功
9:46 所以我们回复observation写入成功
9:50 拿到这个结果后
9:51 DeepSeek又开始运行了
9:53 这次它还是先用thought标签思考了一下
9:56 然后再使用action标签请求写入css文件的内容
10:00 我们照例回复写入成功
10:02 DeepSeek又开始返回了
10:04 让我们稍等一下
10:08 可以看出DeepSeek还是先用thought思考
10:11 再用action请求写入js文件的内容
10:15 我们还是回复写入成功
10:17 然后DeepSeek的返回就有了些变化
10:20 因为三个必要的文件都已经写入完成了
10:22 不需要再调用工具了
10:24 因此DeepSeek在thought之后
10:26 返回了一个final answer
10:27 整个回答就彻底结束了
10:29 你看这就是ReAct模式真正运行时的节奏
10:32 每一步都按照系统提示词的要求来
10:35 thought action observation
10:39 一直到任务完成
10:41 此时会输出thought和final answer
10:43 系统提示词就相当于
10:44 给模型安排了一个迷你剧本
10:46 它会严格按照这个剧本一步一步的走完
10:53 前面我们用DeepSeek演示了一个Agent的运行流程
10:56 可以看到整个流程的关键在于系统提示词
10:59 它决定了模型该如何一步步运行
11:02 其实在这个系统提示词的基础上
11:04 再加上一些配套的代码
11:06 我们就可以搭建出一个真正可用的ReAct Agent
11:09 实际上我已经把这个Agent写好了
11:11 就放在我的github仓库里
11:14 有需要的同学可以自行获取
11:16 接下来我先演示一下这个Agent的使用过程
11:19 随后再带大家一起看一遍它的代码
11:22 我已经进入到这个Agent所处的项目目录了
11:25 我们先执行一下tree命令
11:27 看一下这个项目目录里面都有什么文件
11:31 这里文件很多
11:32 但实际上你只有两个文件需要留意一下
11:36 第一个是agent.py文件
11:37 这个文件里面就写了我们的Agent的代码
11:40 我们等会儿要运行的就是这个文件
11:43 另外一个是snake文件夹
11:46 它里面什么也没有
11:48 我用tree命令给你证实一下
11:52 可以看出确实没有任何文件
11:55 等会儿我就会让Agent把代码写入到这个文件夹里面
11:59 好介绍完毕
12:00 下面我们来执行一下这个Agent
12:02 让你看看它是如何运作的
12:04 首先我们启动一下这个Agent
12:07 我们用的命令是
12:08 uv run agent.py snake
12:11 前面的uv run agent.py
12:13 就是用来启动agent.py文件的
12:16 后面的snake是agent.py这个脚本的第一个参数
12:19 意思是告诉agent.py
12:21 它要操作的项目目录是snake
12:24 代码就写在那里面
12:25 agent.py首先向我们询问需要完成的任务
12:29 我们的任务就是
12:29 写一个贪吃蛇游戏
12:31 使用html、css和js实现
12:34 代码分别放在不同的文件中
12:37 回车
12:37 agent.py已经开始运行了
12:39 它现在正在请求大模型
12:42 我这里采用了同步返回的机制
12:44 所以需要等模型把所有内容都生成完毕之后
12:47 才能看到结果
12:48 其实也可以用流式返回的
12:50 模型返回几个字就能看到几个字
12:53 这样可能效果更好一点
12:55 不过代码的复杂度会增加
12:57 所以综合权衡之后
12:59 我就没有使用流式返回
13:01 好
13:01 看到第一轮的结果了
13:03 我们的结果一共是包含三个部分
13:05 Thought
13:06 Action
13:08 Observation
13:09 跟我们之前在DeepSeek那里看到的一模一样
13:13 这里的Action是请求调用
13:15 write_to_file工具写入
13:16 index.html文件
13:18 后面的Observation显示的就是具体的调用结果了
13:21 写入成功
13:23 注意啊
13:23 这个写入成功可不是模拟的
13:26 这是真的执行了write_to_file工具
13:28 工具也真的返回了写入成功这几个字
13:31 好
13:31 这个呢是第一部分
13:33 我们把滚动条往下拉一拉
13:35 看一下剩下的返回是个什么样子的
13:37 后面的流程呢也基本类似
13:40 可以看到在Observation之后
13:42 Agent会再次请求模型
13:43 然后Agent就又进行了一段Thought
13:48 Action
13:48 Observation
13:50 这一轮写入的是CSS
13:53 我们再把滚动条往下拖一拖
13:54 在这里我们就可以看到第三轮的Thought
14:01 Action
14:04 Observation
14:05 这次写入的是JS
14:08 最后所有文件都写完之后
14:09 它会给出Thought
14:12 和FinalAnswer
14:13 整个流程就结束了
14:15 再看看snake文件夹
14:18 确实三个文件都有了
14:20 执行index.html
14:22 看看游戏能不能玩
14:27 可以看到界面出来了
14:28 我们动一下
14:29 确实也是能动的
14:31 然后吃一个红色的方块呢
14:33 也是可以吃的
14:34 左上角是分数
14:35 看来运转的非常顺畅
14:37 从这个结果中也可以判断出
14:39 我们这个Agent做的非常成功
14:41 完全可以作为一个简化版的 Claude Code 来使用
14:45 下面我们来看一下这个Agent的具体代码
14:47 我们首先从入口处看起
14:49 这里面的project_directory
14:51 就是我们传给Agent.py文件的第一个参数
14:53 也就是snake那个文件夹
14:55 tools代表可用的工具列表
14:58 我们这里给出了三个
14:59 分别用于读取文件
15:01 写入文件和运行终端命令
15:04 这些都是很实用的函数
15:05 我们可以大体看一下
15:09 这个是读取文件
15:11 这个是写入文件函数
15:13 这个是运行终端命令
15:16 从这里可以看出工具确实就是函数
15:19 让我们回到原来的主链路继续往下看
15:24 这里的ReActAgent便是这个文件的核心了
15:27 它是一个类
15:28 构造这个类的时候需要提供三个参数
15:31 第一个是工具列表
15:32 这个我们前面已经构建好了
15:34 这里直接传了进来
15:36 第二个是我们要用的模型
15:37 我们这里用的是GPT-4o
15:40 第三个是项目目录
15:41 也就是snake文件夹
15:43 传好了这三个参数之后
15:45 我们便获取到了一个agent变量
15:48 之后我们会提示用户输入任务内容
15:50 然后我们把用户任务传入
15:53 agent.run函数
15:54 这个函数是ReActAgent的核心
15:57 调用它就相当于是启动了这个Agent
16:00 之前提到的Thought
16:01 Action Observation和FinalAnswer
16:03 都是在这个函数内部依次处理的
16:06 它处理好了之后
16:06 会给出一个最终答案
16:09 并且把这个final_answer输出到屏幕上
16:12 到这里主链路就结束了
16:14 可以看到这段代码的核心是ReActAgent
16:16 我们来看一下它里面写了些什么
16:19 首先它这里定义了一些自身的属性
16:22 分别是工具列表
16:24 项目目录和模型调用客户端
16:27 到这里
16:28 构造函数就结束了
16:30 后面我们要看的函数便是这个Agent的重点
16:33 Run函数
16:36 这个函数的参数是用户输入的任务
16:39 在函数的内部
16:40 它先构建了一个Message列表
16:42 里面有两个元素
16:43 分别是系统提示词
16:46 和用户问题
16:47 系统提示词是用render_system_prompt这个函数来渲染的
16:52 它接受一个参数是系统提示词模板
16:54 模板里面的内容是这个样子的
16:56 跟我们之前讲的那个系统提示词
16:58 基本上是一样的
17:00 只不过这个模板里面有一些占位符
17:02 比如说是工具列表
17:04 操作系统
17:06 当前目录下的文件列表等等
17:08 这些占位符都是render_system_prompt函数
17:10 在运行的时候填进去的
17:12 在拼接好了Message列表之后
17:14 我们使用call_model函数
17:16 调用了模型
17:16 拿到了模型的执行结果
17:19 然后我们提取出返回结果中的thought部分
17:21 并且打印了出来
17:23 然后代码会检测thought之后的内容
17:26 是不是final answer
17:27 如果是的话
17:28 我们返回这个final answer
17:30 函数执行到此结束
17:32 如果不是的话
17:33 那content里面一定就包含action了
17:36 我们此时就把action给解析出来
17:38 提取出其中的函数名和参数列表
17:42 然后判断了下当前工具
17:44 是不是运行终端命令的工具
17:46 如果是的话
17:47 我们会提示用户是否继续
17:48 因为运行终端命令比较危险
17:51 所以现在一般用于编程的Agent
17:53 都会在运行终端命令之前
17:54 主动询问用户是否要执行
17:57 之后没有问题的话
17:58 我们就会去执行工具背后的函数了
18:01 并且把执行结果放到observation里面
18:04 再把observation放到message列表里面
18:07 因为我们在一个while循环里面
18:08 所以我们下一步还会来到循环的开头这里
18:12 继续请求模型
18:13 我们给call model这个函数
18:15 传了message列表作为参数
18:17 工具执行结果不是作为observation
18:19 放到了message列表里面了吗
18:21 而message又传给了模型
18:23 这样模型就可以拿到工具的执行结果了
18:26 它进而就可以根据工具的执行结果
18:28 推测下一步要干什么
18:30 所以总结一下这个while循环做的事情
18:33 请求模型
18:33 提取thoughts
18:37 检测final answer
18:41 提取action并执行其中的工具
18:43 这个过程会一直重复下去
18:46 直到模型返回了final answer为止
18:49 回想一下
18:50 这正是我们之前所提到的ReAct运行流程
18:57 为了确保你彻底明白这其中发生了什么
18:59 我们来画个Agent的流程图
19:02 整个流程图里面有两个角色
19:03 用户和Agent
19:06 而Agent又可以分成三个部分
19:07 分别是模型
19:10 工具
19:10 也就是函数
19:12 还有Agent主程序
19:14 Agent主程序这个词我们之前没有提过
19:17 其实就是Agent里面负责串联整个流程的代码逻辑
19:21 它会在合适的时候
19:22 调用工具或者是模型等等
19:25 你可以大致理解为我们刚才代码里面的那个run函数
19:28 下面我们就来画个流程图
19:30 看看这四个角色之间是怎么沟通的
19:33 在用户提交任务之后
19:35 任务先到了Agent主程序这里
19:37 Agent主程序会先去调用模型
19:40 模型返回thought和action
19:42 Agent主程序把thought和action打印给用户看
19:45 然后去调用action里面的指定工具
19:48 工具执行完毕之后返回结果
19:51 Agent主程序把结果发回给用户看
19:54 然后把这个工具执行结果加入到历史消息列表里面
19:58 然后再次重复这个框中的流程
20:00 也就是请求模型
20:01 并处理thought,action和observation的逻辑
20:04 直到某个时刻
20:06 在请求模型后
20:07 模型认为用户的任务已经完成了
20:09 不需要再调用工具了
20:11 它就会返回thought和final answer
20:13 Agent主程序把thought和final answer展示给用户看
20:17 整个流程就结束了
20:18 这就是一个完整的ReAct Agent的问答流程
20:25 前面我们讲了如何使用ReAct模式
20:27 来构建一个Agent
20:28 ReAct是目前最常见
20:30 使用最广泛的Agent构建模式
20:32 但它不是唯一的方案
20:34 除了ReAct之外
20:35 还有很多其他的运行模式
20:38 其中很多Agent的运行过程
20:39 就是先规划再执行
20:42 比如我们之前演示过的Manus
20:43 如果你仔细看的话
20:44 就会发现它在一开始回答的时候
20:46 会构建一个待办列表
20:48 后面的执行过程
20:49 都是遵循这个待办列表来
20:51 而Claude Code中
20:52 也会经常看到这种先创建TODO
20:55 再去执行的情况
20:57 这种先规划再执行的模式
20:58 目前并没有一个统一的名字
21:00 而且每个Agent的实现多多少少
21:03 也会有一些差别
21:04 我们今天来讲一个其中比较有名的实现
21:06 是LangChain提出来的Plan-and-Execute模式
21:10 从总体上来看
21:11 它也是遵循了先规划再执行的流程
21:15 只不过它的流程引入了一些动态修改规划的环节
21:18 这使得它的方案有了很大的灵活性
21:23 我们先用时序图来画一下Plan-and-Execute模式的运行流程
21:27 首先我们要搞清楚这个时序图里面有多少个角色
21:31 粗分下来的话那肯定只有两个了
21:33 一个是用户
21:34 另外一个是Plan-and-Execute Agent
21:37 不过既然要研究Plan-and-Execute Agent的运行流程
21:40 我们就肯定要搞清楚这个Agent的组成部分
21:44 首先它里面有一个负责出执行计划的模型
21:47 我们称它为Plan模型
21:49 我们在运行的过程中
21:51 还需要根据每一步的执行结果来动态的调整计划
21:54 因此我们还需要一个负责修改执行计划的模型
21:58 我们称它为Re-Plan模型
22:00 Plan和Re-Plan模型可以是同一个
22:02 也可以分成两个
22:04 都是可以的
22:05 我们暂且将它们列为两个
22:07 除了这两个模型之外
22:08 我们还需要一个负责执行这个计划中每一个步骤的Agent
22:12 我们称它为执行Agent
22:15 对你没看错
22:16 这个Plan-and-Execute Agent内部还有一个Agent
22:20 这种Agent套Agent的设计方案其实也是比较常见的
22:24 最后跟ReAct那个流程一样
22:26 我们还需要一个Agent的主程序
22:29 负责串联整个流程
22:30 这就是Plan-and-Execute Agent的全部模块了
22:34 下面我们就把它们放在流程图里面
22:36 看看各个模块之间是如何运作的
22:39 首先用户会把问题提给Agent的主程序
22:42 比如我们的问题就可以是
22:44 今年澳网男子冠军的家乡是哪里
22:48 这里的澳网指的是每年举办的澳大利亚网球公开赛
22:51 也就是个体育赛事了
22:53 Agent的主程序接到这个问题之后
22:55 会把这个问题发给Plan模型
22:57 让它给出具体的执行步骤
22:59 比如一个可能的执行步骤就是这样的
23:02 先查询当前日期
23:04 然后查询在当前年份下澳网男子冠军的名字
23:08 比如当前时间是2025年的话
23:11 就查询2025年的澳网男子冠军的名字
23:13 如果当前年份是2024年的话
23:16 那就查询2024年的澳网男子冠军的名字
23:19 查出名字后
23:20 我们再根据这个名字来查询这个冠军的家乡
23:24 没错
23:24 这就是一个非常合理的执行步骤
23:27 那计划有了之后
23:29 Agent的主程序便会把这个计划传给执行Agent
23:32 让它去执行这个计划中的第一步
23:35 也就是查询当前日期的那个步骤
23:38 这个执行Agent可以用我们之前讲的ReAct模式来运行
23:42 它内置一个网络搜索工具
23:44 这样它就可以通过搜索网络来查询当前日期了
23:48 当然执行Agent也完全可以用别的模式来运行
23:52 Plan-and-Execute模式
23:54 只要求执行Agent能够完成指定的步骤就行
23:57 至于它的运行模式是不是ReAct
23:59 内置工具有哪些
24:01 它完全不关心
24:02 执行Agent内部一顿操作之后
24:04 就吐出了一个执行结果并返回回去
24:06 然后Agent的主程序会把用户问题
24:09 执行计划和执行记录都发给Re-Plan模型
24:12 让它生成一个新的执行计划
24:14 毕竟我们拿到了第一步的执行结果了
24:17 多了一些信息
24:18 情况可能会发生些变化
24:20 把原计划改改实在正常不过的事情了
24:23 那Agent的主程序接到新的执行计划之后
24:26 它便会回头再重复这个框中的流程
24:29 在我们这个例子中
24:30 这个框中的流程一共会运行三轮
24:33 对应了执行计划里面的三步
24:35 每一轮都包含两个环节
24:37 一个是执行环节
24:40 一个是Re-Plan环节
24:42 为了能够让你彻底明白
24:43 我们模拟一下这个循环中的三轮
24:46 让你看看每一轮的执行环节和Re-Plan环节
24:49 都具体发生了一些什么事情
24:51 在模拟开始前
24:52 我先打个预防针
24:54 为了节省时间
24:54 我在模拟时讲解的速度会稍微快一些
24:57 如果你听不懂
24:58 建议在合适的时候稍微停一下
25:01 好让我们开始
25:02 首先是第一轮
25:03 在执行阶段
25:04 我们把执行计划发给执行Agent
25:06 让他处理其中的第一步
25:09 执行Agent返回之后
25:11 我们把他给出的执行结果
25:12 加入到历史执行记录里
25:15 然后把用户问题
25:16 第一个执行计划和历史执行记录
25:19 一起发给Re-Plan模型
25:21 让他给出第二个执行计划
25:22 第一个执行计划和第二个执行计划
25:25 有两点不同
25:25 这里我专门说一下
25:28 首先原来查询当前日期的那一步
25:30 就不用出现在第二个执行计划里面了
25:33 毕竟已经执行完了
25:34 不用再执行了
25:35 另外查询澳网男子冠军名字的这一步
25:39 也发生了一些变化
25:40 在第一个执行计划中
25:42 他叫做查询对应日期的澳网男子冠军名字
25:46 在第二个执行计划中
25:47 他叫做查询2025年的澳网男子冠军名字
25:51 毕竟日期已经查出来了
25:53 因此我们可以直接把具体的年份
25:55 放到执行计划里
25:57 这样执行Agent接到的任务
25:59 就更加精确了
26:00 然后进入到第二轮
26:02 在这一轮中
26:03 我们同样先取出最新的执行计划
26:05 发给执行Agent
26:07 让他执行其中的第一步
26:09 拿到执行结果后
26:10 我们再把执行结果加入到历史执行记录中
26:13 然后在Re-Plan阶段把用户问题
26:16 执行计划和历史执行记录
26:18 发给Re-Plan模型
26:19 拿到第三个执行计划
26:21 在第三轮中
26:22 我们还是先取出执行计划
26:24 让执行Agent处理其中的第一步
26:27 当然现在也只剩一步了
26:29 执行之后
26:30 我们就可以拿到一个执行结果
26:32 把执行结果加入到历史执行记录里
26:35 然后再把用户问题
26:36 执行计划和历史执行记录
26:38 都发给Re-Plan模型
26:40 让他再生成一个......
26:41 哎,好像所有的任务都已经完成了
26:44 没有步骤要做了吧
26:45 没错
26:46 在最后一轮中
26:47 Re-Plan模型会发现
26:49 所有的步骤都已经做完了
26:50 用户的问题可以回答出来了
26:52 此时Re-Plan模型返回的
26:54 就不是最新的执行计划了
26:56 而是最终的答案
26:58 所以在流程图里面
26:59 我们也要把执行计划
27:01 换成最终答案
27:02 Agent主程序
27:03 接到这个最终答案之后
27:05 便会把这个答案转发给用户
27:06 整个流程也就结束了
27:09 所以回头看一下这个流程图
27:10 我们之前说Agent主程序
27:13 请求Re-Plan模型
27:14 给出一个新的执行计划
27:15 这个说法其实并不准确
27:18 更准确的说法是
27:19 Agent主程序请求Re-Plan模型
27:22 给出一个新的执行计划
27:24 或者是返回最终答案
27:27 如果还有步骤要执行的话
27:28 那就给出一个新的计划
27:30 如果没有步骤要做了
27:31 用户的问题已经回答出来了
27:32 那Re-Plan模型就返回最终答案就好了
27:36 因此Re-Plan模型的返回
27:37 也有两种可能性
27:39 新的执行计划
27:40 或者是最终答案
27:42 这样才是一个准确的流程图
27:44 相信到这里为止
27:46 你对Plan-and-Execute流程
27:47 就有一个非常清晰的认识了
27:50 不过有些人可能想要
27:51 Plan-and-Execute的具体实现代码
27:53 LangChain官方提供了一份
27:55 你可以到这个页面里面自行获取
28:01 今天的视频就到此结束了
28:03 别忘了点赞
28:04 关注
28:04 我们下次再见
28:05 拜拜