前端转 AI 实战 · 总纲:用「垂直切片 + 螺旋升级」六阶段,从零造一个企业级 RAG 知识库

本文是系列第 0 篇(总纲)。适合读者:有前端基础、想做 AI 应用 / 全栈、希望把东西真正跑起来的同学。

一、为什么要写这个系列

带过几个前端同学入坑 AI 应用开发,发现大家几乎都会卡在同一个地方:知道 RAG 是什么,但不知道怎么从零把它做成一个能跑的东西。

常见的两种失败姿势:

  • 姿势一:先啃理论。 花 4~6 周看 Transformer、看向量数据库原理、看各种综述,笔记记了一堆,一行代码没写,两个月后什么都拿不出来。
  • 姿势二:一上来就上企业架构。 Day 1 就设计多租户、SSO、审批流、可观测,表结构画了三版,MVP 遥遥无期,最后热情耗尽。

我自己走通之后的结论是:这两种都错在「没有可交付的中间态」

所以这个系列采用另一条路线——垂直切片 + 螺旋升级

  • 每个阶段交付一个完整可用的增量产品(不是半成品模块)
  • 学什么,完全由「这个阶段要实现的功能」倒推
  • 早期允许有限重构,但绝不为了「完美架构」阻塞 MVP

说人话就是:先让它跑起来,再让它变好,最后让它变成企业级。

二、这个系列写什么(7 篇目录)

篇号 标题 阶段 状态
00 总纲:六阶段路线全景(本篇)
01 P0 地基:不写一行前端,先用 CLI 跑通 RAG 闭环 P0
02 P1 MVP:FastAPI + Next.js,做出能演示的知识库 P1
03 P2 质量:混合检索、rerank 与 RAG 评测 P2
04 P3 工程化:异步入库、权限、审计、可观测 P3
05 P4 企业能力:多租户、SSO、审批流、连接器 P4
06 P5 产品化:Agent、多模态、私有化、计费 P5 🚧

每篇都会把这一阶段的每个步骤拆开写,并且标出 ⚠️ 易错点✅ 解决方案——这些都是真实踩过的,不是从文档抄的注意事项。

阅读约定:文中所有 ⚠️ 易错点 都是实战高频坑,紧跟的 ✅ 解决方案 可以直接照抄。代码已脱敏,但结构和参数与真实实现一致。

三、最终会做出什么

一个单租户可演示 → 企业级可用的知识库产品,最终形态:

                    ┌─────────────────────────────────┐
                    │      Next.js 管理台 + 对话      │
                    │    上传 / 文档管理 / 流式问答   │
                    └────────────────┬────────────────┘
                                     │ HTTP + SSE
                    ┌────────────────▼────────────────┐
                    │            FastAPI              │
                    │        鉴权 / 路由 / SSE        │
                    ├─────────────────────────────────┤
                    │      编排层 Orchestration       │
                    │  ┌───────────┐  ┌────────────┐  │
                    │  │ 工作流    │  │ 对话流     │  │
                    │  │ Workflow  │  │ Chatflow   │  │
                    │  │ 入库管线  │  │ 问答管线   │  │
                    │  └─────┬─────┘  └──────┬─────┘  │
                    │        └──── nodes ────┘        │
                    ├─────────────────────────────────┤
                    │  services 原子能力              │
                    │  chunking / embed / retrieve    │
                    └──┬──────────┬──────────────┬────┘
                       │          │              │
              ┌────────▼──┐ ┌─────▼───┐ ┌────────▼────┐
              │ 元数据库  │ │ 向量库  │ │ LLM /       │
              │ meta.json │ │ Chroma  │ │ Embedding   │
              │ → Postgres│ │ → Qdrant│ │ (OpenAI兼容)│
              └───────────┘ └─────────┘ └─────────────┘

图里的编排层是 P2 才会出现的,P0/P1 阶段 FastAPI 直接调 services。为什么要等到 P2、它到底解决什么问题,第六节专门讲。

而 RAG 的核心链路,从头到尾就这一条,六个阶段都是在这条链路上做加法:

文档 ──切分──▶ chunk ──向量化──▶ 向量库
                                   │
用户提问 ──向量化──▶ 相似度检索 ────┘
                     │
                  top-k chunk ──▶ 拼进 Prompt ──▶ LLM ──▶ 带引用的回答

