Files
PolyGateway/CLAUDE.md
T

13 KiB

CLAUDE.md

[!URGENT] 实验室内部通用基础库(生产级、非 MVP、零业务假设)

  1. 本项目是被多个科研/生产项目依赖的,不是应用:稳定性、并发性、防御性、可观测与测试不可为"简单"让步(YAGNI 仍适用,但不削减健壮性)。库的 bug 会同时击穿所有下游项目。
  2. 你的所有思考过程和回复必须使用 简体中文

1. 项目元数据

  • 核心目标: PolyGateway = 统一的大语言模型(LLM/VLM/OCR,音频预留)调度与中转库。治理单位是一次模型调用:请求封装、多源多账号、限流、错误分类与重试、熔断、Redis 响应缓存、流式看门狗、遥测(含成本)、结构化输出策略。全组件端口化可插拔。
  • 架构权威文档: research-wiki/ARCHITECTURE.md(架构单一事实源,含 D1-D14 决策及讨论过程、子系统设计、三项目迁移验收标准;不受 400 行设计文档限制,以无歧义传达既有讨论为准绳)。开发顺序见 research-wiki/ROADMAP.md;research-wiki/designs/ 仅存放每次实现具体功能的设计文档。
  • 参考项目: reference/ 下三个项目是本库的需求来源与代码蓝本(只读,勿改;M4 起"只读"指工作区文件与 main 检出不变——迁移实施经 git worktree~/Projects/m4-worktrees/ 的 feature 分支进行,worktree 的 git 操作会写 reference/*/.git 元数据,属预期);库必须能按 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 且禁用日志缓存。

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. 项目结构

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.mdreference/.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-D14 及讨论过程、端口清单、错误分类、子系统设计、迁移验收 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/
用户文档站(Gitea Wiki,Diátaxis 四区)结构/更新时机/写作纪律 research-wiki/docs-convention.md;发版或公共行为变更必须按其 §2 清单同步 wiki 与 CHANGELOG,版本 bump 提交不得裸发
治理网关参考实现 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.pyreference/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 惰性资产,现阶段不用,由模型按任务实际需要启用