【AI应用】海兰知识库 RAG 智能问答系统 — 详细设计(二)

发布时间:2026/7/13 15:39:45
【AI应用】海兰知识库 RAG 智能问答系统 — 详细设计(二) 4. 核心模块详解4.1 RAG 核心引擎rag.tsrag.ts是系统的“大脑”它将文档索引、语义检索和对话生成三个环节串成一条完整的流水线。4.1.1 文档索引流程如何让机器“读懂”文档当管理员上传一份文档后系统会异步执行以下步骤将原始文件转化为可检索的向量PDFDOCXTXT/MD/CSV用户上传文档创建 Document 记录status PENDING异步解析 parseDocument文件类型pdf-parse 提取文本mammoth 提取纯文本Buffer.toString 读取更新 Document.content文本分块 splitTextchunkSize500 tokens批量 Embedding embedBatchBATCH_SIZE10存储向量到 DocumentSegment.embedding更新 DocumentstatusCOMPLETED, segmentCount完成关键设计决策异步处理上传接口立即返回索引过程在后台进行避免阻塞用户操作。批量 Embedding每 10 个切片调用一次模型 API减少请求次数。容错降级若批量调用某条失败自动降级为逐条重试确保其他切片不受影响。清理任意步骤失败时删除该文档已创建的分段并将 Document 标记为FAILED。如下图所示4.1.2 检索流程如何从知识库中找到相关内容当用户提出一个问题时系统需要从成千上万个文本片段中快速找出最相关的几个。计算细节余弦相似度公式cos(θ) (A·B) / (||A|| * ||B||)值越接近 1 表示越相关。当前为全表扫描 内存计算适合万级分段规模详见第 9 章性能设计。4.1.3 对话流程如何生成有据可依的回答这是用户最常使用的功能——提问并获得带引用的回答数据库大模型检索模块ragChatStreamUser数据库大模型检索模块ragChatStreamUseralt[绑定了知识库][未绑定知识库]loop[流式生成]发送消息 会话ID加载最近20条历史消息执行 retrieve(query)返回相关片段 (sources)构建增强 System Prompt注入参考资料使用普通 System PromptchatCompletionStream(messages)逐字增量 deltaSSE 事件: dataSSE 事件: sources (引用列表)SSE 事件: done保存 Assistant 消息含 sources, latencyMs亮点流式输出用户能实时看到 AI 逐字生成体验流畅。引用溯源回答中会附带sources事件展示哪些文档片段被引用增强可信度。上下文窗口控制仅加载最近 10 轮对话20 条消息避免 Token 溢出。4.2 向量存储与相似度检索vector-store.ts由于 SQLite 不具备原生向量索引能力系统采用了一种轻量级混合方案将向量序列化为 JSON 字符串存储在DocumentSegment.embedding字段检索时在内存中实时计算相似度。存储格式embedding [0.12, -0.05, 0.98, ...] // 维度由模型决定如 256、768、1536检索过滤策略层层筛选保证质量知识库隔离只检索指定知识库下的分段。非空过滤跳过embedding为空的记录。启用态检查分段和所属文档均需处于enabled true。相似度阈值剔除分数低于similarityThreshold的结果。Top-K 截断按相似度降序取前 K 个默认 5。4.3 LLM 客户端封装llm.tsllm.ts是对不同 LLM 提供商的统一抽象屏蔽了各家 API 的差异提供一致的聊天和 Embedding 接口。支持的提供商矩阵Provider聊天流式Embedding特点ZAI内置✅✅本地哈希无需 API Key开箱即用DeepSeek✅✅国产高性能OpenAI 兼容OpenAI✅✅官方 API生态完善Ollama✅❌本地私有化部署数据不出域CUSTOM✅✅任意 OpenAI 兼容端点内置 ZAI Embedding 的原理由于z-ai-web-dev-sdk未直接提供 Embedding 接口我们实现了一套基于词袋 哈希的本地向量化方法分词CJK 字符逐字切分英文按单词切分并提取 bigram双词组合增强语义。哈希映射使用 FNV-1a 哈希将 token 映射到 256 维索引。TF 加权每个维度的值为log(1 词频)高频词权重更高。L2 归一化确保向量模长为 1便于余弦相似度计算。⚠️注意本地 Embedding 本质上是关键词重叠相似度并非真正的语义相似度。生产环境建议配置 DeepSeek / OpenAI 等外部模型以获得更精准的检索效果。错误处理与超时HTTP 错误映射将 401、404、429 等状态码转换为友好提示。超时保护withTimeout包装器防止请求挂死。流式容错解析到畸形 chunk 时跳过不中断整个生成流。4.4 文档解析document-parser.ts系统支持多种格式的文档解析统一输出为纯文本格式解析库额外处理PDFpdf-parse提取全文记录页数Word (.docx)mammoth转换为纯文本保留段落结构TXT / CSVBuffer.toString直接读取Markdown正则清洗去除标题标记、粗体/斜体、代码块、链接语法保留纯文本Markdown 清洗示例# 标题→标题**粗体**→粗体[链接](url)→链接连续空行合并为单个换行。4.5 文本分块text-splitter.ts将长文档切分为适合 Embedding 的短片段每个约 500 Token是 RAG 系统的基础环节。Token 估算算法中英文统一tokens ≈ ceil( CJK字符数 / 1.5 其他字符数 / 4 )CJK中日韩字符信息密度高按 1.5 字符 ≈ 1 Token。英文按 4 字符 ≈ 1 Token。分块策略句子级 动态合并切分句子按句号、问号、感叹号、换行符拆分。动态合并按顺序累积句子直到 Token 数超过chunkSize500形成一块。超长句子硬切单句若超过 1.5 倍 chunkSize按字符强制切分。尾部合并不足minChunkLengthToEmbed5 Token的尾块合并到前一块。上限保护单文档最多生成 10000 个分段防止恶意文件导致资源耗尽。4.6 认证与授权auth.ts认证机制有状态签名 Token系统采用类似 JWT 的有状态签名 Token兼具无状态部署的便利和一定的安全性Token base64url(payload) . HMAC-SHA256(secret, base64url(payload)) payload { uid: userId, exp: Date.now() 7d }存储HTTP Only Cookie名称为hylan_session防止 XSS 窃取。有效期7 天自动续期。优点无需服务端维护 Session 表支持开发模式热重启不丢登录。局限服务端无法主动吊销需客户端清除 Cookie 或引入黑名单。密码安全当前使用SHA-256哈希存储建议生产环境升级为bcrypt或argon2并加盐以抵抗暴力破解。权限控制矩阵角色可访问功能ADMIN用户管理、模型配置、知识库 CRUD、文档上传/删除、角色管理、API Key 管理、系统配置USER查看知识库列表、对话聊天、管理自己的会话历史接口级权限通过requireUser()/requireAdmin()中间件函数控制。资源级权限普通用户只能查询自己的会话和消息。默认数据种子首次启动自动创建类型名称凭证角色管理员adminhylan.comadmin123ADMIN普通用户userhylan.comuser123USER模型名称Provider类型默认对话GLM-4.6 (Built-in)ZAICHAT默认 EmbeddingEmbedding-3 (Built-in Local)ZAIEMBEDDING角色名称说明默认助手默认助手通用 AI 助手未绑定知识库5. API 层设计5.1 RESTful API 概览系统提供完整的 RESTful 接口覆盖前端所有操作需求方法端点权限功能GET/api/auth/me已登录获取当前用户信息POST/api/auth/login公开邮箱密码登录POST/api/auth/logout已登录登出GET/api/knowledge已登录知识库列表POST/api/knowledgeADMIN创建知识库GET/api/documents已登录文档列表支持筛选POST/api/documentsADMIN上传文档异步索引DELETE/api/documents/[id]ADMIN删除文档POST/api/documents/[id]/reindexADMIN重新索引GET/api/documents/[id]/segments已登录查看文档分段GET/api/modelsADMIN模型列表POST/api/modelsADMIN添加模型GET/api/roles已登录角色列表POST/api/rolesADMIN创建角色GET/api/conversations已登录会话列表POST/api/conversations已登录创建会话POST/api/chat已登录SSE 流式对话核心接口GET/api/recall-testADMIN检索测试调试用GET/api/usersADMIN用户列表GET/api/openapi-keysADMINAPI Key 列表POST/api/openapi-keysADMIN生成 API Key5.2 OpenAI 兼容 API为方便与 LobeChat、ChatGPT-Next-Web、Dify 等第三方工具集成系统提供标准的 OpenAI Chat Completions 接口。认证Authorization: Bearer sk-hylan-xxxxxx端点POST /api/v1/chat/completions请求体标准字段 扩展{model:deepseek-chat,messages:[{role:user,content:公司年假政策是什么}],temperature:0.7,max_tokens:2048,stream:true,// ----- 海兰扩展字段 -----knowledge_base_id:xxx,// 指定知识库role_id:xxx,// 指定角色top_k:5,threshold:0.7}响应流式 SSEdata: {id:chatcmpl-xxx,object:chat.completion.chunk,choices:[{delta:{content:根据}}]} data: {id:chatcmpl-xxx,object:chat.completion.chunk,choices:[{delta:{content:公司规定}}]} ... data: [DONE]非流式则返回标准chat.completionJSON 对象。6. 前端架构设计6.1 单页应用SPA模式系统虽然基于 Next.js 全栈框架但前端采用SPA 模式运行避免页面刷新带来的闪烁提升交互流畅度。唯一的页面入口是src/app/page.tsx通过view状态切换不同组件。所有视图组件位于src/components/views/各司其职。6.2 视图组件清单视图组件权限功能仪表盘DashboardView已登录统计卡片、最近会话、文档状态分布对话ChatView已登录流式对话、引用溯源、历史记录知识库KnowledgeView已登录知识库 CRUD、绑定 Embedding 模型文档管理DocumentsView已登录上传文档、查看状态、重新索引分段查看SegmentsView已登录查看分段内容和向量召回测试RecallTestViewADMIN输入查询测试检索效果模型配置ModelsViewADMIN添加/编辑/删除 LLM 模型角色管理RolesViewADMIN创建角色、绑定知识库API Key 管理OpenApiViewADMIN生成/吊销 API Key会话历史ConversationsView已登录全部历史会话列表用户管理UsersViewADMIN用户 CRUD登录LoginView公开邮箱密码登录6.3 状态管理策略全局状态Zustand存储用户认证信息、当前视图、上下文 ID并支持持久化到 localStorage国际化设置。服务端状态TanStack Query缓存各视图的列表数据支持自动刷新、乐观更新。本地状态React useState用于表单输入、弹窗开关、加载态等短暂 UI 状态。6.4 UI 组件体系基于shadcn/ui构建组件覆盖布局类Sheet、Sidebar、Resizable Panels、Scroll Area数据录入Input、Textarea、Select、Checkbox、Slider、Switch反馈类Toast、Alert Dialog、Progress、Skeleton导航类Tabs、Breadcrumb、CommandCMDK数据展示Table、Accordion、ChartRecharts6.5 国际化i18n自研轻量级 i18n 方案通过 Zustand persist 实现语言切换持久化语言包位于src/messages/zh.json和src/messages/en.json用户可在头像下拉菜单中一键切换默认语言为中文7. 部署架构7.1 独立部署模式StandaloneNext.js 的output: standalone选项生成自包含的运行时无需安装node_modules即可运行.next/standalone/ ├── server.js # 入口文件 ├── .next/static/ # 静态资源 └── public/ # 公共文件生产启动命令bun .next/standalone/server.js7.2 Caddy 反向代理项目附带Caddyfile提供默认反向代理到localhost:3000支持通过XTransformPort查询参数动态转发端口适用于多实例场景自动转发真实客户端 IPX-Forwarded-For,X-Real-IP结合 Caddy 的自动 HTTPS一键获得生产级 TLS 加密8. 安全设计安全维度措施文件上传限制最大 50MB扩展名白名单pdf/docx/txt/md/csv/tsvSQL 注入全部查询通过 Prisma 参数化杜绝字符串拼接XSS 防护React 默认转义富文本通过 MDX Editor 受控渲染Cookie 安全签名使用 HMAC-SHA256防止篡改权限最小化普通用户无法访问管理接口返回 403API Key 隔离每个 Key 可独立绑定默认角色和知识库支持过期时间密码哈希SHA-256建议生产升级为 bcrypt salt数据备份SQLite 单文件可通过文件复制实现全量备份