夜雨聆风学习资料网

ARTICLE · 1289232

【AI Agent】搭建「Agent型」RAG

【AI Agent】搭建「Agent型」RAG

【合辑】AI Agent 开发›

上一次我们搭建了 生产级别的RAG

But!这个 RAG 属于是固定流程的检索

就是每一步要干嘛,都是写死的程序中的

固定流程都有什么步骤?

比如 大致的主要步骤如下

其中的步骤就不多介绍了,不懂的可以先看 生产级别的RAG

那这个固定流程有什么问题???

其实问题不大,已经很完善了,在知识检索上,也能满足大部分的问题

但是主要吃力在 复杂问题 的检索上

简单说就是三类(后续会详细介绍),这里也不扯这么多

所以其实最大的问题,就是

不够灵活

你想想一个固定的流程,如何能满足无穷无尽 各式各样的 用户问题??

那如何满足??

当然是交给 灵活的大模型 来处理

所以 Agent 型 RAG 就来了

但是不要怕,说到底

只是把 固定流程的一部分 抽离出来,交给Agent 来决策吧了

所以 本质上的话,其实没有太大的差异

但是他是非常必备的一个模式,所以今天就来到我们的第一个部分

01

Agent RAG 是什么

上一篇我们说到

Agent RAG 只是把 固定流程 的一部分抽离出来,Agent 自己决策怎么做

比如说

Agent 可以先尝试检索,再根据检索的结果,来决定下一步

—— 再查什么/还查不查/怎么查

也就是,原来由程序规定 下一步做什么,现在由 Agent 决定

而 Agent 的核心是什么?

大模型的灵活性

所以 Agent RAG 是什么

就是在 大模型的基础上

把原来 硬约束的程序逻辑 ,便成了 软约束的提示词

比如 像是系统提示词是,我先简单点说

你是知识助手,先用工具找完资料,再回答问题

你有 a、b、c 三个工具

如果是说明类问题 就用 a 工具,如果是数据查询就是 b工具

只依据工具返回的资料回答,不用自己补充

如果判断资料够了,就直接回答

资料不够就继续查,不能回答就说没有找到....

而 Agent RAG 从 固定流程 中抽离了什么部分,如下图

抽离的这些部分,就从现在的 

  • 串行式的工作流架构 

  • 变成了 

  • Agent主从架构

其中的 几个步骤,全部交由 Agent 内部的大模型处理

其他的通过 工具 和 外部数据进行交互

检索工具内部的流程仍然保持流程一致

Agent 虽然灵活,但也意味着不稳定性,所以让检索流程保持统一,是 灵活 和 稳定性 之间的权衡

并且 检索流程中涉及很多参数,都是需要调试出来的,不应该让大模型去猜

所以 Agent RAG 只是增加一种能力,而不是全盘改造

模型的自由度,增加解决复杂问题的能力

程序的确定性,来保证结果的稳定性

说到这里,其实这在很多场景都体现有这种 确定性 和 自由度 的 权衡问题

暂时偏离主题一会会哈,说个其他知识

在操作系统中,有 实时OS 和 通用OS

实时OS 强调实时性,确定性,用在汽车/医疗/航天,因为分秒必争,关乎任命

实时性,就是 所有事情必须在规定时间内给出回应,每一步都必须在规划设计内

  • 所有运行的任务都是确定好的

  • 所有运行任务的开始时间都是确定好的

  • 所有运行任务的执行时间都是确定好的

不容许有变动

而 通用 OS,则是 基于效率和公平,追求整体响应快,可以动态调整任务执行,防止过度等待,比如 个人电脑,手机 等等

这便是 确定性 和 自由度 权衡的一个经典案例

感兴趣可以看 实时OS

那我们这一节的目标聊完了 Agent RAG 是什么

就来到我们的下一节

02

Agent RAG 流程怎么走

这部分主要先介绍了 Agent RAG 执行的整个流程

对这部分有一个整体的感知

项目就是之前开源在 Github 的 生产版,加了 Agent 模式

https://github.com/Hooho/production-rag

这是预览能力的演示地址,非真实可操作 (手机适配没怎么做)

https://page.hoholoving.com/rag-demo

然后系统中可以详细看到每一轮的详细数据

  • Agent 怎么思考的

  • Agent 要查什么,查到了什么

  • 怎么决定下一步的...等等

大概的项目演示就这样

我们首先来看其中的 Agent 逻辑

核心就是其中的

ReAct 循环

