一份 AGENTS.md,讓多個 AI Coding Agent 共享專案規則(上)
AI coding tools 這幾年幾乎是輪流登場。 Cursor(2023)、Claude Code(2025 年 2 月)、Codex CLI / Codex coding agent(2025 年 4-5 月),以及 Google Antigravity(2025 年 11 月)這類工具持續出現。每個工具都有自己的設定檔、規則格式和使用習慣。剛開始我也會想:是不是每換一個工具,就要重新適應一次?是不是每個工具都要維護一份自己的 instruction? 後來我把問題換了一個角度看。 repo 應該成為穩定的工作入口,工具則負責讀懂 repo 裡的規則。只要專案裡有一份清楚、穩定、可版本控管的工作指引,不管今天打開的是 Cursor、Claude Code、Codex,還是下一個新工具,agent 都應該能快速理解這個專案怎麼跑、怎麼測、文章怎麼寫、commit 怎麼下。AI coding tools 會換,但 repo 的工作規則應該只維護一份。註:本文提到的 Codex 指 OpenAI 在 2025 推出的 Codex CLI / Codex coding agent,不是 2021 年的 OpenAI Codex code generation model。 工具越多,規則越容易漂移 AI coding agent 最怕的情況,不是它不會寫程式,而是它拿到一份過期的專案規則。 這件事通常不是故意發生的。比較常見的情境是:一開始只有 Cursor,所以你寫了 .cursor/rules。後來開始用 Claude Code,又補了一份 CLAUDE.md。再後來想試 Codex,於是多了一份 AGENTS.md。每一份文件剛建立時都很合理,但幾個月後它們開始長得不一樣。 例如:AGENTS.md 說 commit 要有 body CLAUDE.md 還停留在舊的單行 commit 習慣 .cursor/rules 裡的測試指令沒有更新 skills 的內容被複製到多個工具專屬資料夾這種 drift 很難靠記憶補救。人都會忘記更新文件,agent 當然也只能照它讀到的內容做事。當同一個 repo 對不同工具說出不同規則,最後受傷的是開發流程本身。 我的整理方向很簡單:repo 只保留一份 project instructions。工具需要自己的入口時,就讓那個入口變成 adapter。 官方文件其實指向同一個方向 我整理 Claude Code、Codex、Cursor 的官方文件後,發現三個工具雖然格式不同,但可以收斂成同一個架構。 Codex:用 AGENTS.md 當 project instructions Codex 官方文件把 AGENTS.md 當成專案指令的主要入口。這份文件適合放 repo 的固定規則,例如:專案結構 常用指令 coding convention 測試方式 PR / commit 期待Codex 也支援 root AGENTS.md 搭配子目錄的 AGENTS.override.md。如果某個資料夾需要特殊規則,可以把 override 放到那個子目錄,讓越靠近工作目錄的規則有更高優先權。 這個設計很適合放「穩定、全 repo 適用」的內容。它不適合塞進一大段任務細節,因為任務流程會越長越難維護。 Claude Code:用 CLAUDE.md 匯入 AGENTS.md Claude Code 官方預設讀 CLAUDE.md。如果 repo 已經有 AGENTS.md,官方文件建議在 CLAUDE.md 裡用 import: @AGENTS.md這是很重要的小細節。CLAUDE.md 裡只寫 AGENTS.md 可能看起來也像在提醒模型讀檔,但它不是官方 import 語法。用 @AGENTS.md 才能把 Claude Code 的入口降到 adapter 的角色。 最後 repo 裡真正需要維護的 project instructions 還是 AGENTS.md。 Cursor:簡單情境可以讀 root AGENTS.md Cursor 官方主要推薦 .cursor/rules,因為它可以做更細的規則控制,例如 always apply、依檔案路徑套用、agent requested rule 等。 不過 Cursor 也支援 root AGENTS.md 作為簡單 project instructions。對只有一份全專案規則的 repo 來說,這已經足夠。等到專案真的需要針對 src/content/posts/、src/components/、infra/ 套不同規則,再引入 .cursor/rules 也不遲。 我自己的判斷是:先讓 AGENTS.md 承擔共用入口。當規則開始需要分區、分檔、分觸發條件,再讓 Cursor rules 介入。 Google Antigravity:原生支援 AGENTS.md Google 於 2025 年底推出的 Antigravity 是一款以 Agent 為核心的強大開發環境。它原生支援讀取專案根目錄的 AGENTS.md,並以此作為自主任務執行的決策依據。當我們想進一步導入複雜的 Task Workflow 時,它亦可完美讀取在 AGENTS.md 中索引的 .skills/ 目錄,藉此載入對應的任務規則(例如文章潤飾或 Git 審查),使得「單一規則本體」的理想在 Antigravity 中運行得非常流暢。 共用 AGENTS.md 的最小策略 AGENTS.md 很適合回答一個問題:這個 repo 的基本工作方式是什麼? 我會把它控制在短而穩定的範圍: # Agent Instructions## Repository Expectations- Follow the existing project structure and style before introducing new patterns. - Keep shared agent skills in `.skills/`. - Do not duplicate skill files under tool-specific directories.## Commands- Install dependencies: `npm install` - Start dev server: `npm run dev` - Build: `npm run build` - Type check: `npm run check`## Verification- Run `npm run build` after changing Astro, React, styling, or content rendering code. - Run `npm run check` after changing TypeScript or Astro components. - For documentation-only or skill-only changes, no build is required unless behavior changes.這些規則的共同點是穩定。它們不會因為今天用 Claude Code、明天用 Codex 就改變。 最後可以把工具專屬檔案降到 adapter: AGENTS.md # 唯一 project instructions CLAUDE.md # @AGENTS.md .cursor/rules # 只有進階規則需求時才加入這樣 repo 裡真正需要維護的 project instructions 只有 AGENTS.md。Claude Code 透過 CLAUDE.md 匯入它,Cursor 和 Codex 直接讀它。工具可以各自有 adapter,規則本體不要分裂。下一篇我會用這個部落格 repo 當例子,說明我怎麼把 AGENTS.md 和 .skills/ 拆開:AGENTS.md 放穩定入口,.skills/ 放任務流程,讓 Claude Code、Codex、Cursor 都能共用同一套工作規則。一份 AGENTS.md,讓多個 AI Coding Agent 共享專案規則(下)參考資料OpenAI Codex: Custom instructions with AGENTS.md OpenAI Codex: Agent Skills Claude Code: Memory Claude Code: Skills Cursor: Rules Google Developers Blog: Build with Google Antigravity Google Antigravity Official Portal AGENTS.md Guide: Cross-Tool Rules for Antigravity AGENTS.md Official Standard OpenAI: Introducing Codex TechCrunch: Anysphere raises $8M from OpenAI to build an AI-powered IDE TechCrunch: Anthropic launches Claude Code research preview
Read More
一份 AGENTS.md,讓多個 AI Coding Agent 共享專案規則(下)
上一篇先整理了官方文件的共同方向:AGENTS.md 可以成為 repo 的共用 project instructions。這一篇回到我自己的部落格 repo,說明最後實際怎麼放檔案。一份 AGENTS.md,讓多個 AI Coding Agent 共享專案規則(上)我的目標很明確:project instructions 只維護一份 task workflow 只維護一份 工具專屬檔案只做 adapter 團隊共用的內容進 git這樣換工具時不用重寫規則。新的 AI coding agent 只要能讀到 repo 裡的入口,就能快速理解專案。 這個 repo 的最後結構 我最後把 repo 整理成這樣: AGENTS.md CLAUDE.md .skills/ README.md tech-blog-polish/ SKILL.md git-change-commit-review/ SKILL.mdAGENTS.md 是唯一 project instructions。它放所有工具都應該知道的穩定資訊,例如 commands、verification、project structure、git workflow。 CLAUDE.md 只保留一行: @AGENTS.md這樣 Claude Code 會匯入 AGENTS.md。CLAUDE.md 不再複製任何專案規則,也不會和 AGENTS.md drift。 Cursor 這邊,我刪掉原本的 .cursor/rules/skills.mdc。原因很單純:那份檔案和 AGENTS.md 寫的是同一件事。既然 Cursor 可以讀 root AGENTS.md,這個 repo 暫時不需要 .cursor/rules。 AGENTS.md 放 repo 的穩定入口 目前 AGENTS.md 的角色是「讓 agent 進 repo 後先知道工作方式」。 我會放這些內容: # Agent Instructions## Repository Expectations- Follow the existing project structure and style before introducing new patterns. - Keep shared agent skills in `.skills/`. - Do not duplicate skill files under tool-specific directories.## Commands- Install dependencies: `npm install` - Start dev server: `npm run dev` - Build: `npm run build` - Type check: `npm run check`## Verification- Run `npm run build` after changing Astro, React, styling, or content rendering code. - Run `npm run check` after changing TypeScript or Astro components. - For documentation-only or skill-only changes, no build is required unless behavior changes.這些規則每天都會用到,而且不屬於任何單一工具。Codex 讀到它,Claude Code 讀到它,Cursor 讀到它,應該得到同一套結論。 接著再放 repo 結構: ## Project Structure- Blog posts live in `src/content/posts/`. - English posts live in `src/content/posts-en/`. - Shared agent skills live in `.skills/`. - Static assets live in `public/`.這段看起來很普通,但對 agent 很有用。它少猜一次目錄,就少一次亂翻檔案或改錯位置的機會。 Skills 放任務流程 AGENTS.md 不適合放太長的任務流程。像文章潤稿、git diff review 這類流程,細節會很多,也不是每次工作都會用到。 所以我把它們放進 .skills/: .skills/ tech-blog-polish/ SKILL.md git-change-commit-review/ SKILL.mdtech-blog-polish 處理文章潤稿。它會定義文章結構、讀者類型、語氣、要避免的 AI 味句型。 git-change-commit-review 處理 changed files review。它會規定要跑哪些 git checks、怎麼整理 staged / unstaged、怎麼判斷 commit 是否要拆分,以及 commit message 要怎麼寫。 AGENTS.md 只需要保留 skills index: ## Shared SkillsProject skills live in `.skills/`.Before handling a request, check whether it matches one of these skill descriptions:- `.skills/tech-blog-polish/SKILL.md` - `.skills/git-change-commit-review/SKILL.md`When a request matches a skill, read that skill's `SKILL.md` and follow it as the source of truth for the task.這樣 agent 不需要每次都讀完整 skills。它只要先看 AGENTS.md,等任務真的命中某個 skill,再打開對應的 SKILL.md。AGENTS.md 是入口,.skills/ 是細節。入口要穩,細節要能獨立演進。為什麼不直接放 .claude/skills 和 .agents/skills Claude Code 和 Codex 都有各自的 skills discovery 路徑: .claude/skills/ .agents/skills/如果要完全貼合工具預設,可以用 symlink 或同步方式把 .skills/ 暴露到這些路徑: .claude/skills -> .skills .agents/skills -> .skills但我目前先不做這一步。原因是 Windows 上 symlink 可能需要 Developer Mode 或管理員權限,團隊環境不一定一致。對這個 repo 來說,用 AGENTS.md 明確告訴 agent 去讀 .skills/,已經足夠穩定。 等未來真的需要工具原生 skills discovery,再處理 adapter。先把 canonical source 定下來比較重要。 這次調整的 commit 規則 這次整理過程中,我也順手把 git workflow 寫清楚: ## Git Workflow- Use the git change review skill when reviewing changed files or proposing commit messages. - Every commit must include both a subject and a body.這條規則看起來小,但很實用。agent 很容易為了快速完成任務直接下單行 commit。把規則寫進 repo 後,每次 review changed files 或執行 commit,都會回到同一個標準。 這也是我希望 AGENTS.md 進 git 的原因。repo 的工作規則應該像程式碼一樣被 review,而不是散落在每個工具的個人設定裡。 何時才需要工具專屬規則 我現在的選擇不是永遠拒絕 .cursor/rules、.claude/skills 或 .agents/skills。比較好的判斷方式是看需求。 只有全 repo 共用規則時,用 AGENTS.md。 需要任務流程時,用 .skills/<name>/SKILL.md。 需要 Cursor 依檔案路徑自動套用不同規則時,再加入 .cursor/rules。 這裡有一個絕妙的實戰手法:當我們有多個 .skills/ 流程時,雖然為了避免漂移而把內容收攏在 .skills/ 目錄中,但我們仍然可以使用 Cursor 的 .cursor/rules/*.mdc 機制來作為自動觸發(Auto-trigger)轉接器。 例如,你可以建立一個輕量級的 .cursor/rules/polish-trigger.mdc,設定 glob: "src/content/posts/**/*.md"(只要開啟文章就會觸發),而規則內容僅寫上一行:「當撰寫或修改部落格文章時,請務必先閱讀並遵守 .skills/tech-blog-polish/SKILL.md 裡的寫作指南。」這樣做的好處是,我們完全不需要在 Cursor rules 裡重複複製整套寫作規則,但卻能利用 Cursor 原生的檔案監聽,在 Agent 打開文章檔案的瞬間自動將該 Skill 載入為 context。這既能保持 canonical source 的唯一性,又實現了零磨擦的自動化流程。 需要 Claude Code 或 Codex 原生 skills discovery 時,再用 symlink 或同步方式接到 .skills/。 這樣做可以讓 tool-specific adapter 晚一點出現,而且每次出現都有明確理由。 結論:先穩住規則本體 AI coding tools 還會繼續變。今天是 Cursor、Claude Code、Codex,明天可能又多一個新的 agentic IDE。 我不想每換一個工具,就重寫一份 repo 規則。更好的做法是讓 repo 自己帶著工作說明。新的工具進來時,先接到 AGENTS.md;任務流程需要更細,再讀 .skills/。 這套做法沒有一次吃下所有工具功能,但它先解決最重要的問題:規則本體只有一份。AI coding tools 會換,但 repo 的工作規則應該只維護一份。
Read More
善用 AI Coding Agent(上):當 Branch 不足以支撐多 Agent 協作
AI Coding Agent 已經不只是「幫忙補程式碼」的工具。 我自己也付費使用多個 AI Coding 工具,包含 Cursor、Anthropic Claude Code、OpenAI Codex。這些工具的介面不同,但能力越來越接近:它們可以讀專案、改檔案、跑測試、修錯,甚至花一段時間完成一個比較完整的任務。 這讓我的使用方式開始改變。以前我把 AI 放在 IDE 裡,像一個隨叫隨到的助手;後來我開始把 Agent 當成可以接任務的人。這個轉變聽起來很小,實際上會改變整個工作流程。當 Agent 可以長時間工作,我們要管理的不只指令,也包含它正在使用哪一份專案檔案。這篇是「善用 AI Coding Agent」系列的上篇。我想先記錄一個實際遇到的問題:當我開始讓 Agent 跑長時間任務,原本靠 Git branch 切換的做法很快就不夠用了。 從局部修改開始 我一開始跟 AI 協作的方式,和很多開發者差不多:在 IDE 裡圈選一段程式碼,然後請 AI 幫我做局部修改。 例如:幫我重構這個 function 幫我補上 TypeScript 型別 幫我解釋這段邏輯 幫我把這個 API call 改成另一種寫法 幫我補測試這種方式非常直覺,也很有效。因為操作單位很小,風險也相對容易控制。AI 改完之後,我看一下 diff,覺得可以就接受,不行就退掉。 這個階段的工作方式很單純:我知道現在要改哪裡,AI 只負責處理我指定的那一小塊。它像是加速器,幫我把手上的工作做快一點。 當任務只有幾分鐘,這樣非常夠用。專案目前在哪個狀態、改了哪些檔案、要不要接受修改,都還在我的掌控範圍內。 長時間任務改變了問題 後來我在做 Prompt Engineering 相關工作時,遇到一類很適合交給 Agent 的任務:長時間評估。 例如:跑一批 prompt 評估案例 比較不同 prompt 版本的輸出品質 調整 evaluator 或 LLM-as-a-judge 的判斷邏輯 根據測試結果反覆修改 prompt 整理 trace 或測試報告這類任務通常不會改一個地方就結束。Agent 需要讀專案、跑指令、看結果、修改檔案,再重新驗證。時間可能從幾分鐘拉長到半小時甚至更久。 問題出現在等待期間。當一個 Agent 正在跑 prompt evaluation,我自己還想繼續開發新功能,或再開另一個 Agent 去修 bug。 當時我的想法很直接:能不能讓一個 Agent 在背景處理長時間任務,同時我繼續在另一個分支上開發?直覺答案是開新 branch。 Branch 看起來可以解決 我一開始也是這樣做的。 假設現在有一個主要專案資料夾: luke-tech-blog/我可以為長時間任務開一個 branch: git checkout -b agent/prompt-eval然後讓 Agent 在這個 branch 上執行 prompt 評估。 如果你不熟 Git,可以先把 branch 想成「同一個專案的不同版本路線」。一條路線用來做 prompt 評估,另一條路線用來開發新功能,聽起來很合理。 接著我想繼續開發新的搜尋頁面: git checkout -b feature/search-page這個瞬間,問題才真的浮出來。 同一個專案資料夾,一次只能顯示一個 branch 的檔案。當我從 agent/prompt-eval 切到 feature/search-page,目前資料夾裡的檔案也會跟著換成另一個版本。 這代表正在執行長時間任務的 Agent,看到的專案檔案被我換掉了。 對人類來說,這件事很好理解:我剛剛切了 branch,所以檔案換了。對正在工作的 Agent 來說,它只知道目前資料夾裡的檔案突然變了。它剛剛讀過的內容、跑過的測試、接下來準備修改的檔案,都可能和新的狀態對不上。 可以把它想像成同一張辦公桌上有兩個人在工作。Agent A 正在整理一份報告,我突然把整張桌子的文件換成另一個專案。Agent A 沒有離開,但它眼前的東西已經不是剛剛那一份了。Branch 可以分開專案的不同版本路線,但沒有替每個 Agent 準備自己的工作桌。問題其實在工作空間 這次經驗讓我重新理解問題。 我需要的結構是:同一個專案 不同 branch 不同資料夾 每個資料夾可以同時存在 我切換其中一個資料夾時,不影響另一個 Agent理想上,我希望專案可以長這樣: luke-tech-blog/ mainluke-tech-blog.prompt-eval/ agent/prompt-evalluke-tech-blog.search-page/ feature/search-page這樣我就可以把不同任務分配到不同目錄: Agent A -> luke-tech-blog.prompt-eval Agent B -> luke-tech-blog.search-page每個 Agent 都有自己的 branch,也有自己的資料夾。長時間任務不會因為我切 branch 被中斷,不同 Agent 的修改也不會混在同一個地方。 這是多 Agent 協作第一個很務實的限制:任務可以平行,工作空間也要能平行。 下一篇,我會接著介紹我後來改用的解法:Git worktree。它可以讓同一個專案在不同資料夾同時打開不同 branch,也讓每個 Agent 有自己的工作桌。 小結當 Agent 開始承接長時間任務,每個 Agent 都需要一個不會被別人突然換掉的工作資料夾。善用 AI Coding Agent(下):用 Git Worktree 替每個 Agent 建立獨立工作區
Read More
善用 AI Coding Agent(下):用 Git Worktree 替每個 Agent 建立獨立工作區
上一篇提到,我一開始想用 branch 解決多 Agent 協作的問題,後來發現單一 working directory 會把所有人綁在同一個 checkout 狀態上。善用 AI Coding Agent(上):當 Branch 不足以支撐多 Agent 協作當一個 Agent 正在某個 branch 上跑長時間任務時,如果我在同一個資料夾切到另一個 branch,Agent 實際看到的檔案也會跟著改變。這會讓它的上下文、測試結果、接下來要修改的檔案互相對不上。 我後來採用的解法是 Git worktree。它剛好提供我要的結構:同一個 repo,可以在不同資料夾同時打開不同 branch。Worktree 把 branch 從單一 checkout 狀態中拆出來,讓每個 Agent 都有自己的檔案現場。Worktree 的模型 Git worktree 可以讓同一個 Git repository 擁有多個 working tree。 簡單說,它可以替不同 branch 建立不同的工作目錄。 它不是重新 clone 一份 repository。這些 worktree 仍然共享同一份 Git 物件資料庫,但每個 worktree 都有自己的檔案目錄與 checkout 狀態。 用白話說: project/ mainproject.prompt-eval/ agent/prompt-evalproject.search-page/ feature/search-page每個目錄都有自己的 checkout 狀態。你在 project.search-page 修改檔案,不會改到 project.prompt-eval 的 working directory。 從成本角度看,worktree 不是免費的。每個 worktree 都會有一份實際檔案,空間複雜度可以粗略視為 O(s),s 是 working tree 展開後的檔案大小。它共享 Git object database,所以通常比完整 clone 省,但 node_modules、build cache、.env、產物目錄仍然各自存在。 建立或切換 worktree 的時間成本主要來自 checkout 檔案,粗略是 O(n),n 是需要寫入工作目錄的檔案數。實務上,這筆成本換來的是更穩定的隔離邊界:長時間任務不會被另一個 branch checkout 打斷。 建立 Agent 專用工作區 假設我現在在主專案目錄: cd luke-tech-blog我想替 prompt evaluation 任務建立一個新的 branch 和工作目錄,可以執行: git worktree add ../luke-tech-blog.prompt-eval -b agent/prompt-eval這個指令做了兩件事:建立一個新的 branch:agent/prompt-eval 建立一個新的工作目錄:../luke-tech-blog.prompt-eval接著我就可以進入那個目錄: cd ../luke-tech-blog.prompt-eval從這一刻開始,這個資料夾就是 agent/prompt-eval branch 的工作空間。 原本的 luke-tech-blog 目錄仍然可以停在 main 或其他 branch,不會被這個任務影響。 如果 branch 已經存在,只是想替它建立一個工作目錄,可以這樣做: git worktree add ../luke-tech-blog.search-page feature/search-page這會把 feature/search-page checkout 到 ../luke-tech-blog.search-page。 之後你就可以讓另一個 Agent 在這個資料夾工作。 管理 Worktree 可以用這個指令查看目前 repository 連到哪些 worktree: git worktree list輸出大概會像這樣: /Users/luke/projects/luke-tech-blog abc1234 [main] /Users/luke/projects/luke-tech-blog.prompt-eval def5678 [agent/prompt-eval] /Users/luke/projects/luke-tech-blog.search-page 789abcd [feature/search-page]任務完成、branch merge 之後,可以移除 worktree: git worktree remove ../luke-tech-blog.prompt-eval如果手動刪掉資料夾,Git 可能還保留著 worktree 紀錄。這時可以執行: git worktree prune這會清掉已經不存在的 worktree 紀錄。 指令小結日常使用先記住三個指令就夠:git worktree add、git worktree list、git worktree remove。我的多 Agent 分配方式 使用 Git worktree 之後,我的多 Agent 工作流會變成這樣: git worktree add ../project.prompt-eval -b agent/prompt-eval git worktree add ../project.search-page -b agent/search-page git worktree add ../project.refactor-card -b agent/refactor-card然後我會把任務講清楚: 你在 ../project.prompt-eval 這個 worktree 工作。 請專注處理 prompt evaluation 任務。 不要修改 UI、部署設定或無關的資料結構。 完成後請回報修改檔案、測試結果與風險。另一個 Agent 則可能是: 你在 ../project.search-page 這個 worktree 工作。 請實作搜尋頁面的前端功能。 不要修改 prompt evaluation 相關檔案。 完成後請執行 build,並整理主要 diff。這裡要建立的是一個可重複的工作流:一個 Agent 對應一個明確任務 一個任務對應一個 branch 一個 branch 對應一個 worktree 每個 worktree 有自己的檔案狀態這個規則可以降低 review 成本。每個 worktree 最後對應一組 diff,工程師可以用一般 Git 流程看變更、跑測試、決定 merge 順序。 它解決的痛點 Git worktree 最直接解決的是檔案工作區被互相影響的問題。 在單一資料夾裡,切 branch 會改變整個 working directory。你、Agent A、Agent B 共用同一個檔案現場;只要其中一方切 branch,其他工作都會受影響。 使用 worktree 之後,每個 Agent 都有自己的桌子: project/ mainproject.prompt-eval/ agent/prompt-evalproject.search-page/ agent/search-pageproject.refactor-card/ agent/refactor-card這帶來幾個好處:長時間任務不會因為你切 branch 被中斷 不同 Agent 的修改不會混在同一個 working directory 每個任務的 diff 更容易 review 可以保留一個乾淨的主工作區 多個 Agent 才真的有機會平行工作工作流小結Worktree 不會讓 merge conflict 消失,但它會讓每個 Agent 在任務執行期間擁有穩定的檔案世界。人類負責協調邊界 AI Coding Agent 變強之後,人類的工作開始往協調者靠近。 我現在更常做這些事:定義任務邊界 選擇適合交給 Agent 的工作 分配不同 worktree 限制修改範圍 要求 Agent 執行驗證 Review diff 決定哪些變更可以 mergeGit worktree 的價值就在這裡。它提供工程流程需要的隔離邊界,讓多個 Agent 可以同時工作,也讓人類保留 review、驗證、整合的控制權。 常見注意事項 使用 worktree 時,有幾個地方要注意。 第一,同一個 branch 通常不能同時被兩個 worktree checkout。這是 Git 的保護機制,避免同一條工作線在兩個地方同時被修改。 第二,不要直接把 worktree 建在原本 repo 的子目錄裡。否則有些工具在搜尋、格式化、跑測試時,可能會把其他 worktree 也掃進去。 我會比較建議這種結構: projects/ luke-tech-blog/ luke-tech-blog.prompt-eval/ luke-tech-blog.search-page/ luke-tech-blog.refactor-card/第三,多個 worktree 可能各自需要安裝 dependencies。即使它們共享 Git 物件,工作目錄裡的 node_modules、build cache、.env 等檔案仍然要自己管理。 這裡推薦一個實戰細節:如果你的專案使用 pnpm(非常適合 Astro 專案),因為其獨特的「全域硬體連結儲存庫(Global Hard-Link Store)」設計,在每個 worktree 目錄執行 pnpm install 不僅能秒級完成,而且幾乎不額外佔用磁碟空間。這能完美解決多 worktree 重複安裝套件又慢又佔空間的痛點。 此外,為了避免在桌面開啟多個 Cursor 或 VS Code 視窗造成的混亂,你可以使用 VS Code 的 Multi-root Workspace 功能。在根目錄建立一個 .code-workspace 檔案,同時引入主目錄與多個活躍的 worktree: { "folders": [ { "path": "luke-tech-blog" }, { "path": "../luke-tech-blog.prompt-eval" }, { "path": "../luke-tech-blog.search-page" } ] }這樣一來,你就可以在同一個 Cursor 視窗的側邊欄中,同時管理與檢視不同工作區的檔案與變更,協調邊界與審查 diff 都會變得極度輕鬆。 第四,worktree 只能隔離工作空間,不能消除 merge conflict。 如果兩個 Agent 同時修改同一個核心檔案,最後合併時還是可能衝突。Worktree 能避免工作期間互相踩檔案狀態,任務邊界仍然要由人類先設計好。 我會優先把這些任務分到不同 worktree:長時間評估任務 不同 feature 的開發 bug fix 文件更新 測試補強 UI 與 backend 可以明確分開的修改 refactor 範圍清楚的小型重構我會避免同時平行丟出這些任務:多個 Agent 同時重構同一個核心 abstraction 多個 Agent 同時修改 shared schema 多個 Agent 同時調整全域設定 任務描述只有「幫我優化整個專案」小結 當 AI Coding Agent 只幫我們改一小段程式碼時,單一 IDE、單一工作目錄通常就夠了。當 Agent 開始執行長時間任務,甚至多個 Agent 同時處理不同 feature,工作空間管理會變成第一個要補上的工程環節。 Git worktree 提供了一個很實用的基礎。每個 Agent 有自己的 branch 與資料夾,不同任務在檔案層級被隔離;人類負責定義任務、檢查結果、整合變更。 結論善用 AI Coding Agent 的第一步,是替每個長時間任務安排穩定、可驗證、可回收的工作空間。
Read More
PostgreSQL 效能優化(上):LIKE 和 Regex,哪個比較快?
這篇文章是我在工作上真的卡住過的一次效能問題。中間繞了一些路,最後才把真正的瓶頸抓出來。 本篇為上集,先談 LIKE 與 Regex 的抉擇與 I/O/CPU 迷思;接續兩集分別深入:中集:用 EXPLAIN 看見 Seq Scan 的真相 下集:用 Array + GIN 把標籤變成索引上集:當 LIKE 遇上 Regex,到底差在哪? 1. 問題背景(白話版) 我在工作上接了一批 ETL 後的資料。每筆資料裡,很多標籤被塞在同一個欄位,用 ; 串起來,像這樣: tag1;tag2;tag3;tag_VIP;tag_inactive 當我要找特定標籤時,最直覺是寫很多個 LIKE。 2. 同事一句提醒,直接點到問題 同事說:「把多個 LIKE 合成一個 Regex,通常會更快。」 我第一反應是:「沒有索引的話,不是都要整張表一筆一筆看過去嗎?那真的會快多少?」 3. 我們都沒錯,只是看的是不同成本 後來我才搞懂,我們其實切入點不同:我先看讀取成本(I/O),同事先看運算成本(CPU)。我看的是 I/O(讀資料成本)沒有索引時,資料庫通常還是要掃很多資料。這件事不會因為你改成 Regex 就消失。 同事看的是 CPU(運算成本)多個 LIKE 代表同一列要重複比對很多次;合成一個 Regex,通常可把「重複比對」變少。用比喻來說:多個 LIKE 像是同一本書翻很多輪,每次找一個關鍵字。 單一 Regex 像是一輪閱讀就把多個關鍵字一起判斷。4. 這篇上集我最想說的事 如果資料量還小,Regex 可能已經很有感。但資料一大,只換語法通常不夠,最後還是得讓資料庫用不同方式找資料。 結論Regex 可以先減輕 CPU 壓力,但只要查詢還在掃整張表,I/O 依然會是主瓶頸。中集從 EXPLAIN ANALYZE 拆解 LIKE 與 Regex 的真實成本,下集則動手實作 Array + GIN:PostgreSQL 效能優化(中):用 EXPLAIN 看見 Seq Scan 的真相 PostgreSQL 效能優化(下):用 Array + GIN 把標籤變成索引
Read More