当前位置: 首页 > news >正文

HelloAgents:RAG——让 Agent 学会检索知识

HelloAgents:RAG——让 Agent 学会检索知识

一、为什么需要 RAG?

随着 ChatGPT、Claude 等大语言模型的发展,人们越来越习惯向 AI 提问各种问题。

例如:

今天北京天气怎么样? Transformer 是什么时候提出的? 帮我阅读这篇论文。 解释一下公司的内部接口文档。

虽然大模型拥有庞大的知识储备,但它并不是万能的。

它存在一个天然缺陷:

模型的知识来源于训练数据,而不是实时互联网。

这意味着:

  • 训练完成之后,模型参数基本固定;
  • 无法自动学习最新知识;
  • 更不知道企业内部的数据。

例如:

公司内部产品说明书 最新 API 文档 实验室资料 PDF Word Markdown 会议纪要

这些资料,大模型训练时根本没有见过。

因此,即使模型推理能力再强,也无法回答这些问题。


LLM 的三个局限

HelloAgents 在介绍 RAG 时,也总结了目前 LLM 面临的几个主要问题。

1. 知识具有时效性

例如:

今天最新发布的论文是什么? OpenAI 最近更新了哪些模型?

这些内容可能发生在模型训练完成之后。

模型自然无法知道。


2. 无法访问私有知识

例如:

公司的产品文档 学校实验数据 医院病例 企业知识库

这些资料不会公开发布。

因此模型无法学习。


3. 容易产生幻觉(Hallucination)

这是目前 LLM 最大的问题之一。

例如:

用户问:

介绍一下 XX 公司新发布的软件。

模型没有相关知识。

但是:

它往往不会直接回答:

我不知道。

而是:

根据已有知识进行推测。

最终生成:

看起来很合理,

实际上完全错误。

这种现象就是:

Hallucination(幻觉)


二、RAG 是什么?

针对这些问题,目前最主流的方法就是:

Retrieval-Augmented Generation(RAG)

中文一般翻译为:

检索增强生成。

它的核心思想其实非常简单:

回答问题之前,不是直接让 LLM 作答,而是先去查资料。

整个流程如下:

用户提问 │ ▼ 检索知识库 │ ▼ 找到相关文档 │ ▼ 加入 Prompt │ ▼ LLM 回答

可以发现:

LLM 并没有直接回答问题。

而是先获得一份"参考资料"。

然后再根据资料组织答案。

这种方式就像考试时允许查阅参考书一样。


一个简单例子

假设知识库中保存了:

《Python 深度学习实践》 《机器学习导论》 《Transformer 原理解析》

现在用户问:

Transformer 是什么时候提出的?

传统 LLM:

直接依靠参数回答。

而 RAG:

首先检索知识库。

找到:

Attention Is All You Need 发表于 2017 年 Google 提出 Transformer。

随后把这段内容放入 Prompt:

已检索到资料: Transformer 来源于论文 《Attention Is All You Need》,发表于 2017 年。 请根据以上资料回答用户问题。

因此:

最终答案准确率会明显提高。


三、Memory 与 RAG 的关系

上一节我们已经介绍了 Memory。

很多同学容易把 Memory 与 RAG 混淆。

实际上,它们解决的是两类不同的问题。

可以用下面这张图理解:

Agent ┌─────────────────┐ │ LLM │ └────────┬────────┘ │ ┌──────────┴──────────┐ │ │ ▼ ▼ Memory RAG (历史记忆) (知识检索)

两者最大的区别就是:

MemoryRAG
保存 Agent 自己经历的信息查询外部知识
用户画像企业知识库
历史任务PDF、Word
用户偏好API 文档
长期存在根据需要动态检索

举个例子:

用户问:

推荐一本机器学习的书。

Agent 首先查询 Memory:

用户喜欢 Python。

然后查询 RAG:

Hands-On Machine Learning

最终生成:

考虑到你一直使用 Python, 推荐阅读: 《Hands-On Machine Learning》

可以看到:

Memory 决定:

推荐给谁。

RAG 决定:

推荐什么。

二者结合之后,Agent 才真正具有个性化能力。


四、HelloAgents 中 RAG 的整体流程

HelloAgents 并不是简单调用一个向量数据库。

而是构建了一条完整的数据处理 Pipeline。

整体流程如下:

外部文档 │ ▼ MarkItDown 文档解析 │ ▼ Document Processor │ ▼ 文本切分(Chunk) │ ▼ Embedding 向量化 │ ▼ Qdrant 向量数据库 │ ──────────────────────────────── │ 用户提问 │ ▼ Query Embedding │ ▼ Vector Retrieval │ ▼ Top-K 文档返回 │ ▼ Prompt Augmentation │ ▼ LLM │ ▼ 最终回答

整个流程可以分成两个阶段:


第一阶段:知识库构建(Offline)

这一阶段只需要执行一次。

主要完成:

  • 读取文档;
  • 文档解析;
  • 文本切分;
  • Embedding;
  • 写入向量数据库。

完成之后:

知识库就建立好了。

以后无需重复执行。


第二阶段:在线检索(Online)

真正回答问题时:

用户提出问题:

Transformer 是什么?

系统立即:

  1. 对问题进行 Embedding;
  2. 在 Qdrant 中搜索;
  3. 找到最相关几个 Chunk;
  4. 拼接 Prompt;
  5. 调用 LLM。

整个过程通常只需要几百毫秒。

相比直接让模型"猜",准确率会大幅提升。

下面继续第二部分。这一部分重点讲解HelloAgents 如何构建知识库,也是官方 8.3 节最重要的内容之一。


五、知识库是如何构建的?

上一节我们已经了解了 RAG 的整体流程。

那么,一个问题来了:

知识库中的数据是如何建立起来的?

例如,我们希望 Agent 能够回答下面的问题:

实验室规章制度有哪些? 这篇论文主要讲了什么? SpringBoot 项目如何部署? 公司的 API 如何调用?

首先需要把这些文档导入到知识库。

HelloAgents 将整个知识库构建过程划分为几个步骤:

原始文档 │ ▼ MarkItDown 文档解析 │ ▼ Document Processor │ ▼ 文本切分(Chunk) │ ▼ Embedding 向量化 │ ▼ Qdrant 向量数据库

只有完成整个流程之后,这些文档才能真正被 Agent 检索。


六、文档解析(MarkItDown)

现实中的知识通常不会直接以纯文本形式存在,而是保存在各种文件中,例如:

  • PDF
  • Word(.docx)
  • PowerPoint(.pptx)
  • Markdown
  • HTML
  • TXT

如果直接读取这些文件,LLM 很难理解其中复杂的格式。

因此,HelloAgents 首先引入了MarkItDown

什么是 MarkItDown?

MarkItDown 是微软开源的一个文档转换工具,它能够将多种格式的文件统一转换为Markdown

例如:

PDF Word PowerPoint HTML

经过 MarkItDown 后,都可以转换为:

# 第一章 这是正文…… ## 1.1 ……

为什么选择 Markdown?

因为 Markdown:

  • 保留了标题层级;
  • 保留了列表结构;
  • 保留了代码块;
  • 文本更加规整。

相比直接提取纯文本,Markdown 更容易进行后续处理。

因此,HelloAgents 将 Markdown 作为知识库的统一中间格式。


七、为什么不能直接保存整个文档?

很多同学刚接触 RAG 时都会想到:

既然已经得到 Markdown,为什么不直接存入数据库?

原因主要有两个。


原因一:上下文窗口有限

例如:

一本教材:

300 页

一篇论文:

40 页

一个产品手册:

1000 页

如果全部放进 Prompt:

Prompt + 整本书

