Define the five-step ladder (native-schema prevention, repair, shape validation, bounded feedback re-ask, ResultInvalidError) as D14; rewrite section 7.9 accordingly, give the structured parameter its three-tier semantics in the chat() signature, and scope the bounded re-ask outside transport retry and breaker counting.
12 KiB
CLAUDE.md
[!URGENT] 实验室内部通用基础库(生产级、非 MVP、零业务假设)
- 本项目是被多个科研/生产项目依赖的库,不是应用:稳定性、并发性、防御性、可观测与测试不可为"简单"让步(YAGNI 仍适用,但不削减健壮性)。库的 bug 会同时击穿所有下游项目。
- 你的所有思考过程和回复必须使用 简体中文。
1. 项目元数据
- 核心目标: PolyGateway = 统一的大语言模型(LLM/VLM/OCR,音频预留)调度与中转库。治理单位是一次模型调用:请求封装、多源多账号、限流、错误分类与重试、熔断、Redis 响应缓存、流式看门狗、遥测(含成本)、结构化输出策略。全组件端口化可插拔。
- 架构权威文档:
research-wiki/ARCHITECTURE.md(架构单一事实源,含 D1-D14 决策及讨论过程、子系统设计、三项目迁移验收标准;不受 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 命令必须在
PolyGatewayconda 环境中执行(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: 规划与设计
- 涉及公共 API、端口签名、架构边界、新子系统的变更必须调用
brainstorming(产出 2-3 备选方案+权衡)并经人类确认后实施;其余任务自判(判据: 是否改变库对下游的承诺)。动手前查阅research-wiki/(单一事实源)。 - 功能产生运行时数据时必须调用
structured-logging。 - 里程碑级/跨多文件功能编码前必须调用
writing-plans;小改动自判。审核门控: design 走 Claude 自审 → Codex 审 → 人类审;plan 走 Claude 自审 → Codex 审 → 直接执行。
Phase 2: 执行与验证
- 测试结果门: 合并前每个行为变更必须有"先失败后通过"的测试证据(
test-driven-development);bug 修复必带回归测试;不规定中间怎么走。 - 独立验证: 里程碑级/跨多文件/合并前必须派全新上下文的 verifier subagent(
verification-before-completion);任何规模的完成声明都必须逐条对应本会话内的工具输出(证据化声明,禁止虚报)。 - 反 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;频繁语义化提交;提交必须调用
commitskill;大改动前先提交回滚点。
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.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-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/ |
| 治理网关参考实现 | 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 |
惰性资产,现阶段不用,由模型按任务实际需要启用 |