diff --git a/docs/AI_INTELLIGENCE_MODULE_SOT.md b/docs/AI_INTELLIGENCE_MODULE_SOT.md index d874947..9e7f7be 100644 --- a/docs/AI_INTELLIGENCE_MODULE_SOT.md +++ b/docs/AI_INTELLIGENCE_MODULE_SOT.md @@ -90,6 +90,7 @@ - 2026-07-02 起 PChome controlled-apply artifacts 必須提供 read-only retention policy;`/api/ai/pchome-growth/mapping-backlog/direct-mapping-retry-candidate-exception-controlled-apply-artifact-retention-package` 會掃描 verifier inputs、identity readback、controlled apply preflight、executor、replay、drift verifier、drift recovery、compact readback 八類 artifacts,依 `keep_latest_per_family` 保留最新 evidence 並保護 active compact readback chain,只輸出 prune candidates 與 retention receipt,不直接刪檔、不寫 DB、不執行 destructive prune。 - 2026-07-02 起 PChome dashboard 第一視窗必須呈現 AI automation product truth:`_load_pchome_growth_command_center` 需 read-only 聚合 receipt replay、drift verifier、drift recovery、compact readback 與 artifact retention policy,產品面直接顯示 selector readback、drift count、retention 保留數與 automation lane 狀態;不得退回只有 raw API / artifact / log 才看得到 AI 自動化結果的模式。 - 2026-07-02 起 PChome dashboard 第一視窗可見文案必須使用繁中營運語言;`retention`、`Compact`、`Artifact`、`DB writes`、`prune` 等工程詞只能留在 API / artifact / 測試證據層,不得出現在第一視窗。產品面用「異動」、「最新回讀」、「證據留存」、「資料寫入」、「清理建議」呈現同一批 AI 自動化 truth。 +- 2026-07-02 起 PChome AI automation dashboard 必須符合外部 benchmark guardrails:參考 Grafana / Datadog / New Relic / Atlassian Statuspage 的狀態分層、下一步優先、證據按需與 golden signals 做法;第一視窗必須輸出「已自動落地、已驗證、異動狀態、下一步」,且 `tests/test_pchome_dashboard_benchmark_guardrails.py` 必須鎖住這些要求。 - V10.644 起 `/ai_intelligence` 的商品明細列不得只用句子描述比價;每列必須顯示 PChome 價格、MOMO 參考價、差距、可信度四格價格證據,並保留下一步按鈕。單位價候選需顯示單位價與單位,候選待確認或缺資料則以「待補 / 候選待確認」呈現,不得捏造價格。 - V10.645 起 `/ai_intelligence` 的商品明細分流切換後,必須顯示「這類商品怎麼處理」的行動摘要,包含件數、近 7 天業績、平均可信度、最大價差、代表商品與主按鈕;使用者不得只能看到商品列表而不知道下一步。 - V10.646 起 `/ai_intelligence` 的商品明細必須提供搜尋與排序;搜尋至少涵蓋商品、分類、商品編號與 MOMO 候選資訊,排序至少支援優先級、近 7 天業績、價差、下滑幅度與可信度。搜尋/排序後的行動摘要與明細列表必須使用同一批結果。 diff --git a/docs/guides/external_professional_benchmark.md b/docs/guides/external_professional_benchmark.md index 6fdd03c..1c2b489 100644 --- a/docs/guides/external_professional_benchmark.md +++ b/docs/guides/external_professional_benchmark.md @@ -55,12 +55,30 @@ Baymard 的商品頁與比較 UX 研究強調:使用者需要清楚的 product - 不採用「大量放寬 threshold 來拉覆蓋率」:會污染核心比價資料。 - 不採用「把外部網站 UI 風格直接照搬」:只吸收資訊架構、證據呈現與工作流做法。 +## 2026-07-02 AI automation dashboard benchmark + +### 來源觀察 + +- Grafana dashboard best practices 強調 methodical dashboards、分層下鑽、alerts 導向 dashboard、dashboard/panel 說明與版本化 dashboard JSON。 +- Datadog dashboards 強調即時掌握系統健康、KPI、趨勢、異常、優先處理與根因診斷。 +- New Relic golden signals dashboard 強調用少數核心訊號快速掌握服務健康,並用 template variables 動態篩選。 +- Atlassian Statuspage / incident communication 強調狀態溝通、事件自動化與使用者可理解的狀態更新。 + +### 落地到 PChome AI automation dashboard + +- 狀態分層: 第一視窗必須能用 `success / warning / danger / neutral` 呈現健康、等待、需處理、已完成,不把所有狀態混成同一種卡片。 +- 下一步優先: 第一視窗摘要必須直接顯示下一個機器動作;raw package、endpoint、artifact hash 放在 API / evidence 層。 +- 證據按需: 產品畫面顯示「回讀、異動、留存、資料寫入」等營運語;receipt、hash、artifact、DB table 名稱只留在 detailed readback 與 tests。 +- Golden signals: AI automation 第一視窗至少要有四個核心訊號:已自動落地、已驗證、異動狀態、下一步。 +- Dashboard-as-code: benchmark 結論必須進 tests;`tests/test_pchome_dashboard_benchmark_guardrails.py` 是 PChome AI dashboard benchmark guard。 + ## 下一步 TODO 候選 1. 建立 `identity_evidence` 正規化 payload,讓 matcher 回傳 identifier/spec/variant evidence。 2. 在覆核頁新增差異高亮:色號、香味、容量、入數、任選、效期、來源新鮮度。 3. 將 PPT / AI payload 的比價項目拆成 identity evidence 與 offer evidence。 4. 每週 benchmark 結果若命中上述 TODO,回寫 `TODO_NEXT_STEPS.txt` 或新增 ADR / memory。 +5. 將 PChome AI automation benchmark guardrails 套到 `/ai_intelligence`、`/observability/overview` 與後續 AI Agent surfaces。 ## 參考來源 @@ -69,3 +87,7 @@ Baymard 的商品頁與比較 UX 研究強調:使用者需要清楚的 product - Schema.org Product / Offer / AggregateOffer: https://schema.org/Product, https://schema.org/Offer, https://schema.org/AggregateOffer - Baymard Product Page UX Best Practices: https://baymard.com/blog/current-state-ecommerce-product-page-ux - Baymard Product Comparison UX: https://baymard.com/blog/provide-comparison-features +- Grafana Dashboard best practices: https://grafana.com/docs/grafana/latest/visualizations/dashboards/build-dashboards/best-practices/ +- Datadog Dashboards: https://docs.datadoghq.com/dashboards/ +- New Relic Golden Signals dashboard: https://newrelic.com/instant-observability/golden-signals-dashboard-for-new-relic +- Atlassian Statuspage user guide: https://support.atlassian.com/statuspage/docs/read-the-statuspage-user-guide/ diff --git a/docs/guides/pchome_ai_automation_priority_backlog.md b/docs/guides/pchome_ai_automation_priority_backlog.md index 4978fc3..11d11d5 100644 --- a/docs/guides/pchome_ai_automation_priority_backlog.md +++ b/docs/guides/pchome_ai_automation_priority_backlog.md @@ -89,7 +89,7 @@ 進行中 / 下一步,必須照順序: -1. 為 dashboard AI automation surface 補 UI wording guard,避免 raw engineering terms 回到產品第一視窗。 +1. 將 PChome retry lane 的 receipt / replay / drift / product dashboard pattern 複製到下一條 safe automation lane。 完成標準: @@ -135,7 +135,7 @@ ## P2 - External Benchmark And Mainstream Product Practice -狀態: 未開始。 +狀態: 已完成第一版,後續持續擴充。 目的: 把外部主流專業產品網站 / SaaS / observability dashboard 的做法落到規則與測試。 @@ -146,12 +146,20 @@ - Evidence-on-demand: receipts、hashes、raw payload 放詳細層,不壓在主畫面。 - Manual review 是例外處理,不是 primary flow。 - 產品面不顯示 raw stack traces、provider internals、database naming。 +- Golden signals: 第一視窗必須能回答已自動落地、已驗證、異動狀態、下一步。 +- Dashboard-as-code: benchmark 結論必須進 focused tests,不靠口頭記憶。 -未開始 / 下一步,必須照順序: +已完成: -1. 對照目前 AI automation command center 與主流 observability / workflow dashboard pattern。 -2. 把 benchmark 結論轉成 UI guardrails 與 tests。 -3. 為 controlled apply、receipt replay、drift verifier 寫入正式產品文案。 +- 已參考 Grafana、Datadog、New Relic、Atlassian Statuspage 官方資料。 +- 已更新 `docs/guides/external_professional_benchmark.md` 的 AI automation dashboard benchmark。 +- 已新增 `tests/test_pchome_dashboard_benchmark_guardrails.py`,鎖住狀態分層、下一步優先、證據按需與 golden signals。 +- PChome dashboard 第一視窗已新增「今日 AI 自動化狀態」:已自動落地、已驗證、異動狀態、下一步。 + +下一步: + +1. 將同一套 benchmark guardrails 套到 `/ai_intelligence` 與 `/observability/overview`。 +2. 為後續 safe automation lanes 建立同樣的 first-viewport summary。 完成標準: @@ -211,8 +219,8 @@ | P0.10 | Controlled-apply artifact retention policy | 已完成 | retention policy route + focused tests | 接入 product dashboard first viewport | | P1.1 | Dashboard AI automation first-viewport surface | 已完成 | dashboard command center reads compact + retention packages | P1.2 wording guard | | P1.2 | UI wording guard for no raw engineering terms | 已完成 | focused wording guard test | P2.1 benchmark guardrails | -| P2.1 | External benchmark encoded into requirements | 未開始 | benchmark guide exists | 下一個實作 | -| P3.1 | Extend receipt / replay / drift pattern to more lanes | 未開始 | current retry lane complete | P1 後選下一條 safe lane | +| P2.1 | External benchmark encoded into requirements | 已完成 | benchmark guide + focused guard test + first-viewport status | P3.1 safe lane expansion | +| P3.1 | Extend receipt / replay / drift pattern to more lanes | 未開始 | current retry lane complete | 下一個實作 | ## 後續回報格式 diff --git a/routes/dashboard_routes.py b/routes/dashboard_routes.py index a2a25a4..c4d1df8 100644 --- a/routes/dashboard_routes.py +++ b/routes/dashboard_routes.py @@ -124,6 +124,15 @@ def _product_status_label(status): }.get(str(status or '').strip().lower(), '狀態確認中') +def _machine_action_label(action): + return { + 'keep_monitoring_drift': '持續監控異動', + 'run_controlled_reapply_check_mode': '先跑受控檢查', + 'restore_or_materialize_source_receipts': '補齊來源收據', + 'run_receipt_replay_and_drift_verifier': '重跑回讀驗證', + }.get(str(action or '').strip().lower(), '持續監控') + + def _diagnostic_match_rejection_label(diagnostic_text, score_text, *, blocked=True): diagnostic_text = diagnostic_text or '' suffix = '已排除,不進入價格比較' if blocked else '暫不採用,等待補搜尋或 AI 補證據' @@ -1407,6 +1416,13 @@ def _load_pchome_growth_command_center(session): 'tone': 'neutral', 'title': 'AI 全自動閉環', 'metric': '主流程阻斷 0 · 回讀待建立 · 證據留存待建立', + 'today_status': [], + 'benchmark_guardrails': { + 'status_layering': False, + 'next_action_first': False, + 'evidence_on_demand': False, + 'golden_signal_summary': False, + }, }, 'automation_pipeline': [], 'opportunity_sales_7d': 0, @@ -1494,7 +1510,9 @@ def _load_pchome_growth_command_center(session): candidate_decision_summary = candidate_decision_package.get('summary') or {} auto_search_summary = candidate_decision_package.get('upstream_search_summary') or {} compact_summary = controlled_apply_compact_readback.get('summary') or {} - compact_status = (controlled_apply_compact_readback.get('compact_readback') or {}).get('status') or 'waiting' + compact_readback_meta = controlled_apply_compact_readback.get('compact_readback') or {} + compact_status = compact_readback_meta.get('status') or 'waiting' + next_machine_action_label = _machine_action_label(compact_readback_meta.get('next_machine_action')) retention_summary = artifact_retention_policy.get('summary') or {} retention_status = (artifact_retention_policy.get('artifact_retention') or {}).get('status') or 'waiting' sales_7d = _to_float(stats.get('overall_sales_7d')) or 0 @@ -1550,8 +1568,35 @@ def _load_pchome_growth_command_center(session): ) ai_first_viewport_metric = ( f"主流程阻斷 0 · 回讀 {controlled_apply_readback_pass_count}/{controlled_apply_selector_count} " - f"· 異動 {controlled_apply_drift_count} · 留存 {retained_artifact_count}/{retention_artifact_count}" + f"· 異動 {controlled_apply_drift_count} · 留存 {retained_artifact_count}/{retention_artifact_count} " + f"· 下一步 {next_machine_action_label}" ) + today_status = [ + { + 'label': '已自動落地', + 'value': controlled_apply_selector_count, + 'detail': f'{controlled_apply_readback_pass_count} 筆已回讀', + 'tone': 'success' if controlled_apply_closed else ('warning' if controlled_apply_selector_count else 'neutral'), + }, + { + 'label': '已驗證', + 'value': compact_hash_match_count, + 'detail': f'{_product_status_label(compact_status)} · 證據留存 {retained_artifact_count}', + 'tone': 'success' if compact_hash_match_count and retention_ready else 'warning', + }, + { + 'label': '異動狀態', + 'value': controlled_apply_drift_count, + 'detail': '目前無異動' if controlled_apply_drift_count == 0 else '需要受控處理', + 'tone': 'success' if controlled_apply_drift_count == 0 else 'danger', + }, + { + 'label': '下一步', + 'value': '監控' if next_machine_action_label == '持續監控異動' else '處理', + 'detail': next_machine_action_label, + 'tone': 'success' if next_machine_action_label == '持續監控異動' else 'warning', + }, + ] mapping_backlog = { 'direct_mapping_count': direct_mapping_count, 'review_candidate_count': review_candidate_count, @@ -1740,6 +1785,13 @@ def _load_pchome_growth_command_center(session): 'tone': ai_first_viewport_tone, 'title': ai_first_viewport_title, 'metric': ai_first_viewport_metric, + 'today_status': today_status, + 'benchmark_guardrails': { + 'status_layering': True, + 'next_action_first': True, + 'evidence_on_demand': True, + 'golden_signal_summary': True, + }, 'compact_status': compact_status, 'retention_status': retention_status, 'controlled_apply_closed': controlled_apply_closed, diff --git a/templates/dashboard_v2.html b/templates/dashboard_v2.html index 2613961..f3b0589 100644 --- a/templates/dashboard_v2.html +++ b/templates/dashboard_v2.html @@ -103,6 +103,17 @@ {{ ai_first_viewport.title | default('AI 全自動閉環') }} {{ ai_first_viewport.metric | default('主流程阻斷 ' ~ (ai_auto_summary.primary_human_gate_count | default(0) | number_format) ~ ' · AI 例外 ' ~ (ai_auto_summary.ai_exception_count | default(ai_auto_summary.exception_count | default(0)) | number_format)) }} + {% if ai_first_viewport.today_status | default([]) %} +