補強 PChome near-threshold 風險邊界
All checks were successful
CD Pipeline / deploy (push) Successful in 1m11s

This commit is contained in:
OoO
2026-05-29 10:32:54 +08:00
parent e4de72d7d7
commit afa91755c1
5 changed files with 80 additions and 2 deletions

View File

@@ -4,6 +4,7 @@
================================================================================
【已完成】
- V10.486 補 PChome near-threshold 風險邊界NEW DIRECTIONS 甜杏仁油 vs 酪梨油直接 `core_ingredient_line_conflict` hard vetoCOCODOR 經典擴香瓶多款任選 vs generic、KAMERIA 足膜任選三款 vs 單一涼感足膜、Hakugen 白元入浴劑橘盒/綠盒不同變體都保留 `variant_selection_review`,不進可採用 gate。Production 已部署 `/health=V10.486`240 筆 near-threshold audit `gate_pass 83→79`、`identity_veto 0→1`、`still_low 157→160`。測試:`tests/test_marketplace_product_matcher.py`、`tests/test_competitor_match_attempts_persistence.py`、`tests/test_competitor_match_attempt_rescore_audit.py` 通過。
- V10.485 補 NITORI 香氛噴霧器短型號防線read-only near-threshold pilot 找到唯一 gate pass 為 5510 vs J82 LBR不應入隊matcher 現在會把 `J82` 這類短英數型號納入 NITORI diffuser model conflict與 5510 / YX168 等不同型號一樣 hard veto。Production 已部署 `/health=V10.485`120 筆 near-threshold audit 由 `gate_pass=1` 變 `gate_pass=0`accepted audit `scanned=89 / gate_pass=89 / still_low=0`。測試:`tests/test_marketplace_product_matcher.py`、`tests/test_competitor_match_attempts_persistence.py`、`tests/test_competitor_match_attempt_rescore_audit.py` 通過。
- V10.484 拆分 PChome manual gatePOWERMAN 男性私密養護液 30ml、PHYSIOGEL AI 冰鎮精華露 200ml 2入、TS6 緊彈水嫩凝膠 40g、DERMA 寶寶洗髮沐浴露 150/500ml、Clarins 黃金亮眼萃 20ml、Cetaphil 長效潤膚乳 237/473ml 等明確同款可走 `exact / total_price / price_alert_exact`COCODOR 大豆蠟燭單側多款任選改留 `variant_selection_review`Pavaruni 雙側 20 香味蠟燭不受新型錄保護誤傷。Production 曾部署 `/health=V10.484`,並退回 COCODOR 舊 accepted 風險 1 筆。測試:`tests/test_marketplace_product_matcher.py`、`tests/test_competitor_match_attempts_persistence.py`、`tests/test_competitor_match_attempt_rescore_audit.py` 通過。
- V10.483 收斂舊 gate pass 風險NARS 遮瑕蜜任選、LOREAL 玻尿酸啵啵精華水/液態紫熨斗 vs 水光精華、SEBAMED 洗髮乳任選、Schick 舒綺 2-in-1 型號落差、TAICEND 保護膜 vs 噴霧,現在都會保留高分但加 `variant_selection_review` 與專屬 reason不再被 rescore 自動送進 accepted queue。Production 已部署 `/health=V10.483`;目標 5 SKU audit `gate_pass=0 / still_low=5`,並用 `--retract-variant-accepted` 退回 4 筆舊 accepted 變體風險latest accepted audit `scanned=90 / gate_pass=90 / still_low=0`。測試:`tests/test_marketplace_product_matcher.py`、`tests/test_competitor_match_attempts_persistence.py`、`tests/test_competitor_match_attempt_rescore_audit.py` 通過。

View File

@@ -350,7 +350,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
# ==========================================
# 系統版本與路徑
# ==========================================
SYSTEM_VERSION = "V10.485"
SYSTEM_VERSION = "V10.486"
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
public_url = PUBLIC_URL # 用於模板顯示

View File

