V10.579 強化高信心比價安全覆蓋
All checks were successful
CD Pipeline / deploy (push) Successful in 1m8s

This commit is contained in:
OoO
2026-06-04 11:39:33 +08:00
parent 3f528dade3
commit 03d60c202f
8 changed files with 65 additions and 7 deletions

View File

@@ -4,6 +4,7 @@
================================================================================
【已完成】
- V10.579 補 PChome 高信心 total-price safe familySAB 私密防護舒緩噴霧 30ml 與 Herbacin 小甘菊 20ml 護手霜在同款式、同規格、無 variant/commercial gap 時可由 focused matcher 進 `exact / total_price / price_alert_exact`讓近門檻重評能真正寫入正式比價Herbacin 柔皙 vs 野生玫瑰等跨 variant 仍保留在 review不放寬全域門檻。同版將 Code Review GCP-B secondary timeout 預設由 60 秒收斂到 25 秒GCP-A preflight 不通且 GCP-B 生成卡住時更快回 deterministic local degraded不呼叫 Gemini/111。
- V10.578 修正 Code Review 靜態掃描 timeout 誤報Hermes deterministic scan 對 `requests.get/post/...` 會檢查同一呼叫 block 的後續行,多行呼叫已帶 `timeout=` 時不再報「HTTP request 未設定 timeout」。避免 V10.577 的 preflight helper 因多行格式被自己誤判為 MEDIUM。
- V10.577 補 Code Review Ollama host preflightOpenClaw 架構評估在 explicit GCP host generate 前先以短 `/api/version` 探測健康度GCP-A 不通時會快速跳 GCP-B不再等 15 秒 generate timeout仍維持 GCP-A/GCP-B 優先、111 預設禁用、Gemini hard-disabled 預設不呼叫。
- V10.576 補 PChome backfill backlog 的型錄 lane counts讓 `/api/ai/pchome-match/backfill/status` 也能回傳 `catalog_variant_review`、`catalog_unit_review`、`catalog_identity_review` 三條操作隊列;同版修正 `OllamaService.generate(allow_111_fallback=False)`,當 lazy resolver 快取到 111 時會強制改試 GCP-A/GCP-B allowlist不再直接 `all 0 hosts failed`,且仍不把長分析推給 111。

View File

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

View File

@@ -104,6 +104,7 @@
- 2026-05-31 起,`V10.506` 新增市場情報 MCP Fetch Candidate Queue Writer Review Decision Approval gate在 review decision 通過後只審核 operator human approval 摘要,要求 decision linkage、approval identity、target table、row count、dedupe keys、`approved_for_writer_preflight` approval result、decision/approval evidence refs、artifact paths、matched row exact-identity/variant/overwrite guard 與 operator confirmation 對齊;仍不讀 token、不執行 CLI、不開 DB、不寫 approval record、不寫 decision record、不更新 review_state、不寫 match result、不補 queue、不掛 scheduler只放行到後續 writer preflight 設計。
- 2026-05-31 起,`V10.509` 新增市場情報 MCP Fetch Candidate Queue Writer Review Decision Approval Writer Preflight gate在 human approval 通過後只審核 operator writer preflight 摘要,要求 approval linkage、writer_preflight_id、target operation、row count、dedupe keys、approved decision 到 target review_state 的逐列映射、decision/approval/preflight evidence refs、matched row exact-identity/variant/overwrite guard 與 operator boundary仍不讀 token、不執行 CLI、不開 DB、不寫 preflight/approval/decision/match、不更新 review_state、不補 queue、不掛 scheduler只放行到後續 CLI review / run package 設計。
- 2026-06-01 起,`V10.566` 新增市場情報 Professional Source Governance gate將 robots/REP、sitemap/lastmod、JSON-LD / schema.org structured data、canonical URL、rate limit、公開資料邊界、provenance、snapshot hash 與 idempotency key 納入 source contract並接上 `/api/market_intel/mcp_professional_source_governance`、UI preview panel、deployment readiness check 與 production smoke target仍不抓外站、不讀 robots/sitemap、不開 DB、不寫檔、不掛 scheduler。
- 2026-06-04 起,`V10.579` 補 PChome 高信心 total-price safe familySAB 私密防護舒緩噴霧 30ml、Herbacin 小甘菊 20ml 護手霜在同款式同規格且無 variant/commercial gap 時可進 `exact / total_price / price_alert_exact`;跨款式反測仍擋在 review`MIN_MATCH_SCORE` 不變。同版將 Code Review GCP-B secondary timeout 收斂到 25 秒GCP-A/GCP-B 都慢時更快回 local degraded。
- 2026-06-04 起,`V10.578` 修正 Code Review deterministic scan 的 timeout 判定,多行 `requests.*(... timeout=...)` 不再被誤報為未設定 timeout。
- 2026-06-04 起,`V10.577` Code Review OpenClaw 會在 explicit Ollama host generate 前先做短 `/api/version` preflightGCP-A 不通時快速跳 GCP-B避免 15 秒 timeout 後才降級,且仍不呼叫 Gemini / 111。
- 2026-06-04 起,`V10.576` 修正 GCP-only Ollama retrycaller 禁用 111 fallback 時resolver 若回到 111 會改試 GCP-A/GCP-B allowlist不再讓 Hermes / Code Review 類任務因 resolver 快取到 111 而 `all 0 hosts failed`