能把这条链路口述清楚,比背下十篇论文有用得多。 这也是 P0 唯一的目标。

四、技术栈(贯穿全程)

选型 为什么这么选
前端 React / Next.js 前端老本行,直接发挥优势
后端 Python + FastAPI AI 生态在 Python,FastAPI 的类型体验对前端很友好
RAG 框架 LlamaIndex 入库 / 检索管线开箱即用,MVP 阶段省时间
编排(P2 起) llama_index.core.workflow 事件驱动、自带会话上下文;已在依赖里,不用自己造 DAG 引擎
向量库 Chroma(本地)→ 可换 Qdrant / pgvector 先本地零依赖跑通,后期再换
元数据 meta.json → Postgres(P3 起) MVP 别急着上数据库;P3 必须分离
LLM 云 API(DeepSeek / 通义 / 任意 OpenAI 兼容) 不折腾显卡,后期可选本地模型
部署 Docker Compose 一键起,方便演示

⚠️ 路线级易错点 1:一上来就纠结「选 LangChain 还是 LlamaIndex」「选 Qdrant 还是 Milvus」,选型对比看了三天,代码零行。
解决方案:MVP 阶段选型不重要,跑通才重要。这套链路的抽象是通的,换框架/换向量库的成本远比你想象的低(P0 里我会把 IndexManager 单独抽出来,就是为了后面能换)。先用 LlamaIndex + Chroma 跑通,等你真的遇到瓶颈了再谈替换。

五、六阶段路线全景

阶段 参考时长 产品形态 这一阶段的核心命题
P0 地基 1–2 周 CLI:上传 → 切分 → 检索 → 回答 建立 AI 开发语感
P1 MVP 3–4 周 可演示的单租户知识库(Web) 端到端产品闭环
P2 质量 3–4 周 检索/回答明显更好 + 评测面板 让答案「真的对」
P3 工程化 3–4 周 异步入库、权限、审计、可观测 从玩具到工程
P4 企业能力 4–6 周 多租户、SSO、审批流、连接器 从工程到企业级
P5 产品化 持续 Agent、多模态、私有化、计费 持续演进

下面逐个说清楚:做什么、验收什么、明确不做什么

P0 地基(1–2 周)

做什么:不碰任何 Web,用两个 CLI 脚本跑通 RAG 全链路。

  • Python 实用向:类型标注、Pydantic、uv 包管理
  • LLM 基础概念:token、temperature、embedding、chunking
  • 向量检索直觉:相似度、top-k、切分质量与回答质量的关系

验收:用 3–5 份自己的文档,能问出「文档里有、模型不该瞎编」的答案;能完整口述 文档 → chunk → vector → retrieve → generate

明确不做:登录、权限、多格式解析、评测、队列、审核。

详见 [第 01 篇:P0 地基]

P1 MVP(3–4 周)

做什么:把 P0 的 CLI 包装成产品。

  • FastAPI 项目结构、依赖注入、错误模型
  • SSE 流式输出(这是前端同学的主场)
  • 知识库创建、文档上传(PDF / MD / TXT)、解析状态
  • 多轮对话、流式回答、展示引用 chunk
  • 文档列表、删除、重建索引
  • Docker Compose 一键起

验收:5 分钟演示走通——上传 → 提问 → 带引用回答 → 删掉文档后再问,必须无法引用该内容。最后一条是整个 P1 最容易翻车的验收项。

明确不做:多租户、RBAC、SSO、连接器、复杂 Agent、审核流。

P2 质量(3–4 周)

做什么:让答案从「能答」变成「答得准」。

  • 混合检索(向量 + BM25)、rerank
  • Query 改写 / HyDE / 多查询
  • RAG 评测:忠实度、相关性、上下文召回;自建 Golden Set
  • 引用高亮、来源跳转、👍/👎 反馈
  • 对话流节点化:新建 orchestration/,把问答链路拆成 classify / rewrite / retrieve / rerank / answer,让两条策略能并存对比(详见第六节)

验收:同一批文档,在自建 Golden Set 上相对 P1 有可量化的提升;能一键切换两条对话流跑同一批题目比分数。

⚠️ 路线级易错点 2:没有 Golden Set 就开始「凭感觉调参」——改了 chunk_size,感觉好像变好了?其实不知道。
解决方案:进 P2 的第一件事不是接 rerank,是先攒 20~50 条问答对做基线。没有基线,后面所有优化都是玄学。

