戰(zhàn):從意圖理解到多輪對(duì)話的工程化落地)
把填槽兩個(gè)字放進(jìn)大模型時(shí)代很多人問的第一個(gè)問題是這不就是實(shí)體識(shí)別嗎其實(shí)差別非常大。我在參與某智能客服平臺(tái)重構(gòu)時(shí)產(chǎn)品同學(xué)丟過來(lái)一條線上對(duì)話記錄用戶上來(lái)就說(shuō)幫我訂兩張明天晚上七點(diǎn)的電影票要前排靠中間的位置。粗看只是普通訂票但真要把這句自然語(yǔ)言轉(zhuǎn)換成下游訂單系統(tǒng)能用的結(jié)構(gòu)化參數(shù)你需要解決的遠(yuǎn)不止是抽出一兩個(gè)實(shí)體。這就是大模型填槽要處理的核心問題。填槽本來(lái)就是任務(wù)型對(duì)話系統(tǒng)里的老概念指的是把用戶自然語(yǔ)言里分散的信息填進(jìn)預(yù)先定義好的字段中比如日期、數(shù)量、影院、座位偏好而意圖則是用戶這整句話想完成的任務(wù)訂票、退票、改簽都算不同意圖。過去大家靠規(guī)則和分類模型做這件事現(xiàn)在換成了大模型做法、坑位和工程邊界全都變了。這篇文章我想從一個(gè)實(shí)際落地的視角把大模型如何理解并提取用戶意圖這件事講透包括三條主流實(shí)現(xiàn)路線、多輪對(duì)話里的槽位管理、典型幻覺問題以及一個(gè)可以直接照著改的電影票預(yù)訂填槽案例。1. 填槽到底在填什么先理清這個(gè)問題的邊界1.1 一次訂票對(duì)話里槽位是怎么被定義的上面的用戶話術(shù)看似簡(jiǎn)單但真正落地時(shí)要拆的東西比想象中多。兩張是人數(shù)明天晚上七點(diǎn)是日期和時(shí)間前排靠中間又拆成排數(shù)和列數(shù)偏好兩個(gè)獨(dú)立維度。如果用戶追加一句第二張票換成靠過道你面對(duì)的就是列表型槽位里某個(gè)元素的修改而不是簡(jiǎn)單的 key-value 覆蓋。在做任何模型接入之前我習(xí)慣先把槽位 Schema 定成一張明確的表這比急著調(diào) Prompt 重要得多。因?yàn)槟P驮俾斆饕残枰环轃o(wú)歧義的字段說(shuō)明才知道該往哪里填、什么算合法值。訂票場(chǎng)景的 Schema 通常長(zhǎng)這樣槽位字段類型示例是否必填備注movie_namestring星海之戰(zhàn)否用戶可能沒說(shuō)片名show_datedate2026-05-20是明天要被換算成具體日期show_timetime19:00是cinemastring某影城是需要和業(yè)務(wù)庫(kù)對(duì)齊seat_countinteger2是seat_areastring前排靠中間否可能拆成兩個(gè)子字段contact_phonestring13800000000取票時(shí)需要格式校驗(yàn)這張表定義好了填槽這件事就有了明確邊界模型要做的就是把用戶語(yǔ)句里的信息放到對(duì)應(yīng)字段里同時(shí)判斷出缺失的必填槽留給下一步對(duì)話管理去追問。1.2 傳統(tǒng) NLU 做了幾十年為什么還需要大模型來(lái)填早年的對(duì)話系統(tǒng)填槽是一條清晰的流水線先有一個(gè)意圖分類模型判斷用戶想做什么再有一個(gè)命名實(shí)體識(shí)別模型抽取時(shí)間、地點(diǎn)、數(shù)量然后對(duì)話狀態(tài)跟蹤模塊把結(jié)果寫進(jìn)狀態(tài)機(jī)最后策略模塊根據(jù)缺失槽位決定下一句反問什么。每一步都有自己的模型和規(guī)則看起來(lái)分工明確實(shí)際維護(hù)起來(lái)相當(dāng)痛苦。真正讓我意識(shí)到這套架構(gòu)天花板的是線上語(yǔ)料里的長(zhǎng)尾表達(dá)。你可以用正則輕松處理兩張但用戶說(shuō)我跟朋友一塊兒去模型需要判斷一塊兒可能對(duì)應(yīng) 2 人還是 3 人用戶說(shuō)晚點(diǎn)也行別太晚模型得理解晚點(diǎn)是相對(duì)當(dāng)前時(shí)刻的模糊偏移用戶說(shuō)還是上次那家吧光靠實(shí)體識(shí)別根本找不到影院。傳統(tǒng)方案遇到這些句子只能讓用戶回到固定菜單點(diǎn)選或者不停地加規(guī)則。規(guī)則每多一條后續(xù)維護(hù)成本就高一分最后整個(gè)模塊變成一團(tuán)誰(shuí)都碰不得的遺產(chǎn)。1.3 大模型把填格子變成了讀懂一段話大模型介入之后本質(zhì)變化不是某個(gè)環(huán)節(jié)變強(qiáng)了而是我們把意圖分類、實(shí)體識(shí)別、對(duì)話狀態(tài)跟蹤三個(gè)步驟合并成了一個(gè)生成任務(wù)給模型一段用戶輸入和槽位 Schema讓它直接輸出結(jié)構(gòu)化 JSON。更重要的是它多出了上下文推理能力。舉個(gè)實(shí)際例子用戶說(shuō)我媽七點(diǎn)半下班幫我訂她下班后那場(chǎng)。傳統(tǒng)實(shí)體識(shí)別只能抽到七點(diǎn)半和下班后但大模型可以結(jié)合當(dāng)前時(shí)間和對(duì)話背景推斷出真正要訂的場(chǎng)次大約在晚上八點(diǎn)前后。再比如還是上次那家影院模型能從歷史對(duì)話里回填 cinema 字段。這種能力不是不能用傳統(tǒng) NLU 做但你需要為每一個(gè)隱含推理場(chǎng)景單獨(dú)設(shè)計(jì)規(guī)則成本極高。當(dāng)然合并成生成任務(wù)也帶來(lái)了新的麻煩輸出不穩(wěn)定、偶爾會(huì)編造用戶沒提過的值、難以像分類日志一樣快速定位錯(cuò)誤環(huán)節(jié)。這就是為什么我一直強(qiáng)調(diào)大模型填槽絕不能只靠模型自由發(fā)揮必須在外圍建立工程約束。2. 大模型做填槽的三條路線提示抽取、函數(shù)調(diào)用、微調(diào)2.1 純提示抽取最快上手的方案如果只是想快速驗(yàn)證效果最直接的方式就是把槽位定義全部寫進(jìn) System Prompt要求模型輸出固定結(jié)構(gòu)的 JSON。我常用的是下面這種模板你是一個(gè)任務(wù)型對(duì)話的語(yǔ)義解析模塊。根據(jù)用戶輸入只輸出 JSON不要任何解釋。 意圖列表book_ticket, cancel_ticket, query_ticket, out_of_scope。 槽位定義 - movie_name: string影片名未提到填 null - show_date: string日期格式 YYYY-MM-DD明天等相對(duì)時(shí)間須換算成具體日期 - show_time: string時(shí)間格式 HH:mm - cinema: string影院名 - seat_count: integer人數(shù) - seat_area: string座位區(qū)域偏好 輸出要求 1. 只輸出 JSON不要輸出任何解釋性文字。 2. 用戶沒有提到的槽位必須填 null嚴(yán)禁猜測(cè)。 3. 如果用戶表達(dá)存在歧義在 ambiguity 字段中用一句話描述。調(diào)用代碼如果后端是常見的大模型接口通常長(zhǎng)這樣import requests import json API_URL https://api.example-llm-service.com/v1/chat/completions def parse_user_input(user_text, history): payload { model: your-model, temperature: 0, response_format: {type: json_object}, messages: [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: f對(duì)話歷史{history}\n當(dāng)前輸入{user_text}} ] } resp requests.post(API_URL, jsonpayload, timeout10) return json.loads(resp.json()[choices][0][message][content])這個(gè)方案優(yōu)勢(shì)是零訓(xùn)練成本改 Prompt 就能調(diào)效果。它的問題也很明顯Prompt 越長(zhǎng)模型越容易漏字段復(fù)雜嵌套關(guān)系難約束日期格式偶爾會(huì)飄。所以我更愿意把它用在 PoC 或輕量場(chǎng)景里直接面對(duì)大流量請(qǐng)求時(shí)要多留個(gè)心眼。2.2 函數(shù)調(diào)用式填槽結(jié)構(gòu)化輸出的正規(guī)軍如果模型服務(wù)支持函數(shù)調(diào)用能力我更推薦把每個(gè)意圖定義成一個(gè)可調(diào)用函數(shù)讓模型用函數(shù)參數(shù)的形式返回槽位。這樣輸出的不是自由文本而是嚴(yán)格貼合參數(shù)簽名的結(jié)構(gòu)。def book_movie_ticket( movie_name: str None, show_date: str None, show_time: str None, cinema: str None, seat_count: int None, seat_area: str None, ): 預(yù)訂電影票。參數(shù)來(lái)自用戶表達(dá)沒有提到的槽位不要填。 return { intent: book_ticket, movie_name: movie_name, show_date: show_date, show_time: show_time, cinema: cinema, seat_count: seat_count, seat_area: seat_area, }把函數(shù)定義和描述傳給模型之后模型會(huì)返回一個(gè)結(jié)構(gòu)化的調(diào)用請(qǐng)求里面帶著參數(shù) JSON。相比純 Prompt 抽取函數(shù)調(diào)用有兩個(gè)實(shí)際好處一是模型對(duì)參數(shù)必須符合函數(shù)簽名這層約束遵守得好很多返回的 JSON 通常合法二是它天然適合多輪流程因?yàn)槟P涂梢栽趨?shù)字典里補(bǔ)上上一輪缺失的字段而不是每次整段重寫。但函數(shù)調(diào)用并不能杜絕幻覺。模型仍有可能在某個(gè)參數(shù)沒有依據(jù)時(shí)自己編一個(gè)值。下游還是要做候選校驗(yàn)不能因?yàn)橛昧撕瘮?shù)調(diào)用就放松警惕。2.3 微調(diào)模型垂直領(lǐng)域里效果更穩(wěn)的另一個(gè)選擇當(dāng)業(yè)務(wù)里存在大量專有名詞比如醫(yī)療科室名稱、商品 SKU、內(nèi)部訂單類型通用模型的先驗(yàn)知識(shí)根本不知道這些詞長(zhǎng)什么樣硬用提示詞堆出一個(gè)幾千項(xiàng)的候選枚舉也不現(xiàn)實(shí)這時(shí)候該考慮微調(diào)。我的建議是先用提示詞把流程跑通攢下足夠的標(biāo)注樣本再對(duì)開源基座模型做 LoRA 這類輕量微調(diào)。數(shù)據(jù)按常見對(duì)話格式構(gòu)造assistant 側(cè)直接放結(jié)構(gòu)化槽位結(jié)果{ messages: [ {role: user, content: 幫我約一個(gè)下周二上午的皮膚科號(hào)}, {role: assistant, content: {\intent\: \book_appointment\, \department\: \皮膚科\, \date\: \2026-05-26\, \time_period\: \上午\, \patient_name\: null}} ] }微調(diào)之后模型對(duì)領(lǐng)域術(shù)語(yǔ)和簡(jiǎn)寫的識(shí)別命中率會(huì)明顯上升輸出穩(wěn)定性往往也比通用模型好一截。但成本要算清楚你需要準(zhǔn)備上萬(wàn)條高質(zhì)量樣本維護(hù)模型版本做回歸評(píng)測(cè)還要處理基座升級(jí)帶來(lái)的差異。對(duì)大多數(shù)中小團(tuán)隊(duì)我不建議一上來(lái)就微調(diào)先把前兩條路榨干再說(shuō)。2.4 三條路線怎么選一張對(duì)照表維度純提示抽取函數(shù)調(diào)用微調(diào)上手成本低中高結(jié)構(gòu)化穩(wěn)定性中高高領(lǐng)域術(shù)語(yǔ)支持靠 Prompt 堆靠 Prompt 堆靠訓(xùn)練數(shù)據(jù)迭代速度快快慢幻覺控制弱中中典型場(chǎng)景原型、小流量生產(chǎn)對(duì)話系統(tǒng)專業(yè)垂直領(lǐng)域我的個(gè)人經(jīng)驗(yàn)是能函數(shù)調(diào)用就別只靠提示詞能靠提示詞解決就別急著微調(diào)。填槽模塊最重要的是可控而可控性通常來(lái)自模型周圍的工程約束而不是模型本身有多聰明。3. 多輪對(duì)話里的槽位管理補(bǔ)全、覆蓋與澄清3.1 缺槽檢測(cè)先分清用戶沒說(shuō)和系統(tǒng)不知道生產(chǎn)系統(tǒng)里缺槽并不總是用戶的錯(cuò)。我們要分兩種情況一種是用戶確實(shí)還沒提供必填槽位比如訂票沒留手機(jī)號(hào)這時(shí)系統(tǒng)要主動(dòng)澄清另一種是用戶說(shuō)了但模型無(wú)法從知識(shí)庫(kù)里把它映射成標(biāo)準(zhǔn)值比如用戶說(shuō)我家附近那家影院而系統(tǒng)不知道我家在哪。我的做法是在 Prompt 里明確區(qū)分 null 和 unknown。null 表示用戶沒提unknown 表示用戶提了但我無(wú)法解析。模型返回 unknown 時(shí)不急著追問同樣的必填項(xiàng)而是先解決候選問題比如引導(dǎo)用戶從影院列表里選擇。這樣的體驗(yàn)差異很明顯用戶不會(huì)覺得機(jī)器在反復(fù)問同一句話。澄清話術(shù)也要帶上已收集的信息比如好的已確認(rèn) 2 張、明晚 7 點(diǎn)場(chǎng)請(qǐng)問在哪家影城取票而不是冷冰冰地來(lái)一句請(qǐng)?zhí)峁┯霸好Q。既然是對(duì)話系統(tǒng)就要讓每一輪追問看起來(lái)像自然延續(xù)。3.2 跨輪槽位記憶兩種主流做法多輪對(duì)話里最常踩的坑是用戶第一句說(shuō)幫我訂兩張明晚七點(diǎn)的票第二句說(shuō)哦不用七點(diǎn)改八點(diǎn)吧。如果你只把第二句丟給模型它根本不知道改的對(duì)象是什么如果把整個(gè)歷史全丟進(jìn)去也不是不行但長(zhǎng)對(duì)話里既費(fèi) token又容易被無(wú)關(guān)內(nèi)容干擾。更穩(wěn)的做法是維護(hù)一個(gè)外部槽位狀態(tài)快照每輪把當(dāng)前狀態(tài)以 JSON 形式注入 Prompt要求模型輸出完整的新狀態(tài)快照而不只是本輪新增字段當(dāng)前狀態(tài)快照 {movie_name: null, show_date: 2026-05-20, show_time: 19:00, seat_count: 2} 當(dāng)前用戶輸入不用七點(diǎn)了改八點(diǎn)吧 請(qǐng)基于快照更新槽位輸出完整 JSON。這樣做的好處是即使某輪模型理解得不好編碼層也可以對(duì)輸出做字段級(jí) diff決定哪些槽位允許被覆蓋、哪些要保持原樣。它相當(dāng)于把對(duì)話狀態(tài)控制的最終決定權(quán)拿回工程手里。因?yàn)槟P洼敵龅氖侨靠煺漳呐滤┛戳藲v史至少還能保留上一輪的正確值。3.3 槽位沖突與修正用戶改主意了怎么辦改主意是多輪對(duì)話里最高頻的事件而 LLM 并不擅長(zhǎng)區(qū)分新值替換舊值和對(duì)舊值的否定。我建議不要讓模型只輸出字符串而是讓它輸出帶操作符的結(jié)構(gòu){ intent: book_ticket, slots: { show_time: {op: set, value: 20:00}, show_date: {op: keep, value: 2026-05-20} } }當(dāng)用戶明確說(shuō)不要七點(diǎn)模型應(yīng)該把 show_time 置為 null并把狀態(tài)調(diào)整為待確認(rèn)而不是執(zhí)著地保留舊值。當(dāng)用戶說(shuō)算了不訂了意圖切換所有槽位全部 clear。外層代碼再根據(jù)這些操作符逐一應(yīng)用就能避免很多看起來(lái)莫名其妙的槽位跳變。這部分工程化程度直接決定系統(tǒng)的可靠度。一個(gè)只會(huì)在單輪里抽槽位的 Demo和一個(gè)能在真實(shí)對(duì)話里接住用戶反復(fù)修改的生產(chǎn)系統(tǒng)差距就在這里。4. 落地最容易翻車的點(diǎn)幻覺、歧義與臟數(shù)據(jù)4.1 幻覺槽位的三道防線大模型填槽最頭疼的是它會(huì)在沒有依據(jù)的時(shí)候憑空填出一些看起來(lái)合理的槽位。比如用戶只說(shuō)幫我訂明天的電影票模型可能擅自把 movie_name 填成星海之戰(zhàn)因?yàn)闆]約束時(shí)它總想給你補(bǔ)全一點(diǎn)什么。對(duì)付幻覺我習(xí)慣設(shè)三道防線。第一道Prompt 里反復(fù)強(qiáng)調(diào)未提到的槽位必須填 null禁止猜測(cè)并給一個(gè)負(fù)例和一個(gè)正例。第二道輸出側(cè)做嚴(yán)格校驗(yàn)代碼里寫清楚每個(gè)槽位的合法范圍import re from datetime import datetime def validate_slots(slots): errors [] if slots.get(show_date): try: datetime.strptime(slots[show_date], %Y-%m-%d) except ValueError: errors.append(show_date 格式錯(cuò)誤) if slots.get(show_time): try: datetime.strptime(slots[show_time], %H:%M) except ValueError: errors.append(show_time 格式錯(cuò)誤) if slots.get(seat_count) is not None: if not (1 int(slots[seat_count]) 10): errors.append(seat_count 超出范圍) if slots.get(cinema) and slots[cinema] not in VALID_CINEMAS: errors.append(cinema 不在候選列表) return errors第三道把校驗(yàn)不過的請(qǐng)求送進(jìn)二次確認(rèn)流程而不是直接報(bào)錯(cuò)。這三道防線疊下來(lái)即使模型的輸出偶爾不靠譜用戶體驗(yàn)依然可控。4.2 同義表達(dá)與歧義處理大模型對(duì)同義詞的理解力遠(yuǎn)超傳統(tǒng)實(shí)體識(shí)別但理解同義詞之后你還需要做歸一化。用戶說(shuō)看星戰(zhàn)而庫(kù)里標(biāo)準(zhǔn)片名可能是星海之戰(zhàn)黎明回響模型輸出標(biāo)準(zhǔn)名還是簡(jiǎn)稱很大程度上取決于 Prompt 里給的候選格式。我的建議是遇到這種需要精確匹配的槽位不要指望模型記憶直接把候選列表放進(jìn) Prompt并限定它從候選里選標(biāo)準(zhǔn)值。歧義則是另一件事。用戶說(shuō)去南站可能指高鐵南站也可能指客運(yùn)南站模型隨便給哪個(gè)都可能是錯(cuò)的。對(duì)這種歧義最穩(wěn)的策略不是猜而是返回候選列表讓用戶確認(rèn)。雖然多了一輪交互卻能避免一次錯(cuò)誤下單帶來(lái)的更大成本。落地中我寧愿系統(tǒng)多問一句也不愿意它自作聰明。4.3 置信度評(píng)分與人工接管不是所有請(qǐng)求都該讓模型一路走到底。生產(chǎn)系統(tǒng)里需要給模型輸出打個(gè)分低于閾值就走人工或回到規(guī)則流程。一個(gè)簡(jiǎn)單可用的置信度計(jì)算方式由三部分組成必填槽位完整度、枚舉槽位命中率、模型自評(píng)低置信度。其中枚舉命中率最客觀比如 cinema 字段不在候選影城里這個(gè)槽位就得 0 分必填缺失一個(gè)字段完整性就會(huì)打折。三項(xiàng)加權(quán)后得到一個(gè) 0 到 1 之間的分?jǐn)?shù)。低于 0.7系統(tǒng)彈出確認(rèn)話術(shù)低于 0.4直接轉(zhuǎn)人工坐席。打分邏輯寫在工程代碼里不依賴模型解釋上線后也好排查。4.4 會(huì)話過期與槽位時(shí)效還有一個(gè)容易被忽略的問題槽位是有時(shí)效的。用戶周一說(shuō)了明天系統(tǒng)換算成 2026-05-26 存下來(lái)如果這個(gè)會(huì)話被擱置到周三用戶回來(lái)說(shuō)我剛才說(shuō)的那場(chǎng)幫我訂了吧你再用 2026-05-26 去下單就錯(cuò)了。更常見的是場(chǎng)次座位和票價(jià)隨時(shí)會(huì)變槽位里的影院和場(chǎng)次必須在下單前重新校驗(yàn)有效性。我會(huì)在狀態(tài)快照里給每個(gè)槽位額外存一個(gè) obtained_at 時(shí)間戳超過一定時(shí)長(zhǎng)后該槽位視為過期需要引導(dǎo)用戶重新確認(rèn)。這個(gè)邏輯簡(jiǎn)單卻能在異步對(duì)話場(chǎng)景里救命。5. 一個(gè)可復(fù)現(xiàn)的最小案例電影票預(yù)訂填槽5.1 場(chǎng)景與槽位 Schema把前面的思路落到一個(gè)可運(yùn)行的例子上。假設(shè)我們做一個(gè)電影票預(yù)訂助手只處理訂票、查票、退票三類意圖。訂票意圖的槽位如上文表格所示。核心必填字段是日期、時(shí)間、影院、人數(shù)和聯(lián)系方式片名和座位偏好可以作為選填。5.2 Prompt 模板我用函數(shù)調(diào)用方式實(shí)現(xiàn)函數(shù)簽名如下def book_ticket( movie_name: str None, show_date: str None, show_time: str None, cinema: str None, seat_count: int None, phone: str None ): 預(yù)訂電影票。當(dāng)前對(duì)話狀態(tài)可以作為上下文。 # 返回槽位字典由上層調(diào)度代碼更新狀態(tài) return locals()5.3 多輪調(diào)度核心循環(huán)下面是一個(gè)極簡(jiǎn)調(diào)度循環(huán)重點(diǎn)展示狀態(tài)維護(hù)和澄清邏輯def run_dialogue(): state {intent: None, slots: {}} history [] require_slots [show_date, show_time, cinema, seat_count, phone] while True: user_text input(用戶) history.append({role: user, content: user_text}) result call_llm_with_function(state, history) if result.get(intent) book_ticket: state[slots].update(result[slots]) missing [s for s in require_slots if s not in state[slots] or state[slots].get(s) is None] if missing: reply clarify_question(missing, state[slots]) else: reply f確認(rèn)訂票{state[slots][cinema]}{state[slots][show_date]} {state[slots][show_time]}{state[slots][seat_count]}張 print(f助手{reply}) break else: reply 抱歉我還不能處理這個(gè)操作 history.append({role: assistant, content: reply}) print(f助手{reply})這里 call_llm_with_function 會(huì)把上一輪狀態(tài)和當(dāng)前用戶輸入一起發(fā)給模型模型返回參數(shù)后外層代碼再更新狀態(tài)。clarify_question 根據(jù)缺失字段生成話術(shù)并把已填信息組合進(jìn)去讓整個(gè)流程看起來(lái)更像真人。5.4 離線評(píng)測(cè)與線上回流跑通之后第一件事是搭一套離線評(píng)測(cè)。最常用的指標(biāo)是意圖準(zhǔn)確率和槽位 F1。意圖準(zhǔn)確率統(tǒng)計(jì)所有測(cè)試樣本里意圖判斷正確的比例槽位 F1 需要把預(yù)測(cè)槽位和人工標(biāo)注槽位對(duì)齊順便校對(duì)值的格式是否完全一致。指標(biāo)計(jì)算方式我的經(jīng)驗(yàn)閾值意圖準(zhǔn)確率正確意圖數(shù) / 總樣本數(shù)95% 以上槽位精確率正確槽位數(shù) / 預(yù)測(cè)槽位數(shù)90% 以上槽位召回率正確槽位數(shù) / 標(biāo)注槽位數(shù)90% 以上任務(wù)完成率多輪內(nèi)成功下單比例85% 以上線上系統(tǒng)需要采樣回流通道把每一輪的模型輸出、用戶反饋、是否人工介入都落到日志表。每周抽取一批失敗樣本人工標(biāo)注后加入評(píng)測(cè)集。填槽這類自然語(yǔ)言模塊最怕的不是初始效果差而是沒有人持續(xù)喂養(yǎng)和驗(yàn)證。6. 實(shí)測(cè)中那些文檔不會(huì)寫的事6.1 溫度與隨機(jī)性同樣的輸入可能給出不同結(jié)果即使把 temperature 設(shè)成 0大模型的輸出也不是嚴(yán)格確定的尤其在長(zhǎng) Prompt 或者函數(shù)定義復(fù)雜的時(shí)候。實(shí)測(cè)里我發(fā)現(xiàn)同樣的用戶輸入在一天之內(nèi)可能返回兩種不同的日期格式或者把同一個(gè)歧義表達(dá)判定成不同意圖。為了應(yīng)對(duì)這種不穩(wěn)定性關(guān)鍵場(chǎng)景我會(huì)對(duì)低置信度請(qǐng)求做兩次調(diào)用取多數(shù)結(jié)果但成本會(huì)翻倍。折中辦法是只對(duì)低置信度的請(qǐng)求做二次采樣其他請(qǐng)求直接走單次輸出。6.2 候選集約束是個(gè)工程活給模型塞候選列表要分層次。一個(gè)城市有幾百家影城全塞進(jìn) Prompt 會(huì)稀釋模型對(duì)槽位本身的注意力也會(huì)讓 token 成本飆升。我的做法是讓模型先填城市和影院名稱外層再用模糊匹配對(duì)齊到數(shù)據(jù)庫(kù)里的標(biāo)準(zhǔn) ID只有候選數(shù)量在幾十個(gè)以內(nèi)時(shí)才直接把列表放進(jìn) Prompt 讓模型選。這個(gè)取舍處理不好后面會(huì)出現(xiàn)模型輸出聽都沒聽過的影院名校驗(yàn)邏輯只能干瞪眼。6.3 從填槽到真正理解意圖的下一步最后說(shuō)一點(diǎn)個(gè)人體會(huì)。LLM 填槽做得再好也只是整個(gè)對(duì)話智能里理解入口的一環(huán)真正決定用戶體驗(yàn)的是理解之后怎么行動(dòng)。你往往還要接庫(kù)存查詢、支付、訂單狀態(tài)同步甚至跨系統(tǒng)調(diào)用。這時(shí)候不要讓大模型直接操盤所有邏輯而是讓它輸出去驅(qū)動(dòng)你寫好的確定性流程。模型負(fù)責(zé)把用戶意圖翻譯成結(jié)構(gòu)業(yè)務(wù)規(guī)則負(fù)責(zé)把結(jié)構(gòu)變成行動(dòng)各管一層出了問題也更容易定位。如果讓我給準(zhǔn)備開始做這件事的人一句建議我會(huì)說(shuō)別把 LLM 當(dāng)成一個(gè)會(huì)說(shuō)話的大腦把它當(dāng)成一個(gè)偶爾走神但大部分時(shí)候很聰明的翻譯官。你在它周圍做的每一道約束、校驗(yàn)、狀態(tài)管理才是系統(tǒng)真正靠得住的根基。