# 知识库与嵌入调试接口
**本文引用的文件**
- [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 检索阈值,形成从上传、向量化到检索的完整排查闭环。