# 知识库与知识应用配置优化实施

状态：2026-10-14 已完成代码复核、提交、本机部署及真实冒烟；最终重新构建页面与服务健康检查通过。

设计依据：用户 2026-10-14 确认的 [v3 原型](design.html)。主会话实施，完成后按 requesting-code-review 技能独立复核；用户已授权提交、本机构建、重启与真实模型冒烟。

目标：知识库专注资料及索引；知识应用独立配置检索、可选重排序、可选回答，保留现有文档与应用生命周期管理。

技术：React/MUI、平台 TypeScript、KB FastAPI/Pydantic/SQLAlchemy、Alembic、Vitest/Pytest/Playwright。

## 实施约束

- 默认分块与自定义分块并列；自定义参数及高级入口始终可见。
- 文档分类、表格和管理操作复用原组件；设置改为保留表单状态的覆盖抽屉。
- 新应用默认向量检索，重排序和生成回答关闭；旧 answer.enabled 缺省为 true。
- 同应用知识库须使用同模型 ID 与版本，选库即时校验，后端继续校验。
- 关闭的阶段不要求模型，不校验旧参数，不调用模型。
- 工具查询仍为 {query}；检索返回 mode/hits/requestId，问答保留 answer/citations/requestId 并新增 mode。
- 旧草稿继承值先固化，发布快照保持冻结；无法解析的冲突保留依赖错误。
- 主仓使用任务分支，保留前次已授权模型标签修改。无共享 k8s 部署，无推送。
- 本机真实测试使用 Qwen3-Embedding 和 Qwen3.8-27B-MTP。

## 任务与检查

- [x] KB 配置与运行：修改 backend/app/model/kb_app_model.py、service/kb_app_service.py、service/kb_app_runtime.py；用 tests/test_kb_cp3_apps.py 覆盖三种检索方式乘两个可选开关、旧配置缺省、关闭环节的非法旧参数、工具实际入口输出与无 Chat 调用。
- [x] KB 临时测试：model/rag_model.py 新增 rerank_enabled（旧请求默认 true），service/kb_rag_runtime.py 条件解析排序模型；新界面显式发送临时回答参数，不继承库默认值。
- [x] 草稿迁移：Alembic 新增 0095_kb_app_answer_defaults；仅对旧草稿固化有效预算与推理配置，不修改发布版本；冲突草稿保留原配置供修复。用 SQLite fixture 检查迁移及幂等。
- [x] 知识库页面：packages/ui/src/views/kb/pages/KnowledgeBaseDocuments.jsx 取消设置 Tab，覆盖抽屉复用 KnowledgeBaseConfiguration；该组件用 radio 并列策略，保留情境增强；RagTestPanel 区分测试模式、排序开关及回答字段。
- [x] 知识应用页面：appConfig.js 默认关闭可选环节，validateAppConfig 条件校验；RagAppForm.jsx 直接编辑区域、兼容选库、去向量字段、保留范围过滤；复用 AppLifecycle 全部管理动作与 AppEditLayout，添加折叠入口和执行输出说明。
- [x] 结果与工具：AppTestPanel 按 mode 渲染 hits 或 answer/citations；核对平台代理、MCP 包装及工具说明，原回答消费方保持兼容。共享文档 docs/contracts/kb-query-output.md 记录两种输出。
- [x] 运行相关 Pytest、Vitest、平台 server 单测及编译。使用 requesting-code-review，处理所有严重和重要问题并运行相关回归。
- [x] 提交 KB 与平台代码，以 rebase/ff-only 合入 main。使用 ./aimp.sh 管理本机；先快照，再迁移 KB，构建平台并重启。
- [x] Playwright 冒烟：新建库、默认/自定义设置、上传/入库、检索和问答；创建同模型多库应用，禁选冲突库，验证 12 组合；发布纯检索/问答工具并真实调用；下线工具、停用/启用及删除测试资源，检查旧应用不变。截图自行检查，产物存 artifacts/ 与 .runtime/。

## 验证命令