P3 工程化(3–4 周)

做什么:从「能跑」到「能上线」。

  • 异步任务(Celery / ARQ):大文件入库不再阻塞 API,入库链路搬成工作流,事件流直接当进度条
  • JWT + 基础 RBAC;知识库级读/管权限
  • 结构化日志、请求追踪、token / 费用统计
  • Postgres 元数据与向量库分离
  • 轻量发布门禁:draft → published,未发布不参与检索

验收:大文件上传后可以离开页面,回来看进度、失败可重试;无权限用户看不见对应知识库;能画出 API / Worker / DB / Vector / LLM 的边界图。

⚠️ 路线级易错点 3:MVP 用 JSON 文件存元数据很爽,然后一路带到生产,并发写直接丢数据。
解决方案:JSON store 是有意为之的临时方案,P0–P2 够用(我在 P0 里会给它加线程锁兜底),但 P3 必须迁 Postgres。关键是从一开始就把它抽成 MetaStore 接口,迁移时只换实现。

P4 企业能力(4–6 周)

做什么:真正的企业级特性。

  • 多租户:tenant_id 隔离,租户 A 的库对租户 B 完全不可见
  • SSO / OIDC(Keycloak / Authing 本地体验)
  • 完整审批流:提交 → 通过 / 驳回 → 发布;待审队列
  • ≥1 个外部连接器(飞书 / Notion / 本地文件夹自动同步)
  • 编排流配置化:按知识库存一份 JSON,决定这个库用哪些节点、什么参数(不同业务库用不同的解析 / 切分 / 检索策略)

⚠️ 路线级易错点 4(设计层面的大坑):把「审核」做成用户身上的一个布尔字段,比如 user.is_reviewer = true
解决方案:审核不是用户标签,而是资源上的权限 + 文档状态机。正确模型是:

User ──< Membership >── KnowledgeBase
              │
           role: admin | editor | reviewer | viewer

Document.status: draft → pending_review → published / 驳回回 draft

权限(kb:upload / kb:publish / kb:review)挂在知识库成员角色上。用全局布尔字段的话,「张三在 A 库是审核人、在 B 库只是普通成员」这种再正常不过的需求根本表达不了,到时候只能推倒重来。

P5 产品化(持续)

按需选做,但每一项都必须有用户故事和验收标准

  • Agent:多步检索、工具调用、护栏(编排层这时候才真正派上大用场)
  • 编排可视化:只读的流程图 + 节点耗时(不做拖拽画布,理由见第六节)
  • 多模态:OCR、表格问答
  • 私有化:本地模型、离线部署文档
  • 质量运营:坏案例回流、回归评测、策略版本管理
  • 商业化:配额、计费、多环境

⚠️ 路线级易错点 5:到了这个阶段容易变成「课程收藏家」——看了一堆 Agent 教程,但产品一点没动。
解决方案:每一项立项前先写一句用户故事和一条验收标准,写不出来就说明现在不需要做它。

六、编排层:工作流与对话流该放在哪

用过 Dify 的同学一定会问:你这套里,像 Dify 那样拖节点的「工作流 / 对话流」在哪?

先说结论:P0 和 P1 里没有,也不该有。 但从 P2 开始,它会长成后端最核心的一层。这里单独拎出来讲,因为这是整条路线上最容易「做早了」和「做过头」的地方。

6.1 两种流,本质是两件事

Dify 分成两套入口不是产品经理拍脑袋,是这两类流的运行模型根本不同:

工作流 Workflow 对话流 Chatflow
触发方式 一次性任务 多轮会话
有没有记忆 有(会话变量 + 历史)
输出形态 跑完给个结果 中途多次流式吐字
关注的指标 吞吐、失败重试 首字延迟
对应到本系列 入库链路 问答链路

6.2 其实你从 P0 起就有两条流了,只是写死在函数里

有意思的地方在于:任何一个 RAG 项目天生就有这两条流,只不过它们是用「代码行的先后顺序」表达的,而不是数据。

[ 工作流 ]  ingest(file)
   读文件 ─▶ 切分 ─▶ 向量化 ─▶ 写库 ─▶ 更新状态
   ↑ 一次性、无记忆、可以跑很久、失败要能重试

