自建 RAG 系统还是集成现成框架

问题从哪里来

最近在做一个运维平台(opsmind),其中需要 RAG 对话能力 —— 上传文档后,用户可以对着文档内容提问。

这个需求本身很常见。不常见的是接下来的决策:要不要用现成的 RAG 框架?

LangChain、LlamaIndex 这些框架已经把 RAG 的各个环节封装好了。文档加载、文本分割、向量存储、检索、LLM 调用 —— 几行代码就能串起来。看起来没有理由不用。

但我最后选了自建。

真正卡住的是哪一步

选框架之前,我先问了三个问题:

1. 我需要多少个组件?

RAG 的核心链路其实很短:文档解析 → 向量检索 → LLM 对话。如果检索结果不够好,加一个 Rerank 重排序。

LangChain 在这一层之上构建了大量的抽象:Chain、Agent、Tool、Memory、Callback…… 每个概念都对应一组类和接口。对于 opsmind 这个场景,我只需要最基础的那层能力,上面的抽象全是额外负担。

2. 这项目要维护多久?

opsmind 是一个需要长期维护的运维平台,不是一次性原型。集成框架意味着把核心对话能力的演进节奏交给框架的版本迭代。

框架升级时 API 可能 breaking change,依赖链可能冲突,行为可能出现静默变化。这些在短期项目中不是问题,但在长期项目中是持续的维护成本。

3. 出问题时我能多快定位?

这不是一个理论问题。之前用过某 RAG 框架,检索结果不理想时,排查链路是:框架的 Retriever 封装 → 框架的向量存储封装 → embedding 调用 → 底层向量库。每一层都可能引入偏差。

自建的系统,我清楚每一步输入输出是什么。排查路径是线性的,不需要先理解框架的设计意图才能定位问题。

我最后怎么处理

技术栈选了三个组件:

  • LLM:llama.cpp 驱动本地模型,不需要外部 API 依赖
  • 文档解析:多格式支持(文本、PDF 等),根据不同文件类型走不同的解析路径
  • Rerank:开源交叉编码器模型,通过 Python 服务做桥接调用

整体架构非常简单:

文件上传 → 文档解析 → 向量化存储 → 检索

用户提问 → 初步检索 → Rerank 重排序 → LLM 生成回答

没有 Chain、Agent、Memory 这些概念层。这不是说它们没用,而是在 opsmind 这个场景下暂时用不上。将来如果确实需要复杂的 multi-step reasoning,再加也不晚 —— 从简单往复杂加比从复杂往简单拆容易得多。

RAG 多模式文件上传、内嵌提示词统一用 Markdown 管理,这些细节也一起做了。

这件事留下的经验

不要因为」别人都在用」就默认选某个方案。 框架解决的是通用问题,你的项目有你的约束。把约束列出来 —— 维护周期、团队规模、性能要求、可调试性 —— 再决定。

自建不是反框架。 如果这是一个两周后就不用的内部工具,LangChain 是更好的选择。决策依据不是」哪个技术更先进」,而是」哪个方案的总成本更低」—— 总成本包括开发成本、维护成本、学习成本和排错成本。

核心链路往往比你想象的短。 RAG 听起来复杂,但最小可用集就是检索 + LLM + 可选的 Rerank。框架把简单的事情包装成复杂的概念,学习这些概念的时间可能比自己写一遍还要长。

最终的选择不是技术信仰问题,而是算清楚什么对当前项目最划算。