# 05 AI 对话与知识库问答 — 跨项目完整能力分析 > 项目角色分类:主链路(iOS、主 API、DeepSeek 模型服务)、上游支撑(Python RAG Worker,仅为知识库内容供给,不参与对话上下文加载)、运维可观测(Admin)。 > Qdrant 不参与对话上下文加载——所有 5 种 Scope 的上下文均来自 PostgreSQL KnowledgeItem 表。 > Heavy Runtime 不直接参与基础 AI 对话——它负责异步 AI 分析任务(学习状态分析、测验生成等),对话链路走 AiGateway 直达模型。 > Rust Document Runtime 不参与 AI 对话链路。 --- ## 1. 能力目标 用户可以通过自然语言与 AI 进行学习相关的对话。对话可以限定在特定知识库、资料或知识点的范围内,AI 基于范围内知识内容回答问题,并提供来源引用。支持流式回复、思考过程展示和多会话管理。 --- ## 2. C 端入口 | 入口页面 | 对话范围 | 触发方式 | |---------|---------|---------| | AI 反馈页 | 全局 | "深入提问"按钮 | | 知识库详情页 | 知识库 | 底部 AI 对话按钮 | | 资料阅读页 | 资料 | 工具栏 AI 按钮 | | 知识点详情页 | 知识点 | 工具栏菜单(如有) | | AI 反馈页 → AIChatPage | 全局 | "深入提问" → AIChatPage | | (废弃)AI 首页 | 全局 | 底部输入栏(页面无入口) | --- ## 3. 对话范围 ### 3.1 全局对话(scopeType: global) - **上下文来源:** 无知识库上下文。AI 仅基于通用知识回答。 - **RAG 查询范围:** 不进行任何检索。 - **会话识别:** 创建 session 时 scopeType=global 且 scopeId 为空。 - **切换处理:** 用户从范围对话点击"新建对话"可创建全局对话。 ### 3.2 知识库范围(scopeType: knowledge_base) - **上下文来源:** 从 KnowledgeItem 表查询该知识库下的知识点(最多 30 条,每条截取前 500 字符,总计最多 4000 字符)。 - **RAG 查询范围:** 上下文直接从 PostgreSQL 的 KnowledgeItem 表加载。所有 5 种 Scope 均不调用 Qdrant——`loadContextByScope` 在代码中完全不涉及向量搜索。 - **会话识别:** 创建 session 时 scopeType=knowledge_base,scopeId=。相同知识库范围的会话通过 "open-or-create" 模式复用(同一用户同一知识库只有一个活跃对话会话)。 - **切换处理:** 用户切换到另一个知识库的对话时,创建新会话或恢复已有会话。 ### 3.3 资料范围(scopeType: material) - **上下文来源:** 按 sourceRef 匹配该资料关联的知识点。与知识库范围相同,上下文直接从 PostgreSQL 的 KnowledgeItem 表加载。Qdrant 不参与对话上下文加载。 - **会话识别:** session 的 scopeType=material,scopeId=。 - **切换处理:** 用户离开资料阅读页后,对话会话保留。下次进入同一资料时恢复。 ### 3.4 知识点范围(scopeType: knowledge_item) - **上下文来源:** 单个知识点的完整内容。 - **RAG 查询范围:** 单个知识点本身,无需检索。 - **会话识别:** session 的 scopeType=knowledge_item,scopeId=。 - **切换处理:** 每个知识点有独立会话。 ### 3.5 范围切换机制 - 用户在不同入口进入 AI 对话时,系统根据当前上下文自动确定对话范围。 - 每个范围维护独立的 ChatSession。 - 会话列表 Sheet 可按范围过滤显示。 - ScopeSnapshot 保存在每条消息中,确保历史消息知道其产生时的范围上下文。 --- ## 4. 用户主流程 ``` 用户进入对话(从知识库详情页/资料阅读页/AI 反馈页等入口) → iOS 调用 API 创建或恢复会话(open-or-create,相同范围复用会话) → 用户输入消息 → iOS 调用流式发送 API(POST /rag-chat/sessions/:id/stream) → API 校验会话所有权 → API 内容安全检查(敏感词匹配) → API 保存用户消息(含 scopeSnapshot) → API 自动生成会话标题(首次消息时,截取前 40 字符) → API 根据 scopeType 加载上下文: - global:空上下文 - knowledge_base:从 KnowledgeItem 表查询最多 30 条(每条约 500 字符) - material/folder:按相应过滤条件查询 - knowledge_item:查询单个知识点 → API 将上下文注入系统提示模板 → API 调用 AiGateway → 路由到 DeepSeek Provider → deepseek-v4-pro → DeepSeek 流式返回(content 块 + thinking 块) → API 通过 SSE 逐块转发给 iOS → iOS 实时展示 AI 回复(含思考过程可折叠动画) → 流式完成后 API 保存 AI 消息(含 token 计数) → API 保存引用(前 5 个上下文项作为 ChatCitation) → iOS 展示引用信息 → 用户可复制回复、重新生成、或发送新消息 ``` --- ## 5. 项目职责 ### iOS — 主链路参与者 - AI 对话界面(消息气泡、思考过程展示、引用展示) - 流式接收与实时渲染(SSE 解析) - 输入栏(文字输入、语音图标占位、发送按钮) - 会话列表 Sheet(搜索、切换、删除、归档、置顶) - 新建对话 - 范围标签展示(当前对话限定范围) - 复制回复、重新生成 ### 主 API — 主链路参与者 - 会话 CRUD(open-or-create、列表、更新、软删除) - 会话所有权校验 - 消息发送(同步 + 流式) - 内容安全检查(输入消息和 AI 输出) - 上下文加载(按 scopeType 从 KnowledgeItem 表查询) - 系统提示构建(上下文注入) - AiGateway 路由(模型选择、回退、重试) - SSE 流式转发 - 引用保存(ChatCitation) - Token 使用记录(ModelInvocationLog) - 自动标题生成 ### DeepSeek 模型服务 — 主链路参与者 - 接收系统提示 + 用户消息 + 上下文 - 流式生成回复(content + reasoning_content) - 模型:deepseek-v4-pro(primary tier),deepseek-v4-flash(cheap tier) - 通过 AiGateway 统一管理 API 密钥和路由 ### Python RAG Worker — 上游支撑(间接参与) - 不直接参与对话流程。负责文档导入后的处理(解析→分块→嵌入→索引),为知识库提供结构化的知识点内容。 - RAG 处理结果(KnowledgeItem、KnowledgeChunk)是对话上下文的间接来源——KnowledgeItem 表中的内容可能来自 RAG 生成的候选知识点。 - 注意:知识库范围对话的上下文来自 KnowledgeItem 表(PostgreSQL),**不依赖** Qdrant 向量搜索,也不依赖 RAG 的实时处理状态。 ### Qdrant — 不参与对话上下文加载 - 存储文档块的向量索引,用于文档导入后的语义检索(Admin RAG 调试页使用)。 - **不参与 AI 对话的上下文加载**——`loadContextByScope` 完全不调用 Qdrant,所有 5 种 Scope 的上下文均来自 PostgreSQL。 ### Admin — 运维与可观测 - 会话日志查看(Admin 聊天日志页,查看所有会话和消息) - AI 网关管理(路由规则、提供商管理、回退日志) - AI 使用统计(调用次数、延迟、失败率、成本,按提供商和模型) - AI 成本管理(费用记录、按用户统计、导出) - 模型配置(temperature、max_tokens 等参数) - 内容安全审核(敏感词库、审核记录、举报管理、违规处罚) ### Heavy Runtime — 不直接参与 Heavy Runtime 负责异步 AI 分析任务(学习状态分析、薄弱点识别、测验生成、闪卡生成),通过独立的作业排队机制运作。**基础 AI 对话不经过 Heavy Runtime**,而是通过 AiGateway 直接调用 DeepSeek。 --- ## 6. 会话管理 ### 6.1 创建 - **方式:** open-or-create 模式。用户从入口进入对话时,iOS 调用 POST /rag-chat/sessions。 - **复用逻辑:** 相同 scopeType + scopeId + userId 下存在未归档未删除的会话时,返回已有会话(HTTP 200)。否则创建新会话(HTTP 201)。 - **这意味着:** 每个用户在每个知识库范围内只有一个活跃对话会话。 ### 6.2 切换 - **方式:** 用户在会话列表 Sheet 中点击历史会话 → iOS 调用 API 加载该会话的消息历史。 - **效果:** 当前对话界面切换到所选会话,范围标签更新。 ### 6.3 搜索 - **方式:** 在会话列表 Sheet 中输入搜索词 → 本地过滤或 API 搜索。 - **范围:** 当前范围内的会话。 ### 6.4 归档 - **方式:** 会话列表 Sheet 中滑动 → "归档"。 - **效果:** API 更新会话 isArchived=true。已归档会话不在默认列表中显示。 - **恢复:** 可通过更新 isArchived=false 取消归档。 ### 6.5 删除 - **方式:** 会话列表 Sheet 中滑动 → "删除"。 - **效果:** API 软删除会话(isDeleted=true)。消息保留在数据库中但不再对用户可见。 ### 6.6 置顶 - **方式:** 会话列表 Sheet 中左滑 → "置顶"/"取消置顶"。 - **效果:** API 更新会话 isPinned 状态。置顶会话排在最前。 ### 6.7 Scope(对话范围) - 每个会话有 scopeType 和 scopeId,确定上下文来源。 - 新建对话时,如果用户从范围入口(知识库/资料)进入,新会话继承该范围。 - 用户也可以在对话中切换到全局模式创建新会话。 ### 6.8 Scope Snapshot(范围快照) - 每条消息保存一个 scopeSnapshot 对象:{ scopeType, scopeId, parentKnowledgeBaseId }。 - 作用:将消息冻结到发送时的范围上下文。即使后续范围发生变化,历史消息仍知道自己引用了哪个范围的上下文。 ### 6.9 引用(Citation) - AI 回复后,系统从上下文项中提取前 5 个创建 ChatCitation。 - 每个引用包含:chunkId(知识点 ID)、sourceTitle(标题)、excerptText(内容前 500 字符)。 - iOS 在消息气泡中展示引用信息。 ### 6.10 历史消息 - iOS 进入会话时调用 GET /rag-chat/sessions/:id/messages 加载历史。 - 消息按时间排序,含角色(user/assistant)、内容、token 数和引用。 --- ## 7. 核心业务数据 ### 7.1 对话会话(ChatSession) - **谁创建:** API 在 iOS 调用 open-or-create 时创建(或返回已有)。 - **谁更新:** API 在每次消息发送时更新 lastMessageAt;iOS 操作更新 isPinned/isArchived/isDeleted/title/modelMode/modelId。 - **谁查询:** iOS 获取会话列表和消息历史;Admin 在聊天日志页查看。 - **用途:** 对话的组织单元,承载范围信息和消息列表。 ### 7.2 对话范围(ChatScope) - **概念性对象**(非独立数据库表),由 ChatSession 的 scopeType + scopeId 定义。 - **取值:** global、knowledge_base、folder、material、knowledge_item。 - **用途:** 确定上下文加载策略和会话唯一性。 ### 7.3 消息(ChatMessage) - **谁创建:** API 在发送流程中创建用户消息和 AI 消息。 - **谁更新:** 创建后不可修改。 - **谁查询:** iOS 加载会话消息历史;Admin 在聊天日志详情中查看。 - **用途:** 对话的完整记录,含角色、内容、token 数、scopeSnapshot。 ### 7.4 引用(ChatCitation) - **谁创建:** API 在 AI 回复保存后自动创建(从前 5 个上下文项提取)。 - **谁更新:** 创建后不可修改。 - **谁查询:** iOS 在消息详情中展示;消息列表查询时惰性加载。 - **用途:** 为 AI 回复提供可追溯的来源引用。 ### 7.5 范围快照(ScopeSnapshot) - **概念性对象**(嵌入在 ChatMessage 中),包含 { scopeType, scopeId, parentKnowledgeBaseId }。 - **用途:** 冻结每条消息产生时的对话范围。 ### 7.6 知识分块(KnowledgeChunk) - **谁创建:** Python RAG Worker 在文档处理时创建。 - **谁更新:** 不更新(软删除通过 Qdrant 实现)。 - **谁查询:** Admin 在分块管理页查看;Qdrant 向量搜索(当前仅 Admin RAG 调试页使用,不用于对话上下文加载)。 - **用途:** 文档的语义检索向量索引。当前不参与 AI 对话上下文构建。 ### 7.7 模型配置(Model Configuration) - **谁管理:** Admin 通过 AI 网关管理页配置路由规则和提供商。 - **谁使用:** AiGateway 在每次对话请求时根据 tier(primary/cheap/strong)和 taskType 选择模型。 - **当前配置:** primary tier → deepseek-v4-pro;cheap tier → deepseek-v4-flash。 --- ## 8. 异常与降级 ### 8.1 RAG 尚未处理完成 - **场景:** 资料已上传但 Python RAG Worker 尚未完成向量索引。 - **影响:** 知识库范围对话的上下文来自 KnowledgeItem 表——**不受 RAG 处理状态影响**。所有 Scope 的上下文加载均不依赖 Qdrant,RAG 未完成不影响对话功能。 ### 8.2 检索无结果 - **场景:** 知识库为空或范围内无匹配知识点。 - **API 处理:** loadContextByScope 返回 isEmpty=true。系统提示注入"当前知识库中暂无相关内容"。 - **模型行为:** AI 基于通用知识回答,可能告知用户知识库内容不足。 ### 8.3 模型调用失败 - **场景:** DeepSeek API 返回错误(超时、限流、服务异常)。 - **API 处理:** AiGateway 自动回退(fallback 到同 tier 的备用模型/提供商),最多重试 3 次。 - **用户感知:** 如果所有重试均失败,返回错误提示。Admin 可在回退日志中查看详情。 ### 8.4 流式响应中断 - **场景:** SSE 连接在网络问题或客户端断开时中断。 - **API 处理:** 检测 res.destroyed,优雅停止流式输出。已生成的部分内容可能不保存为完整消息(取决于中断时机)。 - **iOS 处理:** 显示连接中断提示。用户可重新发送消息。 ### 8.5 用户取消生成 - **场景:** 用户在 AI 生成过程中取消(iOS 断开 SSE 连接或发送取消请求)。 - **API 处理:** 检测连接断开,停止流式输出。 - **影响:** 部分生成的内容不保存。用户可重新发送。 ### 8.6 会话被删除 - **场景:** 用户或 Admin 删除会话。 - **API 处理:** 软删除(isDeleted=true)。消息保留但不可见。 - **用户感知:** 会话从列表中消失。已删除会话不可恢复(当前无回收站功能)。 ### 8.7 资料被删除 - **场景:** 对话引用的知识库/资料/知识点被删除。 - **API 处理:** 上下文加载时自动过滤已删除项。历史消息的 scopeSnapshot 仍保留原范围信息,但该范围可能不再可访问。 - **用户感知:** 新对话中该范围无上下文可用。历史消息仍可查看但引用可能失效。 ### 8.8 无权限 - **场景:** 用户尝试访问其他用户的会话。 - **API 处理:** 会话所有权校验失败,返回 403/404。 - **用户感知:** 无法查看或操作非自己的会话。 ### 8.9 Token 超限 - **场景:** 上下文 + 对话历史超过模型上下文窗口。 - **API 处理:** 上下文加载有 4000 字符硬限制。长对话历史可能需要截断(具体策略待确认)。 - **用户感知:** 较早的对话内容可能不被模型考虑。 ### 8.10 模型 API Key 无效 - **场景:** 平台 DeepSeek API Key 过期或余额不足。 - **API 处理:** AiGateway 调用失败。如果用户配置了自己的 API Key,可回退到用户 Key。 - **Admin 处理:** Admin 在密钥管理页更新或轮换 Key。 - **用户感知:** 对话报错。用户可在 AI 设置中提供自己的 DeepSeek Key。 ### 8.11 DeepSeek 服务不可用 - **场景:** DeepSeek API 全面不可用。 - **API 处理:** AiGateway 尝试所有提供商后失败。 - **用户感知:** 对话完全不可用,显示服务异常提示。 - **Admin 处理:** Admin 在 AI 网关管理页监控提供商状态,配置备用提供商。 --- ## 9. 查询与管理入口 ### 用户查询 - **会话列表:** iOS 对话页工具栏 → 会话列表 Sheet(搜索、筛选)。 - **消息历史:** iOS 对话页加载历史消息。 - **引用信息:** iOS 消息气泡中展示。 - **AI 使用统计:** iOS 端当前未展示(无用户可见的 token 用量或成本页面)。 ### Admin 查询 - **会话日志:** Admin 聊天日志页 → 查看所有会话(含用户 ID、知识库 ID、消息数)。 - **消息详情:** Admin 聊天日志页 → 点击会话查看全部消息(角色、内容预览、token 数、时间)。 - **AI 网关管理:** Admin AI 网关页(路由规则 CRUD、提供商启用/禁用、回退日志)。 - **AI 使用统计:** Admin 指标页(按提供商/模型的调用次数、延迟、失败率、成本)。 - **AI 成本管理:** Admin 计费页(费用记录 CRUD、按用户统计、导出 CSV)。 - **内容安全审核:** Admin 内容安全页(敏感词库、审核记录、举报管理、违规处罚)。 ### 系统内部查询与管理 - **AiGateway 路由:** 每次对话请求时自动查询路由规则和提供商配置。 - **Token 使用记录:** AiGateway 自动记录每次调用的 inputTokens/outputTokens/延迟/成本到 ModelInvocationLog。 - **每日使用聚合:** 系统自动聚合用户和平台的每日 AI 使用量(UserAiUsageDaily、PlatformAiBudgetDaily)。 - **配额检查:** 发送消息前检查用户每日配额和平台预算。 --- ## 10. 当前完成状态 | 组件 | 状态 | 说明 | |------|------|------| | iOS 流式对话界面 | 已完成 | SSE 解析 + 思考过程展示 + 引用展示 | | iOS 消息气泡渲染 | 已完成 | 用户消息紫色渐变 + AI 消息含思考折叠 | | iOS 复制/重新生成 | 已完成 | 复制到剪贴板 + 重新发送 | | iOS 会话列表 Sheet | 已完成 | 搜索、切换、删除、归档、置顶 | | iOS 新建对话 | 已完成 | 强制创建新会话 | | iOS 范围标签展示 | 已完成 | 对话顶部显示当前范围 | | iOS 全局对话 | 已完成 | 无上下文对话 | | iOS 知识库范围对话 | 已完成 | 从知识库详情页底部按钮进入 | | iOS 资料范围对话 | 已完成 | 从资料阅读页工具栏 AI 按钮进入 | | iOS 知识点范围对话 | 暂未确认 | API scopeType=knowledge_item 已定义;iOS 知识点详情页工具栏菜单未发现直接 AI 对话入口,可能需从知识点详情页手动跳转 | | API open-or-create 会话 | 已完成 | 相同范围复用已有会话 | | API 内容安全检查 | 已完成 | 输入消息 + AI 输出敏感词匹配 | | API 上下文加载(KnowledgeItem 表) | 已完成 | 按 scopeType 查询最多 30 条 | | API 系统提示构建 | 已完成 | 上下文注入到提示模板 | | API AiGateway 路由 | 已完成 | tier 路由 + 回退 + 重试 | | API SSE 流式转发 | 已完成 | Content-Type: text/event-stream | | API 引用保存 | 已完成 | 前 5 个上下文项 → ChatCitation | | API 自动标题生成 | 已完成 | 首次消息截取前 40 字符 | | API Token 使用记录 | 已完成 | ModelInvocationLog | | DeepSeek 模型调用 | 已完成 | deepseek-v4-pro(primary)、deepseek-v4-flash(cheap) | | Qdrant 参与对话上下文加载 | 未完成 | `loadContextByScope` 完全不调用 Qdrant;所有 5 种 Scope 上下文均来自 PostgreSQL KnowledgeItem 表 | | 联网搜索 | 暂未确认 | 未发现联网搜索功能实现 | | 深度思考 | 已完成 | DeepSeek reasoning_content → SSE thinking 块 → iOS 思考过程展示 | | 文件附件 | 暂未确认 | 未发现对话中上传文件功能 | | 导图 | 暂未确认 | 未发现 AI 生成导图功能 | | 分享 | 暂未确认 | 未发现对话分享功能 | | 生成笔记 | 暂未确认 | 未发现从对话生成笔记功能 | | Admin 会话日志查看 | 已完成 | 聊天日志页 | | Admin AI 网关管理 | 已完成 | 路由规则 + 提供商 + 回退日志 | | Admin AI 使用统计 | 已完成 | 按提供商/模型的调用统计 | | Admin AI 成本管理 | 已完成 | 费用记录 + 按用户统计 + 导出 | | Admin 内容安全审核 | 已完成 | 敏感词库 + 审核记录 + 举报 + 违规 | | 用户 AI 用量展示 | 未完成 | iOS 端无 token 用量或配额展示 | | 用户自定义 API Key | 已完成 | iOS 设置页 → AI 设置 → 输入自己的 DeepSeek Key | | 平台预算回退 | 已完成 | 平台预算不足时自动回退到用户 Key |