[ 对话流 ]  chat(question, history)
   检索 ─▶ 拼 Prompt ─▶ LLM 流式输出 ─▶ 带引用返回
   ↑ 多轮、有历史、首字要快

编排层要做的事,就是把这两条「硬编码的直线」变成「可组合的节点 + 一份声明」。

对话流这条尤其明显:它现在只有「检索 → 回答」两个节点,而 Dify 对话流最核心的几个能力——问题分类器(闲聊 / 知识库问答 / 拒答)、问题改写(HyDE、多查询)、条件分支(检索为空就别硬答)——一个都没有。巧的是,这几样恰好就是 P2 要补的东西。

6.3 什么时候值得做:P2,不是更早

判断标准很简单:当你开始需要「同一条链路跑出两个版本来对比」的时候。

P2 的验收要求是「策略可切换对比」——朴素检索 vs 混合检索 + rerank,到底哪个在 Golden Set 上更好?如果不节点化,你会在 chat() 里写出这种东西:

if strategy == "hybrid":
    ...
elif strategy == "hyde":
    ...
elif strategy == "hybrid_rerank":
    ...

三个策略之后这个函数就没法看了,而且没法做「A/B 各跑一遍比分数」。节点化之后,一条流就是一份声明:

naive_rag(基线,就是 P1 的行为)
  retrieve → answer

advanced_rag(增强)
  classify          判断:闲聊 / 知识库问答 / 直接拒答
    → rewrite       HyDE、多查询改写
    → retrieve      向量 + BM25 混合检索
    → rerank        重排序
    → [条件分支]    检索结果为空 → refuse
                    否则         → answer

两条流共用同一批节点,只是组合方式不同。评测时跑同一批 Golden Set,分数一比就知道改进有没有效果。

6.4 放在哪:新开一个目录,services/ 一行都不动

backend/app/
├── services/                 # 保持不变,降级为「原子能力」
│   ├── ingest.py
│   ├── retrieve.py
│   └── chat.py               # 变成薄封装,老接口不破
└── orchestration/            # ← 新增:编排层
    ├── events.py             # RetrievedEvent / RewrittenEvent / AnswerChunkEvent
    ├── nodes/                # 原子节点,两种流共用
    │   ├── classify.py       # 闲聊 / 知识库问答 / 拒答
    │   ├── rewrite.py        # HyDE、多查询
    │   ├── retrieve_node.py  # 薄薄包一层 services.retrieve
    │   ├── rerank.py
    │   └── answer.py
    ├── chatflows/            # 对话流
    │   ├── naive_rag.py      # 把 P1 的行为原样搬过来,当基线
    │   └── advanced_rag.py   # 改写 + 混合检索 + rerank + 拒答分支
    └── workflows/            # 工作流
        └── ingest_flow.py    # 把 P1 的入库链路搬过来

关键是节点只是薄薄包一层 services,所以已有的单测和 P1 的验收一条都不会破。这也是我建议把编排层单开目录、而不是就地改造 services/ 的原因。

6.5 引擎不用自己写

这是最值得省的一笔时间:如果你用 LlamaIndex,编排引擎已经在你的依赖里了。

llama_index.core.workflow 自带 Workflow / @step / Event / Context,装了 llama-index-core 就能直接 import,不需要额外装包。它是事件驱动而不是 DAG,这点对 RAG 反而更顺手:

  • 「检索为空就拒答」这种分支,DAG 得画条件边,事件驱动就是 return RefuseEvent() 还是 return AnswerEvent()
  • Context 天生是会话变量容器,正好是对话流需要的
  • stream_events() 的输出可以直接怼给 SSE,前端协议不用改

⚠️ 路线级易错点 6:手撸一个 DAG 执行器。两三百行确实能跑起来,而且很有成就感。
解决方案:跑起来只是第一步。重试、并发、超时、中断续跑、变量作用域,这些一个都逃不掉,最后你会花三周重写一个更差的 workflow 引擎。用现成的,把时间花在节点逻辑上——那才是 RAG 的价值所在。

⚠️ 路线级易错点 7:想把工作流和对话流抽象成同一个引擎、同一个基类。
解决方案:Dify 自己都是两套入口。共享 nodes/,但流的定义各写各的。 强行统一的结果通常是一个谁都读不懂的抽象基类,改一个流会莫名其妙影响另一个。这两者一个要重试和吞吐、一个要记忆和首字延迟,硬凑到一起没有好处。

