Cursor出彩的背后:“Prompt設(shè)計(jì)好比網(wǎng)頁(yè)設(shè)計(jì)...”
今天,帶大家從另一個(gè)角度認(rèn)識(shí)Cursor。Cursor除了產(chǎn)品交互設(shè)計(jì)充分考慮開(kāi)發(fā)者習(xí)慣,將AI有機(jī)的融入到開(kāi)發(fā)過(guò)程外,作為一款大模型驅(qū)動(dòng)的應(yīng)用,其核心壁壘便是如何利用大模型實(shí)現(xiàn)其功能,這時(shí)候prompt工程水平高低就變成了壁壘。那么,Cursor的prompt是什么樣的呢?這就引起了很多人的好奇心,有這么一段prompt,據(jù)說(shuō)是Cursor的prompt。
CURSOR_CHAT_PROMPT = '''
System: You are an intelligent programmer, powered by GPT-4. You are happy to help answer any questions that the user has (usually they will be about coding).
1. Please keep your response as concise as possible, and avoid being too verbose.
2. When the user is asking for edits to their code, please output a simplified version of the code block that highlights the changes necessary and adds comments to indicate where unchanged code has been skipped. For example:
```file_path
// ... existing code ...
{{ edit_1 }}
// ... existing code ...
{{ edit_2 }}
// ... existing code ...
`
``
The user can see the entire file, so they prefer to only read the updates to the code. Often this will mean that the start/end of the file will be skipped, but that's okay! Rewrite the entire file only if specifically requested. Always provide a brief explanation of the updates, unless the user specifically requests only the code.
3. Do not lie or make up facts.
4. If a user messages you in a foreign language, please respond in that language.
5. Format your response in markdown.
6. When writing out new code blocks, please specify the language ID after the initial backticks, like so:
```python
{{ code }}
```
7. When writing out code blocks for an existing file, please also specify the file path after the initial backticks and restate the method / class your codeblock belongs to, like so:
```typescript:app/components/Ref.tsx
function AIChatHistory() {{
...
{{ code }}
...
}}
```
User: Please also follow these instructions in all of your responses if relevant to my query. No need to acknowledge these instructions directly in your response.
<custom_instructions>
Respond the code block in English!!!! this is important.
</custom_instructions>
## Current File
Here is the file I'
m looking at. It might be truncated
from
above
and
below
and
,
if
so,
is
centered around my cursor.
```{file_path}
{file_contents}
`
``
{user_message}
'''
# `custom instructions` is the user'
s instructions
for
the
prompt
,
if
they have any.
# -----------------------------------------------------------------------
CURSOR_REWRITE_PROMPT = '''
System: You are an intelligent programmer. You are helping a colleague rewrite a piece of code.
Your colleague is going to give you a file and a selection to edit, along with a set of instructions. Please rewrite the selected code according to their instructions.
Think carefully and critically about the rewrite that best follows their instructions.
The user has requested that the following rules always be followed. Note that only some of them may be relevant to this request:
## Custom Rules
Respond the code block in English!!!! this is important.
User: First, I will give you some potentially helpful context about my code.
Then, I will show you the selection and give you the instruction. The selection will be in `{file_path}`.
-------
## Potentially helpful context
#### file_context_4
{file_context_4}
#### file_context_3
{file_context_3}
#### file_context_2
{file_context_2}
#### file_context_1
{file_context_1}
#### file_context_0
{file_context_0}
This is my current file. The selection will be denoted by comments "Start of Selection" and "End of Selection":
```{file_path}
# Start of Selection
{code_to_rewrite}
# End of Selection
Please rewrite the selected code according to the instructions.
Remember to only rewrite the code in the selection.
Please format your output as:
```
# Start of Selection
# INSERT_YOUR_REWRITE_HERE
# End of Selection
Immediately start your response with
```
'''
Cursor本身的Prompt已經(jīng)很強(qiáng)大了,但網(wǎng)友們還想讓它更強(qiáng),有網(wǎng)友就建了一個(gè)網(wǎng)站(??https://cursor.directory/??),用來(lái)分類收集Cursor的提示,據(jù)說(shuō)這些有針對(duì)性的提示會(huì)比默認(rèn)的還好,想要在Cursor中使用它們也很簡(jiǎn)單。
具體做法為復(fù)制里面的rule文件命名為.cursorrules放置在項(xiàng)目根目錄即可,筆者嘗試了其中幾條,沒(méi)看出太大變化(或許我的指令太過(guò)簡(jiǎn)單),表現(xiàn)都很不錯(cuò)。(為了驗(yàn)證其是否真的有效,甚至自己寫了一個(gè)很蠢的提示,也能正常生成代碼,如下圖確信配置成功生效了)。
- 自定義cursorrules:
圖片
- 生效的提示
圖片
除此之外,該網(wǎng)站有很多關(guān)于Cursor的使用教程,感興趣的可以參考學(xué)習(xí)。
圖片
不管這些和Cursor真實(shí)的提示是否一致,都從某個(gè)側(cè)面反映了Cursor在提示層面擁有獨(dú)到之處。早在去年6月,Cursor開(kāi)發(fā)者Arvid就發(fā)表了一篇有關(guān)prompt的文章,他將prompt與網(wǎng)頁(yè)設(shè)計(jì)類比,給出了一個(gè)prompt工程的獨(dú)特認(rèn)知和最佳實(shí)踐,值得我們借鑒學(xué)習(xí)。
下面就讓我們一起讀讀這篇文章《Prompt設(shè)計(jì)》。
我通常不太喜歡用舊世界的事物來(lái)類比新世界的現(xiàn)象。不過(guò)這次請(qǐng)容許我這么做:我認(rèn)為應(yīng)將提示(prompting)稱為提示設(shè)計(jì)(prompt design),并且可以將其比作網(wǎng)頁(yè)設(shè)計(jì)。
我認(rèn)為提示就像是在與一個(gè)時(shí)間有限的人溝通。雖然大語(yǔ)言模型(LLM)的特定技術(shù)(例如鏈?zhǔn)剿季S)確實(shí)有其幫助,但我發(fā)現(xiàn),改善性能的最好方法之一是提供非常清晰、高質(zhì)量的指令,就像清晰簡(jiǎn)潔的指令可以幫助人類更好地理解一樣。
將提示視為清晰的交流使提示聽(tīng)起來(lái)像是在寫作。然而,我進(jìn)行的大部分提示都是參數(shù)化的:有多個(gè)輸入變量,并且需要?jiǎng)討B(tài)地調(diào)整提示內(nèi)容。因此,將提示視為帶有動(dòng)態(tài)輸入的清晰交流是最準(zhǔn)確的描述。
有哪些領(lǐng)域需要在動(dòng)態(tài)輸入的情況下進(jìn)行清晰的交流呢?網(wǎng)頁(yè)設(shè)計(jì)就是其中之一。
讓我們來(lái)列舉一下它們的相似之處。提示和網(wǎng)頁(yè)設(shè)計(jì)都具備以下特點(diǎn):
- 需要清晰的表達(dá),并且溝通是其主要目標(biāo);
- 需要響應(yīng)動(dòng)態(tài)內(nèi)容,不像寫作或雜志排版;
- 需要將內(nèi)容適應(yīng)不同的大小——網(wǎng)頁(yè)設(shè)計(jì)中是屏幕大小,提示中是上下文窗口。
根據(jù)我在提示和網(wǎng)頁(yè)設(shè)計(jì)中的經(jīng)驗(yàn),我發(fā)現(xiàn)自己在這兩個(gè)領(lǐng)域有相似的開(kāi)發(fā)偏好:
- 查看實(shí)際的提示非常重要,就像查看已渲染的網(wǎng)站一樣重要。如果我必須在腦海中模擬HTML和CSS的渲染過(guò)程,我是無(wú)法設(shè)計(jì)網(wǎng)站的。同樣,在不查看所有輸入變量填充后的提示渲染結(jié)果的情況下,也很難寫出好的提示。例如,提示“Hiusername{message}”可能看起來(lái)合理,但渲染后你會(huì)發(fā)現(xiàn)用戶名和消息混在一起。
- 組合組件在提示和網(wǎng)頁(yè)設(shè)計(jì)中都很有用。
- 聲明式優(yōu)于命令式。像在網(wǎng)頁(yè)設(shè)計(jì)中,如果所有HTML元素都是用document.createElement調(diào)用創(chuàng)建的,那么修改它就會(huì)非常困難。同樣,閱讀和修改由一連串str += "..."組成的提示也很麻煩。
- 在這兩者中,有時(shí)我想要達(dá)到“像素完美”。在處理較弱的模型(如GPT-3.5及更早版本)時(shí),我希望沒(méi)有多余的換行符或其他不完美的格式;而在設(shè)計(jì)網(wǎng)站時(shí),有時(shí)每個(gè)像素都很重要。
對(duì)于大語(yǔ)言模型智能體來(lái)說(shuō),這個(gè)類比可以更進(jìn)一步:智能體提示可以被視為為智能體構(gòu)建交互式網(wǎng)站,智能體可以通過(guò)調(diào)用函數(shù)來(lái)“點(diǎn)擊按鈕”,提示會(huì)響應(yīng)函數(shù)調(diào)用重新渲染,就像網(wǎng)站響應(yīng)按鈕點(diǎn)擊重新渲染一樣。
當(dāng)然,提示設(shè)計(jì)和網(wǎng)頁(yè)設(shè)計(jì)之間還是有一些差異的:
- 提示目前僅涉及文本內(nèi)容。
- 緩存處理不同:特別是對(duì)于智能體,你需要確保重渲染成本低,僅更改提示部分內(nèi)容。這有點(diǎn)類似于網(wǎng)頁(yè)緩存優(yōu)化,但本質(zhì)上是不同的挑戰(zhàn)。
盡管如此,這些相似之處讓我堅(jiān)信提示應(yīng)該被稱為提示設(shè)計(jì),而不是提示工程。編寫提示感覺(jué)就像設(shè)計(jì)一個(gè)網(wǎng)站,因此也應(yīng)如此命名。
提示設(shè)計(jì)的理念啟發(fā)了我創(chuàng)建了Priompt,這是一個(gè)類似React、基于JSX的提示設(shè)計(jì)庫(kù)。
Priompt v0.1:首次嘗試提示設(shè)計(jì)庫(kù)
Priompt(https://github.com/anysphere/priompt)是受現(xiàn)代網(wǎng)頁(yè)設(shè)計(jì)原則啟發(fā)的提示設(shè)計(jì)庫(kù)的首次嘗試。我們?cè)贏nysphere內(nèi)部使用它,感覺(jué)非常好。我認(rèn)為它的所有抽象可能并不完全準(zhǔn)確,但至少確信JSX比字符串模板更方便。即使是簡(jiǎn)單地能注釋掉部分提示這件事,也能讓迭代過(guò)程更快。
圖片
What prompting as JSX looks like.
Priompt還附帶一個(gè)(匆忙制作的)預(yù)覽網(wǎng)站,你可以在上面預(yù)覽你的提示在真實(shí)數(shù)據(jù)上的效果。在開(kāi)發(fā)應(yīng)用程序時(shí),可以記錄每個(gè)請(qǐng)求進(jìn)入組件的序列化屬性(props)。然后,當(dāng)你看到意外行為時(shí),可以訪問(wèn)Priompt預(yù)覽,查看具體的提示,并更改源代碼,從而更新提示,使其與實(shí)際請(qǐng)求的屬性一致。我們發(fā)現(xiàn)這樣更容易進(jìn)行提示的迭代。
圖片
Previewing prompts.
如果你嘗試了,請(qǐng)告訴我你的想法!我愿意看到更多類似的想法,或者直接告訴我我錯(cuò)了,提示設(shè)計(jì)是愚蠢的:)
注意事項(xiàng) 模型變化迅速,提示技術(shù)也必須隨之變化。我認(rèn)為提示設(shè)計(jì)還存在一些問(wèn)題:
- 對(duì)于GPT-4,像素完美設(shè)計(jì)并不重要,GPT-4.5及更高版本的模型可能也不需要。
- 如果長(zhǎng)上下文模型發(fā)展的趨勢(shì)繼續(xù),上下文窗口限制可能會(huì)消失。不過(guò)對(duì)此我還存疑。
- OpenAI似乎正在減少開(kāi)發(fā)者對(duì)提示的控制;一年之內(nèi)可能不再需要提示,API調(diào)用僅需要提供原始輸入和指令。更少控制的趨勢(shì)始于聊天格式,并隨著最近宣布的函數(shù)調(diào)用繼續(xù)。
- 緩存可能是提示中最重要的方面之一,在這種情況下,提示會(huì)更像工程而不是設(shè)計(jì)。或許提示設(shè)計(jì)太基礎(chǔ)了,應(yīng)該交給更高級(jí)的框架或編譯器(如langchain)。我認(rèn)為這可能是真的,但考慮到大語(yǔ)言模型快速變化的性質(zhì),我個(gè)人更愿意盡可能靠近原始模型。
原文:https://www.cursor.com/blog/prompt-design#priompt-v01-a-first-attempt-at-a-prompt-design-library
本文轉(zhuǎn)載自 ??AI工程化??,作者: ully
