從 Coding Assistant 到開發協作者:我使用 AI Agent 的方式轉變了
從 Copilot、Cursor 到 CLI agent,分享如何拆分任務、驗證 AI 產出的程式碼,並在使用 AI 的同時保留工程判斷。
過去我使用 AI agent 的方式比較保守。
通常我會先自己思考完整的架構,決定核心模組怎麼拆分,再由 agent 協助處理比較局部的工作,例如調整某個 method、補上文件、撰寫測試,或協助確認某段程式碼是否有問題。整體來說,agent 比較像是一個隨時可以詢問的 coding assistant,而不是實際負責一段功能開發的工程師。
但最近幾個月,我開始慢慢改變這個習慣。隨著模型處理複雜專案的能力提升,它不再只能針對單一檔案提供建議,而是能夠理解專案結構、追蹤模組之間的關係,甚至協助進行大範圍重構和新功能開發。
這讓我開始思考:如果 agent 已經可以接手更大範圍的開發工作,那工程師自己的角色應該怎麼改變?我們需要親自完成的,還是每一個 method 的實作嗎?還是更重要的是定義問題、拆分任務、設定限制,並且驗證 agent 產生的結果?
而這個轉變也出現在最近的面試過程中。現在有些面試官不只想知道你會不會寫程式,也會透過實作題觀察你如何使用 AI、如何和 agent 協作,以及你是否有能力判斷它產出的程式碼是否可靠。
從 Tab 到 Chat
Agent 協作最早可以從我大四的時候開始。當年在大四準備畢業的時候 GitHub Copilot 剛推出,一開始他們整合在 VSCode 中並透過 tab 的形式做程式碼補全。

起初這就讓我夠驚艷了,過去在還沒 Copilot 並且還在學習階段的時候開發一組 CRUD API 再到前端串接,整個 E2E 的流程幾乎可以花費我 1 到 2 天的時間,中間包含查 Stack Overflow 及相關文章; 然而在 GitHub Copilot 出來後這也大幅度縮小開發時間了,當年他可以從既有的 code 做對應的程式碼生成除了減少重複性較高的方法開發,甚至他也可以基於方法名稱就直接實現這個方法。
而這樣的開發方式一路持續到 2024 年左右,我又做了一次轉換。那時候 Cursor 正紅,但我剛開始使用時其實很不習慣。這是我第一次用聊天的方式修改程式碼,使用一段時間後,甚至又切回 VSCode 開發。不過那時候 Cursor 的 tab 補全確實比 Copilot 更方便。

後來真正讓我留下來使用 Cursor Chat 的原因,是它可以直接在現有的 codebase 中理解專案上下文。過去遇到問題時,我通常需要先整理相關程式碼和錯誤訊息,再複製到瀏覽器來查詢。這個過程不只需要花時間整理資訊,有時候也會因為漏掉某個檔案或相依關係,讓得到的答案不完整。
Cursor Chat 讓我可以直接在目前的專案環境中,針對正在閱讀或修改的程式碼詢問 agent。例如:我可以請它說明一段資料流、找出某個錯誤可能涉及的模組,或協助確認一個修改方向。這樣就不需要一直在編輯器和瀏覽器之間切換,也不用反覆複製和整理上下文。
這也是我從單純依賴 tab 補全,逐漸轉向透過聊天和 agent 協作的主要原因。tab 仍然適合處理局部而且明確的程式碼補全;但當問題涉及多個檔案,或需要先釐清專案脈絡時,直接在 codebase 中和 agent 對話,更符合我的開發流程。
從局部修改到完整任務
還記得去年開發 Donkin.ai 時,我花了不少時間規劃和設計整個專案的模組,包含 TradingView 的圖表插件、Agent 的聊天狀態管理,以及各個交易相關模組。

Donkin.ai
這是我們當初整合大型語言模型與多元外部資料來源,並透過社群爬蟲與錢包識別技術進行即時事件監測的去中心化投顧平台,使用者可以透過 Agent 的多輪聊天功能,了解對應幣種及交易錢包的分析狀況。
當時在整理聊天架構時,我花了不少時間研究如何處理 SSE,以及如何將前端的資料流和方法呼叫整合到其他頁面,讓後續新增頁面和工具呼叫時不需要重新設計整套流程。