@@ -82,6 +82,7 @@
- 2026-05-25 21:25 CST 起accepted queue 清潔不再只靠舊 `diagnostic_codes``--retract-variant-accepted` 改為先抓 latest accepted再用當前 matcher 判斷是否需要退回。這能清掉 V10.480 後才被新規則判為 `variant_selection_review` 的舊 accepted。正式最新狀態`true_low_confidence=751``rescore_accepted_current=89``identity_veto=3994``matched=1570``unit_comparable=379`
- 2026-05-25 23:45 CST 起,`V10.484` 拆分 manual gate exact 與型錄風險POWERMAN 男性私密養護液 30ml、PHYSIOGEL AI 冰鎮精華露 200ml 2入、TS6 緊彈水嫩凝膠 40g、DERMA 寶寶洗髮沐浴露 150/500ml、Clarins 黃金亮眼萃 20ml、Cetaphil 長效潤膚乳 237/473ml 等明確同款可走 `exact / total_price / price_alert_exact`COCODOR 大豆蠟燭單側多款任選保留 `variant_selection_review`Pavaruni 雙側 20 香味蠟燭保持 total-price exact。測試`tests/test_marketplace_product_matcher.py``tests/test_competitor_match_attempts_persistence.py``tests/test_competitor_match_attempt_rescore_audit.py` 通過。
- 2026-05-25 23:55 CST 起,`V10.485` 補 NITORI 香氛噴霧器短型號防線near-threshold read-only pilot 中唯一 gate pass 為 5510 vs J82 LBR已判定不該入隊matcher 將 `J82` 這類短英數型號納入 NITORI diffuser model conflict與 5510 / YX168 等不同型號一樣 hard veto。Production 已部署 `/health=V10.485`120 筆 near-threshold audit 由 `gate_pass=1``gate_pass=0`accepted audit `scanned=89 / gate_pass=89 / still_low=0`
- 2026-05-29 起,`V10.486` 補 PChome near-threshold 風險邊界NEW DIRECTIONS 甜杏仁油 vs 酪梨油直接 hard vetoCOCODOR 經典擴香瓶多款任選、KAMERIA 足膜任選三款、Hakugen 白元入浴劑橘盒/綠盒不同變體都保留 `variant_selection_review`,不進可採用 gate。Production 已部署 `/health=V10.486`240 筆 near-threshold audit `gate_pass 83→79``identity_veto 0→1``still_low 157→160`
## 3. 12 Agent 決策信封整合

View File

