- BFF 薄适配层(FastAPI,8090):QA 代理/SSE 中继/Neo4j 直连/抽取代理/会话持久化 - Vue3 前端:五相位检索流水线、文献来源与证据链、知识图谱、提取任务四 tab - 四档响应式(桌面/笔记本/平板/手机)、深浅主题 - 81 个 FR 全部实现,测试追溯矩阵 81/81,后端 121 测/前端 156 测 - 真实凭据已脱敏,运行时配置在 backend/.env(不入 git) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
16 KiB
16 KiB
CHANGELOG.md —— 进度与决策记录(PM 独占写入)
2026-08-25
- 计划批准:新前端 + 薄适配层方案获批。端口 8090(BFF)/ 5180(Vite dev),并行部署不切换。
- M0 启动:远端目录树建立;8090/5180 端口复核空闲;本地 staging 目录
/Users/jerry/haiguji/PlantAI-rag-new/建立。 - 契约文档定稿:
PRD.md(81 个 FR)、API.md、UI_SPEC.md、ARCHITECTURE.md、TEST_PLAN.md完成并锁定。 - Mock 层完成:
backend/mock/mock_server.py+ 21 个 fixtures(含 SSE 回放序列)。 - 共享前端文件完成:
frontend/src/i18n/labels.js、frontend/src/config/modes.js。 - 环境就绪:
plantai-bffconda 环境(3.11);npm 依赖 187 包(Vite 5.4.11/Vue 3.5.13);Playwright + Chromium headless shell 131 下载完成;mock server 在 8099 运行并全接口验证通过。 - D0 探测完成(
DISCOVERY.md,345 行)。契约偏差修正(基于真实上游):- Neo4j 当选
neo4j-plant-srt-direct-v1-full(bolt 18788,QA 7920 实际使用)。schema 为 canonical(SRT2CanonicalEntity/SRT2CanonicalAssertion),非假设的:Entity;无全文索引,名字检索走name_norm前缀索引(0.09s)。 - 抽取任务真实状态枚举
queued/running/completed/failed,无 progress 数值——BFF 按 stage 派生progress_pct。 - QA source 真实分数字段为
final_score;检索计划在query_plan键;native_graph_chains为列表、graph_knowledge_chains为 dict 双形态。归一化规则已更新。 - 实测 search ≈92s(读超时调至 180s)、stream ≈37s。
processing-status/progress/summary/run-log当前空数据(上游批次目录未配置),前端按空态处理。
- Neo4j 当选
- 已知问题:QA 上游 DeepSeek LLM 余额不足(402 Insufficient Balance)——检索链路正常,chat 当前只出证据列表 fallback,无自然语言答案。需用户充值 DeepSeek 账户。开发不受阻(mock 覆盖);M2 验收对答案质量相应调整。
- 上游重启记录:无。
M0 完成 → M1 启动(2026-08-25 晚)
- M0 验收达成:契约文档、mock(8099 运行中且已按真实上游对齐:canonical schema / queued-runing 派生进度 / run-log JSON)、conda 环境、npm 依赖、Playwright、本地 staging + 远端副本、BFF 骨架 import 通过。
- 本地开发环境补齐:
.venv-backend(3.12,供后端 agent 本地自测)+ 本地 node_modules;deploy/sync.sh排除规则修正(.venv-backend)。 - 跨归属占位脚手架:backend/app 全部模块 + frontend main.js/App.vue 占位,由各 agent 在 M1 以真实实现替换。
- M1 发射:A1/A2/A3(后端三线)+ B1/B2/B3(前端三线)+ T(测试用例)七个 agent 并行。前端三入口占位组件已由 PM 提供;文件归属含测试目录拆分(
tests/frontend/unit/b1|b2|b3,后端单测随代码backend/app/**/test_*.py)。 - A1 完成(15 文件,29 单测全过):config/db/schemas/normalize/upstream/health/sessions/main + pyproject + run.sh + .env.example。7 条偏差全部 PM 裁决通过并回填 API.md(hop 中间态字段、来源聚合取首条、search answer 空串、PATCH 空 body 幂等、title_manual 保护、凭据仅入 BFF 配置、新增 python-multipart)。
- 待办:A1 报告 A3 的 17 个测试失败(
test_kg.py用 ASGITransport 直挂裸 router 与 fastapi 0.141 不兼容;test_extraction.py两处 respx 失败)——待 A3 汇报后统一派发。 - B3 完成(工作台四 tab,54 单测全过,
vite build通过):BenchPanel/RetrievalPane/SourcesPane/SourceRow/ChainGroup/ExtractionPane/ProgressItem/KgPane/KgGraphView(手写 SVG 力导向,无第三方库)/KgEntityDetail/graphLayout/bench store/两 API 模块。15 条工作台文案已由 PM 合并进 labels.js,benchLabels.js 改为薄别名。 - 集成对齐点(B3 提出,待各线就绪后统一处理):① chat store getter 名(
currentEvents/currentMessage/messages,B2 确认);② bench 折叠由 B1 AppShell 控制(emit/props 接缝);③pa-edge-gradSVG defs id 前缀;④ ExtractionPane 卸载时stopPolling(BenchPanel onBeforeUnmount);⑤ kg 邻域深度 2 的 13s 提示已做。 - A2 完成(QA 代理 + SSE 中继,36 单测全过):四端点 + STAGE_PHASE/STAGE_LABEL + 帧解析/重发/看门狗/重试。SSE 读超时采用
read=None+ 应用层看门狗(producer task + Event.wait,规避 anyio.fail_after 毒化 generator 链的工程陷阱)。degraded语义已 PM 裁决:仅 UPSTREAM_DOWN 为 true(API.md 已回填)。 - A2 集成对齐点:A1 就绪后删除 qa.py/sse_relay.py 内本地等价实现(
_fallback_normalize_qa等),归一化以 A1 为准;真实上游冒烟(1.78MB search 响应、SSE 全流程)在远端做(本地 7920 不可达)。 - A3 完成(图谱直连 + 抽取代理,88 单测全过):Neo4jService(实例回退 18788→19788→17687、TCP 预检、depth=1 绝不执行第二跳)+ 五 kg 端点 + ExtractionService(8000 主/7900 回落、progress_pct 派生、plan 409→null、spool 上传)+ 全套 respx/FakeDriver 单测。A1 报告的 17 个测试失败已被 A3 自行解决(测试切换到兼容 pytest-asyncio 的纯 async def)。5 条偏差全部 PM 裁决通过(count 语义、422 暂留原生格式待 M2 全局处理器收敛、plan 失败置 null 等,API.md 已回填)。
- M2 集成前待办(PM 执行):① 补 pyproject dev 依赖
respx;② main.py 加全局 RequestValidationError 处理器(VALIDATION 信封);③ 删除 A2 本地等价实现切换 A1 normalize;④ 验证 A1 health 的probe_neo4j接缝;⑤ 远端真实 Neo4j/QA 冒烟。 - 后端集成预检(PM,2026-08-25):三线代码合并后全量
pytest .= 119 passed(2.34s),仅有 5 个 deprecation warning(A1 main.py 的on_event弃用,建议转 lifespan——列入 M3 收尾清单,不影响功能)。后端三条线无测试冲突,接缝(config/upstream/envelope)互相兼容。 - B1 完成(样式层 + 外壳 + 响应式 + 主题/健康 store,25 单测全过,build 通过 285KB/81KB):tokens 逐字复刻、四档断点、抽屉、覆盖层、visualViewport 键盘适配、http.js 统一错误。
- PM 集成修复(B1 偏差裁决 + 接缝接线):① laptop 档折叠策略裁决为「首次进入无偏好时自动折叠,把手保留,用户显式展开被尊重」(CSS 改为响应 side-collapsed 状态 + AppShell watch tier);② AppShell 顶栏 title/status 接上 B2 sessions store(原返回 null);③ 移动端全屏覆盖层 tab 条接上 B3 bench store 的 setActiveTab(原点击无效);④ 验证:B1 25 测 + B3 54 测全过、build 通过。
- B2 完成(会话与对话流式状态机,58 单测全过):chat store 全流程(落库→骨架→SSE→检查点→终态)、stop/retry/刷新恢复/揭示动画、sessions store、SseParser(多行 data/注释/CRLF/UTF-8 跨 chunk)、16 组件、markdown 消毒。手动冒烟:mock SSE 12 帧消费 + 18 模块 transform 全 200。
- B2 偏差裁决 + PM 集成补丁:① labels 补 4 键(toolParams/toolResult/toolLog/graphSummary);② 消息内 tool 块无 API 产出路径——保留渲染器待数据源;③ checkpoint 时序(揭示完成才落终态)裁决通过;④ interrupted 为前端本地标注(后端枚举不变)裁决通过;⑤ 重试同位置替换、旧 DB 行不更新裁决通过;⑥ FR-CHAT-015 高亮链补全(bench store 加 highlightSource + setHighlightSource 2s 自动清除、SourcesPane 传 highlighted、SourceRow 滚动定位 + 2s 渐隐高亮)。验证:B3 54 测 + B2 58 测全绿。
M2 集成(2026-08-25 夜)
- 真实栈部署:远端 BFF 8090(plantai-bff + python-multipart 补齐)、Vite dev 5180(代理→8090)、集成检查脚本 11/11 通过(健康/qa info/会话/Neo4j canonical/实体搜索/抽取/真实 search ≈90s)。
- 修复两个集成接缝 bug:① A2 的
get_qa_client误用 A1 的 asyncget_client()返回 coroutine → 裁决为「QA 流式路径独立持有 read=None 的 client,不复用 A1 单例」(语义不同:SSE 长静默会被 300s 读超时误杀);② A3_tcp_reachable未解包open_connection的 (reader, writer) 元组。 - PM 集成单点修改:main.py 转 lifespan + 全局 RequestValidationError→VALIDATION 信封;pyproject 补 respx;远端 @playwright/test 安装 + 根 node_modules symlink(T 方案 b)。
- SSH 隧道三连坑(PM 记录,供后续复用):pkill 自匹配杀 shell(用
[x]正则技巧);ExitOnForwardFailure被配置里坏掉的 RemoteForward 15721 触发退出;ClearAllForwardings=yes会清掉命令行自己的-L。 - 响应式断链缺陷(M2 核心 bug):真实浏览器中流水线相位卡冻结。六轮探针定位:fetch 层 12 个 progress + 3MB complete 全到达 → store 状态正确(探针直读 pinia)→ 唯一 PipelineCard props 已是 done 但 DOM textContent 冻结。根因:
send()/retry()里const aMsg = newSkeletonMessage(); this.messages.push(aMsg)后闭包持有 raw 对象,所有 SSE 相位突变作用在 raw target 上——Pinia reactive 代理读值正确但突变不触发渲染,子组件因 props 引用相等被 Vue 跳过 patch。B2 的 vitest 只断言 store 状态未测真实渲染链,故未暴露。修复:三处 push 后改持this.messages[this.messages.length - 1](代理)。修复后 M2 验收 12/12 全过(相位推进 4 快照/47s、答案 690 字、来源、图谱、SQLite 刷新恢复、无 JS 错误)。 - 诊断探针存档:
deploy/m2_probe{1..6}.js(chunk 级/网络层/store 直读/组件 props/卡片枚举),保留备查。
M3 功能面补齐(2026-08-25 深夜)
- 真实 KG 数据缺陷修复(PM):① 邻域 0 边——真实库边属性无
source_canonical_id/target_canonical_id(端点在两端节点上),A3 组装代码从边读这两个键恒 None;改为 Cypher 投影时用startNode(r)/endNode(r)注入;② overview 0/0——1644 万边 COUNT 聚合冷缓存超过 10s 查询超时,新增OVERVIEW_QUERY_TIMEOUT=60s用于 overview 两查询;③ 自环边(真实库gene_structure等实体自身关系)在组装层过滤。验证:overview 200/200(gene 35 万)、邻域 21 节点 8 边 0 自环。 - 部署工具:
deploy/bff_restart.sh(setsid 脱离 SSH +[u]pkill 技巧,解决 SSH 后台挂起坑)。 - M3 响应式接线修复(PM):① 平板档汉堡/工作台按钮不可见——responsive.css 规则写
.top-bar.has-tools但该类挂在.app-shell上,选择器永不匹配;② 手机档工作台按钮开的是右抽屉而非全屏覆盖层——openBench()未按 tier 分派;③ 覆盖层内两套 tab 条重复——隐藏 BenchPanel 内部那套保留外壳 tab 条(含关闭按钮)。 - M3 验收 16/16 通过:真实 KG(实体搜索/邻域图谱/抽取任务列表)、平板抽屉(打开/Esc 关闭)、手机档(底栏隐藏/覆盖层打开/tab 切换)、主题切换(浅色 canvas 精确 #F6F8FC)。三档视口截图存
artifacts/m3/。
M4 测试轮次(2026-08-25 凌晨)
- R1 全量结果:L1+L2 后端 119/119(行覆盖 87% 达标);L3+L4 前端 137/137(81.54% 达标);L5 Playwright 三档 19 pass/17 fail/12 skip → 收敛 8 缺陷;L2s 上游 smoke 7/7;FR 追溯主门禁 81/81 双向零失配。
- R1 缺陷 8 项已批量派发:BUG-R1-07 Blocker(http.js 30s 读超时 < search 92s)→ B1;BUG-R1-01 Major(kg 搜索丢 q 参数)→ B1;BUG-R1-02/03/04/05/06 Major(会话高亮/删除死代码/QA 降级未禁用/错误信封误显示/markdown 零调用)→ B2;BUG-R1-08 Minor(health 索引误报)→ A3。
- T 侧环境说明:远端补装 pytest-cov;曾误
--save-dev动 package.json 已还原(md5 一致);证据归档~/5090/teamWorkspace/zh/r1_test_evidence/。 - R1 修复进展:A3 已交付 BUG-R1-08(probe 列表全等比较误报索引缺失——真实实例另有 canonical_id 约束索引;改为成员判断 + 2 锁定单测,23/90 过,真实冒烟 detail:None)。B1 已交付 BUG-R1-01/07(http.js 默认超时 600s 覆盖 API.md 全表、get 增 query 序列化、FormData 走 multipart;32 测过;隧道实测 KG 搜索 17 条含 q 参数、search 47.7s 不自断)。B2 已交付 BUG-R1-02~06(selectSession 同步 activeId;SessionItem 删除按钮+右键+确认弹层 Teleport;ChatPanel 接 health store 降级禁用;err.code 优先映射 + errText 透传;qaToBlocks/_finalizeReveal 走 renderMarkdown;70 测过,全前端 156 测)。
- R1 修复集成(PM):本地全量回归后端 121 测/前端 156 测全绿;mock 本地远端 md5 一致;BFF 重启后 health 无索引误报;R2 全量回归已派发 T。
- R2 全量回归通过(T):后端 121/121、前端 156/156、Playwright 48 条(35 pass/12 skip 依赖充值/1 flake 复跑通过)、上游 smoke 7/7、行覆盖 87%/80.59%、FR 追溯 81/81。R1 八缺陷全确认修复(含 E2E-01 刷新恢复补验三档全通)。无新缺陷。唯一失败为环境性 flake(tablet 主流程 300s 超时,单独复跑 52.3s 通过,上游 QA 串行排队所致)。T 清理了全部测试污染会话数据。
- M4 判定(PM):主/辅门禁全达标、产品用例全 pass → 按 TEST_PLAN 纪律收尾。收尾前采纳两处加固:① E2E 真实流超时 480s/终态等待 360s(T 测试代码);② Vite 忽略 coverage 目录(测试期覆盖率文件触发 198 次页面重载,干扰 E2E 与浏览器访问)。
- M5 最终验收通过(PM,2026-08-25):
deploy/m5_acceptance.js15/15 全过。生产形态打通(BFF 8090 单进程静态托管,修复 dist 路径解析:backend/frontend/dist → 项目根;sync 排除 dist 需单独同步)。真实 SQLite 历史恢复(相位卡 5/5、引用 chip 高亮定位)、真实问答全链路(答案 698 字 + 4 引用)、三档视口档位全正确。docs/ACCEPTANCE.md归档。项目收官——遗留唯一外部依赖:DeepSeek 余额(充值即恢复,零代码改动)。
DeepSeek 恢复与 QA 修复(2026-08-25 下午)
- 诊断:用户充值后 QA 仍 402。实测三个 DeepSeek key:QA 旧 key(sk-9d70bc)与 PlantAI-rag key(sk-9de0a3)余额均不足;PlantAI-dev 的 NEW_API_KEY(sk-9c0235)余额充足。用户指示用该 key。
- 手工重启的弯路(PM 记录,教训):① 整行 shlex.quote 导致 source 时变量全失效;② 保留旧进程 CONDA_*/PATH 污染新 shell 致 conda activate 崩溃;③ source 缺
set -a导致变量不 export 进 uvicorn;④ runtime env 文件缺V15_QDRANT_URL等进程内联覆盖项。最终用户提供官方管理脚本解决。 - 正确路径:
~/5090/PlanAI-cooperate/RAG/rag-develop/start_plantAI_RAG.sh统一管理 QA(7920)/Neo4j(18788)/Qdrant(26333)/方法学(8000)/Ollama。换 key = 更新runtime/qa_v1_1_73.env(已完成,备份.bak_oldkey)+ 官方脚本start。脚本显式QA_V1_LLM_MODEL=deepseek-chat(flash 模型在新 key 下输出截断)、嵌入服务QA_V1_EMBED_URL=Ollama bge-m3、BGE CUDA 等全套配置。 - 验证结果:PlantAI-rag-new 问答——自然语言答案 1379 字 + 15 条来源(degraded_execution=False);PlantAI-dev 知识问答——success:True + 2671 字答案 + 14 来源(需把
QA_V1_1_73_TIMEOUT从 300 提到 600,完整链路实测 216~273s;已写入 .env 并重启 9011,备份.env.bak_qa_timeout)。 - PlantAI-dev 9011:仍用手动方式重启(官方 manage_plantai.sh 默认管 9000 端口),
source .env+set -a后 uvicorn 拉起,已验证 env 含新超时与 7920 地址。 - 运维提示:QA 服务重启一律走官方脚本
bash start_plantAI_RAG.sh restart|start|verify,不要手工起进程。