AI 智慧報告 v1 自我 critique + v2 簡化版

2026-05-18 · 老闆問「這架構好嗎?有更好的想法嗎?業界怎麼做?」— 誠實 audit 自己剛寫的 v1 + 業界對標
TL;DR — v1 方向對,但過度工程約 30-40%。應該從「2 層 + 業界既有工具(Anthropic tool_use + Zod / Vercel AI SDK Generative UI)」開始,而不是自己造 manifest / 自己分類 intent。

最關鍵的 3 個問題(老闆要看就看這)

  1. 多了一層不需要的 Intent Classifier — 現代 tool-use LLM(Claude Sonnet)自己會選工具,加 Haiku 分類器只是省那一點點錢但增加延遲 + 多一個 fail point。除非規模到日 10 萬次以上才考慮。
  2. 「Manifest JSON」是重造輪子 — 業界已有標準:OpenAI Structured Outputs / Anthropic Tool Use / Vercel AI SDK Generative UI。三家都解「LLM 回符合 schema 的結果,不亂畫」。直接用,不要自己定 manifest format。
  3. NotebookLM 不是好對標 — NotebookLM 是 RAG-over-documents(餵 PDF 問問題)。真正接近 ChefsMate 想做的是 Tableau Pulse / Snowflake Cortex Analyst / Hex Magic / Hashboard(資料 BI + 自然語言 + 動態 widget)。
目錄
  1. 什麼是對的(留)
  2. 什麼是過度工程(砍)
  3. 什麼要改方向(調整)
  4. 業界對標(8 個真的能參考的)
  5. v2 簡化架構(2 層,不是 4 層)
  6. v1 完全沒談的(該補)
  7. 給老闆的問題(更精準版本)

什麼是對的(留)

KEEP AI 不直接碰 DB / Tool whitelist
這是 industry standard。OpenAI Function Calling、Anthropic Tool Use、Google Function Calling 都這樣設計。LLM 只能呼叫白名單 functions,你做的 schema validation 是正確思路。Anthropic 的 cookbook 直接這樣 demo。
KEEP Cold start 4 階段 + industry default fallback
這部分設計合理,而且已有 report-analytics 的 budget RPC 跑過完整 high/medium/low confidence pattern,直接 generalize 即可。業界做法很類似(LinkedIn 的 cold-start ranker、Spotify 新用戶推薦)。
KEEP Widget Library 限制 AI 只能挑 component
這正是 Vercel AI SDK Generative UI 的核心思想 — 「AI returns React Server Components from a registered library, not free HTML」。你直覺對,只是不用自己造,直接用 Vercel AI SDK。
KEEP 「資料來源 panel」可展開
業界叫 "AI Citations" 或 "Grounding Sources",Perplexity / Glean / ChatGPT 的 Search 都這樣。Glean 內部有完整 ML 框架做這個,叫「Trust Graph」。你的方向對,Glean 是好參考。

什麼是過度工程(砍)

CUT 分開的 Intent Classifier(Haiku 分類)
我寫「先用便宜 Haiku 分類 → 再用貴 Sonnet 做 tool plan」,聽起來省錢。實際上錯了: 正確做法:所有 tool 一次餵給 Sonnet,他自己選。Anthropic 的「Building Effective Agents」(Dec 2024)就講這個 — "Use the simplest pattern that works"。
CUT 自己定義「Report Manifest JSON Schema」
v1 我設計了一套 manifest format({version, intent, widgets, sources, ...})。這是重造輪子: 正確做法:用 Zod 定義 UIResponse schema,丟給 Anthropic 的 output_format。LLM 自動只能輸出合法物件,違規直接 retry。不要自己寫 validator。
CUT 4 層架構
我畫了 Data Mart → Orchestrator → Manifest Gen → Widget UI 四層。實際上 Orchestrator 跟 Manifest Gen 是同一個 LLM call:
// v1 思路(4 hops)
boss_q → classifier_llm → orchestrator_logic → manifest_llm → ui

