← 返回文章列表

用 Telegram 給多機 AI Agent 做一個可見的指揮面

為什麼還需要一個聊天指揮面

我已經有兩層 agent 協作基礎設施。

第一層是基於 Git 的記憶和交接:規則、長期記憶、項目上下文、agent 之間的異步留言都進倉庫。這一層可靠、可審計、可回放,但它不是實時入口。它適合保存事實,不適合在手機上臨時喊一句「這台機器幫我跑一下」。

第二層是 A2A 這種機器間實時調用:一個 agent 可以把任務派給另一個 agent,等結果回來。這一層解決的是機器到機器的執行通道。

但中間還缺一層:人怎麼進入這張網。

我不想每次都 SSH 到某台機器,也不想在十幾個終端裏找哪個 agent 在線。更自然的入口應該像一個羣:我能看到各台機器在説什麼,能按設備發任務,能在執行中插話,必要時也能把一條任務廣播給所有 agent。

這就是 Telegram 適合的位置。它不是記憶層,也不是執行協議;它是人可見的指揮面。

拓撲:一個大羣,每台機器一個話題

最終的結構很簡單:

Telegram supergroup
  ├─ Topic: control
  │    └─ control bot -> control machine agent
  ├─ Topic: laptop
  │    └─ laptop bot -> laptop agent
  ├─ Topic: cloud
  │    └─ cloud bot -> cloud agent
  └─ Topic: phone
       └─ phone bot -> phone agent

這裏有兩個關鍵選擇。

第一,每台機器一個 bot。 不要讓多台機器共用同一個 Telegram bot token。Telegram 的 long polling 對同一個 token 只能有一個消費者,多機共用會互相搶 getUpdates,最後表現成某台機器突然收不到消息。多個 bot 在同一個羣裏沒有問題,前提是每個 bot 有自己的 token。

第二,用 topic 做設備路由。 羣是共同的觀察面,topic 是設備的邊界。某台機器的 bot 只處理自己 topic 裏的消息,別的 topic 靜默忽略。這樣就不會出現「我在羣裏説一句話,所有機器一起搶答」。

Telegram bot 的幾個真實坑

Telegram 的接入並不複雜,但有幾個坑很容易浪費時間。

Group Privacy 默認會擋掉羣消息。 新建 bot 後,如果沒有在 BotFather 裏關閉 Group Privacy,bot 在羣裏只能看到非常有限的消息。最迷惑的是:這個狀態可能在 bot 加羣時被緩存。正確順序是先關閉隱私模式,再把 bot 加進羣;如果順序反了,就把 bot 移出羣后重新加入,或者把它設為羣管理員。

chat 白名單和 topic 白名單是兩層門。 用户白名單隻能説明「誰可以操作」,不能替代「在哪個羣、哪個話題響應」。羣消息要同時經過 chat 和 topic 的過濾。發錯 topic 時,最常見的現象不是報錯,而是靜默丟棄。

手動調 getUpdates 會和 gateway 搶輪詢。 排查時用它拿 user id 或看 poller 是否還活着沒問題,但要知道它會和正在運行的 gateway 競爭同一個 long polling。健康的 gateway 佔着輪詢時,手動請求看到衝突反而可能是好信號;如果一直空返回,才要懷疑 gateway 沒在真正收消息。

進程活着不等於 poller 活着。 有些故障裏 gateway 進程還在,狀態文件也看起來正常,但底層長輪詢已經停了。只用 pgrep 做健康檢查會漏掉這種半死狀態。更可靠的檢查應該包含應用層信號:消息是否真的被拉取、是否還在佔用 long polling、是否能回應一條只讀測試。

常駐問題:手機和服務器不是同一種環境

在標準 Linux 服務器上,gateway 常駐可以交給 systemd。寫一個 unit,設置 restart policy,開機自啓,這件事就結束了。

但手機上的 Linux 子系統不是標準服務器。沒有 systemd,沒有 cron,進程還可能被宿主系統電池策略回收。這裏就不能照搬服務器思路。

我最後用的是四層兜底:

開機觸發
  -> 前台 holder 保持子系統會話
  -> keepalive watchdog
  -> ensure 腳本做冪等啓動
  -> gateway 前台長輪詢

這套結構的重點不是腳本名字,而是職責拆開:

  • ensure 只負責「如果沒起來,就用脱離當前 shell 的方式啓動」。
  • keepalive 負責「進程或應用層健康失敗時拉起」。
  • 開機觸發負責「設備重啓後恢復」。
  • shell 啓動鈎子負責「人工進入環境時順手自愈」。

還有一個很小但很致命的坑:不要隨手寫 pkill -f "some command"。它可能匹配到正在執行這條命令的 shell 自己,導致排障命令把自己殺掉。按 pid 操作,或者用不會自匹配的模式。

安全邊界:這是能驅動本機 shell 的入口

Telegram 看起來只是聊天工具,但這條鏈路背後連的是本機 agent,agent 又可能驅動 terminal。換句話説,這不是普通 bot,這是遠程操作入口。

所以安全約束必須前置:

  • bot token 只放本機密鑰文件,不寫進倉庫、文章、提交信息。
  • 只允許明確的用户 id。
  • 只允許明確的羣。
  • 只允許明確的 topic。
  • 不讓陌生羣和陌生用户觸發本機 agent。
  • 公網服務至少要有 TLS 和可輪換的 bearer token。
  • 真正執行 shell 的工具要儘量收窄權限,不能把「聊天入口」等同於「無限制遠程 root」。

這類系統的危險不在於單條命令,而在於鏈路太順:手機上發一句話,遠端機器真的執行了。順是優點,也是風險。

它和 A2A、Git 記憶的分工

現在回頭看,三層分工很清楚。

Git 記憶層解決的是:長期事實、規則、項目上下文和跨會話交接放在哪裏。它慢,但可靠。

A2A 數據層解決的是:機器之間怎麼實時派發任務和拿結果。它快,但更像執行通道。

Telegram 指揮面解決的是:人怎麼觀察、插話、派活、臨時接管。它不是事實源,也不應該承擔最終審計;它只是讓這張網變得可操作。

這三個東西混在一起會出問題。把 Telegram 當記憶庫,會丟上下文;把 Git 當實時指揮面,會太慢;把 A2A 當人類入口,又缺少可見性和插話能力。

正確的組合應該是:

Telegram = 人類可見指揮面
Git       = 長期記憶與審計面
A2A       = 機器間實時執行面

最大的收穫:先把路由和可見性做好

這次接入看似是在「把 bot 接進羣」,本質上是在給多機 agent 系統補一層操作枱。

如果沒有 topic 路由,羣會變成噪音池;如果沒有白名單,羣會變成風險入口;如果沒有常駐和健康檢查,羣會變成一個看似在線、實際半死的假入口;如果沒有 Git 記憶和 A2A 執行層,羣又只剩聊天,沒有系統能力。

所以這層的設計重點不是酷炫,而是四個字:可見、可控。

可見,是我能知道哪台機器在響應、哪條任務去了哪裏。可控,是我能把任務限制在正確的羣、正確的話題、正確的用户和正確的執行面裏。

多 agent 系統越往後走,越不像「開幾個 AI 聊天窗口」,越像在維護一組有權限、有狀態、有網絡拓撲的自動化節點。Telegram 只是入口,但入口設計不好,後面的系統能力就會變成不可控的黑箱。