前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
返回 AI 情报前线
All News · 全部资讯8479
  • 推理模型隐藏思考过程的四种方式及计费陷阱
  • AI Agent 将漏洞利用开发压缩至分钟级
  • Pi Agent:统一多模型 LLM API 的 AI 编程 Agent 工具链
  • LibreChat v0.8.8 RC:ChatGPT 克隆支持 Agent 管理 API
  • LandingAI 文档智能抽取 Gen2:原子级引用+按字符计费
  • 不用向量数据库做个人 RAG:grep 级检索也够用
  • Claude Code vs Cursor:按任务场景选择 AI 编程工具的完整指南
  • 2026 年五大主流模型生产选型指南
  • Agent 记忆层测试:六条真正能发现腐化的断言
  • Agent 生成的限流器如何绕过多租户隔离测试
  • 周末 Agent 项目攻略:用permit文件管控写操作
  • squash-merge 后 HEAD~1 指向无关代码的 Agent bug 分析
  • AI 生成的 Schema 变更:别让自由派 Diff 绕过锁
  • AI 写的代码编译过了,但环境变量、锁文件、日志全踩坑
  • Skild AI S1:仅凭一段视频,机器人学会翻煎饼
  • Java 27 发布:后量子 TLS 与对象头压缩等 9 项 JEP
  • DeepSeek 算子负责人自述:AI 一年内从查文档到独立优化 CUDA 算子
  • 编程任务 LLM 大模型盲测:4 款模型代码质量实测
  • Agent 循环常见路径陷阱自查清单
  • 你的 CDN 可能正在偷偷屏蔽所有 AI 爬虫
  • 我用Electron给Meta Muse Code CLI做了个桌面客户端,核心教训是PTY交互设计
  • Simon Willison 实战:通过 WebSocket 在浏览器里调 Gemini Live
  • 谷歌TPU集群迈入百万芯时代,电力成AI扩张核心瓶颈
  • AI 对话机器人的隐藏指令系统详解
  • 2026 年生产级 AI Agent 的上下文工程指南
  • OpenAI Agent 被指批量投毒 RubyGems 事件分析
  • Google 发布 Gemini 3.8 Live:支持 97 语言实时切换的语音 Agent 模型
  • AI 爬虫实际读取的是原始 HTML 还是渲染后 DOM
  • Next.js/Node单仓库中多租户邮件定时任务的安全隔离实践
  • AI Agent 真实生产故障:可观测性与恢复模式
  • 美国政府令 Anthropic Fable 5 下线事件
  • Google发布Gemini 3.8 Live语音模型,价格仅为GPT-Live-1的零头
  • Gemini企业平台零信任AI Agent运行时防护
  • AI Agent 正在冲垮生产环境:构建 SDLC 防护栏的工程实践
  • Gemini 3.8 Live 发布:扩展思考能力版本登场
  • Azure SRE Agent:Agent 自动化运维,人类做决策
  • 已加载 36 / 8479
8.0
热点
AI SCORE
编程提效2026-09-16 14:33

不用向量数据库做个人 RAG:grep 级检索也够用

dev.to · AI#RAG#检索#AI 工程
Editor brief · 编辑速览

作者 8 个月的实验:只用文件+搜索框做 RAG,效果经常不输完整的向量检索 pipeline,质疑 RAG 流程中哪些环节是真正必要的。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

假设检索必须不依赖 embeddings、不依赖向量数据库、不依赖任何非手工录入的索引。没有余弦相似度,没有分块策略,没有重排器。只有文件和搜索框,其他什么都没有。大约八个月来,这就是我为一个语言模型提供所需上下文的全部配置,而最令我惊讶的是,它败给所跳过的那套 machinery 的次数少得可怜。

我想把这作为一个思想实验而非推荐来讨论,因为真正的问题不是"grep 对你够不够用",而是:一个检索系统中,哪些部件在规模上才起支撑作用,哪些只是在我不具备的规模下才起支撑作用。当我把自己的设置剥离到只剩本质,问自己到底是什么在实际干活,答案几乎全部来自 RAG 教程里根本没出现的那部分。

剥离到本质的 RAG 是什么?

检索增强生成通常被画成一条 pipeline:把文档 embed 成向量、存储、embed 查询、找最近邻、把排名靠前的结果塞进 prompt、生成。在模型读到一个字之前,已经有六个活动部件。