// v2 簡化(2 hops)
boss_q → claude_sonnet(tools=[...], outputSchema=UIResponse) → ui
                ↓                       ↑
            執行 tools  ──────────────────
少 50% 系統複雜度,延遲少一半。
CUT 「12 個 Widget 一次定義完」
v1 列了 12 個 widget。YAGNI:
CUT Materialized views(此階段)
v1 提到「為 hot questions 建 materialized views」。過早優化:

什麼要改方向(調整)

CHANGE 信任分數 — 別合成單一分數
v1 我寫 trust = data_volume × 0.5 + algorithm × 0.3 + statistical × 0.2 然後 map bronze/silver/gold。聽起來精準,實際上失真: 建議改:顯示具體 metrics,但用「📊 高信賴度」/「⚠️ 樣本不足」這種**人話標籤**(不用數字 tier)。老闆要 drill-down 看具體 stats,可以點 source panel。
CHANGE 「老闆切換維度」UX
v1 我說「DimensionSelector chip 切換 → 重打 API 拿新 Manifest」。太重: 建議改:Tools 一次回多維度資料,UI 直接 client-side 切。LLM 只在第一次回答 + 老闆問「能不能拆得更細」這種需要再 reasoning 的時候才被叫。
CHANGE 不要用「NotebookLM」當對標
NotebookLM 是 RAG-over-documents 工具(餵 PDF / Google Docs,LLM 答內容)。ChefsMate 要做的是 generative BI(資料庫 + 自然語言 + 圖表)。混淆會誤導 design。 真正該參考:
CHANGE Cold start 4 階段過於 calendar-based
我寫 Day 0 / Week 1-4 / Month 2-3 / 3 個月+。實際上應該 per-tool / per-question: 建議改:每個 tool 自己回 { data, sample_size, confidence_method },UI 根據 metadata 決定渲染樣式。不要一刀切。

業界對標(8 個真的能參考的)

產品 / 文章對標哪部分能學什麼
Tableau Pulse
(Salesforce, 2024)
整體 generative BI 「Metrics + AI insights + 動態 dashboard」三件套。每個 metric 卡片有 AI 自動生的 insight 段落 + drill-down。最接近 ChefsMate 想做的。
Snowflake Cortex Analyst
(2024)
自然語言 → SQL 的 safety 「Semantic Model」概念 — 不讓 LLM 自己生 SQL,而是定義 metrics / dimensions / measures,LLM 只能組合既有概念。你的「tool whitelist」就是這個。
Vercel AI SDK Generative UI
(2024-2025 持續)
動態 widget 渲染 用 React Server Components 讓 AI 「pick」 components from registry。Zod schema 限制輸出。直接用 SDK,別自己造 manifest。
Anthropic「Building Effective Agents」
(Dec 2024,Anthropic 官方文章)
架構決策 「Use the simplest pattern that works. Add complexity only when measurable need.」直接打中 v1 的過度工程問題。
Glean / Notion AI Q&A Source citation UX 每個 AI 回答都連到具體 source document + paragraph。Glean 內部叫「Trust Graph」。你的「source panel」就是這個。
Hex Magic Notebook-style 互動探索 AI 給「建議下一格 cell」(SQL / chart / explanation),老闆可以接受、改、忽略。比 NotebookLM 更接近 BI 場景。
Perplexity / OpenAI 的 ChatGPT Search Followup questions 設計 每次回答後給 3-5 個 followup 建議(你 v1 的 followup_prompts 對)。Perplexity 做最好。
OpenAI Structured Outputs
(2024-08)
嚴格 schema 強制 把 Zod schema 餵 OpenAI,保證 100% 符合 schema(token-by-token grammar enforcement)。Anthropic 用「prefill + tool_use」達同效。

2 篇必讀

