fix(strategy): 规则底稿补充列表店铺去重SKU口径与摘要一致

竞争结构节在 shops_from_list.unique_sku_basis 存在时输出对照行,便于策略 LLM 与人工复核;新增单测。

Made-with: Cursor
This commit is contained in:
hub-gif 2026-04-17 17:33:18 +08:00
parent 1af6aa00a5
commit 1a569ce727
2 changed files with 49 additions and 0 deletions

View File

@ -77,6 +77,25 @@ def _cr_narrative(label: str, cr1: Any, cr3: Any, top: Any) -> str | None:
return f"- **{label}**:头部为「{top_s}」(缺少占比时可结合列表与商详数据补全)。" return f"- **{label}**:头部为「{top_s}」(缺少占比时可结合列表与商详数据补全)。"
def _shop_unique_sku_basis_lines(shops: dict[str, Any]) -> list[str]:
"""
``shops_from_list.unique_sku_basis`` 与竞品报告/摘要一致按去重 SKU 的店铺集中度对照口径
"""
usb = shops.get("unique_sku_basis") if isinstance(shops, dict) else None
if not isinstance(usb, dict) or not usb.get("n_unique_skus"):
return []
u1 = concentration_first_share(usb)
u3 = concentration_top_three_share(usb)
utop = _esc(usb.get("top_label") or "")
if u1 is None or not utop:
return []
return [
f"- **列表侧店铺(按去重 SKU**:共 **{_num(usb.get('n_unique_skus'))}** 个去重 SKU"
f"第一大店铺「{utop}」约占 **{_pct(u1)}**;前三合计 **{_pct(u3)}**。"
"*(与上行「按列表行」可能因同一 SKU 多行曝光而差异;非销量/市占。)*"
]
def _goal_bullet(label: str, user_val: str, placeholder: str) -> str: def _goal_bullet(label: str, user_val: str, placeholder: str) -> str:
v = _esc(user_val).strip() v = _esc(user_val).strip()
if v: if v:
@ -230,6 +249,8 @@ def build_strategy_draft_markdown(
) )
if n_shop: if n_shop:
lines.append(n_shop) lines.append(n_shop)
for uline in _shop_unique_sku_basis_lines(shops):
lines.append(uline)
if n_brand: if n_brand:
lines.append(n_brand) lines.append(n_brand)
if not n_shop and not n_brand: if not n_shop and not n_brand:

View File

@ -105,3 +105,31 @@ class StrategyDraftTests(SimpleTestCase):
) )
self.assertIn("「口感」:子串统计命中约 **501** 次", md) self.assertIn("「口感」:子串统计命中约 **501** 次", md)
self.assertIn("场景「控糖/血糖相关」:约 **305** 条", md) self.assertIn("场景「控糖/血糖相关」:约 **305** 条", md)
def test_shops_unique_sku_basis_rendered(self) -> None:
brief = {
"schema_version": 1,
"keyword": "测试",
"concentration": {
"shops_from_list": {
"first_share": 0.6,
"top_three_combined_share": 0.85,
"top_label": "京东自营",
"unique_sku_basis": {
"first_share": 0.35,
"top_three_combined_share": 0.7,
"top_label": "京东自营",
"n_unique_skus": 120,
},
},
"detail_brand_among_merged": {},
},
}
md = build_strategy_draft_markdown(
job_id=1,
keyword="测试",
brief=brief,
)
self.assertIn("按去重 SKU", md)
self.assertIn("120", md)
self.assertIn("35.0%", md)