Knowledge Studio 本地开源版:对标百炼 RAG 控制台的架构、重难点与差异

Knowledge Studio 本地开源版:对标百炼 RAG 控制台的架构、重难点与差异

发布日期:2026-08-06

标签:RAG / Knowledge Studio / pgvector / Ollama / Next.js / 工程实践

项目:jiaxiantao/knowledge-studio · 静态预览:jiaxiantao.xyz/knowledge-s...

阿里云百炼把 Knowledge Studio 做成了企业级「知识管理 → 知识检索 → 知识问答」闭环。用起来很顺:上传、切片、召回、引用,控制台一眼就能演示。

但顺的代价是:链路被托管了,你看不见 OCR 为什么挂、分数怎么算、弱召回时 Prompt 该怎么写。

我做了一个本地开源版 Knowledge Studio:同一套产品形态,技术栈换成 Next.js + PostgreSQL/pgvector + 本机 Ollama。目标不是替代云产品,而是把 RAG 控制台的最小可运行切片拆开------前端工程师也能读懂、改得动、讲得清。

🎭 左边:云端把链路收进按钮。右边:本地把解析、向量、问答全部摊开------这篇讲的就是右边那条白盒。

全文约 18 分钟。读完你应该能回答三件事:

  1. 本地版整条链路怎么串起来的
  2. 真正卡住工程的是哪几块(不是「调个 embedding」那么简单)
  3. 和百炼 Knowledge Studio 比,云端买走了什么、本地逼你直面了什么

一句话定位

维度 说明
定位 轻量 RAG 知识库控制台(学习 / 本机 / 内网)
对标 百炼 Knowledge Studio 的核心产品环,不是完整企业版
技术栈 Next.js 16 · React 19 · Prisma · Postgres + pgvector · Ollama(qwen3 + nomic-embed-text
安全默认值 无鉴权------面向本机/可信内网;公网前请自己加门禁

产品上三根柱子对齐云端 IA:

页面 对应百炼能力 本地实现要点
/knowledge 知识管理 多知识库、类目、异步上传、切片 CRUD / 启停检索
/retrieval 知识检索 多库联合向量试跑,暴露 latency / minScore / hitCount
/assistant 知识问答 多库联合召回 + SSE 流式(思维链 → 结论)+ 引用与置信度

总架构:一条进程里跑完 RAG

本地版刻意做成「可拆开看的单体」:UI、API、解析、向量写入、问答编排都在同一个 Next.js 进程里。

🎭 Console → API 再分叉到入库 / 检索 / 问答;底下一层是 Postgres+pgvector 与本机 Ollama。

和云端对照一下数据流就更清楚:

环节 百炼 Knowledge Studio / 知识存储 本地开源版
原始文件 OSS data/uploads/
解析 / 切片 托管流水线(如 DocMind) 进程内解析器 + 可选 OCR
向量 Tablestore + 托管索引 Chunk.embedding vector(768)
检索 向量 + 全文混合,RRF / WEIGHT / Rerank 纯向量 + minScore 门槛
生成 云端大模型 / 应用编排 本机 Ollama,OpenAI 兼容也可换
运维 Serverless、按量计费 Docker Compose 或 pnpm dev

数据模型几乎是同一套名词,方便对照文档:

scss 复制代码
KnowledgeBase
  ├── DocumentCategory
  ├── Document (pending → parsing → ready | failed)
  │     └── Chunk (content + enabled + embedding?)
  └── ChatSession (branches JSON)

Prisma 里向量类型走 Unsupported("vector(768)"),读写用 raw SQL------这是后面第一个工程坑。


主链路:上传 → 切片 → 召回 → 有依据地答

1. 上传要「立刻返回」,解析不能堵在请求里

POST /api/documents 落盘并创建 pending 文档后,用 Next.js after() 把重活甩到响应之后:

typescript 复制代码
after(() => {
  void processDocumentIngest(document.id);
});
return NextResponse.json({ document }, { status: 201 });

进度条按阶段推进:文字/OCR 约 12--28%,切片与向量化 30--96%,完成 100%。另有 INGEST_STUCK_MINUTES(默认 15 分钟)把卡死任务标出来,支持强制重试。

这和云端「异步建索引」产品体验一致,但实现差一个量级:本地是进程内内存去重ingestInFlight Set),不是 durable job queue。单机够用;多副本 / 重启中途会丢任务------这是诚实边界,不是「也算生产级调度」。

