XIJIAN DOCS

推荐子系统 TDD

技术设计:双引擎算法/特征流水线/C-C 飞轮/校准回滚 · ← 返回文档中心

目录
1. 定位与边界2. 评分引擎设计3. 估价引擎设计4. 特征流水线5. C/C 飞轮机制(三期主体,本文出地基)6. 归因链路(漏斗数据从哪来)7. 运行形态8. cfg 键清单9. P1-6 任务映射与实现顺序10. 开放问题与上游缺口附:信息来源变更记录

达人推荐子系统技术设计(TDD)

版本:v1 草案 | 2026-08-17 | 作者:backend-dev | 状态:待主会话评审(评审通过后才出表设计迁移与代码,本文只出设计)

上游输入:《推荐子系统 PRD》v1.1(docs/product/xijian-recommend-prd.md,产品定义)|《推荐子系统业务册》v1.1(docs/business/xijian-recommend-biz.md,SOP 评分卡/分档/一票否决)| 基线 v2.1 §2/§5.1/§5.2/§5.3/§6.13/§7.1/§7.4/§12A(唯一口径源)| docs/dev/influencer-schema-design.md(特征的表来源)| docs/dev/jixing-api-notes.md(集星字段与四坑)| docs/dev/msgbridge-contract.md §2.1/§2.5(批次归因)| docs/xijian-architecture.md §4/§5/§9(架构约束)| 代码实况 server/app/domains/influencers/grade.pydomains/jixing/enrich.pyapp/scheduler.pydomains/config_center/cache.py

纪律声明:本文不定义任何口径数字。凡判定阈值/权重/比例一律指向 cfg 键(§8)并注基线出处;SOP 未给到子项分值的地方,本文只出打分框架,分值标「初值待运营校准,走 cfg」。


1. 定位与边界

1.1 本文覆盖

评分引擎(五维映射/硬门槛短路/证据 schema/沉底与探索位,P1-6.4)| 估价引擎(双锚/距离分段/输出结构/冷启动,P1-6.5)| 特征流水线(快照库与标签库 schema 草案/刷新策略/指纹去重,P1-6.1~6.3)| C/C 飞轮(权重版本/校准批次/度量/切换回滚——三期主体,P1 只建表与报表)| 归因链路(wcid→邀约→报名→履约,P1-6 + P1-11.2 接口点)| 运行形态(进程内计算论证/调度清单/性能实测)。

1.2 本文不覆盖(边界,不动摇)

1.3 与已落地代码的衔接点(不重复发明)