把它剥离到只剩那句承重的话,只有一个分句存留下来。A RAG 把你已经拥有的相关文本放进 prompt,这样模型就用你自己的世界来回答,而不是用它在所有人平均数据上的那套东西。检索是整个想法的核心。Embeddings 是做检索的一种方式——那种方式在机器必须在没人从头读过的语料库上猜测"相关"是什么意思时才会发挥价值。

最后这个条件正是我悄悄不满足的那一条。我的语料库是一个日期标注的纯文本文件夹,里面的每一行我都自己读过、写过的、反复看过。几千行,不是几百万份文档。Embeddings 漂亮解决的那个检索问题,在我这里基本不存在。

我的检索实际上是什么样的?

说实话,就是这样。我的笔记是 markdown,每个月一份只追加的文件,每一行都标注日期,用我预期日后会去搜索的词语写成。当我坐下来用 Claude 或在 Cursor 里处理一个问题时,我不会召唤一个 pipeline。我在这个文件夹里搜索与当前问题相关的五到二十行,读一遍,把经过那轮阅读后还存活的部分粘贴到 prompt 里。

搜索是一条命令,这是整个系统里最不花哨的部分:

rg -i --sort path 'outbox|retry|idempoten' notes/

这就是整个检索层。"索引"不是数据结构,是一种习惯:我写每一行的时候,仿佛一年后会有一个陌生人带着和我一模一样的问题来 grep 它,所以把名词放在前面,而不是感觉放在前面。模型从不接触我的笔记。是我在接触。模型看到的永远只是我选择搬运过去的那几行。

没有任何 embed 步骤,因为根本不存在一个我需要机器来猜测哪些行相关的时刻。我自己就知道。亲自做检索者的代价是几秒钟的阅读;我用那几秒钟买来的,是让我在模型看到上下文之前先看到进入 context window 的究竟是什么。

团队级 RAG 和单人检索不是同一台机器

这种感觉像是异端的原因在于,大多数关于 RAG 的写作是为团队和产品构建的,很容易假设它的形态会直接下放到一张办公桌前。不会的。几乎每一条使向量 pipeline 变得合理的轴线,在语料库变成一个人的笔记时都转向了反面。

顺着右边那一列读下来,向量数据库不是被偷懒省略了。它被要求在与一个小到可以装进一个脑袋里的语料库和一个免费的查询规划器(我)竞争时证明自己的价值。在那一列上它基本做不到。

为什么这个"笨"版本持续胜出?

三个属性在起作用,没有一个是检索算法。

第一个是规模,或者说规模的缺失。对几千行做字面搜索,返回时间短到我把手从键盘上挪开就够了。没有召回天花板需要去工程化绕过,因为我可以把每条命中都扫一眼。Embeddings 大放异彩的地方恰恰在于扫完所有命中已不可能,而那条边界远在个人笔记的规模之上。

第二个是我就是查询规划器,而且对于我自己的材料来说,我是一个非常优秀的查询规划器。向量搜索必须推断"outbox"和"存放未发邮件的那个东西"是同一个概念。我不需要推断;我记得两个都写过,搜索的时候用哪个都行。RAG 里那笔昂贵的智能花在了重建意图上,而对于我自己的笔记来说,那份意图从未离开过这个房间。

第三个是信任,这是我一开始低估了的那一条。因为我在检索结果进入 prompt 之前先读了它们,所以我也在审查它们。我会捕捉到那条过时的笔记、那条看似当前但其实是猜测的文字、那个我不应该作为事实交出去的数字。静默注入前八个 chunk 的 pipeline 会剥夺我那唯一一道审核步骤,而正是那道步骤防止了模型在我已知已错的东西上信心满满地继续构建。我在之前的一篇文章里论证过,上下文的塑造才是产品,不是 prompt;手动做检索是我保持对那个产品所有权的的方式,而不是把它委托给一个相似度分数。

如果我在讲有效的部分就停住,就是说谎省略了真正的问题。这个笨版本有一个真实的漏洞,而那恰恰是 embeddings 被发明出来填补的那个洞。

