From ce10881eb08fdce4dae19faf3f52e4be93a93fe0 Mon Sep 17 00:00:00 2001 From: iomgaa Date: Thu, 1 Oct 2026 23:03:51 -0400 Subject: [PATCH] docs: archive preserved wiki records and register hedge nodes --- CLAUDE.md | 18 ++++++++++++++---- research-wiki/ROADMAP.md | 6 +++--- research-wiki/graph/edges.json | 17 +++++++++++++++++ research-wiki/index.md | 8 +++++++- research-wiki/log.md | 3 +++ .../plans/2026-09-11-streaming-stall.md | 2 +- 6 files changed, 45 insertions(+), 9 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index cb59b1e..8a19b99 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,10 +2,12 @@ > [!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 被它们迁移接入,否则即边界缺口。 @@ -35,11 +37,13 @@ make ci # 只读验证(check + test) > **同一理由适用于长跑命令**: 需要后台跑时(如全套件测试),命令末尾**不得接管道**,否则退出码失真;要判完成用 `wait`/轮询 PID,不要用会匹配到自身的 `pgrep -f "<完整命令串>"`。 ### 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**: 不做任务外的重构、抽象与"顺手清理"。 @@ -47,6 +51,7 @@ make ci # 只读验证(check + test) ## 4. 核心规则 ### 4.1 核心原则(按优先级) + - **P1 YAGNI**: 不写当前用不到的代码;但并发控制、防御校验、可观测埋点、错误隔离与测试是"当前需要",不在削减之列。 - **P2 高可读性**: 领域术语命名;注释解释"为什么"。 - **P3 单一职责**: 一句话说不清职责(需要"和")= 拆分。 @@ -58,7 +63,7 @@ make ci # 只读验证(check + test) ### 4.2 库铁律(本项目特有,违反即 bug) | 铁律 | 内容 | -|---|---| +| --- | --- | | 零业务假设 | 库内禁止出现任何下游业务领域词汇(视频/文书/超声等)与业务 fixtures;扩展点一律 Protocol | | 纯 asyncio 中立 | 无全局状态、无框架假设、无模块级单例;同一 `GatewayClient` 在 arq worker 与裸脚本中行为一致 | | 取消可穿透 | `asyncio.CancelledError` 永不捕获吞没;重试循环、限流等待、流式读取全部可被取消;in-flight 资源在 finally 释放 | @@ -69,6 +74,7 @@ make ci # 只读验证(check + test) | 无缓存毒化 | 缓存 key 必含 model + messages 摘要 + 命名空间/租户 + salt;多模态 content 先摘要再 hash | ### 4.3 代码开发规范 + - 模块/类/方法必须有**中文 Docstring**;复杂逻辑用 `# Phase N` 注释组织。 - 校验分层: 外部输入校验用显式异常(Python `-O` 移除 assert,禁止 assert 承担生产校验);assert 仅用于内部不变量。 - 类名 `PascalCase`,私有前缀 `_`;导入顺序标准库→第三方→项目内。 @@ -76,6 +82,7 @@ make ci # 只读验证(check + test) - 不考虑向后兼容,直接修改原文件。**例外**: `LLMResponse` 等已被三项目消费的公共类型,字段只增不删不改名(迁移兼容约束,见 ARCHITECTURE.md §5.1)。 ### 4.4 Git 工作流 + - 一切开发在 feature 分支,严禁直改 main;频繁语义化提交;提交**必须**调用 `commit` skill;大改动前先提交回滚点。 ### 4.4.1 发布流程(每步都是历史欠账换来的,不得跳步) @@ -87,7 +94,7 @@ make ci # 只读验证(check + test) 按顺序执行,**构建之前**必须先改完所有文档: | # | 动作 | 要点 | -|---|---|---| +| --- | --- | --- | | 1 | **更新 README** | 打包会把当时的 README 固化进 sdist,**发布后再改就来不及了**(包里那份永远是旧的)。逐项核对: 安装命令的版本约束(`==1.1.*` 这类**极易漏改**,漏了下游就被锁在旧版)、能力表是否覆盖新行为、数字型断言是否仍成立(如遥测字段数,须用 `inspect.signature` 实测而非凭记忆) | | 2 | CHANGELOG 定版 | "未发布" → `## X.Y.Z(日期)` | | 3 | 版本号 | `pyproject.toml` + `src/polygateway/__init__.py` 两处必须一致 | @@ -106,11 +113,13 @@ Gitea 包 registry 是 **owner 级**(`/iomgaa/-/packages/`)不是仓库级;PyPI 发布验证补充(2026-09-09 实测):私有索引不镜像 setuptools,下载 sdist 时 pip 即使带 `--no-deps` 仍可能尝试安装构建依赖;已具备构建工具的 conda 环境可加 `--no-build-isolation`,仍须核对下载来源与散列。包关联 POST 本次返回400,但匿名包页面和认证 GET 包 API 均证实已关联目标仓库;**400本身不算成功,也不能直接推断已关联**,必须读取实际 `repository.full_name` 与页面链接。包 API 可能要求认证(匿名401),页面仍应匿名亲查;不要为重试关联先解绑现有正确关系。 ### 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`)。 @@ -140,7 +149,7 @@ project_root/ ## 6. 上下文导航 | 需求 | 路径 | -|---|---| +| --- | --- | | 架构全貌: 决策 D1-D14 及讨论过程、端口清单、错误分类、子系统设计、迁移验收 | `research-wiki/ARCHITECTURE.md`(单一事实源) | | 开发顺序与里程碑状态 | `research-wiki/ROADMAP.md`(活文档,随进度更新) | | 三项目迁移文档(ARCHITECTURE §11 的展开,库设计的常驻约束) | `research-wiki/migrations/`(govdoc-saas / video-tree-trm5 / chsanalyzer) | @@ -154,6 +163,7 @@ project_root/ | 第一次抽库尝试(教训与蓝本) | `reference/GovDoc-SaaS/packages/docagent-core/` | ## 7. 输出规范 + - 所有输出**中文**;文档优先表格/伪代码/Mermaid;禁止超 15 行代码块入文档、禁止连续超 5 条碎片列点;设计 ≤400 行、计划 ≤1000 行、报告 ≤300 行。 - **例外**: `research-wiki/ARCHITECTURE.md` 不受行数限制——它的准绳是"后来的 AI/人类无需还原原始讨论即可准确理解全部决策及理由",宁详勿略(详细 ≠ 琐碎:记录论证与取舍,不堆砌实现细节)。 @@ -163,7 +173,7 @@ project_root/ > **Skill 的 description 即触发边界。** 下表标注 **MANDATORY** 的情形是硬门(设计人类门、合并前测试证据门、合并前独立验证门、commit 格式),不得跳过;其余情形按 description 边界自判——自判看任务实质(规模/风险/是否触及公共承诺),不是省事。任何 skill 流程不得引入任务外的重构或抽象。优先级: 用户显式指令 > Skill 详细流程 > 本文件宏观规则。 | Skill | 触发边界 | -|-------|---------| +| ------- | --------- | | `brainstorming` | **MANDATORY**: 公共 API/端口签名/架构边界/新子系统变更;其余自判 | | `writing-plans` | **MANDATORY**: 里程碑级/跨多文件功能;小改动自判 | | `test-driven-development`(测试结果门) | **MANDATORY**: 合并前——行为变更须有先失败后通过的测试证据 | diff --git a/research-wiki/ROADMAP.md b/research-wiki/ROADMAP.md index 9b7f663..b9fd4a2 100644 --- a/research-wiki/ROADMAP.md +++ b/research-wiki/ROADMAP.md @@ -13,7 +13,7 @@ ## 1. 总览与状态 | 阶段 | 内容 | 接入方 | 状态 | -|---|---|---|---| +| --- | --- | --- | --- | | P0 奠基 | 调研、ARCHITECTURE.md、CLAUDE.md、skill Fable 5 改造、hooks 硬边界、脚手架(git/pyproject/Makefile/conda 环境/CI 绿) | — | ✅ 完成(2026-07-20) | | M1 核心 | 内核类型 + httpx transport + 治理中间件(内存后端)+ 多源多账号 + 缓存 + SQLite 遥测 + 结构化输出 + from_env | GovDoc、Video-Tree | ✅ 完成(2026-07-20;239 测试全绿、覆盖 92%、真实网关+真实 Redis 验收通过、独立 verifier 问题清零;见 designs/2026-07-20-m1-core-design.md 状态行) | | M2 分布式 | Redis 限流/熔断后端、多源 × Redis 联合验证、背压、Postgres 遥测、成本、Embedding(Q3)、压测 harness | CHSAnalyzer(治理) | ✅ 完成(2026-07-21;契约双后端全绿 + 时间语义真实等待变体 10/10、跨连接联合验证、CHS 对标十项打钩、P3 真实验收 300 次双进程七不变量 PASS、独立 verifier 0 Critical 且 Important 清零;见 designs/2026-07-20-m2-distributed-design.md 与 findings/m2-verifier-fixes.md。压测收官: P5 故障混编 40 次八不变量 PASS,P6 首跑 58.1% 暴露三大治理盲区(findings/2026-07-21-p6-soak-baseline.md)→ **M2.5 治理韧性**六轮迭代(双通道熔断/健康选源/AIMD/429 免预算/健康门槛降权/连败抑制)后同场景 **98.96%**、八不变量全 PASS,验收见 findings/2026-07-21-m25-acceptance.md 与 designs/2026-07-21-m25-resilience-design.md) | @@ -25,7 +25,7 @@ **内部开发顺序**(编号即依赖顺序,同号可并行): | 步 | 内容 | 顺序理由 | -|---|---|---| +| --- | --- | --- | | 1 | `types.py` + `errors.py` + `ports.py` 全量设计与冻结 | 原则 2:公共承诺先行;这是 M1 设计文档(人类门)的主体 | | 2a | `streaming.py` 看门狗移植 | 原则 4:纯函数,零依赖,直接移植+补测 | | 2b | `providers.py` 注册表 | 叶子模块;transport 的前置(思考流字段声明;thinking 注入的**决策**已于 issue #16/#17 搬到 `thinking.py`,这里只留形态声明) | @@ -75,6 +75,6 @@ ## 7. 开放决策依赖 | 决策 | 阻塞点 | 需拍板时间 | -|---|---|---| +| --- | --- | --- | | Q1 打包分发(git+ssh vs 内网 index) | 不阻塞开发,阻塞 M4 发布 | M4 前 | | Q3 Embedding 是否纳入 | ~~影响 M2 范围~~ **已拍板纳入 M2**(2026-07-20) | ✅ 已决 | diff --git a/research-wiki/graph/edges.json b/research-wiki/graph/edges.json index d0bbe77..2bb45e0 100644 --- a/research-wiki/graph/edges.json +++ b/research-wiki/graph/edges.json @@ -240,6 +240,16 @@ "id": "review:2026-10-01-issue29-cache-review", "label": "保真缓存审查修复与1.4.0准备", "type": "review" + }, + { + "id": "plan:2026-09-10-24-hedged-requests", + "label": "issue #24 长尾对冲请求与裸生成时间实施计划", + "type": "plan" + }, + { + "id": "design:2026-09-10-24-hedged-requests-design", + "label": "长尾对冲请求(issue #24)设计", + "type": "design" } ], "links": [ @@ -508,6 +518,13 @@ "relation": "informs", "evidence": "统一缓存与transport的有效产物判据,保持内核依赖边界", "added": "2026-10-01T18:27:16.434742+00:00" + }, + { + "source": "plan:2026-09-10-24-hedged-requests", + "target": "design:2026-09-10-24-hedged-requests-design", + "relation": "implements", + "evidence": "计划头部与设计 §9 批准状态(2026-09-10 H1-H8 全数获批)", + "added": "2026-09-10T16:48:37.849653+00:00" } ] } \ No newline at end of file diff --git a/research-wiki/index.md b/research-wiki/index.md index 2672b77..22f0f3b 100644 --- a/research-wiki/index.md +++ b/research-wiki/index.md @@ -1,8 +1,9 @@ # Research Wiki 索引 -> 自动生成,更新时间:2026-10-01 18:27 UTC +> 自动生成,更新时间:2026-10-02 02:23 UTC ## design (47) + - [1.3.4 推理意图与测试证据设计](designs/2026-09-09-134-thinking-contracts-design.md) `design:2026-09-09-134-thinking-contracts-design` - [2026-07-20-m1-core-design](designs/2026-07-20-m1-core-design.md) `design:2026-07-20-m1-core-design` - [2026-07-20-m2-distributed-design](designs/2026-07-20-m2-distributed-design.md) `design:2026-07-20-m2-distributed-design` @@ -52,6 +53,7 @@ - [采样参数透传设计(issue #4)](designs/sampling-params.md) `design:sampling-params` ## finding (22) + - [1.3.4 推理契约验证与发布准备](findings/2026-09-09-134-thinking-contracts-validation.md) `finding:2026-09-09-134-thinking-contracts-validation` - [1.3.5 T2/T3/T4 验收证据:36 列遥测、失败终态、PG 存储兼容与变异矩阵](findings/2026-09-09-135-call-observability-validation.md) `finding:2026-09-09-135-call-observability-validation` - [1.3.5 发布完成与外部验收:合并后门、registry 产物与页面亲查](findings/2026-09-09-135-release-completion.md) `finding:2026-09-09-135-release-completion` @@ -76,6 +78,7 @@ - [推理开关与 reasoning_tokens: 供应商实测与业界做法](findings/2026-08-02-thinking-switch-and-reasoning-tokens.md) `finding:2026-08-02-thinking-switch-and-reasoning-tokens` ## plan (42) + - [1.3.4 推理契约实施计划](plans/2026-09-09-134-thinking-contracts.md) `plan:2026-09-09-134-thinking-contracts` - [1.3.5 逻辑调用统计与结构化失败诊断实施计划](plans/2026-09-09-135-call-observability.md) `plan:2026-09-09-135-call-observability` - [1.3.6 可选调用期限与取消结算修复实施计划](plans/2026-09-10-136-call-deadline.md) `plan:2026-09-10-136-call-deadline` @@ -120,6 +123,7 @@ - [采样参数透传实现计划(issue #4)](plans/sampling-params-plan.md) `plan:sampling-params-plan` ## review (6) + - [2026-09-11-138-branch-review](reviews/2026-09-11-138-branch-review.md) `review:2026-09-11-138-branch-review` - [2026-09-11-138-verifier](reviews/2026-09-11-138-verifier.md) `review:2026-09-11-138-verifier` - [2026-09-11-streaming-stall-design-review](reviews/2026-09-11-streaming-stall-design-review.md) `review:2026-09-11-streaming-stall-design-review` @@ -128,8 +132,10 @@ - [整分支审查: issue #14 熔断等待档](reviews/issue14-branch-review.md) `review:issue14-branch-review` ## schema (1) + - [表结构: llm_calls(遥测 36 字段)](schemas/llm-calls.md) `schema:llm-calls` ## metric (2) + - [OCR 治理调用成功率与错误分类分布](metrics/ocr-call-success.md) `metric:ocr-call-success` - [每次调用必录覆盖率(含缓存命中/失败/取消)](metrics/call-telemetry-coverage.md) `metric:call-telemetry-coverage` diff --git a/research-wiki/log.md b/research-wiki/log.md index 44c492b..4de5a99 100644 --- a/research-wiki/log.md +++ b/research-wiki/log.md @@ -160,6 +160,8 @@ - [2026-09-09 13:42 UTC] 重建索引: 100 篇页面 - [2026-09-09 16:49 UTC] 重建索引: 101 篇页面 - [2026-09-09 18:01 UTC] 重建索引: 102 篇页面 +- [2026-09-10 16:48 UTC] 新增边: plan:2026-09-10-24-hedged-requests --implements--> design:2026-09-10-24-hedged-requests-design +- [2026-09-10 16:48 UTC] 重建索引: 107 篇页面 - [2026-10-01 17:52 UTC] 新增 design: OpenAI消息保真设计 (design:2026-10-01-issue29-openai-fidelity-design) - [2026-10-01 17:52 UTC] 新增 plan: OpenAI消息保真实现计划 (plan:2026-10-01-issue29-openai-fidelity) - [2026-10-01 17:52 UTC] 新增边: plan:2026-10-01-issue29-openai-fidelity --implements--> design:2026-10-01-issue29-openai-fidelity-design @@ -168,3 +170,4 @@ - [2026-10-01 18:24 UTC] 新增 review: 保真缓存审查修复与1.4.0准备 (review:2026-10-01-issue29-cache-review) - [2026-10-01 18:27 UTC] 新增边: review:2026-10-01-issue29-cache-review --informs--> design:2026-10-01-issue29-openai-fidelity-design - [2026-10-01 18:27 UTC] 重建索引: 120 篇页面 +- [2026-10-02 02:23 UTC] 重建索引: 120 篇页面 diff --git a/research-wiki/plans/2026-09-11-streaming-stall.md b/research-wiki/plans/2026-09-11-streaming-stall.md index 4a63804..f0b57e8 100644 --- a/research-wiki/plans/2026-09-11-streaming-stall.md +++ b/research-wiki/plans/2026-09-11-streaming-stall.md @@ -228,7 +228,7 @@ generation_sink.append((wall_ms, stall_ms_i, stall_count_i)) | --- | --- | | loader | `_load_hedge`(:745-769)扩读 `STALL_AFTER_S`:`_first` + `_cast` + `ensure_call_deadline`(origin 传实际命中键名),返回字典加 `"hedge_stall_after_s"` 键;未设 = None(关闭) | | 字段 | `GatewaySettings` 加 `hedge_stall_after_s: float \| None = None`;`_validate_hedge`(:382-392)扩传 | -| 守卫(全部落进 `check_hedge_assembly` :772-849,签名加 keyword-only `stall_after_s` 参;**返回契约钉死(审查 B2)**:返回 `tuple[float | None, float | None]` = (归一化 after_s, 归一化 stall_after_s),`config.py:384` 与 `client.py:252` 两处调用点随之解构,`test_config.py:1174/:1184` 列入 T4 同步清单(`is None` 断言按新返回形态改写);**两阈值皆 None 才早退**——"同 `after is None` 早退形态"字面执行会让仅 stall 配置绕过守卫②③④,禁止) | ①值域 = `ensure_call_deadline` 同款(有限正数);②`stall_after_s ≥ min over sources of (inter_token_timeout_s or timeout_s)`(有效最小值,与 openai_compat.py:573 回落同款)→ **ValueError**(对冲窗永不开,装配期直接拒绝;stall 场景无非流式残留收益,warning 论证不足,N5);③`stall_after_s ≥ call_deadline_s`(两者皆设)→ ValueError(与 `after_s` 同款,config.py:825-828 邻域);④单源 scope 设阈值 → warning 允许(1.3.7 §5 同款);⑤**B4**:Embedding/OCR scope 装配 warning 落 `EmbeddingSettings.__post_init__`(:865-869 邻域)与 `OcrSettings`(新增 `__post_init__`):内嵌 gateway 的 `hedge_after_s` **或** `hedge_stall_after_s` 非 None → warning"对冲键仅对 chat scope 生效,本 scope 非流式静默退化"(1.3.7 `AFTER_S` 同病顺带补齐,缺陷修复不扩公共面);chat 侧装配 warning 明确不做(per-call stream,装配期无信号,B4 裁决) | +| 守卫(全部落进 `check_hedge_assembly` :772-849,签名加 keyword-only `stall_after_s` 参;**返回契约钉死(审查 B2)**:返回 `tuple[float | None, float | None]`= (归一化 after_s, 归一化 stall_after_s),`config.py:384` 与 `client.py:252`两处调用点随之解构,`test_config.py:1174/:1184`列入 T4 同步清单(`is None` 断言按新返回形态改写);**两阈值皆 None 才早退**——"同 `after is None` 早退形态"字面执行会让仅 stall 配置绕过守卫②③④,禁止) | ①值域 = `ensure_call_deadline` 同款(有限正数);②`stall_after_s ≥ min over sources of (inter_token_timeout_s or timeout_s)`(有效最小值,与 openai_compat.py:573 回落同款)→ **ValueError**(对冲窗永不开,装配期直接拒绝;stall 场景无非流式残留收益,warning 论证不足,N5);③`stall_after_s ≥ call_deadline_s`(两者皆设)→ ValueError(与 `after_s` 同款,config.py:825-828 邻域);④单源 scope 设阈值 → warning 允许(1.3.7 §5 同款);⑤**B4**:Embedding/OCR scope 装配 warning 落 `EmbeddingSettings.__post_init__`(:865-869 邻域)与 `OcrSettings`(新增 `__post_init__`):内嵌 gateway 的 `hedge_after_s` **或** `hedge_stall_after_s` 非 None → warning"对冲键仅对 chat scope 生效,本 scope 非流式静默退化"(1.3.7 `AFTER_S` 同病顺带补齐,缺陷修复不扩公共面);chat 侧装配 warning 明确不做(per-call stream,装配期无信号,B4 裁决) | | client | `GatewayClient.__init__` 加 `hedge_stall_after_s: float \| None = None` keyword-only,:252-257 守卫调用扩传;RetryMW 构造(:264-283)传 `stall_after_s=` 归一化值(取守卫返回二元组第二元,B2);`from_settings`(:525 邻域)透传 | ### 3.6 T4:retry 编排改动(P2 唯一实现形态)