2. 多格式解析:对标上传矩阵,而不是只做 ChatPDF

早期只支持 md/txt/pdf。对齐百炼演示后,上传规则按类型收紧:

类型 格式 默认限制(节选)
文档 pdf / doc / docx / ppt / pptx ≤150MB;PDF ≤1000 页
表格 xls / xlsx ≤10MB;≤10 万行
图片 png / jpg / ... ≤20MB + 尺寸/长宽比
纯文本 md / txt / html ≤10MB

解析路由大致是:docx→mammoth,表格→xlsx,老式 office→officeparser,html 去标签,图片直接 OCR。PDF 先走 pdf-parse 抽文字层。

3. 扫描件 PDF:文字层为空时才上 OCR

这是 changelog 里写过的真实翻车:思维导图类 PDF 显示 24 页,文本长度却是 0------不是文件坏了,是图片型 PDF

回退路径:

bash 复制代码
pdf-parse 无文本
  → PDFium 按页渲染 bitmap
  → @napi-rs/canvas 转 PNG
  → Tesseract(默认 chi_sim)识别
  → 再切片、向量化

OCR 有页数上限、渲染倍率、语言包配置(PDF_OCR_*)。识别会有错字,但多数场景检索仍可用;大文件耗时长,所以进度回调必须接进 UI。

云端用 DocMind 一类托管解析,你几乎感觉不到这一刀。本地做一遍,才知道「支持 PDF」四个字后面有多少分支。

4. 切片:段落优先,固定窗口 + 重叠

splitIntoChunks 默认约 700 字窗口、80 字重叠 :先按空行攒段落,超长段落再滑窗切开。标题取第一行有意义内容。Token 用 ceil(len/1.5) 粗估中英混合------够排进度、不够当精确计费。

百炼侧切片策略偏托管/智能切;本地刻意保持可读、可调、可解释的规则切片,方便演示「改 chunk 大小会怎样」。

5. Embedding:聊天走 /v1,向量走原生 API

对话用 OpenAI SDK 打 Ollama 的 OpenAI 兼容口;向量走原生 /api/embeddings,维度写死 768nomic-embed-text)。两个 base URL 容易配错------OLLAMA_NATIVE_BASE_URL 就是为这个拆开的。

写入:

sql 复制代码
UPDATE "Chunk" SET embedding = $1::vector WHERE id = $2

换 embedding 模型若维度变了,要改 schema / 重建索引。百炼文档也强调:Embedding 配置创建后不可改,换模型等于重建知识库------本地版用硬编码维度把同一约束提前暴露给你。

6. 检索:多知识库联合 + minScore 门槛

sql 复制代码
ORDER BY c.embedding <=> $1::vector
-- score = 1 / (1 + distance)

过滤条件:embedding IS NOT NULLenabled = true、文档 ready,并可按一个或多个 knowledgeBaseId 过滤。问答侧还会按库数量放大 topK(约 ids.length * 4,夹在 5--20)。

弱命中用 RAG_MIN_SCORE(默认 0.42)丢掉,避免「随便召回两段无关文字 → 模型硬编文档事实」。

检索工作台刻意只保留真参数(query / topK / minScore / 多库),假开关(路由模式、假权重等)已拆掉------演示产品最忌 UI 假装有能力。

7. 问答:先引用、再流式、真多轮

POST /api/chat 的 SSE 顺序:

  1. references --- 过门槛的切片
  2. meta --- 置信度、searchMs、hitCount、minScore
  3. chunk* --- 模型增量文本
  4. done / error

置信度不来自模型自评,而来自召回分均值 (高/中/低标签)。多轮历史最多带约 6 轮;助手历史只保留 <conclusion>,避免把上一轮思维链再次喂回去污染上下文。

