收緊 PChome 近門檻自動回刷隊列
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
================================================================================
|
||||
|
||||
【已完成】
|
||||
- V10.493 新增市場情報 MCP Fetch Candidate Handoff Review 安全預覽 gate:只審核 parser review 後的候選交接包,確認 source/candidate key 對齊、queue policy 仍是 manual preview、候選數維持小批次、無 raw/secret/side-effect;API 不建立 queue、不寫 DB、不讀 artifact、不連外、不掛 scheduler。
|
||||
- V10.492 收緊 PChome 近門檻自動回刷隊列:`retryable_candidate_revalidation` 不再把 `identity_veto`、`unit_comparable`、`true_low_confidence` 納入每日自動回刷;只處理 `recoverable_low_score` 與 legacy `low_score / refresh_low_score`,並要求無 hard veto、仍在 `exact_identity`、且具備同品線/identity anchor 證據。這讓「可救回」與「正確阻擋」在操作層面真正分流,避免為了壓低 low_score 而重跑不該自動推進的候選。
|
||||
- V10.491 新增市場情報 MCP Fetch Result Parser Review 安全預覽 gate:只審核操作員貼回的 parser 結構化摘要,對齊 receipt source/path、候選必要欄位、公開 URL、小批次上限與 raw HTML/secret/side-effect 風險;API 不讀 artifact、不執行 parser CLI、不抓外站、不寫 DB、不掛 scheduler。
|
||||
- V10.489 補 PChome 低分同款人工覆核回收與 gate-pass 風險邊界:TS6 超美白香氛誘霜 120g/ml、W 修護保養蝸牛特潤修護面膜 6 片、Derma 大地 Eco 植萃護膚油 2 入,從低信心升成 `identity_review` 人工覆核候選;Clarins 輕盈美體護理油 vs 身體調和護理油、台塑生醫嬰兒沐浴/洗髮組合數量反轉、isLeaf 私密慕絲香型數量不一致改 hard veto;HOOOME 大理石暖燈 vs 泛稱經典款改留 `variant_selection_review`。正式價差表仍需人工採用才會寫入。Production 已部署 `/health=V10.489`;500 筆 read-only audit 由 V10.486 基線 `gate_pass=129 / identity_veto=1 / still_low=370` 收斂為 `gate_pass=124 / identity_veto=4 / still_low=372`。測試:完整 `pytest` 1289 passed / 9 skipped。
|
||||
- V10.488 新增市場情報 MCP Fetch Run Receipt 安全預覽 gate,只審核操作員 dry-run receipt,不執行 CLI、不抓外站、不寫 DB。
|
||||
|
||||
@@ -350,7 +350,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
|
||||
# ==========================================
|
||||
# 系統版本與路徑
|
||||
# ==========================================
|
||||
SYSTEM_VERSION = "V10.491"
|
||||
SYSTEM_VERSION = "V10.493"
|
||||
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
|
||||
public_url = PUBLIC_URL # 用於模板顯示
|
||||
|
||||
|
||||
@@ -87,6 +87,8 @@
|
||||
- 2026-05-29 起,`V10.489` 補 PChome 低分同款人工覆核回收與 gate-pass 風險邊界:TS6 超美白香氛誘霜 120g/ml、W 修護保養蝸牛特潤修護面膜 6 片、Derma 大地 Eco 植萃護膚油 2 入,從低信心升成 `identity_review` 候選;Clarins 輕盈美體護理油 vs 身體調和護理油、台塑生醫嬰兒沐浴/洗髮組合數量反轉、isLeaf 私密慕絲香型數量不一致改 hard veto;HOOOME 大理石暖燈 vs 泛稱經典款只留 `variant_selection_review`,不進 total-price accepted。Production 已部署 `/health=V10.489`;500 筆 read-only audit 由 V10.486 基線 `gate_pass=129 / identity_veto=1 / still_low=370` 收斂為 `gate_pass=124 / identity_veto=4 / still_low=372`,三應用容器 healthy、`momo-db` 未 recreate。
|
||||
- 2026-05-31 起,`V10.490` 補 ElephantAlpha / OpenClaw 舊策略 action 相容:正式日誌觀察到 `agent=openclaw action=generate_market_strategy` 被當未知步驟丟錯;此類 OpenClaw strategy 產生步驟已定義為 advisory skipped,只記 warning,不觸發 circuit breaker、不執行外部策略、不影響價格行動。測試覆蓋 `generate_market_strategy` 與 `generate_resource_optimization_strategy`,未知 action 仍維持 fail-fast。
|
||||
- 2026-05-31 起,`V10.491` 新增市場情報 MCP Fetch Result Parser Review gate:在 receipt gate 後只審核操作員 shell parser 貼回的結構化摘要,對齊 source/path、公開 URL、候選必要欄位、小批次上限、raw HTML/secret/side-effect 風險;仍不讀 artifact、不執行 CLI、不連外、不寫 DB、不掛 scheduler。
|
||||
- 2026-05-31 起,`V10.492` 收緊 PChome 近門檻自動回刷:`run_retryable_candidate_revalidation()` 只回刷 `recoverable_low_score` 與 legacy `low_score / refresh_low_score`,且 SQL 端要求 `hard_veto=false`、`comparison_mode=exact_identity`、diagnostic reasons 命中同品線/identity anchor;`identity_veto`、`unit_comparable`、`true_low_confidence` 不再進每日自動回刷隊列,需等待新證據或人工處理。
|
||||
- 2026-05-31 起,`V10.493` 新增市場情報 MCP Fetch Candidate Handoff Review gate:在 parser review 通過後只審核候選交接包,要求 source/candidate key 完全對齊、queue policy 維持 manual preview、小批次上限與操作員無寫入/無連外/無排程確認;仍不建立 queue、不寫 DB、不讀 artifact、不連外、不掛 scheduler。
|
||||
|
||||
## 3. 12 Agent 決策信封整合
|
||||
|
||||
|
||||
@@ -65,6 +65,8 @@ RECOVERABLE_DIAGNOSTIC_REASONS = {
|
||||
"spec_name_alignment",
|
||||
}
|
||||
|
||||
RECOVERABLE_SQL_REASON_LIST = ", ".join(f"'{reason}'" for reason in sorted(RECOVERABLE_DIAGNOSTIC_REASONS))
|
||||
|
||||
# ── Feeder 結果 ───────────────────────────────────────
|
||||
@dataclass
|
||||
class FeederResult:
|
||||
@@ -1037,16 +1039,17 @@ class CompetitorPriceFeeder:
|
||||
"""
|
||||
取得近門檻候選,供 matcher 升級後重新評分。
|
||||
|
||||
這條路徑不重新搜尋,只用前次留下的 PChome product_id 批次查詢最新商品資料,
|
||||
適合把舊 scorer 卡在 0.70~0.759 的真同款重新推進正式比價。
|
||||
僅重跑明顯有回收價值的候選;最後仍由現行 matcher 重新判斷,
|
||||
不因舊 attempt_status 自動寫入正式比價。
|
||||
這條路徑優先用前次留下的 PChome product_id 批次查詢最新商品資料;
|
||||
若 product_id 過期或重評仍低分,才走受控 fresh search recovery。
|
||||
自動隊列只收「近門檻、無 hard veto、仍在 exact_identity 軌道、已有同品線證據」
|
||||
的候選;identity_veto、unit_comparable、true_low_confidence 不在自動回刷主戰場。
|
||||
最後仍由現行 matcher 重新判斷,不因舊 attempt_status 自動寫入正式比價。
|
||||
"""
|
||||
if self.engine is None:
|
||||
raise RuntimeError("需要注入 SQLAlchemy engine")
|
||||
|
||||
from sqlalchemy import text
|
||||
sql = text("""
|
||||
sql = text(f"""
|
||||
WITH latest_momo AS (
|
||||
SELECT
|
||||
p.id AS product_id,
|
||||
@@ -1067,6 +1070,7 @@ class CompetitorPriceFeeder:
|
||||
cma.best_match_score,
|
||||
cma.attempt_status,
|
||||
cma.hard_veto,
|
||||
cma.match_diagnostic_json,
|
||||
cma.attempted_at
|
||||
FROM competitor_match_attempts cma
|
||||
WHERE cma.source = 'pchome'
|
||||
@@ -1096,18 +1100,16 @@ class CompetitorPriceFeeder:
|
||||
AND la.attempt_status IN (
|
||||
'low_score',
|
||||
'refresh_low_score',
|
||||
'recoverable_low_score',
|
||||
'true_low_confidence',
|
||||
'unit_comparable',
|
||||
'refresh_unit_comparable',
|
||||
'identity_veto'
|
||||
'recoverable_low_score'
|
||||
)
|
||||
AND la.best_competitor_product_id IS NOT NULL
|
||||
AND la.best_competitor_product_id <> ''
|
||||
AND COALESCE(la.best_match_score, 0) >= :min_score
|
||||
AND COALESCE(la.hard_veto, false) = false
|
||||
AND COALESCE(la.match_diagnostic_json->>'comparison_mode', 'exact_identity') = 'exact_identity'
|
||||
AND (
|
||||
COALESCE(la.hard_veto, false) = false
|
||||
OR la.attempt_status = 'identity_veto'
|
||||
la.attempt_status = 'recoverable_low_score'
|
||||
OR COALESCE(la.match_diagnostic_json->'reasons', '[]'::jsonb) ?| array[{RECOVERABLE_SQL_REASON_LIST}]
|
||||
)
|
||||
ORDER BY la.best_match_score DESC NULLS LAST, lm.momo_price DESC NULLS LAST, lm.sku
|
||||
LIMIT :limit
|
||||
|
||||
@@ -111,13 +111,19 @@ def test_competitor_feeder_persists_all_match_attempt_outcomes():
|
||||
"'low_score'",
|
||||
"'refresh_low_score'",
|
||||
"'recoverable_low_score'",
|
||||
):
|
||||
assert status in retryable_source
|
||||
retryable_status_list = retryable_source.split("la.attempt_status IN (", 1)[1].split(")", 1)[0]
|
||||
for status in (
|
||||
"'true_low_confidence'",
|
||||
"'unit_comparable'",
|
||||
"'refresh_unit_comparable'",
|
||||
"'identity_veto'",
|
||||
):
|
||||
assert status in retryable_source
|
||||
assert "OR la.attempt_status = 'identity_veto'" in retryable_source
|
||||
assert status not in retryable_status_list
|
||||
assert "COALESCE(la.hard_veto, false) = false" in retryable_source
|
||||
assert "match_diagnostic_json->>'comparison_mode'" in retryable_source
|
||||
assert "?| array[" in retryable_source
|
||||
latest_attempt_source = retryable_source.split("latest_attempt AS", 1)[1].split(
|
||||
"SELECT\n lm.product_id", 1
|
||||
)[0]
|
||||
|
||||
Reference in New Issue
Block a user