- KB：`cd ../aimp-kb/backend && uv run pytest tests/test_kb_cp3_apps.py tests/test_kb_rag_runtime.py tests/test_kb_answer_settings.py tests/test_kb_rag_stream.py -q`，新增后先确认针对性用例因行为缺失失败，再实现通过。
- UI：`cd ../aimp-platform/packages/ui && npx vitest run src/views/kb`。
- 平台：`cd ../aimp-platform/packages/server && npm run test:unit -- --runInBand` 按实际受影响用例选择；`npx tsc` 编译。
- UI 构建：`cd ../aimp-platform/packages/ui && npm run build`。
- 本机健康：`./aimp.sh status`，真实冒烟经 `http://192.168.31.220:18180/chatV2/`。

实施记录与复核结论在完成相应阶段后追加，不能用设计原型检查替代实际功能验收。

## 代码复核（2026-10-14）

使用 requesting-code-review 技能，独立只读复核 KB、平台及 agent-base 的工作区差异，随后复核修复。没有未处理的严重或重要问题；真实浏览器历史跳转仍由冒烟验收。

| 发现 | 修复与依据 |
|---|---|
| 纯检索草稿测试误读 publishedApp.status | 先检查发布对象存在；回归测试真实渲染 hits，无回答字段 |
| 旧草稿 normalize 丢失 enabled 缺省语义 | 保留 legacy 标记，冲突库继续阻止保存；补加载冲突草稿用例 |
| 相同选库确认清空范围过滤 | 相同集合不触发修改；只删除属于已移除库的子资源，保留标签和元数据 |
| 未保存知识库设置可被程序导航和浏览器返回丢弃 | 包装导航方法并拦截 popstate，取消时恢复历史位置；处理 basename，保留卸载提示 |
| MCP 执行器只接受 answer/citations | 接受 retrieve/hits、显式 answer 及旧问答，拒绝错误模式和形状；HTTP-server 测试确认全文透传 |
| 工具说明仍声称一定生成回答 | 平台与 agent-base 统一说明两种结果，并同步已有断言 |

兼容性补充：保留旧应用 rerank.top_n 小于 retrieval.top_k 的有效配置，实际返回上限是两者较小值。关闭阶段不验证其旧参数；此点取代原型中较严格的数量约束，避免使存量应用失效。

代码提交并以 ff-only 合入本机 main：KB d77b343，平台 6d619639（功能）及 497ae5d3（入口位置），agent-base e5058bb。未推送。

已完成检查：KB 回归 181 通过、20 环境相关跳过；平台发布单测 36 通过；agent-base 显式启用测试 38 通过（根 POM 默认 skipTests，命令已使用 -DskipTests=false）；UI 构建与平台 TypeScript 编译通过。最终 UI 回归 133 个用例通过，真实冒烟结果见下方验收记录。

## 本机部署与真实验收（2026-10-14）

- 快照：`.runtime/backups/kb-20261013T163257Z/`，包含 KB、存储、MySQL 与运行配置，校验通过。
- 依赖输入：现有 KB 镜像的 pyproject.toml、uv.lock、.python-version 与本仓 SHA256 一致。完整镜像构建时字体下载缓慢，终止该次构建；复用已核对的本机依赖镜像，重新 COPY app、alembic 与 alembic.ini 构建业务层。新镜像 ID 为 19bdd1ce9e48，运行容器已使用它。
- 数据库：127.0.0.1:15432/aimp_kb，迁移至 0095_kb_app_answer_defaults。未修改数据库连接配置。
- 本机平台 UI、server、agent-base 均重新构建，按 KB → agent-base → platform 顺序启动／重启。最后截图发现入口位置偏离确认稿，已将知识库设置移至标题右侧、应用收起按钮右对齐，复核与 8 条回归通过，再构建 UI。
- 自动化：KB 181 通过、20 环境条件用例跳过；UI 133 通过；平台发布单测 36 通过；agent-base 明确开启测试 38 通过。
- 真实冒烟 28 项通过：页面分块策略与真实保存、返回取消／确认、上传与入库、检索／问答、同模型多库及冲突禁选、12 组合、标准 MCP 检索与问答、同工具 ID 同步、下线／重发、停用／启用、页面删除与工具移除、原 6 个应用及发布快照保持不变。模型为 Qwen3-Embedding、Qwen3.8-27B-MTP。
- 页面截图已自行检查。仅临时测试资源被删除；原有知识库、应用与用户要求保留的 CLI 测试资源未清理。当前正式工具查询方式由发布版本固定，用户未请求切换现有工具。

