
mikan 開發心得:把 AI Coding Agent 搬進聊天室
GitHub: geminixiang/mikan
最近在做一個 side project: mikan
一句話介紹的話,他是一個可以跑在 Slack / Telegram / Discord 上的 AI coding agent
可以在聊天室裡 @ bot,請他讀 repo、跑 command、改 code、查 session,或者透過 /login 把 credential 存進 vault,讓 agent 在 sandbox 裡面使用
p.s. 目前 npm package 叫
@geminixiang/mikan,名字來源沒什麼深意,就是覺得 mikan 很可愛 🍊
這篇文章主要想記錄一下開發心得
不是完整教學,也不是很正式的 architecture review,比較像是做完一輪後,回頭看哪些地方比想像中麻煩、哪些設計還算滿意,以及我對 chat-based coding agent 的一些想法
開發契機
我現在蠻常使用 Claude Code / Pi 這類 coding agent,基本上已經回不太去了
但這些工具大多有一個使用前提: 你坐在 terminal 或 IDE 前面
可是實際工作中,很多事情不是從 terminal 開始,而是從聊天室開始
例如:
- Slack channel 裡有人貼一段 error log
- Telegram 群組有人問「這個 deploy 怎麼壞了」
- Discord 裡有人回報一個 issue
- thread 裡面討論了半天,最後還是要有人回去開 repo 處理
我就開始想,如果 coding agent 不只是 terminal 工具,而是直接住在聊天平台裡,會怎樣?
也就是說,agent 不只是回答「你可以怎麼做」,而是真的可以在當下對話的 context 裡做事
讀檔、改檔、跑測試、回報結果
mikan 就是從這個想法開始的
核心架構

mikan 做到後來,我覺得最重要的設計其實是這句:
chat record、agent session、execution runtime 要分開
一開始很容易把這些東西混在一起
- 聊天平台的歷史 = agent context ?
- tool call 結果要不要直接塞回聊天室 ?
- command 直接在 host 上跑應該沒關係吧 ?
短期看起來都可以,反正 demo 會動
但一旦開始支援 Slack thread、Discord reply、Telegram reply chain,再加上多使用者、多 sandbox、多 credential,這些東西混在一起就會開始爆炸
所以 mikan 後來大概切成這幾層:
- Platform adapters: Slack / Telegram / Discord 原生事件轉成統一格式
- Session orchestration: 判斷這則訊息屬於哪個 agent session
- Agent runner: 載入 model、memory、skills、structured session,然後執行 pi-coding-agent
- Tools: read / bash / edit / write / event 等工具
- Sandbox executor: host、container、image、firecracker、cloudflare bridge
- Vault: credential 不放 workspace,而是在執行時注入 sandbox
如果用比較直覺的方式講:
- 聊天室是入口
- session 是工作記憶
- sandbox 是實際動手的地方
- vault 是 secret 的邊界
這幾個東西分開後,整個系統才比較不會變成一坨
最難的不是串平台 API
原本以為多平台 bot 最麻煩的是串 API
結果不是
真正麻煩的是 session model
Slack 有 thread,Discord 有 reply / thread,Telegram 沒有真正 thread 但有 reply chain。每個平台對「一段對話」的定義都不太一樣
但 agent 需要的是一個穩定的工作上下文
mikan 目前大概是這樣切:
| Platform | Session 規則 |
|---|---|
| Slack | top-level / DM 共用 conversation session,thread 以 conversationId:threadTs 分支 |
| Discord | DM 用 channel,shared channel 的 top-level / reply 依 root message 切 session |
| Telegram | private chat 用 chat,群組靠 top-level message / reply chain 推出 session |
這件事情比我想像中重要很多
如果切太粗,兩個人在同一個 channel 叫 bot 做不同事情,context 會互相污染
如果切太細,每次都像新對話,agent 又完全沒有連續工作能力
所以現在我的感覺是:
chat-based agent 的 session model,基本上就是產品體驗本身
使用者不會在意你底下怎麼存 jsonl
但他一定會在意:「我在這個 thread 繼續回,他到底知不知道我剛剛在講什麼?」
log.jsonl 和 sessions/*.jsonl
mikan 裡面有兩種歷史紀錄
<workspace>/<conversation>/├── log.jsonl # 平台對話紀錄,偏人類可讀└── sessions/ ├── current └── *.jsonl # pi-coding-agent structured sessionlog.jsonl 記的是聊天室裡真的發生了什麼
誰說了什麼、bot 回了什麼、附件是什麼
sessions/*.jsonl 則是 agent 工作時真正需要的 structured context
包含 system prompt、tool calls、tool results、model response
這兩個東西一開始看起來有點重複,但實際上用途完全不同
log.jsonl適合 grep、稽核、debug platform eventsessions/*.jsonl適合恢復 agent 工作狀態- thread / reply scope 可以有自己的 session file
- top-level session 用
current指標管理
做 agent 系統後我越來越覺得,context 不是只有「使用者說了什麼」
agent 中間做過什麼也很重要
它讀了哪些檔案、跑了哪些 command、哪一步失敗,這些都是後續推理的一部分
Sandbox
coding agent 最大的爽點是它可以動手
最大的風險也是它可以動手
所以 mikan 從一開始就把 executor 抽象出來,目前支援幾種模式:
| 模式 | 用途 |
|---|---|
host | 本機開發最方便,但不注入 vault env |
container:<name> | 在既有 Docker container 執行 |
image:<image> | mikan 管理 per-conversation container,目前最推薦 |
firecracker:* | microVM 實驗性支援 |
cloudflare:* | Cloudflare sandbox bridge 實驗性支援 |
目前我會優先選 image:<image>
原因很現實,這是目前成本、維護性、隔離性之間比較合理的平衡
它大概會做到:
- 一個 conversation 對應一個 vault
- 一個 conversation 對應一個 managed container
- container 閒置後可以停掉
- vault env / file credential 只在執行時注入
- container 只能看到必要的 workspace 範圍
這樣 mikan 比較像一個可以多人共用的 agent service,而不是只有我自己在本機玩的 toy project
不過 image:<image> 不是終點,只是目前比較 pragmatic 的 default
我比較希望 mikan 的 sandbox 是一個可以持續強化的 runtime boundary
後續會慢慢看怎麼導入更完整的 sandbox backend,例如:
也就是說,不同部署情境可以選不同隔離等級
本機開發可以簡單一點,團隊共用或正式環境就需要更強的 boundary
o.s. sandbox 永遠不是銀彈,只是讓你比較不容易當場爆炸
只要 agent 可以跑 command,就一定要思考:
- 它能看哪些檔案?
- 它能不能連網?
- 它拿到哪些 credential?
- CPU / memory 要不要限制?
- 它失控時要怎麼停?
這些都不是很潮的功能,但沒有這些東西,agent 很難放心給別人用
Vault
credential 是另一個我很在意的點
如果 agent 要真的做事,它一定會需要 token
例如 GitHub token、雲端憑證、內部 API key 等等
但 secret 最不應該出現的地方就是聊天記錄和 repo workspace
所以 mikan 的 /login 走另一條路:
- 使用者在 DM 裡輸入
/login - mikan 產生一個短效 onboarding link
- 使用者在 web portal 裡填 API key 或走 OAuth
- credential 寫入
--state-dir底下的 vault - agent 執行 command 時,依 conversation / sandbox routing 注入 env 或 mount file
聊天室只負責觸發 login,不承載 secret 本身
這個設計不酷,但我覺得是 agent infra 很重要的底線
Commands
mikan 有一些 chat commands:
/login: credential onboarding/session: 開 read-only web session viewer/new: 重置目前 session/model: 切換模型/pi-auto-reply on|off|status: 控制群組自動回覆/stop: 中止目前執行
一開始我也覺得這些只是功能
後來發現不是
這些其實是 chat UI 裡的 control plane
因為聊天平台不像 terminal
沒有 ctrl-c,沒有 process list,也不一定看得到完整 stdout / stderr
當 agent 開始跑比較久的任務,如果沒有 /stop、/session、/new 這類控制手段,使用者會非常沒安全感
所以 command 的存在,其實是把 bot 從「一個可能亂跑的東西」變成「一個可以被控制的工作單元」
測試
mikan 的測試比我一開始預期多很多
包含 Slack / Telegram / Discord context、command parsing、session policy、sandbox executor、vault routing、login flow、event tool、session viewer 等等
原因很簡單,平台 API 的邊界情境太多
例如同樣是「回覆一則訊息」
Slack thread、Discord reply、Telegram reply chain 對 session 的影響完全不一樣
如果只靠手動測,很快就會壞掉
所以現在比較偏向把 platform event 轉成內部共用型別後,用 fake context 測核心邏輯
不要讓所有測試都真的依賴 Slack / Discord / Telegram API
這應該也是多 adapter 專案的老問題:
外部平台要薄,核心模型要厚
一些心得
1. context 不是越多越好
很多人會把長 context 當萬能解
但在 mikan 這種多 conversation、多 thread 的情境,真正重要的是 scope
錯的 context 比沒有 context 更糟
2. tool result 也是 UX
Agent 不是最後回答一句話就好
它中間讀了什麼、跑了什麼、失敗在哪裡,都會影響使用者信不信任它
所以 tool diagnostics、session viewer、log 這些東西很重要
雖然很無聊,但超重要
3. 不要太早硬抽象平台
Slack / Discord / Telegram 看起來都是 chat,但語意其實差很多
一開始就硬抽象,很容易做出一個看似漂亮,但其實不符合任何平台使用習慣的 interface
mikan 現在比較像是 adapter 裡保留平台差異,進 runtime 前再轉成共同模型
4. Sandbox / Vault 要比功能更早設計
如果等 bot 已經能做一堆事情後,才回頭補 credential isolation 和 sandbox,會很痛苦
Agent 產品最好一開始就想清楚:
- 它可以讀哪些檔案?
- 它可以跑哪些 command?
- 它拿到哪些 secret?
- 多人共用時,secret 會不會混在一起?
- 它失控時怎麼停?
5. Chat UX 和 CLI UX 是兩個世界
CLI 使用者可以忍受很多細節,因為他本來就在控制環境裡
聊天平台使用者期待的是: 我講一句話,它知道要做什麼,做完回報
這迫使 agent 必須更重視狀態、回覆節奏、錯誤訊息和可中止性
目前還不完美
mikan 現在還有很多可以改的地方
- Firecracker / Cloudflare sandbox 還偏實驗性
- 多人協作下的權限模型還可以更細
- session viewer 可以更像 observability console
- 長期 memory 和短期 session 的界線還能再打磨
- 不同模型在聊天平台上的成本與延遲策略還有很多可玩空間
但也因為這樣才好玩
做 mikan 的過程讓我更確定,AI coding agent 不會只停留在 IDE 或 terminal 裡
它會慢慢出現在 issue tracker、chat、CI、incident channel、文件系統裡,變成團隊工作流的一部分
總結
如果用一句話總結 mikan 的開發心得,我會說:
把 AI coding agent 放進聊天室,真正困難的不是讓它回話,而是讓它在正確的 context、正確的權限、正確的執行環境裡工作
LLM 會回答問題只是第一步
要讓它變成可靠的協作夥伴,還需要 session、sandbox、vault、commands、logs、tests 這些不性感但很重要的基礎設施
這些東西做好後,聊天平台就不只是通知工具,而可以變成一個多人共享的 agent workspace
這也是 mikan 想探索的方向





