V10.563 收斂 preview 假可救候選

This commit is contained in:
OoO
2026-06-01 21:43:01 +08:00
parent 94e1967171
commit 3ca0f742f7
5 changed files with 28 additions and 2 deletions

View File

@@ -4,6 +4,7 @@
================================================================================
【已完成】
- V10.563 收斂正式 preview 假可救候選M.A.C 超持妝輕透濾鏡蜜粉若只有 PChome 端出現明確色號(例如 `#絕絕紫`),會標成 `variant_selection_review` 並維持 `true_low_confidence`,不再佔 recoverable 池SAUGELLA 賽吉兒菁萃潔浴凝露新增潤澤 / 日用型 / 加強 / 黃金女郎型變體互斥,避免同品線不同私密清潔款式被誤救成 matched。
- V10.561 補 PChome 比價補強前端分段回饋Dashboard 的 PChome 卡片從「補抓產線」改為「比價補強產線」,按鈕與確認文案同步說明會先刷新舊 identity、再重評近門檻與補抓未配對結果區新增刷新 / 重評 / 補抓三段 matched/total 摘要,避免後端已完成分段統計但操作員仍只看到一個籠統成功數。
- V10.560 串起手動 PChome 比價補強三段式流程:`/api/ai/pchome-match/backfill` 現在不只跑近門檻重評與未配對補抓,也會先用小批次 `run_expired_identity_refresh()` 刷新已知 `identity_v2` 舊價格,讓操作員按一次補強就能同時處理「舊 identity 新鮮度」、「near-threshold low_score」與「pending identity」三條主線。結果 payload 新增 `stale_identity_refresh` 分段統計,方便後續 Dashboard / 簡報 / AI 決策知道覆蓋率改善是來自刷新、重評或補抓。
- V10.559 收斂 retryable 有效身份新鮮度:`_fetch_retryable_candidate_skus()` 不再把 `expires_at IS NULL` 的舊 PChome `identity_v2` 當成有效阻擋條件,只有明確 `expires_at > CURRENT_TIMESTAMP` 的新鮮 identity 才會阻止 near-threshold revalidation。未知新鮮度仍走 V10.551 的 expired / recovery 刷新入口,重評後仍必須通過最新版 matcher、hard-veto、auto write safety 與既有正式候選覆寫保護,避免為了拉覆蓋率犧牲準確率。

View File

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

View File

@@ -13,6 +13,7 @@
## 📅 詳細更新日誌 (考古存檔)
### 2026-06-01PChome 比價新鮮度操作閉環
- **V10.563 正式 preview 假可救候選收斂**: 針對正式 `retryable_candidate_preview` 露出的 M.A.C 蜜粉與 SAUGELLA 菁萃潔浴凝露案例補 guard。M.A.C 單邊明確色號(如 `#絕絕紫`)會進 `variant_selection_review`,維持 `true_low_confidence`SAUGELLA 潤澤 / 日用型 / 加強 / 黃金女郎型互斥,直接 hard veto避免同品線不同私密清潔款式被當成 recoverable low_score。
- **V10.561 PChome 比價補強前端分段回饋**: Dashboard 的 PChome 操作卡改名為「比價補強產線」,手動按鈕與確認文案同步說明三段流程;結果摘要會顯示刷新、重評、補抓各自的 matched/total讓操作員能判斷覆蓋率改善來自舊 identity 新鮮度回補、近門檻 matcher 回刷,或 pending 商品 fresh search 補抓。
- **V10.560 手動 PChome 比價補強三段式串接**: `/api/ai/pchome-match/backfill` 與每日 scheduler 口徑對齊,手動執行時先小批次刷新過期 `identity_v2`,再跑近門檻候選重評,最後補抓高優先未配對商品。回傳結果新增 `stale_identity_refresh` 分段統計,讓後續 Dashboard、簡報與 AI 決策能區分覆蓋率改善來自舊 identity 新鮮度回補、matcher 回刷,還是 fresh search 補抓。
- **V10.559 retryable 有效身份新鮮度收斂**: `_fetch_retryable_candidate_skus()` 的既有 identity 阻擋條件改成只接受 `cp.expires_at > CURRENT_TIMESTAMP`,不再讓 `expires_at IS NULL` 的未知新鮮度舊配對壓住近門檻候選回刷。未知新鮮度仍由 expired identity refresh / recovery 路徑處理,最後寫入仍必須通過現行 matcher、hard-veto、auto write safety 與 stronger existing production match 保護。

View File

@@ -713,6 +713,7 @@ VARIANT_OPTION_COLOR_WORDS = {
"奶茶色",
"豆沙色",
"紫色",
"絕絕紫",
"薰衣草",
"藍色",
"綠色",
@@ -3180,7 +3181,7 @@ def _has_saugella_private_wash_variant_conflict(left: ProductIdentity, right: Pr
and ("saugella" in right_text or "賽吉兒" in right_text)
):
return False
variant_tokens = ("日用", "加強", "黃金女郎型")
variant_tokens = ("日用", "日用型", "加強", "潤澤", "黃金女郎型")
left_hits = {token for token in variant_tokens if token in left_text}
right_hits = {token for token in variant_tokens if token in right_text}
return bool(left_hits and right_hits and left_hits.isdisjoint(right_hits))

View File

@@ -2085,6 +2085,7 @@ def test_marketplace_matcher_rejects_saugella_private_wash_variant_gap():
for momo_name in (
"【SAUGELLA 賽吉兒】菁萃潔浴凝露日用250ml二入組",
"【SAUGELLA 賽吉兒】菁萃潔浴凝露加強250ml二入組",
"【SAUGELLA 賽吉兒】菁萃潔浴凝露潤澤二入組",
):
diagnostics = score_marketplace_match(
momo_name,
@@ -2097,6 +2098,28 @@ def test_marketplace_matcher_rejects_saugella_private_wash_variant_gap():
assert diagnostics.comparison_mode == "not_comparable"
assert "saugella_variant_conflict" in diagnostics.reasons
production_preview = score_marketplace_match(
"【SAUGELLA 賽吉兒】菁萃潔浴凝露潤澤二入組",
"《2入特惠》SAUGELLA賽吉兒 菁萃潔浴凝露【日用型】500ml",
)
assert production_preview.hard_veto is True
assert "saugella_variant_conflict" in production_preview.reasons
def test_marketplace_matcher_keeps_mac_powder_single_shade_as_review():
from services.competitor_price_feeder import _classify_low_score_attempt
from services.marketplace_product_matcher import score_marketplace_match
diagnostics = score_marketplace_match(
"【M.A.C】超持妝輕透濾鏡蜜粉(國際航空版)",
"【M.A.C】超持妝輕透濾鏡蜜粉6.5g #絕絕紫",
)
assert diagnostics.score < 0.76
assert diagnostics.hard_veto is False
assert "variant_selection_review" in diagnostics.reasons
assert _classify_low_score_attempt(diagnostics.score, diagnostics) == "true_low_confidence"
def test_marketplace_matcher_rejects_dr_hsieh_labsmart_vs_repair_serum_line_gap():
from services.marketplace_product_matcher import score_marketplace_match