那時候我參考了 Lightweight Charts 官方的插件,以及 LobeChat 的聊天管理方式。LobeChat 同樣使用 Zustand 管理相關狀態,也有完整的前後端實作可以研究。
這個階段的開發方式比較接近過去熟悉的流程:我會先理解需求,再自己規劃模組、研究相關專案,最後逐步完成核心功能。當時 agent 主要還是協助查詢、補上局部程式碼或處理重複性的工作,專案的架構和主要技術決策仍然由我自己負責。
這樣的開發模式持續到今年下半年。當我從 Cursor 陸續轉向 CLI agent,例如 Claude Code 和 Codex 後,和 agent 協作的方式也開始改變。
之所以會有這轉變主要是模型的變化關係,過往的模型在較大的任務及整體的 codebase 理解能力仍有落差;然而 Fable 出來後不得不說他的理解力跟執行力真的好上不少了。除了模型本身的進步之外還有一點是目前自己開發的專案架構都越來越複雜了,有的是上了年紀摻雜了過時的程式有的則是模組拆分較多,而這時候透過 Agent 能夠幫助我更快理解既有架構、找出需要修改的檔案,並且一次完成跨模組的功能。這也讓 agent 不再只是協助我處理零碎工作,而是可以在我定義好目標和限制後,實際負責一個完整任務的執行。
起初用 Fable 有一次讓我很驚艷的點是,當初有個專案要調整 GitHub actions 一段的私有套件安裝方式的驗證,結果 Fable 是我第一個看到直接自主用 gh CLI 去線上確認 log 的,並且對焦到問題後,他直接去了我另一個本地 repo (就是 action 上要安裝的那個 repo) 改了一個 postinstall 的指令修正後並 commit,其實當下看到本來想要阻止結果後來看了改動確實合理;也注意到近期較新的模型幾乎都會這樣做了,他們開始會自主的對齊問題並驗證再做自主修復,過去這些行為在過往模型幾乎看不到,有的可能去網路上查再反饋給你而已,而現在模型在自主驗證及修復能力真的很強。
這次轉換不只是從 GUI 改成 CLI,也讓我的工作重心從 以 code 為主、agent 為輔,逐漸轉成 以任務為主、讓 agent 協助執行。過去我通常會先找到需要修改的檔案,再請 agent 協助處理其中一段程式碼;後來則會先說明要完成的目標和限制,讓 agent 自己閱讀 codebase、找出相關檔案,並提出修改方式。

因此,我交付給 agent 的範圍也從單一方法或局部修改,逐漸擴大到跨模組的重構和完整功能開發。這也讓我開始重新整理自己現在如何拆分任務、提供上下文,以及驗證 agent 產出結果的方式。
我現在如何把任務交給 agent
當我開始把更大範圍的任務交給 agent 後,最明顯的改變是:我不會再直接告訴它要修改哪個檔案或哪個方法,而是先描述這次要解決的問題及需求。

先確認需求、上下文和架構
雖然現在會讓 agent 自己閱讀 codebase、找出相關檔案,但這不代表我可以完全不了解原本的架構。相反地,自己仍然需要知道專案大致如何拆分、主要資料流怎麼運作,以及這次需求可能會影響哪些模組。這些理解可以幫助我判斷 agent 提出的方向是否合理,也能在它偏離需求時及時修正。
在真正開始修改之前,我通常會先用幾種方式確認自己和 agent 對問題的理解是否一致。其中一種方式,是直接告訴它預計採用的實作方向,但不特別說明背後的目的和需求;另一種方式,則是先描述目前遇到的問題和預期結果,但不指定具體的實作方式。
這兩種方式說明完之後,我都會先請 agent 評估並提供反饋,再決定是否讓它開始修改。透過這個過程,我也能觀察不同模型理解問題和需求的能力,以及它們提出的解決方向是否符合我的預期。
這裡以我個人部落格的驗證層級調整為例:我希望將 www 的 agent 權限驗證改成必須登入後才能使用。原本的規劃是讓一般未登入使用者也能使用,但目前仍在開發階段,所以暫時只有 root 可以使用。接著,我會請 agent 先確認這項需求需要調整哪些地方。

