新增程式碼註解:行級評論、建議和關注點
學完你能做什麼
- ✅ 在程式碼 diff 中新增行級註解(comment/suggestion/concern)
- ✅ 為程式碼修改提供建議程式碼(suggestedCode)
- ✅ 標記需要關注的程式碼段(concern)
- ✅ 檢視和管理所有註解(側邊欄)
- ✅ 理解三種註解類型的使用情境
- ✅ 匯出回饋為 Markdown 格式
你現在的困境
問題 1:審查程式碼變更時,只能在終端機看 diff,然後寫「第 3 行有問題」、「建議改成 XXX」,位置不精確。
問題 2:有些程式碼只是想評論一下(comment),有些想提修改建議(suggestion),有些是嚴重問題需要關注(concern),但沒有工具幫你區分。
問題 3:想給某個函式修改建議,但不知道怎麼把程式碼片段傳給 AI。
問題 4:新增了多個註解後,忘記都審查了哪些地方,沒有概覽。
Plannotator 能幫你:
- 點擊行號即可選取程式碼範圍,精確到行
- 三種註解類型(comment/suggestion/concern)分別對應不同情境
- 可以附加建議程式碼,AI 直接看到修改方案
- 側邊欄列出所有註解,一鍵跳轉
什麼時候用這一招
使用情境:
- 執行
/plannotator-review指令後檢視程式碼變更 - 需要對具體程式碼行給出回饋
- 想提供程式碼修改建議給 AI
- 需要標記潛在問題或風險點
不適用情境:
- 審查 AI 產生的實施計畫(使用計畫審查功能)
- 只需要快速瀏覽 diff(使用程式碼審查基礎功能)
🎒 開始前的準備
前置條件:
觸發方式:
- 在 OpenCode 或 Claude Code 中執行
/plannotator-review指令
核心思路
程式碼註解是什麼
程式碼註解是 Plannotator 程式碼審查的核心功能,用於在 Git diff 中新增行級回饋。透過點擊行號選取程式碼範圍,你可以精確地針對具體程式碼行新增評論、建議或關注點,註解會顯示在 diff 下方,便於 AI 準確理解你的回饋意圖。
為什麼需要程式碼註解?
在程式碼審查中,你需要對具體的程式碼行給出回饋。如果只是用文字描述「第 5 行有問題」、「建議改成 XXX」,AI 需要自己去定位程式碼,容易出錯。Plannotator 讓你點擊行號選取程式碼範圍,直接在該位置新增註解,註解會顯示在 diff 下方(GitHub 風格),AI 能準確看到你針對哪段程式碼提出的建議。
運作流程
┌─────────────────┐
│ /plannotator- │ 觸發指令
│ review 指令 │
└────────┬────────┘
│
│ 執行 git diff
▼
┌─────────────────┐
│ Diff Viewer │ ← 顯示程式碼 diff
│ (split/unified) │
└────────┬────────┘
│
│ 點擊行號 / Hover +
▼
┌─────────────────┐
│ 選取程式碼範圍 │
│ (lineStart- │
│ lineEnd) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ 新增註解 │ ← 工具列彈出
│ - Comment │ 填寫評論內容
│ - Suggestion │ 可選:提供建議程式碼
│ - Concern │
└────────┬────────┘
│
▼
┌─────────────────┐
│ 註解顯示 │ 在 diff 下方
│ (GitHub 風格) │ 側邊欄列出所有註解
└────────┬────────┘
│
▼
┌─────────────────┐
│ 匯出回饋 │ Send Feedback
│ (Markdown) │ AI 收到結構化回饋
└─────────────────┘註解類型
Plannotator 支援三種程式碼註解類型,每種都有不同的用途:
| 註解類型 | 用途 | 典型情境 | 建議程式碼 |
|---|---|---|---|
| Comment | 評論某段程式碼,提供一般性回饋 | 「這段邏輯可以簡化」、「變數命名不太清晰」 | 可選 |
| Suggestion | 提供具體的程式碼修改建議 | 「建議用 map 替代 for 迴圈」、「用 await 替代 Promise.then」 | 推薦 |
| Concern | 標記潛在問題或風險點 | 「這個 SQL 查詢可能有效能問題」、「缺少錯誤處理」 | 可選 |
註解類型的選擇建議
- Comment:用於「提建議但不強制」,比如程式碼風格、最佳化方向
- Suggestion:用於「強烈建議修改」,並且你有明確的修改方案
- Concern:用於「必須注意的問題」,比如 bug、效能風險、安全隱患
Comment vs Suggestion vs Concern
| 情境 | 選擇類型 | 範例文字 |
|---|---|---|
| 程式碼可以運作,但有最佳化空間 | Comment | 「這段可以用 async/await 簡化」 |
| 程式碼有明確的改進方案 | Suggestion | 「建議用 Array.from() 替代展開運算子」(附程式碼) |
| 發現 bug 或嚴重問題 | Concern | 「這裡缺少 null 檢查,可能導致執行時期錯誤」 |
跟我做
第 1 步:觸發程式碼審查
在終端機中執行:
/plannotator-review你應該看到:
- 瀏覽器自動開啟程式碼審查介面
- 顯示 git diff 內容(預設是
git diff HEAD) - 左側是檔案樹,中間是 diff viewer,右側是註解側邊欄
第 2 步:瀏覽 diff 內容
在瀏覽器中檢視程式碼變更:
- 預設使用 split 檢視(左右對比)
- 可以切換到 unified 檢視(上下對比)
- 點擊檔案樹中的檔案名稱切換檢視的檔案
第 3 步:選取程式碼行,新增註解
方式一:Hover 點擊「+」按鈕
- 將滑鼠懸停在要新增註解的程式碼行上
- 右側會出現一個 + 按鈕(僅在 diff 行上顯示)
- 點擊 + 按鈕
- 彈出註解工具列
方式二:直接點擊行號
- 點擊某個行號(例如
L10),選取單行 - 點擊另一個行號(例如
L15),選取多行範圍 - 選取範圍後,工具列自動彈出
你應該看到:
- 工具列顯示選取行號(例如
Line 10或Lines 10-15) - 工具列包含文字輸入框(
Leave feedback...) - 可選的「Add suggested code」按鈕
第 4 步:新增 Comment 註解
情境:對程式碼提供建議,但不要求必須修改
- 在工具列的文字框中輸入評論內容
- 可選:點擊 Add suggested code,輸入建議程式碼
- 點擊 Add Comment 按鈕
範例:
評論內容:這個函式的參數命名不太清晰,建議改名為 fetchUserData你應該看到:
- 工具列消失
- 註解顯示在 diff 下方(藍色框)
- 側邊欄中新增一條註解記錄
- 如果提供了建議程式碼,會顯示在註解下方(程式碼區塊格式)
第 5 步:新增 Suggestion 註解
情境:提供明確的程式碼修改方案,希望 AI 直接採用
- 在工具列的文字框中輸入建議說明(可選)
- 點擊 Add suggested code
- 在出現的程式碼輸入框中輸入建議的程式碼
- 點擊 Add Comment 按鈕
範例:
建議說明:使用 async/await 簡化 Promise 鏈
建議程式碼:
async function fetchData() {
const response = await fetch(url);
const data = await response.json();
return data;
}你應該看到:
- 註解顯示在 diff 下方(藍色框)
- 建議程式碼以程式碼區塊形式顯示,帶「Suggested:」標籤
- 側邊欄中顯示建議程式碼的第一行(帶省略號)
第 6 步:新增 Concern 註解
情境:標記潛在問題或風險點,提醒 AI 注意
注意:目前版本的 Plannotator UI 中,註解類型預設為 Comment。如果需要標記 Concern,可以在註解文字中明確說明。
- 在工具列的文字框中輸入關注點說明
- 可以使用
Concern:或⚠️等標記明確這是關注點 - 點擊 Add Comment 按鈕
範例:
Concern: 這裡缺少 null 檢查,如果 user 為 null 會導致執行時期錯誤
建議新增:
if (!user) return null;你應該看到:
- 註解顯示在 diff 下方
- 側邊欄中顯示註解內容
第 7 步:檢視和管理註解
在側邊欄中檢視所有註解:
- 右側邊欄顯示所有註解清單
- 每條註解顯示:
- 檔案名稱(擷取最後一個路徑元件)
- 行號範圍(例如
L10或L10-L15) - 作者(如果是協作審查)
- 時間戳記(例如
5m、2h、1d) - 註解內容(最多顯示 2 行)
- 建議程式碼預覽(第一行)
點擊註解跳轉:
- 在側邊欄中點擊某條註解
- Diff viewer 自動捲動到對應位置
- 該註解被醒目提示
刪除註解:
- 滑鼠懸停在側邊欄中的某條註解上
- 點擊右上角的 × 按鈕
- 註解被刪除,diff 中的醒目提示消失
你應該看到:
- 側邊欄顯示註解數量(例如
Annotations: 3) - 點擊註解後,diff viewer 平滑捲動到對應行
- 刪除註解後,數量更新
第 8 步:匯出回饋
完成所有註解後,點擊頁面底部的 Send Feedback 按鈕。
你應該看到:
- 瀏覽器自動關閉
- 終端機中顯示 Markdown 格式的回饋內容
- AI 收到結構化回饋,可以自動回應
匯出的 Markdown 格式:
# Code Review Feedback
## src/app/api/users.ts
### Line 10 (new)
這段邏輯可以簡化,建議用 async/await
### Lines 15-20 (new)
**Suggested code:**
```typescript
async function fetchUserData() {
const response = await fetch(url);
return await response.json();
}Line 25 (old)
Concern: 這裡缺少 null 檢查,如果 user 為 null 會導致執行時期錯誤
::: tip 複製回饋
如果需要手動複製回饋內容,可以在側邊欄底部點擊 **Copy Feedback** 按鈕,將 Markdown 格式的回饋複製到剪貼簿。
:::
## 檢查點 ✅
完成以上步驟後,你應該能夠:
- [ ] 在程式碼 diff 中點擊行號或 Hover「+」按鈕選取程式碼行
- [ ] 新增 Comment 註解(一般性評論)
- [ ] 新增 Suggestion 註解(附建議程式碼)
- [ ] 新增 Concern 註解(標記潛在問題)
- [ ] 在側邊欄檢視所有註解,點擊跳轉到對應位置
- [ ] 刪除不需要的註解
- [ ] 匯出回饋為 Markdown 格式
- [ ] 複製回饋內容到剪貼簿
**如果某一步失敗**,詳見:
- [常見問題](../../faq/common-problems/)
- [程式碼審查基礎](../code-review-basics/)
- [故障排除](../../faq/troubleshooting/)
## 踩坑提醒
**常見錯誤 1**:點擊行號後,工具列沒有彈出
**原因**:可能點擊的是檔案名稱或行號不在 diff 範圍內。
**解決**:
- 確保點擊的是 diff 行的行號(綠色或紅色行)
- 對於刪除行(紅色),點擊左側的行號
- 對於新增行(綠色),點擊右側的行號
**常見錯誤 2**:選取多行後,註解顯示在錯誤的位置
**原因**:side(old/new)不正確。
**解決**:
- 檢查你選取的是舊程式碼(deletions)還是新程式碼(additions)
- 註解會顯示在範圍最後一行的下方
- 如果位置不對,刪除註解重新新增
**常見錯誤 3**:新增建議程式碼後,程式碼格式錯亂
**原因**:建議程式碼可能包含特殊字元或縮排問題。
**解決**:
- 在建議程式碼輸入框中,確保縮排正確
- 使用等寬字型編輯建議程式碼
- 如果有換行,使用 `Shift + Enter` 而不是直接按 Enter
**常見錯誤 4**:側邊欄中看不到新增的註解
**原因**:側邊欄可能沒有重新整理,或者註解新增到了其他檔案。
**解決**:
- 切換檔案後再切換回來
- 檢查註解是否新增到了目前檢視的檔案
- 重新整理瀏覽器頁面(可能遺失未提交的註解)
**常見錯誤 5**:匯出回饋後,AI 沒有按建議修改
**原因**:AI 可能沒有正確理解註解的意圖,或者建議不可行。
**解決**:
- 使用更明確的註解(Suggestion 比 Comment 更明確)
- 在建議程式碼中新增註解說明原因
- 如果問題持續,可以再次傳送回饋,調整註解內容
## 本課小結
程式碼註解是 Plannotator 程式碼審查的核心功能,讓你可以精確地回饋程式碼問題:
**核心操作**:
1. **觸發**:執行 `/plannotator-review`,瀏覽器自動開啟 diff viewer
2. **瀏覽**:檢視程式碼變更(split/unified 檢視切換)
3. **選取**:點擊行號或 Hover「+」按鈕選取程式碼範圍
4. **註解**:新增 Comment/Suggestion/Concern 註解
5. **管理**:在側邊欄檢視、跳轉、刪除註解
6. **匯出**:Send Feedback,AI 收到結構化回饋
**註解類型**:
- **Comment**:一般性評論,提供建議但不強制
- **Suggestion**:明確建議修改,附建議程式碼
- **Concern**:標記潛在問題或風險點
**最佳實踐**:
- 使用 Suggestion 時,盡量提供完整的可執行程式碼
- 對於效能或安全問題,使用 Concern 標記
- 註解內容要具體,避免模糊描述(如「這個不好」)
- 可以附加圖片輔助說明(使用圖像標註功能)
## 下一課預告
> 下一課我們學習 **[切換 Diff 檢視](../code-review-diff-types/)**。
>
> 你會學到:
> - 如何切換不同的 diff 類型(uncommitted/staged/last commit/branch)
> - 不同 diff 類型的使用情境
> - 如何在多種 diff 類型間快速切換
---
## 附錄:原始碼參考
<details>
<summary><strong>點擊展開檢視原始碼位置</strong></summary>
> 更新時間:2026-01-24
| 功能 | 檔案路徑 | 行號 |
|--- | --- | ---|
| CodeAnnotation 類型定義 | [`packages/ui/types.ts`](https://github.com/backnotprop/plannotator/blob/main/packages/ui/types.ts#L53-L56) | 53-56 |
| CodeAnnotation 介面 | [`packages/ui/types.ts`](https://github.com/backnotprop/plannotator/blob/main/packages/ui/types.ts#L55-L66) | 55-66 |
| DiffViewer 元件 | [`packages/review-editor/components/DiffViewer.tsx`](https://github.com/backnotprop/plannotator/blob/main/packages/review-editor/components/DiffViewer.tsx#L1-L349) | 1-349 |
| ReviewPanel 元件 | [`packages/review-editor/components/ReviewPanel.tsx`](https://github.com/backnotprop/plannotator/blob/main/packages/review-editor/components/ReviewPanel.tsx#L1-L211) | 1-211 |
| 匯出回饋 Markdown | [`packages/review-editor/App.tsx`](https://github.com/backnotprop/plannotator/blob/main/packages/review-editor/App.tsx#L86-L126) | 86-126 |
| Hover「+」按鈕 | [`packages/review-editor/components/DiffViewer.tsx`](https://github.com/backnotprop/plannotator/blob/main/packages/review-editor/components/DiffViewer.tsx#L180-L199) | 180-199 |
| 註解工具列 | [`packages/review-editor/components/DiffViewer.tsx`](https://github.com/backnotprop/plannotator/blob/main/packages/review-editor/components/DiffViewer.tsx#L267-L344) | 267-344 |
| 註解渲染 | [`packages/review-editor/components/DiffViewer.tsx`](https://github.com/backnotprop/plannotator/blob/main/packages/review-editor/components/DiffViewer.tsx#L140-L177) | 140-177 |
**關鍵類型**:
- `CodeAnnotationType`:程式碼註解類型('comment' | 'suggestion' | 'concern')(`packages/ui/types.ts:53`)
- `CodeAnnotation`:程式碼註解介面(`packages/ui/types.ts:55-66`)
- `SelectedLineRange`:選取的程式碼範圍(`packages/ui/types.ts:77-82`)
**關鍵函式**:
- `exportReviewFeedback()`:將註解轉換為 Markdown 格式(`packages/review-editor/App.tsx:86`)
- `renderAnnotation()`:在 diff 中渲染註解(`packages/review-editor/components/DiffViewer.tsx:140`)
- `renderHoverUtility()`:渲染 Hover「+」按鈕(`packages/review-editor/components/DiffViewer.tsx:180`)
**API 路由**:
- `POST /api/feedback`:提交審查回饋(`packages/server/review.ts`)
- `GET /api/diff`:取得 git diff(`packages/server/review.ts:111`)
- `POST /api/diff/switch`:切換 diff 類型(`packages/server/review.ts`)
**業務規則**:
- 預設檢視未提交的 diff(`git diff HEAD`)(`packages/server/review.ts:111`)
- 註解顯示在範圍最後一行的下方(GitHub 風格)(`packages/review-editor/components/DiffViewer.tsx:81`)
- 支援在註解中附加建議程式碼(`suggestedCode` 欄位)(`packages/ui/types.ts:63`)
</details>