[Herdr 實戰] 自己寫一個 Herdr mod:用 label 做出「待 review」佇列,一眼看出哪個 coder 回報了、還沒被看

前情提要 前兩篇(第一次用 Herdr、用兩個 agy Pane 做 record2gif)都是同一個模式: 左邊 Claude Code 當 PM / Reviewer,開 Issue、review、commit。 右邊 agy 當 coder,做完用 hc send 回報。 用久了有一個很實際的困擾:coder 的回報是直接打進 PM 的輸入框裡的。一次開兩三個 coder、來回幾輪之後,我(人類)很難回答: 現在有哪幾個 coder 已經回報了?哪些我看過了、哪些還沒? Herdr 側欄的 done 狀態幫不上忙,因為只要瞄一眼那個 Pane,它就會變回 idle,「看到」不等於「review 過」。 上一篇查網路資料時也發現,自己寫 Herdr mod 是中文圈幾乎沒人寫過的主題。所以這次就自己做一個: 一個「待 review」佇列面板:列出哪些 coder 已經回報、還沒被看過。 成果:kkdai/herdr-review-queue 一、動手前的發現:hc send 是看不到的 我原本的想法很直覺:mod 去監聽 hc send 的訊息,有人 send 給 reviewer 就加進佇列。 但實際測了一下 hc events(herdr-core 的即時事件串流): hc run --bg --name probe-target cat hc run --bg --name probe -- sh -c 'hc events --json' hc send probe-target "probe message" hc label probe-target review=ready 結果事件裡有 foreground、title、labels……就是沒有 send。訊息只會出現在收件者的輸入框,外人觀察不到。 不過這個實驗也找到了出路:label 的變化會即時出現在事件裡,而 mod API 的 terminals() 也會即時帶出每個 terminal 的 labels。 所以設計就轉向了: 不去偷看訊息,而是讓 coder 在回報時「順便」在自己的 terminal 上貼一張標籤。 二、Label contract:coder 和 reviewer 之間的合約 標籤貼在 coder 自己的 terminal 上(hc label <t> k=v,k= 代表移除): Label 值 誰設定 review ready 或 seen(沒有 = 不在佇列裡) ready:coder;seen:reviewer review.summary 一行摘要,最多 200 字 coder review.at 變成 ready 的時間(毫秒) coder review.to reviewer 的位址(例如 t15) coder review.seen_at 被標成 seen 的時間...
繼續閱讀

[Herdr 實戰] 用 Herdr 開兩個 agy Pane 平行開發:一天做出 macOS 錄影直接轉 GIF 的 record2gif