字面搜索只能找到我记得存在的笔记。如果我忘了自己写过某行,或者用了我今天不会想到去搜索的词语来写它,grep 救不了我,因为它匹配字符串,而我输入的是错误的字符串。语义搜索不在乎我记得什么。当我搜索"the outbox keeps double-sending"的时候,它会把我六个月前写的那条关于 retry storms 的笔记捞上来,尽管两者没有一个共同的词。对于"遗忘材料的召回"这个场景,这是那套 machinery 真正的论据,而且随着文件夹的增长,这个论据每个月都在变强。

只要第二个人需要查询我的笔记,这套方案也就失效了,因为现在那个免费的专业查询规划器——我——不在循环里了,而所有那些我从未需要写下来的意图最终还是要由机器来重建。而且它会随着纯规模增长而缓慢失效:当我扫完所有命中的时间不再"瞬间"的那一刻,就是我悄悄跨过了教程们正确的那片领域的时刻。

这些都还没有严重咬到我。但我能看到边缘,而一个只美化自己设置的思维实验就只是一个广告。

什么让一条笔记真正可检索?

这是就算明天加上向量索引我也会保留的部分,因为它在每种检索方法的上游。一条笔记可被发现的程度,取决于它的词语与未来查询会用的词语之间匹配得有多好。Embeddings 放宽了那个约束;它们没有移除它。一条写成"felt off, fixed it"的笔记,用任何方法——语义或字面——都几乎不可发现,因为它没有编码任何后续问题会抓住的手柄。

所以这种自律和让笔记对未来的读者可读的自律是同一套:我把一行写出来的时候,让它自己的主题就在里面。我之前写过关于让笔记可以被未来的读者和未来的模型都能解析的文章,而个人 RAG 原来就是戴着时尚缩写的同一套习惯。检索方法在下游。写作才是索引。

每个人都应该跳过 embeddings 吗?

不,而这就是整张表的用意所在。规模翻转了答案。超过你能扫完所有命中的规模,或者超过除了作者之外的其他人开始查询语料库的那一刻,向量 pipeline 就从开销变成了唯一能工作的东西。论点很窄:对于一个人的几千条笔记,检索不是瓶颈,先为它付费是在解决错误的问题。

grep 不过是更差的召回率套了一张Straight Face 吗?

是的,一点没错,而更差的召回率是唯一值得花钱去解决的弱点。Pipeline 提供的其他一切,我要么不需要,要么宁可自己用眼去做。所以合理的混合方案很明显:把字面搜索作为主路径,把语义搜索仅作为"我知道我写过这方面的内容但找不到"这种召回失败场景的备选。

模型有没有读过整本笔记?

从来没有。它只读我粘贴过去的那几行。把语料库挡在 context window 外面是特性,不是限制;正是这个小的、手工挑选的集合让答案保持 grounded,而不是漂移到最大的那个相邻 chunk 恰好说的话里。

我实际要跑的那一半

在一个思想实验结尾诚实的做法是去检验那个我始终半信半疑的部分,所以这是我一直在回避的那个。我要加一个语义备选,但只用于召回未命中场景:字面搜索留在正门,embedding 索引只在 grep 什么也没返回而我仍然相信存在一条笔记的时候才被查询。我会把它跑一个月,对同一个文件夹记两个数——备选触发的频率,以及它捞到真实内容的频率——因为一个永远得不到命中的备选只是我得独自维护的基础设施。

我猜它触发得很罕见,而在它触发的那些天里是值得的。但我之前也判断错了一个系统里哪一半在承担重量,所以与其继续叙述,不如测量。

真正我想回答的问题是:当模型因为一条我忘了自己写过的笔记而答对了最后一道题,那是怎么找到的——你是搜索找到的,还是检索在你没问的情况下把它浮上来的?我在收集那些检索而非模型悄悄干了活的案例,因为这些案例才是决定那套 machinery 对一个人来说值不值的东西。

Simple Memo 是我自己做的 iOS 应用;它唯一的工作就是把脑子里的一行字在蒸发之前弄成纯文本。我大约每周在这里写一篇关于围绕那一个习惯生长的 workflow 的文章,而那些笔记中经过 curation 的 markdown 侧就是慢的那一半所在的地方。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
LandingAI 文档智能抽取 Gen2:原子级引用+按字符计费
下一篇
Claude Code vs Cursor:按任务场景选择 AI 编程工具的完整指南