System Prompt 有一条产品级决策,和很多「没召回就拒答」的 Demo 相反:

有切片 → 优先依据切片,不编造文档事实;

无切片或明显无关 → 用模型自身知识正常回答 ,禁止「知识库没有」式甩锅;

只有用户明确在问「我上传的文档里写了什么」且确实没有材料时,才可以说库里没有。

输出强制 <thinking> / <conclusion> 标签,前端边流边拆「推理 / 结论」两栏。解析器容忍半截标签和纯文本回退。


五个重难点(比写个 Chat 框难)

难点 1:Prisma × pgvector

ORM 不认 vector。方案是 schema 标 Unsupported,业务层 raw SQL 读写。优点是依赖少、和 Postgres 同库运维;缺点是查询难抽象、维度绑死、类型安全靠约定。

云端把向量表、全文索引、融合排序都藏在 Retrieve API 后面------你调接口,它出结果。本地你必须自己写 <=> 和 score 公式。

难点 2:异步入库不是「加个 await」

after() + 内存 Set 能扛演示和单机。扛不住的是:进程重启、多实例抢同一文档、OCR 跑半小时把请求线程拖死。配套能力是进度字段、卡住判定、批量强制重试------产品补救,不是调度系统。

若要上生产,这一步几乎一定要换成队列(BullMQ / SQS / 云端异步任务)+ 可观测。

难点 3:OCR 是解析的「最后一公里」

文字层 PDF 很快;扫描件是另一条产品。本地用 PDFium + Canvas + Tesseract,还要处理:

  • CJK 语言包(多语 a+b 在 tesseract.js WASM 上不稳,默认只用主语言)
  • 页数 / 清晰度 / 耗时三角
  • 失败可重试、列表按上传时间排序(避免解析刷新把文档顶到最前)

百炼侧解析质量通常更高、也更贵;本地版换来的是可调试数据不出机器

难点 4:检索质量 = 分数门槛 + Prompt 契约 + UI 诚实

三件事绑在一起:

杠杆 本地做法
召回 纯向量 topK + minScore
生成 有据引用 / 无据通识,禁止假拒答
体验 展示引用、置信度、latency;去掉假能力开关

百炼默认是向量 + 全文混合,融合可用 WEIGHT(如 0.7/0.3)、RRF 或 Rerank 模型。本地版目前没有全文通道和 Rerank------专有名词、编号类 query 会弱一截。这是有意砍掉的复杂度,也是和云端差距最大的检索能力点之一。

难点 5:多知识库联合问答的产品细节

技术上只是 WHERE knowledgeBaseId IN (...)。产品上要处理:

  • 聊天顶栏多选,选择进 sessionStorage
  • 引用上展示来源知识库名
  • 会话仍归属入口主库(权限/列表语义简单)
  • 客户端路由 ?kb= 必须用 useSearchParams,不能首屏读一次 window.location

云端 RAG 4.0 叙事里还有 Agentic Search(多轮搜)、NL2SQL、MCP/CLI 发布等;本地版停在「多库一次向量召回 + grounded 生成」。对标的是控制台主路径,不是 Agentic 全家桶。


和阿里云 Knowledge Studio 怎么比

先对齐「比的是谁」:百炼 Knowledge Studio 是 SaaS 化知识库 / RAG 控制台(管理、检索、问答、对外 API/MCP 等);底层知识存储常见组合是 OSS + 解析流水线 + Tablestore 向量/全文索引 。PAI LangStudio 是另一条线(Agent 工作流编排),别混成一个产品。

🎭 云端买的是运维、混合检索与规模;本地买的是白盒、可控成本与工程判断力。

对照表

维度 百炼 Knowledge Studio 本地开源版
定位 企业托管、开箱即用 学习 / 本机 / 内网可改
部署 SaaS,难私有化离线 Docker / 本机;MIT
鉴权与多租户 平台账号、业务空间;存储侧还有 Subspace 等 默认无鉴权
文件与解析 OSS + 托管解析 本地盘 + 自研解析/OCR
向量与检索 混合检索 + 多种融合/Rerank pgvector 单路 + minScore
模型 云端 Embedding / LLM,按量 Ollama 本地,可换兼容 API
规模 文档量级可到很大(平台 SLA) 单机;入库非持久队列
可观测 控制台与云监控 检索 meta + health;链路自建
对外集成 API / MCP / CLI / 应用发布 同源 REST + SSE;分享只读页
你买到的 运维、解析质量、混合检索、合规与规模 白盒、可控成本、可二次开发

