在周三之前,我花了每周分配給Claude的預算中的64%來開發(fā)一個旨在減少對Claude使用頻率的工具。這種具有諷刺意味的情況,確實值得專門寫一篇說明來描述。
這個工具被稱為“spec-writer”:它是一種基于Claude Code開發(fā)的技能,能夠在編寫任何一行代碼之前,根據(jù)用戶提供的模糊需求生成結(jié)構(gòu)化明確的需求文檔、技術(shù)計劃以及任務(wù)分解方案。
它所解決的問題,正是大多數(shù)開發(fā)者在使用AI編碼助手的第一周就會遇到的問題:這些助手會“自信地”朝著錯誤的方向進行開發(fā),而你卻因此付出雙重代價——一次是消耗代幣,另一次則是需要重新修改代碼。
本教程將教你如何安裝spec-writer,如何在實際項目中使用它,以及如何解讀其生成的輸出結(jié)果,這樣你就能及時發(fā)現(xiàn)那些可能會浪費你時間的錯誤假設(shè)或不合理設(shè)計。
目錄
直接使用提示語來指導助手開發(fā)的問題
如果你跳過了編寫需求文檔這個步驟,就會發(fā)生以下情況:
你腦海中有一個功能需求:“為用戶提供導出數(shù)據(jù)的功能。”你打開Claude Code并描述了這個需求,助手隨后生成了代碼。乍看之下,代碼似乎沒什么問題,但你運行后發(fā)現(xiàn):它不僅會導出所有數(shù)據(jù),包括那些被“軟刪除”的記錄;也沒有分頁功能;在處理大型賬戶時會出現(xiàn)超時現(xiàn)象;而且導出接口也沒有任何身份驗證機制。
這些錯誤其實都并不在你的原始需求描述中。助手是根據(jù)自己的判斷來生成代碼的,而這種判斷雖然看似合理,但實際上卻完全是錯誤的。直到你進行測試時,才發(fā)現(xiàn)了這些問題。
對于任何非簡單的開發(fā)任務(wù)來說,直接使用提示語來指導助手開發(fā),本質(zhì)上面臨的就是這個問題:你的提示語只反映了你意識中明確提出的需求,但每個功能背后其實都存在著一些你沒有考慮到的潛在要求,而助手就會根據(jù)這些隱含的要求來生成代碼。
大多數(shù)情況下,這些隱含的要求都是合理的;但有時候,它們也會導致嚴重的錯誤,而要發(fā)現(xiàn)這些錯誤往往需要花費很多時間。
這種錯誤的本質(zhì)并不是“幻覺”,而是助手僅僅按照你提供的提示語來工作,而已這些提示語本身并不足以確保開發(fā)出正確的結(jié)果。
規(guī)范驅(qū)動的開發(fā)方式正是為了解決這個問題而設(shè)計的。像Julián Deangelis這樣的專家已經(jīng)對這種方法進行了深入的探討,他們認為:編寫需求文檔并不是一種額外的負擔,而是一種強制你在助手開始開發(fā)之前就明確各項要求的機制。
什么是規(guī)范驅(qū)動開發(fā)
規(guī)范驅(qū)動開發(fā)是指在編寫代碼或啟動自動化工具之前,先制定結(jié)構(gòu)清晰的規(guī)范文檔。這份規(guī)范明確了功能需要實現(xiàn)的具體內(nèi)容、所基于的假設(shè)條件,以及實現(xiàn)過程應(yīng)分解為哪些步驟。
關(guān)鍵在于要明白規(guī)范的作用:規(guī)范并不是為了替代代碼,而是為了讓那些原本隱藏在開發(fā)過程中的決策變得顯而易見。無論有沒有規(guī)范,自動化工具最終都會做出這些決策;但有規(guī)范的話,這些決策可以在開發(fā)初期就被明確下來;而沒有規(guī)范的話,就只能在測試階段才發(fā)現(xiàn)這些問題。
針對規(guī)范驅(qū)動開發(fā)最有力的反對意見來自Gabriella Gonzalez:她認為“一份足夠詳細的規(guī)范本質(zhì)上就是代碼”。她的觀點有一定道理,因為有些規(guī)范確實會詳細到幾乎與實現(xiàn)代碼沒有區(qū)別的程度。
但問題在于,這些規(guī)范所采用的抽象層次并不合適。規(guī)范的作用應(yīng)該是明確各項決策,而不是預先完成這些決策的實現(xiàn)。“只有經(jīng)過身份驗證的用戶才能執(zhí)行此操作”屬于決策內(nèi)容,而“調(diào)用verifyJWT(token),如果失敗則返回401錯誤碼”則是具體的實現(xiàn)細節(jié)。規(guī)范應(yīng)該側(cè)重于前者,而后者則應(yīng)由自動化工具來處理。
規(guī)范驅(qū)動開發(fā)可以分為三個層次:
-
規(guī)范優(yōu)先:在開發(fā)每個功能之前先制定規(guī)范文檔,然后將其作為輸入提供給自動化工具。本教程重點介紹的就是這種工作方式。
-
以規(guī)范為依據(jù):規(guī)范文檔保存在代碼倉庫中,并與代碼同步發(fā)展。當需求發(fā)生變化時,只需更新規(guī)范文件,再重新啟動自動化工具即可使其適應(yīng)新的要求。
-
將規(guī)范作為核心資源
:在這種情況下,規(guī)范本身就是最重要的開發(fā)成果,代碼則是根據(jù)規(guī)范生成的,屬于可隨時替換的臨時性產(chǎn)物。這是最高階的規(guī)范驅(qū)動開發(fā)模式,也是許多團隊正在努力的方向。
使用spec-writer工具,你可以立即開始采用“規(guī)范優(yōu)先”的開發(fā)方式,而無需進行任何復雜的設(shè)置。
spec-writer的工作原理
spec-writer是一種屬于Claude Code技能的工具——它是一個Markdown格式的文件,當被導入自動化工具的環(huán)境中后,會改變該工具的處理方式。
這種工具遵循一個原則:先生成完整的規(guī)范文檔,然后直接標明其中所依賴的假設(shè)條件。它在生成結(jié)果之前不會要求用戶進行補充說明,而是會立即生成完整的規(guī)范,并使用[ASSUMPTION: ...]標簽標出所有未經(jīng)用戶明確指定的決策內(nèi)容。之后用戶就可以根據(jù)這些標記來修改錯誤之處。
這種方式比傳統(tǒng)的問答式開發(fā)方式更快,因為它能讓各種決策以一種可以直接應(yīng)對的形式呈現(xiàn)出來,而無需用戶事先進行預測。
生成的輸出文件包含三個固定順序的部分:
-
規(guī)范內(nèi)容:明確功能的目的、用戶需求、邊界情況以及驗收標準,這些信息會按照“給定條件/操作步驟/預期結(jié)果”的格式呈現(xiàn)。
-
實施計劃:包括技術(shù)架構(gòu)選擇、數(shù)據(jù)模型變更、API接口設(shè)計、測試策略以及安全要求等內(nèi)容。
-
具體任務(wù)列表:將整個開發(fā)過程分解為一系列有序且獨立的任務(wù),每個任務(wù)都可以在一次自動化工具運行中完成,并且每個任務(wù)都有各自的驗收標準。
在完成這三個部分的編寫后,該技能會生成一份假設(shè)項匯總:輸出內(nèi)容中的每一條[ASSUMPTION: ...]都會根據(jù)其影響程度進行排序。在將任何內(nèi)容提交給智能助手之前,你都需要先查看這份匯總。
該技能與GitHub Spec Kit以及OpenSpec兼容。如果你使用的是這兩種框架中的任何一種,只需將規(guī)范編寫結(jié)果保存到.specify/或openspec/changes/目錄中,然后繼續(xù)后續(xù)操作即可。
如何安裝spec-writer
spec-writer遵循Agent Skills標準,這意味著同一個SKILL.md文件可以在Claude Code、Cursor、GitHub Copilot、Gemini CLI以及任何支持該標準的智能助手中正常使用。你只需安裝一次,它就可以在所有地方發(fā)揮作用。
安裝步驟
如果還沒有創(chuàng)建技能目錄,請先創(chuàng)建一個,然后克隆相應(yīng)的倉庫:
mkdir -p ~/.claude/skills
git clone https://github.com/dannwaneri/spec-writer.git ~/.claude/skills/spec-writer
在Windows PowerShell中操作時:
注意:PowerShell使用反引號(`)來表示行續(xù)接,而不是反斜杠。
New-Item -ItemType Directory -Force -Path "$HOME\.claude\skills"
git clone https://github.com/dannwaneri/spec-writer.git "$HOME\.claude\skills\spec-writer"
以上就是全部的安裝步驟。不需要安裝任何軟件包,也不需要編輯配置文件或輸入API密鑰。該技能實際上就是一個Markdown文件,智能助手會直接讀取這個文件即可。
驗證安裝是否成功
打開Claude Code,然后輸入以下命令:
/spec-writer test
如果安裝正確,智能助手會讀取SKILL.md文件并生成相應(yīng)的規(guī)范結(jié)構(gòu)——即使輸入的內(nèi)容僅僅是“test”這樣的簡單指令。你會看到三個部分以及假設(shè)項匯總。如果沒有出現(xiàn)任何反應(yīng),請確認~/.claude/skills/spec-writer/SKILL.md文件確實存在。
如何編寫你的第一個規(guī)范文檔
調(diào)用該技能的格式如下:
/spec-writer [你的功能描述]
這個描述可以像你在Slack中發(fā)送消息時寫的那樣簡略。該技能的任務(wù)就是將這些描述整理成規(guī)范的格式。你不需要寫得非常詳細,因為規(guī)范本身才是用來詳細說明各項要求的。
一個實際示例
以下是一個來自Foundation項目的真實調(diào)用示例。該項目是一個基于Cloudflare Workers構(gòu)建的聯(lián)邦知識庫:
/spec-writer Add CLI capture for Claude Code sessions stored in ~/.claude/projects/
這條命令只有十二個字,其中沒有提到技術(shù)棧、數(shù)據(jù)模型細節(jié)、認證要求或錯誤處理機制等內(nèi)容。所有這些信息都會在生成的規(guī)范文檔中體現(xiàn)出來。
以下是該命令執(zhí)行后的簡化輸出結(jié)果:
技術(shù)規(guī)格
功能簡介:** 開發(fā)人員可以將自己本地文件系統(tǒng)中的Claude Code會話日志保存到Foundation系統(tǒng)中,這樣這些日志在30天后被刪除之前就能得到妥善保留。
適用用戶及使用場景:
-
作為每天都會使用Claude Code的開發(fā)人員,我希望自己的編碼會話記錄能夠被自動保存下來,這樣那些關(guān)于架構(gòu)設(shè)計或調(diào)試過程中的信息就不會在30天后丟失。
-
作為Foundation系統(tǒng)的用戶,我希望通過同一個知識庫來查看所有的CLI會話記錄以及瀏覽器擴展程序產(chǎn)生的數(shù)據(jù),這樣我就可以在一個地方查詢所有與AI相關(guān)的交互記錄了。
驗收標準:
當開發(fā)人員的Claude Code會話記錄存儲在~/.claude/projects/目錄中時,如果他們運行Foundation的CLI捕獲命令,系統(tǒng)會顯示一份未捕獲的會話列表,并且這些列表會按照會話創(chuàng)建的時間順序進行排序。
如果某個會話已經(jīng)保存在Foundation系統(tǒng)中,當開發(fā)人員再次運行捕獲命令時,這個會話不會出現(xiàn)在列表中。
如果輸入的.jsonl文件格式不正確,捕獲命令在處理該文件時會記錄錯誤信息,但會繼續(xù)處理其他會話記錄。
實施計劃:
技術(shù)架構(gòu):**
CLI捕獲功能是在本地運行的——它需要讀取本地的文件系統(tǒng)數(shù)據(jù),而Cloudflare Workers無法完成這一操作。[假設(shè):CLI捕獲工具是一個本地的Node.js腳本或Bun腳本,它會調(diào)用Foundation API來保存會話記錄,而不是本身作為一個Worker來運行。]
API接口規(guī)范:
-
POST /api/sessions/import– 接收經(jīng)過解析的JSON格式會話數(shù)據(jù),返回會話ID -
如果會話已經(jīng)存在,該接口會返回409錯誤代碼
-
成功插入會話記錄后,會觸發(fā)相應(yīng)的評估流程
待完成任務(wù):
## 任務(wù)1:.jsonl文件解析器
**開發(fā)內(nèi)容:** 編寫一個解析器,能夠讀取Claude Code生成的.jsonl格式會話文件,并將其轉(zhuǎn)換成Foundation系統(tǒng)內(nèi)部使用的消息格式。
**可能涉及的文件:** cli/src/parsers/claudeCode.js
**驗收標準:**
1. 能夠正確解析有效的.jsonl文件,將其轉(zhuǎn)換為正確的消息格式。
2. 對于格式錯誤的文件,解析器不應(yīng)出現(xiàn)崩潰現(xiàn)象,而應(yīng)記錄錯誤信息并跳過這些錯誤行。
3> 如果文件內(nèi)容為空,解析器應(yīng)返回一個空數(shù)組。
**依賴庫:** 無
需要確認的事項:
1. CLI捕獲工具是一個本地腳本,它通過調(diào)用Foundation API來保存會話記錄,而不是作為一個Worker來運行。
影響程度:高
如果你希望采用純服務(wù)器less架構(gòu),請修改這一設(shè)計。
2> 會話記錄的導入是手動進行的,而非自動批量導入。
影響程度:高
如果你希望實現(xiàn)自動背景捕獲功能,請修改這一設(shè)置。
3> .jsonl文件名中的會話ID被用作去重鍵。
影響程度:中等
如果你的數(shù)據(jù)存儲方案中會話ID的存儲方式不同,請相應(yīng)地調(diào)整代碼。
4> 在當前版本中,不會對會話記錄中的敏感數(shù)據(jù)進行清洗處理。
影響程度:中等
如果你的會話記錄包含密碼或密鑰等敏感信息,請修改相關(guān)邏輯。
在讀了這十二個字之后,立刻就有四個決定浮現(xiàn)出來——其中三個決策實際上對建筑設(shè)計產(chǎn)生了直接影響。
第三個假設(shè)(“.jsonl文件中的會話ID就是去重鍵”)很可能會引發(fā)最隱蔽的錯誤。如果代理程序根據(jù)文件名來執(zhí)行去重操作,那么在會話名稱被更改之前,這種機制應(yīng)該是可以正常工作的。而在任何代碼被編寫出來之前,規(guī)范文檔就已經(jīng)發(fā)現(xiàn)了這個問題。
如何閱讀輸出結(jié)果
輸出結(jié)果的閱讀順序應(yīng)該是:首先查找[ASSUMPTION: ...]標簽,然后再閱讀與任務(wù)相關(guān)的內(nèi)容。
閱讀假設(shè)條件
每個[ASSUMPTION: ...]標簽都標志著代理程序在哪些地方根據(jù)用戶未明確指定的內(nèi)容進行了自動填充。你的任務(wù)是仔細閱讀這些假設(shè)條件,并針對每一條做出如下判斷:
-
正確:該假設(shè)條件是正確的,保留原樣即可。
-
需要修改:該假設(shè)條件有誤,需要重新表述假設(shè)內(nèi)容并重新運行測試流程。
-
暫不處理:對于當前迭代來說,這個假設(shè)條件并不重要,可以直接跳過它繼續(xù)下一步。
影響程度的評級會告訴你哪些假設(shè)條件需要在開始編碼之前先進行修正。影響程度較高的假設(shè)條件會影響到系統(tǒng)架構(gòu)或數(shù)據(jù)模型;如果這些假設(shè)有誤,修改它們會導致整個系統(tǒng)需要重新設(shè)計。而影響程度較低的假設(shè)條件則會影響那些日后容易更改的行為細節(jié)。
閱讀驗收標準
以“Given/When/Then”格式編寫的驗收標準是規(guī)范文檔中用于檢測范圍錯誤的最有用部分。閱讀每一條驗收標準后,要問自己:這確實是我想要測試的內(nèi)容嗎?
驗收標準的性質(zhì)本質(zhì)上是二元的。“未認證時返回401狀態(tài)碼”屬于明確的驗收標準,而“運行正常”則不屬于。如果你在閱讀某條驗收標準時覺得“這個標準其實并不明確”,那么這說明這條標準背后隱藏著某種假設(shè)條件,你需要重新表述這條標準。
閱讀任務(wù)內(nèi)容
這些任務(wù)都是按順序排列的,并且每個任務(wù)都能產(chǎn)生可驗證的結(jié)果。在將任何任務(wù)交給代理程序執(zhí)行之前,請先檢查以下兩點:
-
該任務(wù)是否包含了所有必要的上下文信息?如果任務(wù)要求“遵循現(xiàn)有的認證機制”,但你還沒有向代理程序提供相應(yīng)的認證代碼,那么代理程序就會自行猜測。
-
該任務(wù)的驗收標準是否與你實際想要測試的內(nèi)容一致?如果驗收標準不夠明確,請在代理程序開始執(zhí)行任務(wù)之前將其細化。
如何將規(guī)范文檔交給代理程序
規(guī)范文檔本身就包含了完成任務(wù)所需的所有上下文信息,它并不需要用戶另行提供提示或說明。當為某個任務(wù)啟動代理程序會話時,請將相關(guān)的規(guī)范內(nèi)容與任務(wù)描述一起提供給代理程序。
以上面例子中的任務(wù)1為例,你的代理程序會話可能會這樣開啟:
上下文信息:
- 該系統(tǒng)是一個基于Cloudflare Workers、D1和Vectorize構(gòu)建的聯(lián)邦知識庫。
- 會話數(shù)據(jù)以.jsonl文件的格式存儲在~/.claude/projects/目錄下。
- API接口的地址為https://.workers.dev。
規(guī)范內(nèi)容:
[粘貼SPEC和PLAN部分]
任務(wù)內(nèi)容:
[粘貼任務(wù)1的具體要求]
上述示例僅用于說明目的。請將其替換為您自己項目所使用的技術(shù)棧、文件路徑以及API地址。關(guān)鍵在于要讓代理在第一天就能獲得與新團隊成員相同的開發(fā)環(huán)境信息。
現(xiàn)在,代理已經(jīng)掌握了需求信息、架構(gòu)背景,以及一項具有明確驗收標準的具體任務(wù)。由于規(guī)范中已經(jīng)明確了相關(guān)細節(jié),因此它不可能錯誤地判斷去重鍵的值;同時,由于驗收標準有明確要求,它也不能忽略錯誤處理環(huán)節(jié)。
這就是該規(guī)范所設(shè)計的目的——它并非取代代理的工作,而是將決策權(quán)從代理手中轉(zhuǎn)移到您的手中,在工作開始之前就為所有事項制定明確的規(guī)則。
保存規(guī)范以備后續(xù)使用
如果您希望采用“以規(guī)范為導向的開發(fā)模式”,即讓規(guī)范存儲在代碼倉庫中,那么請將生成的結(jié)果文件保存到項目中的specs/目錄下:
# 創(chuàng)建spec目錄
mkdir -p specs
# 保存您的規(guī)范文件
# 將輸出內(nèi)容粘貼到specs/cli-capture.md文件中
當需求發(fā)生變化時,只需更新規(guī)范文件,然后重新讓代理根據(jù)新的規(guī)范來調(diào)整開發(fā)工作。此時,規(guī)范才是權(quán)威依據(jù),而非代碼注釋。
下一步該怎么做
在編寫任何代碼之前,先在下一個功能開發(fā)項目中嘗試使用這種規(guī)范編寫方式。規(guī)范中指出的那些問題會幫助您發(fā)現(xiàn)一些尚未被意識到的問題——而在將任務(wù)交給代理之前糾正這些高影響性的錯誤,正是這一方法的核心意義。如果跳過這個步驟,就相當于直接讓代理隨意決策。
如果您的項目規(guī)模正在擴大,建議盡快采用“以規(guī)范為導向的開發(fā)模式”。請將所有規(guī)范文件保存在代碼倉庫的specs/目錄下。這樣,當有新成員加入團隊或代理開始新的工作流程時,他們可以直接參考這些規(guī)范來開展工作,而無需花費時間去反推代碼實現(xiàn)細節(jié)。
目前,這種開發(fā)模式面臨的最大挑戰(zhàn)在于有人認為過于詳細的規(guī)范實際上會變成代碼本身。如果您的規(guī)范文件中包含了具體的實現(xiàn)細節(jié),那就意味著您已經(jīng)越過了合適的界限。應(yīng)該把決策權(quán)保留給自己,只規(guī)定“只有經(jīng)過身份驗證的用戶才能執(zhí)行某項操作”,而將具體實現(xiàn)工作交給代理來完成。規(guī)范的作用應(yīng)該是指出那些代理可能會犯錯的環(huán)節(jié),而不是詳細描述功能的實現(xiàn)過程。
目前,《Agent Skills》標準已適用于Claude Code、GitHub Copilot、Cursor以及Gemini CLI等工具。規(guī)范編寫工具的代碼倉庫地址為github.com/dannwaneri/spec-writer。
確實,我們在Claude項目中投入了64%的資源來開發(fā)這個工具,但這一努力確實取得了成效——通過這個規(guī)范,我們從一個短短12個字的提示中得出了4項重要的決策。其中第4項關(guān)于去重鍵的假設(shè),如果處理不當,可能會導致程序出現(xiàn)錯誤,而這種錯誤在會話名稱被更改之前是無法被發(fā)現(xiàn)的。
這不是幻覺,而是代理確實發(fā)揮了它所能發(fā)揮的最大作用。
正是通過規(guī)范,我們才能真正提升“輔助工具”的效用水平。