已落地 推荐域怎么用
influencers/grade.py::evaluate/recompute 分级结果(excellent/low_recommend)与 recommend_penalty_reason(P0 已写)是排序输入,不是评分维度
grade_evidence 结构(含 cfg_snapshot 评分证据 JSON 同构扩展(§2.4):证据带判定时读到的 cfg 值,供事后追溯
influencer.recommend_index / _at P0 建好的占位列(恒 NULL),本子系统是其唯一写入方(清单生成后回写归一化分,值变才写)
jixing/enrich.py(fingerprint 值变才写) 批量特征刷新直接复用,不重写集星链路;METRIC_FIELDS 指纹手法照搬到特征表
douyin_account_metric.quotation_min/max_fendouyin_account.resident_city_code 分别是估价行情锚与距离分段/「异地无法拍摄」门槛的现成输入(集星直供)
influencer_binding.wcid / batch_id 归因链路现成落点(契约 §2.1),不新增接口
app/scheduler.py::@scheduledconfig_center/cache.py::cfg job 用装饰器登记不改装配点;阈值唯一入口,占位 "待确认" 原样返回字符串绝不转 0(短路先例见 grade.py

2. 评分引擎设计

2.1 总流程(短路优先,省算力也省误导)

候选池(scope.outreach_scope 过滤旁类)
 → ① 轨道门槛 track_gate(粉丝/等级/招募价,按轨)→ ② 一票否决 hard_gates(命中即 blocked,不再算分)
 → ③ 五维打分(逐维出 score/status/证据)→ ④ 汇总 raw/coverage/normalized/tier
 → ⑤ 强制规则(配合度<6 或黑名单 → 不作主选)→ ⑥ 排序(blocked 出列 → sunk 沉底 → 分数降序)
 → ⑦ 探索位插入(cfg 比例,可复现随机)→ ⑧ 逐人挂建议价(§3)
 → ⑨ 落 recommend_batch / recommend_item + 特征快照(§4)

2.2 SOP 五维 → 特征映射表

满分列 = SOP 100 分表(基线 §5.3:定位 20 / 内容 30 / 数据健康 30 / 商业匹配 10 / 配合度 10),落 cfg recommend.weights.<track> 三套模板(PRD §4.2 三轨独立)。子项分值 SOP 未给,全部走 recommend.subscore.<dim> 的分段规则表,初值待运营校准。

维度 满分 子项特征 来源(表列 / API 字段) 计算式 一期状态
数据健康度 30 中位数播放 | 播放波动 | 断更 视频序列(P1-6.3 中台)|降级源 douyin_account_metric.video_avg_vv(集星 talent_video_avg_vv median(vv_30d) 落分段表 | MAD(vv)/median(vv) 越低越稳 | now − last_publish_at + 近 90 天最大间隔 ✅ 自动(降级需标注,见下)
涨粉趋势 douyin_account.fans_count自累积时间序列(§4.2) Δfans_30d;无历史点 → insufficient_data ⚠️ 冷启动 3 个月内不可算
退款率 | 刷量信号 中台 v_aftersale_detail(P1-6.2)| 互动均值 video_avg_like/comment/share_cnt ÷ video_avg_vv 达人维度退款额/成交额 | 互动率离群 → 扣分 + 触发 gate 标记 ⏳ 待中台 | ✅ 自动(粗判)
内容质量与稳定性 30 可复制结构/出镜稳定/制作质量 豆包视频模型(抽样:爆款/普通/低播放各 3,PRD §4.1) AI 初判分 pending_ai(二期)
定位清晰度 20 主页与内容一致性、一句话定位 豆包(二期)|一期代理:categories 集中度 + tags 一致性 代理分默认不计入(cfg 开关默认关) pending_ai(二期)
用户与商业匹配 10 品类匹配 | 地域 | 粉丝画像(二期) categories/primary_category vs 任务品类 | resident_city_code vs 项目地 code | 集星 fans_tag_list 命中主/次/不命中 三档 | 同城/省内/跨省 三档(同 §3.4 距离口径) ✅ 自动(画像项 ⏳ 二期)
达人配合度 10 催发响应时长 | 交稿准时率 | 人工 1–10 分 消息台触达→回复间隔 | 商单域 SLA(基线 §4)| fulfillment_label.cooperation_score(业务册 §06 待业务确认) 分段 | 达标次数/总次数 | 直接映射 ⚠️ 首次合作 → pending_human,明示「待人工」;已履约项待 P0-5/P1-7

降级源的坑(必须标注在证据里):SOP 要的是中位数播放,集星只给稿均(均值)播放。均值被爆款拉高,与 SOP 的抗噪意图相反——一期用降级源时,证据项必须写 source.degraded=true, note="集星稿均,非中位数",且该子项的分段表用独立 cfg 子键,序列到位后切换不影响历史快照可比性(快照存的是当时的 feature_version)。

2.3 一票否决硬门槛(短路实现)

gate 注册表 recommend/scoring/gates.py,每条 gate 返回 pass | blocked | manual | unknown 四态。unknown 绝不当 pass(数据源未接入不等于没问题,PRD §03 舆情源仍「评估中」)。

# gate code 业务册 §03 措辞 PRD §4.1 措辞 一期实现 判定输入
1 category_conflict 定位冲突 品类冲突(自动 pass) 自动 blocked categories ∩ 任务品类 = ∅
2 unstable_appearance 不稳定出镜 无出镜(自动 pass) unknown → 转人工核 二期视频理解
3 suspected_fake_traffic 疑似刷量 刷量疑似(自动标记人工核) 半自动 → manual 互动率离群信号(§2.2);二期加评论区人机判别
4 violation_risk 违规风险 违规舆情(源接入后自动) unknown(舆情源评估中)
5 capacity_missing 承接条件缺失 意愿与承接条件(人工核对项) manual
6 ⚠️冲突项 拒绝复盘 云剪短片号 不实现,标待确认 上游两份材料第 6 条不一致(见 §10 G1)
7 offsite_infeasible —(PRD §03 数据基建行提及「异地无法拍摄自动判」) 同左 cfg 开关默认 距离 > recommend.offsite_gate_max_km,待运营给值

2.4 证据结构(参照 grade_evidence 先例)

一分一证据,落 recommend_item.evidence(JSON)。schema 草案:

{ "schema":"recommend.evidence.v1", "track":"effect",  // brand|effect|group
  "weight_version_id":12,        // champion 权重版本(可回放)
  "feature_version":"feat.v1",   // 特征口径版本(降级源切换时递增)
  "gates":[ {"code":"category_conflict","result":"pass","evidence":{...}},
            {"code":"violation_risk","result":"unknown","note":"舆情源未接入,不视为通过"} ],
  "dimensions":[
    {"code":"data_health","max":30,"score":24.5,"status":"scored","items":[
      {"code":"median_vv","value":12000,"score":8.0,"max":10,
       "rule":"cfg:recommend.subscore.data_health.median_vv_tiers",
       "source":{"type":"metric","field":"douyin_account_metric.video_avg_vv",
                 "fetched_at":"2026-08-17T03:00:00","degraded":true,"note":"集星稿均,非中位数"}} ]},
    {"code":"content_quality","max":30,"score":null,"status":"pending_ai"},
    {"code":"cooperation","max":10,"score":null,"status":"pending_human","note":"首次合作,SOP 明示待人工"} ],
  "raw_score":41.5, "coverage":0.6, "normalized_score":69.2,
  "tier":null, "tier_reason":"coverage 低于 recommend.tier_min_coverage,不给档位",
  "cfg_snapshot":{"recommend.tier_thresholds":{...},"recommend.tier_min_coverage":0.7} }

汇总口径raw = Σ 已评维度得分coverage = Σ 已评维度满分 / 100normalized = raw / coverage分档裁决建议:分档基于 normalized,但 coverage < cfg("recommend.tier_min_coverage")不给档位,只标「证据不足」——不能拿 60 分可评满分里的 45 分冒充 75 档。该阈值初值待运营校准。分档线 85/75/65 有出处(基线 §5.3),走 recommend.tier_thresholds

2.5 沉底、强制规则与探索位

探索候选池 = 过硬门槛 且 coverage < cfg("recommend.explore_coverage_max") 且 未履约
e_min/e_max = round(N * cfg("recommend.explore_slot_ratio_min|max") / 100)   # 强制下限/上限
e    = clamp(e_min, 0, min(e_max, len(候选池)))   # 候选不足可少,但必须回报实际比例
step = max(1, N // (e + 1))                      # 插入位 [step, 2*step, ...],均匀分散不堆尾部
候选池内排序 = 以 md5(f"{batch_id}:{task_id}") 为种子的可复现打散(回放一致)

响应必带 explore_ratio_actual;候选不足导致低于下限时给出显式 note,不静默降配额(基线 §6.13 判据 2)。


3. 估价引擎设计

3.1 双锚公式(PRD §05)

建议上限 suggest_max = min(market_high, income_cap)                   # 取低
建议下限 suggest_min = min(max(base_fee, market_low), suggest_max)
income_cap = P30(预测产出) / (roi_target + 1)                          # roi_target 走 cfg

+1 不是魔法数字:基线 §7.4 定义 ROI = (GMV − 费用) / 费用,要求 ROI ≥ r费用 ≤ GMV/(r+1)。PRD §05 的例子(GMV 3,000、ROI≥2 → 上限 1,000)正是 3000/(2+1)roi_targetcfg("settlement.explore_roi_min")(实探)/cloud_edit_roi_min/live_roi_min,按任务类型选,不另立推荐域自己的达标线

3.2 行情锚(market anchor)

数据来源 取值
自身历史成交价(权重最高,私有真实数据) 新库商单实际成交价 + influencer.last_deal_price_fen;历史部分跨库只读 lynoxi.task_order.actual_earnings(架构 §5.2 三分法) 中位数(low=P25, high=P75)
同层同类分布 fulfillment_labelitem_level + primary_category + track 聚合 P50 / P70
达人自报价(偏高,权重最低,只作上界参考 douyin_account_metric.quotation_min_fen/max_fen(集星 quotations 原样
车马费基础价 距离分段金额 × 层级系数(全走 cfg,见 §3.4) 单值

合成:market_x = Σ wᵢ·xᵢ,权重走 recommend.market_anchor_weights(初值待校准)。样本量不足即降权归零并重新归一n < cfg("recommend.market_anchor_min_samples")),证据记 dropped_sources——不足样本的源静默参与是"用噪声当行情"。

3.3 收益锚(income anchor)

3.4 距离与车马费分段

resident_city_code(集星直供,6 位行政区划码)→ 项目地城市 code(项目域字段;未接入前由请求参数传入)。距离方案三选一:① 城市质心 + Haversine 直线距离(静态 JSON,约 300 城)→ ✅ 一期采用,零外部依赖且精度对"几十公里粒度的分段"足够;② 城市码同城/省内/跨省三档——质心表缺城时的兜底分支;③ 地图 API 驾车距离——❌ 需外部 key 且增外呼,YAGNI。

3.5 输出结构与冷启动降级

{ "schema":"recommend.price.v1", "suggest_min_fen":90000, "suggest_max_fen":110000,
  "binding_anchor":"income",     // 哪把尺子卡住了上限
  "market":{"high_fen":150000,"low_fen":80000,"sources":[...],"dropped_sources":["peer_dist"]},
  "income":{"p30_gmv_fen":300000,"roi_target":2,"cap_fen":100000,"sample_n":7,"fallback_level":1},
  "base_fee_fen":0, "base_fee_status":"unavailable", "confidence":"medium",  // 由样本量与回退级派生
  "quote_fen":150000, "quote_flag":"over_cap", "target_price_fen":110000,    // 「压价至 ¥X 或换人」
  "cfg_snapshot":{...} }

冷启动策略(PRD §10 一期「数据就绪即做」):

情形 输出
无自身成交价,有同层同类样本 行情锚走群体分布,confidence=medium
无任何成交样本,有集星 quotations 只出「行情参考区间」= quotations ∩ 车马费基础价,confidence=low,明示「无历史成交样本」
收益锚样本不足且行情锚也不可用 suggest_* 返回 null + reason,清单显示「暂无建议价」——不编造
base_fee > income_cap(车马费本身超收益上限) 区间退化为单点 + 标 infeasible,提示「需加预算或换人」

4. 特征流水线

4.1 表 schema 草案(P1-6.1 建,本文只出设计)

命名与类型沿用达人域约定(influencer-schema-design.md §0):无 xijian_ 前缀、金额列名带 _fen、比率 DECIMAL(10,4) 标度 0–1、多值 JSON、不建物理 FK。

influencer_feature_current(当前特征,与账号 1:1,值变才写)

account_id BIGINT UNIQUE / window_days SMALLINT(默认 30,与 metric 表同口径)/ median_vv INT / vv_mad_ratio DECIMAL(10,4) / publish_cnt INT / max_gap_days INT / last_publish_at DATETIME / fans_count INT / fans_growth INT NULL(NULL=历史点不足)/ refund_rate、interaction_rate、fake_signal_score DECIMAL(10,4) NULL / item_density INT NULL(接单密度,PRD §03)/ source_map JSON(逐特征来源与degraded标记,证据要用)/ computed_at / fingerprint CHAR(32) / created_at / updated_at

influencer_feature_snapshot(推荐时刻全量快照,append-only)

id / batch_id / influencer_id / account_id / track / features JSON / feature_version / source_map JSON / created_at,唯一约束 uq(batch_id, account_id)

为什么两张表:current 是"最新值"(打分快取,高频刷新、值变才写);snapshot 是"当时值"(回测地基,PRD §07「模型可换,特征快照库是不动产」)。合成一张会逼出"要么丢历史,要么每次刷新都写一行"的两难。快照不可变、不去重、不清理——它是资产不是缓存。

fulfillment_label(履约标签库,护城河本体)

id / order_id UNIQUE / influencer_id / account_id / task_id / track / deal_price_fen / gmv_fen / exposure / roi DECIMAL(10,4) / cpm_fen / refund_rate / is_ghosted / on_time_delivery / response_minutes / cooperation_score TINYINT(1–10 人工) / settled_at / label_version / fingerprint / created_at / updated_at

为什么物化而不是查商单视图:① 回测要冻结口径(商单表会随业务演进改列,标签要按 label_version 稳定);② 跨库聚合(历史单在 lynoxi)成本高;③ 对外产品化时它就是精算数据集(PRD §01A)。写入方 = 商单/结算域的「已结算」事件(P0-5/P1-9),推荐域只读消费。

recommend_batch / recommend_item(清单与决策留痕)

4.2 数据源 → 特征的刷新策略

来源 通道 复用什么 频率与受控集合
集星档案/指标 dls.lynoxi.com(架构 §5.4) 直接复用 jixing/enrich.py(fingerprint 值变才写、四坑已平),只加批量编排 job recommend.feature_refresh,只刷活跃实体layer ∈ (contacted, fulfilled) 或近 recommend.feature_active_window_days 天被推荐过的账号——永不全量扫(轮询三原则)
视频指标序列 中台统一 API 包(P1-6.3,待用户侧统发) app/central.py client 接口未就绪 → 特征置 None + source_map.status="unavailable"绝不填 0;打分侧走 §2.2 降级源
退款率/带货归因 中台 v_aftersale_detail / v_talent_sales_detail(P1-6.2) 同上 同上
履约数据回流 商单「已结算」事件(P0-5 状态机) 事件驱动,非轮询 upsert fulfillment_label + 标记该账号特征失效
涨粉趋势的自造历史 每轮刷新把 fans_count 追加进 influencer_feature_snapshot(快照天然是时间序列) 冷启动期该子项 insufficient_data,不假装有趋势

4.3 指纹去重与值变才写(铁律 3 的落地)


5. C/C 飞轮机制(三期主体,本文出地基)

5.1 权重版本管理

recommend_weight_versionid / track / role(champion|challenger|archived)/ version_no / weights JSON / subscore_rules JSON / derived_from_id / source(seed|challenger|manual)/ promoted_at / retired_at / note / created_by / created_at

每轨同时最多一个 champion + 一个 challenger(MySQL 无部分唯一索引 → 应用层保证 + ix(track, role))。清单必记版本recommend_batch.weight_version_id)让任何历史清单可回放。cfg 里的 recommend.weights.<track> 只是种子默认值;上线后权威值在版本表,cfg 仅在无版本行时兜底(避免两份真相)。

5.2 校准批次

recommend_calibration_batchid / track / batch_no / window_start / window_end / champion_version_id / challenger_version_id / metrics JSON / sample_size / verdict(challenger_win|champion_win|inconclusive)/ applied_action(promote|rollback|none)/ created_at

5.3 效果度量(PRD §09 指标的可计算定义)

指标 计算式 数据来源
TopN 采纳率 count(rank ≤ N and decision='adopted') / N recommend_item
采纳者达标率 采纳者商单达标数 / 采纳者商单数 fulfillment_label + 结款达标 cfg(基线 §7.4)
人工直选对照组 该场次商单中不在任何 recommend_item.decision='adopted' 集合内的达人 天然对照(PRD §06)
按建议价成交达标率 suggest_min ≤ 实际成交价 ≤ suggest_max(用快照价,非当前重算价)者的达标率 vs 整体 recommend_item.price_suggestion + 商单
建议价偏差 abs(建议价中值 − 实际成交价) 分布的收敛趋势 同上
探索位命中率 is_explore=true 且最终达标者占比 跟踪即可,不设目标

显著性护栏:任一指标样本 < cfg("recommend.metric_min_samples")verdict=inconclusive,不下结论、不触发晋升/回滚(小样本噪声当信号是飞轮最容易犯的错)。季节作控制变量:按 window 同期对比,不跨季节直接比(PRD §08 分布漂移刹车)。

5.4 自动切换、回滚与限速

challenger 生成: ① 逐维 clamp 到 champion ± cfg("recommend.weight_change_limit_pct")(已有键,20)
                ② 归一化到总分 100  ③ 归一后二次校验,仍越界 → 拒绝该 challenger 并记原因
晋升: 连续 K 批 challenger_win 且 cfg("recommend.auto_promote_enabled")=1 → promote(旧版 archived)
回滚: 质量指标跌破 rollback_line → 自动回退上一版
告警: 连续回滚 ≥ cfg("recommend.rollback_alert_streak") → 冻结自动晋升 + 告警(人只在异常时介入)
审计: 每次 promote/rollback 一条 audit(action=recommend.weights.promote/rollback),走既有 audit()

步骤 3 的坑值得单独测:先 clamp 再归一是常见做法,但归一会把被压制维度的份额转嫁给其他维度,可能反而突破 ±20% 限速——必须二次校验,否则"限速"形同虚设。 shadow-first 同构recommend.auto_promote_enabled 默认 0(只影子跑批、只出报表),与 msgbridge 三态门同一纪律——自动改权重是"重大影响结果的决策"(基线 §9.1 第 2 条)。


6. 归因链路(漏斗数据从哪来)

recommend_batch + recommend_item ─▶ 人工圈定(decision=adopted/skipped+可选原因,基线 §6.13 判据 4)
 ─▶ ②A 定向邀约(P1-11.2,人工确认后发起;契约 §2.1 的 send-miniprogram 返回 wcid,
     server 存 wcid ↔ (batch_id, influencer_id),不新增任何接口)
 ─▶ 达人点卡片 ─▶ wcid 回流(架构 §6.2)─▶ influencer_binding.wcid/batch_id(P0 已建列)
 ─▶ 报名意向 ─▶ 商单(P0-5)─▶ 履约 ─▶ fulfillment_label(§4.1③)
漏斗段 数据来源 现状
推荐 → 采纳 recommend_item.decision 本子系统建
采纳 → 邀约送达 msgbridge 审计事件 msgbridge.invite.*(记 scene/batch_id/influencer_id/wcid,契约 §2.1) 契约已定
邀约 → 报名 → 履约达标 influencer_binding.wcid/batch_id → 商单状态机 → fulfillment_label P0 列已建;P0-5 / P1-9

与 P1-11.2 的接口点(必须对齐,否则漏斗断在这一段):邀约批次需要能反查推荐批次。建议 ①邀约批次表加列 source_recommend_batch_id,或 ②统一批次号命名 rec:<recommend_batch_id>(msgbridge 的 note 已用 xijian:<batch_no> 作幂等标记,天然可承载)。推荐方案 ①(显式列,可索引),②作为消息台侧的可读兜底。此项需在 P1-11.2 开工前确认。


7. 运行形态

7.1 进程内计算(无独立服务、无向量库、无特征平台)

量级实测(本机 Python 3.12,纯 Python 五维 × 每维 5 子项分段查表 + 证据对象构造):N=1,000 → 9.9 ms;N=6,660(当前达人量级,上游口径)→ 76.4 ms;N=20,000(达人广场采集 19,299 行量级,基线 §8 实测)→ 264.6 ms(单人 10–13 μs)。

结论:打分不是瓶颈,取数才是(一次批量拉 1e4 行特征表约数百 ms)。单次清单生成 p95 < 2s 完全可达,无需异步化、无需独立算分服务。

7.2 APScheduler 任务清单(@scheduled 注册表模式,不改 app/scheduler.py

job 触发 频率 cfg 受控集合 无活跃实体时
recommend.feature_refresh interval recommend.feature_refresh_minutes 活跃账号(§4.2),分批 recommend.feature_batch_size 零出站
recommend.label_backfill interval 同上(低频档) settled_at 水位游标补齐标签 零写入
recommend.calibration cron recommend.calibration_cron 上一窗口内有结算的批次 直接返回
recommend.challenger_shadow cron 同上(校准后串行) 有 challenger 的轨 直接返回

调度纪律(APScheduler 进程内的两个真坑):① 全部 job 显式 max_instances=1 + coalesce=True——特征刷新慢于间隔时会堆积并发,重复打集星接口触发反爬;② 单进程部署(systemd + uvicorn 单 worker)是当前形态,若将来多 worker 必须只在一个进程起调度器,否则 job 重复执行。写进 job 注册处的注释。


8. cfg 键清单

8.1 已有与复用(不新建,避免两份真相)

8.2 本文新增设计(29 键,P1-6.1 随迁移落,全部注 baseline 出处)

# 键(类型) 默认/状态 出处
1–3 recommend.weights.brand/.effect/.group(json) SOP 五维满分(20/30/30/10/10)为初值,三轨差异待运营校准 基线 §5.3 / PRD §4.2
4–6 recommend.subscore.data_health / .business_match / .cooperation(json) 子项分段规则表,SOP 未给子项分值 → 初值待运营校准 SOP 缺口(§10 G3)
7 recommend.tier_thresholds(json) {primary:85,backup:75,caution:65} 基线 §5.3
8 recommend.tier_min_coverage(float) 待校准:低于此覆盖率不给档位 本文 §2.4 裁决
9 recommend.cooperation_min_score(int) 6(<6 不作主选) 基线 §5.3 强制规则
10 recommend.hard_gates(json) 六条 gate 的启用与模式;第 6 条待确认(§10 G1) 业务册 §03 / PRD §4.1
11 recommend.track_gates(json) 品宣 fans≥200000 / 品效 item_level≥6 / 团购 item_level≥4 + 招募价约束 基线 §5.1 / PRD §4.2
12 recommend.positioning_proxy_enabled(int) 0(一期不用代理分装懂) PRD §01 边界
13 recommend.explore_coverage_max(float) 待校准:探索候选的「数据不足」界线 PRD §4.3
14–15 recommend.market_anchor_weights(json)/ .market_anchor_min_samples(int) 待校准:四源权重与最小样本 PRD §05 / 本文 §3.2
16–17 recommend.income_anchor_window_days / .income_anchor_min_samples(int) 待校准(窗口建议初值 90) PRD §08 / 本文 §3.3
18 recommend.travel_fee_level_coefficients(json) 待运营(与距离分段配套) 基线 §5.3 / §12A
19 recommend.price_band_floor_ratio(float) 待校准:两锚均缺下限时的兜底比例 本文 §3.1
20–21 recommend.distance_source(str,city_centroid)/ .offsite_gate_max_km(int) 前者工程取值;后者待运营(gate 7 默认关) 本文 §3.4 / PRD §03
22–24 recommend.feature_refresh_minutes / .feature_active_window_days / .feature_batch_size(int) 工程取值(受控集合与批量,铁律 3 轮询三原则) 本文 §7.2
25 recommend.auto_promote_enabled(int) 0(shadow-first 同构,自动改权重属重大决策) 基线 §9.1
26–29 recommend.calibration_window_days(int)/ .calibration_cron(str)/ .metric_min_samples(int)/ .rollback_alert_streak(int) 窗口与显著性下限待校准;cron 与告警连击数为工程取值 PRD §06 / §08

计数:新增 29 键(编号 1–29)。其中 14 键无可用初值(4/5/6/8/13/14/15/16/17/18/19/21/26/28)→ 一律以 value="待确认"(str)占位入种子,依赖它的判定短路 + 告警,不编默认值(沿用 recommend.calibration_batch_kgrade.travel_category_whitelist 的先例);#10 键本身有默认值,仅其第 6 条 gate 待确认;#1–3 以 SOP 五维满分为初值(有基线出处),三轨差异待校准。


9. P1-6 任务映射与实现顺序

本文章节 子任务 建议顺序与理由
§4.1 表 schema 草案 P1-6.1 特征快照库 + 标签库设计→评审→迁移 ① 最先。四张表(feature_current/feature_snapshot/fulfillment_label/recommend_batch+item)+ 两张飞轮表(§5.1/5.2)一次评审、一个迁移
§4.2 集星/中台/回流 P1-6.2 数据前置聚合(属地/接单密度/报价/退款率) ② 复用 enrich 链路,工作量最小、解锁最多下游
§2.2 降级源与序列 P1-6.3 视频指标序列接入 可并行但不阻塞:中台 API 未到就走降级源,特征位先留好
§2 全节 P1-6.4 推荐引擎一期 ④ 依赖 6.1~6.3;内部顺序:gates → dimensions → 汇总分档 → 排序沉底 → 探索位
§3 全节 P1-6.5 估价引擎 ⑤ 与 6.4 可并行(只依赖 6.2 的报价/属地);先行情锚(数据现成)后收益锚(依赖标签库)
§2.4 / §3.5 输出结构 P1-6.6 console 清单页 ⑥ 前端依赖本文两个 JSON schema 冻结后开工
§2.5 / §3.1 / §4.3 P1-6.7 契约测试 ⑦ 必测:分档边界(85/75/65 各 ±1)| 探索位比例可配(改 cfg 即变)| 双锚取低(构造 market<income 与 income<market 两例)| 快照落库断言 | cfg 占位短路("待确认" 不转 0)| 佣金不入现金
基线 §6.13 P1-6.8 验收 ⑧ 五条判据逐条实证
§5 全节 三期(P2 排期) 飞轮自动化。P1 期只落版本表 + 快照 + 度量报表(人工看),auto_promote_enabled=0

模块布局(单模块 ≤200 行有效代码,机检):

app/domains/recommend/
├── router.py / schemas.py(清单生成、决策留痕、单人评分卡)| service.py(批次编排:候选→打分→估价→落库)
├── scoring/{engine,gates,dimensions,evidence}.py | pricing/{engine,market_anchor,income_anchor,distance}.py
├── features/{build,refresh,snapshot}.py | flywheel/{attribution,challenger,promote}.py
└── data/city_centroid.json(静态城市质心,§3.4)

10. 开放问题与上游缺口

G1/G2 已裁决(主会话拉 SOP 原文核对,2026-08-17):G1——硬门槛六条以 SOP 原文为准(5=拒绝复盘、6=承接条件缺失),"云剪短片号 pass"属 §4 三分钟初筛规则,作为独立的预筛 gate 类别注册(不占硬门槛六条);PRD 该处归类错误待修。G2——评分表就是五项,"六维"是 §5 数据观察维度(数据健康度 30 分的子观察项),权重模板按五项落地,基线 §5.3 已同步修正。(不自补,报告上游)

# 问题 影响 建议处置
G1 一票否决第 6 条两份材料不一致:业务册 §03 写「拒绝复盘」,PRD §4.1 写「云剪短片号」,其余五条可一一对应 六条 gate 中有一条无从实现 报 product-owner 回查 SOP 原文;未定案前该 gate 不注册,清单标注「硬门槛 5/6 项已判」
G2 「六维」实为五维:基线 §5.3 与 PRD §4.1 均称「六维评分表」,但列出的是 5 项(20+30+30+10+10=100) 命名与实现不符,易误导 要么 SOP 有第六维未转录,要么是措辞误差;权重模板设计成可扩展 map,加维只改 cfg 不改代码
G3 子项分值分配 SOP 未给(如数据健康 30 分里中位数播放占几分) 一期分数的绝对值不可信 框架先落,分值走 cfg 占位;由运营用真实案例校准(建议:拿 10 个已知好/坏达人反推)
G4 车马费距离分段口径未给(travel_fee_distance_tiers 仍是 [])+ 层级系数未给 行情锚缺车马费项 基线 §12A/PRD §10 已列为运营待办;未给前短路为 0 并告警
G5 calibration_batch_k / calibration_rollback_line 占位「待确认」 飞轮无法自动晋升/回滚 三期开工前定案;一期只跑度量报表
G6 配合度记录机制待业务确认(业务册 §06 两件小事:跳过原因、1–10 分) 配合度 10 分维度长期 pending_human 已在业务册请确认清单内,跟踪其答复
G7 邀约批次 ↔ 推荐批次的连接键未定(§6) 漏斗在"采纳→邀约"段断裂 P1-11.2 开工前拍板(建议加显式列)
G8 「6,660 达人」量级为上游口径,本文未实证(基线 §8 实测值是达人广场 19,299 行采集数据) 仅影响性能估算表述 性能结论在 1e3–2e4 全区间成立,不受影响

附:信息来源

变更记录

日期 版本 变更
2026-08-17 v1 草案 首版:双引擎算法设计(五维映射/硬门槛短路/证据 schema/探索位算法/双锚估价/距离方案)+ 特征流水线四表 schema 草案 + C/C 飞轮两表与限速回滚 + 归因链路 + 运行形态实测 + 29 个新 cfg 键 + 8 项上游缺口。未出迁移、未写代码,待主会话评审