⚠️ 路线级易错点 8(做早了比做晚了更糟):P0/P1 就急着搭编排层,理由是「反正早晚要做」。
解决方案:只有两个节点的链路,节点化之后代码量翻倍、可读性下降,收益为零。等到你真的需要「两条策略并存对比」的那一刻再做——那时候你已经知道节点边界该切在哪了。抽象是长出来的,不是设计出来的。

6.6 别做拖拽画布

一定会有人想做可视化编排。给个成本参考:Dify 的画布 + 变量系统 + 调试面板是几万行代码,那是它的产品护城河,不是一个学习项目该碰的东西。

真想要视觉效果,有个成本只有 1/50 的替代方案:做一个只读的流程图展示——把 Python 里定义好的节点关系渲染成图,标上每个节点的耗时。前端同学做这个很快,讲架构的时候效果一样好。

配套的低成本改动是在 SSE 里多发一种事件:

{"type": "node", "name": "rewrite", "status": "done", "elapsed_ms": 120}

前端就能展示「这次回答走了哪些节点、各花了多久」——这就是 Dify 的运行日志。严格说属于 P3 可观测的范畴,但成本极低,建议顺手做了。

6.7 编排能力在六个阶段里的演进

阶段 编排层的状态
P0 无。两条硬编码直线,这是对的
P1 无。加了 Web 和 SSE,链路本身没变
P2 orchestration/,问答链路节点化,naive_rag / advanced_rag 两条流并存对比
P3 入库链路搬成工作流,丢给 worker 异步跑,事件流直接当进度条
P4 流配置化:按知识库存一份 JSON,决定用哪些节点、什么参数
P5 才轮到只读流程图 / Agent 多步编排

七、三个贯穿全程的坑

前面按阶段列了 8 个,这里再补 3 个每个阶段都会遇到的:

⚠️ 路线级易错点 9:chat 模型和 embedding 模型混为一谈。很多人选了 DeepSeek 做对话,配了一个 OPENAI_API_BASE 就以为万事大吉,结果向量化直接 400 / 401。
解决方案DeepSeek 目前不提供 embedding 接口。chat 和 embedding 是两个独立能力,可以来自不同厂商。MVP 阶段最省事的做法是全用一家支持两者的(如通义 DashScope 兼容模式、硅基流动、OpenAI),或者把 chat / embedding 拆成两组配置。这个坑我在 P0 会详细写怎么配。

⚠️ 路线级易错点 10:只跑单元测试就宣布「这个阶段完成了」。
解决方案:每个阶段的验收都必须是端到端的真实演示(真 Key、真文档、真提问)。单测只保证函数没写错,保证不了链路是通的——我在 P0 就吃过这个亏,单测全绿,一跑真实 Key 直接报模型名不在枚举里。

⚠️ 路线级易错点 11:每周做了很多,但说不清楚「为什么这么选」。
解决方案:养成每周写一条决策笔记的习惯——不用长,三行就够:遇到什么问题、有哪几个选项、为什么选了这个。这个系列里大量的「为什么」都是从这些笔记里来的。

八、每周节奏建议

如果你能全天投入,建议「4 天做 + 1 天学/复盘」:

时间 安排
周一–周四 实现当前阶段的下一个可演示切片
周五 补原理 + 把本周的决策写成笔记
周末(可选) 录 3–5 分钟 Demo,更新 README

每周强制交付:① 一个可运行的增量功能;② 一条架构 / 决策笔记;③ P2 起:至少一个自动化测试或评测用例。

九、小结

整个系列的方法论,其实就一句话:

别先学 6 周理论,也别 Day 1 上企业架构。垂直切片、每阶段可演示、把坑记下来。

下一篇 [P0 地基] 会从零开始,不写一行前端代码,用两个 CLI 脚本把 切分 → 向量化 → 检索 → 生成 这条链路完整跑通,并且把我在这一步踩的 37 个坑全部标出来——包括那个让我卡了半天的「模型名不在 OpenAI 枚举里」。


系列文章会陆续更新,有问题欢迎评论区交流。

posted @ 2026-08-08 12:37  南珂丶一梦  阅读(28)  评论(0)    收藏  举报