fix(strategy): 矩阵收窄时 §5.1 集中度注明非列表行口径

strategy_scope_applied 下 concentration 来自分组内合并 SKU;修正店铺/品牌叙事措辞并加口径说明,避免与全关键词列表行混淆。

Made-with: Cursor
This commit is contained in:
hub-gif 2026-04-21 17:25:57 +08:00
parent 44fa291eb3
commit 3f6c750ac4
2 changed files with 77 additions and 5 deletions

View File

@ -48,8 +48,19 @@ def _num(x: Any) -> str:
return str(x)
def _cr_narrative(label: str, cr1: Any, cr3: Any, top: Any) -> str | None:
"""从集中度生成一句策略向描述,无数据则返回 None正文避免英文缩写"""
def _cr_narrative(
label: str,
cr1: Any,
cr3: Any,
top: Any,
*,
first_share_wording: tuple[str, str] | None = None,
) -> str | None:
"""从集中度生成一句策略向描述,无数据则返回 None正文避免英文缩写
``first_share_wording`` ``(第一大句前缀, 前三大句前缀)`` 时覆盖默认措辞用于矩阵收窄口径
避免误写列表行
"""
try:
c1 = float(cr1) if cr1 is not None else None
except (TypeError, ValueError):
@ -57,7 +68,9 @@ def _cr_narrative(label: str, cr1: Any, cr3: Any, top: Any) -> str | None:
if c1 is None and not (top or "").strip():
return None
top_s = _esc(top) or ""
if "店铺" in label:
if first_share_wording is not None:
w1, w3 = first_share_wording
elif "店铺" in label:
w1, w3 = "第一大店铺约占列表行的", "前三大店铺合计约占"
elif "品牌" in label:
w1, w3 = "第一大品牌约占", "前三大品牌合计约占"
@ -480,6 +493,9 @@ def build_strategy_draft_markdown(
conc = brief.get("concentration") or {}
shops = conc.get("shops_from_list") or {}
dbrand = conc.get("detail_brand_among_merged") or {}
scope_ap = brief.get("strategy_scope_applied")
scoped_matrix = isinstance(scope_ap, dict) and bool(scope_ap.get("group"))
gname_scoped = _esc(scope_ap.get("group")) if scoped_matrix else ""
lines.extend(
[
"## 五、与其它品牌有何不同",
@ -488,17 +504,47 @@ def build_strategy_draft_markdown(
"",
]
)
if scoped_matrix:
lines.append(
"*本任务已按矩阵细类收窄:**下列店铺/品牌占比均按该分组内「深入合并 SKU」条数统计**"
"与全关键词 **PC 搜索列表行** 集中度**不是同一口径**;亦非销量或市占。*"
if not for_llm_input
else "*集中度:按所选矩阵分组内合并 SKU 条数;非全站列表行。*"
)
lines.append("")
shop_label = (
f"店铺分布(「{gname_scoped}」内样本 SKU"
if scoped_matrix
else "列表侧店铺集中度"
)
brand_label = (
f"品牌分布(「{gname_scoped}」内样本 SKU"
if scoped_matrix
else "深入样本内品牌集中度"
)
scoped_wording: tuple[str, str] | None = (
("第一大店铺约占该分组样本 SKU 的", "前三大店铺合计约占")
if scoped_matrix
else None
)
scoped_brand_wording: tuple[str, str] | None = (
("第一大品牌约占该分组样本 SKU 的", "前三大品牌合计约占")
if scoped_matrix
else None
)
n_shop = _cr_narrative(
"列表侧店铺集中度",
shop_label,
concentration_first_share(shops),
concentration_top_three_share(shops),
shops.get("top_label"),
first_share_wording=scoped_wording,
)
n_brand = _cr_narrative(
"深入样本内品牌集中度",
brand_label,
concentration_first_share(dbrand),
concentration_top_three_share(dbrand),
dbrand.get("top_label"),
first_share_wording=scoped_brand_wording,
)
if n_shop:
lines.append(n_shop)

View File

@ -161,6 +161,32 @@ class StrategyDraftTests(SimpleTestCase):
self.assertNotIn("子串统计命中约 **501**", md)
self.assertNotIn("场景「控糖", md)
def test_matrix_scope_concentration_not_list_rows_wording(self) -> None:
"""收窄矩阵时 concentration 来自分组内 SKU§5.1 勿写「列表行」。"""
brief = {
"schema_version": 1,
"keyword": "低GI",
"strategy_scope_applied": {"group": "饼干"},
"concentration": {
"shops_from_list": {
"first_share": 0.238,
"top_three_combined_share": 0.571,
"top_label": "碧翠园京东自营旗舰店",
},
"detail_brand_among_merged": {
"first_share": 0.238,
"top_three_combined_share": 0.667,
"top_label": "碧翠园",
},
},
}
md = build_strategy_draft_markdown(job_id=1, keyword="低GI", brief=brief)
self.assertIn("与全关键词 **PC 搜索列表行** 集中度**不是同一口径**", md)
self.assertIn("店铺分布(「饼干」内样本 SKU", md)
self.assertIn("该分组样本 SKU 的", md)
self.assertNotIn("列表侧店铺集中度", md)
self.assertNotIn("第一大店铺约占列表行的", md)
def test_shops_unique_sku_basis_rendered(self) -> None:
brief = {
"schema_version": 1,