ConsistencyMiddleware 子系统设计
1. 职责定义
ConsistencyMiddleware 承接 ADR-007 supplement 中 S1 子流程(叙事-数字一致性)在工程层的实现。在 FinBayes 骨架(ADR-025)中,它是 ReAct 主回路里 LLM 可主动调用的「叙事-数字一致性自检工具」:LLM 在形成判断的过程中按需调用它,检查 M5 / M6 / M7 的叙事与数字是否自洽;返回的一致性评估作为观测回到主回路,由 LLM 自主决定是否补取证据、调整判断或照常输出。它不是主回路之外、结论发布前强制拦截每条输出的 blocking 校验墙(ADR-007 supplement §2.3)。
具体覆盖:
- 4 失败模式 a/b/c/d:模式 a 远期数字过度外推(Case 5 NVDA 型)/ 模式 b 源端数字缺失(Case A-4 跨市场翻译型)/ 模式 c 叙事-数据脱节(Case 1 transitory 型)/ 模式 d 计量单位 / 会计准则不可比(R-A P1-1 新立项)。
- 正向耦合标签(Case 7 NVDA FY25Q1 型「叙事-数字耦合正向」)—— 合法上调触发,但不豁免 M7 双峰后验输出。S1 不止抓失败:印证方向 + 强度作为正向方向性观察可呈现给用户(见 §3.1 正向呈现)。
- Attention 二阶分支:当
applicability_flags.valuation.level = "not-applicable"时启用(Case 10 meme 型),把「基本面数字 vs 叙事」替换为「attention 数字(funding rate / 链上 / 集中度 / KOL / 微周期阶段)vs 叙事自洽度」。 - 矛盾的处置提示(供主回路 LLM 自主决策):S1 识别出模式 a/b/c,提示 LLM 可加强 M7 偏差识别;模式 a + M5 含远期承诺节点,提示可复查 M5 反身性反馈;任一失败模式,提示可重算 M6 估值双峰区间;模式 d,提示 M6 横向倍数支柱降权 + 不通约下游对照需谨慎;正向耦合 + 远期外推并行,提示可启用 M7b 元认知慢思考。这些是 LLM 收到自检结果后可选的后续动作(在 ReAct 主回路里由 LLM 决定要不要做),不是中间件在主回路外自动施加的强制回算。
- 重复评估的收尾:若 LLM 选择多次自检、矛盾反复出现,以 hash 稳定 / 置信度软收敛 / 矛盾归多模态归档为收尾信号;是否重复评估、评估几次由主回路 LLM 决定(工程上可设一个安全上限防失控,类同主回路的 max_iterations,而非强制必须跑满的固定回路)。
输出 ADR-008 supplement 1.1 契约的 s1 顶层字段(ADR-008 supplement §2.6)。
2. 接口契约
class ConsistencyMiddleware:
def evaluate(
self,
task: Task,
cognition_result_draft: StructuredCognitionResultDraft,
causal_graph: TransmissionGraph,
applicability_flags: ApplicabilityFlags,
posterior_draft: BimodalPosterior,
) -> NarrativeNumberConsistency: ...
def extract_falsification_template(
self,
narrative_text: str,
self_consistency_n: int = 5,
) -> FalsificationTemplate:
"""承接 ADR-007 supplement §2.3 四要素模板:
quantitative_target / time_horizon / observable_source / falsification_threshold
+ self-consistency n=5 投票.
"""
...
def detect_second_order_branch(
self,
applicability_flags: ApplicabilityFlags,
attention_signals: list[AttentionSignal] | None,
) -> AttentionMarketBranch | None:
"""applicability_flags.valuation.level = 'not-applicable' 时返回二阶分支对象,
否则返回 None.
"""
...
def suggest_followups(
self,
s1_result: NarrativeNumberConsistency,
candidate_modules: list[Literal["M5", "M6", "M7", "M7b-meta"]],
) -> list[FollowupSuggestion]:
"""根据 s1 评估结果返回后续动作建议(如『可加强 M7 偏差识别』『可重算 M6 估值区间』)。
这是供 ReAct 主回路 LLM 自主决策的提示,不是中间件自动触发的回算指令。
"""
...
def assess_stability(
self,
iterations: list[StructuredCognitionResultDraft],
safety_cap: int = 8,
) -> StabilityAssessment:
"""LLM 选择多次自检时,评估迭代间是否软收敛(hash 稳定 / 置信度软收敛 / 矛盾归多模态归档)。
safety_cap 是防失控的工程安全上限(类同主回路 max_iterations),不是强制必跑的固定回路次数。
"""
...
NarrativeNumberConsistency / AttentionMarketBranch / BackTrigger / ConvergenceFlag / S1Evidence 子模型字段定义以 ADR-008 supplement §2.6 为事实源;派生 Pydantic schema 见 StructuredCognitionResult 1.1 契约源。s1.evidence.numbers_ref 通过引用 id 指向 10 要素「依据」节点(不复制内容);s1.falsification_ref 通过引用 id 指向 10 要素「失效条件」节点(统一以 10 要素「失效条件」为事实源)。
子模型类型 placeholder(M0 阶段简定义)
接口签名引用的 StructuredCognitionResultDraft 类型在 ADR-008 supplement / 1.1 契约源中尚未独立给出(1.1 契约源 §1 仅锁定 StructuredCognitionResult 终稿类型)。本节给 M0 阶段的最小 Pydantic v2 placeholder,目的仅是让 Codex import 链闭合。字段细节留 M1+ 收紧路径见本子系统 §9 实现里程碑映射 + 后续 milestone-field-evolution-matrix.md 起草;事实源回写发生于 ADR-008 supplement v2 / 1.1 契约源后续 patch 段。
# M0 placeholder 段。M1+ 收紧字段定义;事实源在 ADR-008 supplement v2 / cognition-1.1-contract.md v1.2 时回写。
from pydantic import BaseModel, ConfigDict
class StructuredCognitionResultDraft(BaseModel):
"""M0 placeholder。承载 Evidence + Synthesis 子系统传入的 10 要素初稿 + 机制层 6 字段初稿,
与终稿 `StructuredCognitionResult` 区分;终稿由 ReAct 主回路 LLM 在自检与重决策达成稳态后产出。
"""
model_config = ConfigDict(extra="ignore")
draft_id: str # 草稿唯一 id,用于 LLM 多次自检时 hash 稳定判定
loop_count: int = 0 # LLM 已自检的次数(observability 用),与 §2.6 ConvergenceFlag.loop_count 对齐
payload_blob: dict # 10 要素 + 6 字段初稿的临时 dict,M1+ 收紧为强类型
# 其它字段待 M1+ 锁定
3. 数据流
- 输入源:
- 来自 Evidence + Synthesis 子系统的
StructuredCognitionResultDraft(10 要素初稿 + 机制层结构化输出 6 字段初稿)。 - 来自 KnowledgeGraphService 的
causal_graph/phase_evidence。 - 来自上游机制 M6 的
applicability_flags(三支柱适用性三态枚举)。 - 来自上游机制 M7 的
posterior_draft(双峰后验初稿)。
- 来自 Evidence + Synthesis 子系统的
- 内部处理(8 步工作流,承接 ADR-007 supplement §2.3 S1.1–S1.8):
- S1.1 抽取 M6 数字依据;
- S1.2 抽取 M5 叙事;
- S1.3 抽取 M7 偏差与不确定性;
- S1.4 路由判定(按
applicability_flags.valuation.level); - S1.5 主流程(4 失败模式 + 正向耦合判定);
- S1.6 二阶检测(attention 二阶分支按需启用);
- S1.7 结构化字段输出(
s1.s1_mode可多选 /coupling_direction/coupling_strength/evidence.*/falsification_ref/backtrigger/confidence/second_order_branch/convergence_flag;backtrigger字段记录中间件给主回路的后续动作建议清单,convergence_flag记录 LLM 多次自检时的软收敛评估,二者均供 ReAct 主回路 LLM 自主决策); - S1.8 返回后续动作建议(suggest_followups 给出对 M5 / M6 / M7 / M7b-meta 的可选建议,由主回路 LLM 自主决定是否再调它们)。
- 输出 StructuredCognitionResult 1.1 字段:
s1.s1_mode(可多选枚举:a-far-extrapolation/b-source-missing/c-narrative-data-detachment/d-unit-accounting-incompatible/positive-coupling)。s1.coupling_direction/s1.coupling_strength/s1.confidence。s1.evidence.narratives/s1.evidence.numbers_ref(引用 id,不复制)。s1.falsification_ref(引用 id,不复制)。s1.backtrigger(中间件给主回路的后续动作建议清单,字段名沿用 ADR-008 锁定术语;语义见 §2suggest_followups)/s1.second_order_branch(attention 二阶分支) /s1.convergence_flag(loop_count 记录 LLM 已自检次数 / converged / convergence_method;非强制必跑的固定回路)。
3.1 正向呈现(产出意图 — ADR-013 Build-Y over Prevent-X)
S1 的价值不止「抓出失败」。s1_mode / backtrigger 等是内部审计层标签(surface=internal_audit,给评测 / 复盘 / 主回路后续动作建议用,不直接进用户面);除此之外,S1 必须产出一个正向的方向性观察给用户面(surface=user_widget,翻译为「叙事-数字一致性观察」,见 字段暴露面分层契约 MP-5):
- 印证方向 + 强度:把「叙事与数字是否相互印证、谁带动谁、印证有多强」作为可呈现给用户的方向性观察。事实源是
s1.coupling_direction(narrative-leads-numbers/numbers-lead-narrative/decoupled/positive-coupled)+s1.coupling_strength ∈ [0,1],翻译为产品语言(例:「这次叙事和数字相互印证,且印证较强」/「叙事跑在数字前面,关注是否兑现」)。 - 正向耦合不是 bug:
positive-coupling(Case 7 NVDA FY25Q1 型)是合法的「叙事-数字耦合正向」结果,应明确告知用户「这次对得上」,而非只在脱节时才出声。注意它不豁免 M7 双峰后验输出。 - 定位:正向呈现让用户看清「这份判断的叙事根基稳不稳」,是 S1 的用户价值面;内部 failure mode 标签是同一判断的审计面,两面共用
s1字段,靠 surface 分流,不重复产出新字段(无字段漂移)。
4. 关键依赖
| 依赖类型 | 内容 |
|---|---|
| 外部数据源 | Attention 二阶分支信号(funding-rate / 链上 first-sign / 集中度 / KOL / 微周期阶段)— 接入路径见 ADR-007 supplement §5.3 工程依赖清单 |
| 内部模块 | KnowledgeGraphService(causal_graph / phase_evidence)/ Evidence + Synthesis(StructuredCognitionResultDraft)/ MCAClassifier(桶位影响 attention 信号权重)/ Provider Adapter(self-consistency n=5 投票走 LLM 多次采样) |
| 持久化 | LLM 每次自检的 trace 全量写入审计 trail(loop_count / hash / convergence_method 三段一并落审计,承接架构主稿 §18 可观测性 全量审计 trail 口径) |
5. 测试要求
测试维度对齐 EvalHarness 子系统的 D7(S1 叙事-数字一致性识别)+ D6(偏差识别 + 不确定性量化)。
- 单元测试:
- 4 失败模式 a/b/c/d + 正向耦合标签的二元命中(每个失败模式至少 3 case 正负样本,承接 14 case 反向校准库)。
coupling_strength ∈ [0, 1]/confidence ∈ [0, 1]取值约束。convergence_flag.loop_count取非负整数;工程安全上限对齐assess_stability的safety_cap(默认 8,防失控用,非强制必跑值)。second_order_branch启用条件:applicability_flags.valuation.level = "not-applicable"时必返回非 None;= "applicable"时必返回 None;= "partial"时主流程 + 二阶并行(即返回非 None 但主流程也运行)。
- 集成测试:
- 与 KnowledgeGraphService 联动:
correlation_regime.regime_label = regime-switched触发 attention 二阶分支检查(若 valuation 同时为 not-applicable)。 - 与 EvalHarness 联动:D7 标答强制外部独立源(Damodaran "Narrative & Numbers" + Howard Marks memo + Stratechery + FT Alphaville + NYU Stern 课程库五源),IAA kappa ≥ 0.7 入评测池。
- 自检后续动作:S1 识别模式 c → suggest_followups 返回「可重算 M6 估值区间」建议 → 主回路 LLM 选择再调 M6 后用 ConsistencyMiddleware 重评;hash 稳定 / 置信度软收敛 / 矛盾归多模态归档三种软收敛信号全覆盖(由 LLM 决定是否继续,不依赖固定外部回路)。
- 与 KnowledgeGraphService 联动:
- 评测维度(消费方为 EvalHarness):
- D6 多标签 F1 加权防 top-3 gaming(14 case 历史频率反向加权 + macro-F1 差距 > 0.15 触发复审 + ECE ≤ 0.15)。
- D7 标答来源外部独立 + 14 case 自标降为「内部参考标注」。
- 端到端测试:M0 走通骨架 5 条样例输入的
s1字段录制 → 重放稳定性校验(确保 LLM 重复自检时以 hash 稳定在合理次数内收尾,不依赖外部强制回路)。
6. v1 工程回退
v1 阶段允许半人工标注的字段(承接 Phase 7 半人工标注 SLA 附录 任务 C):
- M7.meta-v1 慢思考触发判定(影响 S1 给 LLM 的 M7b-meta 后续动作建议):reviewer 月度增量 ≤ 5 工作日 SLA / 准确率 ≥ 75% / IAA kappa ≥ 0.70 / 抽样复核 ≥ 30%。
- 可证伪条件抽取的「模板四要素 + self-consistency n=5 投票」结果允许 reviewer 推翻;推翻案例进入 holdout 集。
必须模型自动产出(不允许人工标注覆盖最终值):
s1.coupling_strength(S1 量化判定)。s1.confidence(S1 量化判定)。s1.convergence_flag.loop_count/converged/convergence_method。
7. 待解决问题 / 已知 trade-off
- 重复自检的安全上限与并发语义:S1 自检由主回路 LLM 按需调用、可重复,工程上设一个安全上限防失控(类同主回路 max_iterations,非强制必跑的固定回路)。该上限与综合层并发模型(asyncio.TaskGroup)的关系待架构主稿 §12 并发与异步处理 锁定。
- Attention 二阶分支信号阈值校准:funding-rate / 链上 first-sign / 集中度 / KOL / 微周期阶段五类信号的阈值 v1 用一致默认值,待 Case 10 meme 类 holdout 评测后校准。
s1.evidence.numbers_ref/falsification_ref引用 id 一致性:v1 阶段对引用 id 的全局唯一性由 KnowledgeGraphService 节点 id 兜底,若引用失效(如证据节点被撤回)则 S1 重评;引用失效的具体处理路径(重评 / 降级 / 阻断)待 Phase 7+ 实证后决议。- 正向耦合 + 远期外推并行触发 M7b 慢思考的代价 / 收益:M7.meta-v1 慢思考路径会显著拉高 LLM 调用 token 成本,触发条件 v1 偏保守;实际触发频率 / 成本曲线待 Phase 4 评测压测后调整。
- 模式 d(计量单位 / 会计准则不可比)的判定准确率:R-A P1-1 新立项,14 case 反向校准未充分;v1 起步以「IFRS vs US GAAP / A 股扣非 vs 海外 Non GAAP / 银行股拨备前利润 vs 一般企业净利润 / 保险股内含价值 vs GAAP / 货币与时段口径」5 类显式检测,更细类目留 Phase 7+。
8. 与其它子系统的接口对齐
- KnowledgeGraphService:本子系统消费其
causal_graph+phase_evidence输出;自检后续动作(suggest_followups 含 M5 时)可能建议主回路 LLM 再调 KnowledgeGraphService 重算correlation_regime或调整 M5.5 反向力量召回阈值。 - MCAClassifier:本子系统通过 Task 上的
mca_bucket选择 attention 二阶分支信号权重(如 B5b 散户踩踏桶下 funding rate 权重上调 / B6 跨市场翻译桶下叙事自洽度门槛上调)。 - EvalHarness:本子系统的
s1字段产物按 D7 + D6 评测维度消费;评测产生的失败模式分类退化反向触发 Phase 5 治理流程的子机制级变更(L2 / L3)。 - 既有子系统(Evidence + Synthesis):本子系统是 ReAct 主回路里 LLM 可调用的自检工具;LLM 在判断形成过程中按需调用 evaluate 检查一致性,据结果自主决定是否再调用 M5 / M6 / M7 子任务,而非在结论发布前对每条输出强制过一道横切层。
9. 实现里程碑映射
承接 架构主稿 §29 v1 实现路径建议 与 M0 Walking Skeleton §3.5。
| 里程碑 | 本子系统落地范围 | 不落地(留下个里程碑) |
|---|---|---|
| M0 | s1 顶层字段以 extra="ignore" stub 形式存在(仅 mode + confidence 子字段最小子集);evaluate 接口签名落地,内部返回 fixture 固定模式(不调 LLM、不产生后续动作建议);产物 JSON blob 落入 audit_events.payload | 4 失败模式 a/b/c/d 自动判定、suggest_followups 后续动作建议、二阶 attention 分支、模式 d 5 类显式检测 |
| M1 | s1 升级为 judgment_records 独立索引列;4 失败模式中 a + c 上线自动判定(b + d 仍人工标注);二阶 attention 分支接入但仅在 B5b / B6 桶激活;suggest_followups 限「建议重新调用 M5」单路径 | 失败模式 b(源端数字缺失)的自动召回、失败模式 d 自动判定、跨 M5 / M6 / M7 多路径后续动作建议 |
| M2 | 失败模式 b 自动召回(按 ADR-007 supplement §5.1 v1→v2 路径门槛);suggest_followups 扩展到 M5 / M6 / M7 三路径建议;attention 二阶分支全桶激活 | 失败模式 d 自动判定(仍走人工 IFRS / GAAP 等显式 5 类检测) |
| M3 | 失败模式 d 自动判定上线 + 模式 d 5 类显式检测扩到 Phase 7+ 更细类目;S1 与 EvalHarness D7 的退化追踪流程稳态运行 | 跨工作流的 v2 体系演进项(按 Phase 5 治理流程节奏) |