有些模型,例如 Opus 5,會先整理這次需求中需要釐清的部分,再一次提出問題。這樣做的好處是可以更快對焦需求;但有時候它提出的方案也會和我原本預期的方向不同。整體而言,它通常能把需要確認的內容整理得蠻清楚,也可能幫我注意到原本忽略的地方。
另外,有些模型像 Fable,則會直接提供建議方向,並說明需要調整哪些地方,以及這些調整的原因。它甚至會列出預期修改的檔案和可能影響的範圍。這時候我通常會先檢查它是否正確理解需求,再補充遺漏的限制或修正方向。確認彼此對目標有共識後,才會讓它開始進行實作。
先規劃,再分階段執行
當需求和實作方向確認後,我才會讓 agent 開始修改。這時候我通常不會一次要求它完成所有事情,而是會先請它依照剛才的規劃執行。完成後,我會先檢查 diff、執行測試,再針對結果繼續追問或調整,確認每個階段的修改都符合預期。
在這個過程中,我也注意到高階模型的 token 費用之所以比較高,並不是沒有原因。目前以我自己的 review 經驗來說,Fable 的流程最順。它通常有較高的完成度,能比較直接地完成任務,也不太會繞遠路。相較之下,Opus 有時候會出現 過度思考 的情況,原本簡單的需求可能被它拆解得過於複雜,最後雖然完成了任務,卻也讓人更難理解整體實作。
這也讓我更確定,選擇模型時不能只看它能不能把任務完成,還要看最後產出的程式碼是否容易理解、是否符合既有架構,以及後續是否容易維護。agent 可以協助完成更多工作,但最後的 review 和技術判斷仍然需要由自己負責。
把任務交給 agent,不代表把責任交出去
現在不少人會把 AI agent 帶來的改變,放在 產品價值 和 程式碼變便宜 這兩個方向上。確實,agent 可以讓功能更快被實作出來,也讓工程師能用更短的時間完成過去需要花很多時間的工作。
但在我看來,程式碼的產生成本降低,不代表系統的維護成本也會一起降低。如果 agent 沒有理解原本的架構和限制,只是快速產生一段當下看起來可以運作的程式碼,後續功能加入後,反而可能增加更多問題。這類只針對眼前需求、沒有考慮整體上下文的程式碼,也很容易變成需要之後再收拾的 slop code。
API 型別理解錯誤:ky 的 onUploadProgress
我自己就遇過程式碼可以通過 TypeScript 檢查,但實際上沒有按照預期運作的情況。
ky 是建立在 Fetch API 之上的 HTTP client,這裡使用它的 onUploadProgress callback 追蹤檔案上傳進度。過去較低階的模型曾經協助產生下面這段程式碼:
onUploadProgress: (progress: unknown) => {
const progressEvent = progress as {
loaded: number;
total?: number;
};
if (
progressEvent &&
typeof progressEvent.loaded === "number" &&
progressEvent.total &&
progressEvent.total > 0
) {
const percent = Math.round(
(progressEvent.loaded / progressEvent.total) * 50 + 50
);
setUploadItems((prev) =>
prev.map((i) =>
i.id === item.id ? { ...i, progress: percent } : i
)
);
}
},這段程式碼把 progress 當成瀏覽器常見的 progress event,假設裡面會有 loaded 和 total 兩個欄位。但 ky 的 onUploadProgress 實際上會使用包含以下欄位的資料格式:
type Progress = {
percent: number;
transferredBytes: number;
totalBytes: number;
};正確的欄位是 transferredBytes 和 totalBytes,而不是 loaded 和 total。由於這段程式碼先把參數宣告成 unknown,再透過 type assertion 強制轉成自訂型別,TypeScript 不會知道這個假設和實際 API 不一致。結果是 progressEvent.loaded 實際上會是 undefined,條件判斷不會成立,後面的 setUploadItems 也就不會執行。除非有人真的去檢查 API 文件或追蹤執行結果,否則很難只從 type check 發現問題。
React 的 useEffect 和 setState
前端也有另一類問題。以 React 為例,有些模型很容易在 useEffect 裡呼叫 setState。如果 dependency array 和 state 更新之間沒有處理好,這段程式碼在當下的 A 功能中可能還能正常運作,但後續加入 B 功能、改變資料流或增加新的 state 後,就可能產生不必要的重新渲染,甚至形成 infinite loop。這類問題通常不是只修改某一行程式碼就能完整解決,而是需要回頭檢查 state 的責任邊界、資料流和元件架構。
CRON job 和多 replicas
後端也有類似的情況。例如需要定期執行的工作,如果服務會以多個 replicas 運行,通常不會直接在每個 backend instance 裡使用 setInterval。否則每個 replica 都可能同時執行同一個 job,造成重複處理或資料競爭。實務上,我們可能會把 CRON job 放到獨立的 worker 或排程服務中,讓它和處理一般 request 的 backend 分開。但如果 agent 不知道目前的部署方式,只看到「每隔一段時間執行某個函式」的需求,就可能直接在 backend 裡加入一個 interval。這段程式碼在本機或單一 instance 的環境中看起來可以運作,部署到多 replicas 後卻可能產生完全不同的問題。
這些問題的共同點是,agent 都可能產生一段看起來合理的程式碼,但它未必理解整個系統的上下文。工程師如果只確認程式碼能不能編譯,或只看當下功能有沒有跑起來,就可能把錯誤延後到下一個功能、正式環境或未來維護時才發現。
因此,把任務交給 agent 的前提,是自己仍然要理解既有的架構、資料流、API 和部署方式。agent 可以協助閱讀檔案、整理問題、提出修改方案,甚至直接完成跨模組的實作;但最後的技術判斷和 review 仍然需要由自己負責。如果自己無法解釋 agent 產生的程式碼,就不應該直接把它合併進專案。
面試開始評估如何使用 AI
自己這兩年面試下來,也陸續遇到面試官評估面試者使用 AI 的方式。有些會直接給實作題,有些則是口頭詢問平常的使用習慣。印象中,第一次遇到是在去年 11 月,當時的題目是要錄影實作一個轉盤應用,並完成其他延伸功能。
第一次遇到這類題目時,我其實蠻意外的。因為在這之前,自己多半還是做白板題;但到了近期的面試,感覺評估重點也逐漸轉向如何使用 AI。
Coinbase 在 7 月分享了他們花一年時間重新設計工程面試流程的經驗,並將 AI fluency 納入所有面試階段。
Coinbase 表示,AI 產生的程式碼占合併程式碼的比例,從 2025 年第一季的 5.7%,到 2025 年第四季首次超過 50%。後來幾乎所有新程式碼都由 AI 生成,但仍然需要由人類審查,確認品質與合規性。
在這樣的工作方式下,資深工程師的核心工作也會轉向:寫清楚規格、引導 AI 產出實作、審查 PR 的正確性與安全性、找出模型看似有信心但實際錯誤的架構決策,以及評估取捨、風險和系統邊界。
目前對 AI agent 開發的看法
這是 Vercel CEO Guillermo Rauch 近期分享的文章。
未來大部分程式碼可能會變得更像組合工作,工程師不一定需要親自完成每一個方法。但在那之前,軟體基礎設施和真實使用者仍然是建立在這些模型產出的程式碼上。只要系統還需要長期運作,工程師就不能把閱讀、理解和驗證程式碼的責任交出去。
這也是我目前對 AI agent 的態度:可以把更大範圍的任務交給 agent,但不能因此停止閱讀程式碼。agent 可以負責執行,工程師仍然需要理解它做了什麼,並且對最後的架構、風險和結果負責。
Written by: Chia1104 CC BY-NC-SA 4.0