# 用 Claude Code 的 routine 把已標記的 Issue 變成沙箱裡的 PR — 但無法追問

> 用兩個用完即丟的 GitHub Issue 測試 Claude Code 的雲端 routine：標記一個就能從沙箱拿到真正的 PR，但 routine 沒有 AskUserQuestion 這個工具。

- Source: https://oharu121.com/zh-tw/blog/claude-code-routines-github-issue-pr-sandbox-askuserquestion/
- Published: 2026-08-23T08:20:26+09:00
- Updated: 2026-08-24T16:49:12+09:00
- Tags: Claude Code, Claude Routines, 自動化, AI 智能體

---
**重點摘要**

- 幫 GitHub Issue 加上標籤，讓 Claude Code 的 routine 複製 repo、完成工作並開出 pull request，第一次正式測試就順利完成，完全不需要人在旁邊看著。
- routine 完全沒有 `AskUserQuestion` 這個工具。不是被停用，而是根本不在工具清單裡。真的碰到需要判斷的時刻，routine 只能停下來回報，無法暫停等待。
- 自己開的、自己盯著看的即時 session，無法驗證無人值守的路徑。會混淆這兩件事，是因為重新讀過那個測試原本該證明什麼之後才發現的。
- Anthropic 自己的文件把推播通知限定在需要讓機器保持開機的 Remote Control 上。但一個卡住的 routine 執行，還是把通知送到了手機上，這是文件沒有解釋的地方。
- 既然工具不存在，routine 的提示詞就必須寫成一份完整的規格，連不確定的情況都要先想好備案，而不是留著什麼可以問的空間。
- 第三次測試改用隨選 session 而不是 routine，確認 `AskUserQuestion` 在那裡確實可以正常運作：推播通知、原生的問題卡片，還有隔了十二分鐘之後正確地繼續執行。這個限制是 routine 特有的。

## 引言

我聽說 Claude Code 現在提供一種大家稱為「cowork」的雲端功能：啟動一個沙箱，交給它一個 GitHub Issue，就算不讓機器保持開機，也能從手機上看到結果。在真的把重要的事交給它之前，我想知道這個工作流程實際上每天是怎麼運作的，而不只是宣傳詞說的那樣，因為這個部落格已經有一套發布流程，裡面藏著不少陷阱，我不想在沒人看著的情況下讓 routine 悄悄把事情做錯。經過兩個用完即丟的 GitHub Issue，答案落在一個缺少的工具上：**Claude Code 的 routine 完全無法呼叫 `AskUserQuestion`**，而這正是「幫 Issue 加標籤、剩下的交給它」這句話沒有告訴你的事。這篇文章會談到最先遇到的設定摩擦、一個原本設計錯誤、要是沒被抓出來就什麼也證明不了的測試、這個發現本身、一個明明文件說不該出現卻還是到來的通知，以及在這個限制之下，這個部落格真正值得交給 routine 去做的事。

## 沒有出現的私有 repo

第一個卡關的地方，其實還跟 routine 無關。這個部落格的 repo 是私有的，在 `claude.ai/code` 的 repo 選單裡完全沒有出現：輸入名稱只換來一句「No repos match」。

*Image: Claude Code on the web 的 repo 選單，輸入部分 repo 名稱後顯示「No repos match」*

*在重新設定 GitHub App 的存取權之前，repo 搜尋什麼都找不到。*

**私有 repo 本身是支援的，這個 repo 只是不在授權存取的 app 範圍裡而已。** Claude GitHub App 在安裝時會問，要看到帳號底下的所有 repo，還是只看選定的清單，而這個 repo 當時並不在那份清單裡。

*Image: GitHub 的「Install & Authorize Claude」畫面，有 All repositories 和 Only select repositories 兩個選項，目前選的是 All repositories*

*決定 app（以及 Claude Code on the web）能存取哪些 repo 的安裝畫面。*

在 `github.com/settings/installations` 重新設定 app 的 repo 存取權並重新連接後就解決了。**這也是一個獨立於這次修正之外、有紀錄可查的常見問題。** Anthropic 自己的 issue tracker 上有好幾筆回報，說明明 app 確實有存取權的私有 repo，還是不會出現，或是會斷斷續續消失，讀起來比較像後端索引的問題，而不是帳號設定哪裡出錯。

