November
14th,
2026
前情提要 寫部落格、回 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 之間的介面合約:先把...
繼續閱讀
November
11th,
2026
前情提要 最近迷上使用 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 在同一個視窗裡、各自佔一個...
繼續閱讀
November
8th,
2026
前情提要 這陣子陸續把幾個日常主力服務從 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...
繼續閱讀
November
4th,
2026
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 從...
繼續閱讀
November
3rd,
2026
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...
繼續閱讀
November
2nd,
2026
前情提要 在 上一篇 Managed Agents API 全解析 裡,我做了一隻開源的 LINE 研究規劃師 Bot:kkdai/line-research-bot。 它的玩法很簡單: 在 LINE 傳「研究 SOTA 開源向量資料庫的選型」,Bot 會依序跑 PLAN → SEARCH_COMPARE → WRITE_REPORT 三個階段:先設計 4~8 組搜尋關鍵字,再用 Google Search + URL Context 讀真實網頁並交叉比對出「共識 / 分歧 / 缺口」,最後寫成一份有 footnote 引用的繁體中文 Markdown 報告。 報告由 Cloud Run 渲染成 HTML 丟上 Cloud Storage,LINE 收到一張附摘要、主要來源與「閱讀完整報告」按鈕的 Flex 卡片。 之後再傳「第 2 章再深一點,加日文來源」,Bot 會在同一份報告上深化、版本號 +1,舊版自動存成 snapshot。 第一版是 Python 3.11 + FastAPI + google-genai(enterprise=True) 打 Pre-GA 的 Managed Agents API,靠的是官方沙箱的 持久化 filesystem:/workspace/plan.json、/workspace/sources.json、/workspace/report.md 在同一個 environment_id 底下跨回合存活,深化時 Agent 自己去讀檔。 它很好玩,但跑了一陣子之後,有幾件事一直讓我不太放心: Pre-GA,沒有 SLA:base_agent: antigravity-preview-05-2026 這種名字一看就知道哪天會變。 沙箱裡的 gsutil 是 mock 的(上一篇的踩坑二),結果 Agent 寫完報告還是得把整份 Markdown 塞回 JSON 給 Cloud Run 上傳。沙箱 filesystem 的價值其實只剩「跨回合記住三個檔案」。 一定要 background=True + 自己寫 polling 迴圈,Stage 2/3 一慢就要調 timeout(我曾經從 240 秒一路調到 600 秒)。 於是這次我決定:把整個服務改寫成 Go,所有跟 Agent 有關的事情改用 Google 官方的 ADK for Go(google.golang.org/adk v1.9.0)來做,並且部署回原本的 Cloud Run 服務、沿用一模一樣的環境變數。 整個過程我都記錄在原 repo 的 Issue #1。 改寫完成後,我把 Go 版獨立成一個新的 repo,讓上一篇文章引用的 Python 版維持原樣,兩個版本可以直接對照: Repo 內容 kkdai/line-research-bot 原本的 Python 3.11 + FastAPI + Managed Agents 版(上一篇文章的範例),以及這次遷移的 Issue #1 紀錄...
繼續閱讀