返回笔记列表
Note Detail

本地 RAG 不是接个模型:Java、FastAPI、pgvector 的职责边界

把知识库问答做成工程系统,需要同时处理业务权限、异步入库、向量检索、拒答、来源展示和失败状态。

分类:RAG 工程发布时间:2026年7月16日更新:2026年10月2日原创内容
RAGFastAPIpgvectorSources

先说结论

一个知识库问答项目和“把问题转发给模型”的区别,不在聊天框长什么样,而在文档如何进入系统、答案如何找到依据、失败如何被观察,以及用户有没有权限访问这些资料。

My Knowledge Base 的本地 RAG 方案把职责分成三层:

  • React / Vite 负责上传、任务状态、提问、答案与 Sources 展示。
  • Spring Boot 负责用户、JWT、知识库权限、文件、任务状态和统一业务 API。
  • FastAPI 负责解析、切片、Embedding、pgvector 检索、prompt 组装与模型调用。

这个拆分不是因为 Python 或 Java 谁更“高级”,而是让业务系统和 AI 能力各自承担更适合的职责。

文档入库链路

一份文档进入知识库,大致经历下面这些阶段:

  1. 用户登录并选择有权限的知识库。
  2. Spring Boot 接收文件并先保存原始文件。
  3. 创建异步任务,记录当前阶段、成功或失败状态。
  4. FastAPI 解析 txt、md、PDF、docx 等内容;扫描 PDF 需要额外 OCR。
  5. 文本按 chunk size 与 overlap 切分,避免整篇文档直接塞进模型。
  6. 每个 chunk 生成 embedding,并写入 PostgreSQL / pgvector。
  7. 文档与任务状态更新,前端展示处理结果。

先保存原文件、再生成向量,是因为向量属于派生数据。解析或模型调用失败后,系统仍可以基于原文件重试,而不是要求用户重新上传。

查询链路为什么需要拒答和 Sources

提问时,系统先把 query 转成向量,然后限定在当前知识库里检索 TopK 片段。检索结果不是越多越好:太多会增加 token 和噪声,太少又可能缺上下文。

两个工程约束尤其重要:

  • score threshold:相关性低于门槛时拒答,避免模型在没有依据时猜测。
  • Sources:返回文档名、chunk、分数和片段预览,让答案能够被检查。

RAG 只能降低幻觉,不能消灭幻觉。原文没有答案、解析失败、chunk 切坏、检索错误或模型过度发挥,都可能让最终回答出错。

为什么选择 PostgreSQL + pgvector

对中小规模项目而言,PostgreSQL 可以同时保存业务表和向量数据,部署与维护成本比较低。检索时还能直接按知识库 ID、文档 ID 等业务条件过滤。

这并不意味着 pgvector 永远优于专用向量数据库。数据规模、索引方式、查询吞吐和多租户隔离要求上升后,仍然需要重新评估。当前选择是为了在能力与复杂度之间取得平衡。

换 Embedding 模型时也要谨慎:向量维度和语义空间可能发生变化。旧 chunk 用模型 A 生成,新 query 用模型 B 生成,会让检索结果失真,通常需要重建全部向量。

回答错误时按哪条链排查

推荐从输入往输出查,而不是先怀疑大模型:

  1. 原文是否包含答案。
  2. 文件是否被正确解析。
  3. chunk 是否在关键语义处被切断。
  4. embedding 是否一致,知识库过滤是否正确。
  5. TopK 和 threshold 是否召回了可靠片段。
  6. prompt 是否要求模型只根据检索内容回答。
  7. 前端是否展示了正确的 Sources 与任务状态。

这条顺序能把“AI 答错了”拆成可以定位的工程问题。

评测与可观测性证据

项目 Phase 2 用 12 篇笔记和 30 条 Gold cases 做检索实验。chunk size 200、overlap 40 经 DEV 集选择后,在 10 条 held-out TEST 用例上得到 SectionMRR 0.70。它只描述这组小样本中相关章节的排序表现,不是整体问答准确率,也不能代表生产语料效果。

DEV 上选出的 score threshold 0.625 没有泛化到 fresh holdout,因此没有应用,配置继续保留 min_score=0.35。Langfuse query trace 用合成数据验证了 trace 结构;真实材料联调时关闭 tracing,没有向 Langfuse Cloud 发送真实材料 trace。

项目演进与当前边界

项目早期使用 Dify 快速打通知识库和问答闭环,后来演进为 Spring Boot + FastAPI + PostgreSQL/pgvector + Ollama 的本地 RAG 方案,以便控制解析、切片、检索、拒答和来源展示。

2026-09-23 的仓库记录已用临时 PostgreSQL/pgvector、本地 Ollama 与合成 TXT、MD、DOCX、文本层 PDF 验证 Java 上传、FastAPI 切片入库和问答来源返回。扫描件 PDF 在 OCR 关闭时没有产生切片。该记录不覆盖干净机器首次启动、完整 Docker Compose、MinIO、OCR 识别或浏览器直连真实后端;前端 Playwright 使用 mock API,也不能替代真实前端端到端验收。

公开 GitHub README 已更新为本地 RAG 方案,并明确记录了这次验证范围。项目原有 Dify 截图仍是旧版本界面,不能作为当前本地 RAG 界面的证据;Linux 宿主机部署仍待验证。本轮未重跑测试或检索基准。