|
|
@@ -0,0 +1,89 @@
|
|
|
+# M3B 内容判定包重写(Excel+JSON) Implementation Brief
|
|
|
+
|
|
|
+状态:本 brief 覆盖「重写 `douyin_content_discovery_rule_pack_v1` 的 input_contract / hard_gates / scorecard / dimensions / decision_reason_codes,使其读 Gemini 字段与 M3A 的 platform_heat」。纯配置(Excel source of truth + JSON 同步),不改 evaluator。删桥接键/砍包归 M3C,测试/回放归 M3D。依赖 M3A 的 `platform_heat` 字段已注入。
|
|
|
+
|
|
|
+## 目标
|
|
|
+
|
|
|
+把内容包从 decode/分类树语言换成 Gemini 语言:硬门槛 = 适合50+/置信度/技术失败;打分 = 相关性60 + 平台热度40(维度满分 + gte 分档,evaluator 无需数值运算);reason_code 换新词表。**因 build_config_from_excel 只值覆盖不建行**,新增对象必须 Excel 行与 JSON 对象**同步新增**,删除对象两边同步删,最终过 config gate 5 闸。
|
|
|
+
|
|
|
+## 现有证据
|
|
|
+
|
|
|
+- 内容包现状:input_contract(253-272,required 含 `pattern_match_result.pattern_recall`/`category_or_element_binding`/`content_audience_profile.age_50_plus_level`);10 hard_gates(274-430);scorecard 3 活跃维(content_audience_profile max50 / interaction_performance max30 / freshness_available max20)+ 6 scoring_rules(432-572);thresholds 70/60/0(574-601);hard_gate_primary_reason_priority(611-620);decision_reason_codes(1390-1462)。
|
|
|
+- M2 产字段(可读):`pattern_match_result.{fit_senior_50plus(bool),fit_confidence(float),relevance_score(float),judge_status(str "ok"/"failed")}`;M3A 产 `content_engagement_metrics.platform_heat(0-1)`。
|
|
|
+- Excel 流程:改值走 `hard_gate_rules`/`scorecard_scoring_rules`/`scorecard_dimensions`/`decision_reason_codes` sheet → `build_config_from_excel.py --write` → gate;**新增/删除对象需 JSON 与 Excel 同步**(build 只 overlay 已存在的 (rule_pack_id, child_id))。
|
|
|
+- evaluator op:eq/gte/lte/in/not_in/is_empty;维度内首条命中、维度间相加。
|
|
|
+- config gate:canonical / excel_json_byte_equal / rule_pack_fk / excel_json_sync / query_prompts,现全 pass。
|
|
|
+
|
|
|
+## 修改范围
|
|
|
+
|
|
|
+- 改 Excel `tech_documents/规则包映射/规则包映射配置表.xlsx`:`hard_gate_rules`、`scorecard_dimensions`、`scorecard_scoring_rules`、`decision_reason_codes` sheet 的对应行(增/删/改)。
|
|
|
+- 改 JSON `product_documents/规则包/douyin_rule_packs.v1.json`:内容包 input_contract / hard_gates / scorecard.dimensions / scorecard.scoring_rules / decision_reason_codes / hard_gate_primary_reason_priority(与 Excel 同步)。
|
|
|
+- (不在本 brief:删桥接键/砍包=M3C;测试=M3D。)
|
|
|
+
|
|
|
+## 不修改范围
|
|
|
+
|
|
|
+- 不改 evaluator、不改 thresholds(70/60/0)、不改 effect_status_mapping、不改 input_contract 的 `source_evidence` 必填(血缘保留)。
|
|
|
+- 不改 walk_strategy / walk_policy(M3C/M4)。
|
|
|
+- 不动其它 4 个 future 包内容(M3C 整砍)。
|
|
|
+
|
|
|
+## 涉及文件 / 函数 / 类(具体改动清单)
|
|
|
+
|
|
|
+**input_contract**(253-272):删 required `pattern_match_result.pattern_recall`、`pattern_match_result.category_or_element_binding`、`content_audience_profile`、`content_audience_profile.age_50_plus_level`;加 `pattern_match_result.fit_senior_50plus`、`pattern_match_result.fit_confidence`、`pattern_match_result.relevance_score`、`content_engagement_metrics.platform_heat`;保留 `content.platform_content_id`/`source_evidence`/`run_context.run_id`。
|
|
|
+
|
|
|
+**hard_gates**(Excel `hard_gate_rules` + JSON 同步):
|
|
|
+- 删 4:`pattern_recall_required`、`category_or_element_binding_required`、`missing_content_portrait`、`age_50_plus_weak`。
|
|
|
+- 新增 3(JSON 加对象 + Excel 加行):
|
|
|
+ - `not_fit_senior`:field `pattern_match_result.fit_senior_50plus`、op `eq`、value `false`、severity `fatal`、action `REJECT_CONTENT`、reason `content_not_fit_senior`。
|
|
|
+ - `low_confidence`:field `pattern_match_result.fit_confidence`、op `lt`、value `0.6`、severity `fatal`、action `REJECT_CONTENT`、reason `content_low_confidence`。
|
|
|
+ - `judge_failed`:field `pattern_match_result.judge_status`、op `eq`、value `failed`、severity `review`、action `KEEP_CONTENT_FOR_REVIEW`、reason `content_judge_failed`。
|
|
|
+- 保留 5:`missing_platform_content_id`、`missing_source_evidence`、`high_risk_content`、`not_safe_for_50_plus`、`missing_platform_author_id`。
|
|
|
+- **前置:给 evaluator 加 `lt` 算子(已核实 evaluator op 集 = eq/gte/lte/in/not_in/is_empty,无 `lt`)。** `fit_confidence<0.6` 必须严格小于(0.6 应放行,`lte 0.6` 会误拒 0.6;浮点边界 hack 如 lte 0.59 不可取)。按 09 拍板"如需新 operator 再小改 evaluator,单独标注":在 `evaluator.py` op 分派处加 `lt`(对称现有 `lte`,`value is not None and actual < value`,约 2 行)+ `test_rule_judgment_hard_gates.py` 加一条 lt 单测(M3D)。**这是 M3 唯一且明确的引擎小改,其余 gate/scoring 全用现有 op。**
|
|
|
+
|
|
|
+**scorecard.dimensions**(Excel `scorecard_dimensions` + JSON):
|
|
|
+- 退役旧 3(content_audience_profile/interaction_performance/freshness_available → runtime_status deprecated、max_score 0)。
|
|
|
+- 新增 2:`relevance`(max_score 60、weight_percent 60、active、evidence_paths `["pattern_match_result.relevance_score"]`)、`platform_heat`(max_score 40、weight_percent 40、active、evidence_paths `["content_engagement_metrics.platform_heat"]`)。
|
|
|
+
|
|
|
+**scorecard.scoring_rules**(Excel `scorecard_scoring_rules` + JSON,删旧 6 增新):
|
|
|
+- relevance 维(field `pattern_match_result.relevance_score`,gte 分档):`score_relevance_high`(gte 0.8→60)、`score_relevance_mid`(gte 0.6→45)、`score_relevance_low`(gte 0.4→25)。(<0.4 无命中→0)
|
|
|
+- platform_heat 维(field `content_engagement_metrics.platform_heat`,gte 分档):`score_heat_high`(gte 0.8→40)、`score_heat_mid`(gte 0.6→30)、`score_heat_low`(gte 0.4→20)、`score_heat_min`(gte 0.2→10)。(<0.2→0)
|
|
|
+
|
|
|
+**decision_reason_codes**(Excel `decision_reason_codes` + JSON):新增 `content_not_fit_senior`/`content_low_confidence`/`content_judge_failed`(is_hard_gate=true,前两 reason_category hard_gate、judge_failed review_needed);旧 `content_pattern_recall_required`/`category_or_element_binding_required`/`missing_content_portrait`/`age_50_plus_weak` 标 status=deprecated(保留定义供历史数据可读,不再被引用);沿用 `content_score_pool/review/reject`/`missing_platform_content_id` 等。
|
|
|
+
|
|
|
+**hard_gate_primary_reason_priority**(611-620):去退役项,加 `content_not_fit_senior`/`content_low_confidence`,保留 missing_platform_content_id/missing_source_evidence/high_risk_content/content_score_reject。
|
|
|
+
|
|
|
+## 数据合同
|
|
|
+
|
|
|
+- hard_gates 引用字段全部存在于 input_contract / bundle(rule_pack_fk 闸校验);新 scoring_rule 的 dimension_key 绑定新 dimensions(fk 校验)。
|
|
|
+- relevance 维满分 60、platform_heat 维满分 40,相加 ≤100;阈值不变 → ≥70 池/60-69 复看/<60 拒。
|
|
|
+- Excel↔JSON 字节相等、canonical、fk 三闸恒过。
|
|
|
+- 退役 reason_code 仍在 catalog(status=deprecated),不被任何 active gate/threshold 引用。
|
|
|
+
|
|
|
+## 实施步骤
|
|
|
+
|
|
|
+1. 先确认 M3A 已注入 `content_engagement_metrics.platform_heat`。
|
|
|
+2. **JSON 与 Excel 同步**编辑(新增对象两边都加、删除两边都删、改值改 Excel):input_contract → dimensions → scoring_rules → hard_gates → decision_reason_codes → priority。
|
|
|
+3. `python scripts/build_config_from_excel.py --write` 重建(确认 JSON 与手加对象一致、canonical)。
|
|
|
+4. `uv run --with openpyxl python scripts/run_config_gate.py` 5 闸全 pass(重点 excel_json_byte_equal + rule_pack_fk)。
|
|
|
+5. (规则单测/回放在 M3D;此处只保证 gate 过 + 包结构合法。)
|
|
|
+
|
|
|
+## 验证命令
|
|
|
+
|
|
|
+```bash
|
|
|
+uv run --with openpyxl python scripts/run_config_gate.py # 5 闸全 pass
|
|
|
+uv run python -c "import json;p=json.load(open('product_documents/规则包/douyin_rule_packs.v1.json'));g=[x['gate_id'] for x in p['rule_packs'][0]['hard_gates']];print('not_fit_senior' in g, 'pattern_recall_required' not in g)" # True True
|
|
|
+uv run python scripts/validate_rule_pack_config.py # fk 一致
|
|
|
+```
|
|
|
+
|
|
|
+## 失败归因
|
|
|
+
|
|
|
+- excel_json_byte_equal 红:新增对象只在一侧(JSON 或 Excel),或值不一致;build overlay 后与 JSON 不字节相等。
|
|
|
+- rule_pack_fk 红:新 gate 的 decision_action 不在 catalog、新 scoring_rule 的 dimension_key 没绑新 dimension、reason_code 未登记。
|
|
|
+- 评分恒 0:scoring_rule field_path 与 M3A 注入路径不符,或 relevance_score 字段名拼错。
|
|
|
+- op 不支持:用了 evaluator 没有的 op(应以实测 op 集为准;`lt` 若无,按拍板小改 evaluator 加 lt + 单测,单独标注)。
|
|
|
+
|
|
|
+## sub-agent 交叉验证要点
|
|
|
+
|
|
|
+- 确认新增/删除对象在 Excel 与 JSON 两边同步、config gate 字节相等过。
|
|
|
+- 确认 relevance(max60)+platform_heat(max40)维度满分方案、gte 分档,未用 evaluator 不支持的运算。
|
|
|
+- 确认旧 4 hard_gates 删除、旧 reason_code 标 deprecated 不被引用、source_evidence 门槛保留。
|
|
|
+- 确认 input_contract 改为读 Gemini 字段 + platform_heat、thresholds/effect_status_mapping 未动。
|