# ADR-094: Hermes 自然語言介面（@mention 對話）

> **狀態**: 🟡 批准實作中
> **日期**: 2026-04-24
> **決策者**: 統帥 + 12-Agent 全景分析團隊

## 背景

Hermes 目前是 AWOOOI 的 rule quality scanner（`apps/api/src/jobs/hermes_rule_quality_job.py`，每日 04:00 用 LLM 分析噪音規則），**不是對話型 bot**。

使用者需求：把 Hermes 升級為 SRE 戰情室群組中的**自然語言對話入口**，團隊成員可 `@Hermes` 問任何 SRE 問題，系統自動派對應 Claude Code subagent 回答。

Web Research 查證（Telegram Bot API 官方文件）：
- **Bot-to-bot 訊息永遠互不可讀**（即使關 privacy、設 admin）→ 12 獨立 bot 方案不可行
- `editMessage` **48h 硬上限** → pending 卡跨日需 `copyMessage` fallback
- `setWebhook` 需 `secret_token` 防偽
- `allowed_updates` 需明列 `chat_member` 才能收群組成員變動

## 決策

**方案 C：單 bot + Claude Agent SDK 虛擬分派**。

1. **對外**：沿用既有 `OPENCLAW_TG_BOT_TOKEN`，不新增 BotFather bot 帳號
2. **Webhook**：新增 `/api/v1/telegram/webhook` 取代/共存 Long Polling（ADR-091 §4），含：
   - `secret_token` header 驗證
   - `allowed_updates=["message","callback_query","chat_member","my_chat_member"]`
3. **意圖路由**（`apps/api/src/hermes/router.py`）：
   - Layer 1 規則引擎（關鍵字正則，<10ms）
   - Layer 2 LLM 分類（Haiku，<1s，觸發條件 confidence<0.6）
   - Layer 3 default = `debugger`（最常見「X 為什麼壞了」）
4. **SDK 共存**（**不替換** `ai_router.py`）：
   - ADR-082 Phase 2 incident 決策仍走 `ai_router.py`（Ollama/NIM）
   - Hermes NL 走 `claude-agent-sdk`（Anthropic API，需 allowlist）
   - 兩者透過 `HERMES_ENABLED` feature flag 切換

## 理由

### 為什麼不多 bot（方案 B 否決）
- Telegram API 硬性封鎖 bot-to-bot 訊息 → 12 獨立 bot 後端要用 Redis message bus 繞路
- 單人維運 12 token 違反最小憑證面（`feedback_secrets_leak_incidents_2026-04-18`）
- 方案 C 從方案 A/B 的遷移都是**單向相容**的（可後加 bot），但 B→C 要回收 12 bot 麻煩

### Prompt Injection 防護（P0-2 修）
- NL 輸入 → 意圖分類**只允** `query/describe/summarize`
- `mutate/approve/deploy` 動作必須走 `ApprovalRecord` 二次確認
- `danger:*`（`rm -rf` / force push）直接硬拒
- system prompt 前置 `<user_input>...</user_input>` 隔離標籤
- SanitizationService 擴充 12 pattern（既有 LOGBOOK L956）

### 多輪對話（context engineering）
- **短期記憶**（當前 session）：Redis Hash `hermes:session:{chat_id}:{user_id}`，TTL 300s
- **Compaction**：turn ≥5 觸發 summary 壓縮節省 60% token
- **長期記憶**：未來 v2 PostgreSQL `hermes_user_memory` 表

## 後果

### 優點
- 對話體感延遲 <3s（首字元）
- 零新增 Telegram bot，沿用現有 `httpx` 裸打 API 架構（切換成本零）
- `claude-agent-sdk>=0.1.50` 已在 `pyproject.toml` 宣告，無新依賴

### 缺點
- LLM 費用增加（Anthropic Sonnet/Opus API）→ 需 per-user 每小時 10 query 速率限制 + 月度 budget hard cap
- Hermes 現有 scanner job 命名空間與新服務衝突 → 新檔改名 `hermes_nl_gateway.py`（避開 `hermes_service.py`）
- `claude-agent-sdk` 的 `.claude/agents/*.md` **在 SDK 不會自動載入**，需自寫 loader

### 風險
- **LLM 幻覺** → 新增 `hermes_dispatch_log` audit 表 + P95 confidence 監控（ADR-092 Evidence-First Protocol）
- **Rate limit 撞牆** → Redis token bucket per chat_id（20/min 群組上限，預留 5/min buffer）
- **成本失控** → Langfuse trace + per-user budget

## Rollback

Feature flag `HERMES_NL_ENABLED=off` → Hermes 退回純 scanner 模式，不接 Telegram webhook。
SDK 延遲 > 10s P95 → 自動降級 `debugger` agent 預設回覆。

## 參考

- 上位：[ADR-050](ADR-050-telegram-interactive-incident-v2.md) / [ADR-091](ADR-091-telegram-subsystem-round3.md)
- 平行：[ADR-093](ADR-093-telegram-group-migration.md) / [ADR-095](ADR-095-12agent-sdk-integration.md)
- Claude Agent SDK: https://code.claude.com/docs/en/agent-sdk/python
- Anthropic Context Engineering: https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
- 設計: `/Users/ogt/awoooi/docs/design/hermes-telegram-flows/hermes-flows.html`（Flow 1-7）

## 變更紀錄

| 版本 | 日期 | 執行者 | 變更內容 |
|------|------|--------|---------|
| v1.0 | 2026-04-24 | 12-Agent 全景分析 | 初版 Proposed |
| v1.1 | 2026-04-25 | Claude Sonnet 4.6 | WS4 實作完成：hermes/ 套件 + NL gateway + SDK 接入 + dispatch_log + rate limit + session |
