From b6f862cbbc0c6dddcc569c7e40a508059ec7178c Mon Sep 17 00:00:00 2001 From: ogt Date: Thu, 2 Jul 2026 20:15:37 +0800 Subject: [PATCH] style(obs): compact quality workbench copy --- docs/AI_INTELLIGENCE_MODULE_SOT.md | 1 + .../guides/external_professional_benchmark.md | 2 ++ .../pchome_ai_automation_priority_backlog.md | 7 +++- templates/admin/quality_trend.html | 5 +-- ...t_quality_trend_text_density_guardrails.py | 36 +++++++++++++++++++ 5 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 tests/test_quality_trend_text_density_guardrails.py diff --git a/docs/AI_INTELLIGENCE_MODULE_SOT.md b/docs/AI_INTELLIGENCE_MODULE_SOT.md index 0a82206..c434de9 100644 --- a/docs/AI_INTELLIGENCE_MODULE_SOT.md +++ b/docs/AI_INTELLIGENCE_MODULE_SOT.md @@ -100,6 +100,7 @@ - 2026-07-02 起 `/ai_automation_smoke` 也必須採密集 AI 巡檢工作台:首屏使用 `data-density-guardrail="compact-smoke-workbench"`,以「AI 巡檢、風險優先、推播摘要」短標籤保留狀態模式;重複說明、趨勢教學與診斷細節提示必須退到 hidden contract,畫面第一層只保留狀態、數字、趨勢、每日摘要與檢查項目 summary。 - 2026-07-02 起 `/observability/agent_orchestration` 必須採密集 AI Agent 工作台:首屏使用 `data-density-guardrail="compact-agent-workbench"`,以「AI 分工、成本守門、知識命中」短標籤承接分工狀態;hero 說明、KPI 小註、列內描述、卡片描述與頁尾重複標題不得佔用第一層視覺,畫面先保留呼叫總量、主力路徑占比、付費成本、知識命中率、分工矩陣與工具協作表。 - 2026-07-02 起 `/observability/ai_calls` 必須採密集 AI 流量工作台:首屏使用 `data-density-guardrail="compact-ai-calls-workbench"`,以「流量監控、成本守門、知識命中」短標籤承接 AI 呼叫狀態;hero 說明、KPI 小註、素材說明與頁尾重複標題不得佔用第一層視覺,畫面先保留呼叫總量、用量、成本、延遲、知識命中、錯誤、情境矩陣與最近呼叫。 +- 2026-07-02 起 `/observability/quality_trend` 必須採密集 AI 品質工作台:首屏使用 `data-density-guardrail="compact-quality-workbench"`,以「品質回饋、知識可靠、行動成效」短標籤承接 AI 建議可靠性;hero 說明、KPI 小註與頁尾重複標題不得佔用第一層視覺,畫面先保留反饋總量、最低均分、蒸餾樣本、知識評分、使用情境反饋、根因建議與實際動作成效。 - 2026-07-02 起 `/ai_intelligence` 商品明細與單品作戰詳情的四格價格證據必須可測:PChome 價格、MOMO 參考價、差距、可信度需以 `data-evidence` 固定,並以 `aria-label="價格證據"` 對應可掃描區塊;候選待確認或缺資料只能顯示「候選待確認 / 待補」,不得捏造價格或讓使用者打開 raw payload 才知道判斷依據。 - 2026-07-02 起 `/ai_intelligence` 必須是密集 AI 工作台,不得退回大段文字說明頁:首屏與明細可見內容只保留短狀態、數字、四格證據與下一步按鈕;KPI note、benchmark detail、alert 副句、策略說明、decision copy、來源長句與單品 reason list 不得佔用第一層視覺。`tests/test_ai_intelligence_text_density_guardrails.py` 必須鎖住 `data-density-guardrail="compact-ai-workbench"`、短任務文案、detail meta 與 hidden explanatory copy。 - 2026-07-02 起 `/observability/overview` 也必須採密集 AI 觀測工作台:首屏以 `data-density-guardrail="compact-observability-workbench"`、`AI 觀測 / 風險優先 / 下一步` 與 golden signals 先呈現狀態、數字與操作入口;hero lede、signal note、route desc、host meta 與資料來源長句不得佔用第一層視覺。`tests/test_observability_text_density_guardrails.py` 必須鎖住 compact marker 與 hidden explanatory copy。 diff --git a/docs/guides/external_professional_benchmark.md b/docs/guides/external_professional_benchmark.md index 20cfc76..abf1a1a 100644 --- a/docs/guides/external_professional_benchmark.md +++ b/docs/guides/external_professional_benchmark.md @@ -74,6 +74,7 @@ Baymard 的商品頁與比較 UX 研究強調:使用者需要清楚的 product - Surface rollout: `/ai_intelligence` 與 `/observability/overview` 已套用相同 golden-signal guardrails;`tests/test_ai_surface_benchmark_guardrails.py` 鎖住兩頁首屏的狀態分層、下一步優先與 evidence-on-demand 語言。 - AI Agent surface rollout: `/observability/agent_orchestration` 已套用 compact Agent workbench guardrails;`tests/test_agent_orchestration_text_density_guardrails.py` 鎖住首屏短標籤、核心訊號與 hidden explanatory copy。 - AI traffic surface rollout: `/observability/ai_calls` 已套用 compact AI traffic workbench guardrails;`tests/test_ai_calls_text_density_guardrails.py` 鎖住首屏短標籤、成本/錯誤/知識核心訊號與 hidden explanatory copy。 +- AI quality surface rollout: `/observability/quality_trend` 已套用 compact AI quality workbench guardrails;`tests/test_quality_trend_text_density_guardrails.py` 鎖住首屏短標籤、品質/知識/行動成效核心訊號與 hidden explanatory copy。 ## 下一步 TODO 候選 @@ -86,6 +87,7 @@ Baymard 的商品頁與比較 UX 研究強調:使用者需要清楚的 product - 已完成: `/ai_intelligence` 首屏直接消費 surface summary,raw receipt / hash / DB table / endpoint 細節留在 evidence-on-demand 層。 - 已完成: `/observability/agent_orchestration` 首屏以「AI 分工 / 成本守門 / 知識命中」短標籤與四個核心數字呈現 Agent 編排狀態。 - 已完成: `/observability/ai_calls` 首屏以「流量監控 / 成本守門 / 知識命中」短標籤與六個核心數字呈現 AI 呼叫、成本、錯誤與知識狀態。 + - 已完成: `/observability/quality_trend` 首屏以「品質回饋 / 知識可靠 / 行動成效」短標籤與四個核心數字呈現 AI 建議可靠性。 ## 參考來源 diff --git a/docs/guides/pchome_ai_automation_priority_backlog.md b/docs/guides/pchome_ai_automation_priority_backlog.md index c197702..3ecd5f4 100644 --- a/docs/guides/pchome_ai_automation_priority_backlog.md +++ b/docs/guides/pchome_ai_automation_priority_backlog.md @@ -101,7 +101,7 @@ ## P1 - Product Visibility And Professional Website Experience -狀態: 進行中,本輪已完成 `/ai_intelligence`、`/observability/overview`、`/ai_automation_smoke`、`/observability/agent_orchestration` 與 `/observability/ai_calls` 密集 AI 工作台文字密度守門。 +狀態: 進行中,本輪已完成 `/ai_intelligence`、`/observability/overview`、`/ai_automation_smoke`、`/observability/agent_orchestration`、`/observability/ai_calls` 與 `/observability/quality_trend` 密集 AI 工作台文字密度守門。 目的: 讓 AI 自動化在產品裡可見,成為專業營運工作流,而不是只藏在後端。 @@ -140,6 +140,10 @@ - 首屏改成 `data-density-guardrail="compact-ai-calls-workbench"`,以「流量監控 / 成本守門 / 知識命中」短標籤承接 AI 呼叫狀態。 - hero 說明、KPI 小註、素材說明與頁尾重複標題從可見 UI 退場,保留呼叫總量、用量、成本、延遲、知識命中、錯誤、情境矩陣與最近呼叫。 - `tests/test_ai_calls_text_density_guardrails.py` 已鎖住 compact marker、第一層狀態數字與 explanatory copy hidden contract。 +- `/observability/quality_trend` 密集 AI 品質工作台文字密度 guard 已完成: + - 首屏改成 `data-density-guardrail="compact-quality-workbench"`,以「品質回饋 / 知識可靠 / 行動成效」短標籤承接 AI 建議可靠性。 + - hero 說明、KPI 小註與頁尾重複標題從可見 UI 退場,保留反饋總量、最低均分、蒸餾樣本、知識評分、使用情境反饋、根因建議與實際動作成效。 + - `tests/test_quality_trend_text_density_guardrails.py` 已鎖住 compact marker、第一層狀態數字與 explanatory copy hidden contract。 已完成 / 下一步,必須照順序: @@ -264,6 +268,7 @@ | P1.6 | AI automation smoke compact workbench text-density guardrails | 已完成 | `/ai_automation_smoke` first viewport hides explanatory copy; focused density guard test | Apply density guard to remaining high-visibility AI surfaces | | P1.7 | Agent orchestration compact workbench text-density guardrails | 已完成 | `/observability/agent_orchestration` first viewport hides explanatory copy; focused density guard test | Apply density guard to remaining high-visibility AI surfaces | | P1.8 | AI calls compact workbench text-density guardrails | 已完成 | `/observability/ai_calls` first viewport hides explanatory copy; focused density guard test | Apply density guard to remaining high-visibility AI surfaces | +| P1.9 | Quality trend compact workbench text-density guardrails | 已完成 | `/observability/quality_trend` first viewport hides explanatory copy; focused density guard test | Apply density guard to remaining high-visibility AI surfaces | | 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 | 已完成 | direct mapping candidate decision lane closeout route + focused tests | P3.2 scheduled automation health summaries | | P3.2 | Scheduled automation health summaries | 已完成 | `/api/ai-automation/scheduled-health-summary` + smoke service focused tests | P3.3 rollback evidence packages | diff --git a/templates/admin/quality_trend.html b/templates/admin/quality_trend.html index 53b7951..ff3c2bf 100644 --- a/templates/admin/quality_trend.html +++ b/templates/admin/quality_trend.html @@ -7,6 +7,7 @@ .quality-hero,.quality-panel,.quality-table-shell{border:1px solid var(--obs-line);border-radius:26px;background:var(--obs-card);box-shadow:0 16px 38px rgba(70,46,28,.08)} .quality-hero{padding:clamp(1.2rem,2.4vw,2rem);background:radial-gradient(circle at 12% 14%,rgba(201,100,66,.18),transparent 24rem),radial-gradient(circle at 88% 8%,rgba(79,111,143,.14),transparent 22rem),linear-gradient(135deg,rgba(255,248,239,.98),rgba(255,255,255,.74))} .quality-kicker{color:var(--obs-accent);font-size:.76rem;letter-spacing:.13em;text-transform:uppercase;font-weight:850}.quality-title{margin:.45rem 0 .25rem;font-family: var(--momo-font-display, "Inter", "Noto Sans TC", system-ui, sans-serif);font-size:var(--obs-title-size);letter-spacing: 0;line-height:.98}.quality-subtitle{color:var(--obs-muted);max-width:860px;line-height:1.7} + .quality-mode-row{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.75rem}.quality-mode{display:inline-flex;align-items:center;min-height:28px;padding:.32rem .65rem;border:1px solid var(--obs-line);border-radius:10px;background:rgba(255,255,255,.62);color:var(--obs-muted);font-size:.74rem;font-weight:850;white-space:nowrap}.quality-subtitle,.quality-signal-note,.quality-footer-copy{display:none} .quality-filter{display:flex;gap:.55rem;flex-wrap:wrap;margin-top:1rem;padding:.8rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.58)}.quality-command{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-top:1rem}.quality-signal{padding:.95rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.62)}.quality-label{color:var(--obs-muted);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}.quality-value{display:block;margin-top:.28rem;font-size:var(--obs-value-size);font-weight:880;letter-spacing: 0} .quality-grid{display:grid;grid-template-columns:minmax(0,1.18fr) minmax(330px,.82fr);gap:1rem;margin-top:1rem}.quality-stack{display:grid;gap:1rem}.quality-panel-head,.quality-table-title{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;padding:1.05rem 1.1rem .25rem}.quality-panel-title,.quality-table-title h3{margin:.15rem 0 0;font-size:1.1rem;font-weight:850;letter-spacing: 0}.quality-panel-body{padding:1rem 1.1rem 1.1rem}.quality-table-shell{overflow:hidden;margin-top:1rem}.quality-mini-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.7rem}.quality-mini{padding:.85rem;border:1px solid var(--obs-line);border-radius:18px;background:rgba(255,255,255,.58)}.quality-mini strong{display:block;margin-top:.24rem;font-size:1.35rem;letter-spacing: 0}.root-card{padding:.85rem;border:1px solid var(--obs-line);border-radius:18px;background:rgba(255,255,255,.58);margin-bottom:.7rem}.status-good{color:var(--obs-green)}.status-warn{color:var(--obs-amber)}.status-bad{color:var(--obs-red)}.status-blue{color:var(--obs-blue)} @media(max-width:1100px){.quality-command{grid-template-columns:repeat(2,minmax(0,1fr))}.quality-grid{grid-template-columns:1fr}}@media(max-width:720px){.quality-command,.quality-mini-grid{grid-template-columns:1fr}} @@ -18,7 +19,7 @@ {% set rag_total = (rag_overall_dist | sum(attribute='count')) if rag_overall_dist else 0 %}
-
品質診斷 · {{ days }} 日視窗

