From e18cb268a6d60fac9ddc325021e72381f0bcaeca Mon Sep 17 00:00:00 2001 From: 732642856 <732642856@qq.com> Date: Sun, 28 Jun 2026 09:51:24 +0800 Subject: [PATCH] Add layered finance label outputs --- ...adjudicator_sixth_pass_audit_2026_06_28.md | 183 ++++++++++++++++++ mcp_server.py | 11 ++ tests/test_mcp_strict_workflow_finance.py | 8 + 3 files changed, 202 insertions(+) create mode 100644 docs/research/wealth_adjudicator_sixth_pass_audit_2026_06_28.md diff --git a/docs/research/wealth_adjudicator_sixth_pass_audit_2026_06_28.md b/docs/research/wealth_adjudicator_sixth_pass_audit_2026_06_28.md new file mode 100644 index 00000000..3b78f83f --- /dev/null +++ b/docs/research/wealth_adjudicator_sixth_pass_audit_2026_06_28.md @@ -0,0 +1,183 @@ +# Wealth Adjudicator Sixth-Pass Audit (2026-06-28) + +> 目标:把财富裁决输出从“单标签”推进到 `dominant_label + secondary_context` 的最小兼容骨架。 + +--- + +## 1. 本轮完成了什么 + +此前财富 adjudicator 的输出结构核心是: + +- `score` +- `verdict` +- `payout_label` + +这已经足够支撑基本回归,但有一个明显局限: + +> 一次财富事件往往不只是一种标签, +> 它常常还有“主导标签之外的辅助上下文”。 + +本轮没有贸然重做整套输出,而是采用最小兼容升级: + +### 新增字段 + +- `dominant_label` +- `secondary_context` + +### 保持兼容字段 + +- `payout_label` +- `verdict` + +也就是说,旧调用方不会立刻坏掉, +但新链路已经开始拥有更细颗粒的裁决表达层。 + +--- + +## 2. 当前输出行为 + +### 2.1 弱窗口 + +输出: + +- `payout_label = None` +- `dominant_label = None` +- `secondary_context = []` + +含义: + +- 现在不仅知道“不该贴标签” +- 还明确知道“没有主导标签,也没有辅助上下文” + +### 2.2 公众财富身份窗口 + +输出: + +- `payout_label = public_wealth_status` +- `dominant_label = public_wealth_status` +- `secondary_context = ["career_status", "gains_wishes"]` + +含义: + +- 主导事件类型是公众财富身份 +- 但它同时被事业可见度和收益网络支撑 + +### 2.3 收益爆发窗口 + +输出: + +- `payout_label = income_growth` +- `dominant_label = income_growth` +- `secondary_context = ["wealth_family"]` + +含义: + +- 主导事件类型是收益增长 +- 辅助上下文仍然带着财富承诺/财富家族层 + +--- + +## 3. 为什么这一步值钱 + +这一步的价值不在于“多了两个字段”,而在于: + +### 3.1 开始把财富裁决从“单答案”推进到“分层答案” + +以前: + +- 系统只能说:这更像 `income_growth` + +现在: + +- 系统可以说:主导是 `income_growth` +- 但背后还有 `wealth_family` 的辅助上下文 + +这就是从“单标签命中”走向“有语义层次的裁决”。 + +### 3.2 为后面的 `dominant label + secondary context` 正式版打地基 + +本轮只是最小骨架: + +- 没有上复杂 schema +- 没有强推多标签评分器 +- 没有改老 verdict/payout 的兼容层 + +但它已经把最重要的迁移路径打通了: + +> 旧结构还能活, +> 新结构已经开始长。 + +--- + +## 4. 当前仍然保守的地方 + +本轮虽然新增了表达层字段,但仍然保持克制: + +1. `dominant_label` 目前基本与 `payout_label` 同步 +2. `secondary_context` 还只是轻量字符串列表 +3. 没有引入复杂的 secondary 权重排序 +4. 没有让多标签表达反向改写 `verdict` + +这说明当前推进仍然遵守一个很好的节奏: + +- 先让接口骨架存在 +- 再让语义层次出现 +- 最后才考虑让它影响更多推理层 + +--- + +## 5. 本轮和前五轮的关系 + +### 前五轮解决了 + +- 护栏 +- 标签分流 +- Promise 自动折叠 +- 来源自动折叠 +- 来源分散度轻量入分 + +### 第六轮解决了 + +- 输出表达层终于不再只有单标签 + +所以当前财富 adjudicator 已经开始同时拥有: + +1. `promise folding` +2. `source folding` +3. `source weighting` +4. `label layering` + +这说明它已经不再只是“规则列表 + 条件分支”, +而是真的在长成一个有结构的 adjudication engine。 + +--- + +## 6. 下一轮最值钱的动作 + +按现在的 ROI,下一轮最值钱的依然是: + +1. 接一个**轻量、真实、可回归**的 `Yogi` promise hook +2. 让 `dominant_label + secondary_context` 开始吃到 `Yogi` 这类辅助语义 +3. 再决定是否要引入更强的 secondary context 排序或分层 + +--- + +## 7. 本轮状态判断 + +本轮可以诚实宣称: + +- 财富 adjudicator 输出层已经从单标签推进到分层标签骨架 +- 新字段 `dominant_label + secondary_context` 已进入主链 +- 旧字段 `payout_label + verdict` 仍然兼容,没有破坏既有链路 + +但还不能宣称: + +- 多标签财富裁决已经完全成熟 +- `dominant_label` 与 `payout_label` 已彻底解耦 +- secondary context 已具备复杂排序语义 + +更准确的说法是: + +> 财富 adjudicator 已进入第六阶段: +> 不仅会折叠 promise 和来源,还开始以分层输出的方式表达裁决结果。 +> 这让系统第一次具备了“主导标签 + 辅助上下文”的基本形状。 diff --git a/mcp_server.py b/mcp_server.py index f5e1d667..a0c84c04 100644 --- a/mcp_server.py +++ b/mcp_server.py @@ -228,18 +228,29 @@ def _derive_event_judgement(route: str, present: Dict[str, Any], missing: List[s else: verdict = "insufficient_evidence" payout_label = None + dominant_label = None + secondary_context: List[str] = [] gains_score = _convergence_score(present.get("gains_convergence")) wealth_score = _convergence_score(present.get("wealth_convergence")) career_score = _convergence_score(present.get("career_convergence")) if gains_score >= 60 and wealth_score < 40 and career_score < 40: payout_label = "income_growth" + dominant_label = "income_growth" + secondary_context = ["wealth_family"] if present.get("wealth_convergence") else [] elif public_wealth_lift and score >= 60: payout_label = "public_wealth_status" + dominant_label = "public_wealth_status" + if present.get("career_convergence"): + secondary_context.append("career_status") + if present.get("gains_convergence"): + secondary_context.append("gains_wishes") return { "event_family": "finance", "score": score, "verdict": verdict, "payout_label": payout_label, + "dominant_label": dominant_label, + "secondary_context": secondary_context, "primary_drivers": [ key for key in ( "wealth_convergence", diff --git a/tests/test_mcp_strict_workflow_finance.py b/tests/test_mcp_strict_workflow_finance.py index bf07c0a2..68da21a8 100644 --- a/tests/test_mcp_strict_workflow_finance.py +++ b/tests/test_mcp_strict_workflow_finance.py @@ -23,6 +23,8 @@ def test_finance_public_wealth_label_requires_at_least_moderate_window() -> None assert judgement["score"] == 40 assert judgement["verdict"] == "weak_window_needs_confirmation" assert judgement["payout_label"] is None + assert judgement["dominant_label"] is None + assert judgement["secondary_context"] == [] def test_finance_public_wealth_label_can_lift_visible_wealth_cases() -> None: @@ -42,6 +44,8 @@ def test_finance_public_wealth_label_can_lift_visible_wealth_cases() -> None: assert judgement["score"] == 60 assert judgement["verdict"] == "moderate_probability_window" assert judgement["payout_label"] == "public_wealth_status" + assert judgement["dominant_label"] == "public_wealth_status" + assert judgement["secondary_context"] == ["career_status", "gains_wishes"] def test_finance_prefers_income_growth_when_gains_outrun_public_status_signals() -> None: @@ -60,6 +64,8 @@ def test_finance_prefers_income_growth_when_gains_outrun_public_status_signals() assert judgement["score"] == 80 assert judgement["verdict"] == "moderate_probability_window" assert judgement["payout_label"] == "income_growth" + assert judgement["dominant_label"] == "income_growth" + assert judgement["secondary_context"] == ["wealth_family"] def test_finance_strong_wealth_promise_can_unlock_public_wealth_status() -> None: @@ -86,6 +92,8 @@ def test_finance_strong_wealth_promise_can_unlock_public_wealth_status() -> None assert judgement["score"] == 60 assert judgement["verdict"] == "moderate_probability_window" assert judgement["payout_label"] == "public_wealth_status" + assert judgement["dominant_label"] == "public_wealth_status" + assert judgement["secondary_context"] == ["career_status", "gains_wishes"] def test_finance_source_diversity_adds_small_bump_without_changing_verdict_band() -> None: