---
title: "用四種語言寫一個 AI Coding Agent：loop 很簡單，難的是其他所有事"
url: https://geminixiang.com/posts/tiny-agent-four-languages/
description: "tiny-agent 用 TypeScript、Go、Python、Rust 各寫了一個最小 coding agent，還寫成一本繁體中文教學書。記錄為什麼要做、agent loop 其實只有十幾行、真正花時間的 session、recovery、compaction，以及怎麼用 eval 選預設模型。"
published: 2026-10-19
category: "AI Agent"
tags: ["AI Agent", "Coding Agent", "TypeScript", "Go", "Python", "Rust", "MCP"]
---

# 用四種語言寫一個 AI Coding Agent：loop 很簡單，難的是其他所有事

這篇主要想介紹一下 [tiny-agent](https://github.com/geminixiang/tiny-agent)，順便講講做的過程學到什麼

它是用 TypeScript、Go、Python、Rust 各寫一次的最小 AI coding agent，另外整理成一本繁體中文的教學書：[tiny-agent Book](https://tiny-agent.geminixiang.com)

## 為什麼要做

每天都在用 Claude Code、pi 這些 coding agent，用久了會好奇它到底怎麼動的

看別人的原始碼很快就會迷路，功能太多，分不清哪些是核心、哪些是產品包裝

所以我想自己從零寫一個，只留下一個 coding agent 真的需要的東西

一個語言寫完覺得還不夠，想知道哪些設計是跟語言無關的，就乾脆四個都寫了 XD

## agent loop 其實很短

很多人以為 agent 很神秘，其實核心就是一個 while loop

```text
送 messages 給模型
→ 模型回文字：結束
→ 模型要呼叫 tool：執行 tool，把結果塞回 messages，再送一次
```

tool 也只有四個：`bash`、`read`、`write`、`edit`

這樣就能讀 code、改 code、跑測試了

第一版 TypeScript 的 loop 加 tool 一天就寫完了

## 難的是其他所有事

真正花時間的是 loop 以外的東西，這也是書裡大部分篇幅在講的

**session 要撐得過 crash**

agent 跑到一半被 kill 掉，重開之後要能回答：prompt 送出去了嗎？tool 開始執行了嗎？它的副作用可能已經發生了嗎？可以安全重跑嗎？

我最後的做法是先寫 intent、再做 effect，所有事情都 append 到一個 JSONL，resume 的時候從這些紀錄重建狀態（[session design](https://github.com/geminixiang/tiny-agent/blob/main/docs/session-design.md)）

**取消不能留爛攤子**

使用者按 Esc 的時候，正在跑的 bash 要連同整個 process group 一起停掉，session 也要記得這次是被中斷的，不能留一個寫到一半的紀錄

**context 會爆**

對話一長就要 compaction，把舊的內容交給模型摘要，只保留最近幾輪

切點要對齊完整的 turn，不能把 tool call 跟它的結果拆開

這部分我順便比較了 pi、Claude Code、Codex CLI、Gemini CLI 各自怎麼做（[compaction comparison](https://github.com/geminixiang/tiny-agent/blob/main/docs/compaction-comparison.md)），差異比想像中大

**tool 輸出要有上限**

一個 `cat` 大檔案就能把 context 塞滿，所以 bash 輸出超過 2,000 行或 50 KB 只回傳尾巴，完整內容寫到檔案；超過 10 MB 直接把 process 停掉

## 四個語言怎麼保持一致

這是我覺得最有收穫的部分

以 TypeScript 當 reference，其他三個語言要做出「看起來一模一樣」的行為

光靠人眼對照一定會漂掉，所以我把行為寫成共用的 contract 檔，四個語言的測試都跑同一份

例如 bash tool 的 timeout、失敗、截斷、取消，[行為對照表](https://github.com/geminixiang/tiny-agent/blob/main/docs/lang-behavior-matrix.md)上每一格都是「同左」

MCP 一開始有些語言是手寫 protocol，後來全部改回各語言官方的 [MCP](https://modelcontextprotocol.io/) SDK，自己只保留 allowlist、timeout、結果大小限制這些 policy

> p.s. 程式碼行數大概是 Python 3 千多行、TypeScript 5 千、Go 6 千、Rust 1 萬，不是因為 Rust 比較難寫，是它要自己處理的東西真的比較多

## 用 eval 選模型，不要憑感覺

tiny-agent 透過 [OpenRouter](https://openrouter.ai/docs) 打模型，預設用哪個模型我是跑 eval 決定的（[eval history](https://github.com/geminixiang/tiny-agent/blob/main/eval/README.md)）

每個 task 有固定的 fixture 跟隱藏的 verifier，120 秒內通過才算數

同一個 task 對每個候選模型各跑 10 次

| 模型 | 通過 | 中位數時間 | 中位數 token |
|---|---:|---:|---:|
| `openai/gpt-5.6-luna` | 10/10 | 21.0s | 2,712 |
| `deepseek/deepseek-v4-flash-0731` | 10/10 | 29.5s | 8,395 |
| `z-ai/glm-5.3-flash` | 10/10 | 60.6s | 3,754 |
| `qwen/qwen3.8-flash` | 7/10 | 67.0s | 6,958 |

DeepSeek 第一次寫出正確答案其實最快，但時間忽快忽慢，還遇過 timeout

Luna 不是最快寫對的，但最穩、最省 token，寫對之後也最快收尾，所以選它當預設

這只是在我的 task 上的結果，不代表哪個模型比較聰明，provider 的狀況也會變

## 這本書

書是寫給有資料結構、作業系統基礎的資工大三以上學生，從 token、message、context 講起，一路到 tool、skills、durable session、recovery、cancellation、compaction、測試跟 tracing

1. 模型、Token 與 Context
2. 從 LLM 到 Agent
3. 訊息、Transcript 與 Provider Adapter
4. Tool 是 Agent 的手
5. Context、AGENTS.md 與 Skills
6. Durable Session：先記 Intent，再做 Effect
7. Reducer、Planner 與 Recovery
8. Cancellation 與 Durable Compaction
9. 測試、Observability 與安全邊界
10. Committed Lifecycle 與 Phoenix Tracing

很多設計是受 [pi](https://github.com/earendil-works/pi) 啟發的，它的 agent loop、tool 模型、skills 漸進載入都很精簡，很推薦去看原始碼

tiny-agent 不是 pi 的 fork，session 跟 recovery 那塊是自己發展出來的

## 心得

- agent loop 一天就寫得出來，能不能拿來每天用，差在 session、取消、compaction、輸出限制這些地方
- 多語言實作一定要有共用的 contract 測試，不然一定會漂
- 選模型要跑 eval，而且要看穩定度跟 token，不能只看「有沒有寫對」

有興趣的話可以直接 clone 下來玩，四個版本都能 `make install`

## 參考資料

- [geminixiang/tiny-agent](https://github.com/geminixiang/tiny-agent)
- [tiny-agent Book](https://tiny-agent.geminixiang.com)
- [Session design](https://github.com/geminixiang/tiny-agent/blob/main/docs/session-design.md)
- [主流 Coding Agent 長對話壓縮比較](https://github.com/geminixiang/tiny-agent/blob/main/docs/compaction-comparison.md)
- [四語言 Bash 行為矩陣](https://github.com/geminixiang/tiny-agent/blob/main/docs/lang-behavior-matrix.md)
- [Eval history](https://github.com/geminixiang/tiny-agent/blob/main/eval/README.md)
- [pi](https://github.com/earendil-works/pi)、[pi compaction 文件](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/compaction.md)
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [OpenRouter](https://openrouter.ai/docs)

---

## About the author

**Ying Xiang Zhao** (geminixiang) — DevOps Engineer, Taipei, Taiwan.

Ying Xiang Zhao（geminixiang）是住在台北的 DevOps 工程師，工作橫跨雲原生基礎設施、CI/CD、ML 模型部署與全端開發。這個部落格記錄 infra、資安與 AI coding agent 的實戰筆記；作品包含開源專案 mikan（把 AI coding agent 帶進 Slack / Telegram / Discord）與 tiny-agent（用四種語言實作的極簡 coding agent），瀏覽器內的影片編輯器 Studio，並經營旅遊分帳工具 SentriPay。

**Open to work** — DevOps Engineer / Platform Engineer / Site Reliability Engineer / AI Infrastructure Engineer · Taipei, Taiwan / Remote. Résumé: https://geminixiang.com/about/ (JSON: https://geminixiang.com/resume.json)

Topics: DevOps, Cloud Native, Kubernetes, Docker, Terraform, Google Cloud, CI/CD, Security, AI coding agents, ML model deployment, TypeScript, Python

Projects:
- [mikan](https://github.com/geminixiang/mikan) — Self-hosted AI coding agent for Slack, Telegram, Discord and GitHub with per-conversation sandboxes
- [tiny-agent](https://github.com/geminixiang/tiny-agent) — Minimal AI coding agents in TypeScript, Go, Python and Rust, plus a book on how they work
- [SentriPay](https://sentripay.com) — Travel expense splitter with multi-currency conversion and shareable, live-synced trip ledgers
- [Studio](https://studio.geminixiang.com) — Browser-based video editor built on WebCodecs

[About](https://geminixiang.com/about/) · [Résumé](https://geminixiang.com/about/) · [LinkedIn](https://linkedin.com/in/geminixiang/) · [GitHub](https://github.com/geminixiang) · [Twitter](https://x.com/geminixiang)