不仅速度非常慢,而且已经超过 LLM 的上下文长度。

因此:

必须切分。


原因二:检索精度下降

例如:

一本《机器学习》教材包含:

第一章 绪论 第二章 线性回归 第三章 决策树 第四章 神经网络 第五章 Transformer

用户提问:

Transformer 是什么?

真正需要的其实只有:

第五章。

如果整个文档作为一个整体进行检索,那么系统返回的将是整本教材。

不仅浪费 Token,还会干扰模型理解。

因此:

RAG 通常都会进行Chunk(文本切块)


八、Chunk(文本切分)

Chunk 是整个 RAG 中最重要的概念之一。

它的本质就是:

把长文档切成许多较小的语义片段。

例如:

一本书:

机器学习教材

切分之后:

Chunk1 机器学习概述 ------------------- Chunk2 线性回归 ------------------- Chunk3 决策树 ------------------- Chunk4 Transformer

以后:

用户问:

Transformer

系统直接返回:

Chunk4

即可。


Chunk 多大比较合适?

Chunk 并不是越大越好。

也不是越小越好。

例如:

Chunk 太小:

Transformer 是 一种

一句话就切断。

语义已经丢失。


Chunk 太大:

整个 PDF

又失去了检索意义。

因此:

HelloAgents 建议按照:

  • 固定长度
  • 语义边界
  • 标题结构

综合进行切分。

例如:

Markdown ↓ 一级标题 ↓ 二级标题 ↓ 段落

尽量保证:

一个 Chunk 表达一个完整主题。

这样 Embedding 的效果最好。


九、Embedding:让计算机理解语义

完成 Chunk 之后,

接下来就是整个 RAG 最核心的一步:

Embedding(文本向量化)。

计算机并不能直接理解:

Transformer Python 深度学习

这些文字。

因此:

需要转换成数学向量。

例如:

Transformer

经过 Embedding:

[0.24, -0.18, 0.61, ……]

而:

Attention Mechanism

可能变成:

[0.21, -0.15, 0.59, ……]

虽然两个句子不同。

但是:

它们向量距离很近。

说明:

语义相似。


Embedding 的作用

Embedding 最大的作用就是:

把自然语言映射到向量空间。

以后:

不是比较:

字符串是否相同

而是比较:

两个向量是否接近

例如:

数据库中保存:

Python

用户输入:

机器学习编程语言

关键词完全不同。

但是:

Embedding 后:

两个向量非常接近。

因此:

仍然能够成功检索。

这就是:

Semantic Search(语义检索)

相比传统关键词搜索,它更加智能。


十、Qdrant:向量数据库

得到 Embedding 后,

所有 Chunk 都需要保存起来。

HelloAgents 选择使用:

Qdrant

作为默认向量数据库。

它的作用可以理解为:

SQLite 负责保存文本。 ↓ Qdrant 负责保存向量。

例如:

Chunk: Transformer 于 2017 年提出。

数据库中实际上保存的是:

文本 + Embedding + Metadata

其中 Metadata 可以包括:

文件名称 章节 页码 标签 来源

以后检索时:

不仅能够返回内容。

还可以告诉用户:

这段内容来自哪篇文档、哪一章节。


为什么使用向量数据库?

假设知识库有:

100 万个 Chunk

如果每次都逐个计算相似度,

速度会非常慢。

因此:

Qdrant 内部采用了专门的近似最近邻(Approximate Nearest Neighbor,ANN)索引算法,例如 HNSW,使其能够在海量向量中快速找到最相似的几个结果。

整个过程可以表示为:

用户问题 │ ▼ Embedding │ ▼ Qdrant │ ▼ Top-K Chunk

通常只需要几十毫秒即可完成一次检索。


十一、HelloAgents 中知识入库流程

综合前面的内容,HelloAgents 的知识库建立过程可以总结为:

PDF / Word / Markdown │ ▼ MarkItDown │ ▼ Markdown 文本 │ ▼ Document Processor │ ▼ Chunk 切分 │ ▼ Embedding │ ▼ Qdrant 存储

至此,一份文档就真正变成了可检索的知识库

以后用户每提出一个问题,系统都可以快速定位到最相关的几个 Chunk,再交由大语言模型进行回答。

下面是第三部分,也是整个HelloAgents 第8.3节 RAG博客的最后一部分。这一部分结合 HelloAgents 官方实现,介绍检索阶段、MQE、HyDE、RAGTool,最后进行总结。


十二、在线检索:RAG 如何回答用户问题?

完成知识库构建之后,真正的 RAG 才开始发挥作用。

与传统数据库查询不同,RAG 并不是根据关键词直接查找文本,而是经历一套完整的语义检索流程。

整个在线检索流程如下:

用户提问 │ ▼ Query Embedding(问题向量化) │ ▼ Vector Search(向量检索) │ ▼ 返回 Top-K Chunk │ ▼ Prompt Augmentation(构建上下文) │ ▼ LLM │ ▼ 最终回答

整个流程通常只需要几百毫秒。


第一步:Query Embedding

首先,系统不会立即调用 LLM。

而是先对用户问题进行Embedding

例如:

用户: SpringBoot 如何整合 Redis?

Embedding 后:

[0.31, -0.24, 0.61, ......]

这里使用的 Embedding 模型与建立知识库时保持一致。

这样,问题和知识库中的 Chunk 才位于同一个向量空间,可以直接计算相似度。


第二步:Vector Search

随后,系统进入向量数据库。

例如知识库中存在:

Chunk1 SpringBoot 整合 MySQL -------------------- Chunk2 SpringBoot 整合 Redis -------------------- Chunk3 Spring Security

经过相似度计算:

返回:

Top1 SpringBoot 整合 Redis Top2 Redis 配置说明

而不是返回:

Spring Security

这就是语义检索最大的优势。

即使用户没有出现完全相同的关键词,只要表达的含义相近,也能够正确找到相关内容。


第三步:Top-K 检索

实际应用中,系统一般不会只返回一个 Chunk。

而是返回:

Top-K

例如:

Top1 Redis 配置 Top2 Redis 注解 Top3 RedisTemplate 使用

为什么要返回多个?

因为:

一篇完整答案往往分散在多个 Chunk 中。

多个 Chunk 能够共同补充上下文。

当然:

Top-K 也不是越大越好。

如果返回:

Top=100

大量无关内容反而会影响模型理解。

因此:

实际项目通常设置:

Top-K = 3~10

十三、Prompt Augmentation(提示增强)

得到检索结果之后,

HelloAgents 并不会直接返回。

而是把这些内容重新组织成 Prompt。

例如:

用户问题:

SpringBoot 如何连接 Redis?

检索结果:

RedisTemplate 配置…… @EnableCaching…… application.yml……

最终 Prompt:

下面是检索到的资料: ...... 请根据这些资料回答用户问题。 问题: SpringBoot 如何连接 Redis?

这样:

LLM 就拥有了回答问题所需的知识。

因此:

最终生成内容:

既符合知识库,

又保持自然语言表达。


十四、为什么普通 RAG 还不够?

虽然普通 RAG 已经能够解决很多问题。

但是:

实际项目中仍然存在一些挑战。

例如:

用户输入:

GPU 怎么训练?

这个问题非常模糊。

GPU:

可能指:

CUDA PyTorch TensorFlow 显卡驱动 多 GPU

如果直接检索,

容易找到错误 Chunk。

因此:

HelloAgents 进一步介绍了两种高级检索策略。


十五、MQE(Multi-Query Expansion)

MQE 全称:

Multi-Query Expansion

中文一般翻译为:

多查询扩展。

核心思想非常简单:

不要只搜索一次。

例如:

用户输入:

SpringBoot 权限管理

系统首先让 LLM 自动生成多个相似问题:

SpringBoot RBAC Spring Security 权限 JWT 权限认证 用户角色管理

随后:

分别进行检索:

问题1 ↓ 检索 问题2 ↓ 检索 问题3 ↓ 检索

最后:

把所有结果合并。

这样:

能够覆盖更多知识。

相比:

一次检索。

MQE:

召回率更高。


MQE 的优点

例如:

知识库只有:

JWT

用户却输入:

Token

普通 RAG:

可能找不到。

MQE:

自动扩展:

JWT Access Token Bearer Token

因此:

成功检索。


十六、HyDE(Hypothetical Document Embeddings)

HyDE 是近年来比较流行的一种 RAG 优化策略。

全称:

Hypothetical Document Embeddings

它的思想更加有趣。

不是:

直接检索。

而是:

先让 LLM:

“假装已经知道答案。”

例如:

用户:

介绍 Transformer。

LLM:

首先生成:

Transformer 是 Google 在 2017 年提出的…… 采用 Self-Attention……

虽然:

这不是最终答案。

但是:

已经形成了一篇"假设文档"。

随后:

系统:

不是 Embedding:

用户问题

而是 Embedding:

假设答案

为什么这样效果更好?

因为:

知识库中的 Chunk:

一般都是:

完整段落。

而不是:

一句问题。

Embedding:

完整段落。

通常比:

一句问题。

更加接近真正文档。

因此:

检索质量更高。


HyDE 工作流程

整个流程如下:

用户问题 │ ▼ LLM 生成假设答案 │ ▼ Embedding │ ▼ Qdrant │ ▼ Top-K Chunk

相比普通 RAG,

HyDE:

能够明显提高:

长文本检索效果。


十七、HelloAgents 中的 RAGTool

为了方便开发者使用,

HelloAgents 将整个 RAG 封装成:

RAGTool

开发者无需关心:

Embedding、

数据库、

检索流程。

只需要调用接口即可。


添加文本

例如:

rag_tool.execute("add_text",text="Transformer 于 2017 年提出。")

系统自动完成:

Chunk ↓ Embedding ↓ Qdrant

添加文档

例如:

rag_tool.execute("add_document",path="paper.pdf")

内部流程:

PDF ↓ MarkItDown ↓ Markdown ↓ Chunk ↓ Embedding ↓ Qdrant

整个过程无需人工干预。


搜索知识

例如:

rag_tool.execute("search",query="Transformer")

系统返回:

Top-K Chunk

开发者可以:

自己处理。

也可以:

继续交给:

LLM。


直接问答

HelloAgents 还进一步封装:

rag_tool.execute("ask",query="Transformer 是什么?")

系统自动完成:

Embedding ↓ Vector Search ↓ Prompt ↓ LLM ↓ 最终回答

对于开发者来说,

几乎只需要:

一句代码。

即可拥有:

完整 RAG 能力。


十八、Memory + RAG:构建完整的 Agent 知识体系

至此,我们已经学习了第八章的两个核心模块:

  • Memory(记忆)
  • RAG(检索)

二者并不是竞争关系,而是现代 Agent 中最重要的两个组成部分。

可以通过下图理解:

Agent │ ┌────────────┴────────────┐ │ │ ▼ ▼ Memory RAG 保存历史经验 查询外部知识 │ │ └────────────┬────────────┘ ▼ LLM │ ▼ 最终回答

其中:

Memory 负责:

  • 用户画像;
  • 长期偏好;
  • 历史任务;
  • 对话记录。

RAG 负责:

  • 企业知识库;
  • PDF;
  • API 文档;
  • 最新论文;
  • 私有数据。

只有两者结合,Agent 才能够真正做到:

既记得过去,又知道现在。


十九、本章总结

通过 HelloAgents 第八章的学习,我们系统了解了 Agent 中两项关键能力:Memory(记忆)RAG(检索增强生成)

