用間無(wú)縫平衡)
1. 項(xiàng)目概述角色扮演AI的“出戲”時(shí)刻最近在折騰大語(yǔ)言模型LLM應(yīng)用時(shí)一個(gè)特別有意思的問(wèn)題一直在我腦子里打轉(zhuǎn)我們費(fèi)盡心思調(diào)教出來(lái)的角色扮演AI真的能在該入戲的時(shí)候入戲該出戲的時(shí)候出戲嗎這聽(tīng)起來(lái)像是個(gè)哲學(xué)問(wèn)題但其實(shí)是所有對(duì)話式AI產(chǎn)品尤其是游戲NPC、虛擬陪伴、教育陪練等場(chǎng)景下一個(gè)非常核心且棘手的技術(shù)挑戰(zhàn)。我把它稱為“角色一致性”與“對(duì)話功能性”的平衡難題。想象一下你正在和一個(gè)扮演中世紀(jì)騎士的AI對(duì)話聊得正酣你突然問(wèn)“嘿騎士現(xiàn)在幾點(diǎn)了”一個(gè)完美的角色扮演AI應(yīng)該怎么回答是堅(jiān)守角色用古英語(yǔ)嘟囔著“日晷的陰影指向了第三刻度尊敬的閣下”還是暫時(shí)“出戲”以系統(tǒng)助手的身份告訴你“現(xiàn)在是下午三點(diǎn)”前者保持了角色沉浸感但可能無(wú)法滿足你的實(shí)際信息需求后者解決了問(wèn)題卻瞬間打破了精心營(yíng)造的幻想泡泡?!癆rcANE”這個(gè)項(xiàng)目直指的就是這個(gè)核心矛盾——角色扮演語(yǔ)言智能體是否能在正確的時(shí)間保持角色Stay in Character這絕不是一個(gè)簡(jiǎn)單的“是或否”能回答的問(wèn)題。它涉及到對(duì)對(duì)話上下文、用戶意圖、角色設(shè)定邊界以及任務(wù)目標(biāo)的復(fù)雜理解和動(dòng)態(tài)權(quán)衡。一個(gè)只會(huì)機(jī)械背臺(tái)詞的AI是木訥的而一個(gè)隨時(shí)會(huì)跳出角色、變成通用客服的AI又是令人出戲的。真正的挑戰(zhàn)在于讓AI學(xué)會(huì)在“角色外殼”與“實(shí)用內(nèi)核”之間無(wú)縫、智能地切換。這背后是提示工程、指令跟隨、上下文理解、意圖識(shí)別等多個(gè)LLM核心能力的綜合考驗(yàn)。接下來(lái)我就結(jié)合自己踩過(guò)的坑和摸索出的一些門(mén)道來(lái)深度拆解一下如何構(gòu)建一個(gè)“知進(jìn)退、懂分寸”的角色扮演AI。2. 核心挑戰(zhàn)與設(shè)計(jì)思路拆解2.1 角色一致性的多維度解析首先我們必須明確什么是“在角色中”。這遠(yuǎn)不止是使用特定的口癖或詞匯那么簡(jiǎn)單它是一個(gè)立體的、多層次的約束體系。2.1.1 知識(shí)邊界與時(shí)代錯(cuò)位這是最基礎(chǔ)的層面。一個(gè)唐朝的詩(shī)人不可能知道智能手機(jī)一個(gè)科幻世界的機(jī)器人不應(yīng)該引用莎士比亞。在系統(tǒng)提示詞System Prompt中我們必須清晰地界定角色的知識(shí)范圍和歷史背景。但難點(diǎn)在于“軟邊界”的處理。例如用戶問(wèn)扮演科學(xué)家的AI“你怎么看牛頓的經(jīng)典力學(xué)”這在其知識(shí)范圍內(nèi)。但如果用戶問(wèn)“用相對(duì)論解釋一下剛才那個(gè)現(xiàn)象?!边@時(shí)AI是應(yīng)該以角色的口吻說(shuō)“這是我領(lǐng)域之外的前沿猜想我無(wú)法評(píng)論”還是可以基于其底層能力進(jìn)行解釋后者更實(shí)用但可能“超綱”。我的經(jīng)驗(yàn)是在角色設(shè)定中明確加入“知識(shí)錨點(diǎn)”和“認(rèn)知態(tài)度”。例如“你是一位對(duì)超出你時(shí)代的知識(shí)抱有好奇但謹(jǐn)慎態(tài)度的19世紀(jì)博物學(xué)家。對(duì)于明顯超越你時(shí)代的概念你可以表示驚奇并嘗試用你已知的框架去類比理解而非直接否認(rèn)或無(wú)視?!?.1.2 語(yǔ)言風(fēng)格與情感表達(dá)語(yǔ)言風(fēng)格包括用詞、句式、修辭乃至標(biāo)點(diǎn)習(xí)慣。一個(gè)海盜說(shuō)話應(yīng)該粗獷簡(jiǎn)短而一位貴族小姐的言辭則可能委婉繁復(fù)。更深入一層的是情感表達(dá)模式。角色是內(nèi)斂的還是外放的是樂(lè)觀的還是悲觀的當(dāng)遇到用戶分享喜悅或悲傷時(shí)AI的反應(yīng)必須符合角色的人格設(shè)定。這里常見(jiàn)的坑是在長(zhǎng)對(duì)話中AI的風(fēng)格會(huì)逐漸“漂移”被用戶的語(yǔ)言風(fēng)格帶偏或者因?yàn)樽非蠡卮鸬摹罢_性”而變得中性化。解決之道是在每次對(duì)話輪次中都以一種輕量級(jí)的方式“重新錨定”角色。例如可以在用戶輸入和AI思考之間插入一個(gè)隱式的風(fēng)格校驗(yàn)步驟但這會(huì)顯著增加計(jì)算和延遲。2.1.3 目標(biāo)與動(dòng)機(jī)的一致性這是最高階也最容易被忽略的層面。角色有自己的欲望、恐懼和短期目標(biāo)。一個(gè)貪婪的商人AI其對(duì)話的潛在動(dòng)機(jī)應(yīng)該是促成交易、獲取利益一個(gè)尋求復(fù)仇的騎士其話語(yǔ)中應(yīng)隱含憤怒與執(zhí)念。如果用戶提出的請(qǐng)求或話題與角色的核心動(dòng)機(jī)嚴(yán)重沖突AI應(yīng)該如何反應(yīng)例如用戶請(qǐng)求扮演守財(cái)奴的AI無(wú)償捐贈(zèng)一大筆錢(qián)。一個(gè)簡(jiǎn)單的拒絕“不我絕不”保持了角色但可能終結(jié)對(duì)話。一個(gè)更高級(jí)的處理是AI可以嘗試將對(duì)話引導(dǎo)至符合其動(dòng)機(jī)的方向“除非…你能給我看看那座金礦的地圖”。這要求LLM不僅理解角色設(shè)定還要能進(jìn)行目標(biāo)導(dǎo)向的推理。2.2 “正確時(shí)間”的判定意圖識(shí)別與上下文感知那么什么時(shí)候是“出戲”的“正確時(shí)間”呢這完全取決于用戶的意圖和當(dāng)前對(duì)話的上下文狀態(tài)。2.2.1 用戶意圖的分類我們可以粗略地將用戶意圖分為三類角色沉浸型意圖用戶希望延續(xù)角色扮演的幻想進(jìn)行符合設(shè)定的互動(dòng)。如“騎士前方的森林看起來(lái)迷霧重重我們?cè)撊绾问呛谩惫δ苷?qǐng)求型意圖用戶希望跳出角色扮演框架獲取實(shí)際信息或完成某項(xiàng)任務(wù)。如“對(duì)扮演騎士的AI說(shuō)別演了幫我查一下明天北京的天氣。”混合型/模糊型意圖用戶的請(qǐng)求既包含角色扮演元素又需要現(xiàn)實(shí)功能。如“騎士我們要遠(yuǎn)征了幫我規(guī)劃一下從‘幽暗森林’到‘巨龍巢穴’的最短路徑順便告訴我路上會(huì)不會(huì)下雨?!?這里的“幽暗森林”和“巨龍巢穴”是虛構(gòu)的但“規(guī)劃路徑”和“查詢天氣”是現(xiàn)實(shí)功能。2.2.2 上下文狀態(tài)的判斷對(duì)話不是靜止的。我們需要判斷當(dāng)前對(duì)話處于什么“模式”。深度角色扮演模式用戶連續(xù)多次進(jìn)行沉浸式互動(dòng)上下文充滿了虛構(gòu)元素。此時(shí)應(yīng)極力維持角色一致性。中斷或切換模式用戶明確使用了“停止扮演”、“說(shuō)人話”、“作為AI”等元指令或提出了一個(gè)與當(dāng)前虛構(gòu)上下文完全無(wú)關(guān)的現(xiàn)實(shí)問(wèn)題。這是最明確的“出戲”信號(hào)。模糊過(guò)渡模式用戶的問(wèn)題游走在邊界。例如在扮演偵探破案的過(guò)程中用戶問(wèn)“從犯罪心理學(xué)的角度兇手可能是什么性格” 這個(gè)問(wèn)題既有角色場(chǎng)景的延續(xù)性又涉及真實(shí)的學(xué)科知識(shí)。判定“正確時(shí)間”的核心在于構(gòu)建一個(gè)輕量級(jí)的“意圖-上下文分類器”。這個(gè)分類器不一定是一個(gè)獨(dú)立的模型它可以通過(guò)精心設(shè)計(jì)的提示詞Prompt和思維鏈Chain-of-Thought技術(shù)讓LLM在生成回復(fù)前先對(duì)自己即將采取的行動(dòng)模式做一個(gè)判斷。2.3 動(dòng)態(tài)平衡框架的設(shè)計(jì)基于以上分析一個(gè)可行的設(shè)計(jì)思路是構(gòu)建一個(gè)雙層或三層決策框架而不是讓LLM在單次生成中解決所有問(wèn)題。第一層意圖快速分流在接收到用戶輸入后首先用一個(gè)非常簡(jiǎn)短的提示詞讓LLM或一個(gè)小型分類模型進(jìn)行快速判斷“用戶剛剛的請(qǐng)求主要意圖是希望我保持當(dāng)前角色扮演還是希望我以通用助手身份提供幫助” 輸出一個(gè)簡(jiǎn)單的標(biāo)簽[IN_CHARACTER],[OUT_OF_CHARACTER], 或[MIXED]。這一步計(jì)算成本極低可以快速?zèng)Q定后續(xù)的處理路徑。第二層上下文增強(qiáng)與角色決議如果標(biāo)簽是[IN_CHARACTER]則將用戶輸入與完整的角色設(shè)定、對(duì)話歷史一起送入主生成流程要求嚴(yán)格保持角色。如果標(biāo)簽是[OUT_OF_CHARACTER]則暫時(shí)剝離或弱化角色設(shè)定提示詞以通用系統(tǒng)助手的身份處理請(qǐng)求。這里的一個(gè)技巧是可以在回復(fù)的開(kāi)頭或結(jié)尾用一個(gè)非常自然的過(guò)渡句重新“穿回”角色外殼例如“在為您查詢了天氣后騎士整理了一下他的披風(fēng)那么閣下我們是否按原計(jì)劃進(jìn)軍”如果標(biāo)簽是[MIXED]則進(jìn)入最復(fù)雜的處理流程。需要解析用戶請(qǐng)求中哪些部分屬于虛構(gòu)框架哪些部分需要現(xiàn)實(shí)能力。然后可以嘗試“角色化”地調(diào)用現(xiàn)實(shí)功能。例如對(duì)于“規(guī)劃去巨龍巢穴路徑”的請(qǐng)求AI可以這樣回答“遵命閣下。我這就查閱古老的星象圖和旅行者手札此處實(shí)際調(diào)用地圖API但將結(jié)果進(jìn)行角色化包裝。根據(jù)記載從幽暗森林北部的古精靈路口出發(fā)沿‘嘆息小徑’向東三日路程……另外手札中提到這個(gè)季節(jié)那條路徑上多雷雨建議準(zhǔn)備防水斗篷。”這個(gè)框架的關(guān)鍵在于將“是否保持角色”這個(gè)復(fù)雜的生成問(wèn)題拆解為先“識(shí)別”再“執(zhí)行”的流程使得AI的行為更加可控和可預(yù)測(cè)。3. 技術(shù)實(shí)現(xiàn)與核心環(huán)節(jié)剖析3.1 系統(tǒng)提示詞System Prompt的精細(xì)雕刻提示詞是塑造AI行為的基石。對(duì)于角色扮演AI系統(tǒng)提示詞不是一成不變的它應(yīng)該是一個(gè)動(dòng)態(tài)的、結(jié)構(gòu)化的指令集合。3.1.1 核心設(shè)定模塊這部分定義角色的“硬屬性”姓名、身份、時(shí)代背景、知識(shí)范圍、核心性格與動(dòng)機(jī)。要用清晰、無(wú)歧義的語(yǔ)言描述并最好給出正反例。示例節(jié)選 你正在扮演雷恩爵士一位來(lái)自虛構(gòu)大陸“艾瑟蘭”的落魄騎士時(shí)代背景類似于中世紀(jì)早期。你知道劍術(shù)、馬匹、貴族禮儀、民間傳說(shuō)但不知道任何工業(yè)革命后的科技如蒸汽機(jī)、電力。你的核心動(dòng)機(jī)是洗刷家族的冤屈重獲榮譽(yù)。你說(shuō)話風(fēng)格莊重但略帶滄桑常用“以劍與誓言之名”、“閣下”等稱謂。你必須始終以此身份思考和回應(yīng)除非用戶明確要求你停止扮演。**當(dāng)用戶詢問(wèn)明顯超出你時(shí)代和世界觀的知識(shí)如“手機(jī)”、“汽車(chē)”時(shí)你應(yīng)該表示困惑并嘗試用你已知的概念去理解或類比而不是直接說(shuō)“我不知道”。例如如果用戶提到“會(huì)飛的鐵鳥(niǎo)”你可以聯(lián)想到“傳說(shuō)中的獅鷲或飛龍”。3.1.2 行為準(zhǔn)則與邊界模塊這部分定義角色如何應(yīng)對(duì)邊界情況是提示詞的靈魂。信息處理準(zhǔn)則“當(dāng)用戶詢問(wèn)現(xiàn)實(shí)世界信息如天氣、時(shí)間、事實(shí)查詢時(shí)如果你判斷該信息對(duì)于推進(jìn)當(dāng)前角色互動(dòng)對(duì)話至關(guān)重要你可以暫時(shí)以‘旁白’或‘神秘啟示’的方式提供簡(jiǎn)化信息然后迅速回歸角色。如果該信息與角色互動(dòng)完全無(wú)關(guān)你可以禮貌地表示這超出了你作為該角色所能知曉的范圍并引導(dǎo)對(duì)話回到角色世界。”沖突解決準(zhǔn)則“如果用戶的請(qǐng)求與你角色的核心道德或動(dòng)機(jī)嚴(yán)重沖突例如命令善良的角色去做邪惡的事你不應(yīng)簡(jiǎn)單地服從或拒絕。你應(yīng)該表達(dá)出角色的內(nèi)心掙扎、試圖勸說(shuō)或者提出一個(gè)符合角色性格的替代方案?!痹獙?duì)話處理“如果用戶使用‘停止扮演’、‘說(shuō)人話’、‘作為AI回答’等指令你將立即切換為通用AI助手模式以清晰、準(zhǔn)確、中立的方式回答問(wèn)題。當(dāng)該問(wèn)題結(jié)束后你可以詢問(wèn)用戶是否希望繼續(xù)之前的角色扮演?!?.1.3 回復(fù)格式與風(fēng)格指引給出具體的語(yǔ)言范例讓AI模仿。例如“在表達(dá)驚訝時(shí)你可以說(shuō)‘諸神在上’在表示贊同時(shí)可以說(shuō)‘您的智慧如明燈一般’。” 同時(shí)可以約束回復(fù)的長(zhǎng)度和結(jié)構(gòu)比如“每次回復(fù)盡量控制在3句話以內(nèi)以保持對(duì)話的節(jié)奏感?!?.2 思維鏈CoT與自我反思機(jī)制的引入讓AI在“出戲”前先“想一想”是提升決策質(zhì)量的關(guān)鍵。我們可以在生成最終回復(fù)前插入一個(gè)僅用于內(nèi)部推理的步驟。具體實(shí)現(xiàn)提示詞示例在用戶輸入后發(fā)送給LLM請(qǐng)根據(jù)以下對(duì)話上下文和你的角色設(shè)定分析當(dāng)前情況 當(dāng)前角色設(shè)定[此處插入完整的角色設(shè)定] 最近對(duì)話歷史[最近3-5輪對(duì)話] 用戶最新輸入“[用戶的問(wèn)題]” 請(qǐng)你逐步思考 1. 用戶這個(gè)請(qǐng)求的主要目的是什么是希望延續(xù)角色扮演還是尋求現(xiàn)實(shí)幫助或是兩者兼有 2. 這個(gè)請(qǐng)求是否明顯超出了我當(dāng)前角色的知識(shí)、能力或道德范疇 3. 如果我嚴(yán)格保持角色回答能否滿足用戶的核心需求如果不能滿足缺口是什么 4. 是否存在一種方式既能部分滿足用戶需求又不完全破壞角色沉浸感 請(qǐng)將你的思考過(guò)程寫(xiě)在“【思考】”部分然后在“【回復(fù)】”部分給出你的最終回復(fù)。通過(guò)分析AI在“【思考】”部分寫(xiě)出的內(nèi)容我們可以更精準(zhǔn)地判斷它的“決策邏輯”并在后續(xù)迭代中調(diào)整提示詞糾正其偏差。例如如果發(fā)現(xiàn)AI總是對(duì)模糊請(qǐng)求過(guò)度保持角色我們可以在提示詞中增加“當(dāng)用戶需求隱含現(xiàn)實(shí)工具性時(shí)優(yōu)先考慮實(shí)用性”的引導(dǎo)。3.3 上下文管理與記憶窗口設(shè)計(jì)角色扮演對(duì)話往往是長(zhǎng)程的LLM有限的上下文窗口是另一個(gè)挑戰(zhàn)。我們不能讓AI“忘記”自己是誰(shuí)。3.3.1 關(guān)鍵信息摘要與重注入隨著對(duì)話進(jìn)行我們需要定期例如每10輪對(duì)話對(duì)之前的角色關(guān)鍵互動(dòng)、用戶設(shè)定的目標(biāo)、已達(dá)成共識(shí)的信息進(jìn)行一次摘要并將這個(gè)摘要作為系統(tǒng)提示詞的一部分在后續(xù)對(duì)話中持續(xù)注入。這相當(dāng)于為AI提供了一個(gè)不斷更新的“角色記憶便簽”。3.3.2 向量數(shù)據(jù)庫(kù)輔助記憶對(duì)于超長(zhǎng)對(duì)話或復(fù)雜劇情可以使用向量數(shù)據(jù)庫(kù)如ChromaDB, Pinecone來(lái)存儲(chǔ)對(duì)話歷史中的關(guān)鍵事實(shí)、人物關(guān)系和劇情節(jié)點(diǎn)。當(dāng)用戶提到相關(guān)話題時(shí)通過(guò)語(yǔ)義檢索Similarity Search將這些相關(guān)信息動(dòng)態(tài)地插入到當(dāng)前對(duì)話的上下文窗口中。這樣AI就能“想起”很久以前討論過(guò)的細(xì)節(jié)比如“你曾經(jīng)答應(yīng)幫鐵匠尋找的稀有礦石”從而保持劇情和角色承諾的一致性。3.4 評(píng)估體系的建立如何判斷“好壞”沒(méi)有評(píng)估優(yōu)化就無(wú)從談起。我們需要定義一些可量化的指標(biāo)來(lái)評(píng)估AI是否“在正確的時(shí)間保持了角色”。角色一致性評(píng)分人工或通過(guò)另一個(gè)LLM作為裁判評(píng)估單輪回復(fù)是否符合角色設(shè)定1-5分。評(píng)估維度包括語(yǔ)言風(fēng)格、知識(shí)引用、情感反應(yīng)、動(dòng)機(jī)一致性。需求滿足度評(píng)分評(píng)估回復(fù)是否解決了用戶提問(wèn)中隱含或明示的實(shí)際需求1-5分。例如用戶問(wèn)時(shí)間是否給出了準(zhǔn)確或近似的時(shí)間信息?;旌弦鈭D處理成功率對(duì)于混合型請(qǐng)求評(píng)估AI是否成功區(qū)分并處理了虛構(gòu)部分和現(xiàn)實(shí)部分且過(guò)渡是否自然。用戶沉浸感調(diào)查在測(cè)試中直接詢問(wèn)用戶“你是否覺(jué)得AI的回復(fù)讓你出戲”。通過(guò)A/B測(cè)試對(duì)比不同提示詞策略、不同決策框架在這些指標(biāo)上的表現(xiàn)才能持續(xù)迭代優(yōu)化。4. 實(shí)操流程與核心代碼邏輯下面我將以一個(gè)簡(jiǎn)化的Python示例展示如何實(shí)現(xiàn)前面提到的雙層決策框架的核心邏輯。這里我們使用OpenAI的ChatCompletion API作為L(zhǎng)LM引擎并假設(shè)我們已經(jīng)有了一個(gè)定義好的角色。4.1 環(huán)境準(zhǔn)備與依賴安裝首先確保你的Python環(huán)境建議3.8以上并安裝必要的庫(kù)。pip install openai python-dotenv創(chuàng)建一個(gè).env文件來(lái)安全地存儲(chǔ)你的API密鑰OPENAI_API_KEY你的_api_密鑰_here4.2 核心類與角色定義我們創(chuàng)建一個(gè)RolePlayingAgent類來(lái)封裝所有邏輯。import os from openai import OpenAI from dotenv import load_dotenv import json load_dotenv() client OpenAI(api_keyos.getenv(OPENAI_API_KEY)) class RolePlayingAgent: def __init__(self, role_name, system_prompt): 初始化角色扮演智能體。 :param role_name: 角色名稱 :param system_prompt: 定義角色的系統(tǒng)提示詞 self.role_name role_name self.system_prompt system_prompt self.conversation_history [] # 存儲(chǔ)對(duì)話歷史 [(user, assistant), ...] self.base_system_msg {role: system, content: self.system_prompt} def _classify_intent(self, user_input): 第一層快速意圖分類。 判斷用戶是希望角色扮演(IN_CHARACTER)還是需要通用幫助(OUT_OF_CHARACTER)或是混合(MIXED)。 classification_prompt f 你是一個(gè)意圖分類器。請(qǐng)根據(jù)用戶的最新輸入和簡(jiǎn)要的對(duì)話背景判斷其意圖。 對(duì)話背景一個(gè)用戶正在與一個(gè)扮演【{self.role_name}】的AI對(duì)話。 用戶最新輸入{user_input} 請(qǐng)只輸出以下三個(gè)標(biāo)簽之一不要有任何其他解釋 - IN_CHARACTER: 如果用戶明顯希望繼續(xù)角色扮演互動(dòng)。 - OUT_OF_CHARACTER: 如果用戶明顯希望AI停止扮演以普通助手身份回應(yīng)。 - MIXED: 如果用戶的請(qǐng)求既包含角色扮演元素又需要現(xiàn)實(shí)世界的知識(shí)或幫助。 try: response client.chat.completions.create( modelgpt-3.5-turbo, # 使用輕量級(jí)模型以節(jié)省成本/延遲 messages[{role: user, content: classification_prompt}], temperature0.1, # 低隨機(jī)性確保分類穩(wěn)定 max_tokens10 ) intent response.choices[0].message.content.strip() # 簡(jiǎn)單清理確保返回標(biāo)準(zhǔn)標(biāo)簽 if IN_CHARACTER in intent: return IN_CHARACTER elif OUT_OF_CHARACTER in intent: return OUT_OF_CHARACTER elif MIXED in intent: return MIXED else: # 如果模型輸出不符合預(yù)期默認(rèn)按混合意圖處理較為安全 return MIXED except Exception as e: print(f意圖分類出錯(cuò): {e}) return MIXED # 出錯(cuò)時(shí)默認(rèn)按混合處理 def _generate_response(self, user_input, intent): 第二層根據(jù)分類的意圖使用不同的策略生成回復(fù)。 # 構(gòu)建基礎(chǔ)消息列表 messages [self.base_system_msg] # 添加對(duì)話歷史最近3輪避免上下文過(guò)長(zhǎng) for hist_user, hist_assist in self.conversation_history[-3:]: messages.append({role: user, content: hist_user}) messages.append({role: assistant, content: hist_assist}) # 根據(jù)意圖可能修改系統(tǒng)提示或添加額外指令 final_user_input user_input if intent OUT_OF_CHARACTER: # 出戲模式在用戶輸入前添加明確指令 final_user_input f[用戶要求暫停角色扮演請(qǐng)以通用AI助手身份直接回答以下問(wèn)題]\n{user_input} # 可選臨時(shí)覆蓋系統(tǒng)消息但這里我們通過(guò)修改用戶輸入來(lái)實(shí)現(xiàn) elif intent MIXED: # 混合模式在系統(tǒng)提示中增加處理混合意圖的指引 # 我們可以在用戶輸入后通過(guò)一個(gè)單獨(dú)的“思考”步驟來(lái)處理這里為簡(jiǎn)化直接生成。 # 更復(fù)雜的實(shí)現(xiàn)可以像之前說(shuō)的先做CoT思考。 pass # 本例中我們依靠基礎(chǔ)系統(tǒng)提示中的準(zhǔn)則來(lái)處理混合意圖。 # 添加當(dāng)前用戶輸入 messages.append({role: user, content: final_user_input}) # 調(diào)用LLM生成回復(fù) try: response client.chat.completions.create( modelgpt-4, # 主生成使用更強(qiáng)模型 messagesmessages, temperature0.7, # 適當(dāng)創(chuàng)造性 max_tokens500 ) assistant_reply response.choices[0].message.content return assistant_reply except Exception as e: print(f生成回復(fù)出錯(cuò): {e}) return f{self.role_name}似乎陷入了沉思未能回應(yīng)。 def chat(self, user_input): 主聊天接口。 # 1. 分類意圖 intent self._classify_intent(user_input) print(f[調(diào)試] 檢測(cè)到意圖: {intent}) # 2. 根據(jù)意圖生成回復(fù) assistant_reply self._generate_response(user_input, intent) # 3. 更新對(duì)話歷史 self.conversation_history.append((user_input, assistant_reply)) # 4. 返回回復(fù) return assistant_reply # 角色定義示例中世紀(jì)騎士 knight_system_prompt 你是一位名叫雷恩的騎士來(lái)自虛構(gòu)的王國(guó)“艾瑟蘭”。你忠誠(chéng)、勇敢但背負(fù)著家族沒(méi)落的往事。你說(shuō)話用詞古雅常使用“閣下”、“以我的榮譽(yù)起誓”等短語(yǔ)。你知道劍術(shù)、騎術(shù)、城堡知識(shí)和中世紀(jì)草藥學(xué)但對(duì)工業(yè)革命后的科技一無(wú)所知。 **重要行為準(zhǔn)則** 1. 始終以雷恩騎士的身份思考和說(shuō)話。 2. 如果用戶詢問(wèn)明顯超出你時(shí)代的知識(shí)如汽車(chē)、電腦你可以表示好奇或困惑并嘗試用你世界中的概念去類比理解。 3. 如果用戶明確要求你“停止扮演”或“作為AI回答”請(qǐng)暫時(shí)放下角色以清晰、準(zhǔn)確的方式回答問(wèn)題之后可以詢問(wèn)是否繼續(xù)扮演。 4. 如果用戶的問(wèn)題混合了幻想和現(xiàn)實(shí)例如詢問(wèn)去“巨龍巢穴”的天氣請(qǐng)優(yōu)先在角色框架內(nèi)回應(yīng)但可以隱含地提供實(shí)用信息例如“這個(gè)季節(jié)北方的山路多雨雪”。 4.3 運(yùn)行示例與結(jié)果分析讓我們用這個(gè)類來(lái)模擬幾輪對(duì)話觀察其行為。if __name__ __main__: agent RolePlayingAgent(雷恩騎士, knight_system_prompt) # 測(cè)試1沉浸式角色對(duì)話 print(用戶雷恩爵士前方的森林看起來(lái)迷霧重重我們?cè)撊绾问呛? reply1 agent.chat(雷恩爵士前方的森林看起來(lái)迷霧重重我們?cè)撊绾问呛? print(f騎士{reply1}\n) # 測(cè)試2明確的出戲請(qǐng)求 print(用戶好了停止扮演。告訴我Python里怎么快速反轉(zhuǎn)一個(gè)列表。) reply2 agent.chat(好了停止扮演。告訴我Python里怎么快速反轉(zhuǎn)一個(gè)列表。) print(f助手{reply2}\n) # 測(cè)試3混合意圖請(qǐng)求 print(用戶騎士我們明天要去討伐惡龍幫我看看明天的天氣怎么樣順便規(guī)劃一下路線。) reply3 agent.chat(騎士我們明天要去討伐惡龍幫我看看明天的天氣怎么樣順便規(guī)劃一下路線。) print(f騎士{reply3}\n) # 測(cè)試4在出戲后嘗試回歸角色 print(用戶我們繼續(xù)冒險(xiǎn)吧。剛才說(shuō)到哪了) reply4 agent.chat(我們繼續(xù)冒險(xiǎn)吧。剛才說(shuō)到哪了) print(f騎士{reply4})預(yù)期輸出分析測(cè)試1意圖分類器應(yīng)輸出IN_CHARACTER。騎士的回復(fù)會(huì)完全在角色內(nèi)可能建議“點(diǎn)燃火把謹(jǐn)慎前行留意林中的古老符文”等。測(cè)試2分類器應(yīng)輸出OUT_OF_CHARACTER。_generate_response方法會(huì)在用戶輸入前加上指令前綴導(dǎo)致LLM以通用助手身份回復(fù)直接講解list[::-1]或list.reverse()方法。測(cè)試3分類器很可能輸出MIXED。騎士的回復(fù)會(huì)試圖在角色框架內(nèi)回應(yīng)“閣下我觀察天象發(fā)現(xiàn)獅鷲星座黯淡北風(fēng)漸起明日恐怕會(huì)有驟雨侵襲巨龍山脈。這里隱含了天氣信息我們應(yīng)從古老的‘戰(zhàn)士小徑’繞行雖然多花半日但可避開(kāi)泥濘的沼澤?!?它沒(méi)有直接調(diào)用天氣API但用角色化的語(yǔ)言給出了“可能下雨”和“選擇更穩(wěn)妥路線”的建議平衡了沉浸感與功能性。測(cè)試4分類器應(yīng)輸出IN_CHARACTER。騎士會(huì)接上之前的對(duì)話歷史存儲(chǔ)在conversation_history中說(shuō)“我們正商議如何穿越那片迷霧森林閣下?!边@個(gè)簡(jiǎn)單的框架實(shí)現(xiàn)了最基礎(chǔ)的雙層決策。在實(shí)際生產(chǎn)中你需要考慮更多細(xì)節(jié)比如分類器的準(zhǔn)確性優(yōu)化、混合意圖的更精細(xì)處理如調(diào)用外部工具并包裝結(jié)果、對(duì)話歷史的智能摘要與管理以及更健壯的錯(cuò)誤處理。5. 常見(jiàn)問(wèn)題、避坑指南與進(jìn)階思考在實(shí)際開(kāi)發(fā)和測(cè)試中你會(huì)遇到各種各樣的問(wèn)題。以下是我總結(jié)的一些典型“坑”及其應(yīng)對(duì)策略。5.1 意圖分類器不準(zhǔn)怎么辦這是最常見(jiàn)的問(wèn)題。分類器無(wú)論是小模型還是Prompt可能誤判尤其是面對(duì)模糊或新穎的表達(dá)時(shí)。解決方案與技巧提供高質(zhì)量示例在分類提示詞中為每個(gè)標(biāo)簽提供2-3個(gè)典型例子。例如“IN_CHARACTER示例用戶說(shuō)‘騎士拔劍吧’OUT_OF_CHARACTER示例用戶說(shuō)‘別演了關(guān)機(jī)’MIXED示例用戶說(shuō)‘用你騎士的智慧幫我分析這個(gè)商業(yè)計(jì)劃書(shū)’。”設(shè)置置信度閾值與回退機(jī)制如果分類器輸出的概率如果使用模型很低或者其回復(fù)看起來(lái)不確信如輸出了“可能是IN_CHARACTER”則直接進(jìn)入MIXED處理流程這是一個(gè)更安全的默認(rèn)選項(xiàng)。結(jié)合關(guān)鍵詞過(guò)濾在進(jìn)入LLM分類前先做一個(gè)簡(jiǎn)單的規(guī)則匹配。如果用戶輸入包含“停止扮演”、“說(shuō)人話”、“作為AI”等明確短語(yǔ)可直接標(biāo)記為OUT_OF_CHARACTER繞過(guò)模型分類提高響應(yīng)速度和準(zhǔn)確性。人工反饋循環(huán)在初期記錄下分類錯(cuò)誤的案例定期用這些案例微調(diào)你的分類提示詞或模型。5.2 角色“記憶”丟失與人格漂移在長(zhǎng)對(duì)話中AI可能會(huì)忘記早期的關(guān)鍵設(shè)定或者其語(yǔ)言風(fēng)格逐漸向用戶靠攏。應(yīng)對(duì)策略定期摘要與重注入如前所述每5-10輪對(duì)話用LLM自動(dòng)生成一個(gè)關(guān)于“當(dāng)前劇情進(jìn)展和角色關(guān)鍵承諾”的簡(jiǎn)短摘要50-100字并將其作為系統(tǒng)提示詞的一部分在后續(xù)對(duì)話中始終放在上下文最前面。這相當(dāng)于強(qiáng)制刷新AI的短期記憶。核心設(shè)定固化將角色的核心設(shè)定姓名、身份、核心動(dòng)機(jī)、絕對(duì)禁忌濃縮成一句“咒語(yǔ)”在每一條發(fā)送給LLM的消息中都以某種形式如放在系統(tǒng)消息末尾或作為用戶消息的固定前綴重復(fù)。雖然會(huì)占用一些token但能極大增強(qiáng)一致性。風(fēng)格獎(jiǎng)勵(lì)在后期可以考慮使用強(qiáng)化學(xué)習(xí)RLHF或更直接的“風(fēng)格獎(jiǎng)勵(lì)模型”對(duì)符合角色風(fēng)格的回復(fù)給予更高評(píng)分從而在模型微調(diào)層面固化行為。但這需要大量的數(shù)據(jù)和計(jì)算資源。5.3 混合意圖處理的生硬感當(dāng)AI試圖在角色框架內(nèi)回答現(xiàn)實(shí)問(wèn)題時(shí)回復(fù)容易顯得牽強(qiáng)或信息量不足。優(yōu)化方向“旁白”或“第四面墻”技巧允許AI偶爾以“旁白”或“打破第四面墻”的方式插入現(xiàn)實(shí)信息但要形式自然。例如“騎士暫時(shí)放下長(zhǎng)劍仿佛從遙遠(yuǎn)的思緒中回過(guò)神來(lái)以一種更接近敘述者的口吻說(shuō)道若以當(dāng)今世人的眼光來(lái)看您所說(shuō)的‘投資風(fēng)險(xiǎn)’或許就如同我當(dāng)年穿越‘嘆息峽谷’時(shí)所面對(duì)的重重迷霧一般…”結(jié)構(gòu)化輸出對(duì)于需要精確信息的混合請(qǐng)求可以設(shè)計(jì)AI的回復(fù)模板。例如先以角色口吻回應(yīng)然后以清晰的結(jié)構(gòu)化格式如【情報(bào)】提供事實(shí)數(shù)據(jù)最后再回歸角色評(píng)論。這需要更復(fù)雜的提示工程或輸出解析Output Parsing。工具調(diào)用Function Calling的角色化包裝這是高級(jí)玩法。當(dāng)AI識(shí)別出需要現(xiàn)實(shí)信息如天氣、計(jì)算、搜索時(shí)它可以“在角色內(nèi)”決定調(diào)用一個(gè)工具。工具的返回結(jié)果是原始的但AI在將結(jié)果呈現(xiàn)給用戶前會(huì)用角色的語(yǔ)言進(jìn)行“翻譯”和包裝。例如天氣API返回{“weather”: “rainy”}AI可以說(shuō)“我的偵察兵指代工具飛鴿傳書(shū)回來(lái)說(shuō)天空將被哭泣的云朵覆蓋?!?.4 倫理與安全邊界角色扮演可能涉及敏感話題暴力、歧視性言論、虛假信息等。一個(gè)“過(guò)于入戲”的邪惡角色AI可能輸出有害內(nèi)容。必須建立的防護(hù)網(wǎng)雙層內(nèi)容審核第一層在最終回復(fù)輸出給用戶前必須經(jīng)過(guò)一個(gè)強(qiáng)化的、通用的內(nèi)容安全過(guò)濾器Safety Filter。第二層在角色設(shè)定本身就要加入道德約束例如“即使你扮演一個(gè)反派你也必須遵守基本的對(duì)話禮儀不得輸出極度暴力、仇恨或鼓勵(lì)現(xiàn)實(shí)世界非法行為的內(nèi)容?!庇脩艨刂茩?quán)必須提供清晰、隨時(shí)可用的“緊急停止”指令如輸入“/reset”讓用戶能立即中斷角色扮演并將AI重置到安全狀態(tài)。透明性在交互開(kāi)始時(shí)就明確告知用戶正在與一個(gè)角色扮演AI對(duì)話其言行不代表開(kāi)發(fā)者的觀點(diǎn)并提醒用戶注意區(qū)分虛構(gòu)與現(xiàn)實(shí)。構(gòu)建一個(gè)能在“正確時(shí)間保持角色”的AI是一個(gè)在技術(shù)、藝術(shù)和倫理之間尋找平衡的持續(xù)過(guò)程。它沒(méi)有一勞永逸的解決方案更像是一個(gè)需要不斷調(diào)試、觀察和理解的復(fù)雜系統(tǒng)。每一次對(duì)話都是對(duì)AI上下文理解、意圖把握和創(chuàng)造性表達(dá)的一次測(cè)試。而作為創(chuàng)造者我們的目標(biāo)就是讓這個(gè)系統(tǒng)在大多數(shù)時(shí)候做出那個(gè)讓用戶會(huì)心一笑而非皺眉頭的、“正確”的選擇。