## 貼上標籤就合併的用完即丟檔案

repo 可以存取之後，第一次正式測試用的是 routine：一份儲存好的提示詞加上一個 GitHub 觸發條件，在 `claude.ai/code/routines` 設定一次就好。這次沒有寫針對單一任務的提示詞，**routine 的指示刻意寫得很通用：讀取觸發這次執行的 GitHub Issue，並且完全照著它說的做。**

*Image: Claude Code 的 routine 建立表單，Instructions 欄位寫著「讀取觸發這次執行的 GitHub Issue，並且完全照著它說的做」，觸發條件是 Issue: Labeled，並且設定了 cloud-agent-test 標籤的篩選條件*

*每次測試都重複使用同一個 routine：任務寫在 Issue 裡，不是寫在 routine 自己的設定裡。*

agent 提出了一個用完即丟的第一個任務：建立一個只包含固定句子的檔案（`docs/cloud-agent-shakedown.md`），不動其他任何東西，執行 repo 自己的 `pnpm check`，開出 PR 但不合併。這些內容寫進了一個 GitHub Issue，幫它加上專用的 `cloud-agent-test` 標籤，就觸發了這個 routine。

![標題為「[test] Cloud agent shakedown」的 GitHub Issue，標籤面板打開著，正要加上 cloud-agent-test 標籤](./_images/issue-166-apply-label.webp)

*加上標籤就是整個觸發條件，沒有其他步驟會啟動這次執行。*

**完全無人值守，第一次嘗試就乾淨俐落地成功了。** routine 複製了 repo，剛好只建立了被要求的那一個檔案，跑完了驗證流程，還開出一個把實際指令輸出貼進說明欄的 PR：

```
$ astro check && pnpm run check:types && pnpm run check:i18n …

05:57:16 [check] Getting diagnostics for Astro files
Result (244 files):
- 0 errors
- 0 warnings
- 0 hints
```

**它還回報了一件沒人要求它檢查的事**：一個跟這次改動無關、原本就存在的 `Unsupported engine` 警告，是關於 repo 釘住的 Node 版本，它把這件事寫進 PR 裡，而不是悄悄忽略。這是件小事，但也正是這個部落格自己的工具慣例所要求的行為，而 routine 在沒被要求的情況下就做到了。

## 自己回答問題，證明不了 routine 什麼

接下來的問題是，routine 能不能在任務進行到一半時，真的因為需要判斷而暫停，之後再靠手機上的回覆繼續，因為這正是「不用人在旁邊看著」這句宣傳詞的另一半。**測試這件事的第一版設計是錯的**，很慶幸在真的執行之前就被抓出來了：原本的計畫是直接從手機開一個 session，貼上一段會強迫呼叫 `AskUserQuestion` 的提示詞，然後當場回答。

**自己開的、自己盯著看的 session，沒辦法驗證無人值守的路徑。** 在自己主動推進的對話裡回答問題，只能證明即時對話可以運作，而這件事從來就沒有人懷疑過。真正值得知道的是一個性質完全不同的主張：一個由觸發條件啟動、沒有人看著的執行，能不能停下來等待，之後再靠手機上的一則回覆繼續。

重新設計後的測試，重複使用了第一次測試的同一個通用 routine。第二個用完即丟的 Issue 要求同樣類型的用完即丟檔案，只是這次 routine 必須先呼叫 `AskUserQuestion` 並等待回答，才能建立任何東西，而觸發條件也換成了標籤，而不是手動開啟的 session。

## AskUserQuestion 不是 routine 能呼叫的工具

*Image: 標題為「Cloud agent shakedown 2, question path」的 Issue，標籤面板打開著，正要加上 cloud-agent-test 標籤*

*同一個標籤、同一個 routine，Issue 裡的任務不一樣：這次要求先問問題才能做任何事。*

加上標籤觸發了 routine，它幾乎立刻就停下來了，什麼都還沒建立：

*Image: 一次已完成的 Claude Code routine 執行，回報 AskUserQuestion 在這個 routine session 裡不是可用的工具，所以它停下來而不是用猜的*

*與其在兩個選項之間亂猜，這次執行選擇拒絕猜測。*

