← 返回笔记索引

项目实践

从 RAG Demo 到生产级个人 AI Assistant:zglab-rag 的工程演进

复盘 zglab-rag 如何从本地 Markdown 知识处理逐步演进为带公开边界、引用校验、SSE 和生产运行能力的个人知识助手。

从 RAG Demo 到生产级个人 AI Assistant:zglab-rag 的工程演进

目录

背景与目标

个人主页、项目说明和长期笔记中保存着许多可公开的事实,但访客通常不会逐篇阅读。zglab-rag 的目标 不是替作者编写一个“看起来了解本人”的人格,而是在已有公开资料足以支持时,给出可追溯的第一人称 回答;资料不足时明确返回证据不足。

这里的验收对象不是模型文案,而是一条证据链:来源是否被允许公开、检索结果是否正确、上下文是否 受控、最终 claim 是否有合法引用。

为什么不是直接调用通用 LLM

通用模型可以生成流畅的个人介绍,却不能证明它的项目状态、经历或指标来自何处。对于个人 AI Assistant,这会产生两个独立风险:模型把训练知识或相似人物信息误当成事实;系统把本应保密或未确认 的资料暴露到公网。

因此项目把下列关系固定为主路径:

Evidence → Retrieval → Context → Grounded Generation → Citation

第一人称 Persona 位于生成表达层,不是事实来源。公开 API 也不允许客户端提交 visibilitytop_k、模型或调试开关来改变服务端边界。

系统演进

演进不是一次性堆入向量库和聊天界面,而是按可验证的依赖顺序完成。

flowchart LR
    P1[Phase 1\nMarkdown Ingestion] --> P2[Phase 2\n受控 Git 来源]
    P2 --> P3[Phase 3\nEmbedding Benchmark]
    P3 --> P4[Phase 4\n增量 SQLite Index]
    P4 --> P5[Phase 5\nVector Retrieval]
    P5 --> P6[Phase 6/7\nHybrid 与 Reranker 实验]
    P6 --> P8[Phase 8\nGrounding 与 Citation]
    P8 --> P9[Phase 9\nAPI、SSE、Vue]
    P9 --> P10[Phase 10\n部署与同步]

前置阶段先让文档、Chunk、Embedding 和索引具备稳定身份,后续 Retrieval、Generation 与 Web 产品才有可追溯的输入。这样也避免 API 层承担解析、模型加载、检索和 LLM 调用等所有职责。

最终架构

当前公网产品由 Vue、Nginx、FastAPI、SQLite 和本地 Embedding 组成。SQLite 是知识索引的权威 存储,sqlite-vec 保存向量,外部 LLM 只接收经过过滤和预算限制的 Evidence Context。

flowchart TD
    B[Browser] --> W[Vue Assistant UI]
    W --> N[Nginx / HTTPS]
    N --> API[FastAPI Public API]
    API --> S[GroundedAnswerService]
    S --> V[VectorRetriever\npublic only]
    V --> DB[(SQLite + sqlite-vec + FTS5)]
    S --> CB[ContextBuilder]
    CB --> L[OpenAI-compatible LLM]
    L --> CV[CitationValidator]
    CV --> W

SSE 只发送 acceptedretrievinggeneratingvalidatingcompleted 等状态,不直接 流出未经引用校验的模型 token。最终回答与 Sources 只在结构化生成和校验完成后发送。

关键设计决策

先冻结边界,再优化质量

Phase 9 冻结了 Chunking、Embedding、Vector、Hybrid、Reranker、Grounding 和 Citation 的 既有契约。产品接入发现的问题可以修复,但不能借由 UI 开发偷偷改写检索 baseline。

把“证据不足”当作正常结果

insufficient_evidence 不等于 500。它表示系统正确地拒绝把低分召回、LLM 想象或空上下文写成 个人事实。这一状态也为后续受控外部研究预留了清晰入口。

以模块化单体匹配当前规模

项目没有引入 Kubernetes、Redis、Elasticsearch 或消息队列。对单个 2 vCPU、2 GB 内存服务器, Nginx + FastAPI + SQLite + systemd 的组合更容易观察、备份和恢复;可替换接口则为未来变化保留 边界。

验证与结论

截至 2026-08-21,生产验收记录显示:首次索引写入 1,058 个新增 Chunk;服务预热约 5.6~8.2 秒; 稳定 RSS 约 439 MiB;一次实际 SSE 请求在 6.691 秒完成。普通问答、Sources、证据不足、HTTPS、 备份和重启恢复均完成验证。

这些数据不等于系统在所有问题上都可靠。它们只说明当前公开来源、测试集和运行预算下,证据链与产品 链路能够共同工作。下一步改动仍应先进入评测与边界设计,而不是直接扩大模型的自由度。

方法论总结

从 Demo 走向产品的关键不是增加更多组件,而是让每一层都能说明自己的输入、输出和失败语义。对于 个人知识助手,最重要的产品能力不是“什么都回答”,而是知道什么可以回答、依据是什么、什么不能确认。