Slash Command 進階:讓指令讀懂上下文

用 ! 前綴在 command 中執行 shell 指令,自動注入 diff、檔案內容、測試結果,讓 Claude 拿到真實資訊而非模糊描述


大多數人的 slash command 長這樣:

審查當前改動的程式碼品質,給出具體建議。

這能用,但有個根本限制:Claude 得自己去推斷「當前改動是什麼」。如果你的 command 能主動把上下文注入進去,效果會完全不同。

本文要講的是如何讓 command 變成「有眼睛」的指令——觸發時自動讀取檔案內容、git 狀態、專案資訊,把這些塞進提示詞裡,讓 Claude 不用猜。


核心機制:!`命令` 注入 Shell 輸出

自訂 slash command 支援在提示詞裡內嵌 shell 命令,語法是用反引號包住命令並在前面加驚嘆號:!`命令`。觸發時命令先執行,輸出取代占位符,Claude 收到的是最終拼好的提示詞。

以下是當前的 git diff:

!`git diff HEAD`

請審查這些改動,重點關注邏輯錯誤與安全問題。

多行命令請用圍欄程式碼區塊形式,開頭寫 ```!

```!
node --version
git status --short
```

觸發 /review 時,Claude 收到的實際內容是:

以下是當前的 git diff:

diff --git a/app/models/user.rb b/app/models/user.rb
index 3a2f1c8..9b4e2d1 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -12,6 +12,9 @@ class User < ApplicationRecord
...

請審查這些改動,重點關注邏輯錯誤與安全問題。

不需要你手動複製貼上,command 觸發的瞬間,diff 已經在裡面了。


實用模式

注入當前檔案內容

---
allowed-tools: Bash(cat:*)
---

以下是當前檔案的完整內容:

!`cat $ARGUMENTS`

找出這個檔案裡所有潛在的效能問題,給出具體的行號與改法。

用法:/perf app/models/order.rb

$ARGUMENTS 接收檔案路徑,cat 把內容讀進來注入。Claude 拿到的是真實程式碼,不是「請看當前檔案」這種模糊描述。

allowed-tools 在 frontmatter 裡預先授權了 cat 命令,觸發時不會跳權限確認。沒有這一行的話,每次執行都要手動點「允許」。下面的範例都需要用同樣方式宣告。

注入 git 狀態

當前分支與改動狀態:

!`git status --short`
!`git log --oneline -10`

根據以上資訊,產生一份簡潔的 PR 描述,包含改動內容與動機。

這個 /pr command 不需要你描述「我改了什麼」,它自己會去讀。

注入專案特有資訊

專案技術棧:

!`cat .claude/context/stack.md`

當前資料庫結構(關鍵資料表):

!`head -100 db/schema.rb`

根據以上背景,為 $ARGUMENTS 撰寫符合專案規範的 migration 腳本。

把專案背景資訊提前寫進 .claude/context/ 目錄,command 觸發時按需讀取,不用每次重複描述專案狀況。

動態讀取測試結果

最近一次測試執行結果:

!`bundle exec rspec --format progress 2>&1 | tail -30`

以上是失敗的測試。分析根本原因,給出修復方案,不要改測試本身。

/fix-tests 觸發時直接跑測試、拿結果,Claude 看到的是真實的錯誤訊息。


完整範例:上下文感知的程式碼審查

把上面這些組合起來,/review 可以做到相當精準:

---
description: 審查當前改動,自動注入 diff 與相關背景
allowed-tools: Bash(git diff:*), Bash(cat:*)
---

## 本次改動

!`git diff HEAD`

## 改動涉及的檔案清單

!`git diff HEAD --name-only`

## 專案編碼規範摘要

!`cat .claude/context/coding-standards.md 2>/dev/null || echo "(無規範檔案)"`

---

請審查以上改動:

1. 邏輯正確性:有沒有邊界條件沒處理、邏輯錯誤
2. 安全問題:SQL injection、權限驗證、敏感資訊外洩
3. 規範符合度:是否符合專案編碼規範
4. 可讀性:命名、註解、結構

每個問題請給出檔名、行號、具體建議。沒有問題就說沒有,不要硬湊。

這個 command 不需要你做任何準備——觸發時,diff、檔案清單、編碼規範全部自動注入。


處理命令失敗的情況

Shell 命令可能會失敗(檔案不存在、命令不在 PATH 裡等)。用 || 提供預設值,避免 command 因此中斷:

!`git diff HEAD 2>/dev/null || echo "(無 git 改動或不在 git 倉庫中)"`
!`cat .env.example 2>/dev/null || echo "(無 .env.example 檔案)"`
!`which rspec > /dev/null 2>&1 && bundle exec rspec --dry-run 2>&1 | head -20 || echo "(未偵測到 RSpec)"`

命令失敗時,Claude 收到的是說明文字而不是空白,它可以據此調整回答策略。


效能考量:不要注入太多

! 命令的輸出全部會進入 context window。幾個常見的坑:

不要 cat 整個大檔案

# 危險:可能注入幾萬行
!`cat db/schema.rb`

# 更好:只取需要的部分
!`grep -A 5 "create_table \"orders\"" db/schema.rb`

日誌檔案加上行數限制

!`tail -50 log/development.log`

測試輸出截斷

!`bundle exec rspec 2>&1 | tail -40`

context 越精準,Claude 的回答越好。把整個程式碼庫塞進去不會讓它更聰明,只會讓它迷失在雜訊裡。


與 CLAUDE.md 的分工

常見的問題:專案背景資訊應該放 CLAUDE.md 還是用 ! 動態注入?

判斷標準:

資訊類型 放哪裡
每次都需要的專案背景(技術棧、目錄結構、規範) CLAUDE.md
隨時間變化的狀態(當前 diff、測試結果、檔案內容) ! 動態注入
特定任務才需要的背景(某個模組的設計說明) !cat 按需讀取

CLAUDE.md 是長期的背景知識,! 是任務當下的即時快照。兩者互補,不要重複。


一個完整的 .claude/commands/ 目錄

.claude/
├── commands/
│   ├── review.md        # 審查:注入 diff + 規範
│   ├── test.md          # 寫測試:注入目標檔案
│   ├── fix-tests.md     # 修測試:注入失敗結果
│   ├── pr.md            # PR 描述:注入 git log + status
│   ├── explain.md       # 解釋程式碼:注入檔案內容
│   └── migrate.md       # 寫 migration:注入 schema 片段
├── context/
│   ├── stack.md         # 技術棧說明
│   └── coding-standards.md  # 編碼規範
└── settings.json

context/ 目錄存放靜態背景檔案,供各個 command 按需讀取。這套結構可以直接 commit 進 git,讓團隊共享。


效果對比

靜態 command

請審查當前程式碼改動。

Claude 得先問「改動在哪裡」,或是自己去找,結果不穩定。

上下文感知 command

這是 diff(附實際內容)、這是相關規範(附實際內容),請審查。

Claude 直接開始分析,回答精準,不廢話,不需要來回確認。

差別不在於 Claude 的能力,而在於你給了它多少真實資訊。