本文由 Claude & Grok 協助共創。
過去這兩週,我在 DeepWave 交出了幾件東西:AI 媒合會要用的 13 張 PPTX、要衝創業競賽的 4 分鐘 pitch,以及每週固定的內部營運週報自動化、幾個小工具。這三件事,我沒有一件是直接打開 Claude Code 說「幫我做」就完事的。
我的做法很固定:先在 Claude Cowork 裡搭配對應 skill 寫好一份 handoff,自己再看過一次確認可執行,然後才丟給下游 agent(Claude Code、Claude Design、Gemini 或 ChatGPT)。
寫一份 handoff 大概花我 30 到 60 分鐘,但下游一次就到位,幾乎不用來回改。我現在越來越覺得,這 30 分鐘花得非常值得。
這篇文章我想分享,為什麼我現在做重要事情都這樣做,以及 handoff 真正帶給我的三個好處。最後附上一份我這週實際用的 handoff 範例,你可以直接拿去套用。
Prompt 是戰術指令,Handoff 是策略契約
先說清楚一個我最近才想通的區別。
很多人用 AI 還停在「怎麼寫 prompt」的階段——加 chain-of-thought、few-shot、讓它一步步思考。這些技巧都有用,但它們是戰術層級的:一次用、一次丟、適合小任務。
Handoff 完全是另一回事。它是策略層級的契約。
你在動手之前,把「這件事到底要達成什麼」「給誰看」「有哪些不能破的紀律」「什麼才算真的做完」「哪些路千萬別再走」一次想清楚,寫成一份文件。這份文件不挑模型、不挑 agent,可以重複用,還能一直累積。
這兩個東西的差別很大:
- Prompt 是「我想跟 AI 說一句話」——適合發想、討論、構思、處理較短的事情,例如:翻譯。
- Handoff 是「我要交付一件重要的事」——適合複雜、一次到位的事情,例如:文件、寫程式。
我這篇文章講的就是後面這一種。
好處一:Cowork + skill 讓思考更完整、指令下得更清楚
我自己一個人坐下來想一份 pitch deck,能想到的角度大概有十幾個。但同樣的事,我在 Cowork 裡配上對應的 skill 一起想,能想到的會多兩到三倍。
Skill 的本質,是過去做過的事沉澱下來、被寫成可重複使用的經驗濾網。 它不是 AI 臨場發揮,是過去幾十次成功與失敗累積出來的紀律。
我自己一個人腦storm pitch deck,大概只能想到十幾個角度。
但只要我在 Cowork 裡打開對應的 skill,整個思考馬上就升級。Skill 不是 AI 臨場亂想,而是 DeepWave 過去幾十次成功跟失敗慢慢沉澱下來的實戰方法論。
拿上個月做 pitch 那份 4 分鐘 deck 來舉例。我一開 deepwave-pptx 這個 skill,它就直接把我拉到該想的紀律上:
- 每張 slide 的標題都要是一句完整的話(action title)
- 字級死守 30/20/14pt,標題太長就改文案
- 每張 slide 最多一組 hero 文字
- 留白至少 30%
這些不是 AI 自己發明的,是我們過去撞牆撞出來的血淚經驗。我一個人想的時候,幾乎每次都會漏掉一兩條。但有 skill 提醒,handoff 就會把這些全部寫進去。
更進階的還有 ssd-loop、bd-pipeline-tracker、isms-doc-review、financial-consistency-auditor……每一個 skill 都是一套被驗證過的框架。
這讓我從「我覺得這樣應該 ok」變成「這對齊了我們過去驗證過的最佳做法」。 handoff 最直接的好處,就是讓我在思考的時候更完整、指令下得更清楚。
好處二:同一份 handoff 是「不挑下游的執行契約」
當 handoff 寫得夠清楚,它就變成一份「不挑下游」的執行契約。
我會在丟給 Claude Code 之前,自己再看一次,確認這份命令真的可執行。就像軍官把命令寫清楚、自己再檢查一遍,然後交給士官去執行——但軍官和士官之間還是會對話,讓整個過程更滑順。
這兩週我寫的 handoff,分別丟給:
- Claude Code → 做出 13 張 PPTX
- Claude Design → 做出媒合會 deck 的視覺 mockup
- Gemini / ChatGPT → 幫我把這篇文章辯證出不同版本
- 另一個 Claude Code session → 跑每週營運週報
四個下游,模型不一樣,但它們拿到的都是同一份 handoff,沒有一個會跑回來問「你想要什麼樣子?」
執行速度因此大幅加快。寫 handoff 30-60 分鐘,省下後面三、四個小時的來回。我現在可以很自由地調度不同模型的優勢,同一份 handoff 就能發揮最大效果。
更重要的是,後續如果要改,我只改 handoff,不會直接去動產出的結果。一段時間之後再回頭看,也很清楚要從哪裡改起,整個工作流因此變得可維護、可傳承。
好處三:handoff 慢慢變成自己的方法論資產
這個好處是長期累積的,但對要一直跑的工作流來說,影響最大。
我這兩週寫了三份 handoff,慢慢發現它們都有共通的骨架:
- 一頁速覽
- 商業背景
- 觀眾分析
- 預列 Q&A
- 視覺系統 / 風格紀律
- 產出大綱
- Definition of Done
- 收件人與 owner
我已經把這個骨架做成自己的 skill。下次寫 handoff 不用從零開始,只要填入這次任務的內容就好。每寫一份,就把這套骨架再強化一次。
也就是說:寫 handoff 不只是為這一次任務想清楚,更是為這一類任務一次想清楚。
對組織來說,這件事的意義更大。當大家用同一套 handoff 骨架,公司的經驗就不再只裝在老鳥腦袋裡,而是變成可以傳遞、可複製的資產。
一份真實的 handoff 範例(我本週實際丟給 Claude Code 的)
下面這份是我 2026-05-04 真的丟給 Claude Code 的 handoff,用來修我自己做的 macOS Übersicht widget
# Claude Usage Widget — Refresh Fix Handoff
**日期:** 2026-05-04
**對象:** Claude Code
**承接:** `claude-usage.jsx.off`(Sung Desktop 版本)+ live install at `~/Library/Application Support/Übersicht/widgets/claude-usage.jsx`
**為何插隊:** Refresh button 點下去沒反應、reset countdown 卡住不會 tick、5 分鐘心跳間 user 無法 force fresh fetch。Sung 已從 CPO/CTO 雙視角 review 出根因,現要落地。
---
## 前置事實(已驗證)
- ✅ Widget code 完整 source 在 `~/Desktop/小題目/claude-usage-widget/claude-usage.jsx.off`,464 行,已讀過
- ✅ Live install 路徑為 `~/Library/Application Support/Übersicht/widgets/claude-usage.jsx`(依 close button code 推得)
- ✅ Fetch script 路徑為 `~/.claude/claude-usage-fetch.sh`(widget command line 指定)
- ✅ Widget 用 Übersicht 框架,data flow:`command (interval) → stdout → render(props.output)`
- ✅ Widget 用 React,每個 `refreshFrequency` tick 整棵樹 unmount + remount
- ⚠️ **Fetch script 內容未讀,cache 機制 / `--force` flag 是否存在未驗**
## 設計哲學
這是一個已上 GitHub OSS(`Sung-tsan/claude-usage-ubersicht`)、已被 LinkedIn/Threads 公開推廣的小工具。**不可破壞既有使用者的安裝**。所有改動必須保持向後相容:
- 不改 `command` 的對外介面
- 不改 `~/.claude/claude-usage-widget.json` config schema
- localStorage key 不改名(`claude-usage-widget-pos` / `claude-usage-widget-collapsed` 已有 user 在用)
- Close button 的 `mv .jsx → .jsx.off` 行為保留
---
## 0. 一句話目標
修好 refresh button(按了真的有反應)、修好 reset countdown(每分鐘 tick)、永遠顯示 last-updated timestamp,且不破壞既有 OSS 使用者體驗。
## 1. 硬性約束(不可妥協)
| 項目 | 約束 | 來源 |
|---|---|---|
| 向後相容 | command line / config schema / localStorage key 全部不變 | 已 OSS 公開 |
| Single-file widget | 仍維持單一 `.jsx` 檔案,不引入 build step | Übersicht 慣例 |
| 不引入新依賴 | 只用 `uebersicht` 既有 import + React | 維持 OSS 安裝零摩擦 |
| Refresh 必須真的更新畫面 | 點下去 spinner 停 = 畫面已換新數字 | 本輪核心目標 |
| Reset countdown 必 tick | "resets in 1h 23m" 字串至少每 60s 更新 | 本輪核心目標 |
## 2. 既有資產(不要重做)
可複用:
- `getColor()` / `getStatusLabel()` / `formatTimeLeft()` helpers
- `UsageSection`、`DraggableWidget`、`RefreshButton`、`ToggleButton`、`CloseButton` 結構
- 全部 CSS(除非新功能需要)
- localStorage 持久化機制
**不要重寫 drag logic**——上次已經調過、目前 work,動了會壞。
---
## 0-PRE. 動工前先驗證最大未知數(30 分鐘內)
**為何要先驗:** 整個修法的核心假設是「能從 widget JS 內部觸發 Übersicht re-execute command 並把新 stdout 餵回 render()」。如果這個假設不成立,方案 A/B/C 全部要砍掉重設計。先用 5 分鐘驗證,比寫 200 行白工便宜。
### 0-PRE.1 — 驗證 Übersicht refresh dispatch(必做)
跑下面三條命令,**全部記錄實際輸出**:
```bash
# 1. 確認 Übersicht 跑著
osascript -e 'tell application "Übersicht" to get name'
# 2. 試 widget-targeted refresh(這條成功就用方案 A)
osascript -e 'tell application "Übersicht" to refresh widget "claude-usage-jsx"'
echo "exit code: $?"
# 3. 試全域 refresh(如果 #2 不行,這條 fallback)
osascript -e 'tell application "Übersicht" to refresh'
echo "exit code: $?"
```
也讀一下 Übersicht 的 AppleScript dictionary 確認支援的 verbs:
```bash
osascript -e 'tell application "Übersicht" to get the properties' 2>&1 | head -20
# 或
sdef /Applications/Übersicht.app 2>/dev/null | head -50
```
### 0-PRE.2 — 讀 fetch script,確認 cache 與 force flag 行為
```bash
cat ~/.claude/claude-usage-fetch.sh
```
要回答:
- Cache TTL 多久?寫在哪個檔案?
- 已支援 `--force` flag 了嗎?沒有的話本輪要加
- 輸出是 JSON 直出 stdout 還是讀檔案?
### 0-PRE.3 — 驗證 widget id(refresh widget "X" 的 X 是什麼)
Übersicht 的 widget id 通常是檔名去掉副檔名(`claude-usage-jsx`)但**不同版本可能不同**。檢查 Übersicht 的 status:
```bash
# 試:開 Übersicht 的 web inspector(http://localhost:41416)然後 list widgets
curl -s http://localhost:41416/widgets 2>/dev/null | head -50
```
或在 widget 裡 `console.log(props)` 把 props 結構 dump 出來,看是否含 id。
### GO/NO-GO
**✅ 進 P0 條件:**
- 0-PRE.1 #2 或 #3 至少一條 exit 0
- 0-PRE.2 確認 fetch script 內容
- 0-PRE.3 確認正確的 widget id
**❌ NO-GO 處理:**
- 如果 0-PRE.1 兩條都失敗 → **停手回 Sung**,不要繞路改成 polling 或 hack。可能要走方案 D(用 file-watcher + Uebersicht.dispatch 自行注 props,但這條是最後手段)
- 如果 widget id 抓不到 → **停手回 Sung**,可能要從 Übersicht 設定撈
---
## 3. P0 — Refresh button 真的會更新畫面(核心,估時 45 分鐘)
### P0-1. 在 fetch script 加 `--force` flag
如果 0-PRE.2 確認還沒支援 `--force`:
- 在 `~/.claude/claude-usage-fetch.sh` 增加 `--force` 旗標
- 帶 `--force` 時 bypass 自身 cache,直接打 API
- 不帶 flag 時行為完全不變(向後相容)
- `--force` 仍寫入 cache(讓下次 5-min tick 讀到新值)
**Acceptance:**
- ✅ 不帶 flag 連跑兩次,第二次 `_cached: true`
- ✅ 第二次帶 `--force` 跑,`_cached: false`,`_cache_age_sec: 0`
- ✅ Sung 貼出兩次的 stdout 對照
### P0-2. 改寫 RefreshButton 讓它真的觸發 re-render
依 0-PRE.1 結果擇一:
**方案 A(首選,如果 widget-targeted refresh work):**
```javascript
function RefreshButton() {
const [spinning, setSpinning] = useState(false);
const handleClick = (e) => {
e.stopPropagation();
if (spinning) return;
setSpinning(true);
// 1. force 跑 fetch script bypass cache
// 2. 立刻叫 Übersicht 重跑此 widget 的 command → 觸發 render
run(
'/bin/bash "$HOME/.claude/claude-usage-fetch.sh" --force >/dev/null 2>&1; ' +
'osascript -e \'tell application "Übersicht" to refresh widget "claude-usage-jsx"\''
).finally(() => setSpinning(false));
};
// ... rest unchanged
}
```
**方案 B(fallback,全域 refresh):**
```javascript
run(
'/bin/bash "$HOME/.claude/claude-usage-fetch.sh" --force >/dev/null 2>&1; ' +
'osascript -e \'tell application "Übersicht" to refresh\''
)
```
副作用:會 reload 所有 widget,使用者其他 widget state 會 reset。能用但體感較粗。
**方案 C(如果 0-PRE.3 抓到的 widget id 跟「claude-usage-jsx」不同):**
hardcode 改用實際 id,並在註解標註「id 跟檔名綁定,重命名要同步改」。
### P0-3. Spinner 跨 re-render 持久化
Übersicht 5-min tick 會 unmount + remount,`spinning` state 消失。改用 ref + 一個小 hack:
```javascript
const SPIN_KEY = "claude-usage-widget-refreshing";
const SPIN_TTL_MS = 10_000; // 超過 10 秒視為卡住,重置
function RefreshButton() {
const [spinning, setSpinning] = useState(() => {
const ts = parseInt(localStorage.getItem(SPIN_KEY) || "0", 10);
return ts > 0 && (Date.now() - ts) < SPIN_TTL_MS;
});
const handleClick = (e) => {
e.stopPropagation();
if (spinning) return;
localStorage.setItem(SPIN_KEY, String(Date.now()));
setSpinning(true);
run(/* command from P0-2 */)
.finally(() => {
localStorage.removeItem(SPIN_KEY);
setSpinning(false);
});
};
// ...
}
```
### P0 Acceptance(Sung 親手 verify)
- ✅ Sung 開 widget,按 refresh button → 觀察到 spinner 轉 → spinner 停的同時,數字 / `% utilization` / `cached Xm ago` banner 至少有一個視覺上發生變化
- ✅ Sung 連續快速按 3 次,spinner 不會卡住超過 10 秒
- ✅ Sung 等 5 分鐘讓 Übersicht 自動 tick 一次,畫面正常更新
- ✅ Sung 貼一段 30 秒螢幕錄影或 GIF,顯示「按下 refresh → 數值改變」的完整流程
**這是 HITL gate,不可由 Claude Code 自動 proxy。** Claude Code 不能說「實作完成、可以啟動實測」,必須等 Sung 實際在自己 desktop 點過 + 看到變化才算 done。
---
## 4. P1 — Reset countdown 每分鐘 tick(估時 15 分鐘)
### P1-1. 在 Widget component 加 1-min ticker
`formatTimeLeft()` 只在 render 時計算一次。下次 render 是 5 分鐘後,所以 "resets in 1h 23m" 字串會在那 5 分鐘卡住。
```javascript
function Widget({ output, error }) {
const [, forceTick] = useState(0);
useEffect(() => {
const id = setInterval(() => forceTick(t => t + 1), 60_000);
return () => clearInterval(id);
}, []);
// ... rest unchanged
}
```
### P1 Acceptance
- ✅ Sung 開 widget,盯著 reset countdown 的字串
- ✅ 60 秒內看到 "resets in Xh Ym" 的分鐘數至少 -1
- ✅ Sung 文字回報「我看著它從 1h 23m 跳到 1h 22m」+ 截圖兩張對照
---
## 5. P2 — 永遠顯示 last-updated(估時 30 分鐘)
目前只有 `_cached: true` 時才顯示 cache banner。沒 cache 時 user 不知道資料新不新鮮 = status widget 致命缺陷。
### P2-1. 改 cache banner 為「永遠顯示,差別在文字」
```javascript
const ageSec = data._cache_age_sec || 0;
const ageMin = Math.floor(ageSec / 60);
let freshnessLabel;
if (data._cached) {
freshnessLabel = ageMin < 1 ? "cached < 1m ago" : `cached ${ageMin}m ago`;
} else {
freshnessLabel = "fetched just now";
}
// 永遠 render,不再條件判斷
content = (
<>
{/* sections */}
<div className="cache-banner">{freshnessLabel}</div>
</>
);
```
### P2-2. 把 cache banner 文字也納入 P1 的 1-min ticker
「fetched just now」過 1 分鐘要變「fetched 1m ago」。最簡做法:在 render 時根據 `_cache_age_sec + 從 mount 至今經過的秒數` 計算實際 freshness。
```javascript
// 在 Widget 內
const mountedAtRef = useRef(Date.now());
// ...
const elapsedSinceMount = Math.floor((Date.now() - mountedAtRef.current) / 1000);
const totalAgeSec = (data._cache_age_sec || 0) + elapsedSinceMount;
const totalAgeMin = Math.floor(totalAgeSec / 60);
freshnessLabel = totalAgeMin < 1 ? "updated < 1m ago" : `updated ${totalAgeMin}m ago`;
```
統一文案改成 `updated Xm ago`,不再分 cached / fresh(user 不在乎這個區別)。
### P2 Acceptance
- ✅ Sung 開 widget,cache banner 永遠可見(即使首次 fetch)
- ✅ 點 refresh 後 banner 立刻變 `updated < 1m ago`
- ✅ 等 60 秒,banner 變 `updated 1m ago`
- ✅ Sung 貼 3 張截圖:(1) 首次 load (2) refresh 後 (3) 等 60 秒後
---
## 6. 不在本輪(明確 out of scope)
以下我從 review 提出的問題本輪**不要做**——避免 scope creep:
- 401 / 429 細分錯誤訊息與 retry(CPO #3,留 v0.4)
- 80%/95% 跨閾值推 macOS notification(CPO #4,留 v0.5)
- Close button 確認對話框(CPO #5,留 v0.4)
- 多螢幕 clamp position(CPO #7,留 v0.4)
- 歷史 / 趨勢圖(CPO #8,留 v1.0 大版本)
- `backdrop-filter` 性能優化(CTO #7,沒人抱怨前不動)
- Drag listener 殘留風險(CTO #5,低機率,不修)
如果 Claude Code 動工時忍不住想加上述任何一項,**停下來問 Sung**。不要自己 expand scope。
---
## 7. 風險與心理準備
| 風險 | 機率 | 對策 |
|---|---|---|
| Übersicht widget-targeted refresh 不存在或 verb 不同 | 中 | 0-PRE.1 已先驗;fallback 到方案 B 全域 refresh |
| Widget id 不是 `claude-usage-jsx` | 中 | 0-PRE.3 必驗;hardcode 實際值 |
| Fetch script 沒 `--force` 也沒簡單 cache bypass 機制 | 中 | P0-1 補上;script 應該結構單純 |
| 1-min ticker 跟 5-min Übersicht tick 衝突造成額外重繪 | 低 | `forceTick(t => t + 1)` 只觸發 React re-render,不重跑 command,無實際成本 |
| localStorage `claude-usage-widget-refreshing` key 在多個 Übersicht instance 共用造成衝突 | 極低 | 單一 user 不會跑兩個 Übersicht |
**Fallback 必跑承諾:** 如果 0-PRE.1 #2(widget-targeted)失敗,**必須**實際跑 #3(全域 refresh)並貼 stdout 證明 exit 0,才能下「全域 refresh 不可行」的結論。不可只看 #2 失敗就跳結論。
---
## 8. 預估時程
| 階段 | 估時 | 誰執行 |
|---|---|---|
| 0-PRE 驗證三條 | 15 min | Claude Code(可獨立跑) |
| P0 (refresh fix) 實作 | 45 min | Claude Code |
| P0 acceptance(HITL) | 5 min | **Sung 親手測** |
| P1 (countdown ticker) | 15 min | Claude Code |
| P1 acceptance(HITL) | 2 min | **Sung 盯 60 秒** |
| P2 (last-updated) | 30 min | Claude Code |
| P2 acceptance(HITL) | 5 min | **Sung 截圖對照** |
| **合計** | **~2 hr** | |
---
## 9. Definition of Done
每個 bullet 是「Sung 看到 / 點到 / 驗到什麼」,不是「tests pass」:
- ✅ 0-PRE 三條驗證 stdout 已貼回對話,含 exit code
- ✅ Sung 在自己 desktop 按 refresh button,30 秒內看到數字 / cache banner 視覺更新(含螢幕錄影或 GIF)
- ✅ Sung 連續快按 3 次 refresh,spinner 不卡死(自陳 + 截圖即可)
- ✅ Sung 盯 reset countdown 60 秒,看到分鐘數 -1(兩張截圖)
- ✅ `updated Xm ago` banner 永遠可見(首次載入 / refresh 後 / 等待後 三張截圖)
- ✅ 既有 OSS 使用者跑舊 install 不會壞(手動驗:`mv .jsx.off .jsx`、不改 config、確認 widget 載入正常)
- ✅ Diff 只動到 `claude-usage.jsx` + `claude-usage-fetch.sh` 兩檔;不新增依賴;不改 command line interface
---
## 10. 給 Claude Code 的最後叮嚀
**前幾輪 widget 修改有以下 anti-pattern,本輪盯緊:**
1. **No Silent Scope Cut**:硬性約束(向後相容、單檔、零依賴)不可悄悄降級。如果發現必須引入新依賴或改 command line interface,**停手問 Sung**,不要自己決定。
2. **Test With Real Data**:「Build OK / Lint pass」不是 done。每個 phase 的 acceptance 都要 Sung 在自己 desktop 點過、看過、截圖過。Claude Code 跑不了 Übersicht,所以本輪所有 acceptance 都是 HITL,**不可自行 proxy 說「應該 work」**。
3. **Exhaust Fallback Paths**:handoff §7 寫的 fallback(方案 A 失敗跑方案 B)必須實際跑過。不可從 §0-PRE 結果跳結論「無解」。
4. **A/B Single Variable**:本輪沒有 A/B,但相關紀律——**修 P0 時不要順手改 P1/P2 的東西**,不然出 bug 不知道是哪個 phase 害的。三個 phase 各自 commit,分開驗。
5. **回報格式**:每個 phase 完成回報必含:(a) 改了哪些 line(diff 或行號)、(b) 自己跑過什麼驗證、(c) 哪些 acceptance bullet 還等 Sung 手測。不要寫「P0 完成可以進 P1」這種 vague 句子。
**有疑慮停下來問 Sung,不要自己決定。**
這份手寫得這麼細,看起來像殺雞用牛刀,但它正好示範了前面說的三個好處:
§0-PRE「動工前先驗證最大未知數」 — 我預判整個修法的核心假設可能不成立(能不能從 widget JS 內部觸發 Übersicht re-execute command),所以強制 Code 在動工前先花 15 分鐘驗三條。如果假設不成立,方案 A/B/C 全部要砍掉重設計。先驗 30 分鐘,比寫 200 行白工便宜。 這就是「Cowork + skill 規劃比一個人想得更全面」的具體展現——Cowork 配 CPO/CTO 雙視角 review 的 skill,逼我在動工前把最大未知數攤開來驗。
§9 Definition of Done 寫的不是「tests pass」 — 每個 bullet 都是「Sung 看到 / 點到 / 驗到什麼」,不是「Build OK / Tests passing」。Code 不能自己 proxy 說「應該 work」,必須等我在自己 desktop 點過、看過、截圖過才算 done。「Build OK 不是 done」這條紀律,這份 handoff 是它的活範例。
§10 給 Claude Code 的最後叮嚀 — 把過去幾輪 widget 修改累積出來的 anti-pattern 明文寫進去:No Silent Scope Cut、Test With Real Data、Exhaust Fallback Paths、A/B Single Variable、回報格式要含具體 line 跟驗證紀錄。這就是文章好處三講的「handoff 累積成方法論資產」的最直接證據——這份的 §10 直接複製貼上就能用在我下一份工程類 handoff,連抄都不用改。
handoff 不是萬靈丹
跑了三個月之後,我發現 handoff 的意義比「省時間」還大。
第一,它清楚畫出人跟 AI 之間的責任邊界。AI 做錯,是模型的問題;handoff 沒寫好,才是我的問題。這讓我敢把重要事情交給 AI,不再擔心責任模糊。
第二,它悄悄在改變組織裡的角色。以前一份 pitch deck 要 CEO 想策略、PM 寫 spec、設計師排版……現在我把 handoff 寫好,執行就交給 agent。從「一直澄清需求的人」變成「設計思考框架的人」,組織也因此可以更扁平、產出更高。
第三,當大家越來越習慣用 handoff,它很可能會變成 AI 時代新的協作標準。就像當年的 API spec 一樣,誰的手上有越強、越精準的 handoff 範本庫,誰的團隊就跑得越快。
如果你也在思考 AI 怎麼真正進到你的工作流
過去半年,大家談 AI 還是大多在講「自動化重複工作」。但我在 DeepWave 的真實體會是:AI 真正的槓桿不在「做事更快」,而在「逼你先把事情想清楚」。
它把「做」的成本壓到很低,讓「想」變成最稀缺、最重要的事。Handoff 就是把「想清楚」這個過程,從我腦袋裡搬到一份任何 AI 都能看懂的文件。
有了它,我就同時得到三件事:思考更完整、指令更清楚、執行更快。
如果你是企業決策者、CTO,或正在推動政府數位轉型的朋友,也在思考怎麼讓 AI 不只是工具,而是真正走進決策跟產出流程,歡迎找我聊聊。
我提供 30 分鐘免費 AI 顧問諮詢,不推銷任何產品,只用 DeepWave 這幾個月踩過的坑、累積的 handoff 工作流,陪你一起看看你團隊現在最值得用 AI 優化的那幾個環節。























