首先,要明確聲明的一點(diǎn)是,LLM並不會真的執(zhí)行或運(yùn)算,這些代碼也不存在什麼魔力,只是某些情境下可以用很簡潔的方法處理自然語言需要花費(fèi)大篇幅才能表達(dá)的事情。
這裡主要介紹:
- Markdown
- XML、JSON、類JSON
- CSV、TSV、Markdown表格
- 偽高級語言
- 偽變數(shù)
Markdown
- 適用情境:絕大多數(shù)時候。
- 介紹:Markdown是一種非常泛用的輕量化標(biāo)記式格式,易學(xué)易用,好的標(biāo)記可以強(qiáng)化LLM對Prompt的理解,也能節(jié)省大量Tokens。
範(fàn)例
{{char}}喜歡:A、B、C {{char}}討厭:D、E {{char}}擅長:F、G |
若要節(jié)省一些字,改寫為:
{{char}}的資訊: 喜歡:A、B、C 討厭:D、E 擅長:F、G |
這時候如何讓LLM知道這個「{{char}}的資訊」的內(nèi)容該從哪裡開始,哪裡結(jié)束呢?可以這樣寫:
{{char}}的資訊: - 喜歡:A、B、C - 討厭:D、E - 擅長:F、G |
這樣,LLM就會知道底下的列表是延伸定義上面的「{{char}}的資訊」,到列表結(jié)束時,自然也就是「{{char}}的資訊」結(jié)束時。
(註:為了節(jié)省版面,這是一個極簡單的例子,這個例子實(shí)際上即便直接寫自然語言,LLM也不容易理解錯誤,但假設(shè)你有非常長的篇幅,就不一定了。)
建議
- 用# 標(biāo)題、列表- 、分隔線---、縮排等,讓LLM理解哪些指令是一起作用的,哪些指令擁有更高優(yōu)先權(quán)等等。
- 符號也要佔(zhàn)用Tokens,請依情境選擇是否使用,簡單的資訊或許完全不需要標(biāo)記。
XML、JSON或類JSON
- 適用情境:為複雜提示分類、分塊時。雖然Markdown足以應(yīng)付大多數(shù)狀況,但如果你的提示結(jié)構(gòu)十分複雜,即便你使用高Tokens輸入量的LLM,它也未必能清晰的判斷其重點(diǎn),反而容易因結(jié)構(gòu)複雜而丟三落四、首尾不能相顧。這時,你就需要更明確的標(biāo)記來指引LLM如何更好地理解層次與邏輯,這在長篇幅的提示中更為重要。
- 介紹:
- XML是一種廣泛的資訊交換格式。可以明確標(biāo)註資料的屬性、用途、起訖、層次,它支援比JSON更複雜的結(jié)構(gòu),但寫起來也更為冗長。
- JSON是一種比XML更簡潔、輕量的資料交換格式。
範(fàn)例
世界運(yùn)行的規(guī)則 (省略十萬字) 角色的資訊 (十個角色) 事件的流程 (省略十萬字) 回應(yīng)的格式 (省略十萬字) |
XML
<world_rules desc="定義世界運(yùn)行的規(guī)則。"> (省略十萬字) </world_rules> <char_info desc="所有預(yù)設(shè)角色的資訊。"> <char name="角色1的名字">角色1的資訊</char> <char name="角色2的名字">角色2的資訊</char> <char name="角色3的名字">角色3的資訊</char> (省略剩餘角色) </char_info> <event_flow desc="定義事件的流程。"> (省略十萬字) </event_flow> <response_format desc="定義回應(yīng)的格式。"> (省略十萬字) </response_format> |
JSON
{ "world_rules": { "desc": "定義世界運(yùn)行的規(guī)則。", "content": "(省略十萬字)" }, "char_info": { "desc": "所有預(yù)設(shè)角色的資訊。", "chars": [ { "name": "角色1的名字", "info": "角色1的資訊" }, { "name": "角色2的名字", "info": "角色2的資訊" }, { "name": "角色3的名字", "info": "角色3的資訊" } // (省略剩餘角色) ] }, "event_flow": { "desc": "定義事件的流程。", "content": "(省略十萬字)" }, "response_format": { "desc": "定義回應(yīng)的格式。", "content": "(省略十萬字)" } } |
類似的選項還有YAML,LLM也能正常理解它,但因為它跟JSON挺類似的,就不再浪費(fèi)版面寫介紹,有興趣的同學(xué)可以自行查詢。
建議:
- 因為比起Markdown,會消耗更多Tokens,因此若非必要,並不建議。
CSV、TSV、Markdown表格
- 適用情境:有大量資料,擁有重複的鍵值,並且其格式可以編排為二維表格。
- 介紹:這三種都是一種表格形式,在情境合適下,可以節(jié)省版面與Tokens。
- CSV與TSV:是一種最簡單的表格形式,使用,逗號或\t分隔符來分割表格內(nèi)容。
- Markdown表格:Markdown所使用的表格形式,消耗Tokens會多些,但實(shí)測時不知道為什麼,不管什麼LLM都更容易處理這種形式,可能與預(yù)先的訓(xùn)練內(nèi)容有關(guān)。
範(fàn)例
A姓名:莉莉亞 A性別:女 A特質(zhì):可愛 A外貌:金馬尾 A性格:害羞 A喜好:甜食 A厭惡:孤獨(dú) B姓名:雅柔 B性別:女 B特質(zhì):學(xué)霸 B外貌:黑長髮 B性格:矜持 B喜好:鴨子 B厭惡:虛偽 (??中略) Y姓名:露比娜 Y性別:女 Y特質(zhì):高雅 Y外貌:紅長髮 Y性格:溫柔 Y喜好:劍術(shù) Y厭惡:男權(quán) Z姓名:星瑩 Z性別:女 Z特質(zhì):笨蛋 Z外貌:黑短髮 Z性格:開朗 Z喜好:漫畫 Z厭惡:規(guī)矩 |
CSV
姓名,性別,特質(zhì),外貌,性格,喜好,厭惡 莉莉亞,女,可愛,馬尾,害羞,甜食,孤獨(dú) 雅柔,女,學(xué)霸,長髮,矜持,鴨子,虛偽 (??中略) 露比娜,女,高雅,紅長髮,溫柔,劍術(shù),男權(quán) 星瑩,女,笨蛋,短髮,開朗,漫畫,規(guī)矩 |
TSV
姓名 性別 特質(zhì) 外貌 性格 喜好 厭惡 莉莉亞 女 可愛 馬尾 害羞 甜食 孤獨(dú) 雅柔 女 學(xué)霸 長髮 矜持 鴨子 虛偽 (??中略) 露比娜 女 高雅 紅長髮 溫柔 劍術(shù) 男權(quán) 星瑩 女 笨蛋 短髮 開朗 漫畫 規(guī)矩 |
Markdown表格
|姓名|性別|特質(zhì)|外貌|性格|喜好|厭惡| |---|---|---|---|---|---|---| |莉莉亞|女|可愛|馬尾|害羞|甜食|孤獨(dú)| |雅柔|女|學(xué)霸|長髮|矜持|鴨子|虛偽| (??中略) |露比娜|女|高雅|紅長髮|溫柔|劍術(shù)|男權(quán)| |星瑩|女|笨蛋|短髮|開朗|漫畫|規(guī)矩| |
建議
- 中等資料量時節(jié)省Token用。
- 量太大時低成本LLM處理表格的表現(xiàn)都不太好,高成本LLM也有機(jī)率出錯。
- 使用CSV、TSV時,用Markdown的代碼框將之框起來,明確告訴LLM這是什麼格式。例如:
```csv
表格內(nèi)容
```
偽高級語言
- 適用情境:敘述中「如果」、「否則」、狀況眾多,或者引入變數(shù)後容易產(chǎn)生歧義,難以用自然語言表達(dá)清楚時。
- 簡介:使用一些「看起來像高級語言」(實(shí)際上不是)的寫法,明確的區(qū)分出每個條件的區(qū)塊。
範(fàn)例
if({{user}}正在做 == 'A'){ {{char}}反應(yīng)1; }else if({{user}}正在做 == 'B'){ if(目前場景 == '洗澡'){ {{char}}反應(yīng)2; }else if(目前場景 == '泡溫泉'){ {{char}}反應(yīng)3; }else{ {{char}}反應(yīng)4; } } |
建議
- 不用真的嚴(yán)格按照程式語言撰寫。也不要使用對格式要求太嚴(yán)格的語言,雖然LLM最熟悉的可能是Python,但它也可能因為你格式錯誤而當(dāng)成無意義的囈語。
- 建議模仿Javascript的形式,因為它不太嚴(yán)格,且它是一種易學(xué)易用的語言,最後它或許是LLM除Python外最熟悉的語言。
- 不要加Markdown代碼框,避免LLM真的把它理解成一種高級語言,而產(chǎn)生奇怪的結(jié)果。
偽變數(shù)
- 適用情境:一個詞有多種可能時、讓LLM隨機(jī)多選一時、使用相同的輸出格式但替換不同的關(guān)鍵詞時。
- 簡介:自行建立一個偽變數(shù),就像Caveduck內(nèi)建的{{user}}與{{char}}那樣,但不同的是,Caveduck內(nèi)建的{{var}}是真的會被程式取代成正確的值,才扔給LLM處理,而我們定義的只是在提示內(nèi)讓LLM按照它的理解去處理這些字。
範(fàn)例
生成以下文字:「{{user}}被派到(隨機(jī)選取:中國、韓國、日本、英國)執(zhí)行任務(wù),任務(wù)內(nèi)容是(隨機(jī)選取:建立聯(lián)絡(luò)網(wǎng)、刺探情報、意識形態(tài)宣傳、收買官員)。」 |
LLM有時只會傻傻的把整句一字不差的輸出,或者因前文有什麼影響它認(rèn)知的東西,生成牛頭不對馬嘴的內(nèi)容,但我們使用變數(shù)就能避免這種情形:
## 變數(shù) (這裡最好再加一段解釋如何執(zhí)行的內(nèi)容) - $location$:隨機(jī)選取(中國、韓國、日本、英國) - $mission$:隨機(jī)選取(建立聯(lián)絡(luò)網(wǎng)、刺探情報、意識形態(tài)宣傳、收買官員) 生成以下文字:「{{user}}被派到$location$執(zhí)行任務(wù),任務(wù)內(nèi)容是$mission$。」 |
建議
- 此類狀況不多時,內(nèi)容能用自然語言清晰描述時,可能是多此一舉,但如果內(nèi)容較多,這是個很好的辦法。
- 你可以用任何方式去標(biāo)記變數(shù),但盡量不要與自然語言的常見符號衝突。
- 不是必須,但建議將之前後封閉,例如$var$優(yōu)於$var,如果是非封閉的變數(shù),必須明確其後面有空格,這在拼音語言中問題不大,但使用表意文字時可能時常會忽略其空格,畢竟表意文字並不依賴空格切分詞彙或語素,另外也無法保證由自動翻譯系統(tǒng)將拼音文字翻譯為表意文字時,會保留那個空格。
- 不建議和Caveduck使用一樣的方式{{var}},一來是你自己容易弄混。二來是有小道消息稱,他們正在開發(fā)一個名為「模板」的功能,屆時可以讓創(chuàng)作者將常用、容易重複的文字設(shè)成模板,並自行插入Prompt內(nèi),我認(rèn)為如果此訊息為真,到時使用方式很可能也是{{template}}。
- 條件複雜時可配合偽高級語言使用。
總結(jié)
手冊
Markdown
XML
JSON
- LLM(Large Language Model):大型語言模型,像是OpenAI的GPT等,能基於大量文字資料進(jìn)行自然語言處理或生成。例如在Caveduck中,與AI角色的所有互動都是透過LLM完成。LLM擅長理解與生成類似人類語言的文字,但需要精確的提示(Prompt)來達(dá)成理想效果。
- 提示詞(Prompt):創(chuàng)作者提供給LLM的文字輸入,用於引導(dǎo)模型生成回應(yīng)。Prompt的設(shè)計對生成結(jié)果影響甚大。清晰、簡潔的Prompt能提高模型理解意圖的準(zhǔn)確性,冗長或含糊的提示則可能導(dǎo)致回應(yīng)偏離預(yù)期。
- Token:Token是LLM處理文字的最小單位,可包括單詞、標(biāo)點(diǎn)符號或部分單詞。在Caveduck中,每次互動都會消耗Token,包括使用者輸入的內(nèi)容、角色的Prompt,和角色產(chǎn)生的回應(yīng)。每個LLM的Token處理上限不同,但Caveduck未公開具體的上限數(shù)字,大致可透過消耗的點(diǎn)數(shù)推測。過多的Token可能導(dǎo)致內(nèi)容被截斷,因此設(shè)計Prompt時需要優(yōu)化長度與信息密度,確保最重要的部分能完整被處理。希望未來Caveduck能公佈詳細(xì)Token上限資訊,方便創(chuàng)作者更有效率地設(shè)計提示詞。
- YAML(Yet Another Markup Language):一種簡潔的資料表示語言,類似JSON,但更容易讀寫。適合用於簡單結(jié)構(gòu)化資料,常見於設(shè)定檔中。
- 層次結(jié)構(gòu)(Hierarchy):指資訊的組織方式。透過明確的層級標(biāo)示(例如以嵌套結(jié)構(gòu)呈現(xiàn)內(nèi)容),能幫助LLM更有效地理解並解析指令或內(nèi)容。