Skip to content

新增程式碼註解:行級評論、建議和關注點

學完你能做什麼

  • ✅ 在程式碼 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(使用程式碼審查基礎功能)

🎒 開始前的準備

前置條件

  • ✅ 已安裝 Plannotator CLI(詳見 快速開始
  • ✅ 已學會程式碼審查基礎(詳見 程式碼審查基礎
  • ✅ 本機有 Git 儲存庫,並且有未提交的變更

觸發方式

  • 在 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 步:觸發程式碼審查

在終端機中執行:

bash
/plannotator-review

你應該看到

  1. 瀏覽器自動開啟程式碼審查介面
  2. 顯示 git diff 內容(預設是 git diff HEAD
  3. 左側是檔案樹,中間是 diff viewer,右側是註解側邊欄

第 2 步:瀏覽 diff 內容

在瀏覽器中檢視程式碼變更:

  • 預設使用 split 檢視(左右對比)
  • 可以切換到 unified 檢視(上下對比)
  • 點擊檔案樹中的檔案名稱切換檢視的檔案

第 3 步:選取程式碼行,新增註解

方式一:Hover 點擊「+」按鈕

  1. 將滑鼠懸停在要新增註解的程式碼行上
  2. 右側會出現一個 + 按鈕(僅在 diff 行上顯示)
  3. 點擊 + 按鈕
  4. 彈出註解工具列

方式二:直接點擊行號

  1. 點擊某個行號(例如 L10),選取單行
  2. 點擊另一個行號(例如 L15),選取多行範圍
  3. 選取範圍後,工具列自動彈出

你應該看到

  • 工具列顯示選取行號(例如 Line 10Lines 10-15
  • 工具列包含文字輸入框(Leave feedback...
  • 可選的「Add suggested code」按鈕

第 4 步:新增 Comment 註解

情境:對程式碼提供建議,但不要求必須修改

  1. 在工具列的文字框中輸入評論內容
  2. 可選:點擊 Add suggested code,輸入建議程式碼
  3. 點擊 Add Comment 按鈕

範例

評論內容:這個函式的參數命名不太清晰,建議改名為 fetchUserData

你應該看到

  • 工具列消失
  • 註解顯示在 diff 下方(藍色框)
  • 側邊欄中新增一條註解記錄
  • 如果提供了建議程式碼,會顯示在註解下方(程式碼區塊格式)

第 5 步:新增 Suggestion 註解

情境:提供明確的程式碼修改方案,希望 AI 直接採用

  1. 在工具列的文字框中輸入建議說明(可選)
  2. 點擊 Add suggested code
  3. 在出現的程式碼輸入框中輸入建議的程式碼
  4. 點擊 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,可以在註解文字中明確說明。

  1. 在工具列的文字框中輸入關注點說明
  2. 可以使用 Concern:⚠️ 等標記明確這是關注點
  3. 點擊 Add Comment 按鈕

範例

Concern: 這裡缺少 null 檢查,如果 user 為 null 會導致執行時期錯誤

建議新增:
if (!user) return null;

你應該看到

  • 註解顯示在 diff 下方
  • 側邊欄中顯示註解內容

第 7 步:檢視和管理註解

在側邊欄中檢視所有註解

  1. 右側邊欄顯示所有註解清單
  2. 每條註解顯示:
    • 檔案名稱(擷取最後一個路徑元件)
    • 行號範圍(例如 L10L10-L15
    • 作者(如果是協作審查)
    • 時間戳記(例如 5m2h1d
    • 註解內容(最多顯示 2 行)
    • 建議程式碼預覽(第一行)

點擊註解跳轉

  1. 在側邊欄中點擊某條註解
  2. Diff viewer 自動捲動到對應位置
  3. 該註解被醒目提示

刪除註解

  1. 滑鼠懸停在側邊欄中的某條註解上
  2. 點擊右上角的 × 按鈕
  3. 註解被刪除,diff 中的醒目提示消失

你應該看到

  • 側邊欄顯示註解數量(例如 Annotations: 3
  • 點擊註解後,diff viewer 平滑捲動到對應行
  • 刪除註解後,數量更新

第 8 步:匯出回饋

完成所有註解後,點擊頁面底部的 Send Feedback 按鈕。

你應該看到

  • 瀏覽器自動關閉
  • 終端機中顯示 Markdown 格式的回饋內容
  • AI 收到結構化回饋,可以自動回應

匯出的 Markdown 格式

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>