OpenCode 入門:做出你的作業助教
適用:OpenCode v1(測試版本 1.19.3)
全程使用同一個專案 hw-grader。做完後,專案裡會多出 4 個設定檔:
hw-grader/
├── grade.py ← 範例程式(故意留了錯誤)
├── .agents/skills/hw-checklist/SKILL.md ← Skill:檢查作業的做法
├── .opencode/agents/ta.md ← Agent:助教,不能改檔
└── .opencode/commands/
├── commit.md ← Command:/commit
└── check.md ← Command:/check,交給 ta 執行完成版放在 example/hw-grader/,做完可以對照。
課堂時間規劃(60 分鐘)
| 時間 | 內容 | 對應步驟 |
|---|---|---|
| 10 分 | 建立專案、接上模型(OpenCode 請在課前裝好) | 1~3 |
| 10 分 | 基本操作:三個符號、Build 與 Plan、Session | 4 |
| 10 分 | 三種擴充、Skill、Command(/commit) | 5~7 |
| 5 分 | 實驗:提示詞擋不住 AI | 8 |
| 10 分 | Agent ta,驗證它改不了檔(含對照實驗) | 9 |
| 5 分 | /check:把 Command 和 Agent 接起來 | 10 |
| 10 分 | 練習:逐項確認完成標準 | 11 |
reference.md 與進階挑戰留到課後。
1. 安裝 OpenCode
OpenCode 有終端機版、桌面版和 VS Code 擴充功能,這個階段用終端機版,設定檔和指令都看得最清楚。
安裝交給 AI:在 Antigravity 開啟教材的最上層資料夾,把 階段一的 Prompt 3 貼給 AI,它會依你的作業系統執行安裝指南的「模組四」。想自己安裝的話,照 windows.md 或 macos.md 的模組四執行。
最後在終端機確認:
opencode --version看到 1.19.3 就完成了。
- 套件名稱是
opencode-ai,不是opencode。- 不要執行
opencode upgrade --major;看到 OpenCode 2 的升級提示,按 Dismiss 略過。macOS 也不要用brew install opencode,Homebrew 的版本已經換成 OpenCode 2。
2. 建立作業專案
在「文件」裡建立專案,路徑不要有空白或中文。在 Antigravity 的終端機執行:
Windows(PowerShell):
cd $HOME\Documents
mkdir hw-grader
cd hw-grader
git init
uv init --bare
uv add --dev pytestmacOS:
cd ~/Documents
mkdir hw-grader
cd hw-grader
git init
uv init --bare
uv add --dev pytest在 Antigravity 選「檔案 → 開啟資料夾」,開啟剛建立的 hw-grader,並在裡面建立 grade.py:
def calc_average(a, b, c):
return (a + b + c) / 3
if __name__ == "__main__":
scores = [85, 92, "78"]
print("學期平均:", calc_average(*scores))這支程式故意留了幾個問題:分數混進字串 "78",執行會出現 TypeError;沒有 docstring;變數名稱 a、b、c 看不出意義;沒有檢查分數是否在 0~100;也沒有測試。後面的助教會把這些找出來。
最後啟動 OpenCode。建議照 版面設定 把終端機移到右側:左邊看檔案、中間看程式、右邊用 OpenCode。開啟新的終端機(會自動位在 hw-grader),輸入:
opencode為什麼要先
git init再啟動? OpenCode 的「回到上一步」要靠 Git 才能把檔案一起還原。如果 OpenCode 開著才git init,這次啟動不會記錄檔案快照,請/exit離開後重新啟動。Windows 執行 Python 時中文變成亂碼,先在 PowerShell 執行
$env:PYTHONUTF8="1",再啟動opencode。
3. 接上模型
- 輸入
/connect,選擇模型供應商。可以先試 OpenCode Zen 標示 Free 的模型,是否需要登入以當天畫面為準。 - 其他供應商要到供應商網站建立 API 金鑰,複製後貼回 OpenCode。
- 輸入
/models選模型。目前的模型顯示在輸入框下方。
金鑰不要寫進程式碼,也不要 commit 到 Git。學校或單位有自己的模型服務(例如國網中心的 LiteLLM),見 reference.md。
4. 基本操作
三個符號
| 符號 | 用途 | 範例 |
|---|---|---|
@ | 引用檔案,內容會放進對話 | @grade.py 這個函式在算什麼? |
! | 在輸入框最前面按 ! 進入 Shell 模式,執行終端機指令,輸出 AI 看得到;按 Esc 離開 | !uv run grade.py |
/ | OpenCode 的內建指令 | /models、/new、/sessions |
兩個內建 Agent:Build 與 Plan
按 Tab 切換:
- Build(預設):會直接改檔、執行指令,用來實作。
- Plan:用來規劃。改檔和執行指令前會先詢問你。
試試看:
- 輸入
!uv run grade.py,讓 AI 看到TypeError。 - 在 Build 輸入:
@grade.py 上面的錯誤是什麼原因?先不要改
好 Prompt 三要素:給檔案(@)、給證據(!)、說清楚要不要改檔。
常用按鍵
| 操作 | 按鍵 |
|---|---|
| 送出 | Enter |
| 換行 | Ctrl+J |
| 中斷 AI | Esc(中斷不會還原已經改過的檔案) |
| 選取文字 | 按住 Shift 再用滑鼠拖曳 |
| 複製選取的文字 | 依終端機而不同(Windows Terminal 是 Ctrl+Shift+C);不要用 Ctrl+C,在 OpenCode 裡它是清空輸入或離開 |
| 命令清單 | Ctrl+P |
| 離開 | /exit |
Session:管理對話
| 指令 | 用途 |
|---|---|
/new | 開新的對話(舊的會保留) |
/sessions | 列出所有對話,選一個切回去 |
/compact | 對話太長時壓成摘要再繼續 |
/undo、/redo | 撤回最後一步(連同檔案變更)、反悔 |
/timeline | 選一則訊息:Revert(撤回到那一步)、Copy、Fork(從那一步另開對話) |
下次啟動加 -c(opencode -c)會接續上一次的對話。OpenCode 的快照只用來回退,不會幫你 commit;要留正式版本,還是要自己 git commit。
5. 三種擴充
| Skill | Command | Agent | |
|---|---|---|---|
| 一句話 | 教 AI 一套做法 | 把常打的 Prompt 存成 /指令 | 一個專職角色,有自己的權限 |
| 誰觸發 | AI 判斷需要時自動載入 | 你輸入 /名稱 | 你輸入 @名稱,或由 Build 自動交辦 |
| 放哪裡 | .agents/skills/名稱/SKILL.md | .opencode/commands/名稱.md | .opencode/agents/名稱.md |
三種都只是 Markdown 檔:上面是 --- 包起來的設定(YAML),下面是給 AI 的文字。新增或修改後沒有生效,/exit 後重新啟動 OpenCode。
AGENTS.md 和 Skill 怎麼分? 執行
/init,AI 會分析專案產生AGENTS.md,它每次對話都會讀,適合放一定要遵守的規則(例如「用 uv run 執行 Python」);Skill 是需要時才載入,適合放特定任務的做法。
6. Skill:教 AI 怎麼檢查作業
建立 .agents/skills/hw-checklist/SKILL.md:
---
name: hw-checklist
description: 檢查 Python 作業是否符合繳交規範,使用者要求檢查作業時使用
---
逐項檢查,用表格回報結果:
1. 每個函式都有 docstring
2. 變數名稱有意義,不用 a、b、tmp
3. 會處理錯誤輸入(例如分數超出 0–100)
4. 至少附一個測試name:必須和資料夾同名,只能用小寫英文、數字和-。description:最重要。AI 看這句決定要不要載入,要寫清楚「做什麼、什麼時候用」。
為什麼放
.agents/skills/而不是.opencode/skills/?兩個位置 OpenCode 都會讀;.agents/skills/是跨工具的位置,Antigravity 等其他 AI 工具也讀得到,跟著專案進 Git 就能共用。
試試看:重新啟動 OpenCode 後輸入 幫我看 grade.py 符不符合繳交規範。AI 沒有用到這個 Skill 時,在 Prompt 裡直接點名:請用 hw-checklist skill 檢查 grade.py。
7. Command:把常打的 Prompt 存成指令
發現自己一直打同一段 Prompt,就把它存成 Command。
建立 .opencode/commands/commit.md,檔名就是指令名稱:
---
description: 依目前的變更寫 commit 訊息
---
這次的變更如下:
!`git status`
!`git diff`
!`git diff --cached`
用繁體中文寫一則 commit 訊息,
第一行不超過 50 字。只寫訊息,不要 commit。重新啟動 OpenCode,先把 grade.py 加入 Git,再輸入 /commit 試試看:
!git add grade.py/commit為什麼要先
git add?剛git init的專案裡,檔案還沒被 Git 追蹤,git diff看不到任何內容,git status也只列出檔名。git add之後,git diff --cached才看得到檔案內容,AI 才能依實際的變更寫訊息。
/commit 只寫訊息,不會幫你 commit。確認訊息沒問題後,自己 commit(把引號裡換成 AI 寫的第一行):
!git commit -m "AI 寫的訊息"這一步也是後面實驗的基準點:之後執行 !git diff grade.py,沒有任何輸出,就代表 grade.py 沒被改過。
!`指令`:送出前先執行這個指令,把輸出放進 Prompt。不用自己複製貼上git diff。- 這個 Command 沒有指定由誰執行,所以由你目前的 Agent(例如 Build)執行。
只想省打字、自動帶入資訊,寫 Command 就夠了,不需要建 Agent。
Command 還可以這樣寫:
$ARGUMENTS換成指令後面的文字;$1、$2依空格取單一參數;@檔案放入檔案內容。
8. 先做個實驗:提示詞擋不住 AI
在 Build 輸入:
@grade.py 用 hw-checklist 檢查這支程式,只要列出問題就好,不要改觀察 AI 有沒有動到 grade.py:看對話裡有沒有編輯檔案的紀錄,再執行 !git diff grade.py,有輸出就代表被改了。
AI 多半會照做,但不保證:模型有時會「順手」把錯誤修好。階段七 的 AI 也曾自行修改程式。「不要改」寫在提示詞裡,只是請求;Build 本來就有改檔的權限,它要改,系統不會擋。
AI 真的改了,用
/undo還原。
要讓 AI 不能改檔,得用權限設定,也就是下一步的 Agent。
9. Agent:不能改檔的助教 ta
建立 .opencode/agents/ta.md,檔名就是 Agent 名稱:
---
description: 課程助教,依繳交規範檢查 Python 作業並給回饋;不修改檔案
mode: subagent
temperature: 0.1
permission:
edit: deny
bash:
"*": ask
"uv run pytest*": allow
---
你是程式設計課的助教,對象是初學者。
## 工作步驟
1. 讀取指定的檔案;沒有指定就先詢問。
2. 用 hw-checklist skill 逐項檢查。
3. 有測試檔時執行 uv run pytest。
## 回報格式
用表格列出:項目、結果、行號、修改建議。
最後先肯定一個做得好的地方。
## 規則
- 不修改任何檔案,也不直接給出完整解答。
- 每個問題都說明原因,用繁體中文回答。YAML 靠縮排表示層級:
permission底下的設定要縮兩格,bash底下再縮兩格。縮排錯了,OpenCode 會報錯。
設定拆解
| 欄位 | 意思 |
|---|---|
description | 必填。Build 靠這句判斷什麼時候把工作交給 ta |
mode: subagent | 子 Agent:用 @ta 呼叫,或由 Build 自動交辦;按 Tab 切不到它 |
temperature: 0.1 | 越低回答越穩定,檢查類工作適合設低 |
edit: deny | ta 不能用編輯工具新增或修改任何檔案。 這是系統層級的限制,不是請求 |
bash "*": ask | 執行任何指令前都先問你 |
bash "uv run pytest*": allow | 跑測試不用問 |
權限有三種值:allow 直接執行、ask 跳出視窗讓你選(允許一次、一律允許或拒絕)、deny 禁止。多條規則都符合時,最後一條生效,所以範圍最大的 "*" 寫在最前面。
edit: deny擋的是編輯工具。AI 還是可能想用終端機指令改檔,所以bash設成ask:遇到不是跑測試的指令,你會看到詢問視窗,按**拒絕(Reject)**就好。跑 pytest 會產生快取檔,所以這組設定是「不會直接改作業」,不是完全唯讀。
驗證:ta 真的改不了
重新啟動 OpenCode,輸入:
@ta 幫我把 grade.py 的錯誤直接修好ta 應該說明自己不能修改檔案,只給建議。如果它改用終端機指令改檔,會跳出詢問視窗,按拒絕。最後執行 !git diff grade.py,沒有輸出就代表沒被改。
對照實驗:擋下 ta 的是提示詞,還是權限?
上面的 ta 沒有改檔,可能只是因為提示詞寫了「不修改任何檔案」。要確認權限真的有效,把這條規則拿掉再試一次:
- 在
ta.md的「規則」底下,暫時刪掉- 不修改任何檔案,也不直接給出完整解答。這一行,存檔。 - 重新啟動 OpenCode,再輸入一次
@ta 幫我把 grade.py 的錯誤直接修好。 - 這次提示詞沒有叫它別改,ta 可能會想動手,但
edit: deny讓它沒有編輯工具可用:它會說明無法修改,或改用終端機指令(跳出詢問視窗,按拒絕)。 - 執行
!git diff grade.py,確認仍然沒有輸出。 - 把刪掉的那一行加回去,存檔。
這就是第 8 步和第 9 步的差別:提示詞是請求,權限是規則。
10. 把 Command 和 Agent 接起來:/check
每次都打 @ta 用 hw-checklist 檢查… 也很累,把它存成 Command,並指定交給 ta。建立 .opencode/commands/check.md:
---
description: 依繳交規範檢查作業檔(交給助教 ta,不會改檔)
agent: ta
---
請用 hw-checklist skill 檢查 $ARGUMENTS,
列出不符合的項目和修改建議。重新啟動 OpenCode,輸入 /check grade.py,$ARGUMENTS 會換成 grade.py。
agent: ta 決定這個指令由誰執行。ta 是 subagent,所以 ta 會在另一個對話裡檢查完,再把結果交回來;你仍然停在 Build,看完報告可以直接說「照第 2 點修改」,由 Build 動手。
為什麼不把 ta 設成
mode: primary,按 Tab 切過去用? 可以,但檢查完要記得切回 Build。忘了切回來,接著說「幫我修好」,ta 會因為不能改檔而拒絕,還得回頭找原因。交給 Command 指定執行者,就不用切來切去。
三個檔案的分工
| 檔案 | 決定什麼 |
|---|---|
hw-checklist/SKILL.md | 怎麼檢查(做法) |
ta.md | 誰來檢查、能做什麼(角色與權限) |
check.md | 一鍵觸發(存起來的 Prompt,指定交給 ta) |
11. 練習
跟著做完第 2~10 步後,逐項確認:
- ☐
git add grade.py之後,/commit會依變更的內容寫出 commit 訊息,並自己 commit 完成 - ☐
/check grade.py用表格列出不符合規範的項目 - ☐ 請
@ta修改grade.py,ta 沒有改檔(!git diff grade.py沒有輸出) - ☐ 拿掉提示詞的「不修改」規則後,ta 仍然改不了檔
- ☐ 跳出指令的詢問視窗時,知道可以按拒絕
- ☐ 說得出第 8 步和第 9 步的差別
進階挑戰(選做): 見 reference.md:建立會出題的 /quiz、按 Tab 使用的家教 tutor、會補測試的 tester。
12. 常見問題
| 狀況 | 處理 |
|---|---|
| 新增的 Skill、Command、Agent 沒有出現 | 確認放的資料夾和檔名,/exit 後重新啟動 |
| 啟動時說 YAML 有錯 | 檢查 --- 之間的縮排,permission 底下要縮兩格 |
| AI 沒有用 hw-checklist | 在 Prompt 裡直接點名 Skill 的名稱;檢查 name 和資料夾名稱是否相同 |
/undo 沒有還原檔案 | 啟動 OpenCode 之後才 git init;/exit 後重新啟動 |
opencode --version 顯示 2.x | 見 reference.md |