Files
PlantAI-rag-new/docs/ARCHITECTURE.md
T
jerryandClaude Fable 5 1e94de7464 PlantAI-rag-new 首次提交:文献知识工作台
- 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>
2026-08-25 20:47:52 +08:00

14 KiB
Raw Blame History

ARCHITECTURE.md —— PlantAI-rag-new 架构与协作约定

版本 1.0 | 作者 PM | 本文件由 PM 独占写入,所有开发/测试 agent 只读


1. 项目定位

PlantAI-rag-new 是植物基因家族文献 RAG 知识系统的新一代工作台。

它不重写 RAG 算法、检索引擎与论文抽取流水线——那些是现有 PlantAI-rag 工程中经真实论文验证的资产。本项目做两件事:

  1. 一层薄适配(BFF, Backend-For-Frontend):代理并归一化现有运行中的上游服务,补齐上游缺失的能力(会话持久化、图谱直连、统一错误信封)。
  2. 一套全新的响应式前端:严格实现 plantai-agent-ui-prototype.html 的视觉系统,并扩展为支持手机的四档自适应布局。

红线:不修改 PlantAI-rag、PlantAI-dev、rag-qa-v1_1_73 的任何源文件;不占用其端口;不切换其流量。


2. 系统拓扑

┌────────── 用户浏览器(桌面 / 平板 / 手机)──────────┐
│                                                      │
│   Vue 3 SPA   ← 开发期 Vite dev :5180                │
│                 生产期由 BFF 静态托管                 │
└───────────────────────┬──────────────────────────────┘
                        │ /api/*  (同源,JSON + SSE)
┌───────────────────────▼──────────────────────────────┐
│         BFF   FastAPI + Uvicorn   127.0.0.1:8090     │
│  ┌────────────┬────────────┬───────────┬──────────┐  │
│  │ sessions   │ qa         │ kg        │extraction│  │
│  │ (SQLite)   │ (代理+SSE) │(Bolt直连) │ (代理)   │  │
│  └────────────┴─────┬──────┴─────┬─────┴────┬─────┘  │
└────────────────────┬┴────────────┴──────────┴────────┘
                     │             │          │
        ┌────────────▼──┐  ┌───────▼─────┐  ┌─▼──────────────┐
        │ QA V1.1.73    │  │  Neo4j Bolt │  │ Gene Family    │
        │ 127.0.0.1:7920│  │ 19788/18788 │  │ RAG :8000      │
        │ (只读消费)  │  │ /17687      │  │ 回落 :7900     │
        └───────────────┘  └─────────────┘  └────────────────┘

BFF 的存在理由(不是无谓的中间层):

职责 为什么前端不能直连上游
会话持久化 上游 QA 完全无状态,没有会话概念,UI 的历史列表必须有人存
别名归一化 上游同一语义有多个字段名(answer/response/message 等),归一化放前端会污染每个组件
SSE 阶段映射 上游推十余个细粒度 stage,UI 只需五阶段;映射放 BFF,前端不需要知道上游阶段名
图谱直连 上游 /kg/* 路由指向已死的 7687 端口,必须由 BFF 用 Bolt 驱动绕过
统一错误信封 三个上游三套错误格式,前端只应处理一种
跨域与凭据 上游只绑回环且 Neo4j 需要密码,凭据不能进浏览器

3. 运行时约定

项 值
BFF 监听 127.0.0.1:8090(占用则退 8091)
Vite dev 127.0.0.1:5180(占用则退 5181)
BFF conda 环境 plantai-bff(Python 3.11,新建,不复用 gfpy312)
SQLite 路径 backend/data/plantai.db(WAL 模式)
前端工具链 Vite 5.4.x + @vitejs/plugin-vue 5.2.x + Vue 3.5.x + Pinia 2.3.x
Node v18.19.1(已 EOL)——禁止升级 Vite 至 7(需 Node 20+),禁止用 npm create vite

生产形态:npm run build 产出 frontend/dist,BFF 用 StaticFiles 挂载,单进程从 :8090 提供服务。


4. 开发工作流:本地 staging + rsync

远端机器是运行与测试环境,本地是编辑环境。原因:agent 在本地能用完整的读/写/编辑工具迭代,通过 SSH 逐行改远端文件既慢又易错。

角色 路径
本地编辑(权威源) /Users/jerry/haiguji/PlantAI-rag-new/
远端运行(部署副本) /home/xzq/5090/teamWorkspace/zh/PlantAI-rag-new/

同步命令(由 deploy/sync.sh 封装):

rsync -az --delete \
  --exclude 'node_modules' --exclude '__pycache__' --exclude '.venv' \
  --exclude 'backend/data' --exclude 'frontend/dist' --exclude '.pytest_cache' \
  /Users/jerry/haiguji/PlantAI-rag-new/ \
  100.109.52.26:/home/xzq/5090/teamWorkspace/zh/PlantAI-rag-new/

规则:

  • 所有 agent 只在本地路径写文件,绝不用 SSH heredoc 改代码。
  • 同步由 PM 统一执行,agent 不自行 rsync(避免半成品覆盖远端)。
  • backend/data(数据库)、node_modules、dist 不同步,属远端运行时产物。
  • 文档最终必须在远端 docs/ 下可查——每次里程碑结束由 PM 同步一次。

5. Agent 分工与文件归属

铁律:文件归属严格互斥。任何 agent 不得写入不属于自己的文件。 需要跨归属改动时,向 PM 提出,由 PM 单点裁决修改。

Agent 职责 独占路径
PM 契约文档、集成、缺陷派发、验收、rsync docs/{PRD,API,UI_SPEC,ARCHITECTURE,TEST_PLAN,ACCEPTANCE,CHANGELOG}.md、deploy/**、src/i18n/labels.js、src/config/modes.js、backend/mock/**
D0 探测 上游探测与选型 docs/DISCOVERY.md
A1 后端·骨架 app 工厂、配置、SQLite、会话与消息 CRUD、归一化器、错误信封 backend/pyproject.toml、backend/run.sh、backend/.env.example、backend/app/{main,config,db,schemas,upstream}.py、backend/app/routers/{health,sessions}.py、backend/app/services/normalize.py
A2 后端·QA QA 代理、SSE 中继、阶段映射、重试与看门狗 backend/app/routers/qa.py、backend/app/services/sse_relay.py
A3 后端·图谱与抽取 Neo4j Bolt 直连、抽取代理与回落 backend/app/routers/{kg,extraction}.py、backend/app/services/{neo4j,extraction}.py
B1 前端·基础 令牌层、AppShell、四档响应式框架、主题、顶栏/底栏、通用 UI、健康轮询 frontend/{package.json,vite.config.js,vitest.config.js,index.html}、frontend/src/{main.js,App.vue}、frontend/src/styles/**、frontend/src/components/{layout,ui}/**、frontend/src/stores/{theme,health}.js、frontend/src/api/http.js、tests/frontend/unit/b1/**
B2 前端·会话与对话 会话列表与抽屉、对话区、作曲器、流水线卡、SSE 客户端 frontend/src/components/{session,chat}/**、frontend/src/stores/{sessions,chat}.js、frontend/src/sse/**、frontend/src/api/{qa,sessions}.js、tests/frontend/unit/b2/**
B3 前端·工作台 右侧四个 tab:检索过程、文献来源、提取任务、知识图谱 frontend/src/components/bench/**、frontend/src/stores/bench.js、frontend/src/api/{kg,extraction}.js、tests/frontend/unit/b3/**
T 测试 用例编写与执行、缺陷报告 tests/backend/api/**、tests/e2e/**、playwright.config.js、docs/TEST_CASES.md、docs/TEST_REPORT_*.md

后端各 agent 的单测放在各自归属子树内(backend/app/**/test_*.py,随代码一起交付),运行 pytest backend/app -q;T 的 L2 接口测试与 L5 e2e 放在 tests/。