[完整冒烟记录与截图](../../../artifacts/latest/kb-config-1791909601374/report.md) 为本机测试产物，不入库。复核后未发现未处理的严重或重要问题。该结论限定于受影响功能与已执行测试，不将环境跳过用例记为通过。

最终界面复查：497ae5d3 构建并重启平台后，知识库设置入口位于标题右侧，分类及文档表格保持原布局；应用可选开关与管理面板折叠正常，无浏览器 pageerror。最终 `./aimp.sh status` 所有服务及健康点正常。

## 文档上传超时调整（2026-10-14）

用户测试约 6 MB 文档时出现 `KB service timeout`。排查确认平台代理的普通请求使用 30 秒绝对超时，文件传输也占用该时间；本次文档没有入库或解析记录。使用不存在的知识库进行无入库数据的对照测试：6 MiB 快速上传正常进入接口校验；160 KiB/s 持续上传在 30.009 秒返回 504，当时仅发送约 4.6 MiB。

按用户要求，将准确匹配的文档上传 POST 请求超时调整为 120 秒，本机 edge 对应请求的上游 socket 超时同步调整为 120 秒。其他请求保留现有规则。新增上传路由、查询参数及相邻路由的回归检查，修改前两个上传用例失败，修改后相关 49 项测试通过；edge 路由 6 项检查及服务端 TypeScript 编译通过。

重新构建 server 并重启本机 platform、edge 后，6 MiB 文件以同样速率在 38.497 秒完整传输，返回预期的 `kb not found` 校验结果，无 504。该测试验证上传传输链路，不代表文档解析或向量化验收；没有新增知识库、文档或模型调用。所有服务及健康点正常。


## 上传弹窗进度与动态超时（2026-10-14，已完成）

用户已批准 [弹窗进度补充设计](upload-progress.html)，并确认动态等待方案及每批最多 20 个文件、单文件最多 50 MB 的前端提示与校验。此决定替代上一节整批固定 120 秒的规则。

实施顺序：先补充前端进度、取消和容量边界测试及代理动态计时测试；修改进度界面、前端校验、平台代理与 edge 超时，以及 KB 单文件限制；执行复核，重新构建、重启本机，再验证超过 120 秒的持续上传、超过 50 MB 的合规批次与超限拦截。文件传输以 2 分钟无数据为超时，发送完成后确认窗口为 2 分钟，整批以 30 分钟为硬上限。Node HTTP 接收请求的默认 5 分钟期限同步调整至 31 分钟，edge 上传 socket 空闲期限为 130 秒；外围期限留出响应缓冲，实际上传由平台代理的 2 分钟空闲期限与 30 分钟硬上限控制。普通请求仍由自身代理期限保护。


验收结果：前端 13 项、平台代理 54 项、KB 上传及资源域 23 项测试通过；服务端 TypeScript 编译与 UI 构建通过。requesting-code-review 独立只读复核未发现严重或重要问题；已修复初始未知总量短暂显示 0% 的细节，并验证重试保留同一批文件且使用新的取消控制器。

本机真实检查：
- 6 MiB 文件持续慢速传输 134.564 秒，完整到达 KB，返回测试目标不存在的预期 404，未触发固定 120 秒超时。
- 两份各 32 MiB 的文件，合计 64 MiB，完整通过上传代理；测试目标不存在，返回预期 404，不产生入库数据。
- 51 MiB 单文件返回 413，21 个文件返回 422；原知识库文档数在测试前后均为 7，没有新增文档或向量化任务。
- 首次停滞测试在 120.019 秒由 edge 抢先返回 502。给外围期限增加缓冲后，最终停滞测试在 120.379 秒由平台代理返回明确的 504；页面对应中文上传超时提示。
- 实际浏览器检查弹窗 26% 进度、等待服务器确认、取消、21 文件与 51 MiB 前端拦截，无 pageerror。上传事件为浏览器内模拟，不发送测试文件；截图已自行检查，位于 `.runtime/kb-upload-progress-live-26.png`、`.runtime/kb-upload-progress-live-wait.png`，不入库。
- KB 使用现有镜像与本机 app 源码挂载部署，无依赖或数据库变更；重启本机 KB、platform、edge 后健康点正常。没有发布到共享集群。