這是執行本身的原話：*「AskUserQuestion 在這個 routine／trigger session 裡不是可用的工具，不在工具清單裡，ToolSearch 也找不到任何相符的東西……我選擇停下來，而不是捏造答案或在選項 A、B 之間亂猜。沒有建立任何檔案，沒有任何提交，也沒有開出任何 PR。」*

**這是比 Anthropic 公開文件更強、也更精確的發現。** 文件只寫了 routine 執行時「完全沒有核准提示」，這句話讀起來像在講工具權限提示，而不是一個完全不同、用來對話式詢問使用者的工具。實際的行為兩邊都說清楚了：**這個工具根本不在 routine 的工具箱裡**，所以不是「拒絕」詢問，而是根本沒有東西可以呼叫。碰到這道牆的失敗方式是對的：它沒有在兩個選項之間亂猜，也沒有悄悄選一個預設值。**它停下來並且回報了**，這正是無人值守的自動化在真的無法繼續時該有的樣子。

我確實希望這個工具能存在。如果 routine 能呼叫 `AskUserQuestion`，在真正需要判斷時暫停，並且像現在的隨選雲端 session 已經做到的那樣，靠手機上的回覆繼續，就能消除 routine 的提示詞必須寫成一份完全沒有留白的完整規格的唯一理由。在這件事實現之前，這個限制不是可以繞過的偏好，而是設計上必須遵守的前提。

## 第三次測試改用隨選 session

「就跟現在的隨選雲端 session 已經做到的那樣」這句比較，其實是憑著 Anthropic 自己的文件寫的，並沒有實際驗證過：目前為止的兩次測試都只試過 routine 這條路徑。**第三次測試補上了這個缺口**，這次直接從手機開啟 session，而不是透過加了標籤的 Issue，用的是同樣用完即丟的任務、同樣被強制呼叫的 `AskUserQuestion`，但這一次的執行過程完全跟 routine 無關。

*Image: 一則標題為「Claude has a question」的 iOS 推播通知，待處理的問題名稱顯示為「Shakedown line」*

*隨選 session 需要答案的那一刻，通知就送到了。*

確實成功了，app 在需要的那一刻推播了通知：*「Claude has a question — Shakedown line」*。打開之後看到的是真正原生的問題卡片，不是文字湊合出來的替代方案。

*Image: 標題為「Which line should be used in docs/cloud-agent-shakedown-3.md?」的行動裝置 AskUserQuestion 卡片，有 Option A、Option B、Other 欄位和 Submit 按鈕*

*routine session 完全碰不到的互動工具，在手機上以原生 UI 呈現。*

**這個問題就這樣懸在那裡十二分鐘沒人回答**，手機上的時間戳記顯示，提示出現在 1:26，完成的結果則是 1:38，這段時間長到足以排除第一版 routine 測試設計裡「即時對話」那個瑕疵。

*Image: 十二分鐘後的同一個 session，已經提交了選定的檔案、乾淨地跑完 pnpm check，並對 main 開出了 pull request*

*隔了一段時間才回答之後，session 自己恢復執行，並且正確地完成了。*

隔了一段時間才回答，session 正確地繼續執行：用選定的選項建立檔案、乾淨地跑完 `pnpm check`，並照要求對 `main` 開出未合併的 pull request。**這個限制是 routine 特有的，不是雲端 session 整體的問題。** `AskUserQuestion` 除了在 routine 的無人執行裡之外，到處都是真正能用、會推播通知的工具，這也是上面那個設計前提成立的另一個理由：routine 的提示詞要當作這個工具永遠不存在來寫，因為對 routine 來說，它確實從來就不存在。

## 通知還是送到了

Anthropic 的行動裝置文件把推播通知的範圍限定得很窄：*「當 Remote Control 啟用時，Claude 可以把推播通知送到手機上……通常是在長時間執行的任務結束時，或是需要你做決定時。」* **Remote Control 是跟 routine 不一樣的功能**，它把手機連到一個在自己機器上即時執行的 session，需要那台機器保持開機，而這正好抵消了 routine 能在雲端執行、讓筆電闔上也沒關係的優點。

