不用向量数据库做RAG?
被 AAAI 2026 接收的 Amazon 研究团队论文Keyword search is all you need(arXiv:2602.23368)提出:让 LLM Agent 使用 shell 命令进行关键词搜索,可以替代管理成本较高的向量数据库,同时达到向量数据库 RAG 约 90% 的精度。 论文中的评估基于英文文本 PDF 和 Anthropic Claude 3 Sonnet(Amazon Bedrock)。
本文记录了作者在日文 PDF 与 claude-sonnet-4-6(截至 2026 年 5 月)条件下,对这一方法所做的个人实验。 作者想确认以下 3 点:
- 在日文中是否也能同样有效
- 成本方面会有什么差异
- 精度是否存在差别
本文对论文提出的“基于关键词搜索的 Agentic RAG”在日文 PDF 上做了一次小规模验证。 先说结论:在表格和图表中的数值抽取任务上,Agent RAG 更强;但从 API 成本和延迟看,Vector RAG 更稳定。 下文会介绍实验设置、实现、结果和对应解释。
由于本文没有执行论文使用的 RAGAS 自动评估(Faithfulness / Context Recall / Answer Correctness),因此不能和论文数值直接对比。 此外,本实验只有 10 道题,并由作者手动评估,只能观察小规模条件下的趋势,并不能得出统计显著的结论。
实验设置
比较的两种方法
Agent RAG(论文方法):让 LangChain ReAct Agent 把pdfgrep作为工具,在没有预先索引的情况下直接全文搜索 PDF。每个查询由 LLM 决定搜索关键词,并根据搜索结果继续选择下一组关键词,形成迭代搜索。最大迭代次数为max_iterations=15(LangChainAgentExecutor的默认值)。
Vector RAG(对照方法):将intfloat/multilingual-e5-small生成的嵌入写入 ChromaDB,再把查询向量化并做近邻搜索。分块设置为chunk_size=600, overlap=120。论文中使用chunk_size=300,但本实验考虑到日文 PDF 中语境不宜切得过碎,经预先确认后改为chunk_size=600。
两种方法都使用claude-sonnet-4-6(输入 ,输出15.0/1M tokens)。
主要库版本
# pyproject.toml(节选)[project]requires-python = ">=3.12"dependencies = [ "langchain>=0.3.0,<1.0", # 实际使用: 0.3.30 "langchain-anthropic>=0.3.0,<1.0", # 实际使用: 0.3.22 "langchain-community>=0.3.0,<1.0", # 实际使用: 0.3.31 "anthropic>=0.102.0", "chromadb>=1.5.0", "sentence-transformers>=3.0.0", "pypdf>=4.0.0",]评估数据
实验对象是 5 份日文政府文档:2 份 IPA 的 DX 相关资料、信息通信白皮书、2025 年版制造业白皮书,以及大坝与堰设施技术标准。
| 类别 | 题数 |
|---|---|
| 事实抽取 | 4 题 |
| 概念说明 | 1 题 |
| 比较问题 | 2 题 |
| 步骤/标准 | 2 题 |
| 多文档横断 | 1 题 |
评估采用作者手动标注(correct / incorrect / partial)。由于作者同时负责实现和评估,结果可能受到确认偏差影响。
实现
pdfgrep 包装工具
这里把pdfgrep包装成 LangChain 自定义工具。
from langchain.tools import BaseToolfrom pydantic import BaseModel, Fieldimport subprocess, jsonfrom pathlib import PathPDF_DIR = Path("data/japanese_pdfs")class PdfgrepSearchInput(BaseModel): pattern: str = Field(description="搜索模式(可用 Perl 正则表达式,用 | 做 OR 搜索)") pdf_dir: str = Field(default=str(PDF_DIR), description="PDF 目录路径")class PdfgrepSearchTool(BaseTool): name: str = "pdfgrep_search" description: str = ( "使用 pdfgrep 对 PDF 做全文搜索。" "使用 Perl 正则表达式(-P 标志),因此可以像 '目的|概要' 这样做 OR 搜索。" ) args_schema: type[BaseModel] = PdfgrepSearchInput def _run(self, pattern: str, pdf_dir: str = str(PDF_DIR)) -> str: # 定义 args_schema 时,参数有时会以 JSON 字符串传入,因此这里手动解析。 try: parsed = json.loads(pattern.strip()) if isinstance(parsed, dict): pdf_dir = parsed.get("pdf_dir", pdf_dir) pattern = parsed.get("pattern", pattern) except (ValueError, TypeError): pass # -------------------------------- pdf_files = list(Path(pdf_dir).glob("*.pdf")) ifnot pdf_files: returnf"No PDF files found in {pdf_dir}" all_output = [] for pdf in pdf_files: cmd = [ "pdfgrep", "-P", # Perl 正则表达式(用 | 做 OR 搜索) "-i", # 不区分大小写 "--context=2", # 显示匹配行前后 2 行 pattern, str(pdf), ] result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) if result.stdout: all_output.append(f"[{pdf.name}]\n{result.stdout}") return"\n".join(all_output)[:3000] if all_output else"No matches found."成本监控
ReAct 循环会多次调用 LLM,因此作者用下面的代码检查每次调用的成本。
from langchain.callbacks.base import BaseCallbackHandlerfrom langchain_core.outputs import LLMResultINPUT_COST_PER_M = 3.0 # USD / 1M tokens (claude-sonnet-4-6)OUTPUT_COST_PER_M = 15.0class TokenUsageCallback(BaseCallbackHandler): def __init__(self) -> None: self.total_input_tokens = 0 self.total_output_tokens = 0 self.llm_call_count = 0 @property def total_cost_usd(self) -> float: return ( self.total_input_tokens / 1_000_000 * INPUT_COST_PER_M + self.total_output_tokens / 1_000_000 * OUTPUT_COST_PER_M ) def on_llm_end(self, response: LLMResult, **kwargs) -> None: self.llm_call_count += 1 in_tok, out_tok = self._extract_tokens(response) self.total_input_tokens += in_tok self.total_output_tokens += out_tok call_cost = ( in_tok / 1_000_000 * INPUT_COST_PER_M + out_tok / 1_000_000 * OUTPUT_COST_PER_M ) print( f" [LLM#{self.llm_call_count}] " f"in={in_tok:,} out={out_tok:,} tokens | " f"call=${call_cost:.5f} | 累计=${self.total_cost_usd:.5f}" ) def _extract_tokens(self, response: LLMResult) -> tuple[int, int]: # langchain-anthropic 0.3.x: usage_metadata 会存放在 AIMessage 中 for gens in response.generations: for gen in gens: msg = getattr(gen, "message", None) meta = getattr(msg, "usage_metadata", None) if msg elseNone if meta: return meta.get("input_tokens", 0), meta.get("output_tokens", 0) return0, 0定量结果
综合比较
| 指标 | Agent RAG | Vector RAG |
|---|---|---|
| 正确率(10 题中) | 9/10(90%) | 7/10(70%) |
| API 总成本(10 题) | $1.0401 | $0.1286 |
| 平均 API 成本 / 每题 | $0.1040 | $0.0129 |
| 平均延迟 | 32.2 秒 | 6.7 秒 |
| 平均工具执行次数 | 5.7 次 / 每题 | - |
平均 API 成本与平均延迟比较(柱状图)
各题详情
| ID | 类别 | Agent 结果 | Agent 迭代 | Agent API 成本 | RAG 结果 | RAG API 成本 |
|---|---|---|---|---|---|---|
| q001 | 事实抽取 | 正确 | 7 次 | $0.1000 | 正确 | $0.0134 |
| q002 | 比较问题 | 正确 | 4 次 | $0.0717 | 正确 | $0.0171 |
| q003 | 事实抽取 | 正确 | 5 次 | $0.0565 | 错误 | $0.0120 |
| q004 | 事实抽取 | 正确 | 4 次 | $0.0326 | 错误 | $0.0107 |
| q005 | 步骤/标准 | 正确 | 4 次 | $0.0513 | 正确 | $0.0130 |
| q006 | 多文档横断 | 失败 | 15 次 | $0.4878 | 部分正确 | $0.0135 |
| q007 | 概念说明 | 正确 | 5 次 | $0.0405 | 正确 | $0.0098 |
| q008 | 事实抽取 | 正确 | 3 次 | $0.0451 | 正确 | $0.0083 |
| q009 | 步骤/标准 | 正确 | 4 次 | $0.0710 | 正确 | $0.0164 |
| q010 | 比较问题 | 正确 | 6 次 | $0.0835 | 正确 | $0.0144 |
各题 API 成本(横向柱状图)—— q006 的 Agent 成本明显突出
成本梳理:API 调用成本和运维成本是两回事
比较这两种方法的成本时,需要把API 调用成本和基础设施/运维成本分开看。
API 调用成本:Agent RAG 高出 8.1 倍
在这次验证中,平均每题 API 成本为 Agent RAG 、0.0129,也就是说Vector RAG 便宜 8.1 倍。
Agent RAG 成本高有结构性原因。ReAct 循环每多调用一次 LLM,就会产生一次 API 费用。每个问题平均发生 5.7 次工具调用;q006(多文档横断)达到 15 次,消耗 $0.4878。仅这一题就占 Agent RAG 全部 API 成本约 47%。
两者的成本波动也很不同。Vector RAG 在 10 道题中都落在 到0.0171 之间(约 2 倍范围),而 Agent RAG 落在 到0.4878 之间(约 15 倍范围)。由于成本会随查询复杂度大幅波动,若要嵌入生产服务,就需要设计成本上限。
需要注意的是,论文在讨论成本优势时比较的是“向量数据库的基础设施成本”,而不是 LLM API 调用成本。
基础设施/运维成本:Vector RAG 需要预先构建并持续维护
Vector RAG 有运维上的固定成本。本实验中,对 5 个文件、351 个分块构建索引约耗时 30 秒(CPU,multilingual-e5-small)。在生产环境中,以下运维工作会持续发生:
- 每次新增、删除、更新文档时,都需要增量更新索引
- 需要管理嵌入模型版本(更换模型时要全量重建)
- 需要处理向量数据库的存储和内存扩展
Agent RAG 不会产生这些基础设施成本。它在查询时直接读取 PDF 文件,因此文档新增或更新只需要替换原文件。
论文所说的“降低成本”,指的正是这种基础设施和运维成本的下降。不过,如果同一组文档会被高频查询,索引构建的固定成本也会很快被摊薄。
回答质量分析
Vector RAG 失败的情况:表格和图表中的具体数值(q003、q004)
q004 的问题是:“在 2025 年版制造业白皮书中,对员工自我提升提供支持的制造业事业所占比是多少?”
Agent RAG 的回答(正确):
提供支持的事业所占比:**80.7%**。最常见的支持形式是“课程费用等金钱援助”。 出处:monodzukuri_hakusho_2025_gaiyo.pdf 中写有“对员工自我提升提供支持的事业所占比为 80.7%”。
Vector RAG 的回答(错误):
给定上下文中没有记载具体信息。上下文中只有这条信息:“制造业中进行自我提升的劳动者比例,正式员工约为 4 成……”这说的是劳动者一侧进行自我提升的比例,因此没有找到答案。
Vector RAG 把“自我提升”“比例”这些语义相近的另一段分块(劳动者侧自我提升比例约 4 成)取进了前 5 个结果,而真正包含答案的位置(事业所侧支持比例 80.7%)没有进入排序靠前的结果。Agent RAG 则通过不断更换关键词,抵达了正确记述位置。
q003“在 DX 推进框架中,明显低于总体平均的项目是什么?”也出现了类似趋势。Vector RAG 返回了“心态/企业文化与投资决策”(另一个指标),而 Agent RAG 准确引用了“经营高层承诺、愿景为负值”。
Agent RAG 失败的情况:多文档横断查询(q006)
q006 的问题是:“《DX 动向 2025》和《DX 推进指标自我诊断报告 2024 年版》两份资料都指出的 DX 推进共同课题是什么?”在这个问题上,Agent RAG 达到max_iterations=15后仍未能回答。
根本原因在于工具设计限制。pdfgrep_search会搜索整个目录,因此无法把特定文件的结果分离出来。Agent 在无法区分“结果来自哪份文档”的状态下持续收集证据,无法进入合成答案阶段。从实际迭代过程可以看得很清楚。
| 迭代 | 搜索模式 | 结果情况 |
|---|---|---|
| 2 到 6 | 课题 / 障碍 / 阻碍 | 尝试指定特定文件但失败,命中结果混在全部 PDF 中 |
| 7 到 14 | 人才短缺 / 人才确保、经营高层 / 承诺、局部最优 / 整体最优等 | 从多个角度继续搜索,但无法区分结果分别来自哪份文档 |
| 15 | 共同 / 主要课题 / 重要课题 | 达到迭代上限 |
搜索结果在上下文窗口中不断累积,最终输入膨胀到 22,103 tokens,累计成本达到 ,延迟达到秒。相比之下,用0.0135、8.4 秒返回了一个部分正确的答案。
Agent 一直判断“证据还不够”,这种行为不能脱离工具设计来看。若要用 Agent RAG 处理多文档横断查询,就需要拆分为可指定文件的工具,或提前准备按文档划分的摘要。
方法选择标准
基于实验结果,可以得到如下选择标准。
Agent RAG 适合的场景:
- 对同一文档的查询较少,无法摊销索引构建成本的用途(一次性调查、分析等)
- 对表格和图表中具体数值的抽取精度要求较高的用途
- 文档更新频率高,难以持续维护索引的系统
- 需要追踪回答依据中的关键词和引用位置的用途
Vector RAG 适合的场景:
- 同一文档集合会被重复查询的系统(可以利用 API 成本单价优势)
- API 成本和延迟的可预测性对生产服务很重要
- 需要跨多份文档整合信息的查询
- 询问没有直接关键词匹配、但存在概念相似性的问题
两种方法共同的弱点:
在本次实现中,跨多文档整合信息的查询对两种方法都比较困难。Agent RAG 会导致迭代成本膨胀,Vector RAG 则因为分块竞争而只能给出部分回答。
不过,两者失败的性质并不相同。 Vector RAG 暴露出的是这类简单 Top-k 分块搜索的限制:独立检索分块时,很难稳定完成跨文档整合。 相对而言,Agent RAG 的失败主要来自工具设计。尤其是pdfgrep_search会搜索整个目录,不容易按文档整理结果。只要改成可指定文档的工具,或准备按文档划分的摘要索引,Agent RAG 仍有改善空间。
另外,多文档横断是 2025 到 2026 年 RAG 研究中的活跃课题,GraphRAG、IndexRAG 等专门方法也在不断出现。它是标准实现中被广泛认识到的限制,但设计得当的 Agentic RAG 也可能克服这一问题。
说真的,这两年看着身边一个个搞Java、C++、前端、数据、架构的开始卷大模型,挺唏嘘的。大家最开始都是写接口、搞Spring Boot、连数据库、配Redis,稳稳当当过日子。
结果GPT、DeepSeek火了之后,整条线上的人都开始有点慌了,大家都在想:“我是不是要学大模型,不然这饭碗还能保多久?”
我先给出最直接的答案:一定要把现有的技术和大模型结合起来,而不是抛弃你们现有技术!掌握AI能力的Java工程师比纯Java岗要吃香的多。
即使现在裁员、降薪、团队解散的比比皆是……但后续的趋势一定是AI应用落地!大模型方向才是实现职业升级、提升薪资待遇的绝佳机遇!
这绝非空谈。数据说话
2025年的最后一个月,脉脉高聘发布了《2025年度人才迁徙报告》,披露了2025年前10个月的招聘市场现状。
AI领域的人才需求呈现出极为迫切的“井喷”态势
2025年前10个月,新发AI岗位量同比增长543%,9月单月同比增幅超11倍。同时,在薪资方面,AI领域也显著领先。其中,月薪排名前20的高薪岗位平均月薪均超过6万元,而这些席位大部分被AI研发岗占据。
与此相对应,市场为AI人才支付了显著的溢价:算法工程师中,专攻AIGC方向的岗位平均薪资较普通算法工程师高出近18%;产品经理岗位中,AI方向的产品经理薪资也领先约20%。
当你意识到“技术+AI”是个人突围的最佳路径时,整个就业市场的数据也印证了同一个事实:AI大模型正成为高薪机会的最大源头。
最后
我在一线科技企业深耕十二载,见证过太多因技术卡位而跃迁的案例。那些率先拥抱 AI 的同事,早已在效率与薪资上形成代际优势,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在大模型的学习中的很多困惑。
我整理出这套 AI 大模型突围资料包【允许白嫖】:
- ✅从入门到精通的全套视频教程
- ✅AI大模型学习路线图(0基础到项目实战仅需90天)
- ✅大模型书籍与技术文档PDF
- ✅各大厂大模型面试题目详解
- ✅640套AI大模型报告合集
- ✅大模型入门实战训练
这份完整版的大模型 AI 学习和面试资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
①从入门到精通的全套视频教程
包含提示词工程、RAG、Agent等技术点
② AI大模型学习路线图(0基础到项目实战仅需90天)
全过程AI大模型学习路线
③学习电子书籍和技术文档
市面上的大模型书籍确实太多了,这些是我精选出来的
④各大厂大模型面试题目详解
⑤640套AI大模型报告合集
⑥大模型入门实战训练
👉获取方式:
有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓
