@@ -8,7 +8,7 @@
--obs-ink : var ( - - momo - ink , #302720 ) ;
--obs-muted : var ( - - momo - muted , #8b8077 ) ;
--obs-paper : var ( - - momo - paper , #fff8ef ) ;
--obs-card : rgba ( 255 , 252 , 246 , 0.92 ) ;
--obs-card : var ( - - momo - bg - surface , #faf7f0 ) ;
--obs-line : rgba ( 86 , 64 , 48 , 0.14 ) ;
--obs-accent : var ( - - momo - accent , #c96442 ) ;
--obs-accent-soft : rgba ( 201 , 100 , 66 , 0.12 ) ;
@@ -17,28 +17,31 @@
--obs-red : #b94b45 ;
--obs-blue : #4f6f8f ;
color : var ( - - obs - ink ) ;
font-family : var ( - - momo - font - family , "Inter" , "Noto Sans TC" , system - ui , sans-serif ) ;
}
. obs-hero {
position : relative ;
overflow : hidden ;
border : 1 px solid var ( - - obs - line ) ;
border-radius : 2 8px ;
padding : clamp ( 1.3 5 rem , 3 vw , 2.3 rem ) ;
background:
radial-gradient ( circle at 12 % 18 % , rgba ( 201 , 100 , 66 , 0.2 ) , transparent 28 % ) ,
radial-gradient ( circle at 84 % 12 % , rgba ( 79 , 111 , 143 , 0.18 ) , transparent 30 % ) ,
linear-gradient ( 135 deg , #fff8ed 0 % , #f7eadb 48 % , #fffdf8 100 % ) ;
box-shadow : 0 22 px 55 px rgba ( 70 , 46 , 28 , 0.1 ) ;
border-radius : var ( - - momo - radius - lg , 8 px ) ;
padding : clamp ( 1.0 5 rem , 2.2 vw , 1.65 rem ) ;
background-color : var ( - - momo - bg - surface , #faf7f0 ) ;
background-image : var ( - - obs - dot ) ;
background-size : 13 px 13 px ;
box-shadow : var ( - - momo - shadow - md , 0 2 px 8 px rgba ( 42 , 37 , 32 , 0.06 ) ) ;
}
. obs-hero :: after {
content : "" ;
position : absolute ;
inset : auto -8 % -42 % 42 % ;
height : 260 px ;
background : repeating-linear-gradient ( 90 deg , rgba ( 201 , 100 , 66 , 0.1 ) 0 1 px , transparent 1 px 18 px ) ;
transform : rotate ( -7 deg ) ;
inset : auto 1 rem 1 rem auto ;
width : 8.5 rem ;
height : 8.5 rem ;
border : 1 px solid color-mix ( in srgb , var ( - - obs - accent ) 22 % , transparent ) ;
background-image : var ( - - obs - dot ) ;
background-size : 10 px 10 px ;
opacity : 0.46 ;
pointer-events : none ;
}
@@ -46,30 +49,36 @@
display : inline-flex ;
align-items : center ;
gap : 0.5 rem ;
padding : 0.42 rem 0.72 rem ;
padding : 0.36 rem 0.58 rem ;
border : 1 px solid rgba ( 201 , 100 , 66 , 0.22 ) ;
border-radius : 999 px ;
background : rgba ( 255 , 255 , 255 , 0.58 ) ;
border-radius : var ( - - momo - radius - lg , 8 px ) ;
background : var ( - - momo - bg - elevated , #fdfaf3 ) ;
color : var ( - - obs - accent ) ;
font-size : 0.78 rem ;
letter-spacing : 0.12 em ;
text-transform : uppercase ;
font-family : var ( - - momo - font - family - mono , "JetBrains Mono" , ui - monospace , monospace ) ;
font-size : var ( - - momo - text - label , 0.6875 r em) ;
font-weight : 800 ;
letter-spacing : 0.06 em ;
}
. obs-kicker-date {
color : var ( - - obs - muted ) ;
}
. obs-title {
margin : 0.85 rem 0 0.4 rem ;
margin : 0.7 rem 0 0.35 rem ;
max-width : 820 px ;
font-family : ' Noto Sans TC' , 'Inter' , sans-serif ;
font-size : clamp ( 1.9 rem , 3.2 vw , 2.75 rem ) ;
line-height : 0.95 ;
letter-spacing : -0.055 em ;
font-family : var ( - - momo - font - display , "JetBrains Mono" , " Noto Sans TC" , ui - monospace , monospace ) ;
font-size : var ( - - obs - title - size , 1.8 rem ) ;
line-height : 1.18 ;
letter-spacing : 0 ;
font-weight : 800 ;
}
. obs-lede {
max-width : 760 px ;
margin : 0 ;
color : var ( - - obs - muted ) ;
font-size : 1 rem ;
font-size : var ( - - momo - text - body , 0.875 rem ) ;
line-height : 1.75 ;
}
@@ -83,28 +92,30 @@
. obs-signal {
position : relative ;
z-index : 1 ;
min-height : 112 px ;
padding : 1 rem ;
min-height : 104 px ;
padding : 0.92 rem ;
border : 1 px solid var ( - - obs - line ) ;
border-radius : 20 px ;
background : rgba ( 255 , 255 , 255 , 0.66 ) ;
border-radius : var ( - - momo - radius - lg , 8 px ) ;
background : var ( - - momo - bg - surface , #faf7f0 ) ;
backdrop-filter : blur ( 8 px ) ;
}
. obs-signal-label ,
. obs-section-eyebrow ,
. obs-route-code {
color : var ( - - obs - muted ) ;
font-size : 0.72 rem ;
letter-spacing : 0.11 em ;
text-transform : uppercase ;
color : color-mix ( in srgb , var ( - - obs - accent ) 76 % , var( - - obs - muted ) ) ;
font-family : var ( - - momo - font - family - mono , "JetBrains Mono" , ui - monospace , monospace ) ;
font-size : var ( - - momo - text - label , 0.6875 r em) ;
font-weight : 800 ;
letter-spacing : 0.06 em ;
}
. obs-signal-value {
margin-top : 0.45 rem ;
font-size : clamp ( 1.65 rem , 3 vw , 2.35 rem ) ;
font-weight : 800 ;
letter-spacing : -0.04 em ;
font-family : var ( - - momo - font - family - mono , "JetBrains Mono" , ui - monospace , monospace ) ;
font-size : var ( - - obs - value - size , 1.85 rem ) ;
font-weight : 850 ;
letter-spacing : 0 ;
}
. obs-signal-note {
@@ -122,9 +133,9 @@
. obs-panel {
border : 1 px solid var ( - - obs - line ) ;
border-radius : 24 px ;
border-radius : var ( - - momo - radius - lg , 8 px ) ;
background : var ( - - obs - card ) ;
box-shadow : 0 14 px 36 px rgba ( 70 , 46 , 28 , 0.07 ) ;
box-shadow : var ( - - momo - shadow - md , 0 2 px 8 px rgba ( 42 , 37 , 3 2, 0.06 ) ) ;
}
. obs-panel-head {
@@ -137,9 +148,9 @@
. obs-panel-title {
margin : 0.18 rem 0 0 ;
font-size : 1.1 rem ;
font-size : var ( - - momo - text - title , 1.0625 rem ) ;
font-weight : 800 ;
letter-spacing : -0.02 em ;
letter-spacing : 0 ;
}
. obs-panel-body {
@@ -158,13 +169,13 @@
align-items : center ;
padding : 0.9 rem ;
border : 1 px solid var ( - - obs - line ) ;
border-radius : 1 8px ;
background : rgba ( 255 , 255 , 255 , 0.62 ) ;
border-radius : var ( - - momo - radius - lg , 8 px ) ;
background : var ( - - momo - bg - elevated , #fdfaf3 ) ;
}
. obs-host-card . is-good { border-left : 5 px solid var ( - - obs - green ) ; }
. obs-host-card . is-warn { border-left : 5 px solid var ( - - obs - amber ) ; }
. obs-host-card . is-bad { border-left : 5 px solid var ( - - obs - red ) ; }
. obs-host-card . is-good { border-left : 4 px solid var ( - - obs - green ) ; }
. obs-host-card . is-warn { border-left : 4 px solid var ( - - obs - amber ) ; }
. obs-host-card . is-bad { border-left : 4 px solid var ( - - obs - red ) ; }
. obs-host-top {
display : flex ;
@@ -178,9 +189,10 @@
}
. obs-host-pct {
font-family : var ( - - momo - font - family - mono , "JetBrains Mono" , ui - monospace , monospace ) ;
font-size : 1.35 rem ;
font-weight : 850 ;
letter-spacing : -0.04 em ;
letter-spacing : 0 ;
}
. obs-host-meta ,
@@ -230,7 +242,7 @@
align-items : center ;
gap : 0.35 rem ;
padding : 0.32 rem 0.55 rem ;
border-radius : 999 px ;
border-radius : var ( - - momo - radius - lg , 8 px ) ;
background : var ( - - obs - accent - soft ) ;
color : var ( - - obs - accent ) ;
font-size : 0.76 rem ;
@@ -251,15 +263,16 @@
. obs-mini {
padding : 0.85 rem ;
border : 1 px solid var ( - - obs - line ) ;
border-radius : 1 8px ;
background : rgba ( 255 , 255 , 255 , 0.58 ) ;
border-radius : var ( - - momo - radius - lg , 8 px ) ;
background : var ( - - momo - bg - elevated , #fdfaf3 ) ;
}
. obs-mini strong {
display : block ;
margin-top : 0.25 rem ;
font-family : var ( - - momo - font - family - mono , "JetBrains Mono" , ui - monospace , monospace ) ;
font-size : 1.45 rem ;
letter-spacing : -0.04 em ;
letter-spacing : 0 ;
}
. obs-status-good { color : var ( - - obs - green ) ; }
@@ -273,8 +286,8 @@
gap : 0.45 rem ;
padding : 0.58 rem 0.78 rem ;
border : 1 px solid rgba ( 201 , 100 , 66 , 0.25 ) ;
border-radius : 999 px ;
background : rgba ( 255 , 255 , 255 , 0.65 ) ;
border-radius : var ( - - momo - radius - lg , 8 px ) ;
background : var ( - - momo - bg - elevated , #fdfaf3 ) ;
color : var ( - - obs - accent ) ;
text-decoration : none ;
font-size : 0.82 rem ;
@@ -298,16 +311,18 @@
. obs-route-group {
border : 1 px solid var ( - - obs - line ) ;
border-radius : 24 px ;
border-radius : var ( - - momo - radius - lg , 8 px ) ;
padding : 1 rem ;
background:
linear-gradient ( 180 deg , rgba ( 255 , 255 , 255 , 0.74 ) , rgba ( 255 , 248 , 239 , 0.82 ) ) ;
background-color : var ( - - momo - bg - surface , #faf7f0 ) ;
background-image : var ( - - obs - dot ) ;
background-size : 13 px 13 px ;
}
. obs-route-group h3 {
margin : 0.25 rem 0 0.85 rem ;
font-size : 1.1 rem ;
font-size : var ( - - momo - text - title , 1.0625 rem ) ;
font-weight : 850 ;
letter-spacing : 0 ;
}
. obs-route-list {
@@ -322,10 +337,10 @@
align-items : center ;
padding : 0.72 rem ;
border : 1 px solid transparent ;
border-radius : 16 px ;
border-radius : var ( - - momo - radius - lg , 8 px ) ;
color : var ( - - obs - ink ) ;
text-decoration : none ;
background : rgba ( 255 , 255 , 255 , 0.58 ) ;
background : var ( - - momo - bg - elevated , #fdfaf3 ) ;
transition : border-color 160 ms ease , transform 160 ms ease , background 160 ms ease ;
}
@@ -341,7 +356,7 @@
place-items : center ;
width : 2 rem ;
height : 2 rem ;
border-radius : 12 px ;
border-radius : 6 px ;
background : var ( - - obs - accent - soft ) ;
color : var ( - - obs - accent ) ;
}
@@ -403,32 +418,32 @@
< div class = "obs-war-room" >
< section class = "obs-hero" >
< span class = "obs-kicker" > < i class = "fas fa-satellite-dish" > < / i > AI Observability Command Room · {{ today }} < / span >
< span class = "obs-kicker" > < i class = "fas fa-satellite-dish" > < / i > 01 指揮總覽 < span class = "obs-kicker-date" > · {{ today }}< / span > < / span >
< h1 class = "obs-title" > AI 觀測戰情室< / h1 >
< p class = "obs-lede" >
這裡是 momo-pro 私有 AI 中樞的第一入口: 三主機、AI 呼叫、RAG 學習、MCP、AIOps、預算與 PPT 視覺審核全部 收斂到同一張作戰圖。 數字只讀正式資料來源;沒有 資料時顯示 診斷空狀態,不用假 KPI 撐場面 。
私有 AI 中樞的第一入口: 三主機、AI 呼叫、RAG 學習、MCP、AIOps、預算與 PPT 視覺審核收斂到同一張工作台。所有 數字只讀正式資料來源;缺 資料時呈現可 診斷空狀態。
< / p >
< div class = "obs-command-strip" >
< div class = "obs-signal" >
< div class = "obs-signal-label" > Risk Signals < / div >
< div class = "obs-signal-label" > 即時風險 < / div >
< div class = "obs-signal-value {% if risk_count == 0 %}obs-status-good{% elif risk_count <= 2 %}obs-status-warn{% else %}obs-status-bad{% endif %}" > {{ risk_count }}< / div >
< div class = "obs-signal-note" > 主機、預算、錯誤率、待審核的即時風險數< / div >
< / div >
< div class = "obs-signal" >
< div class = "obs-signal-label" > AI Calls / 24h < / div >
< div class = "obs-signal-label" > 24 小時呼叫 < / div >
< div class = "obs-signal-value" > {{ "{:,}".format(ai.total) if ai else '—' }}< / div >
< div class = "obs-signal-note" > Token {{ "{:,}".format(ai.tokens) if ai else '—' }}< / div >
< div class = "obs-signal-note" > 權杖量: {{ "{:,}".format(ai.tokens) if ai else '—' }}< / div >
< / div >
< div class = "obs-signal" >
< div class = "obs-signal-label" > Cost < / div >
< div class = "obs-signal-label" > 成本水位 < / div >
< div class = "obs-signal-value" > ${{ "%.2f"|format(ai.cost_24h) if ai else '0.00' }}< / div >
< div class = "obs-signal-note" > 當月累計 ${{ "%.2f"|format(summary.month_cost|default(0)) }}< / div >
< / div >
< div class = "obs-signal" >
< div class = "obs-signal-label" > RAG Hit Rate < / div >
< div class = "obs-signal-label" > RAG 命中率 < / div >
< div class = "obs-signal-value obs-status-blue" > {{ "%.1f"|format(ai.rag_rate) if ai else '—' }}{% if ai %}%{% endif %}< / div >
< div class = "obs-signal-note" > Cache {{ "%.0f"|format(ai.cache_rate) if ai else '—' }}{% if ai %}%{% endif %}< / div >
< div class = "obs-signal-note" > 快取命中 {{ "%.0f"|format(ai.cache_rate) if ai else '—' }}{% if ai %}%{% endif %}< / div >
< / div >
< / div >
< / section >
@@ -438,7 +453,7 @@
< article class = "obs-panel" >
< div class = "obs-panel-head" >
< div >
< div class = "obs-section-eyebrow" > Host Cascade < / div >
< div class = "obs-section-eyebrow" > 02 主機級聯 < / div >
< h2 class = "obs-panel-title" > 三主機生命線< / h2 >
< / div >
< a class = "obs-link-button" href = "/observability/host_health" > < i class = "fas fa-arrow-right" > < / i > 主機健康< / a >
@@ -453,7 +468,7 @@
< span class = "obs-host-name" > {{ h.label }}< / span >
< span class = "obs-host-pct {% if h.uptime_pct >= 99 %}obs-status-good{% elif h.uptime_pct >= 90 %}obs-status-warn{% else %}obs-status-bad{% endif %}" > {{ "%.1f"|format(h.uptime_pct) }}%< / span >
< / div >
< div class = "obs-host-meta" > {{ h.up }}/{{ h.total }} probes · 平均 {{ h.avg_ms }} ms · 24h 視窗< / div >
< div class = "obs-host-meta" > {{ h.up }}/{{ h.total }} 次探測 · 平均 {{ h.avg_ms }} ms · 24 小時 視窗< / div >
< / div >
< div class = "obs-sparkline" >
{% if host_sparkline.get(h.label) %}
@@ -468,7 +483,7 @@
{% else %}
< div class = "obs-empty" >
< i class = "fas fa-triangle-exclamation me-1" > < / i >
host_health_probes 無資料。請確認 migration 029 與 scheduler probe job 是否已啟動。
主機探測尚無資料。請確認第 029 號資料遷移與排程探測任務 是否已啟動。
< / div >
{% endif %}
< / div >
@@ -478,7 +493,7 @@
< article class = "obs-panel" >
< div class = "obs-panel-head" >
< div >
< div class = "obs-section-eyebrow" > Budget Guard < / div >
< div class = "obs-section-eyebrow" > 預算守門 < / div >
< h2 class = "obs-panel-title" > 預算告警< / h2 >
< / div >
< a class = "obs-link-button" href = "/observability/budget" > < i class = "fas fa-bolt" > < / i > 處理預算< / a >
@@ -509,7 +524,7 @@
< article class = "obs-panel" >
< div class = "obs-panel-head" >
< div >
< div class = "obs-section-eyebrow" > AI Runtime < / div >
< div class = "obs-section-eyebrow" > AI 呼叫 < / div >
< h2 class = "obs-panel-title" > 呼叫品質< / h2 >
< / div >
< a class = "obs-link-button" href = "/observability/ai_calls" > < i class = "fas fa-chart-bar" > < / i > 詳情< / a >
@@ -519,8 +534,8 @@
< div class = "obs-metric-grid" >
< div class = "obs-mini" > < span class = "obs-microcopy" > 錯誤率< / span > < strong class = "{% if ai.error_rate >= 15 %}obs-status-bad{% elif ai.error_rate >= 5 %}obs-status-warn{% else %}obs-status-good{% endif %}" > {{ "%.1f"|format(ai.error_rate) }}%< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > 失敗< / span > < strong > {{ ai.errors }}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > RAG hits < / span > < strong class = "obs-status-blue" > {{ ai.rag_hits }}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > Cache hits < / span > < strong > {{ ai.cache_hits }}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > RAG 命中 < / span > < strong class = "obs-status-blue" > {{ ai.rag_hits }}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > 快取命中 < / span > < strong > {{ ai.cache_hits }}< / strong > < / div >
< / div >
{% else %}
< div class = "obs-empty" > ai_calls 無 24h 資料。< / div >
@@ -531,7 +546,7 @@
< article class = "obs-panel" >
< div class = "obs-panel-head" >
< div >
< div class = "obs-section-eyebrow" > Learning Loop < / div >
< div class = "obs-section-eyebrow" > 學習閉環 < / div >
< h2 class = "obs-panel-title" > RAG 學習閘< / h2 >
< / div >
< a class = "obs-link-button" href = "/observability/promotion_review" > < i class = "fas fa-brain" > < / i > 審核< / a >
@@ -540,7 +555,7 @@
{% if summary.episodes %}
< div class = "obs-metric-grid" >
< div class = "obs-mini" > < span class = "obs-microcopy" > 待審核< / span > < strong class = "{% if summary.episodes.pending > 0 %}obs-status-warn{% else %}obs-status-good{% endif %}" > {{ summary.episodes.pending }}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > 30d episodes < / span > < strong > {{ summary.episodes.total_30d }}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > 30 日樣本 < / span > < strong > {{ summary.episodes.total_30d }}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > 已晉升< / span > < strong class = "obs-status-good" > {{ summary.episodes.approved_30d }}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > 晉升率< / span > < strong > {{ "%.0f"|format(summary.episodes.approval_rate) }}%< / strong > < / div >
< / div >
@@ -553,7 +568,7 @@
< article class = "obs-panel" >
< div class = "obs-panel-head" >
< div >
< div class = "obs-section-eyebrow" > AIOps / MCP / PPT < / div >
< div class = "obs-section-eyebrow" > 自動化後勤 < / div >
< h2 class = "obs-panel-title" > 自動化後勤< / h2 >
< / div >
< / div >
@@ -561,7 +576,7 @@
< div class = "obs-metric-grid" >
< div class = "obs-mini" > < span class = "obs-microcopy" > AIOps 未解< / span > < strong class = "{% if summary.aiops and summary.aiops.incidents_open > 0 %}obs-status-bad{% else %}obs-status-good{% endif %}" > {{ summary.aiops.incidents_open if summary.aiops else '—' }}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > 自癒成功率< / span > < strong > {{ "%.0f"|format(summary.aiops.heal_rate) if summary.aiops else '—' }}{% if summary.aiops %}%{% endif %}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > MCP calls < / span > < strong > {{ "{:,}".format(summary.mcp.total) if summary.mcp else '—' }}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > MCP 呼叫 < / span > < strong > {{ "{:,}".format(summary.mcp.total) if summary.mcp else '—' }}< / strong > < / div >
< div class = "obs-mini" > < span class = "obs-microcopy" > PPT 通過率< / span > < strong > {{ "%.0f"|format(summary.ppt.pass_rate) if summary.ppt and summary.ppt.total > 0 else '—' }}{% if summary.ppt and summary.ppt.total > 0 %}%{% endif %}< / strong > < / div >
< / div >
< / div >
@@ -571,7 +586,7 @@
< section class = "obs-route-map" aria-label = "AI 觀測台子頁入口" >
< div class = "obs-route-group" >
< div class = "obs-section-eyebrow" > Command < / div >
< div class = "obs-section-eyebrow" > 03 戰情指揮 < / div >
< h3 > 戰情室< / h3 >
< div class = "obs-route-list" >
< a class = "obs-route-card" href = "/observability/agent_orchestration" > < span class = "obs-route-icon" > < i class = "fas fa-network-wired" > < / i > < / span > < span > < span class = "obs-route-title" > Agent 編排矩陣< / span > < span class = "obs-route-desc" > 四 Agent × 模型 × MCP × RAG 分工。< / span > < / span > < span class = "obs-route-code" > 02< / span > < / a >
@@ -580,17 +595,17 @@
< / div >
< div class = "obs-route-group" >
< div class = "obs-section-eyebrow" > Runtime < / div >
< div class = "obs-section-eyebrow" > 系統成本 < / div >
< h3 > 系統與成本< / h3 >
< div class = "obs-route-list" >
< a class = "obs-route-card" href = "/observability/host_health" > < span class = "obs-route-icon" > < i class = "fas fa-heartbeat" > < / i > < / span > < span > < span class = "obs-route-title" > 主機健康< / span > < span class = "obs-route-desc" > 三主機、MCP、AIOps、AutoHeal。< / span > < / span > < span class = "obs-route-code" > 04< / span > < / a >
< a class = "obs-route-card" href = "/observability/ai_calls" > < span class = "obs-route-icon" > < i class = "fas fa-chart-bar" > < / i > < / span > < span > < span class = "obs-route-title" > AI 呼叫< / span > < span class = "obs-route-desc" > Token 、成本、錯誤、RAG × MCP 矩陣。< / span > < / span > < span class = "obs-route-code" > 05< / span > < / a >
< a class = "obs-route-card" href = "/observability/budget" > < span class = "obs-route-icon" > < i class = "fas fa-wallet" > < / i > < / span > < span > < span class = "obs-route-title" > 預算控管< / span > < span class = "obs-route-desc" > 供應商成本與 force-throttle 。< / span > < / span > < span class = "obs-route-code" > 06< / span > < / a >
< a class = "obs-route-card" href = "/observability/ai_calls" > < span class = "obs-route-icon" > < i class = "fas fa-chart-bar" > < / i > < / span > < span > < span class = "obs-route-title" > AI 呼叫< / span > < span class = "obs-route-desc" > 權杖量 、成本、錯誤、RAG × MCP 矩陣。< / span > < / span > < span class = "obs-route-code" > 05< / span > < / a >
< a class = "obs-route-card" href = "/observability/budget" > < span class = "obs-route-icon" > < i class = "fas fa-wallet" > < / i > < / span > < span > < span class = "obs-route-title" > 預算控管< / span > < span class = "obs-route-desc" > 供應商成本與強制節流 。< / span > < / span > < span class = "obs-route-code" > 06< / span > < / a >
< / div >
< / div >
< div class = "obs-route-group" >
< div class = "obs-section-eyebrow" > Quality < / div >
< div class = "obs-section-eyebrow" > RAG 品質 < / div >
< h3 > RAG 與品質< / h3 >
< div class = "obs-route-list" >
< a class = "obs-route-card" href = "/observability/promotion_review" > < span class = "obs-route-icon" > < i class = "fas fa-brain" > < / i > < / span > < span > < span class = "obs-route-title" > RAG 晉升審核< / span > < span class = "obs-route-desc" > Promotion Gate 與人工審核。< / span > < / span > < span class = "obs-route-code" > 07< / span > < / a >
@@ -603,7 +618,7 @@
< p class = "obs-microcopy mt-3" >
< i class = "fas fa-database me-1" > < / i >
資料來源:host_health_probes / ai_calls / ai_call_budgets / learning_episodes / rag_query_log / mcp_calls / incidents / heal_logs / ppt_audit_results 。
資料來源:主機探測、AI 呼叫、預算、學習事件、RAG 查詢、MCP 呼叫、事件與自癒、PPT 審核 。
< / p >
< / div >
@@ -636,7 +651,7 @@
legend : { display : false } ,
tooltip : {
displayColors : false ,
callbacks : { label : c => ` ${ c . label } : ${ c . parsed . y . toFixed ( 0 ) } % uptime ` }
callbacks : { label : c => ` ${ c . label } : ${ c . parsed . y . toFixed ( 0 ) } % 可用率 ` }
}
} ,
scales : {