583c012706
Add research-wiki/migrations/ (govdoc-saas, video-tree-trm5, chsanalyzer): deletion lists, component mappings, call-site inventories, config migration, stepwise rollback plans, legacy behavior audits, and reverse constraints on the library design including flagged architecture gaps.
145 lines
12 KiB
Markdown
145 lines
12 KiB
Markdown
# CLAUDE.md
|
|
|
|
> [!URGENT]
|
|
> **实验室内部通用基础库(生产级、非 MVP、零业务假设)**
|
|
> 1. 本项目是被多个科研/生产项目依赖的**库**,不是应用:稳定性、并发性、防御性、可观测与测试不可为"简单"让步(YAGNI 仍适用,但不削减健壮性)。库的 bug 会同时击穿所有下游项目。
|
|
> 2. 你的所有思考过程和回复必须使用 **简体中文**。
|
|
|
|
## 1. 项目元数据
|
|
- **核心目标**: PolyGateway = 统一的大语言模型(LLM/VLM/OCR,音频预留)调度与中转库。治理单位是**一次模型调用**:请求封装、多源多账号、限流、错误分类与重试、熔断、Redis 响应缓存、流式看门狗、遥测(含成本)、结构化输出策略。全组件端口化可插拔。
|
|
- **架构权威文档**: `research-wiki/ARCHITECTURE.md`(架构单一事实源,含 D1-D13 决策及讨论过程、子系统设计、三项目迁移验收标准;**不受 400 行设计文档限制**,以无歧义传达既有讨论为准绳)。开发顺序见 `research-wiki/ROADMAP.md`;`research-wiki/designs/` 仅存放每次实现具体功能的设计文档。
|
|
- **参考项目**: `reference/` 下三个项目是本库的需求来源与代码蓝本(**只读,勿改**);库必须能按 ARCHITECTURE.md §11 被它们迁移接入,否则即边界缺口。
|
|
- **技术栈**: Python 3.11+,核心仅依赖 `httpx` + `pydantic`,其余(redis/sqlite/postgres/json_repair/openai)一律 optional extras。conda 环境 `PolyGateway`。
|
|
|
|
## 2. 常用命令
|
|
|
|
> [!CRITICAL]
|
|
> 所有 Python 命令必须在 `PolyGateway` conda 环境中执行(`conda run -n PolyGateway <cmd>` 或先激活)。长时间运行的程序用 tmux 且禁用日志缓存。
|
|
|
|
```bash
|
|
make install # editable 安装(含 dev 与全部 extras)
|
|
make test # pytest + 覆盖率
|
|
make lint # ruff --fix + import-linter(依赖铁律机械化执法)
|
|
make format # ruff format
|
|
make ci # 只读验证(check + test)
|
|
```
|
|
|
|
## 3. 标准作业程序(分档触发)
|
|
|
|
> **档位原则(Fable 5 适配,2026-07 调研决策)**: 约束"边界与验收",不规定思考步骤。强制档(MANDATORY)是硬门;其余由模型按 skill description 自判,自判标准是任务实质(规模/风险/是否触及公共承诺),不是省事。硬边界(reference/ 只读、危险命令、提交质量门)由 `.claude/settings.json` 注册的 hooks **确定性执行**,不依赖提示词自觉。
|
|
|
|
### Phase 1: 规划与设计
|
|
1. 涉及**公共 API、端口签名、架构边界、新子系统**的变更**必须**调用 `brainstorming`(产出 2-3 备选方案+权衡)并经**人类确认**后实施;其余任务自判(判据: 是否改变库对下游的承诺)。动手前查阅 `research-wiki/`(单一事实源)。
|
|
2. 功能产生运行时数据时**必须**调用 `structured-logging`。
|
|
3. **里程碑级/跨多文件**功能编码前**必须**调用 `writing-plans`;小改动自判。审核门控: design 走 Claude 自审 → Codex 审 → **人类审**;plan 走 Claude 自审 → Codex 审 → 直接执行。
|
|
|
|
### Phase 2: 执行与验证
|
|
1. **测试结果门**: 合并前每个行为变更必须有"先失败后通过"的测试证据(`test-driven-development`);bug 修复必带回归测试;不规定中间怎么走。
|
|
2. **独立验证**: 里程碑级/跨多文件/合并前**必须**派全新上下文的 verifier subagent(`verification-before-completion`);任何规模的完成声明都必须逐条对应本会话内的工具输出(证据化声明,禁止虚报)。
|
|
3. **反 gold-plating**: 不做任务外的重构、抽象与"顺手清理"。
|
|
|
|
## 4. 核心规则
|
|
|
|
### 4.1 核心原则(按优先级)
|
|
- **P1 YAGNI**: 不写当前用不到的代码;但并发控制、防御校验、可观测埋点、错误隔离与测试是"当前需要",不在削减之列。
|
|
- **P2 高可读性**: 领域术语命名;注释解释"为什么"。
|
|
- **P3 单一职责**: 一句话说不清职责(需要"和")= 拆分。
|
|
- **P4 显式优于隐式**: 公共函数完整类型注解;依赖注入,不从全局偷取;严禁默认参数掩盖关键逻辑。
|
|
- **P5 防御性与安全性**: 一切外部输入(网关响应、LLM 返回、配置)校验后使用;严禁 `except Exception: pass`;严禁默认值掩盖错误;敏感信息只走 `.env`。
|
|
- **P6 可测试性**: 纯函数优先;外部依赖经 Protocol 注入;测试用真实样本或其二次构造。
|
|
- **P7 架构依赖规则**: 决策逻辑与状态存储分离(中间件算法一份,后端可插拔);`ports.py`/`types.py`/`errors.py` 为最内层,不 import 任何具体实现;`middleware/` 只依赖端口;`transports/`、`backends/`、`telemetry/` 只实现端口,互不依赖(import-linter 契约执法)。
|
|
|
|
### 4.2 库铁律(本项目特有,违反即 bug)
|
|
|
|
| 铁律 | 内容 |
|
|
|---|---|
|
|
| 零业务假设 | 库内禁止出现任何下游业务领域词汇(视频/文书/超声等)与业务 fixtures;扩展点一律 Protocol |
|
|
| 纯 asyncio 中立 | 无全局状态、无框架假设、无模块级单例;同一 `GatewayClient` 在 arq worker 与裸脚本中行为一致 |
|
|
| 取消可穿透 | `asyncio.CancelledError` 永不捕获吞没;重试循环、限流等待、流式读取全部可被取消;in-flight 资源在 finally 释放 |
|
|
| 错误分类驱动 | 一切失败必须落入 `errors.py` 四分类(Transient/SourceDead/RequestRejected/ResultInvalid),由分类决定重试/换源/熔断,禁止散落 ad-hoc 判断 |
|
|
| 遥测必录 | 每次调用(含缓存命中、失败)必经 `TelemetryRecorder` 记录,遥测写失败降级不冒泡;遥测调用点收敛为单一 helper,禁止复制参数列表(三项目 4 处复制的教训) |
|
|
| 降级方向 | 缓存/遥测后端不可用 → 静默降级(warning);限流/熔断后端不可用 → **报错而非放行**(防击穿网关) |
|
|
| 依赖极简 | 核心仅 httpx + pydantic;新增任何依赖必须进 optional extras 并经人类确认 |
|
|
| 无缓存毒化 | 缓存 key 必含 model + messages 摘要 + 命名空间/租户 + salt;多模态 content 先摘要再 hash |
|
|
|
|
### 4.3 代码开发规范
|
|
- 模块/类/方法必须有**中文 Docstring**;复杂逻辑用 `# Phase N` 注释组织。
|
|
- 校验分层: 外部输入校验用显式异常(Python `-O` 移除 assert,禁止 assert 承担生产校验);assert 仅用于内部不变量。
|
|
- 类名 `PascalCase`,私有前缀 `_`;导入顺序标准库→第三方→项目内。
|
|
- 日志统一 **loguru**,禁用 `print()`;返回类型用 frozen dataclass。
|
|
- 不考虑向后兼容,直接修改原文件。**例外**: `LLMResponse` 等已被三项目消费的公共类型,字段只增不删不改名(迁移兼容约束,见 ARCHITECTURE.md §5.1)。
|
|
|
|
### 4.4 Git 工作流
|
|
- 一切开发在 feature 分支,严禁直改 main;频繁语义化提交;提交**必须**调用 `commit` skill;大改动前先提交回滚点。
|
|
|
|
### 4.5 配置管理
|
|
- 工程配置走 `pydantic-settings` + `.env`(模板 `.env.example`,敏感项不提交);严禁硬编码默认值;缺失关键配置直接报错。
|
|
- 多源命名约定 `{SCOPE}__{PROVIDER}__{N}__{FIELD}`;韧性参数键名沿用三项目习惯(`LLM_TIMEOUT` 等),降低迁移成本。
|
|
- 装配只有两条路: `GatewayClient.from_env()`/`from_settings()`(工厂)或构造函数全量注入(测试/高级);库内部任何组件不得自读环境变量。
|
|
|
|
### 4.6 测试组织
|
|
- `tests/{unit,integration,e2e}`;真实场景优先(录制的真实网关响应二次构造优于凭空 mock)。
|
|
- 覆盖率目标 80%;并发/韧性行为是一等测试对象: 重试穿透取消、熔断开路半开、限流结算退款、Redis 掉线降级方向、缓存 key 隔离。
|
|
- Redis 相关测试用真实 Redis(integration),不 mock Lua 行为;限流契约测试随实现一起交付(参考 CHSAnalyzer `tests/contracts_limiter.py`)。
|
|
- 涉及真实 LLM 的测试输出结构化 Markdown 至 `tests/outputs/<module>/<test>_<ts>.md`。
|
|
|
|
## 5. 项目结构
|
|
|
|
```text
|
|
project_root/
|
|
├── src/polygateway/ # 库本体(结构见奠基设计 §7: ports/types/errors 内核 +
|
|
│ # middleware/ transports/ backends/ telemetry/ structured/,
|
|
│ # 见 ARCHITECTURE.md §8)
|
|
├── tests/ # unit/integration/e2e + 限流契约测试
|
|
├── reference/ # 三个参考项目(只读,勿改,不提交)
|
|
├── tools/ # 独立工具脚本(不被 import)
|
|
├── scripts/ # 仅 .sh
|
|
├── research-wiki/ # 单一事实源(designs/plans/findings/adrs/reviews)
|
|
├── data/ logs/ # 运行产物,不提交
|
|
└── Makefile / pyproject.toml / .env(.example) / CLAUDE.md
|
|
```
|
|
|
|
> 注: 以上为**目标结构**。当前已落地: `research-wiki/ARCHITECTURE.md`、`reference/`、`.claude/`(18 个 skill 已完成 Fable 5 适配改造 + hooks 硬边界 + settings.json);其余随 M1 里程碑创建(ARCHITECTURE.md §12)。
|
|
|
|
硬性规则: 根目录不得出现 `.py`;`scripts/` 只放 `.sh`;禁止 `helpers/ common/ shared/ misc/ lib/` 目录名;`data/`、`logs/`、`tests/outputs/` 不提交;`reference/` 只读且不入库。
|
|
|
|
## 6. 上下文导航
|
|
|
|
| 需求 | 路径 |
|
|
|---|---|
|
|
| 架构全貌: 决策 D1-D13 及讨论过程、端口清单、错误分类、子系统设计、迁移验收 | `research-wiki/ARCHITECTURE.md`(单一事实源) |
|
|
| 开发顺序与里程碑状态 | `research-wiki/ROADMAP.md`(活文档,随进度更新) |
|
|
| 三项目迁移文档(ARCHITECTURE §11 的展开,库设计的常驻约束) | `research-wiki/migrations/`(govdoc-saas / video-tree-trm5 / chsanalyzer) |
|
|
| 功能设计文档(每次实现新功能时新增) | `research-wiki/designs/` |
|
|
| 实现计划 | `research-wiki/plans/` |
|
|
| 治理网关参考实现 | `reference/Video-Tree-TRM5/adapters/`(llm/breaker/streaming/redis_cache/telemetry) |
|
|
| 分布式限流/熔断参考实现 | `reference/CHSAnalyzer/app/coordination/`(limiter+Lua/provider_gate)与 `app/providers/governance.py` |
|
|
| 错误分类参考 | `reference/CHSAnalyzer/app/domain/errors.py` |
|
|
| OCR 两端点参考 | `reference/Video-Tree-TRM5/adapters/ocr.py` 与 `reference/CHSAnalyzer/app/providers/invokers.py:408-552` |
|
|
| 第一次抽库尝试(教训与蓝本) | `reference/GovDoc-SaaS/packages/docagent-core/` |
|
|
|
|
## 7. 输出规范
|
|
- 所有输出**中文**;文档优先表格/伪代码/Mermaid;禁止超 15 行代码块入文档、禁止连续超 5 条碎片列点;设计 ≤400 行、计划 ≤1000 行、报告 ≤300 行。
|
|
- **例外**: `research-wiki/ARCHITECTURE.md` 不受行数限制——它的准绳是"后来的 AI/人类无需还原原始讨论即可准确理解全部决策及理由",宁详勿略(详细 ≠ 琐碎:记录论证与取舍,不堆砌实现细节)。
|
|
|
|
## 8. Skill 使用规则
|
|
|
|
> [!CRITICAL]
|
|
> **Skill 的 description 即触发边界。** 下表标注 **MANDATORY** 的情形是硬门(设计人类门、合并前测试证据门、合并前独立验证门、commit 格式),不得跳过;其余情形按 description 边界自判——自判看任务实质(规模/风险/是否触及公共承诺),不是省事。任何 skill 流程不得引入任务外的重构或抽象。优先级: 用户显式指令 > Skill 详细流程 > 本文件宏观规则。
|
|
|
|
| Skill | 触发边界 |
|
|
|-------|---------|
|
|
| `brainstorming` | **MANDATORY**: 公共 API/端口签名/架构边界/新子系统变更;其余自判 |
|
|
| `writing-plans` | **MANDATORY**: 里程碑级/跨多文件功能;小改动自判 |
|
|
| `test-driven-development`(测试结果门) | **MANDATORY**: 合并前——行为变更须有先失败后通过的测试证据 |
|
|
| `verification-before-completion`(独立验证) | **MANDATORY**: 声称完成/合并前;里程碑级须派全新上下文 verifier subagent |
|
|
| `commit` | **MANDATORY**: 提交代码时 |
|
|
| `requesting-code-review` / `receiving-code-review` | **MANDATORY**: 合并/PR 前 / 收到审查反馈后;中途审查自判 |
|
|
| `systematic-debugging` | 遇到 bug、测试失败、异常行为时(根因先于修复) |
|
|
| `structured-logging` | 功能会产生运行时数据时 |
|
|
| `subagent-driven-development` | 执行大型已批准计划时的**可选**执行器(内含合并前一次整分支审查) |
|
|
| `finishing-a-development-branch` | 实现完成且测试通过,准备集成时 |
|
|
| `using-git-worktrees` | 需要并行/隔离的分支开发时 |
|
|
| `research-wiki` / `graphify` | 管理知识库时 / 已建图后的代码结构检索 |
|
|
| 科研类: `harness-eval` `idea-creator` `novelty-check` `research-lit` | 惰性资产,现阶段不用,由模型按任务实际需要启用 |
|