@@ -2061,6 +2061,9 @@ def score_marketplace_match(
candle_catalog_selection_gap = _has_candle_catalog_selection_gap(left, right)
if candle_catalog_selection_gap:
reasons.append("candle_catalog_selection_gap")
bath_additive_variant_gap = _has_bath_additive_variant_gap(left, right)
if bath_additive_variant_gap:
reasons.append("bath_additive_variant_gap")
makeup_catalog_selection_gap = _has_makeup_catalog_selection_gap(left, right)
if makeup_catalog_selection_gap:
reasons.append("makeup_catalog_selection_gap")
@@ -2081,6 +2084,7 @@ def score_marketplace_match(
or commercial_condition_gap
or relove_private_cleanser_variant_gap
or candle_catalog_selection_gap
or bath_additive_variant_gap
or makeup_catalog_selection_gap
or loreal_serum_variant_gap
or sebamed_shampoo_variant_catalog_gap
@@ -3257,11 +3261,13 @@ def _has_aroma_scent_variant_conflict(left: ProductIdentity, right: ProductIdent
def _has_core_ingredient_line_conflict(left: ProductIdentity, right: ProductIdentity) -> bool:
pair_text = f"{left.searchable_name} {right.searchable_name}"
if not any(term in pair_text for term in ("油膏", "護膚油", "身體油", "精油", "", "乳霜")):
if not any(term in pair_text for term in ("油膏", "護膚油", "身體油", "精油", "基礎油", "按摩油", "甜杏仁油", "酪梨油", "", "乳霜")):
return False
ingredient_groups = {
"coconut_oil": ("椰子油", "coconut"),
"shea_butter": ("乳木果油", "shea"),
"sweet_almond_oil": ("甜杏仁油", "sweet almond"),
"avocado_oil": ("酪梨油", "avocado"),
}
left_groups = {
group
@@ -3556,10 +3562,14 @@ def _has_catalog_specific_variant_selection_gap(left: ProductIdentity, right: Pr
"車用擴香",
"車用擴香蕊",
"香氛擴香罐",
"擴香瓶",
"擴香罐",
"擴香蕊",
"水性指甲油",
"指甲油",
"足膜",
"泡澡入浴劑",
"入浴劑",
"融蠟小夜燈",
"融蠟燈",
"滋養霜",
@@ -3571,6 +3581,25 @@ def _has_catalog_specific_variant_selection_gap(left: ProductIdentity, right: Pr
return left_catalog != right_catalog
def _has_bath_additive_variant_gap(left: ProductIdentity, right: ProductIdentity) -> bool:
pair_text = f"{left.searchable_name} {right.searchable_name}"
if not any(term in pair_text for term in ("入浴劑", "泡澡錠", "泡澡包", "泡澡")):
return False
if not (left.brand_tokens & right.brand_tokens):
return False
left_terms = {
term
for term in ("馨香", "懷舊", "橘盒", "綠盒", "粉盒", "藍盒")
if term in left.searchable_name
}
right_terms = {
term
for term in ("馨香", "懷舊", "橘盒", "綠盒", "粉盒", "藍盒")
if term in right.searchable_name
}
return bool(left_terms and right_terms and not (left_terms & right_terms))
def _has_taicend_baby_spray_equivalence(left: ProductIdentity, right: ProductIdentity) -> bool:
brand_tokens = {"taicend", "泰陞"}
return (

View File

@@ -1246,6 +1246,53 @@ def test_marketplace_matcher_keeps_same_candle_catalog_alignment_as_total_price(
assert "focused_exact_identity_pavaruni_20_scent_candle" in diagnostics.reasons
def test_marketplace_matcher_blocks_different_carrier_oil_core_ingredients():
from services.marketplace_product_matcher import score_marketplace_match
diagnostics = score_marketplace_match(
"【NEW DIRECTIONS】甜杏仁油1000ml+按壓頭1入組(澳洲原裝進口-新方向按摩油保濕油基礎油)",
"【NEW DIRECTIONS】酪梨油1000ml+按壓頭1入組(澳洲原裝進口-新方向按摩油保濕油基礎油)",
)
assert diagnostics.hard_veto is True
assert diagnostics.comparison_mode == "not_comparable"
assert "core_ingredient_line_conflict" in diagnostics.reasons
def test_marketplace_matcher_sends_fragrance_and_foot_mask_catalog_gaps_to_review():
from services.marketplace_product_matcher import score_marketplace_match
cocodor = score_marketplace_match(
"【COCODOR】經典擴香瓶200mlx4入(多款任選/官方直營/韓國香氛)",
"COCODOR 經典擴香瓶200mlx4",
)
kameria = score_marketplace_match(
"【KAMERIA】凱蜜菈 足足稱奇足膜17ml*2枚入(任選三款)",
"Kameria足足稱奇涼感去皮嫩足膜 17ml*2枚入",
)
for diagnostics in (cocodor, kameria):
assert diagnostics.hard_veto is False
assert diagnostics.price_basis == "manual_review"
assert diagnostics.alert_tier == "identity_review"
assert "variant_selection_review" in diagnostics.reasons
def test_marketplace_matcher_sends_bath_additive_box_variants_to_review():
from services.marketplace_product_matcher import score_marketplace_match
diagnostics = score_marketplace_match(
"【日本Hakugen白元】濁湯溫泉之旅炭酸泡澡入浴劑45gx16錠/馨香-橘盒(含4種湯色發泡沐浴劑草本溫泉粉泡澡錠)",
"日本Hakugen白元-濁湯溫泉之旅炭酸泡澡入浴劑-懷舊45gx16錠/綠盒",
)
assert diagnostics.hard_veto is False
assert diagnostics.price_basis == "manual_review"
assert diagnostics.alert_tier == "identity_review"
assert "bath_additive_variant_gap" in diagnostics.reasons
assert "variant_selection_review" in diagnostics.reasons
def test_marketplace_matcher_keeps_kiehls_no1_lip_balm_as_product_line_not_color_number():
from services.marketplace_product_matcher import score_marketplace_match