全称是 Reasoning + Acting,意思是 推理+行动

—— 模型先思考,再调用工具,看到工具结果后再思考,如此循环,直到可以回答

我们先通过一个简单的例子来走一遍

  • 第 1 轮输入:系统提示词 + 问题 A—— 输出决定调用 工具 B

  • 第2轮输入:系统提示词 + 问题 A + 工具 B 的结果—— 输出:决定调用 工具C

  • 第3轮输入:系统提示词 + 问题 A + 工具 B 的结果 + 工具C 的结果—— 输出:资料已经够了,循环结束,直接输出回答

如果对这个还有问题,那么我就针对实际的问答来走一遍 Agent 循环

比如我问了一个问题

“他赚了多少钱,最多的一笔赚了多少”(前面已经问了很多了,他指段永平

第一轮Agent 收到的输入

就包含五个部分

  • 可调用的工具

  • 系统提示词(不用多说了吧

  • 长期记忆(就是关于你的身份,一些回答偏好

  • 短期记忆,就是本会话内所有记忆

  • 本轮问题

如下图(就不细说了,这些内容和 固定流程也没什么区别

第一轮Agent 的输出

Agent 接收到上一步的内容,发给大模型之后

大模型开始处理,并输出内容

  • 思考过程(就是决定做什么,为什么这么做

  • 内容(一般就是最终回答,如果资料查够了,才有这个字段,不然就是空字段

  • 工具,就是本次模型决定调用什么工具

比如这一次的思考过程是

让我搜索知识库中关于段永平的利润、净资产以及单笔最大收益的具体数值。

我来进行并行搜索:

1. search_knowledge 混合检索:“段永平投资赚了多少钱,身家多少亿”

2. search_knowledge 混合检索:“段永平哪一笔投资赚得最多,最大盈利金额”

或许还可以用 query_data?不,这是关于某人的知识库内容,不是商业数据。

我来并行执行这两次搜索

然后 大模型就决定调用 知识检索工具 两次

返回结构化的调用信息(这是 function calling,这样外部的程序就可以直接解析,从而去调用工具 

第一轮工具调用

拿到模型想要调用工具,传入 模型 设置的参数

工具内部就开始执行,是已经固定了的程序流程逻辑(只截图一个

得到工具执行结果

准备在下一轮继续发给 Agent,开启下一个循环

第2轮Agent 接收的输入

主要就是新增了工具调用的结果 + 上一轮 大模型的输出

详细说内容就是两部分

  • 上一轮 大模型的 思考过程 + 工具决策

  • 工具调用结果

本轮全部返回过去,相当于是把所有的操作日志,原封不动地传入

因为大模型是没有记忆的,要让他知道他之前是怎么思考的,调用了什么,从而帮助它这次的决策

第2轮Agent 的输出

这部分就略了,内容差不多,就是

  • 再次思考

  • 决定是否再调用工具,决定怎么调用,查什么内容

比如这次就决定换一种查询的角度和方式

第2轮工具调用,略!
第3轮Agent接收的输入,略!
第3轮Agent 的输出

本次大模型觉得资料已经够了,就不再调用工具

直接输出回答

至此,循环就结束了

所以整个循环就是这样

  • 调用了两轮工具,得到了结果

  • 最后一轮,直接生成回答

哦莫,那这个 Agent 流程

我们就已经清楚得不能再清楚了吧

具体的内容,可以看我这个预览界面

https://page.hoholoving.com/rag-demo/#chat

不清楚的你来评论区和我battle

Agent RAG 执行流程我们熟悉了

那这个流程是怎么搭建的呢,就来到我们的下一个部分了

03

Agent RAG 怎么搭建

这部分不会说得太细,而是把大体的主要逻辑说出来

现在谁还主要关注代码啊!!

本来这个 Agent 循环也不是什么 高难度的玩意

就给一些伪代码吧

在固定流程的基础上,只是新建一种 Agnet 回答模式,所以并不算特别大的改动

我们先看固定流程的一份伪代码,然后和 Agent 的对比

而 Agent的部分就简单多了

但是重点在于其中的 Agent 循环

没错,就是一个 While 循环

看到了吧,所以其实这个 Agent 循环 并不是什么高难度的逻辑

但是最重要的是不是它的实现,而是

如何去限制 Agent

因为前面说过了

固定流程 和 Agent 模式的区别,无非就是

把 程序的硬约束代码逻辑 变成了 软约束的大模型提示词 

所以就会出现两个问题

  • 不遵守提示词(不鸟你

  • 出现幻觉,查询无限扩大化

1不遵守提示词,可是太常见了

比如以本项目碰到的问题为例,为了避免 Agent 无限制查下去,我在提示词中已经写清楚了

  • 资料够回答就停,不为细节继续查

  • 同一个小问题最多检索两次

  • 看到“这次检索没有新资料”,就用已有资料回答

结果 Agent 查了3轮,每轮检索了四次,只有第1轮命中资料,然后白白 查询了两轮,白查了4次

最后花了 57秒,用了 2.9w token

又费时,又费Token

2出现幻觉,查询无限扩大化

Agent 目的也是为了查得更全面

会拆分各种小问题,越拆越细

比如项目中一个例子就是,我问 “段永平和 小霸王有什么关系”

最后 Agent 去查了 段永平在这几家公司的持股情况

就像我问你,“你和你爸妈是什么关系”

你不仅跟我说,你是你爸妈一把屎一把尿带大的,还介绍了 爸妈是怎么认识的,经历了多少磨难,生你的时候还特别困难,超生了还罚款

罗里吧嗦的,查的次数越来越多,答案越写越长,离原来的问题也越来越远。

自作主张,一个小问题越查越大

所以在这方面来说

有些规则只写在提示词里管不住,要改成程序硬约束检查

所以这里主要就是

  • 1.在程序中限定 查询次数

  • 2.在程序最后一次中强制回答

在程序中限定 查询次数

—— 限制工具调用次数,默认最多 6 次,超过6次就强制回答,不给你再调用工具了

不过这个次数其实可以根据自己的资料来调试,看你的统计,是否大部分问题在 6次以内基本就能回答好

比如我的项目评测统计中

也就是说

证据全部拿齐的 165 道题里,在第几次调用拿齐

  • 前 2 次就拿齐的:133 道(81%)

  • 6 次以内拿齐的:164 道(99%)

次数被浪费的情况

  1. 87 道题(38%)把 6 次预算用满,被强制回答

  2. 906 次检索里,247 次一个新分块都没拿到(27%)

在程序最后一次中强制回答

目前我的做法是,如果工具调用6 次用完

程序再调用一次模型,但这次请求里不带任何工具,并提示它根据已有资料直接回答。模型手里没有工具可用,只能写答案

其实也让模型自己选择不调用,但是 tool_choice 这个参数 MiniMax 的文档里没写支持,所以直接不带 tools,最可靠

那现在我们姑且就算搭好了一个 Agent RAG

那这个 Agent RAG 是不是真的像我们期望的那样厉害

可以解决那些复杂的问题?

是不是真的比 固定流程要好?

总不能理论上是可以就不管了吧!!!!

所以我们要针对 Agent RAG 进行评测!!

管生还管教!

↓

04

Agent RAG评测

在评测中,我们要把 Agent 模式 和固定流程放在一起,用同样的题、同样的标准去比

去追寻两个问题

  • Agent 在复杂问题上,是不是真的比固定流程回答更好?

  • Agent 的能力,需要花多少代价,比如 时间、token?

所以这里新建一个评测集,分成三类题目

  • 多跳题

  • 比较题

  • 宽泛汇总题

这就是属于 复杂的动态问题

就是那种

无法一次查询就查到答案的问题

要查很多次,还要换不同角度查才行 那种

所以 这三类题,是比较能体现 Agent 能力的,距我多次评测的结果来看,Agent 确实都能拿到很高的分数

一共12道题,40个计分项

OK,先来介绍这三种题吧

1多跳题

就是一起问两个问题,A + B

你无法直接搜索B,你必须先搜索A 得到资料,再根据资料 才能去搜索B

比如我问,“我出生的那年,大A 涨跌多少”

你直接单独查 “我出生的年份” 和 “大A 涨跌多少” 都不行

你必须先查 我的出生年份之后,才能去查 大A 涨跌多少

很明显,固定流程在这方面就很吃力

在多跳题上的具体表现就很明显了

2比较题

这总体,就是 一个题目里面包含多个不相关的子题目,需要分别查询,然后再结合在一起回答

其实这类问题,属于是针对固定流程的缺陷进行打击的

比如我一次性问了 A+B ,固定流程目前的 查询改写,可以分成2个子问题 进行查询

  • 先查A,得到A问题的资料

  • 再查B,得到B问题的资料

但是在固定流程中,有两个步骤是

重排 + 阈值过滤

  • 重排:把 用户问题 和所有找到的 资料 分别进行计算,得到相关性分数

  • 阈值过滤:则是把 相关性分数低的过滤掉

问题就出现在 这两个环节上

因为完整问题是 A+B,而最后重排的时候,却会拿A+B 和 每个子问题得到的资料 进行 单独计算,从而得到相关性分数

  • A+B 和 子问题A 得到的资料 算分

  • A+B 和 子问题B 得到的资料  算分

每段资料只回答了问题的一部分,和完整问题一比较,相关度就被稀释了,分数就低了,直接被阈值过滤掉

结果就是,明明查到了,却没交给模型,问题只能答一半 或者可能无法回答

实际的表现也是如此

具体在我这次的评测链接中

    https://page.hoholoving.com/rag-demo#/eval/runs/20261029-143746_unknown

    很明显可以看到 资料因为重排分被过滤,每道比较题都是

    Agent 在这方面简直无敌,因为 Agent 是 单独检索 单独重排的

    Agent 每次检索只查一件事,用这件事自己的检索词去重排,资料相关度不会被完整问题稀释

    当然了,也不是说 固定流程 无法优化,比如说直接把阈值调低就完美解决哈哈

    但是你就可能会携带上不相关的资料,影响大模型的回答质量

    当然也有其他的做法

    比如 FastGPT 的做法是重排分和召回名次一起算,也能缓解这个问题

    具体你可以看我写的 各种开源RAG 对比

    所以在比较题上,并不算是 Agent 的明显优势

    真正我觉得拉开差距的是下面这一列题

    3宽泛汇总题

    这一类就属于考验 Agent 推理能力的题了

    题目十分宽泛,你需要一步步获取资料,然后调整查询的方向,才能找得到答案

    比如我问 ,“段永平的书里拿哪些公司当反面例子?”

    大模型 怎么知道什么是反面例子?

    它只能一点点推理(根据返回的资料,或者 自己的知识

    比如 试图命中一些关键词 “衰落” “倒闭” “失败”

    然后再继续根据返回的资料,进行推理,比如我摘取了部分 思考过程

    只摘取其中的重要部分

    ....

    我需要再检索一下书中的负面案例:乐视?京东?网易?夏新?UT斯达康? 可能还有其他。让我检索"段永平 投资失败 亏损 案例"以及"东方园林 乐视 诺基亚 反面案例"。

    还有可能是《投资的本质》中的"反面教材"章节。让我搜一下。

    具体检索: 1. keyword/vector: "段永平 投资失败 例子 亏损 教训 公司" 2. "东方园林 乐视 财报 造假 例子"

    你可以看到它下一步开始查询

    —— 造假、投资失败、亏损

    从而又命中了新的资料

    这一轮查询完之后,它又继续推理

    ....

    还可能有的:夏新/乐视/网易(网易是正面)、UT斯达康? 需要再检索一下书中的其他负面案例,比如"夏新""诺基亚""柯达""黑莓"等。也可能有"UT斯达康""福光"等。

    让我做一次针对更多反面案例的检索,问"书中提到哪些经营失败、走下坡路的公司,如衰落、破产、造假、盲目扩张"

    所以Agent 就是可以利用自己的推理能力,一点点调整查询的方向

    —— 利用模型自身的常识+ 上一步提供的资料,来决定下一步查询的方向

    这便是 Agent 最大的优势

    虽然它也无法保证百分百拿到所有资料,但是已经比 固定流程 表现要好得多,上限高得多

    比如它也可能无法推理出 “业务升级失败” “老板不靠谱” “管理层净吹🐮逼” 这种反面案例的查询方向

    比如 富国银行虚开账户被罚 30 亿 的部分,意思上是反面例子,但用词完全不沾边,Agent 实在查询不到

    从这三类题目,我们已经可以感受到 Agent RAG 的能力所在了

    重点的优势就是,动态自由灵活,解决复杂的复合问题

    Last

    最后

    好了,Agent RAG 的内容差不多就讲到这里了

    它无法替代 固定流程RAG 的能力,它属于是在原来的基础上赋能,解决更多查询场景的问题

    不是说 Agent RAG 就一定比固定流程的好

    如果只是简单事实查询的话,固定流程会更快更高效更省钱

    Agent RAG 属于是拓宽能力上限

    (完)

    回首页,搜索你想要的文档

    在首页搜索框输入关键词,快速定位资料

    文库首页搜索指引 立即搜索

    相关学习资料