View File

@@ -13,6 +13,7 @@
## 📅 詳細更新日誌 (考古存檔)
### 2026-06-01PChome 比價新鮮度操作閉環
- **V10.579 PChome 高信心 total-price safe family + Code Review timeout 收斂**: matcher 新增 SAB 私密防護舒緩噴霧 30ml 與 Herbacin 小甘菊 20ml 護手霜的窄範圍 total-price safe 路徑。這些候選仍必須通過既有 score、hard veto、variant/commercial gap 與 overwrite protectionHerbacin 柔皙 vs 野生玫瑰跨 variant 反測維持不進正式價差。目的在不放寬 `MIN_MATCH_SCORE` 的前提下,把可證明同款的高信心 `true_low_confidence` 轉進正式比價覆蓋。同版將 Code Review GCP-B secondary timeout 預設由 60 秒收斂到 25 秒GCP-A preflight 不通且 GCP-B 生成卡住時更快回 deterministic local degraded不呼叫 Gemini/111。
- **V10.578 Code Review 靜態掃描 timeout 誤報修正**: Hermes deterministic scan 對 `requests.get/post/put/delete/patch` 改檢查同一呼叫 block 的後續行,已在多行呼叫中帶 `timeout=` 時不再報「HTTP request 未設定 timeout」。這修掉 V10.577 preflight helper 被 Code Review 自己誤判為 MEDIUM 的噪音。
- **V10.577 Code Review Ollama host preflight**: OpenClaw 架構評估在 explicit GCP host generate 前先以短 `/api/version` 探測健康度;若 GCP-A 從 188 連線 timeout會快速跳到 GCP-B `gemma3:4b`,避免每次等 primary generate timeout。此 preflight 只作用於 Code Review Ollama-first 路徑,仍維持 111 預設禁用、Gemini hard-disabled 預設不呼叫。
- **V10.576 PChome backlog lane 與 GCP-only Ollama retry 修補**: `/api/ai/pchome-match/backfill/status` 的 coverage 與 operation backlog 同步輸出 `catalog_variant_review``catalog_unit_review``catalog_identity_review`,讓 Dashboard 操作建議可直接跳到三條人工隊列。同版修正 `OllamaService.generate(allow_111_fallback=False)`:若 resolver 已快取到 111會改試尚未嘗試的 GCP-A/GCP-B allowlist不再直接 `all 0 hosts failed`,同時仍避免長分析落到 111。

View File