儘管文件這樣限定範圍，上面那個卡住的 routine 執行，在完全沒有任何 Remote Control session 在跑的情況下，還是把通知送到了手機。**文件跟實際觀察到的行為在這裡對不上**，而比較重要的實務判讀是：就算沒有 Remote Control，至少有一類 routine 事件，也就是徹底卡死，還是會送到手機上。還沒測試到的是，一個不是完全放棄、而是卡在等待某件事的 routine，會不會用同樣的方式推播。因為會造成那種暫停的工具根本不存在，這件事沒有辦法測試。

## 在這個部落格，真正值得交給 routine 的是什麼

讓 Claude Code 離開終端機工作有四種不同的方式，它們互相拿同樣兩件事做取捨：工作是不是需要機器保持開機，以及人能不能在中途介入操作。

| 方式 | 執行位置 | 機器是否要保持開機 | 能不能暫停等待輸入 |
| --- | --- | --- | --- |
| 隨選雲端 session | Anthropic 的雲端 | 不用 | 可以，閒置直到你回覆 |
| routine | Anthropic 的雲端 | 不用 | **不行：對應的工具根本不存在** |
| Remote Control | 自己的機器 | 要 | 可以，還能推播通知 |
| Dispatch | 自己機器上的 Desktop app | 要 | 可以，透過 Desktop app |

**routine 是唯一一種既無人值守、又不需要機器保持開機的方式，同時也是唯一一種完全無法反過來問你任何事的方式。** 這個取捨就是整個發現的核心，也決定了什麼該交給 routine，什麼不該。

這個部落格自己的 release skill 會一路處理完整個發布流程：決定標題、選標籤、合併 PR、幫版本打標籤。它刻意在每一個判斷點都保持互動，考量到這兩次測試的結果，這些判斷點沒有一個適合交給 routine。routine 沒辦法問該用哪個標題，就跟它沒辦法問該用兩句佔位句子中的哪一句一樣。

兩次測試都撐過去的，是那種流程具體到完全不需要任何判斷的工作。這個部落格的 changelog，每次有依賴套件更新機器人在正常發布流程之外合併東西，就會跟著漂移，而修正方式是一套已經寫好、固定不變的整理流程：讀出上次打標籤之後進來的內容，補上漏掉的項目，開一個只碰那一個檔案的 PR。**這個流程裡完全沒有需要 routine 開口詢問的分岐點**，而這正是這次的兩次測試花力氣確認、真正重要的性質。

## 總結

**幫 GitHub Issue 加標籤，讓 routine 複製 repo、完成工作、開出 pull request 是真實可行的**，而且第一次嘗試就成功，完全不用人在旁邊盯著。真正重要的限制，比「routine 不能被交付判斷」更窄、也更機械化：`AskUserQuestion` 就是不在 routine session 能呼叫的工具清單裡，這一點透過看著執行真的撞上那道牆、停下來而不是用猜的，得到了確認。要走到這個發現，得先捨棄第一版的測試設計，因為**不管看起來多有說服力，一個自己開啟、自己回答的 session，都無法取代一個無人值守的觸發條件**。Anthropic 的文件把推播通知限定在需要機器保持開機的功能上，但一個卡住的 routine 執行還是把通知送到了手機，這是文件寫的行為和實際觀察到的行為對不上的又一個地方。從這一切導出的實務規則是：**routine 的提示詞要寫成一份把不確定的情況都先解決好的完整規格**，因為不存在開口詢問、等待回覆這種退路。第三次測試把僅剩的一個疑問也解決了：**在隨選 session 上，同一個工具能正確運作**，會推播通知，也能在真正延遲之後恢復執行，這證實了缺少的這個工具是 routine 特有的性質，而不是整體雲端 session 的性質。

## 參考連結

- [Claude Code Docs：用 routine 自動化工作（包含「執行時完全沒有核准提示」這句話）](https://code.claude.com/docs/en/routines)
- [Claude Code Docs：Claude Code on the web](https://code.claude.com/docs/en/claude-code-on-the-web)
- [Claude Code Docs：Claude Code on mobile](https://code.claude.com/docs/en/mobile)
- [Claude Code Docs：Remote Control（包含推播通知的範圍限定）](https://code.claude.com/docs/en/remote-control)