对于 RAG 部分,可以总结为以下几点:

  1. RAG 的本质是“先检索,再生成”。它通过在生成答案前引入外部知识,有效弥补了大语言模型知识过时、无法访问私有数据以及容易产生幻觉等缺陷。

  2. 知识库构建(Indexing)是 RAG 的基础,包括文档解析(MarkItDown)、文本切分(Chunk)、Embedding 向量化以及 Qdrant 向量存储等步骤,这些操作通常离线完成。

  3. 在线检索(Retrieval)包括 Query Embedding、Vector Search、Top-K 检索和 Prompt Augmentation。系统首先检索最相关的知识片段,再将其作为上下文交给 LLM,从而生成更加准确、可靠的回答。

  4. MQE(Multi-Query Expansion)和 HyDE(Hypothetical Document Embeddings)是提升检索质量的重要策略。前者通过扩展多个查询提高召回率,后者通过生成假设文档改善向量表示,二者都能够有效增强 RAG 的性能。

  5. HelloAgents 提供了高度封装的RAGTool,开发者只需调用简单接口即可完成文档导入、知识检索和问答,大大降低了构建 RAG 系统的开发难度。

http://www.jsqmd.com/news/1125378/

相关文章:

  • 记录arm64内核调试环境搭建qemu_arm64_linux_01
  • 金融职业发展:应用统计 vs 大数据管理,如何选择?
  • Tokio 背压设计:通道满了,比内存爆了更早告诉你问题
  • 爬虫转大模型:信息采集能力如何变成 AI,用真实案例讲清边界
  • 在浏览器里逛唐长安城,这个开源项目让我直接穿越了!
  • Go 推理客户端:重试要懂模型调用的副作用
  • WebShell溯源实战:从CVI-360001告警到漏洞根因挖掘
  • 故障诊断 Agent 权限:能查很多,不代表能改很多
  • 基于STM32单片机智能手环心率血氧体温GPS定位跌倒计步器系统设计12(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • 别被名字骗了:普通人如何用 Codex 打造专属的“AI 超级员工”
  • camelAI 是一款主打“随心构建”理念的编程工具
  • DIO四川资阳生产基地量产纪念仪式圆满举行 | 全球“双核制造体系”与口腔AI实验室同步启航
  • 《用AI做公众号流量主》第13课:为什么 99% 的人用 AI 生产的都是“电子垃圾”?
  • Java毕设项目:乡村物资救助与公益捐赠服务系统的设计与实现 智慧助农公益帮扶综合管理平台 (源码+文档,讲解、调试运行,定制等)
  • 手中有机, 心中不慌 (5 只 二手 Android 手机)
  • 短剧AI翻译隐性收费横评:5款平台费用明细对比避坑
  • 基于51/STM32单片机点滴速度液体检测 智能输液蓝牙监控系统 套件12(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • 漏扫发现-Web服务篇Poc开发Yakit插件编写Afrog项目Yaml语法Yak语言接受匹配
  • 2026知识付费平台全对比!新手开课首选平台汇总推荐
  • 华为 eNSP 安装完全指南(人民标准版 v3.0)
  • 一起动手学LangChain吧-从零创建一个agent
  • try-throw-catch异常捕获流程
  • Redis Stream 消息队列总结
  • CTF ECC基础离散对数爆破 解题Writeup
  • 调试排查工具介绍(gdb、strace、Valgrind等)
  • JBoss 6.1.0.Final 弱口令加固实战:3步修改 jmx-console-users.properties 默认密码
  • 基于51/STM32单片机智能电饭煲 电饭锅设计 温度加热预约13(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • Java 转大模型开发:后端程序员的升级路线,把工具链跑成稳定流程
  • Agent 云原生运行时:智能体也需要健康检查
  • CenterNet实战:从零搭建到模型测试的完整环境配置指南