跨归属的接缝

以下文件被多方读取但只有一个写入方,接缝处必须按契约对齐:

接缝 写入方 读取方 契约依据
BFF 接口形态 A1/A2/A3 B1/B2/B3、T API.md
设计令牌 CSS 变量 B1 (styles/tokens.css) B2、B3 UI_SPEC.md §令牌
组件类名 B1 定义基础类,B2/B3 复用 互相 UI_SPEC.md §组件
五阶段标签与颜色 PM (i18n/labels.js) A2(计算 phase)、B2、B3 PRD.md FR-CHAT-009
模式参数集 PM (config/modes.js) B2 PRD.md FR-CHAT-006
块联合结构 A1(落库)、B2(渲染) T API.md §块联合

6. 并行解耦:mock server

前端三个 agent 不等待后端。M0 阶段 PM 产出 backend/mock/mock_server.py:

  • FastAPI,监听 127.0.0.1:8099
  • 实现 API.md 中全部接口,返回 backend/mock/fixtures/*.json 里的固定数据
  • 包含一条可回放的 SSE 事件序列(按真实时序 sleep),让流式 UI 能在无上游时开发
  • 支持 ?scenario= 查询参数切换场景:normal / empty(空结果)/ slow(慢响应)/ error(上游故障)/ degraded(部分降级)

B 组开发时把 vite.config.js 的 proxy 指向 8099;集成阶段由 PM 切回 8090。

fixtures 是单一事实源:mock 与真实 BFF 的单元测试共用同一批 fixture 文件,保证契约不漂移。


7. 集成节奏

M0 契约锁定 ──┬─→ A1 A2 A3(对真实上游)──┐
              ├─→ B1 B2 B3(对 mock)    ─┤→ M2 PM 集成 → M3 补齐 → M4 测试循环 → M5 验收
              └─→ T 写用例(对 PRD)      ─┘
  • 每一波结束,agent 向 PM 汇报「完成项 + 未决问题 + 对契约的偏差建议」,不直接改契约。
  • PM 在集成点统一处理契约偏差,必要时更新 API.md 并广播给受影响的 agent。
  • 缺陷修复一律批量派发,禁止边测边改(见 TEST_PLAN.md 轮次纪律)。

8. 目录结构

PlantAI-rag-new/
├── docs/                       # 全部文档,见第 5 节归属
├── deploy/
│   ├── sync.sh                 # 本地 → 远端 rsync
│   └── start-dev.sh            # 拉起 BFF + vite,打印隧道命令
├── backend/
│   ├── pyproject.toml  run.sh  .env.example
│   ├── data/                   # plantai.db(不入库、不同步)
│   ├── mock/
│   │   ├── mock_server.py
│   │   └── fixtures/*.json
│   └── app/
│       ├── main.py config.py db.py schemas.py upstream.py
│       ├── routers/  health.py sessions.py qa.py kg.py extraction.py
│       └── services/ normalize.py sse_relay.py neo4j.py extraction.py
├── frontend/
│   ├── package.json  vite.config.js  index.html  vitest.config.js
│   └── src/
│       ├── main.js  App.vue
│       ├── styles/    tokens.css base.css animations.css responsive.css
│       ├── i18n/labels.js       config/modes.js
│       ├── api/       http.js qa.js sessions.js kg.js extraction.js
│       ├── sse/       parser.js
│       ├── stores/    theme.js health.js sessions.js chat.js bench.js
│       └── components/
│           ├── layout/   AppShell 相关、TopBar、StatusBar、AuroraBg、Drawer
│           ├── ui/       StatusBadge、StatusDot、IconButton、Skeleton、EmptyNotice
│           ├── session/  SessionPanel、SessionItem、SessionRail、SearchBox
│           ├── chat/     ChatPanel、MessageList、Composer、PipelineCard、ToolCard …
│           └── bench/    BenchPanel、RetrievalPane、SourcesPane、ExtractionPane、KgPane …
├── tests/
│   ├── backend/                # pytest
│   ├── frontend/               # vitest
│   └── e2e/                    # playwright
└── playwright.config.js

9. 编码约定

后端

  • 全异步(async def + httpx.AsyncClient + aiosqlite);不在请求路径上做阻塞 IO。
  • 所有对上游的调用集中在 services/,routers/ 只做参数校验与响应组装。
  • 不吞异常:上游故障必须转成带 code 的错误信封,并在日志里保留原始异常。
  • 类型标注齐全,Pydantic v2 模型定义在 schemas.py。

前端

  • Vue 3 <script setup> + Composition API;组件单一职责,超过 ~250 行考虑拆分。
  • 样式一律用 --pa-* 令牌,禁止硬编码颜色值(令牌表见 UI_SPEC.md)。
  • 组件内 <style scoped>;跨组件复用的类放 styles/base.css(B1 归属)。
  • 状态跨组件共享一律走 Pinia store,禁止用 provide/inject 传业务状态。
  • 所有用户可见文案走 i18n/labels.js,组件内不写死中文字符串(错误提示除外,见 PRD.md §全局约定)。

通用

  • 文件编码 UTF-8,LF 换行。
  • 提交粒度:一个 FR 一次提交,提交信息含 FR 编号。

10. 已知的既存故障(不修,仅规避)

现象 影响 我们的对策
默认端口 7687 无 Neo4j,:8000/api/v1/kg/* 与 /v15-graph-qa/* 报错 上游图谱路由不可用 BFF 用 Bolt 直连非标准端口实例,见 DISCOVERY.md
PlantAI-dev .env 指向 7925(空端口),实际 QA 在 7920 PlantAI-dev 知识问答当前是坏的 与本项目无关,仅记录;本项目指向 7920
上游 QA 无 token 级流式,答案在终态一次返回 无法做真流式打字 客户端揭示动画,视觉一致但不伪造数据流
上游 max_rounds: 1,每个提问独立 无多轮上下文 UI 明确提示「每次提问独立检索」,不假装有上下文记忆