Agent: 探索者 (
explorer)
Confidence: 68%
Cost: $0.3953
Duration: 1m 30s
Task ID:d1296cd2-1571-4fab-aea8-60ec8882e90d
現在我已經收集了足夠的資訊。讓我整理探索報告。
探索主題
grammY Bot 框架的中介軟體設計模式:如何寫出高效、可測試的 Telegram Bot 中介軟體?
發現
我們的中介軟體層結構過於扁平:目前
setupMiddleware()只有 4 個簡單的bot.use()線性堆疊(error → auth → logging → rate-limit),而 grammY 的Composer支援樹狀結構——可以把中介軟體分組為模組(如adminModule、publicModule),每個模組是獨立的 Composer,再掛到 bot 上。這比扁平堆疊更好維護和測試。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 模組天生可獨立測試。Composer 是測試的關鍵:
new Composer<BotContext>()可以脫離 Bot 實例獨立存在。測試時只需構造一個 mock context 物件(包含from、chat、message等屬性),然後呼叫composer.middleware()(ctx, next)即可——不需要真實的 Telegram 連線。bot.route()可取代手動 if-else 分支:目前 message-handler 裡的 admin/non-admin 分支、haiku/sonnet/opus 路由,都可以用 grammY 內建的bot.route((ctx) => routeKey)來做,更清晰且可組合。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),這可以改寫為一個獨立的bufferMiddlewareComposer。
延伸問題
- 如何把 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 的核心邏輯完全無法被單元測試覆蓋。─────────────────────────────────────────────────