# 知识库与嵌入调试接口 **本文引用的文件** - [KnowledgeBaseController.java](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java) - [EmbeddingDebugController.java](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/controller/EmbeddingDebugController.java) - [KnowledgeBaseService.java](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeBaseService.java) - [KnowledgeDocService.java](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java) - [SaveKnowledgeBaseDTO.java](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/dto/SaveKnowledgeBaseDTO.java) - [KnowledgeBaseVO.java](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/vo/KnowledgeBaseVO.java) - [KnowledgeDocVO.java](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/vo/KnowledgeDocVO.java) - [KnowledgeBase.java](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/entity/KnowledgeBase.java) - [KnowledgeDoc.java](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/entity/KnowledgeDoc.java) - [EmbeddingDebugDTO.java](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/dto/EmbeddingDebugDTO.java) - [EmbeddingDebugVO.java](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/vo/EmbeddingDebugVO.java) - [knowledgeApi.ts](file://ai-electron/frontend/src/ai/api/knowledgeApi.ts) ## 目录 1. [简介](#简介) 2. [项目结构与定位](#项目结构与定位) 3. [核心组件总览](#核心组件总览) 4. [架构概览](#架构概览) 5. [知识库接口规范](#知识库接口规范) 6. [嵌入调试接口规范](#嵌入调试接口规范) 7. [知识库与 Agent RAG 向量检索的关系](#知识库与-agent-rag-向量检索的关系) 8. [使用示例](#使用示例) 9. [常见问题排查](#常见问题排查) 10. [权限与隔离模型](#权限与隔离模型) 11. [结论](#结论) ## 简介 本文档面向调用方和运维人员,系统化说明知识库管理接口与嵌入调试接口的行为、参数、响应、错误语义和排查方法。重点覆盖: - 知识库的创建、查询、更新、删除。 - 知识库文档上传、下载、重试向量化、删除。 - 嵌入调试接口对本地 ONNX 模型的批量文本嵌入与相似度计算。 - 知识库与 Agent RAG 中向量检索的协作关系。 - 文档解析失败、向量入库失败、相似度检索为空等典型问题的排查路径。 ## 项目结构与定位 知识库接口位于后端 `ai-server` 模块的 `com.zsjz.ai.module.knowledge.controller` 包;嵌入调试接口位于 `com.zsjz.ai.module.embedding.controller` 包。前端 Electron 应用通过 `ai-electron/frontend/src/ai/api/knowledgeApi.ts` 封装知识库 API,包括登录态传递、文件下载处理等细节。 ```mermaid graph TB Client["调用方或前端"] --> Gateway["Sa-Token 鉴权
x-token 头"] Gateway --> KB_Ctrl["KnowledgeBaseController"] Gateway --> Emb_Ctrl["EmbeddingDebugController"] KB_Ctrl --> KB_Service["KnowledgeBaseService"] KB_Ctrl --> Doc_Service["KnowledgeDocService"] Doc_Service --> Parser["文档解析器"] Doc_Service --> Indexer["知识索引器"] Doc_Service --> Storage["本地文件存储"] Emb_Ctrl --> Emb_Service["EmbeddingService"] Emb_Service --> Model["本地 ONNX 模型"] ``` **图示来源** - [KnowledgeBaseController.java:1-122](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L1-L122) - [EmbeddingDebugController.java:1-62](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/controller/EmbeddingDebugController.java#L1-L62) - [KnowledgeBaseService.java:1-200](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeBaseService.java#L1-L200) - [KnowledgeDocService.java:1-200](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L1-L200) - [knowledgeApi.ts:1-97](file://ai-electron/frontend/src/ai/api/knowledgeApi.ts#L1-L97) **章节来源** - [KnowledgeBaseController.java:1-122](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L1-L122) - [EmbeddingDebugController.java:1-62](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/controller/EmbeddingDebugController.java#L1-L62) - [knowledgeApi.ts:1-97](file://ai-electron/frontend/src/ai/api/knowledgeApi.ts#L1-L97) ## 核心组件总览 | 组件 | 职责 | 关键行为 | |---|---|---| | KnowledgeBaseController | 暴露知识库 REST 接口 | 列表、新建、编辑、删除知识库;文档列表、上传、删除、重试、下载 | | KnowledgeBaseService | 知识库生命周期与归属校验 | 内置库只读;自建库可编辑删除;级联清理文档、向量、方案绑定 | | KnowledgeDocService | 文档上传、解析、审计下载、删除、重试索引 | Tika 提取全文;异步向量化;PENDING/INDEXING/READY/FAILED 状态机 | | EmbeddingDebugController | 嵌入调试入口 | 批量文本生成向量,返回维度、耗时、向量数组、两两余弦相似度矩阵 | | knowledgeApi.ts | 前端知识库 API 封装 | 携带 x-token 下载文件、multipart 上传、统一错误提示 | **章节来源** - [KnowledgeBaseController.java:1-122](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L1-L122) - [KnowledgeBaseService.java:1-200](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeBaseService.java#L1-L200) - [KnowledgeDocService.java:1-200](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L1-L200) - [EmbeddingDebugController.java:1-62](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/controller/EmbeddingDebugController.java#L1-L62) - [knowledgeApi.ts:1-97](file://ai-electron/frontend/src/ai/api/knowledgeApi.ts#L1-L97) ## 架构概览 知识库流程分为两层: 1. **元数据层**:知识库表记录名称、描述、是否内置、创建者;文档表记录文件名、路径、字符数、块数、索引状态、失败原因。 2. **向量层**:文档解析后由索引器切分并写入向量数据库;RAG 检索消费 READY 文档对应的向量。 ```mermaid flowchart TD Upload["上传文档"] --> Validate["校验类型、大小、数量上限"] Validate --> SaveFile["保存原件到本地存储"] SaveFile --> Extract["Tika 提取全文到 sidecar"] Extract --> Register["登记文档行"] Register --> Status{"提取成功?"} Status -->|是| Pending["索引状态设为 PENDING"] Status -->|否| Failed["索引状态设为 FAILED"] Pending --> Publish["发布索引事件"] Publish --> Vectorize["异步切分并向量化入库"] Vectorize --> Ready["索引状态变为 READY"] Failed --> Retry["重试索引后可重新抽取并入库"] ``` **图示来源** - [KnowledgeDocService.java:1-200](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L1-L200) - [KnowledgeDoc.java:1-81](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/entity/KnowledgeDoc.java#L1-L81) ## 知识库接口规范 ### 公共约定 - 基础路径:`/knowledge-bases` - 登录要求:所有接口依赖 Sa-Token 登录态,从请求头 `x-token` 获取当前用户 ID。 - 返回值包装:除下载接口外,其他接口均返回统一结果对象,包含业务数据和状态信息。 - ID 传递:前端使用字符串 ID,后端按 Long 处理;跨语言调用时注意数字精度。 ### 1. 列出知识库 - HTTP 方法:`GET` - URL:`/knowledge-bases` - 请求参数:无 - 权限要求:已登录 - 行为: - 返回内置知识库与当前用户自建知识库。 - 内置库全局可见;自建库仅创建者可见。 - 返回列表项包含知识库标识、名称、描述、是否内置、是否属于当前用户、我的文档数、待索引文档数。 **章节来源** - [KnowledgeBaseController.java:34-43](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L34-L43) - [KnowledgeBaseService.java:53-74](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeBaseService.java#L53-L74) - [KnowledgeBaseVO.java:1-31](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/vo/KnowledgeBaseVO.java#L1-L31) ### 2. 新建知识库 - HTTP 方法:`POST` - URL:`/knowledge-bases` - 请求体: - `name`:必填,长度不超过 100。 - `description`:可选,长度不超过 500。 - 权限要求:已登录 - 行为: - 新建的是非内置知识库,归属当前用户。 - 返回新建知识库 VO。 **章节来源** - [KnowledgeBaseController.java:45-49](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L45-L49) - [SaveKnowledgeBaseDTO.java:1-22](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/dto/SaveKnowledgeBaseDTO.java#L1-L22) - [KnowledgeBaseService.java:108-116](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeBaseService.java#L108-L116) ### 3. 更新知识库 - HTTP 方法:`PUT` - URL:`/knowledge-bases/{id}` - 路径参数: - `id`:知识库主键。 - 请求体:同新建知识库 DTO。 - 权限要求: - 必须是当前用户自建的库。 - 内置知识库拒绝更新。 - 行为: - 更新名称与描述。 - 返回最新知识库 VO。 **章节来源** - [KnowledgeBaseController.java:51-55](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L51-L55) - [KnowledgeBaseService.java:118-126](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeBaseService.java#L118-L126) ### 4. 删除知识库 - HTTP 方法:`DELETE` - URL:`/knowledge-bases/{id}` - 路径参数: - `id`:知识库主键。 - 权限要求: - 必须是当前用户自建的库。 - 内置知识库拒绝删除。 - 行为: - 删除该知识库下全部文档原件与 sidecar。 - 删除向量数据。 - 删除下载记录与文档行。 - 解绑所有引用该知识库的研判方案。 **章节来源** - [KnowledgeBaseController.java:57-63](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L57-L63) - [KnowledgeBaseService.java:128-152](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeBaseService.java#L128-L152) ### 5. 列出“我的上传文档” - HTTP 方法:`GET` - URL:`/knowledge-bases/{id}/docs` - 路径参数: - `id`:知识库主键。 - 权限要求: - 必须能访问该知识库。 - 列表只返回当前用户上传的文档,不返回其他用户的文档。 - 行为: - 返回文档标识、知识库标识、文件名、MIME、大小、字符数、已向量化块数、索引状态、失败原因、下载次数、创建时间。 **章节来源** - [KnowledgeBaseController.java:65-69](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L65-L69) - [KnowledgeDocService.java:63-79](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L63-L79) - [KnowledgeDocVO.java:1-38](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/vo/KnowledgeDocVO.java#L1-L38) ### 6. 上传文档 - HTTP 方法:`POST` - URL:`/knowledge-bases/{id}/docs` - 路径参数: - `id`:知识库主键。 - 请求体:`multipart/form-data`,字段名 `file` - 权限要求: - 自建库:库主人可上传。 - 内置库:仅平台管理员(固定用户 ID 为 1)可维护上传。 - 行为: - 校验文件是否为空、类型、大小、用户在当前库下的文档数量上限。 - 保存原件到本地存储。 - 尝试提取全文到 sidecar;提取失败不阻断登记,文档状态设为失败。 - 提取成功后登记为 PENDING,并异步触发向量化。 - 返回文档 VO,前端应轮询 `indexStatus`。 **章节来源** - [KnowledgeBaseController.java:71-75](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L71-L75) - [KnowledgeDocService.java:81-157](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L81-L157) - [KnowledgeBaseService.java:160-166](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeBaseService.java#L160-L166) ### 7. 删除文档 - HTTP 方法:`DELETE` - URL:`/knowledge-bases/{id}/docs/{docId}` - 路径参数: - `id`:知识库主键。 - `docId`:文档主键。 - 权限要求:只能删除自己上传的文档。 - 行为: - 删除原件与 sidecar。 - 删除对应向量。 - 删除下载记录。 - 删除文档行。 **章节来源** - [KnowledgeBaseController.java:77-81](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L77-L81) - [KnowledgeDocService.java:171-186](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L171-L186) ### 8. 重试文档索引 - HTTP 方法:`POST` - URL:`/knowledge-bases/{id}/docs/{docId}/reindex` - 路径参数: - `id`:知识库主键。 - `docId`:文档主键。 - 权限要求:只能重试自己上传的文档。 - 行为: - 将文档状态重置为 PENDING,清空失败原因。 - 重新发布索引事件,由索引器执行幂等重放。 - 适用于提取失败、sidecar 缺失、嵌入服务临时不可用等情况。 **章节来源** - [KnowledgeBaseController.java:83-87](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L83-L87) - [KnowledgeDocService.java:188-206](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L188-L206) ### 9. 下载文档 - HTTP 方法:`GET` - URL:`/knowledge-bases/{id}/docs/{docId}/download` - 路径参数: - `id`:知识库主键。 - `docId`:文档主键。 - 权限要求:只能下载自己上传的文档。 - 响应特点: - 不是普通 JSON,而是裸文件流。 - 响应头包含附件文件名。 - 前端必须通过带 `x-token` 的请求下载,否则会被视为未登录。 - 行为: - 校验文档归属。 - 从本地存储读取原件流。 - 写入下载审计记录。 - 原子增加下载次数。 **章节来源** - [KnowledgeBaseController.java:89-108](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L89-L108) - [KnowledgeDocService.java:159-169](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L159-L169) - [knowledgeApi.ts:67-97](file://ai-electron/frontend/src/ai/api/knowledgeApi.ts#L67-L97) ## 嵌入调试接口规范 ### 1. 嵌入调试 - HTTP 方法:`POST` - URL:`/embedding/debug` - 请求体: - `texts`:字符串数组,必填,最多 16 条。 - 权限要求:依赖登录态;主要用于人工验证本地嵌入模型。 - 行为: - 调用本地嵌入服务批量生成向量。 - 记录本次嵌入耗时。 - 计算每两条文本之间的余弦相似度,保留四位小数。 - 返回向量维度、耗时、向量数组、相似度矩阵。 ```mermaid sequenceDiagram participant Caller as "调用方" participant Ctrl as "EmbeddingDebugController" participant Service as "EmbeddingService" Caller->>Ctrl: POST /embedding/debug Ctrl->>Service: 批量嵌入 texts Service-->>Ctrl: 向量数组 Ctrl->>Ctrl: 计算两两余弦相似度 Ctrl-->>Caller: 维度、耗时、向量、相似度矩阵 ``` **图示来源** - [EmbeddingDebugController.java:19-62](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/controller/EmbeddingDebugController.java#L19-L62) **章节来源** - [EmbeddingDebugController.java:1-62](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/controller/EmbeddingDebugController.java#L1-L62) - [EmbeddingDebugDTO.java:1-19](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/dto/EmbeddingDebugDTO.java#L1-L19) - [EmbeddingDebugVO.java:1-24](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/vo/EmbeddingDebugVO.java#L1-L24) ## 知识库与 Agent RAG 向量检索的关系 知识库不是直接参与 RAG 检索的唯一通道,而是 RAG 的上游数据来源之一。其关系如下: 1. **知识库负责文档入库**:上传文档后,系统提取全文、切分、生成向量并写入向量数据库。 2. **索引状态决定能否被检索**:只有索引状态为 READY 的文档才会产生可用向量;PENDING、INDEXING、FAILED 的文档自然无法被检索命中。 3. **RAG 检索消费向量**:Agent RAG 在执行检索时,会基于问题生成查询向量,并在向量数据库中查找相似片段。知识库中的 READY 文档是这些相似片段的重要来源。 4. **文档层隔离不影响 RAG 全量检索**:“我的上传文档”只对上传者开放,但 RAG 检索绑定知识库时会扫描该知识库下的全部文档向量,而不是只扫描上传者本人上传的部分。 ```mermaid flowchart LR KB["知识库文档"] --> Parse["文档解析"] Parse --> Chunk["文本切分"] Chunk --> Vector["向量嵌入"] Vector --> Store["向量数据库"] Query["Agent RAG 查询"] --> QVector["查询向量"] QVector --> Search["相似度检索"] Search --> Store Store --> Context["召回上下文"] Context --> LLM["大模型生成回答"] ``` **图示来源** - [KnowledgeDoc.java:1-81](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/entity/KnowledgeDoc.java#L1-L81) - [KnowledgeDocService.java:1-200](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L1-L200) **章节来源** - [KnowledgeDoc.java:1-81](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/entity/KnowledgeDoc.java#L1-L81) - [KnowledgeDocService.java:1-200](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L1-L200) ## 使用示例 以下示例以 curl 形式展示常见调用方式。实际使用时需替换 `{host}`、`{kb_id}`、`{doc_id}`、`{token}` 等占位符。 ### 列出知识库 ```bash curl -H "x-token: {token}" \ http://{host}/knowledge-bases ``` ### 新建知识库 ```bash curl -X POST -H "Content-Type: application/json" \ -H "x-token: {token}" \ -d '{"name":"测试知识库","description":"用于验证知识库接口"}' \ http://{host}/knowledge-bases ``` ### 更新知识库 ```bash curl -X PUT -H "Content-Type: application/json" \ -H "x-token: {token}" \ -d '{"name":"更新后的知识库","description":"描述已更新"}' \ http://{host}/knowledge-bases/{kb_id} ``` ### 删除知识库 ```bash curl -X DELETE -H "x-token: {token}" \ http://{host}/knowledge-bases/{kb_id} ``` ### 列出我的上传文档 ```bash curl -H "x-token: {token}" \ http://{host}/knowledge-bases/{kb_id}/docs ``` ### 上传文档 ```bash curl -X POST -H "x-token: {token}" \ -F "file=@/path/to/document.pdf" \ http://{host}/knowledge-bases/{kb_id}/docs ``` ### 删除文档 ```bash curl -X DELETE -H "x-token: {token}" \ http://{host}/knowledge-bases/{kb_id}/docs/{doc_id} ``` ### 重试文档索引 ```bash curl -X POST -H "x-token: {token}" \ http://{host}/knowledge-bases/{kb_id}/docs/{doc_id}/reindex ``` ### 下载文档 ```bash curl -H "x-token: {token}" \ -o downloaded_file.pdf \ http://{host}/knowledge-bases/{kb_id}/docs/{doc_id}/download ``` ### 嵌入调试 ```bash curl -X POST -H "Content-Type: application/json" \ -H "x-token: {token}" \ -d '{ "texts": [ "今天天气很好", "明天可能下雨", "北京今天的温度很高" ] }' \ http://{host}/embedding/debug ``` ## 常见问题排查 ### 文档解析失败 **现象** - 上传后文档状态为 `FAILED`。 - 文档列表中显示失败原因。 - RAG 检索不到该文档相关内容。 **可能原因** - 文件格式不被支持。 - 文件损坏或编码异常。 - 文件大小超过配置上限。 - Tika 解析抛出异常。 **排查步骤** 1. 检查上传响应中的文档状态,确认是否为 `FAILED`。 2. 查看文档列表中的失败原因字段。 3. 确认文件后缀是否在允许的可解析文本类型范围内。 4. 确认文件大小没有超过系统配置的最大值。 5. 使用重试接口重新触发索引;若 sidecar 缺失,索引器会重新抽取。 6. 若仍失败,检查日志中“文档提取失败”相关记录。 **章节来源** - [KnowledgeDocService.java:81-157](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L81-L157) - [KnowledgeDocService.java:188-206](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L188-L206) ### 向量入库失败 **现象** - 文档状态长期停留在 `PENDING` 或 `INDEXING`。 - 文档状态变为 `FAILED`,失败原因与嵌入服务相关。 - 知识库中有文档,但 RAG 检索结果为空。 **可能原因** - 嵌入服务暂时不可用。 - 本地 ONNX 模型初始化失败。 - 向量数据库连接异常。 - 文本切分后向量维度异常。 **排查步骤** 1. 查看文档 `indexStatus` 与 `failReason`。 2. 调用嵌入调试接口,验证本地模型是否能正常输出向量。 3. 检查返回结果的 `dimension` 是否符合预期。 4. 检查返回的向量数组是否为空。 5. 检查向量相似度矩阵是否合理。 6. 如果嵌入服务只是临时故障,使用重试接口重新触发索引。 7. 如果向量维度异常,优先检查嵌入模型配置和输入文本。 **章节来源** - [KnowledgeDocService.java:188-206](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L188-L206) - [EmbeddingDebugController.java:19-62](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/controller/EmbeddingDebugController.java#L19-L62) - [EmbeddingDebugVO.java:1-24](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/vo/EmbeddingDebugVO.java#L1-L24) ### 相似度检索为空 **现象** - 知识库有文档且状态为 `READY`。 - 调用 Agent RAG 检索后,没有找到相关知识片段。 **可能原因** - 文档虽为 `READY`,但向量质量差,语义表达弱。 - 查询语句与文档内容差异过大。 - 向量检索阈值过高。 - 文档被切分成过细或过粗的片段。 - 使用了错误的知识库。 **排查步骤** 1. 确认文档索引状态是 `READY`。 2. 使用嵌入调试接口输入相同或相近文本,观察相似度矩阵。 3. 如果相似度矩阵对角线接近 1、其他位置接近 0,说明向量区分度正常。 4. 如果多条不同文本之间相似度也很高,说明嵌入质量可能存在问题。 5. 调整查询语句,使其更接近文档语义。 6. 检查知识库是否正确绑定到 Agent 或相关检索流程。 7. 检查向量检索配置中的相似度阈值。 **章节来源** - [KnowledgeDoc.java:1-81](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/entity/KnowledgeDoc.java#L1-L81) - [EmbeddingDebugController.java:19-62](file://ai-server/src/main/java/com/zsjz/ai/module/embedding/controller/EmbeddingDebugController.java#L19-L62) ### 下载失败或未登录 **现象** - 浏览器地址栏直接访问下载链接返回未登录。 - 前端下载报错,提示未登录或 token 失效。 **可能原因** - 下载请求缺少 `x-token`。 - 使用了 `` 直链而非带鉴权的 fetch。 - token 过期或被清除。 **排查步骤** 1. 确保下载请求携带 `x-token`。 2. 不要使用普通超链接直接跳转。 3. 前端应使用带 token 的 fetch 或封装好的下载函数。 4. 如果后端返回 JSON 而不是文件流,说明鉴权失败,需要刷新 token。 **章节来源** - [KnowledgeBaseController.java:89-108](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/controller/KnowledgeBaseController.java#L89-L108) - [knowledgeApi.ts:67-97](file://ai-electron/frontend/src/ai/api/knowledgeApi.ts#L67-L97) ### 无权操作知识库或文档 **现象** - 更新或删除知识库返回权限错误。 - 删除或下载文档提示只能操作自己上传的文档。 **可能原因** - 知识库是内置库,不允许编辑或删除。 - 自建知识库不属于当前用户。 - 文档不是当前用户上传的。 - 内置知识库仅管理员可上传。 **排查步骤** 1. 确认知识库是否内置。 2. 确认当前用户是否为知识库创建者。 3. 确认当前用户是否为平台管理员。 4. 确认文档的 `userId` 是否与当前登录用户一致。 **章节来源** - [KnowledgeBaseService.java:154-174](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeBaseService.java#L154-L174) - [KnowledgeDocService.java:208-218](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L208-L218) ## 权限与隔离模型 系统采用双层隔离: | 层级 | 控制点 | 规则 | |---|---|---| | 知识库层 | `KnowledgeBaseService.requireVisible`、`requireOwned` | 内置库全局可见;自建库仅创建者可见;内置库不可编辑删除 | | 文档层 | `KnowledgeDocService.requireOwnedDoc` | 文档列表、下载、删除、重试仅上传者本人可操作 | | 上传权限 | `KnowledgeBaseService.requireUploadable` | 自建库=库主人;内置库=平台管理员 | | 向量检索 | RAG 侧消费知识库向量 | 不按上传者过滤,按绑定知识库的全量向量检索 | ```mermaid classDiagram class KnowledgeBase { +Long id +Long userId +Integer isBuiltin +String name +String description +boolean isBuiltin() } class KnowledgeDoc { +Long id +Long kbId +Long userId +String fileName +String filePath +String sidecarPath +String indexStatus +String failReason +Integer chunkCount +Integer downloadCount } class KnowledgeBaseService { +list(userId) +create(userId, dto) +update(userId, id, dto) +delete(userId, id) +requireVisible(userId, kbId) +requireUploadable(userId, kb) } class KnowledgeDocService { +listMine(userId, kbId) +upload(userId, kbId, file) +download(userId, docId) +delete(userId, docId) +reindex(userId, docId) -requireOwnedDoc(userId, docId) } KnowledgeBaseService --> KnowledgeBase : "读写" KnowledgeDocService --> KnowledgeDoc : "读写" KnowledgeDocService --> KnowledgeBaseService : "校验知识库" ``` **图示来源** - [KnowledgeBase.java:1-57](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/entity/KnowledgeBase.java#L1-L57) - [KnowledgeDoc.java:1-81](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/entity/KnowledgeDoc.java#L1-L81) - [KnowledgeBaseService.java:1-200](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeBaseService.java#L1-L200) - [KnowledgeDocService.java:1-200](file://ai-server/src/main/java/com/zsjz/ai/module/knowledge/service/KnowledgeDocService.java#L1-L200) ## 结论 知识库接口提供完整的文档生命周期管理能力,并通过内置库与自建库、知识库层与文档层的权限模型,兼顾共享性与隐私性。嵌入调试接口则专注于本地 ONNX 模型的质量验证,帮助快速定位向量维度、归一化、语义区分度等问题。在实际使用中,应重点关注文档索引状态、失败原因、嵌入调试结果和 RAG 检索阈值,形成从上传、向量化到检索的完整排查闭环。