@@ -66,7 +66,7 @@ CODE_REVIEW_OLLAMA_SECONDARY_MODEL = os.getenv(
"gemma3:4b",
)
CODE_REVIEW_OLLAMA_SECONDARY_TIMEOUT = int(
os.getenv("CODE_REVIEW_OLLAMA_SECONDARY_TIMEOUT", "60")
os.getenv("CODE_REVIEW_OLLAMA_SECONDARY_TIMEOUT", "25")
)
CODE_REVIEW_OLLAMA_FALLBACK_MODEL = os.getenv(
"CODE_REVIEW_OLLAMA_FALLBACK_MODEL",

View File

@@ -535,12 +535,18 @@ FOCUSED_IDENTITY_BRANDLESS_REVIEW_REASONS = {
"the_forest_maple_diffuser_flower_brandless",
}
FOCUSED_IDENTITY_BRANDLESS_TOTAL_PRICE_REASONS = {
"herbacin_classic_hand_cream_20ml_brandless",
}
FOCUSED_IDENTITY_TOTAL_PRICE_REASONS = {
"3w_clinic_collagen_foundation_50ml_2pack",
"hanamisui_moisture_original_gel_1_7g_3pack",
"hanamisui_inclear_private_gel_1_7g_3pack",
"hanamisui_relax_lavender_gel_1_7g_3pack",
"the_ordinary_caffeine_egcg_30ml",
"herbacin_classic_hand_cream_20ml_brandless",
"sab_private_spray",
"st_clare_private_mousse_150ml_2pack",
"st_clare_private_mousse_spray_set",
"biopeutic_plus_aha_lotion_20_150ml",
@@ -2239,7 +2245,6 @@ def _classify_match_quality(
)
or (
focused_total_price_safe
and brand_score >= 0.95
and type_score >= 0.55
and score >= 0.86
)
@@ -2582,9 +2587,20 @@ def score_marketplace_match(
)
)
)
focused_total_price_brand_safe = (
brand_score >= 0.95
or (
focused_exact_line_reason in FOCUSED_IDENTITY_BRANDLESS_TOTAL_PRICE_REASONS
and brand_score == 0.55
and bool(left.brand_tokens) != bool(right.brand_tokens)
and spec_score >= 0.85
and token_score >= 0.70
and sequence_score >= 0.55
)
)
focused_exact_total_price_safe = (
focused_exact_line_reason in FOCUSED_IDENTITY_TOTAL_PRICE_REASONS
and brand_score >= 0.95
and focused_total_price_brand_safe
and not hard_veto
and spec_score >= 0.45
and token_score >= 0.30

View File

@@ -226,7 +226,7 @@ def test_code_review_ollama_defaults_use_fast_local_model(monkeypatch):
assert svc_mod.CODE_REVIEW_OLLAMA_MODEL == "qwen2.5-coder:7b"
assert svc_mod.CODE_REVIEW_OLLAMA_TIMEOUT == 15
assert svc_mod.CODE_REVIEW_OLLAMA_SECONDARY_MODEL == "gemma3:4b"
assert svc_mod.CODE_REVIEW_OLLAMA_SECONDARY_TIMEOUT == 60
assert svc_mod.CODE_REVIEW_OLLAMA_SECONDARY_TIMEOUT == 25
assert svc_mod.CODE_REVIEW_OLLAMA_FALLBACK_MODEL == "hermes3:latest"
assert svc_mod.CODE_REVIEW_OLLAMA_FALLBACK_TIMEOUT == 20
assert svc_mod.CODE_REVIEW_OLLAMA_NUM_PREDICT == 384
@@ -305,7 +305,7 @@ def test_openclaw_uses_secondary_local_model_before_gemini(monkeypatch):
assert result == "SECONDARY-LOCAL"
assert [call["model"] for call in calls] == ["qwen2.5-coder:7b", "gemma3:4b"]
assert calls[0]["timeout"] == 15
assert calls[1]["timeout"] == 60
assert calls[1]["timeout"] == 25
fake_claude.generate.assert_not_called()
fake_genai.GenerativeModel.assert_not_called()
fake_elephant.generate.assert_not_called()
@@ -366,7 +366,7 @@ def test_openclaw_preflight_skips_dead_primary_before_generate(monkeypatch):
assert calls == [{
"host": ollama_mod.OLLAMA_HOST_SECONDARY,
"model": "gemma3:4b",
"timeout": 60,
"timeout": 25,
}]
fake_claude.generate.assert_not_called()
fake_genai.GenerativeModel.assert_not_called()

View File

@@ -1946,6 +1946,7 @@ def test_marketplace_matcher_promotes_focused_low_score_exact_identity_lines():
assert diagnostics.hard_veto is False
assert expected_reason in diagnostics.reasons
if expected_reason in {
"focused_exact_identity_sab_private_spray",
"focused_exact_identity_herb24_mist_diffuser_black",
"focused_exact_identity_pavaruni_40_scent_oil",
"focused_exact_identity_pavaruni_20_scent_candle",
@@ -1956,6 +1957,44 @@ def test_marketplace_matcher_promotes_focused_low_score_exact_identity_lines():
assert diagnostics.alert_tier == "price_alert_exact"
def test_marketplace_matcher_promotes_precise_brandless_herbacin_hand_cream_to_total_price():
from services.marketplace_product_matcher import score_marketplace_match
cases = [
(
"【Herbacin 德國小甘菊】小甘菊柔皙護手霜20ml",
"小甘菊柔皙護手霜 20ml",
),
(
"【Herbacin 德國小甘菊】小甘菊野生玫瑰護手霜20ml 條狀",
"小甘菊野生玫瑰護手霜20ml",
),
]
for momo_name, competitor_name in cases:
diagnostics = score_marketplace_match(momo_name, competitor_name)
assert diagnostics.score >= 0.76
assert diagnostics.hard_veto is False
assert diagnostics.match_type == "exact"
assert diagnostics.price_basis == "total_price"
assert diagnostics.alert_tier == "price_alert_exact"
assert "focused_exact_total_price_safe" in diagnostics.reasons
assert "focused_exact_identity_herbacin_classic_hand_cream_20ml_brandless" in diagnostics.reasons
def test_marketplace_matcher_keeps_herbacin_cross_variant_out_of_total_price():
from services.marketplace_product_matcher import score_marketplace_match
diagnostics = score_marketplace_match(
"【Herbacin 德國小甘菊】小甘菊柔皙護手霜20ml",
"小甘菊野生玫瑰護手霜20ml",
)
assert diagnostics.price_basis != "total_price"
assert diagnostics.alert_tier != "price_alert_exact"
assert "focused_exact_total_price_safe" not in diagnostics.reasons
def test_marketplace_matcher_keeps_high_variant_low_score_lines_outside_focused_promotion():
from services.marketplace_product_matcher import score_marketplace_match