前情提要 寫部落格、回 Issue 的時候,常常需要錄一小段操作畫面。macOS 內建的 QuickTime(或 ⌘⇧5)錄出來是 .mov,每次都還要再丟去別的工具轉 GIF、調尺寸,非常麻煩。 所以我想要一個很單純的小工具: 介面像 QuickTime 的「新增螢幕錄影」,可以錄整個桌面或框選範圍,錄完直接產生 GIF,而且可以選 GIF 的解析度。 剛好上一篇第一次用 Herdr 用得很順,這次就把規模再拉大一點: Claude Code 當 PM:開 remote GitHub repo、寫 SPEC、開 Issue、review、commit、push。 agy 當 coder,而且一次開兩個 Pane:同時解兩個 Issue。 每個 coder 做完都要回報給 Claude Code,review 通過才會 commit。 成果在這裡:kkdai/record2gif,從開 repo 到 GIF 成功存到桌面,大概一天。 一、record2gif 做了什麼? 功能 說明 QuickTime 風格控制列 小小一條浮動視窗:錄整個螢幕 / 錄選取範圍、Options、紅色 Record 按鈕 框選範圍 全螢幕半透明遮罩,拖一個方框,顯示像素尺寸,可以調整後再錄 錄影中 控制列自動隱藏(不會被錄進去),選單列顯示 ⏹ + mm:ss,點一下或按 ⌃⌘Esc 停止 匯出視窗 循環預覽、解析度(原尺寸 / 1280 / 960 / 640 / 480 / 320 px / 自訂寬度,維持比例、絕不放大)、影格率(5–30 fps)、無限循環開關、預估輸出尺寸 存檔 預設存到桌面,檔名 Recording 2026-11-14 at 15.13.43.gif,有進度條、可以取消、存完可以在 Finder 顯示 技術選擇刻意保持簡單,完全沒有第三方套件: 部分 技術 專案 Swift Package Manager(沒有 .xcodeproj),macOS 14+ UI SwiftUI + AppKit(NSPanel、NSStatusItem、遮罩視窗) 錄影 ScreenCaptureKit(SCStream)→ AVAssetWriter 寫 H.264 .mov 暫存檔 轉 GIF AVAssetReader 逐格解碼 + ImageIO(CGImageDestination)編碼 全域快捷鍵 Carbon RegisterEventHotKey(不需要輔助使用權限) 測試 Swift Testing,19 個測試 錄影時一律用原生像素解析度錄(points × scale),縮小只在匯出 GIF 的時候做,所以同一段錄影可以匯出好幾種尺寸。 二、PM 的工作:先寫 SPEC,再拆 Issue 兩個 coder 平行寫程式,最怕的就是「各寫各的,最後接不起來」。所以 Claude Code 第一件事不是開 coder,而是寫一份 SPEC.md,裡面最重要的是兩件事: 固定的目錄結構:哪個 Issue 只能動哪個資料夾(例如只有 #4 可以改 Recording/、只有 #5 可以改 Export/)。 Issue 之間的介面合約:先把...
繼續閱讀

[Herdr 實戰] 第一次用 Herdr:讓 Claude Code 當 Reviewer、agy 當實作者,在左右 Pane 協作完成 Go 後端 Code Review、5 個 Issue 修正與 Cloud Run 部署

前情提要 最近迷上使用 TTT(Terminal Text Tool),也就是大家俗稱的 AI Terminal Editor,第一個使用的就是 Herdr。 昨天用它(Master Agent 是 Claude Opus 5.5)由他來分配工作,請 Gemini 4 Argon 去實作來優化程式碼,最後再由 Claude Code 來審核,最後再請 Claude Agent 將相關過程寫成文章,一次完成(還會自動幫我截圖附上)。 整條流水線長這樣: 階段 誰負責 做什麼 1. 分派 Master Agent(Claude Opus 5.5,左 Pane) 拆任務、開 Issue、決定誰做什麼 2. 實作 Gemini 4 Argon(透過 agy,中 Pane) 改程式、跑測試 3. 審核 Claude Code 看 diff、自己再跑測試、通過才放行 commit/push 4. 寫文章 Claude Agent(blog-writer,最右邊 Pane) 把整個過程寫成這篇文章,順便用 herdr-app shot 截圖附上 沒錯,你現在讀的這篇文章,就是上圖最右邊那個 Pane 裡的 Claude Agent 寫的(連這張截圖也是它自己拍的)。用下來也能了解,為什麼一些高手可以使用這些 TTT 來打造一條線的流水線工作架構——這部分我在第八節會再展開。 真的蠻讚~ 其他身邊同事不是玩 rex + Pi,就是一直叫我去玩 Orca 🤣 這次的實驗場:song-lingo song-lingo 是我自己做來學日文歌的小工具:貼上一支 YouTube MV,Gemini 會幫我聽寫歌詞、標註羅馬拼音、繁中翻譯與文法,再用 Gemini TTS 產生「老師示範音」;我錄音跟讀之後,Gemini 會轉錄我的發音並逐字評分。 前幾天,我才在同一個 Claude Code session 裡把整個後端從 Python + Next.js API routes 全部改寫成 Go 1.26(Issues #44–#49、Tracking Issue #50、PR #51–#56)。改寫完之後的架構長這樣: Next.js 只剩前端,用 rewrite 把 /api 轉給同一個容器裡的 Go server(127.0.0.1:8081)。 部署在 Cloud Run(asia-east1),資料放在 Cloud Storage bucket,透過 gcsfuse 掛在 /data;學習進度存在 Firestore;前面用 IAP 限制只有我能登入。 Go 版的幾個重點:genai SDK、Gemini REST(voices / interactions)、Firestore transaction、用 kagome 斷詞轉平假名、自己寫的 Hepburn 羅馬拼音表,以及把 Python difflib.SequenceMatcher 移植成 Go(用 400 組 Python 產出的 golden 測試對齊評分)。 改寫完、能動、測試也過了。但「自己寫、自己審」總是有盲點。剛好這次想試試 Herdr——一個讓多個 AI Agent 在同一個視窗裡、各自佔一個...
繼續閱讀

[AI 實戰] 用 Antigravity Remote Agent + 本地 agy 接力重構 LINE 名片助理:Python 改寫 Go + Google ADK + Firestore 實戰與雲地交接限制解析

前情提要 這陣子陸續把幾個日常主力服務從 Python 改寫成 Go,這回輪到我平常整理名片的 LINE 機器人:kkdai/linebot-namecard-python。 這隻機器人過去已經演進了好幾輪:從最初的 Gemini Vision 辨識 + vCard QR Code 匯入通訊錄、搬上 Vertex AI 擺脫配額限制、導入 Python 版 ADK 動態閉包 Tools,一路加上 Structured Output 與消歧義清單 和 正反雙面名片合併辨識。 但這次重構成 Go 版(kkdai/linebot-namecard-go),我想挑戰一個不太一樣的工作流:先把架構改寫與單元測試丟給 Google Antigravity 的 Remote Agent 在雲端自動跑完,等我回到電腦前,再由本機的 agy CLI 接手部署到 Cloud Run 並切換 LINE Webhook。 實際跑過一輪之後,成果很驚豔——Remote Agent 在雲端 17 分鐘就把整套 Go 1.27 + google.golang.org/adk + Firestore 架構與測試寫完推上 GitHub;但同時也實地驗證了一個非常關鍵的邊界限制:你可以用 agy 呼叫 Remote Agent,卻「無法」把同一個 Remote Agent 對話切換成本地 Agent 繼續。 這篇文章上半部先把 Antigravity Remote Agents 的用法、雲地隔離原因與兩種實務解法一次講清楚;下半部再完整拆解這次 linebot-namecard-python → linebot-namecard-go 的系統架構升級與實際交接部署踩坑紀錄。 一、認識 Antigravity Remote Agents:把重活交給雲端隔離 VM 依據 Google Antigravity 官方文件(Remote Agents),Remote Agents 的核心概念是把自主開發任務從你本機的筆電,搬到 Google 代管的雲端隔離虛擬機(Cloud Sandbox VM) 裡執行。 這對長時間重構、大範圍測試或跨語言改寫非常有用: 非同步離線執行:任務在雲端 VM 跑,就算你闔上筆電、電腦休眠或斷網,Agent 依然會繼續寫扣、跑測試與改檔案。 跨裝置監看與解鎖:你可以在桌機或 CLI 派工後出門,中途用手機瀏覽器打開 antigravity.google.com 看進度、批准權限或補充指令,最後直接拿到一個完整的 GitHub Commit / PR。 雲端資源掛載(Remote Resources):因為 Agent 跑在雲端隔離沙盒,存取檔案透過三種方式掛載: GitHub Repositories:透過 OAuth 授權後自動 clone 並掛載進遠端專案環境。 Google Drive:可直接在對話中讀取 Google Docs、Sheets、Slides、PDF 與資料夾。 上傳本地檔案:直接把檔案傳到遠端專案(單檔上限 8 MiB、每個專案最多 50 檔 / 100 MiB、帳號總上限 2 GiB),檔案會持久掛載在 /home/antigravity/upload。 1. 可以用 agy CLI 呼叫 Remote Agent 嗎? 可以。 依據 Remote Agents 官方文件,使用前須符合兩個條件: CLI 版本:agy CLI...
繼續閱讀

[AI 實戰] 把 LINE 研究 Bot 從 Go ADK 搬到 DeepSeek Harness(DSH):搬遷對照與踩坑全紀錄

flowchart LR subgraph BEFORE["Before:Go + ADK for Go(一個 container)"] direction TB B_HOOK["LINE Webhook / Cloud Tasks"] --> B_WK["worker(Go)"] B_WK -->|"runner.Run()<br/>同一個行程"| B_ADK["ADK llmagent × 3<br/>OutputSchema<br/>Session State"] B_ADK -->|"GoogleSearch + url_context"| B_GM["Vertex AI<br/>Gemini"] end subgraph AFTER["After:TypeScript + DeepSeek Harness(app + sidecar)"] direction TB A_HOOK["LINE Webhook / Cloud Tasks"] --> A_WK["worker(TypeScript)"] A_WK -->|"dsh-sdk-client<br/>stdio JSON-RPC"| A_DSH["dsh runtime 子程序<br/>sdk-minimal + patch<br/>submit_* / web_research 工具"] A_DSH -->|"Anthropic /v1/messages"| A_LL["LiteLLM sidecar"] A_LL --> A_GM["Vertex AI<br/>Gemini"] A_DSH -->|"web_research:<br/>googleSearch + urlContext"| A_GM end BEFORE ==>|"只換 Agent 層<br/>LINE / Firestore / GCS / Cloud Tasks 不變"| AFTER   Before(ADK for Go) After(DeepSeek Harness) Agent 跑在哪 同一個 Go 行程 每個 stage 一個 dsh 子程序 怎麼接 Gemini 直連 Vertex AI DSH(Messages 協定)→ LiteLLM sidecar → Vertex AI 結構化輸出 OutputSchema submit_* 工具 + 讀 session 事件 Google Search ADK 內建 geminitool 自寫 web_research 工具 Cloud Run 1 個 container 2 個 container(app + LiteLLM),一樣可以縮到 0 前情提要 在 前前篇 裡,我把 LINE 研究規劃師 Bot 從...
繼續閱讀

[AI 實戰] 同樣叫 Harness,差在哪?DeepSeek Harness(DSH)框架解析,以及跟 Google Research Harness² 的比較

flowchart LR subgraph H2["Google Research Harness²:改「裝備的內容」"] direction TB OPT["雙層遞迴優化器(Python)<br/>Propose → Probe → Compose<br/>Experience Reflector"] TREE["c1..c8 裝備檔案樹<br/>systemprompt / guardrails /<br/>LongTermMEMORY / skills…"] OPT -->|"產生下一代 H^(k)"| TREE end subgraph DSH["DeepSeek Harness:負責「把 Agent 組起來跑」"] direction TB PROF["Profile = bundle + YAML patch"] RT["dsh runtime<br/>agent loop / ctx.tools / ctx.llm /<br/>session 事件"] PROF -->|"Cordis 組裝外掛"| RT end TREE -.->|"裝備被某個執行環境載入"| RT RT -.->|"執行軌跡 / 分數"| OPT   DeepSeek Harness(DSH) Google Research Harness² 一句話 Agent 的執行環境 Agent 裝備的自動優化器 「Harness」指的是 跑 Agent 的那套 runtime 包在模型外面的提示詞、護欄、記憶、技能 你會改的東西 Profile、YAML patch、外掛 c1..c8 檔案樹(但通常是 Harness² 自己改) 這個系列裡用在哪 LINE 研究 Bot 的 Agent 層 LINE AI 名片王的自我演化 前言:兩個 Harness,一週內碰到兩次 前幾天的 Harness² 三部曲(上、中、下),我把 Google Research 的 google-research/harness2 接上 LINE AI 名片王,讓它讀 OpenTelemetry 軌跡、自己長出技能檔,準確率從 62.5% 一路爬到 100.0%。 這週又剛好碰到 DeepSeek 開源的 deepseek-ai/dsh-superagent-prototype,它建在 DeepSeek Harness(DSH) 上。我把 LINE 研究 Bot 的 Agent 層從 ADK for Go 換成了 DSH,做成 kkdai/line-research-bot-dsh,目前已經在線上跑了。 兩個都叫 Harness,我一開始也以為是同一類東西。實際用過之後才發現: DSH 是「馬具怎麼組裝、怎麼套在馬身上跑」;Harness² 是「自動調整馬具上的每一條皮帶」。 兩個在不同層,甚至可以接在一起用。 因為內容太多,這次拆成兩篇: 本篇:DSH 框架到底是什麼(附框架圖),以及它跟 Google Harness² 的逐項比較。 下一篇:實際怎麼把 LINE 研究 Bot 從 ADK...
繼續閱讀