AI-Agents:我有个优化RAG的想法,你写个本地知识库服务来验证
以前,“传统RAG”的工程,我们是让大模型读取很多个“原始”知识片段。
现在,我们让大模型多看看“摘要”,如有必要再基于“摘要”去查阅原文。
想要达成三个目标:
-
减少token;
-
减少LLM思考时间;
-
保持答案质量、甚至提升答案质量。
AI-Agent
AI-Agent(智能体)已经很长时间是我工作和生活中不可分离的成员,她是一个好助手。
有时,我请她去安装特定的工具,毕竟我都不知道工具的包名。
有时,我请她解答多个项目里面的特定功能问题,毕竟翻代码是个体力活。
时不时,我也请她验证“我有一个大胆的想法”。
我请助手安装工具:
root@ai-dev:/林生的奇思妙想# ai_agent 安装这个工具:pdf2txt
>>> Final Answer:
已成功安装 PDF 转文本工具。在 Ubuntu/Debian 系统中,对应的工具是 pdftotext(来自 poppler-utils 包),而不是 pdf2txt。
安装的工具包括:
- pdftotext (版本 25.03.0) - 用于将 PDF 转换为纯文本
- 其他 PDF 工具:pdfattach, pdfdetach, pdffonts, pdfimages, pdfinfo, pdfseparate, pdfsig, pdftocairo, pdftohtml, pdftoppm, pdftops, pdfunite
使用方法:
```bash
pdftotext input.pdf output.txt
或直接输出到标准输出:
pdftotext input.pdf -
我请助手分析代码:
```code-snippet__js
root@ai-dev:/林生的奇思妙想/essence-of-AI-engineering# ai_agent 这个项目对文档分片的方法是什么:$PWD
[AgentReAct] [2025-10-24 22:10:32] [
{
"step_name": "thought",
"raw_text": "用户询问的是关于项目 '/林生的奇思妙想/essence-of-AI-engineering' 中使用的文档分片方法。我需要先检查这个路径是否存在,然后查看项目中的相关文档或代码来了解文档分片的具体实现方法。"
},
...
>>> Final Answer:
这个项目 `/林生的奇思妙想/essence-of-AI-engineering` 使用的文档分片方法如下:
## 核心分片工具:IterChunks 类
**位置**:`/林生的奇思妙想/essence-of-AI-engineering/rag/rag_base/chunk_tool.py`
### 主要特点:
1. **流式处理**:采用迭代器模式,逐行读取文件,避免一次性加载大文件到内存
2. **智能分片策略**:
- 默认分片大小:1000字符(可配置)
- 最大分片大小:chunk_size + 1000字符
- 支持自定义分隔符
3. **语义感知分片**:
- 识别句子边界:使用中文和英文的句子结束符(。!?.!?)
- 括号匹配:支持各种括号的智能处理(()、[]、{}、<>、()、【】、《》)
- 特殊字符处理:对引号、连字符、等号等特殊字符有专门处理
4. **分片逻辑**:
- 优先在句子边界处分割
- 考虑括号的完整性
- 避免在短行或空行处分割
- 强制截断保护:当分片超过最大大小时强制分割
### 集成方式:
在 `rag_core.py` 的 `prepare_data` 函数中调用:
- 使用 `IterChunks` 迭代器处理文档
- 对每个分片进行向量化嵌入
- 可选生成摘要(使用 BERT 或 Pegasus 模型)
- 存储到向量数据库中
这种方法结合了传统的基于长度的分片和基于语义的分片,既保证了分片的均匀性,又尽量保持了语义的完整性。
AI-Agent,我已经离不开她!
RAG
RAG(Retrieval-Augmented Generation)是一种结合“信息检索”和“LLM(大语言模型)生成能力”的技术框架,目标是提升模型生成答案的质量。
大家在用 kimi、deepseek、豆包 进行聊天的时候,它会自行从网络搜索资料进行整合,从而生成更新、更准的回答,并且答案有据可查、引用来源清楚。
我在用AI-Agent的时候,她也会根据提示词自行调用相关工具去找到信息,从而生成准确的答案,并且答案也有据可查、来源清楚。
这些其实都算RAG的技术思想。
root@ai-dev:/林生的奇思妙想# time ai_agent 基于知识库/workspace解答我的问题:1900年中国发生了哪些事?
>>> Final Answer:
根据《中国百科全书c1.txt》知识库的内容,1900年中国发生了以下重要事件:
1. **义和团运动**:1900年义和团运动达到高潮,这是一场反对帝国主义侵略的民众运动。运动影响了外国在华企业的运营,如英商立德筹组专行川江的轮船公司计划因义和团运动而破灭。
2. **外国在华企业合并扩张**:
- 英商祥生和耶松两家船厂在1900年合并为耶松船厂公司,资本增至五百五十余万两
- 日本大阪轮船公司资本在1900年增长一倍,达一千一百万元
- 英商道格拉斯轮船公司因日本竞争于1900年撤出台南线
3. **帝国主义列强继续攫取中国权益**:
- 英人"收买"开平煤矿,实为夺取中国原有产业
- 日本南满铁道株式会社自1900年成立后,工矿业投资达一千九百六十余万日元
- 义和团运动过后,帝国主义列强继续攫取新的铁路权益
4. **外国航运势力竞争加剧**:英、日、德等国在华航运竞争激烈,日本轮运势力迅速崛起,在长江干线和华南沿海线上与英国势力不相上下。
这些事件反映了1900年中国正处于帝国主义列强加紧侵略、民族危机深重的历史时期。
real0m13.098s
user0m1.503s
sys 0m0.182s
传统RAG
这里的传统RAG是指这个工程:
-
数据准备: 将文档切分成小块(chunk,也称为‘知识片段’),使用嵌入模型(embedding)将这些小块文本转换成向量,将小块文本和向量存入向量数据库。有时也会带入元信息(Metadata),类似于索引或标签,可以根据这些元信息进行检索。
-
数据查询: 用户提出问题,同样使用嵌入模型将问题转换成向量,然后,到向量数据库进行相似度搜索即召回(retrieve),有时也可以做重排(rerank)去精筛选,最终找出与问题最接近的几个知识片段。
-
提示词准备: 将用户问题和检索到的知识片段进行整合,构造提示词。
-
大模型生成: 根据"提示词"生成最终答案。
尽管我的笔记本电脑还是能跑这个传统RAG服务用来做“本地知识库”,但是我用它甚少。
传统RAG很长时间被我放在小角落上~冷眼旁观,主要原因是我还用不上,我也没有什么保密级别高的大文档要放本地知识库。
此外,文档分片工作也是个费力活,毕竟这决定着往后的检索精度。
况且,虽然传统RAG的"应用工程"较为简单,但是"模型工程"方面最核心的嵌入模型复杂度高、驾驭难度大。
再看,最近网上对它的风评如此不佳:检索速度慢、精确度不足,消耗token(很多内容都不相关),大量文本扔给LLM后注意力分散了、容易幻觉。
甚至,有人扬言~RAG已死。
这些风评有时也需辨证地看,实际上和使用场景紧密相关,例如:对于法律类知识就要求精准、即使多吃token也是必要;而对于历史百科就只需提个大概、多吃token就费钱、费计算资源。
我平常都请AI-Agent去解答问题,她会用经典的linux文本处理工具(grep,awk,sed ...)去找到关键信息,特别的直截了当。虽然执行时间长了点,但是工作一直稳定良好、精度也很ok、答案几乎满意。深得我心!
优化RAG
在某个寂静的夜晚,忽如其来,我有一个想法:
-
在‘提示词准备’阶段,通过减少‘知识片段’,增加许多‘摘要片段’,从而减少提示词输入量,进而减少大模型的思考时间。‘摘要片段’是指对知识片段进行概括,形成摘要总结。
-
尽管减少了‘知识片段’,但增加了更多的‘摘要片段’,也可以保障答案准确率,甚至能提升准确率。
这是一个基于传统RAG的改法:
以前,我们是让大模型读取很多个“原始”知识片段;
现在,我们让大模型多看看“摘要”,如有必要再基于“摘要”去查阅原文。
这个想法是想要达成三个目标:
-
减少token;
-
减少LLM思考时间;
-
保持答案质量、甚至提升答案质量。
我马上构建提示词去请AI-Agent助我验证这个想法。我把提示词放在了git工程里头:【AI大模型教程】
提示词分成4个文件:1个总计划、3个子任务。同时,也准备了两个文本素材用于知识库的构建。
root@ai-dev:/林生的奇思妙想/essence-of-AI-engineering/rag/idea_for_abstract# tree -I _ai_generation
.
├── plan-20251018.md # 总计划
├── rag
│ └── txt
│ ├── t-ara.txt
│ └── 中国百科全书c1.txt
├── rag_database.md
├── rag_server.md
├── run.sh
└── text.md
这是验证计划:
-
使用编程助手编写服务:rag_server。
-
使用写作助手准备文本素材。
-
使用编程助手建立RAG知识库。
-
进行RAG知识检索。
最终能生成一份验证报告。
我使用青云智算平台的LLM:DeepSeek-V3.1
我们运行起来:
root@ai-dev:/林生的奇思妙想/essence-of-AI-engineering# ./rag/idea_for_abstract/run.sh
最初的结果,她给了这个报告,让人惊呆了:处理时间减少95%以上!如下图所示:
后来,我仔细看了代码和日志,确认代码没问题,日志也确实显示超时。
最终,确定这是个误判,这是由于智算平台做了API相关的限制而引起的超时,并非大模型思考太久。
然后,我在提示词里面加了一句话:“若结果显示这类问题:RateLimitError,timeout,你要重试。”
接着,我直接将问题输入到任务中,请AI-Agent再去生成验证报告。
root@ai-dev:/林生的奇思妙想/essence-of-AI-engineering# DEBUG=1 uv run AgentReAct.py -p ./rag/idea_for_abstract/plan-20251018.md -t "使用这个问题生成验证报告:T-ARA的出道歌曲"
由于,我设计的提示词具有可重复执行的特性,一些已经完成的子任务不会重复执行。
最终结果很快出来了,如下图所示:
再看一下验证报告的内容,如下图:
AI-Agent结论:本次验证成功证明了RAG优化的有效性。通过减少知识片段、增加摘要片段的策略,在保持甚至提升答案准确度的同时,显著降低了提示词长度和处理成本。这为大规模RAG应用提供了重要的优化方向。
!这是AI-Agent协助我做的验证,先到这里。她生成的代码我也放到了这里:
root@ai-dev:/林生的奇思妙想/essence-of-AI-engineering/rag/idea_for_abstract# tree _ai_generation/
一种现象
我在实践过程中,不小心发现一个现象,当我询问“什么是XXX”的时候,从向量数据库中检索不到近似答案,当我带着英文询问“what is XXX”,就检索出来了。
我问“什么是瓦剌”,无答案,如下图:
我问“what is 瓦剌”,有答案,如下图:
包括平常在写提示词,有时遇到大模型容易幻觉,当我换成“英文”后,就变得顺利了起来。
这种现象在一定程度上给了我们一些启示!
结语
本次主要是让AI-Agent去验证我的想法,一定程度上证明了有效性,并未做太多深入的验证。
“RAG”是一种技术思路,“RAG工程”依赖于特定场景进行恰到好处的实践,实际落地时经常要基于使用场景进行调整,它的参数不是一成不变,它所用的模型更是需要按场景去做恰当的选择和调整。
以前,“传统RAG”的工程,我们是让大模型读取很多个“原始”知识片段。
现在,我们让大模型多看看“摘要”,如有必要再基于“摘要”去查阅原文。
未来,我们能否让大模型认识向量,用向量和大模型进行通讯呢?
期待RAG变革的到来!