AI 品質診斷台

用反饋、知識分數與行動閉環檢查 AI 建議是否可靠。

反饋總量
{{ total_feedback.value }}使用情境反饋總量
最低均分
{{ "%.2f"|format(worst_avg.value) }}最低使用情境平均分
蒸餾樣本
{{ episode_total }}蒸餾池 {{ days }} 日
知識評分
{{ rag_total }}已回饋知識查詢
+
品質診斷 · {{ days }} 日視窗

AI 品質診斷台

品質回饋知識可靠行動成效

用反饋、知識分數與行動閉環檢查 AI 建議是否可靠。

反饋總量
{{ total_feedback.value }}使用情境反饋總量
最低均分
{{ "%.2f"|format(worst_avg.value) }}最低使用情境平均分
蒸餾樣本
{{ episode_total }}蒸餾池 {{ days }} 日
知識評分
{{ rag_total }}已回饋知識查詢
{% if error %}
{{ error }}
{% endif %}
@@ -35,7 +36,7 @@ {% if rag_root_causes %}
根因分析

知識根因建議

{% for rc in rag_root_causes %}
{{ obs_label.caller(rc.caller) }}{{ "%.2f"|format(rc.avg_score) }}/5{{ rc.feedback_n }} 筆
    {% for h in rc.hits %}
  • {{ obs_label.insight(h.insight_type) }}相似度 {{ "%.2f"|format(h.similarity) }}{{ h.content }}{% if h.content|length >= 200 %}…{% endif %}
  • {% endfor %}
{% endfor %}
{% endif %} {% if recommendations %}
智能建議

