All checks were successful
CD Pipeline / deploy (push) Successful in 2m55s
ADR-019 Phase 1 (止血):PPT 生成前 probe 資料新鮮度。月初/缺資料期間用戶按 ppt:monthly/daily 不再產出空白報告,改主動 inline keyboard 詢問: - 改看最新有資料的月份/日期(一鍵) - 自訂月份/日期(接 await:date_ppt_*) - 取消 新增 PPTDataInsufficientError exception + _ppt_check_data_freshness() helper。 _generate_ppt_cmd 簽章加 _reply_to=None;_ppt_background 靜默吞此例外。 順手修同檔 :1976/:1993 兩處 store_insight() positional args 錯位 bug — 原本 (date, report_type, ai_text) 對應 signature (insight_type, content, period) 完全錯位,導致 period varchar(50) 被 2000 字 AI 內容截斷、INSERT 失敗、 ai_insights 表寫入永久失敗。改成 kwargs 呼叫。 ADR-019 (Telegram Bot Agentic Conversation Layer) 同步落地,Status: Accepted。 六 Phase 路線圖見 ADR 文件,本 commit 完成 Phase 1。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.3 KiB
6.3 KiB
ADR-019: Telegram Bot Agentic Conversation Layer
- Status: Accepted
- Date: 2026-05-02
- Deciders: 統帥
- Related: ADR-001(三 Agent 學習分工)、ADR-012(Agent Action Ladder)、ADR-015(Telegram Menu Restoration)、ADR-018(四 Agent Control Plane)
Context
ADR-018 已定義 Hermes / NemoTron / OpenClaw / ElephantAlpha 四 Agent control plane 的責任邊界。OpenClaw 是 L3 Strategist,負責高品質策略、報告、長期洞察。
但實作上,Telegram Bot 的互動層完全繞過 OpenClaw 的決策能力:
- 菜單按鈕走快車道 —
cmd:Xcallback (routes/openclaw_bot_routes.py:4412) 直接呼叫寫死 handler(如_generate_ppt_cmd:2189),不經 agent。 - NL chat 是 last-resort fallback —
openclaw_answer:4176已具備 Gemini Function Calling + NIM tool use 能力,但只在用戶輸入文字「沒匹配任何 keyword/state」時才被呼叫(telegram_bot_service.py:933)。 - Rigid default + 靜默空白 —
_generate_ppt_cmd月報分支 line 2293 用now.year, now.month當預設,若 ETL 未進當月資料,PPT 生成「本月業績為零」的虛文,無提示無詢問。 - 無對話 state — 每條訊息獨立,無 multi-turn confirmation、無 carry-over slot。
- EventRouter 覆蓋 1.8% — 21 個 telegram 發送點各自為政(記憶
feedback_agent_action_ladder.md、reference_telegram_endpoints_map.md)。
痛點觸發(2026-05-02 真實事件):用戶在月初 5/2 點 ppt:monthly → 系統預設查 5 月 → DB 最新資料只到 4/25 → AI 老實寫「業績為零」→ PPT 內容大量空白 → 用戶反映「老是異常你都無感嗎」。
Decision
採用「Agent-First Conversation Layer」原則:Telegram Bot 互動層的所有用戶輸入(cmd / menu / NL)都經過 OpenClaw agent 決策層,菜單按鈕降級為「agent suggestion shortcuts」,而非繞過 agent 的快車道。
五條互動原則
| # | 原則 | 含意 |
|---|---|---|
| 1 | 單一決策入口 | 所有 cmd:X / menu:X / NL message 統一進 openclaw_decide(intent, args, ctx),agent 自決下一步動作 |
| 2 | 資料缺口優先告知,不靜默 | Agent 在執行任何資料查詢前,先 probe latest_date() / query_available_*();缺資料時主動 inline ask,不出空白報告 |
| 3 | NL 對話一等公民 | 用戶可用「我要看上個月月報」「最近一週的銷售」等 NL 觸發,與按鈕等價,agent 用 tool calling 解析 |
| 4 | Multi-turn state | 加 services/openclaw_session.py 管 chat_id 對話狀態,支援 carry-over slot(如「剛問月份 → 用戶答 4 → 接續執行」) |
| 5 | EventRouter 統一出口 | 所有 telegram 發送經 EventRouter;agent 的 ask / answer / report 也走同管道,便於去重/降級/重送 |
邊界(不做什麼)
- 不取代 ADR-018 的 control plane 責任分工(仍是四 agent)
- 不繞過 ADR-012 的 L0/L1/L2/L3 信任邊界(高風險 action 仍走 HITL)
- 不重寫 telegram_templates.py(31 個模板繼續用)
- 不改 webhook/polling 雙路徑架構(ADR-008 已定)
- 不改 dedup guard(commit
1a886d9已部署)
範圍
- ✅
routes/openclaw_bot_routes.pycmd dispatch 改造 - ✅
services/telegram_bot_service.pyhandle_message NL → agent 路徑 - ✅ 新增
services/openclaw_session.py對話 state - ✅ 新增
services/openclaw_tools.pyagent tool registry - ✅ EventRouter 21 個發送點遷移(refactor-specialist 範圍)
- ❌ Hermes embedding worker 不動
- ❌ NemoTron / ElephantAlpha 內部邏輯不動
Alternatives Considered
| 方案 | 不採用原因 |
|---|---|
| A. 只補 freshness gate(band-aid) | 同類 bug 散在 daily/weekly/strategy/competitor/promo 多處,補不完,治標不治本 |
| B. 引入外部 agent framework (LangGraph/AutoGen) | 黑盒、難審計、跨 agent 通訊已有 EventRouter 能擴展,不增加依賴 |
| C. 直接 deprecate cmd:X 路徑只留 NL | 用戶習慣按鈕互動,移除會破壞 UX;菜單可以保留為 agent suggestion |
| D. 把 OpenClaw 換成 ElephantAlpha 做對話入口 | ADR-018 已分工:ElephantAlpha 是 orchestrator 不是對話 agent;OpenClaw 才是 |
Consequences
正面:
- PPT 空白等「rigid default」類 bug 一次性根除(agent 主動 detect 缺口)
- NL 對話和按鈕互動統一,用戶體驗一致
- Multi-turn state 讓複雜場景(如「上個月 vs 過去 3 個月」對比)變可能
- EventRouter 覆蓋率 1.8% → 80%,系統可觀測性大幅提升
風險:
- Phase 3 影響 21 個 cmd 行為,需灰度 + feature flag + e2e regression
- Agent 多一層決策,每個 cmd 增加 200-500ms latency(NIM/Gemini call)
- 對話 state 引入新故障面(session race / memory leak)
- 全部完成需 4-6 週工程,期間需保持向下相容
降級策略:
- Agent 失敗 → 回退原 cmd:X 寫死 handler(feature flag off)
- Tool call timeout → 用 cached response or template fallback
- Session lookup fail → 視為新對話,不阻斷主流程
Implementation Plan
分 6 Phase 漸進交付,每 Phase 可獨立上線/回滾:
| Phase | 目標 | 工時 | 可獨立 ship |
|---|---|---|---|
| 0 | 本 ADR + 計畫對齊 | 1h | ✅ |
| 1 | PPT 3 個 handler 補 freshness gate(止血) | 2h | ✅ |
| 2 | OpenClaw tool registry(query_*, ppt 等變 tool) | 1d | ✅ |
| 3 | cmd:X dispatch 接入 agent.decide()(feature flag 灰度) | 2d | ✅ |
| 4 | Multi-turn state(services/openclaw_session.py) | 1d | ✅ |
| 5 | EventRouter 21 發送點遷移(refactor-specialist) | 2-3d | ✅ |
| 6 | Proactive 09:00 資料新鮮度 probe + agent 主動通知 | 1d | ✅ |
每 Phase 後驗收:
- Phase 1: PPT 空白事件 = 0
- Phase 3: 21 cmd regression test pass + agent 接管率 100%
- Phase 5: EventRouter coverage 1.8% → 80%
References
- ADR-001 三 Agent 學習分工
- ADR-012 Agent Action Ladder
- ADR-015 Telegram Menu Restoration
- ADR-018 四 Agent Control Plane
- 記憶:
feedback_agent_action_ladder.md、reference_telegram_endpoints_map.md、feedback_iterative_rollout.md - 觸發事件:2026-05-02 用戶 PPT 月報空白回報