什么时候用云,什么时候用本地

  • 要上业务、要混合检索、要 IAM/审计、要少运维 → 直接百炼 Knowledge Studio(或同类托管)。
  • 要讲清楚 RAG、要内网数据、要改切片/门槛/Prompt、要前端同学能贡献代码 → 本地版更合适。
  • 最佳学习路径:先用云产品建立「正确产品形态」的直觉,再用本地版把同一形态拆成可改代码------两边对照,进步最快。

一句话:

云端 Knowledge Studio 把难处抽象成按钮;本地重建同一闭环,是为了把难处变成你自己的工程判断力


工程上还有几处「故意诚实」的设计

  1. 静态预览与全栈双模式 :GitHub Pages 导出时把 api/ 挪开再 output: "export",线上只读壳;真上传/检索必须本地或 Docker。
  2. 健康检查/api/health 报 DB、vector 扩展、LLM 是否可用;DB 挂了服务层尽量返回空而不是整站白屏。
  3. 切片可关检索enabled=false 清 embedding,内容还在------运营向能力,不只是 Demo。
  4. 会话分支 JSON 落库:分叉、分享链接、侧栏会话,接近「能演示的产品」而不是一次性 Chat。

快速上手(本地)

bash 复制代码
pnpm i
cp .env.example .env
docker compose up -d db
pnpm db:setup

ollama pull qwen3
ollama pull nomic-embed-text

pnpm dev
# http://localhost:3000/knowledge

关键环境变量:DATABASE_URLOLLAMA_*RAG_MIN_SCOREPDF_OCR_*LLM_DISABLED(CI/演示可关真模型)。


小结

本地 Knowledge Studio 证明一件事:对标云产品,不必复刻全部企业能力,但要把主路径做「真」。

真异步入库、真多格式与 OCR 回退、真向量分数与门槛、真多库联合、真引用与置信度、真去掉假开关------这些比换一个更炫的聊天皮肤更有教学和生产迁移价值。

若你接下来要演进,优先级我会这样排:

  1. 全文检索(或至少 BM25)+ 简单融合,补专有名词短板
  2. after() 换成持久化任务队列
  3. 鉴权与按知识库的 ACL
  4. 离线评测集守住召回与拒答策略(改 Prompt 前先回归)

云端已经帮你验证了产品形态;本地版帮你验证的是:你是否真的理解这条形态背后的工程代价。

仓库:github.com/jiaxiantao/...


相关推荐
晨米酱1 小时前
Matt Pocock Skills v1.2:控制从主流程深入到每一步
面试·架构·agent
谢白羽2 小时前
SGLang源码剖析-2-sglang双层体系架构全景
分布式·架构·llm·vllm·sglang
weixin_431600442 小时前
做 Agent 会用到的 Node API(3):异步与流
前端·学习·ai·agent·ai编程
小七-七牛开发者3 小时前
Agent 小知识|长任务不重来:Agent 状态保存的工程设计
ai·大模型·agent·claude·token·工作流·skill·claudecode·ai coding
扯蛋4383 小时前
langchain1.x 时代的记忆系统 (二)
javascript·llm·agent
leeyi3 小时前
Router / Parent 源码:多个知识库怎么查,切太碎怎么补上下文(第75篇-E61)
aigc·agent·ai编程
Loveyourself3 小时前
🔥 claude code auto compact源码解析
面试·agent
王中阳Go3 小时前
用TRAE Work批量优化学员简历,原来2天的活现在2小时就干完了
后端·面试·agent
安逸sgr3 小时前
Zero-shot、Few-shot 和 One-shot Prompt 有什么区别?
人工智能·ai·大模型·agent·智能体