Agent: 探索者 (
explorer)
Confidence: 68%
Cost: $0.3543
Duration: 1m 22s
Task ID:34f1a317-0037-433a-899c-f5d5d13c5e20
現在我有完整的資訊了。讓我彙整探索報告。
探索主題
grammY Bot 框架的中介軟體設計模式
發現
我們的中介軟體是扁平的線性堆疊(
index.ts:9-14):4 個bot.use()呼叫依序串接。grammY 實際上支援樹狀結構——Composer可以建立分支、巢狀模組、error boundary,但我們完全沒用到。message-handler.ts是 250 行的巨型 handler:plugin routing、intent matching、user tracking、model routing、Claude 呼叫、streaming progress 全部擠在同一個bot.on('message:text')裡。這正是 Composer 模組化要解決的問題——每個關注點應該是獨立的 Composer。grammY 的
Composer.filter()+errorBoundary()組合可以取代我們手動的 if/else 分支。例如:admin 判斷可以用bot.filter(ctx => ctx.from?.id === ADMIN_ID)建立專屬分支,而不是在 handler 內部 if/else。Error boundary 可以做域隔離:目前
errorHandlerMiddleware是全域 try/catch,但 grammY 支援 per-module error boundary。plugin routing 失敗不應該影響到 Claude Code 呼叫——可以各自包在不同的errorBoundary裡。可測試性的關鍵突破:獨立的 Composer 模組可以單獨 unit test——不需要啟動整個 bot,直接
new Composer()→ 注入 mock context → 驗證行為。目前message-handler.ts幾乎無法單元測試。
有趣的連結
- grammY 的
bot.route()可以取代我們的 model routing if/else 分支——根據 route tier 把 update 分流到不同 Composer Composer.lazy()支援動態載入中介軟體——可以讓 plugin hot-reload 更優雅
延伸問題
- 具體重構方案:如何把
message-handler.ts拆成userTrackingComposer→pluginRouterComposer→intentMatchComposer→claudeComposer(admin)的 Composer 樹?每個 Composer 獨立測試。 Composer.lazy()是否能改善 plugin hot-reload?目前用 file-copy cache busting,lazy middleware 可能更乾淨。
重要性:4/5
能直接改善專案品質:message-handler.ts 的可維護性和可測試性是當前瓶頸。拆分成 Composer 樹是低風險、高回報的重構。
★ Insight ─────────────────────────────────────
grammY 的中介軟體不是堆疊,是樹。 大多數教程只教 bot.use(a); bot.use(b) 的線性模式,但 grammY 內部維護的是完整的樹狀結構。Composer 是這棵樹的節點,filter()/on() 建立分支,errorBoundary() 建立隔離域。理解這點後,「一個 250 行的 handler」就可以變成「5 個各 50 行的可測試模組」。
實作路線圖:
1 | bot.use(errorBoundary) // 全域錯誤兜底 |
─────────────────────────────────────────────────