📖 Anthropic — Building Effective Agents(anthropic.com/research/building-effective-agents)
講 6 種 agent patterns(prompt chaining / routing / parallelization / orchestrator-workers / evaluator-optimizer / autonomous)。建議從 simplest 開始,measure 出真需求才加層。
對 ChefsMate 啟示:MVP 用「Single LLM + Tools」(他們叫 "Augmented LLM"),不要一開始就用 orchestrator-workers。
📖 Vercel — Generative UI(AI SDK docs)(sdk.vercel.ai/docs)
示範用 streamUI() 讓 LLM 直接 stream React component。Zod schema 限制 props。
對 ChefsMate 啟示:Widget library 用這 pattern 實作,免去自己寫 manifest renderer。

v2 簡化架構(2 層,不是 4 層)

┌────────────────────────────────────────────────────────────────┐
│  Layer B — Renderer (Web / iOS)                                 │
│   - 對話介面 + 預設問題 chips                                    │
│   - 動態 component canvas(Vercel AI SDK Generative UI pattern) │
│   - Zod schema 限制 AI 只能輸出合法 component                    │
└──────────────────────▲─────────────────────────────────────────┘
                       │ Streamed UIResponse (schema-validated)
┌──────────────────────┴─────────────────────────────────────────┐
│  Layer A — Single LLM with Tools (Claude Sonnet 4)              │
│   - 一個 LLM call,參數帶 tools[] + outputSchema                 │
│   - tools[] = 既有 report-analytics 7 演算法 wrap + 新加 5 個   │
│   - outputSchema = Zod-defined UIResponse                       │
│   - 自動 tool_use(可能多輪)→ 最後輸出 UIResponse                │
└────────────┬─────────────────────────────────────▲─────────────┘
             │ tool calls                            │ tool results
             ▼                                       │
        ┌────┴──────────────────────────────────────┴────┐
        │  Tool Registry(各 tool = TypeScript function) │
        │   - 每個 tool 有 Zod input/output schema       │
        │   - RLS gate 在每個 tool 內                    │
        │   - 直接 query Supabase RPC,不過 manifest 層  │
        └────────────────────────────────────────────────┘

關鍵程式碼 sketch

// tools/registry.ts
const tools = {
  get_revenue_summary: {
    description: '取得指定期間總營收 / 客單價 / 來客數',
    input_schema: z.object({
      period: z.enum(['today', 'this_week', 'this_month', /*...*/]),
      restaurant_id: z.string().uuid(),
    }),
    execute: async (input, ctx) => {
      // RLS check + Supabase RPC
      return { revenue: 12345, guest_count: 45, ... }
    },
  },
  // 其他 tools...
}

// ui-schema.ts
export const UIResponseSchema = z.object({
  summary_md: z.string(),
  trust_label: z.enum(['high', 'medium', 'low', 'insufficient_data']),
  widgets: z.array(z.discriminatedUnion('type', [
    KPICardSchema,
    LineChartSchema,
    BarComparisonSchema,
    InsightCalloutSchema,
    DataTableSchema,
  ])),
  sources: z.array(z.object({ tool: z.string(), params: z.any() })),
  followups: z.array(z.string()).max(3),
})

// api/smart-report/ask.ts
export async function POST(req) {
  const { question, restaurant_id } = await req.json()

  // 一個 LLM call 搞定
  const result = await anthropic.messages.create({
    model: 'claude-sonnet-4',
    tools: Object.entries(tools).map(([name, def]) => ({
      name,
      description: def.description,
      input_schema: def.input_schema,
    })),
    messages: [
      { role: 'user', content: question },
    ],
    // 強制最終輸出符合 UIResponse schema
    // (Anthropic 用 prefill + tool_use 達同效;OpenAI 用 response_format)
  })

  // tool_use 結果丟回 LLM 直到他輸出 UIResponse
  // 整個過程是 streaming,UI 可以 progressive render

  return NextResponse.json(UIResponseSchema.parse(result.final_output))
}

跟 v1 比的好處

v1 完全沒談的(該補)

