嗨大家,我是 Debuguy。
還記得 Day 21 我們做了 Grafana Alert 的自動化分析嗎?AI 會生成一份技術分析報告,內容確實有用,但有個問題一直讓我很困擾...
目前的 Grafana 分析報告長這樣:
🚨 Grafana 警報分析
摘要:API 出現大量 5xx 錯誤,影響用戶登入功能。經過分析發現是 database 連線池耗盡導致。
優先級:高
這是一個高優先級問題,因為影響到核心的登入功能,導致用戶無法正常使用服務。
信心水準:高 (95%)
基於充足的日誌證據和清晰的錯誤模式,我對這個分析結果有很高的信心。
影響範圍:
主要影響 Auth Service 和 User Profile Service。根據日誌統計,約有 1247 個用戶在這段時間內遇到登入失敗。
立即建議:
1. 立即檢查 Auth Service 的 database 連線池配置
2. 查看最近的部署記錄
3. 增加監控告警
這段文字在 Slack 裡就是一大段純文字:
問題一:可讀性差
問題二:無法程式化處理
// 我想要自動判斷優先級來決定通知方式
if (報告.優先級 === '高') { // ❌ 報告是一大段字串啊!
notifyOnCall();
}
問題三:Slack 有更好的呈現方式
Slack 的 Block Kit 可以做出很漂亮的視覺效果:
但 AI 給我一大段文字,要怎麼轉換成這些精美的 blocks?
翻了 Genkit 的文件後發現,原來可以直接要求 AI 輸出結構化的 JSON!
概念很簡單:
# prompts/grafana_analysis.prompt
---
model: litellm/gemini-2.5-flash
output:
schema:
title: string
summary: string
priority: (enum[high, medium, low])
confidence:
level: (enum[high, medium, low])
percentage: number
---
你是一位 Grafana 警報診斷專家...
就這樣!在 output.schema
裡面定義好格式,AI 就會按照這個格式輸出。
Before(純文字):
摘要:API 出現大量 5xx 錯誤...
優先級:高
信心水準:高 (95%)
...
After(結構化 JSON):
{
"title": "API 5xx 錯誤率異常警報分析",
"summary": "API 出現大量 5xx 錯誤,影響用戶登入功能...",
"priority": "high",
"confidence": {
"level": "high",
"percentage": 95
}
}
差異立見:
// 現在可以這樣寫了!
if (report.priority === 'high') {
await notifyOnCall(report);
}
// 自動建立 ticket
if (report.confidence.percentage >= 90) {
await createJiraTicket(report);
}
// 存入資料庫
await db.alerts.create({
data: report
});
定義 schema 時:
priority: (enum[high, medium, low])
AI 只能輸出這三個值之一:
"high"
"medium"
"low"
"較高"
(會被拒絕)"critical"
(會被拒絕)不用擔心 AI 會突發奇想用其他的詞彙。
有了結構化資料,就可以:
priority
顯示不同顏色的 emoji(🔴🟡🟢)confidence
做成進度條recommendations
轉成 Slack 的條列 blocks分析報告需要包含什麼?
output:
schema:
title: string
summary: string
priority: (enum[high, medium, low])
confidence:
level: (enum[high, medium, low])
percentage: number
reason: string
impact:
services(array): string
userCount?: number
description: string
recommendations(array):
action: string
priority: (enum[immediate, soon, later])
{
"title": "API 5xx 錯誤率異常",
"summary": "Auth Service 的 database 連線池耗盡導致大量 5xx 錯誤",
"priority": "high",
"confidence": {
"level": "high",
"percentage": 95,
"reason": "日誌證據充足,錯誤模式清晰"
},
"impact": {
"services": ["auth-service", "user-profile-service"],
"userCount": 1247,
"description": "所有需要登入的功能都受到影響"
},
"recommendations": [
{
"action": "檢查 database 連線池配置",
"priority": "immediate"
},
{
"action": "增加監控告警",
"priority": "soon"
}
]
}
完美!現在我們有了結構清晰的資料。
有了結構化的 JSON 後,明天我們要來解決:
如何把這個 JSON 轉換成漂亮的 Slack blocks?
Slack 的 Block Kit 有很多種 blocks:
header
(大標題)section
(內容區塊)divider
(分隔線)context
(次要資訊)rich_text
(豐富的文字格式)每種 block 都有自己的 JSON 格式規範,而且可以組合出千變萬化的視覺效果。
Slack 還有提供線上的所見即所得可以預覽樣式
Block Kit Builder
問題是:這麼多種 blocks 的格式,要怎麼優雅地定義成 TypeScript types?
明天我們就來聊聊如何用 Zod schema 把 Slack blocks 的複雜格式「馴服」,讓程式碼既類型安全又好維護。
今天我們學到了 Output Schema 的核心概念:
核心價值:
設計原則:
下一步預告:
明天我們要把這個結構化資料轉換成精美的 Slack 訊息!
AI 的發展變化很快,目前這個想法以及專案也還在實驗中。但也許透過這個過程大家可以有一些經驗和想法互相交流,歡迎大家追蹤這個系列。
也歡迎追蹤我的 Threads @debuguy.dev