自建 RAG 系统还是集成现成框架
问题从哪里来
最近在做一个运维平台(OpsMind),需要 RAG 对话能力 —— 上传文档后,用户能对着文档提问。
这个需求很常见。不常见的是接下来的决策:要不要用现成的 RAG 框架?
LangChain、LlamaIndex 已经把 RAG 各环节封装好了。文档加载、文本分割、向量存储、检索、LLM 调用 —— 几行代码就能串起来。看起来没有理由不用。
但我最后选了自建。
真正卡住的是哪一步
选框架之前,先问三个问题。
1. 我需要多少个组件?
RAG 的核心链路其实很短:文档解析 → 向量检索 → LLM 对话。检索结果不够好,加一个 Rerank 重排序。
flowchart LR
A[文档上传] --> B[文档解析]
B --> C[向量化存储]
D[用户提问] --> E[初步检索]
E --> F[Rerank 重排序]
F --> G[LLM 生成回答]
C -.-> ELangChain 在这一层之上建了大量抽象:Chain、Agent、Tool、Memory、Callback…… 每个概念对应一组类和接口。
对这个场景,只需要最基础那层能力,上面的抽象全是额外负担。
2. 这项目要维护多久?
OpsMind 是长期维护的运维平台,不是一次性原型。
集成框架意味着把核心对话能力的演进节奏交给框架的版本迭代。框架升级可能 breaking change,依赖链可能冲突,行为可能静默变化。短期项目无所谓,长期项目是持续维护成本。
3. 出问题时我能多快定位?
这不是理论问题。之前用过某 RAG 框架,检索结果不理想时,排查链路是:框架的 Retriever 封装 → 框架的向量存储封装 → embedding 调用 → 底层向量库。每一层都可能引入偏差。
自建的系统,我清楚每一步输入输出。排查是线性的,不需要先理解框架的设计意图。
我最后怎么处理
技术栈选了三个组件:
- LLM:llama.cpp 驱动本地模型,不依赖外部 API。
- 文档解析:多格式支持(文本、PDF 等),不同文件类型走不同解析路径。
- Rerank:开源交叉编码器模型,用 Python 服务桥接调用。
整体架构很简单:
文件上传 → 文档解析 → 向量化存储 → 检索 |
没有 Chain、Agent、Memory 这些概念层。不是它们没用,是这个场景暂时用不上。
将来需要复杂 multi-step reasoning,再加也不晚。从简单往复杂加,比从复杂往简单拆容易得多。
RAG 多模式文件上传、内嵌提示词统一用 Markdown 管理,这些细节也一起做了。
这件事留下的经验
不要因为」别人都在用」就默认选某个方案。
框架解决通用问题,你的项目有你的约束。把约束列出来 —— 维护周期、团队规模、性能要求、可调试性 —— 再决定。
自建不是反框架。
如果这是两周后就不用的内部工具,LangChain 是更好的选择。决策依据不是」哪个技术更先进」,而是」哪个方案总成本更低」。总成本包括开发、维护、学习、排错。
核心链路往往比你想象的短。
RAG 听起来复杂,最小可用集就是检索 + LLM + 可选的 Rerank。框架把简单的事包装成复杂概念,学习这些概念的时间可能比自己写一遍还长。
最终选择不是技术信仰问题,而是算清楚什么对当前项目最划算。