用 AGENTS.md 馴服 agent
工作坊上你已經會叫 opencode 幫你寫程式了。但你大概也遇過這些狀況:
- 它用英文回你,你要的是中文
- 它寫
python lab1.py,可是你的環境是 uv,跑起來找不到 numpy - 你叫它「手刻 k-means」,它偷偷
from sklearn.cluster import KMeans交差 - 每開一個新對話,你就要把上面這些規矩再講一次
這章要解決的就是最後一句。AGENTS.md 是一個放在專案根目錄的 Markdown 檔,opencode 每次開始工作都會先讀它。把規矩寫一次,之後每個對話都自動生效。
1. AGENTS.md 是什麼
它就是一個純文字 Markdown 檔,沒有特殊語法、沒有必填欄位。裡面寫的是你希望 agent 每次都遵守的規則:用什麼語言、用什麼指令跑程式、圖存哪裡、什麼事不准做。
opencode 會把這個檔案的內容接在系統提示後面送給模型。所以它的效力等同於「你每次對話開頭都手動貼上這段話」,只是你不用真的貼。
重點觀念:AGENTS.md 是給模型看的,不是給人看的。它不是 README。README 寫給同學看「這專案怎麼跑」,AGENTS.md 寫給 agent 看「你該怎麼動手」。兩者內容可以重疊,但目的不同。
2. opencode 什麼時候讀它
opencode 啟動時會依序尋找規則檔:
- 專案層:從目前目錄往上層逐層找
AGENTS.md(找不到才找CLAUDE.md) - 全域:
~/.config/opencode/AGENTS.md - Claude Code 相容:
~/.claude/CLAUDE.md(除非關閉此相容性)
找到的檔案會一起合併使用,不是只取第一個。同一類別中 AGENTS.md 優先於 CLAUDE.md。
因為是「從目前目錄往上找」,所以有個很實際的後果:
在課前建立的專案資料夾開啟終端機,先確認位置:
pwd
ls
清單裡應有本課程的 AGENTS.md 與 opencode.json。如果沒有,先切回正確的資料夾,不要在目前位置另建一套。
養成習慣:一律 cd 進專案根目錄再打 opencode。 這是初學者最常見的「規則怎麼沒生效」原因。
3. AGENTS.md 與 instructions 設定的關係
你的 opencode.json 目前長這樣:
{
"$schema": "https://opencode.ai/config.json",
"model": "opencode/big-pickle",
"permission": { "bash": "ask", "edit": "ask", "webfetch": "ask" },
"instructions": ["AGENTS.md"]
}
很多人以為是 instructions 這行讓 AGENTS.md 生效的。不是。 根目錄的 AGENTS.md 是自動被找到的,不寫 instructions 也會讀。
instructions 真正的用途是追加其他檔案。它支援三種寫法:
{
"instructions": [
"AGENTS.md",
"docs/math-conventions.md",
".cursor/rules/*.md",
"https://example.com/team-rules.md"
]
}
- 相對路徑(相對於設定檔位置)
- glob 萬用字元(
*.md) - 遠端 URL(有 5 秒逾時限制)
所有 instructions 指到的檔案,會和自動找到的 AGENTS.md 合併在一起。
所以起始專案裡那行 "instructions": ["AGENTS.md"] 其實是多餘的,寫明白一點而已,刪掉也不影響。但如果你之後想把規則拆成好幾個檔(例如 notes-style.md、plot-style.md),就要靠 instructions 把它們掛進來。
設定檔本身也是多層合併的,由低到高:
remote (.well-known/opencode)
→ 全域 ~/.config/opencode/opencode.json
→ OPENCODE_CONFIG 環境變數指定的檔
→ 專案根目錄 opencode.json ← 教材一律用這層
後面的會覆蓋前面同名的鍵。這門課的所有設定都寫在專案根目錄的 opencode.json,這樣你的設定跟著專案走,換台電腦、交作業都不會掉。
.jsonc 是可以包含註解的 JSON 格式;本課程使用專案中的 opencode.json,不需要改全域設定。
4. 全域 vs 專案層的 AGENTS.md
全域 ~/.config/opencode/AGENTS.md | 專案 <專案>/AGENTS.md | |
|---|---|---|
| 適合放 | 你個人的偏好 | 這個專案的技術規則 |
| 例子 | 「一律用繁體中文回答」「解釋時先講結論」 | 「用 uv run python」「圖存 figs/」 |
| 會不會跟著作業一起交 | 不會 | 會(建議進版控) |
| 換專案還在嗎 | 在 | 不在 |
判斷原則很簡單:換一個專案還成立的,放全域;只對這個專案成立的,放專案層。
「用繁體中文」兩邊都可以。放全域你每個專案都不用再寫;放專案層則讓同學拿到你的專案時,也能沿用相同的語言要求。這門課建議放專案層,讓規則和練習檔案一起保存。
5. /init 指令會做什麼
在 opencode 的對話介面裡輸入:
/init
它會掃描專案的重要檔案(pyproject.toml、目錄結構、既有設定等),可能問你幾個問題,然後產生或更新 AGENTS.md,內容涵蓋建置指令、架構、慣例。
什麼時候用:從零開始一個新專案,你懶得自己想要寫什麼,用 /init 生一份草稿再手動改。
/init 可能修改既有的 AGENTS.md。本課程已提供規則,現場不用再執行這個指令。
想在其他專案試 /init,請先完成 Git 安全網,保存目前狀態,再產生草稿並檢查差異。本章先練習閱讀與修改現成規則。
6. 實用寫法:六件值得寫進去的事
以下每一條都對應一個真實會出錯的狀況。
6.1 語言
## 語言
一律使用台灣繁體中文回答。程式碼、變數名稱、函式名稱、套件名稱保留英文。
要寫「保留英文」的部分,否則有些模型會很熱心地把 n_clusters 翻成 叢集數,程式就壞了。
6.2 執行環境(最重要的一條)
## 執行環境
本專案用 uv 管理環境。執行 Python 一律用:
uv run python <檔案>
不要用 `python`、`python3`、`pip install`。要加套件用 `uv add <套件>`。
為什麼這條最重要:你的套件(numpy、sklearn)裝在專案的 .venv/ 裡。直接打 python lab1.py 用的是系統的 Python,看不到那些套件,會噴 ModuleNotFoundError。而 agent 的訓練資料裡絕大多數是 python xxx.py,不特別交代它就會照慣例寫。
同理,pip install 會裝到錯的地方或直接失敗;uv 的做法是 uv add,它會同時更新 pyproject.toml,環境才可重現。
6.3 可重現性
## 可重現性
任何用到隨機性的地方,一律設定 `random_state=0`(或 `np.random.seed(0)`)。
包括但不限於:train_test_split、KMeans、PCA 的 randomized solver、資料洗牌。
這是數學課的硬需求。沒固定亂數種子,你今天跑出來的圖和明天跑出來的不一樣,寫報告時你會不知道要相信哪一張。助教重跑你的程式也對不上你的數字。
6.4 不准偷呼叫現成函式充數
## 不要偷懶呼叫現成函式
如果我要求「手刻」「自己實作」某個方法,就不可以直接呼叫 sklearn 的對應
實作來充數。sklearn 只能當作**對照組**:手刻的結果算完後,可以再跑一次
sklearn 的版本,印出兩者的數值差異來驗證。
這是這門課最容易被 agent 陽奉陰違的一條。你說「幫我實作 PCA」,它回一個包了 sklearn.decomposition.PCA 的三行函式。程式會跑、結果會對,但你什麼都沒學到,作業分數是零。
寫成「sklearn 只能當對照組」比單純寫「不准用 sklearn」更好,因為前者給了 agent 一個合法的替代做法。純禁止的規則容易被繞過,給出路的規則比較會被遵守。
6.5 圖存哪裡
## 圖檔
所有圖存到 `figs/`,用 `matplotlib.pyplot.savefig()`,不要用 `plt.show()`
(這是無視窗環境,`show()` 不會有任何效果)。
檔名用英文小寫加底線,例如 `figs/pca_scree_plot.png`。
plt.show() 在終端機環境裡是靜默無效的:不會報錯,就是什麼都沒發生,然後你以為程式壞了。明確要求 savefig() 到固定目錄,你才找得到圖。
6.6 不准 commit
## 不要做的事
- 不要執行 `git commit`、`git push`,除非我明講。
- 不要改 `pyproject.toml` 以外的設定檔。
- 不要刪除 `figs/` 或 `notes/` 裡既有的檔案。
為什麼不准 agent commit:commit 是你檢查過之後的動作。如果 agent 改完自己就 commit,一般的 git diff 就不再顯示那些修改,需要再到歷史中比較。先看差異再存檔,較容易逐步確認。讓 agent 只負責改,你負責檢查和存檔。
git push 更是絕對不行,那會把東西推到網路上,收不回來。
7. 完整範例(可直接複製)
這是你的起始專案裡那份,可以直接用,也可以照自己的需要改:
# AI-Math 工作坊 專案規則
## 語言
一律使用台灣繁體中文回答。程式碼、變數名稱、函式名稱、套件名稱保留英文。
## 執行環境
本專案用 uv 管理環境。執行 Python **一律**用:
uv run python <檔案>
不要用 `python`、`python3`、`pip install`。要加套件用 `uv add <套件>`。
## 數學程式的規矩
1. **可重現**:任何用到隨機性的地方,一律設定 `random_state=0`(或 `np.random.seed(0)`)。
2. **先說數學,再寫程式**:動手前先用兩三句話說明你要用的公式或演算法步驟。
3. **自己驗證**:寫完數值方法後,必須附一段驗證程式碼,並實際執行、印出比對結果。
不可以只說「應該正確」。
4. **不要偷懶呼叫現成函式**:如果我要求「手刻」某個方法,就不可以直接呼叫
`sklearn` 的對應實作來充數。`sklearn` 只能當作**對照組**。
## 圖檔
所有圖存到 `figs/`,用 `matplotlib.pyplot.savefig()`,不要用 `plt.show()`
(這是無視窗環境,`show()` 不會有任何效果)。
## 筆記
數學筆記寫在 `notes/` 底下的 `.md` 檔,數學式用 `$...$`(行內)與 `$$...$$`(獨立行)。
## 不要做的事
- 不要 `git commit`、`git push`,除非我明講。
- 不要改 `pyproject.toml` 以外的設定檔。
- 不要刪除 `figs/` 或 `notes/` 裡既有的檔案。
注意第 3 條「自己驗證」的寫法:它不只說「要驗證」,還說「必須實際執行、印出比對結果,不可以只說『應該正確』」。這個補充很關鍵。不加的話,agent 常常寫一段驗證程式碼然後直接宣稱通過,根本沒跑。
8. 反例:哪些寫法沒用或有反效果
反例 1:寫得像許願,沒有可判斷的標準
請寫出高品質、優雅、專業的程式碼。
沒用。「高品質」對模型來說沒有可操作的意義,它本來就在盡力產生它認為好的程式碼。這行字佔了 context 卻改變不了任何行為。
改成:說出可以檢查的具體要求。
每個函式都要有 docstring,說明輸入的 shape 與輸出的 shape。
例如:`X: (n_samples, n_features) -> (n_samples, n_components)`
反例 2:寫成「教學」而不是「規則」
PCA 是一種降維方法,它透過計算共變異數矩陣的特徵向量⋯⋯
沒用而且浪費空間。模型知道什麼是 PCA。AGENTS.md 要寫的是你的專案的特殊約定,不是通識教材。
反例 3:太長
塞三千字進去,效果通常比三百字差。規則一多,每條被遵守的機率就下降,而且長規則會擠壓真正重要的內容。
原則:只寫「不講就會做錯」的事。 講了跟沒講一樣的(例如「請寫正確的程式」),刪掉。
反例 4:自相矛盾
不要使用任何第三方套件。
...
用 sklearn 做交叉驗證。
矛盾的規則會讓模型行為變得不可預測,它可能隨機挑一條遵守。寫完整份檔案後從頭讀一次,確認沒有打架的條文。
反例 5:以為 AGENTS.md 能強制執行
這是最重要的一個認知:AGENTS.md 是提示,不是權限控制。
「不要 git push」寫在 AGENTS.md 裡,是請求 agent 不要做;模型絕大多數時候會聽,但不保證。真正的強制要靠 opencode.json 的 permission 設定:
{
"permission": {
"bash": {
"*": "ask",
"git push": "deny",
"git push *": "deny"
}
}
}
設定完成後,用 opencode agent list 檢視解析後的權限。規則以樣式比對,最後一條符合的規則生效,因此一般規則放前面、特例放後面。
注意上面同時寫了 "git push" 和 "git push *" 兩條。前者擋不帶參數的 git push,後者擋 git push origin main 這類帶參數的。兩種形式都明列,閱讀設定時就能看出想限制哪些動作。
permission 的可用值是 "allow"、"ask"、"deny"。除了 bash、edit、webfetch,還有 read、glob、grep、task、skill、websearch、external_directory 等。
心法:想拜託的事寫 AGENTS.md,不能出事的事寫 permission。
9. 怎麼驗證 AGENTS.md 真的生效了
不要憑感覺。有三個層次的檢查。
層次 1:確認 opencode 讀到了你的設定
opencode debug config
起始專案中的輸出例子:
{
"$schema": "https://opencode.ai/config.json",
"model": "opencode/big-pickle",
"permission": {
"bash": "ask",
"edit": "ask",
"webfetch": "ask"
},
"instructions": [
"AGENTS.md"
],
"agent": {},
"mode": {},
"plugin": [],
"command": {},
"username": "phonchi"
}
這證明 opencode 找到了你的專案 opencode.json,模型是 opencode/big-pickle,權限是 ask。
注意這個指令的限制:它顯示的是合併後的設定,不會把 AGENTS.md 的內文印出來。所以它能證明「設定讀到了」,不能證明「規則被遵守了」。要驗證後者,往下看。
層次 2:請它說明執行方式
最快的行為測試,在專案根目錄執行:
opencode run "用一句話回答:依照專案規則,執行 Python 檔案應該用哪一個指令?"
輸出例子:
> build · big-pickle
`uv run python <檔案>`。
這次回答符合語言與執行方式的要求。接下來還要看它是否在實際任務中照做。
回答正確,還不能確認什麼
agent 可能先自己讀檔,再回答規則。這表示它找得到規則,但不能單靠一句回答判斷規則是不是自動載入。也不要只把檔案改名成 .bak 就當成「沒有規則」的對照,agent 仍可能找到它。
對這門課最實用的判斷,是查看下一個實際任務:它是否使用指定的執行方式,輸出是否放在正確位置。
層次 3:實際任務測試
最終還是要看真實行為。先執行 opencode,在互動介面貼上下面的小任務,閱讀並確認寫檔要求:
在 notes/ 寫一個 test.md,裡面用 LaTeX 寫出 PCA 的目標函式,並定義式子裡的符號。
然後檢查:檔案是不是寫在 notes/?數學式是不是用 $$...$$?說明是不是繁體中文?
有任何一項不符,就回頭把 AGENTS.md 那條規則寫得更具體。通常是規則太含糊,不是模型不聽話。
常見「規則沒生效」的原因
| 症狀 | 最可能的原因 | 怎麼修 |
|---|---|---|
| 完全不理會規則 | 不在專案根目錄啟動 opencode | cd 到根目錄再開 |
| 偶爾遵守偶爾不遵守 | 規則太含糊,或整份檔案太長 | 改具體、砍掉不重要的條文 |
| 改了 AGENTS.md 沒反應 | 可能是舊對話的脈絡還在 | 開新對話再試 |
| 某條永遠沒用 | 跟另一條規則矛盾 | 從頭讀一次,找出打架的條文 |
10. 本章重點
AGENTS.md放專案根目錄,自動被讀取,不需要靠instructions宣告。instructions是用來追加其他檔案的(支援相對路徑、glob、遠端 URL)。- 設定多層合併,這門課一律用專案根目錄的
opencode.json。 - 最該寫的規則:語言、
uv run python、random_state=0、不准用 sklearn 充數、圖存figs/、不准 commit。 - 規則要具體可檢查;許願式、教學式、過長、矛盾的寫法都沒用。
- AGENTS.md 是提示不是強制。不能出事的事情要用
permission擋。 - 驗證三層次:
opencode debug config看設定、opencode run問它規則、真實任務看行為。
練習
- 在你的專案跑
opencode debug config,確認model是opencode/big-pickle。 - 跑一次層次 2 的行為測試,確認它答出
uv run python。 - 在 AGENTS.md 加一條你自己的規則(例如「所有
.py檔開頭要有一行註解說明這支程式在做什麼」),開新對話,叫它寫一支小程式,檢查有沒有遵守。 - 想一想:你加的那條規則,應該放 AGENTS.md 還是
permission?為什麼?
資料來源
- https://opencode.ai/docs/rules/ — AGENTS.md 的尋找順序、
instructions設定、/init指令 - https://opencode.ai/docs/config/ — 設定檔位置與多層合併順序、JSONC 支援、變數替換
- https://opencode.ai/docs/permissions/ —
permission的鍵、值與樣式比對規則 - https://learnopencode.com/3-workflow/03-init.html —
/init對既有 AGENTS.md 是「改善而非覆寫」(中文教學站,簡體) - https://learnopencode.com/2-daily/04-global-rules.html — 全域規則路徑、規則熱載入的說法(中文教學站,簡體)