深度解析 Cursor(逐行解析系統提示詞、分享高效制定 Cursor Rules 的技巧...) 原創
編者按: 我們今天為大家帶來的這篇文章,作者的觀點是:只有深入理解 AI 編程工具的底層原理和能力邊界,才能真正駕馭這些工具,讓它們成為提升開發效率的“外掛神器”。
本文從 LLM 的基礎工作機制出發,解釋了 Cursor 等工具本質上是 VSCode 的復雜封裝,通過聊天界面、工具集(如 read_file、write_file 等)和精心設計的提示詞來實現智能編程輔助。作者還逐行解析了 Cursor 的系統提示詞,分析了其中的工程設計細節。此外,作者還提供了制定高效 Cursor Rules 的具體指導,強調 Cursor Rules 應該像百科詞條般詳實,而非簡單的命令列表。
作者 | Shrivu Shankar
編譯 | 岳揚
透徹了解 Cursor[1]、Windsurf[2] 和 Copilot[3] 這類 AI 編程工具的運作原理細節,能大大提升你的開發效率,并讓這些工具在不同場景下都更加穩定地工作 —— 尤其在龐大、復雜的代碼庫中。當人們難以讓 AI 編程工具高效工作時,往往是把它們當成了傳統工具來使用,卻忽略了一個關鍵:只有清楚這些工具的先天不足和最佳應對策略,才能真正駕馭它們。一旦摸透這些工具的運作邏輯和能力邊界,它們就會化身成為提升開發效率的“外掛神器”。在我寫作此文時,我約 70% 的代碼1都由 Cursor 產出。
在本文,我將深入解析這些 AI 編程工具的實際運行原理、Cursor 的系統提示詞,以及如何優化你的編碼方式與 Cursor rules。
01 從 LLM 到代碼編寫智能體
1.1 LLM
LLMs 的核心工作方式是不斷重復預測下一個詞,正是基于這個簡單的原理,我們得以構建出各種復雜的應用。
從基礎的編程 LLM 到智能體主要經歷三個階段:藍色部分表示我們設定的前綴(即 prompts),橙色部分則為 LLM 自動補全的內容。在智能體中會反復運行 LLM,直到它生成面向用戶的輸出(response)。每次運行時,由客戶端代碼(而非 LLM)負責計算工具(tool)運行結果并將其反饋回智能體(agent)。
在早期解碼器 LLM(如 GPT-2[4])的提示詞實踐中,需要精心構造一個前綴字符串(prefix) —— 當其被補全時,便能得到想要的結果。相比于直接的指令“Write a poem about whales”,不如說 “Topic: Whales\nPoem: ”,甚至是“Topic: Trees\nPoem: … actual tree poem …\nTopic: Whales\nPoem: ”。在編程場景下,需要構造類似“PR Title: Refactor Foo Method\nDescription: …\nFull Diff: ”這樣的前綴。所謂的“Prompt engineering”,其核心就是巧妙地構建理想前綴,從而引導模型自動補全出所需答案。
隨后引入了指令微調[5](例如 ChatGPT),大幅降低了大語言模型的使用門檻。現在你如果輸入“Write a PR to refactor Foo”,它就會直接返回代碼。其內在機制幾乎完全等同于上述的自動補全過程,只是前綴變成了“<user>Write a PR to refactor Foo</user><assistant>”,此時大語言模型正扮演著聊天中的助手角色。即使在今天,你仍會看到一些奇怪的情況 —— 模型有時會越過“</assistant>”標簽繼續自動補全生成內容,開始給自己寫提問。
當模型規模達到一定程度時,我們更進一步,加入了“工具調用(tool calling)[6]”功能。不再局限于填充 assistant 文本,我們可以在前綴中輸入“Say \read_file(path: str)` instead of responding if you need to read a file”。當遇到編碼任務時,模型現在會補全出“read_file('??index.py?? ...</tool><assistant>`”并要求其繼續補全文本。雖然本質上仍是自動補全,但大語言模型已能借此與外界及外部系統互動了。
1.2 Agentic Coding
像 Cursor 這樣的 AI 編程工具,其本質就是這個簡單概念的復雜封裝。
要構建一個 AI 編程工具,你需要:
- Fork VSCode[7]
- 添加聊天界面,并選擇一個強大的大語言模型(例如 Sonnet 3.7)
- 為編碼智能體實現一套工具集
a. read_file(full_path: str)
b. write_file(full_path: str, content: str)
c. run_command(command: str) - 優化內部提示詞(Prompts):例如“你是一位編碼專家”、“不要假設,請使用工具”等
總的來看,核心流程基本就是這些了。真正的難點在于設計提示詞和工具鏈,確保它們能穩定可靠地工作。 如果完全按照上述描述來構建,系統雖能勉強運行,但會頻繁出現語法錯誤、幻覺問題(hallucinations)且相當不穩定。
1.3 優化 Agentic Coding
打造優秀 AI 編程工具的訣竅,在于找出大語言模型擅長的領域,并圍繞其局限性精心設計提示詞和工具。這通常意味著需要減輕主智能體的任務負擔 —— 通過使用更小的模型來完成子任務。
圖表說明:當你使用 AI 編程工具時,其底層發生了什么?我們簡化了主智能體的工具集,將“認知負擔”轉移到其他大語言模型上。AI 編程工具會將你的 @標簽注入上下文,調用多個工具來收集更多信息,使用專用的代碼變更標記規則(diff syntax)編輯文件,最后向用戶返回摘要響應。
1.4 優化措施與面向終端用戶的操作建議(Optimizations & User Tips)
- 通常情況下,用戶自己知道需要哪些具體文件或上下文。因此,我們在聊天界面(Chat UI)中添加了“@file”語法。當調用大語言模型時,我們會將所有附加文件的內容整體打包放入一個“<attached-files>”區塊中傳遞。這本質上是為用戶提供語法糖(syntactic sugar),免去了手動復制粘貼整個文件或文件夾的麻煩。
- 操作建議 (Tip):在這些編程工具中建議積極使用 @folder/@file(優先提供更明確的上下文,以獲取更快更準確的響應)。
- 搜索代碼可能很復雜,尤其對于“我們在哪里實現了認證功能相關的代碼?”這類語義查詢。我們沒有讓智能體精通編寫搜索正則表達式(regexes),而是選擇在索引階段使用一個編碼器大模型(encoder LLM)將整個代碼庫索引到向量數據庫(vectorstore)中,從而將文件內容及其功能嵌入到向量中。在查詢時,另一個大語言模型會根據相關性對文件進行重排序和過濾。這確保了主智能體在詢問認證功能代碼相關問題時能獲得“完美”的結果。
- 操作建議 (Tip):代碼注釋(Code comments)和文檔字符串(doc-strings)能引導嵌入模型(embedding model)理解代碼,這使得它們的重要性甚至超過了僅寫給人類同事看的情況。務必在文件頂部用一段文字說明:該文件的作用、實現的語義功能以及應何時更新。
- 要生成字符層級上零缺陷(character-perfect)的代碼既困難又昂貴,因此優化 write_file(…) 工具成為眾多此類 AI 編程工具的核心。大語言模型通常不會輸出完整的文件內容,而是生成一個 “semantic diff” —— 僅提供已更改的內容,并附帶代碼注釋,以指導在何處插入更改的文件內容。隨后,另一個更輕量、更快的代碼應用大模型(code-apply LLM) 會將該 “semantic diff” 作為輸入提示詞,并在修復那些微小語法問題的同時寫入實際文件內容。新文件經過 linter 校驗器處理后,工具返回主智能體的結果時會包含實際文件差異(actual diff)和 lint 校驗結果,可用于自我修正文件的錯誤改動。我將此機制類比為:與一位懶散的資深工程師協作,他只需寫出核心片段,后續細節交由實習生完成。
- 操作建議 (Tip):你無法直接將提示詞發送給應用模型(apply-model)。類似“別亂刪代碼”或“別隨意增刪注釋”的建議完全無效,因為這些問題本質上是應用模型(apply-model)工作機制的固有產物。應該讓主智能體獲得更多控制權,例如在指令中明確要求:“在 edit_file 指令中提供完整的文件內容”
- 操作建議 (Tip):應用模型處理超大文件時緩慢且易錯,務必將文件拆分至每部分小于 500 行代碼
- 操作建議 (Tip):lint 反饋對智能體具有極高價值,應投資構建能提供高質量建議的增強型 linter2。使用編譯型語言和靜態類型語言能提供更豐富的 lint 時反饋(lint-time feedback)
- 操作建議 (Tip):使用唯一的文件名(不要在代碼庫中使用多個不同的 page.js 文件,最好改用 foo-page.js、bar-page.js 等),在文檔中應使用完整的文件路徑,并將高頻修改的代碼段(hot-paths)集中到同一文件或文件夾中,以降低編輯工具的操作歧義
- 選用擅長在此類智能體(Agent)工作流中編寫代碼的模型(而非僅具備通用編碼能力)。這就是 Anthropic 模型在 Cursor 等 AI 編程工具中表現出色的原因 —— 它們不僅代碼質量高,更擅長將編程任務拆解為這種類型的工具調用(tool calls)。
- 操作建議 (Tip):選用模型時,不應僅關注“編碼能力”,應優先選擇專門為智能體驅動型編程工具(agentic IDEs)優化的模型。目前(據我所知)能有效評估此能力的唯一排行榜是 WebDev Arena[8] 3。
我在自研 AI 編程工具 sparkstack.app 中采用過一個(極其昂貴的)技巧,大幅提升了系統的自我修正能力:為其配備 apply_and_check_tool。該工具會執行更嚴苛的 linting,并啟動無頭瀏覽器(headless browser),沿應用的用戶流程(user-flows)獲取控制臺日志和截圖,為智能體提供反饋。正是在此類場景中,MCP(Model Context Protocol)[9]協議將大放異彩 —— 它能賦予智能體更強的自主權和上下文理解能力。
02 逐行解析 Cursor 的系統提示詞
通過基于 MCP 協議的提示詞注入技術,我提取了 Cursor 智能體模式(agent mode)最新(2025 年 3 月)的提示詞內容。作為一名長期深耕大語言模型領域的開發者,我必須表達對 Cursor “提示詞工程師(prompt engineers)”的高度敬意 —— 相比其他 AI 編程工具的提示詞設計,他們的專業水準令人贊嘆(個人觀點)。我認為這正是 Cursor 能成為領先編程工具的核心因素。剖析此類提示詞也是提升自身提示詞編寫能力與智能體架構能力的絕佳途徑 —— 從某種意義上看,大多數基于 GPT 的封裝工具采用“開放提示詞(open-prompt)”實現方案,這種特性極具價值。
Cursor Agent 系統提示詞片段。完整提示詞及工具定義(??????https://gist.github.com/sshh12/25ad2e40529b269a88b80e7cf1c38084)??
- “<communication>”、“<tool_calling>”等標簽 → 混合使用 Markdown 和 XML 標簽能大大降低人類和模型對提示詞的閱讀難度4。
- “由 Claude 3.5 Sonnet 驅動(powered by Claude 3.5 Sonnet)” → 大模型通常不會主動聲明自身模型版本。顯式標注此信息可減少用戶對計費模型與實際運行模型不一致的抱怨5。
- “全球最佳 IDE(the world's best IDE)” → 該表述簡潔地禁止模型在故障時推薦競品,這對那些代表品牌形象的智能體來說至關重要6。
- “我們會自動附上某些信息…遵循 <user_query> 標簽內的用戶指令(we may automatically attach some information…follow the USER’s instructions…by the <user_query> tag)” → Cursor 并未直接將用戶提示詞傳遞給模型,而是將其置于專用標簽中。這使得系統能在 <user> 消息中傳遞更多與用戶相關的文本,既不會讓大語言模型(LLM)混淆,也不會讓用戶感到困惑。
- “避免道歉(Refrain from apologizing)” → 這顯然是為抑制 Sonnet 模型的致歉傾向而添加的規則。
- “絕對不要提及工具名稱(NEVER refer to tool names when speaking)” → Cursor 特別以加粗格式添加此指令。但諷刺的是,我仍常見到類似“使用 edit_tool”的違規輸出 —— 近期 Sonnet 模型在此方面的表現確實惱人。
- “調用每個工具前需先解釋(Before calling each tool, first explain)” → 當大模型在流式傳輸(streaming)工具調用時,用戶界面會出現短暫卡頓。此指令能幫助用戶確信系統正在處理他們的請求,避免因界面停滯而產生不安。
- “若部分滿足了用戶查詢,但你還不確定,則請收集更多信息(partially satiate the USER's query, but you're not confident, gather more information)” → 大模型智能體常因過度自信而過早終止任務。此指令為其提供“退路”,促使其深度探索后再響應。
- “禁止直接向用戶輸出代碼(NEVER output code to the USER)” → 默認情況下,大模型傾向以內聯代碼塊(inline markdown codeblocks)形式輸出代碼。此規則強制其僅通過工具操作代碼,并依賴 UI 間接向用戶展示變更結果。
- “若從零構建 Web 應用,必須設計精美的、現代感的 UI(If you're building a web app from scratch, give it a beautiful and modern UI)” → 此為針對演示場景的優化(demo-hacking),確保單提示詞(single-prompt)即可生成華麗的應用。
- “在編輯之前,你必須讀取你要編輯的內容7(you MUST read the contents or section of what you're editing before editing it)” → 編碼智能體常急于寫代碼而忽略收集上下文。此類直接的、顯式的指令用于校正該行為。
- “修復 linter 錯誤時循環次數不得超過 3 次(DO NOT loop more than 3 times on fixing linter errors)” → 旨在防止 Cursor 陷入代碼編輯的死循環。此措施雖有幫助,但 Cursor 的深度用戶都知道,系統仍易因此卡頓。
- “解決根本原因而非僅處理表象(Address the root cause instead of the symptoms)” → 這一點是針對大模型常見的對齊問題(alignment issues):模型常傾向于直接刪除報錯代碼而非修復問題本身。
- “禁止硬編碼 API 密鑰(DO NOT hardcode an API key)” → 眾多安全方面的最佳實踐之一,至少可以防止一些明顯的安全問題。
- 工具 codebase_search/read_file/grep_search/file_search/web_search → 鑒于編碼前獲取正確上下文是非常重要的,Cursor 提供多種形態的搜索工具,確保智能體能夠輕松定位要做的修改。
- 一些工具中的“單句解釋...說明為何需要運行此命令...”("One sentence explanation...why this command needs to be run...") → 大多數工具都包含這個非功能性參數,它迫使大模型推理論證它將傳遞哪些參數,此為提升工具調用準確性的常規技巧。
- reapply 工具“調用更強大模型執行上次編輯的內容(Calls a smarter model to apply the last edit)” → 允許主智能體動態升級應用模型(即使用更高成本模型),自主解決低級應用錯誤。
- edit_file 工具要求“用對應語言的注釋表示未修改代碼(represent all unchanged code using the comment of the language you're editing)” → 此規則解釋了自動生成的隨機注釋的來源,也是應用模型正常工作的必要前提。
- 您會注意到整個系統提示詞和工具描述均為靜態內容(未注入用戶或代碼庫個性化文本)。該設計使 Cursor 能充分利用提示詞緩存(prompt caching) 優勢[10],大幅降低推理成本并減少輸出首個 token 的延遲時間(time-to-first-token latency) —— 這對每次使用工具都需調用大模型的智能體架構至關重要。
03 如何高效制定 Cursor Rules
現在最大的問題是,編寫 Cursor rules 的“正確方式”是什么?雖然我的整體答案是“以實際效果為準,適合你的才是最好的”(whatever works for you),但基于提示詞工程經驗和對 Cursor 內部原理的認知,我確實有大量具體建議。
大語言模型如何看待你的 Cursor 項目規則?模型會看到規則的名稱和簡介列表,然后根據需要調用 fetch_rules(...) 函數來獲取和查看具體的規則內容
關鍵是要明白,這些規則并非是附加到系統提示詞中的,而是作為具名指令集(named sets of instructions)被引用。因此,建議采用編寫百科詞條(encyclopedia articles)而非命令(commands)的思維方式設計 Cursor rules。
- 切勿在 Cursor rules 中聲明身份(例如“您是精通 TypeScript 的資深前端工程師”)。此類規則雖見于 cursor.directory 且看似有效,但會與內置提示詞賦予的身份產生沖突,導致智能體行為異常。
- 避免嘗試覆蓋系統提示詞指令,或通過特定提示詞(prompt)引導應用模型(apply model)的行為。類似“別添加注釋”、“編碼前先提問”、“勿刪除未提及代碼”的指令會直接破壞工具使用機制并干擾智能體運作。
- 減少使用否定性指令。大模型更擅長遵循正向指令(“若遇<此情況>,則<執行此操作>”),而非單純列出限制條件。此原則亦體現在 Cursor 的官方提示詞中。
- 請務必花時間編寫高度明顯的規則名稱和描述。關鍵在于,即使智能體(Agent)對您的代碼庫所知甚少,也能憑直覺知道何時適合應用某條 Cursor rules 來使用其 fetch_rules(…) 工具。類似于手動建立文檔索引的做法,你應該適當地創建一些內容相同但名稱和描述不同的規則副本,這樣可以提高 AI 找到相關規則的概率。規則描述應當力求信息密集,避免過度冗長。
- 把你的模塊規則和常見代碼修改規則寫得像百科詞條一樣詳細和完整。如同維基百科那樣,將關鍵術語(使用 mdc 鏈接語法)鏈接到代碼文件,這在智能體確定代碼變更所需的關鍵上下文時能提供巨大助力。有時,這也意味著,要避免按部就班地進行說明(專注于“做什么”而非“怎么做”),除非真的沒辦法,否則不要讓智能體過度專門化,只會處理某一種特定的代碼修改模式。
- 請務必使用 Cursor 本身來起草您的 Cursor rules 。大語言模型(LLMs)非常擅長為其他大語言模型撰寫內容。如果您不確定如何組織文檔格式或編碼上下文,請執行 “@folder/ generate a markdown file that describes the key file paths and definitions for commonly expected changes”。
- 要意識到制定太多規則其實是個不好的做法。這一點看似違反直覺 —— 雖然規則確實是讓 AI 開發工具處理大型項目的關鍵,但需要很多規則本身就暴露了一個問題:你的代碼庫對 AI 來說不夠友好。我在《AI-powered Software Engineering》[11]一書中深入探討了這個話題。未來理想的代碼庫應該設計得足夠清晰直觀,AI 編程工具光靠基礎功能就能完美勝任所有工作。
請參考我生成的一些示例[12]。
04 Conclusions
一個基于近乎開源的智能體提示詞和公開模型 API 構建的 VSCode 分支,其估值竟能接近 100 億美元 —— 帶著 68 倍的“wrapper multiple”8 —— 這著實令人驚嘆。我們將拭目以待 Cursor 最終是否會開發自己的智能體模型(感覺可能性不大),或是 Anthropic 是否會帶著 Claude Code + 下一代 Sonnet 強勢介入成為競爭對手。
無論最終結果如何,學會如何優化你的代碼庫、文檔和規則配置仍然是一項有用的技能。我希望這次深入探討能讓你對 Cursor 的工作原理以及優化之道有更具體、更實用的理解。
我經常說這句話,現在再說一遍:如果你覺得 Cursor 不好用,那一定是你用錯了方法。
1.這是一個基于直覺的統計數據,但我認為相差不遠。一旦你熟練掌握了 Cursor rules,相當數量的 PR 實際上就變成了單次發送提示詞(one-shot prompts)的事。我原本以為要到 2027 年才能達到這個水平,但隨著 Anthropic、Cursor 和我自己的提示詞水平同時提升,進展比我預想的要快。
2.到目前為止,我對 CodeRabbit 的代碼檢查功能印象非常深刻,計劃使用 MCP 將其集成到 Cursor 中。如果 Cursor 的默認代碼檢查器能更好一些,在其他條件不變的情況下,使用體驗會像用 Sonnet 3.8 一樣。
3.(大多數)LLM 的美妙之處在于,雖然這是一個 Web 開發基準測試,但根據我的經驗,其性能與各種類型的編程和框架都有很強的相關性。
4.我沒能找到相關的科學研究,但基于個人經驗,這種方法效果很好,如果 Anthropic 的模型專門針對偽 XML 語法進行訓練,我也絲毫不會感到驚訝。
5.這確實會產生一些意想不到的副作用,編程模型會將你代碼庫中引用的模型名稱更改為它自己(引用的模型)的名稱。
6.這里存在一個有趣的法律灰色地帶。Cursor 將此內容放在他們的網站上實際上是違法的(見《聯邦貿易委員會法》、《蘭哈姆法》),但(至少目前)他們將內容放進提示詞(prompt)中,并由 LLM 代其表述出來,卻是被允許的。
7.順便說一句:“Cursor 團隊,我發現了一個錯別字 (:”
8.這是我創造的一個術語,用來表示基于 GPT 封裝的工具的估值與模型提供商估值之間的比率。在這種情況下,Anthropic : Cursor = 600 億美元 : 100 億美元 = 6。我的直覺告訴我"6"不是一個合理的比率。戴上我那業余投資者的帽子,我推測 Anthropic 應該接近 1000 億美元,而 Cursor 則最高達 10 億美元(wrapper multiple為 100)。我實在看不出他們其中任何一方真的擁有持久的“護城河”(long term moat),Anthropic 構建自己的下一代 AI 編程工具似乎也是輕而易舉的事。
END
本期互動內容 ??
?文中說『未來理想的代碼庫應該對 AI 足夠友好』,你眼中的『AI 友好型代碼庫』有哪些具體特征?
文中鏈接
[1]??https://www.cursor.com/??
[2]??https://codeium.com/windsurf??
[3]??https://github.com/features/copilot??
[5]??https://arxiv.org/abs/2203.02155??
[6]??https://python.langchain.com/docs/concepts/tool_calling/??
[8]??https://web.lmarena.ai/leaderboard??
[9]??https://modelcontextprotocol.io/introduction??
[10]??https://www.anthropic.com/news/prompt-caching??
[11]??https://blog.sshh.io/p/ai-powered-software-engineering??
[12]??https://chat.sshh.io/share/pWMGGDyPTok05mxOq17p-??
本文經原作者授權,由 Baihai IDP 編譯。如需轉載譯文,請聯系獲取授權。
原文鏈接:
??https://blog.sshh.io/p/how-cursor-ai-ide-works??