智能建議

    {% for rec in recommendations %}
  • {% if rec.action == 'review' %}{% else %}{% endif %}{{ obs_label.caller(rec.caller) }}:{{ rec.reason }}
  • {% endfor %}
{% endif %} {% if action_outcomes_stats %}
動作成效

實際動作成效

{% set total_ao = (action_outcomes_stats | sum(attribute='count')) or 1 %}{% for r in action_outcomes_stats %}
{{ obs_label.verdict(r.verdict) }}{{ r.count }}{{ "%.1f"|format(r.count / total_ao * 100) }}%
{% endfor %}
{% endif %} -

AI 品質診斷台

+
diff --git a/tests/test_quality_trend_text_density_guardrails.py b/tests/test_quality_trend_text_density_guardrails.py new file mode 100644 index 0000000..611fca3 --- /dev/null +++ b/tests/test_quality_trend_text_density_guardrails.py @@ -0,0 +1,36 @@ +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] + + +def test_quality_trend_uses_compact_workbench_contract(): + template = (ROOT / "templates/admin/quality_trend.html").read_text(encoding="utf-8") + + assert 'data-density-guardrail="compact-quality-workbench"' in template + assert 'aria-label="AI 品質狀態模式"' in template + assert "品質回饋" in template + assert "知識可靠" in template + assert "行動成效" in template + + +def test_quality_trend_keeps_quality_signals_and_hides_explanatory_copy(): + template = (ROOT / "templates/admin/quality_trend.html").read_text(encoding="utf-8") + + for marker in ["反饋總量", "最低均分", "蒸餾樣本", "知識評分"]: + assert marker in template + + assert ".quality-subtitle,.quality-signal-note,.quality-footer-copy{display:none}" in template + assert 'class="quality-subtitle"' in template + assert 'class="text-muted quality-signal-note"' in template + assert "quality-footer-copy" in template + + +def test_quality_trend_preserves_feedback_tables_and_non_raw_wording(): + template = (ROOT / "templates/admin/quality_trend.html").read_text(encoding="utf-8") + + for marker in ["使用情境反饋分佈", "知識分數分布", "知識根因建議", "實際動作成效"]: + assert marker in template + + for forbidden in ["{{ caller }}", "{{ rc.caller }}", "{{ rec.caller }}", "top_k"]: + assert forbidden not in template