探索主題

Agent: 探索者 (explorer)
Confidence: 68%
Cost: $0.3953
Duration: 1m 30s
Task ID: d1296cd2-1571-4fab-aea8-60ec8882e90d


現在我已經收集了足夠的資訊。讓我整理探索報告。


探索主題

grammY Bot 框架的中介軟體設計模式:如何寫出高效、可測試的 Telegram Bot 中介軟體?

發現

  1. 我們的中介軟體層結構過於扁平:目前 setupMiddleware() 只有 4 個簡單的 bot.use() 線性堆疊(error → auth → logging → rate-limit),而 grammY 的 Composer 支援樹狀結構——可以把中介軟體分組為模組(如 adminModulepublicModule),每個模組是獨立的 Composer,再掛到 bot 上。這比扁平堆疊更好維護和測試。

  2. message-handler.ts 有 445 行,混合了太多職責:user tracking、plugin routing、intent matching、model routing、context weaving、streaming progress、buffer merge——全部塞在一個 bot.on('message:text') 裡。grammY 的最佳實踐是用 Composer 把每個功能拆成獨立模組,然後用 bot.use(module) 組合。這些 Composer 模組天生可獨立測試。

  3. Composer 是測試的關鍵new Composer<BotContext>() 可以脫離 Bot 實例獨立存在。測試時只需構造一個 mock context 物件(包含 fromchatmessage 等屬性),然後呼叫 composer.middleware()(ctx, next) 即可——不需要真實的 Telegram 連線。

  4. bot.route() 可取代手動 if-else 分支:目前 message-handler 裡的 admin/non-admin 分支、haiku/sonnet/opus 路由,都可以用 grammY 內建的 bot.route((ctx) => routeKey) 來做,更清晰且可組合。

  5. Transformer Functions 是 API 層中介軟體:我們已經用了 apiThrottler()autoRetry()(在 bot.ts),這是正確的做法。但 transformer 也可以用來做 API 層日誌、cost tracking 等——目前 cost tracking 散落在 message-handler 各處,可以抽成一個 transformer。

有趣的連結

  • grammY 的 Composer 內部實作和 Express/Koa 的中介軟體本質不同:它保留樹狀結構而非壓平成陣列,這意味著 use().use().use() 鏈式呼叫建立的是 parent→child 關係,depth-first traversal,而不是簡單的陣列 push。
  • 我們的 message-handler.ts 某種程度上在手動重建中介軟體功能(buffer merge = 自製的 concurrent queue middleware),這可以改寫為一個獨立的 bufferMiddleware Composer。

延伸問題

  • 如何把 message-handler 拆解成 Composer 模組? 具體方案:trackingComposer(user update + interaction recording)、routingComposer(plugin + intent)、claudeComposer(model routing + context weaving + streaming)。每個可獨立用 vitest 測試。
  • grammY 的 bot.errorBoundary() 是否應該替代我們的 errorHandlerMiddleware 官方文件推薦用 error boundary 做模組級錯誤隔離,而非單一全域 try-catch。

重要性:4/5

★ Insight ─────────────────────────────────────
核心洞察:我們的 message-handler.ts(445 行)是典型的「God Handler」反模式。grammY 的 Composer 設計正是為了解決這個問題——每個 Composer 是一個獨立的中介軟體子樹,可以:(1) 獨立測試 (2) 獨立替換 (3) 有自己的 error boundary。重構方向是把 message-handler 拆成 5-6 個 Composer 模組,每個不超過 100 行,掛到 bot 上就像插拔零件一樣。這不只是風格改善,更能讓我們的中介軟體層可測試性從 0 提升到接近 100%——目前那 4 個 middleware 函式雖然結構清楚,但 message-handler 的核心邏輯完全無法被單元測試覆蓋。
─────────────────────────────────────────────────