議題該怎麼做
Caching - 同 restaurant + 同問題 + 30 分鐘內:直接 return cached UIResponse
- Tool results 自己 cache(今日營收 1 分鐘 / 月營收 1 小時)
- Vercel Edge Functions unstable_cache 或 Supabase 內建 cache
Streaming UI - 用 Vercel AI SDK streamUI()
- 老闆按 enter → 0.5s 內看到 「思考中...」
- 1-3s 內陸續 stream 出 widget(像 ChatGPT)
- 比 wait 5 秒一次 render 體感快很多
Cost observability - 每次 LLM call 記 token 用量 + 成本到 llm_usage
- Daily report 給老闆「今天 AI 花了 NT$X」
- 預算超過 alert(Telegram 推 admin)
Audit log - 每個問題 + 結果存 smart_report_history
- 老闆可以回看「上週問過什麼」
- 也是法規 / 信任的基礎(老闆能 prove 他做決策時看的是什麼資料)
Hallucination 防護 - System prompt 嚴格約束:「所有數字必須來自 tool result,不可自己算 / 估計
- Schema validation:UIResponse 內每個數字必須有 source: tool_call_id
- 沒 source 的數字 = reject + 重生
- Random spot-check:1% 的回答自動跑 evaluator LLM 檢查是否符合 tool result
Multi-restaurant aggregation - 集團老闆(海邊小巫 + 溪邊小巫)會問「兩家比起來?」
- Tool 內建 restaurant_ids[] 支援
- Permission gate:check 老闆對每家都有讀權
Offline / cache miss fallback - LLM API 失敗:回 「智慧問答暫時無法,顯示固定報表」+ 既有 ReportAPIClient
- 不要 hard fail
Weekly digest email - Cron 週一早上自動跑 5 個固定問題 → AI summarize → email 給老闆
- 這是 Tableau Pulse 殺手鐧 — 老闆不用主動問就有 insight

給老闆的問題(更精準版本)

  1. 架構走 v1 還 v2?
    • v1(4 層,自製 manifest): 完整但慢、debug 難
    • v2(2 層,用 Anthropic Tool Use + Zod + Vercel AI SDK Generative UI): 推薦
  2. MVP 第一版做哪 4 個 widget?
    • 建議 KPICard / LineChart / BarComparison / InsightCallout(70% 場景覆蓋)
  3. LLM 用 Claude Sonnet 4 還是 OpenAI GPT-5?
    • 建議 Claude(我們已有 anthropic 整合經驗 + tool_use schema 穩)
    • 若有 OpenAI credit 也可,structured_outputs 更嚴格(token-level grammar)
  4. Streaming UI 從第一天就做?(Vercel AI SDK 直接支援)
    • 建議是 — 體感差異大,免費 lift
  5. Weekly digest email 排哪期?
    • Phase 1 MVP 直接做(週一早上自動寄前 7 天總結)— Tableau Pulse 殺手 feature
    • 還是 Phase 3 才做
  6. Audit log + cost tracking 做不做?
    • 建議從 Day 1 做(便宜,但晚做要 retrofit 痛)

總結 — 老闆看這段就好

我的 v1 spec 方向對,但過度工程約 30-40%。真實業界做法更簡單:

  1. 不要分 4 層,就 2 層:「Single LLM + Tools」直接生「UIResponse(Zod 限制)」
  2. 不要自製 manifest 格式,用 Anthropic Tool Use + Vercel AI SDK Generative UI
  3. NotebookLM 不是好對標 — 真正該對標 Tableau Pulse / Snowflake Cortex Analyst / Hex Magic
  4. 從 4-5 個 widget + streaming UI + audit log + weekly digest email 開始,別一次做 12 個 widget
  5. Trust score 別合成單一分數,讓老闆看具體 stats(90 天樣本 / Pearson r=0.61)+ 人話標籤

Phase 0 改 1 週可結束(原本估 1-2 週),因為大部分基礎設施都不用自造:

等老闆回答上面 6 個問題,可以 1-2 週內出 MVP demo。

ChefsMate Spec v2 · 2026-05-18 · 老闆問「v1 好嗎?」的誠實 critique + 業界對標