欄與信息保真實(shí)踐)
你有沒有遇到過這種情況讓大模型幫你把一段需求“潤(rùn)色得更專業(yè)”結(jié)果它把關(guān)鍵數(shù)字改了讓它在多輪對(duì)話里整理會(huì)議紀(jì)要幾十條結(jié)論最后只剩下一個(gè)大概方向更危險(xiǎn)的是當(dāng)你用 Agent 串聯(lián)多個(gè)模型節(jié)點(diǎn)時(shí)最開始的原始指令經(jīng)過幾層傳遞后已經(jīng)面目全非。這就像小時(shí)候玩的“傳話游戲”——一句話從第一個(gè)人傳到第十個(gè)人意思早就跑偏了。LLM 雖然是目前最聰明的文本生成工具但它本質(zhì)上是一個(gè)基于概率的續(xù)寫模型而不是一個(gè)可靠的信息存儲(chǔ)介質(zhì)。當(dāng)它在“傳遞”你的想法時(shí)如果沒有任何保護(hù)措施信息就會(huì)像傳話游戲一樣逐級(jí)失真而且這種失真往往不容易被發(fā)現(xiàn)直到產(chǎn)品上線或代碼部署后才暴露出問題。本文要討論的不是“怎么讓 LLM 更聰明”而是一個(gè)更基礎(chǔ)的工程問題如何防止 LLM 在理解、改寫、轉(zhuǎn)述、執(zhí)行你原始想法的時(shí)候“添油加醋”或“丟三落四”。我會(huì)從 LLM 產(chǎn)生信息失真的根源出發(fā)給出六道工程護(hù)欄設(shè)計(jì)并用 Python 代碼演示如何建立一個(gè)“信息保真測(cè)試臺(tái)”最后討論 Agent 鏈路、數(shù)據(jù)標(biāo)注和本地模型場(chǎng)景下的防失真方案。1. 為什么 LLM 會(huì)“傳話失真”而且這個(gè)坑比想象中更嚴(yán)重1.1 傳話游戲的本質(zhì)是概率重建傳話游戲之所以失真是因?yàn)槊總€(gè)傳話人并不是逐字背誦而是先理解、再記憶、最后用自己的語(yǔ)言復(fù)述。人在這個(gè)過程中會(huì)丟失細(xì)節(jié)、腦補(bǔ)缺失、傾向簡(jiǎn)化。LLM 的工作方式與此高度相似它會(huì)把輸入文本切分成 token然后根據(jù)上下文計(jì)算下一個(gè) token 的概率分布再逐個(gè) token 地生成回復(fù)。這個(gè)過程本質(zhì)上是“在不完全理解的情況下基于概率重建語(yǔ)義”。更麻煩的是LLM 的生成帶有一個(gè)關(guān)鍵特性它永遠(yuǎn)傾向于生成“合理的”內(nèi)容而不是“完全等于輸入”的內(nèi)容。當(dāng)你的原始信息不夠明確、存在歧義或是在多輪對(duì)話中被更晚的指令覆蓋模型就會(huì)自行“腦補(bǔ)”最合理的解釋。這個(gè)“腦補(bǔ)”在大多數(shù)文本生成任務(wù)中是優(yōu)點(diǎn)但在需要忠實(shí)傳達(dá)意圖時(shí)就是災(zāi)難。1.2 信息保真度一個(gè)沒有被足夠重視的指標(biāo)我們平時(shí)評(píng)價(jià) LLM 輸出時(shí)最關(guān)注的是流暢度、相關(guān)性、準(zhǔn)確性卻很少關(guān)注“信息保真度”——也就是模型輸出相對(duì)原始輸入有多少關(guān)鍵信息被保留、多少被篡改、多少被新增。準(zhǔn)確性和保真度不是一回事。一個(gè)句子可能語(yǔ)法正確、通順流暢但其中最關(guān)鍵的時(shí)間、數(shù)字、人名、業(yè)務(wù)規(guī)則已經(jīng)被悄悄改掉。比如下面這句話原意本次上線時(shí)間為 2026-03-15目標(biāo)用戶是企業(yè)級(jí)客戶付費(fèi)方式為年付。模型改寫后可能是“為了盡快推向市場(chǎng)初步計(jì)劃在2026年3月中旬左右主要面向大型企業(yè)客戶采用按年訂閱的收費(fèi)模式。”乍一看沒問題甚至更“專業(yè)”了。但“2026-03-15”變成了“2026年3月中旬左右”精確日期變成了模糊日期“企業(yè)級(jí)客戶”變成了“大型企業(yè)客戶”也許業(yè)務(wù)上就有嚴(yán)格區(qū)分“年付”變成了“按年訂閱”也可能改變了產(chǎn)品定價(jià)語(yǔ)義。如果下游直接使用這段文本信息就已經(jīng)失真了。1.3 失真會(huì)怎么擴(kuò)散單個(gè)模型輸出失真還可以通過人工 review 發(fā)現(xiàn)但如果你的流程是“用戶需求 - LLM 總結(jié) - LLM 生成 PRD - LLM 生成任務(wù)清單 - LLM 寫代碼注釋”那么每一級(jí)都可能丟失一部分信息。失真的誤差是累積的而不是簡(jiǎn)單的加減法。最終產(chǎn)品經(jīng)理發(fā)現(xiàn)需求不對(duì)開發(fā)發(fā)現(xiàn)注釋誤導(dǎo)測(cè)試發(fā)現(xiàn)用例沒覆蓋關(guān)鍵業(yè)務(wù)規(guī)則問題已經(jīng)很難追溯到源頭。所以我們真正需要的是一套系統(tǒng)性的防失真工程方法而不是依賴某一次“運(yùn)氣好的生成”。2. 最容易出問題的四類“傳話鏈”在實(shí)際開發(fā)和內(nèi)容生成場(chǎng)景中有四條最典型的“傳話鏈”幾乎每個(gè)用過 LLM 的人都可能踩過坑。2.1 自然語(yǔ)言需求被“潤(rùn)色”成另一種含義這是最常見的場(chǎng)景。你讓 LLM 寫一封郵件、寫一段周報(bào)、寫一個(gè) PRD模型默認(rèn)會(huì)進(jìn)行語(yǔ)言層面的“優(yōu)化”。優(yōu)化過程中它可能調(diào)整句子結(jié)構(gòu)、替換同義詞、補(bǔ)充解釋甚至是刪除它認(rèn)為不重要的細(xì)節(jié)。但如果原始信息是業(yè)務(wù)約束模型根本無(wú)法判斷哪些重要哪些不重要。預(yù)防思路在提示詞中明確區(qū)分“不可變字段”和“可加工字段”并讓模型輸出結(jié)構(gòu)化內(nèi)容而不是一段自由文本。2.2 多輪對(duì)話中的上下文覆蓋多輪對(duì)話中LLM 需要同時(shí)記住系統(tǒng)提示詞、歷史消息、用戶最新消息。但模型對(duì)上下文的注意力并不是均勻的最新消息通常權(quán)重更高早期消息容易被“遺忘”或忽略。當(dāng)你先說了 A 需求又說了 B 需求模型很可能會(huì)用 B 的表述覆蓋 A 的細(xì)節(jié)。比如你第一輪說“必須支持手機(jī)號(hào)登錄”第二輪說“順便支持郵箱登錄”模型可能在最終輸出里把“必須”降級(jí)為“建議”或者直接丟失“手機(jī)號(hào)”這個(gè)詞。這就是典型的上下文覆蓋導(dǎo)致的信息失真。預(yù)防思路不要依賴模型的“記憶”把每次請(qǐng)求都當(dāng)作無(wú)狀態(tài)調(diào)用來(lái)設(shè)計(jì)。原始約束要重復(fù)出現(xiàn)在 system prompt 和關(guān)鍵位置。2.3 Agent 多節(jié)點(diǎn)傳遞當(dāng)你使用 Agent 架構(gòu)時(shí)一條指令往往會(huì)經(jīng)過 planner規(guī)劃器、executor執(zhí)行器、writer總結(jié)器等多個(gè)模型節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)都會(huì)對(duì)輸入做一次“理解-重寫”。哪怕每個(gè)節(jié)點(diǎn)只產(chǎn)生 5% 的信息損失經(jīng)過 5 個(gè)節(jié)點(diǎn)后關(guān)鍵細(xì)節(jié)可能已經(jīng)丟失 20% 以上。更危險(xiǎn)的是很多 Agent 框架內(nèi)部只用字符串拼接消息你無(wú)法直觀看到中間每一個(gè)節(jié)點(diǎn)到底修改了什么。等到最終結(jié)果出錯(cuò)你根本不知道問題出在哪個(gè)環(huán)節(jié)。預(yù)防思路在每個(gè)節(jié)點(diǎn)都保留“原始輸入?yún)^(qū)塊”并讓最終輸出引用原始輸入中的關(guān)鍵字段同時(shí)記錄完整鏈路日志。2.4 文本與代碼互轉(zhuǎn)代碼注釋、接口文檔、字段命名、數(shù)據(jù)契約之間互相轉(zhuǎn)換時(shí)非常容易失真。例如模型把“訂單狀態(tài)從待支付改為已支付”翻譯成英文注釋可能會(huì)寫成“Order status changes from pending to paid”看起來(lái)正確但后續(xù)再轉(zhuǎn)回中文時(shí)可能就變成“訂單狀態(tài)從待付款改為已付款”而你的業(yè)務(wù)系統(tǒng)里“待支付”和“待付款”是同一個(gè)字段嗎不見得。另一個(gè)典型場(chǎng)景是讓 LLM 根據(jù)數(shù)據(jù)庫(kù)字段生成文檔它很可能把枚舉值匯總錯(cuò)或者漏掉某個(gè)重要約束。因此凡是文本和代碼之間存在“語(yǔ)義映射”就必須手工校驗(yàn)關(guān)鍵映射關(guān)系不能用 LLM 的輸出直接替代人工核對(duì)。3. 防止失真的核心設(shè)計(jì)六道護(hù)欄要想不讓 LLM 變成傳話游戲的參與者我們必須把它當(dāng)成一個(gè)“不可靠組件”來(lái)對(duì)待。在構(gòu)建可靠 AI 系統(tǒng)的工程實(shí)踐中防止信息失真的要義不是提高模型智商而是設(shè)計(jì)一套從輸入到輸出的護(hù)欄讓失真無(wú)處可逃。我把它整理為六道護(hù)欄可以直接用在你的 LLM 應(yīng)用和 Agent 架構(gòu)中。3.1 意圖鎖定區(qū)分“不可變字段”和“可加工字段”這是第一道護(hù)欄也是最容易被忽略的。很多人在寫提示詞時(shí)只會(huì)說“幫我潤(rùn)色這段話”但模型并不知道哪些信息是事實(shí)核心、哪些是表達(dá)方式。你應(yīng)該在提示詞里明確列出不可變字段并告訴模型這些字段一旦改變?nèi)蝿?wù)失敗。推薦的做法是在系統(tǒng)提示詞中加入一個(gè)“硬約束區(qū)塊”用 XML 或 JSON 分隔符鎖住關(guān)鍵信息例如hard_constraints launch_date2026-03-15 target_userenterprise_customer pay_typeyearly /hard_constraints然后要求模型輸出時(shí)先原樣復(fù)述這些字段再做文字加工。這一步雖然簡(jiǎn)單但能顯著降低信息丟失風(fēng)險(xiǎn)。3.2 上下文隔離原始資料只讀模型不寫不回寫在多輪對(duì)話和 Agent 鏈路中不要隨意把模型生成的中間結(jié)果當(dāng)作下一輪的“事實(shí)基礎(chǔ)”。更安全的做法是原始資料庫(kù)單獨(dú)存放每一輪生成時(shí)都從原始資料庫(kù)加載最新源頭而不是從上一輪輸出中取。也就是說系統(tǒng)要有明確的“源數(shù)據(jù)層”和“生成數(shù)據(jù)層”。模型只負(fù)責(zé)讀源數(shù)據(jù)、生成加工數(shù)據(jù)絕不直接擴(kuò)大源數(shù)據(jù)范圍。誰(shuí)要是讓模型把上一次生成的總結(jié)再作為原始輸入就等于主動(dòng)開啟了傳話游戲。3.3 結(jié)構(gòu)化約束用 JSON Schema 或枚舉鎖死關(guān)鍵字段自由文本是最難校驗(yàn)的。它沒有邊界無(wú)法自動(dòng)比對(duì)。如果你希望 LLM 輸出可靠、可驗(yàn)證的內(nèi)容就一定要用結(jié)構(gòu)化輸出。你可以通過 function calling、JSON mode 或 Pydantic 定義字段類型和枚舉值把模型的行為限制在一個(gè)固定的 schema 內(nèi)。例如“付費(fèi)方式”只能取月付/年付/一次性三個(gè)枚舉值之一而不是讓模型自由發(fā)揮成“按年訂閱”“按年度收費(fèi)”“年繳”等等各種表達(dá)。結(jié)構(gòu)化約束讓校驗(yàn)從“語(yǔ)義模糊比對(duì)”變成“字段級(jí)精確比對(duì)”失真概率大幅下降。3.4 輸出校驗(yàn)跑完就檢查不等事后追責(zé)每次拿到 LLM 輸出后立即用一段規(guī)則腳本檢查關(guān)鍵信息是否仍然存在。這一步不需要多么智能最簡(jiǎn)單的字符串包含、正則匹配、數(shù)據(jù)庫(kù)查詢就可以解決 80% 的問題。例如原文中有日期、金額、用戶ID輸出中必須包含這些字段的精確值。一旦校驗(yàn)失敗馬上重新生成或丟棄輸出而不是繼續(xù)往下游走。如果你處理的是復(fù)雜長(zhǎng)文本可以借助相似度算法如 partial ratio或嵌入向量相似度做參考但要記住相似度只是輔助關(guān)鍵還是要做“實(shí)體級(jí)”和“字段級(jí)”的硬校驗(yàn)。3.5 鏈路審計(jì)每次轉(zhuǎn)換都保存“輸入-輸出”映射無(wú)論任務(wù)大小都應(yīng)該保留一條可復(fù)現(xiàn)的審計(jì)鏈原始輸入是什么、提示詞是什么、模型版本是什么、輸出是什么、校驗(yàn)結(jié)果是什么。這樣一旦最終結(jié)果出現(xiàn)問題你可以沿著審計(jì)鏈回溯到出錯(cuò)節(jié)點(diǎn)。在 Agent 系統(tǒng)中這一點(diǎn)尤其重要。不要只記錄最終結(jié)果而要記錄每個(gè)中間節(jié)點(diǎn)收到什么提示詞、輸出什么內(nèi)容、修改了原始信息的哪個(gè)部分。缺少這個(gè)審計(jì)鏈排查傳話失真就像大海撈針。3.6 人工復(fù)核把人的審批放在風(fēng)險(xiǎn)點(diǎn)對(duì)業(yè)務(wù)影響重大的輸出必須在關(guān)鍵節(jié)點(diǎn)加入人審。不是所有內(nèi)容都要人看而是說“不可變字段是否被改動(dòng)”這個(gè)問題必須由人確認(rèn)一次。比如合同條款生成、數(shù)據(jù)庫(kù)變更腳本生成、對(duì)外發(fā)布文案生成都應(yīng)該設(shè)計(jì)一個(gè)“草稿-人類審批-生效”的環(huán)節(jié)而不是 LLM 輸出后直接使用。人審的重點(diǎn)是檢查原始意圖是否被忠實(shí)保留其次才是文字是否流暢。如果人審環(huán)節(jié)成本過高就通過 3.3/3.4 的自動(dòng)校驗(yàn)先把問題篩掉大部分人工只看高風(fēng)險(xiǎn)樣本。4. 環(huán)境準(zhǔn)備與基礎(chǔ)代碼構(gòu)建一個(gè)最小“保真測(cè)試臺(tái)”在進(jìn)入完整架構(gòu)前我們先來(lái)做一個(gè)能落地的實(shí)驗(yàn)用 Python 調(diào)用任意 LLM API寫一個(gè)“保真測(cè)試臺(tái)”檢測(cè)模型在改寫一句話時(shí)是否篡改了關(guān)鍵信息。你不需要復(fù)雜框架只需要一個(gè) API 和一個(gè)文本相似度庫(kù)。4.1 環(huán)境準(zhǔn)備本示例使用 Python 3.10調(diào)用 OpenAI 兼容的 API。如果你使用的是 DeepSeek、通義千問、Ollama 本地模型只需修改base_url和model參數(shù)即可。演示中使用openaiSDK 和rapidfuzz文本相似度庫(kù)。pip install openai rapidfuzz pydantic在項(xiàng)目根目錄創(chuàng)建.env文件或在命令行中設(shè)置環(huán)境變量export OPENAI_API_KEY你的API密鑰如果你用本地模型比如通過 Ollama 啟動(dòng) GGUF 模型可以這樣配置客戶端client OpenAI( base_urlhttp://localhost:11434/v1, api_keyollama # 本地服務(wù)一般為任意占位符 )4.2 最小保真測(cè)試腳本新建verify_fidelity.py文件內(nèi)容如下# verify_fidelity.py import os from openai import OpenAI from rapidfuzz import fuzz client OpenAI( api_keyos.environ.get(OPENAI_API_KEY), ) def ask_llm(prompt: str) - str: resp client.chat.completions.create( modelgpt-4o-mini, # 實(shí)際使用時(shí)替換為你的模型名 temperature0, # 降低隨機(jī)性提高可復(fù)現(xiàn)性 messages[ { role: system, content: 你是一名嚴(yán)謹(jǐn)?shù)奈淖志庉嫛D愕娜蝿?wù)是在不改變?nèi)魏问聦?shí)信息的前提下幫助用戶潤(rùn)色文字。, }, {role: user, content: prompt}, ], ) return resp.choices[0].message.content.strip() if __name__ __main__: # 原始信息關(guān)鍵字段包括日期、用戶類型、付費(fèi)方式 original 本次上線時(shí)間為 2026-03-15目標(biāo)用戶是企業(yè)級(jí)客戶付費(fèi)方式為年付。 prompt f請(qǐng)將下面這句話改寫為更正式的版本。 要求 - 必須保留以下關(guān)鍵字段的原始值不得改寫 1. 上線時(shí)間 2. 目標(biāo)用戶 3. 付費(fèi)方式 - 不得增補(bǔ)原文沒有的信息比如具體產(chǎn)品名稱、部門、日期解釋。 原文如下 {cases_original} 輸出要求 先用“【無(wú)害潤(rùn)色】”輸出潤(rùn)色后的文本再用“【關(guān)鍵字段核對(duì)】”逐項(xiàng)列出你保留的關(guān)鍵字段。 result ask_llm(prompt) print(模型輸出) print(result) print(\n關(guān)鍵字段相似度檢查) # 用 partial_ratio 檢查關(guān)鍵字段是否出現(xiàn)在輸出中 for field in [2026-03-15, 企業(yè)級(jí)客戶, 年付]: score fuzz.partial_ratio(field, result) print(f{field}: {score}) if score 85: print(f - 警告{field} 疑似被改動(dòng)或丟失)這段代碼做的事情非常直白把一段包含明確事實(shí)的文本丟給 LLM要求它做“無(wú)害潤(rùn)色”然后檢查三個(gè)關(guān)鍵字段在輸出中是否仍然存在。partial_ratio的值越高說明字段保留得越完整低于 85 分就需要警惕。4.3 為什么設(shè)置 temperature0把 temperature 設(shè)為 0能讓模型在同樣的輸入下盡量輸出穩(wěn)定的結(jié)果降低“隨機(jī)性失真”。但要明白temperature0 并不等于確定性保證。模型仍然可能因?yàn)?prompt 措辭不同而產(chǎn)生不同的輸出。所以代碼中的校驗(yàn)環(huán)節(jié)永遠(yuǎn)不能省。5. 進(jìn)階方案用結(jié)構(gòu)化輸出“鎖死”關(guān)鍵字段單純?cè)谔崾驹~里說“請(qǐng)保留字段”還不夠可靠尤其當(dāng)你接入的開源小模型或本地 GGUF 模型遵循指令能力不強(qiáng)時(shí)它很容易忽略你的約束。更穩(wěn)妥的做法是讓模型輸出結(jié)構(gòu)化 JSON并且用 Pydantic 模型在代碼層面對(duì)關(guān)鍵字段進(jìn)行強(qiáng)校驗(yàn)。5.1 定義 Pydantic 輸出模型新建schemas.py# schemas.py from pydantic import BaseModel, validator from enum import Enum from datetime import date class PayType(str, Enum): MONTHLY 月付 YEARLY 年付 ONCE 一次性 class ReleasePlan(BaseModel): launch_date: date target_user: str pay_type: PayType validator(target_user) def target_user_not_blank(cls, v): if not v.strip(): raise ValueError(target_user 不能為空) return v這里的關(guān)鍵在于pay_type是枚舉類型。模型如果試圖輸出“年度訂閱”Pydantic 會(huì)直接拋錯(cuò)而不是悄悄接受一個(gè)近似值。5.2 使用 JSON 輸出模式強(qiáng)制結(jié)構(gòu)化在你的業(yè)務(wù)代碼中可以通過 response_format 或 function calling 讓模型輸出符合 schema 的 JSON。以 OpenAI 風(fēng)格 API 為例# extract_plan.py import os, json from openai import OpenAI from schemas import ReleasePlan client OpenAI(api_keyos.environ.get(OPENAI_API_KEY)) def extract_plan(text: str) - ReleasePlan: resp client.chat.completions.create( modelgpt-4o-mini, # 按需替換 response_format{type: json_object}, messages[ { role: system, content: 你是信息抽取器。只輸出 JSON 對(duì)象不要輸出任何解釋性文字。字段必須符合給定 schema。, }, { role: user, content: ( 從以下文本中抽取上線時(shí)間、目標(biāo)用戶、付費(fèi)方式。\n f文本{text}\n 輸出 JSON 字段{launch_date: 2026-03-15, target_user: ..., pay_type: 月付/年付/一次性} ), }, ], temperature0, ) content resp.choices[0].message.content data json.loads(content) return ReleasePlan.model_validate(data) if __name__ __main__: sample_text 我們計(jì)劃2026年3月15日發(fā)布主要面向企業(yè)級(jí)客戶采用年費(fèi)訂閱方式。 try: plan extract_plan(sample_text) print(plan) except Exception as e: print(結(jié)構(gòu)化校驗(yàn)失敗, e)如果模型把“年費(fèi)訂閱”理解成年付Pydantic 校驗(yàn)會(huì)通過如果它理解成“年費(fèi)訂閱”由于不是枚舉值程序會(huì)拋錯(cuò)。這時(shí)你應(yīng)該意識(shí)到要么是 prompt 示例不夠清晰要么是當(dāng)前模型無(wú)法區(qū)分“年付”和“訂閱”。無(wú)論如何錯(cuò)誤會(huì)被提前攔截而不是流向下游。5.3 對(duì)“無(wú)效枚舉”的處理策略不要簡(jiǎn)單地把校驗(yàn)失敗當(dāng)作“系統(tǒng)故障”。在很多真實(shí)項(xiàng)目中模型輸出枚舉值非法往往意味著你的原始需求存在模糊地帶。比如“年付”和“年度訂閱”在業(yè)務(wù)上可能確實(shí)不同。此時(shí)應(yīng)該讓校驗(yàn)失敗回流到“人工作業(yè)隊(duì)列”由人工確認(rèn)語(yǔ)義后更新詞表或映射規(guī)則。這就把一次模型錯(cuò)誤變成了一次知識(shí)沉淀。6. Agent 鏈路中的“防傳話”模式Agent 是目前大模型應(yīng)用中最容易出現(xiàn)傳話失真的架構(gòu)。一個(gè)簡(jiǎn)單的多節(jié)點(diǎn)鏈路可能是主任務(wù) - 規(guī)劃節(jié)點(diǎn) - 工具調(diào)用 - 匯總節(jié)點(diǎn) - 最終輸出每個(gè)節(jié)點(diǎn)都是獨(dú)立的 LLM 調(diào)用。更嚴(yán)重的是很多 Agent 框架會(huì)主動(dòng)對(duì)輸入做“精簡(jiǎn)歷史消息”例如只保留最后一輪結(jié)果把更早的原始需求丟棄掉。這會(huì)讓傳話失真變成不可逆的。6.1 主任務(wù)原文隨行防傳話的第一原則是主任務(wù)原文必須隨每個(gè)子節(jié)點(diǎn)的消息一起傳遞而不是只傳遞上游輸出。也就是說不論 Agent 中間做了多少步每個(gè) LLM 節(jié)點(diǎn)的 prompt 中都要有一塊“主任務(wù)原文區(qū)塊”。Python 偽代碼如下# agent_fidelity.py def run_agent_step(task_original: str, step_prompt: str, model) - str: task_original: 主任務(wù)原文永遠(yuǎn)不允許被改寫 step_prompt: 針對(duì)當(dāng)前節(jié)點(diǎn)的具體指令 prompt f 【主任務(wù)原文不可修改僅供理解和校驗(yàn)】 {task_original} 【當(dāng)前節(jié)點(diǎn)指令】 {step_prompt} 請(qǐng)基于主任務(wù)執(zhí)行當(dāng)前指令。在最終輸出中必須引用主任務(wù)原文中的關(guān)鍵字段不得自行替換。 output model.generate(prompt) # 弱校驗(yàn)主任務(wù)中的關(guān)鍵命令詞是否仍然出現(xiàn)在輸出中 assert_fidelity(task_original, output) return outputassert_fidelity可以是一個(gè)自定義函數(shù)用來(lái)檢查主任務(wù)原文中的日期、編號(hào)、命令動(dòng)詞等是否仍然存在于輸出中。雖然稍顯粗糙但在多數(shù)場(chǎng)景下能攔住“關(guān)鍵字段丟失”問題。6.2 鏈路審計(jì)日志在 Agent 架構(gòu)中務(wù)必為每個(gè)節(jié)點(diǎn)生成一條日志記錄至少包含四樣?xùn)|西節(jié)點(diǎn)名稱和模型名稱輸入 prompt含主任務(wù)原文字段模型原始輸出校驗(yàn)結(jié)果哪些字段通過哪些字段丟失這些日志可以用 JSON Lines 格式寫入本地或日志平臺(tái)。下面是一條示例日志結(jié)構(gòu){ step: planner, model: qwen-plus, prompt_hash: sha256:..., task_original_hash: sha256:..., output: ...節(jié)點(diǎn)輸出..., fidelity_check: { required_fields: [launch_date, target_user], missing_fields: [], passed: true } }當(dāng)你發(fā)現(xiàn)最終結(jié)果不對(duì)時(shí)按prompt_hash或task_original_hash搜索日志就能定位到第一個(gè)“missing_fields”不為空的節(jié)點(diǎn)。6.3 長(zhǎng)任務(wù)的“斷點(diǎn)續(xù)傳”意識(shí)如果你的 Agent 鏈路特別長(zhǎng)上下文很容易超限。有些框架會(huì)自動(dòng)截?cái)嘣缙谙⒁浅P⌒?。建議把“主任務(wù)原文”“當(dāng)前步驟輸入”“最近一輪輸出”拆成三個(gè)獨(dú)立區(qū)域而不是把所有歷史消息都塞給模型。主任務(wù)原文永遠(yuǎn)處于最高優(yōu)先級(jí)的區(qū)域即使上下文超限也不能先刪它??梢詢?yōu)先壓縮歷史對(duì)話摘要但不能壓縮原始需求本身。7. 驗(yàn)證與排查如何量化“想法變沒變”有了代碼和鏈路設(shè)計(jì)我們必須有一套驗(yàn)證方法來(lái)判斷一個(gè) LLM 任務(wù)是否遵循了“保真”要求。這套方法不需要高大上但要在工程中持續(xù)執(zhí)行。7.1 用字段級(jí)覆蓋檢查替代“讀一遍”對(duì)于結(jié)構(gòu)化任務(wù)把關(guān)鍵字段列出來(lái)逐項(xiàng)檢查輸出中是否存在。以下表格演示了一個(gè)簡(jiǎn)單的檢查規(guī)則關(guān)鍵字段原始值輸出中是否存在判定標(biāo)準(zhǔn)上線時(shí)間2026-03-15是精確匹配2026-03-15或日期規(guī)范化后相同目標(biāo)用戶企業(yè)級(jí)客戶是允許同義改寫默認(rèn)不允許付費(fèi)方式年付否輸出里寫成了“按年訂閱”需要在業(yè)務(wù)詞表中匹配項(xiàng)目名稱Alpha是精確匹配Alpha如果某個(gè)字段輸出中不存在或者只存在一個(gè)模糊近似就要重新生成或觸發(fā)人工復(fù)核。7.2 相似度評(píng)分只是一個(gè)參考partial_ratio可以輔助判斷字段是否完整保留但它無(wú)法識(shí)別“日期變化但語(yǔ)義相近”的情況也無(wú)法識(shí)別“完全新增了一段無(wú)關(guān)內(nèi)容”。例如原詞企業(yè)級(jí)客戶輸出大型企業(yè) 客戶partial_ratio得分可能很高但從業(yè)務(wù)上“企業(yè)級(jí)”不等于“大型”。因此相似度評(píng)分只是過濾工具不是最終裁判。真正可靠的是 3.3 結(jié)構(gòu)化約束 3.4 輸出校驗(yàn)的組合。7.3 常見問題與排查思路以下表格整理了五類典型的傳話失真問題及排查方法問題現(xiàn)象可能原因排查方式解決方案輸出把“2026-03-15”改成“2026年3月中旬”模型認(rèn)為自然語(yǔ)言表達(dá)更流暢主動(dòng)做語(yǔ)義泛化用正則提取日期字段檢查是否精確匹配在 prompt 中把日期列為 hard_constraints或使用結(jié)構(gòu)化輸出多輪對(duì)話后丟失最初的約束上下文過長(zhǎng)早期消息被截?cái)嗷蜃⒁饬?quán)重下降檢查實(shí)際請(qǐng)求中是否仍包含最初的 system prompt打印 prompt 日志壓縮內(nèi)容時(shí)保留主任務(wù)原文區(qū)塊使用無(wú)狀態(tài)請(qǐng)求Agent 最終結(jié)果里出現(xiàn)了原始輸入完全沒有的“細(xì)節(jié)”模型出現(xiàn)幻覺式補(bǔ)全通常是能力不足或 prompt 引導(dǎo)過度對(duì)比最終結(jié)果與原文的實(shí)體集合查找“新增實(shí)體”在 system prompt 中禁止補(bǔ)全尚未出現(xiàn)的信息必要時(shí)用更小的任務(wù)粒度模型把“年付”改成“年訂閱”導(dǎo)致下游判定失敗枚舉值沒有被嚴(yán)格約束查看輸出 JSON 中 pay_type 字段值使用 Pydantic 枚舉類型或 function calling非法值直接報(bào)錯(cuò)本地小模型如 7B GGUF發(fā)生失真小模型指令跟隨能力弱用同一個(gè) prompt 測(cè)試開源模型和商業(yè) API 的差異降低 temperature、增加 few-shot 示例、拆分短任務(wù)或選用更強(qiáng)模型8. 工程最佳實(shí)踐與落地建議構(gòu)建可靠 AI 系統(tǒng)并不是買一個(gè)更強(qiáng)的大模型就一勞永逸。從“防止 LLM 傳話失真”這個(gè)具體問題出發(fā)我建議你在自己的項(xiàng)目里落地以下幾項(xiàng)工程實(shí)踐。8.1 建立原始需求臺(tái)賬不要把原始需求散落在對(duì)話歷史、群聊記錄或臨時(shí)文檔里。建立一個(gè)單獨(dú)的、版本化的原始需求庫(kù)每次 LLM 調(diào)用都要引用這個(gè)庫(kù)里的內(nèi)容。你可以放在 Git 倉(cāng)庫(kù)、數(shù)據(jù)庫(kù)或內(nèi)容管理系統(tǒng)中。原始需求一旦變化通過版本號(hào)管理而不是讓模型“憑記憶”自適應(yīng)。8.2 受控詞表常態(tài)化把業(yè)務(wù)中經(jīng)常被模型改寫的術(shù)語(yǔ)維護(hù)為一套“受控詞表”。比如簽約方式、訂單狀態(tài)、客戶等級(jí)、日期格式。在 prompt 中把受控詞表明確列出來(lái)并讓模型只能使用表中詞語(yǔ)。詞表本身也要定期更新每次模型輸出中出現(xiàn)詞表之外的相似表達(dá)都記錄下來(lái)并決定是否加入詞表。8.3 輸出差異留痕不要讓 LLM 輸出直接覆蓋原始文件。要求模型生成一個(gè)“diff”或至少生成一個(gè)“修改說明”。在文本類任務(wù)中你可以用difflib對(duì)比原始文本和輸出文本在代碼類任務(wù)中使用 Git diff。這樣任何改動(dòng)都是可審計(jì)的。8.4 回歸測(cè)試集為每一類高風(fēng)險(xiǎn)任務(wù)準(zhǔn)備 20~50 個(gè)“保真測(cè)試用例”每個(gè)用例包含原始信息、期望保留字段、允許改寫字段。每當(dāng)你更換模型版本、修改 prompt 模板或接入新的 Agent 節(jié)點(diǎn)就跑一遍回歸測(cè)試觀察關(guān)鍵字段保留率是否有下降。這套測(cè)試集才是防止傳話失真長(zhǎng)期有效的關(guān)鍵。8.5 人在回路的設(shè)置時(shí)機(jī)不要讓人工審批淹沒在全部流程中應(yīng)該只在高風(fēng)險(xiǎn)輸出點(diǎn)設(shè)置。例如修改數(shù)據(jù)庫(kù)變更腳本時(shí)生成對(duì)外發(fā)布文案時(shí)翻譯合同、法務(wù)文件時(shí)Agent 自動(dòng)修改代碼且影響范圍較大時(shí)對(duì)于低風(fēng)險(xiǎn)任務(wù)比如轉(zhuǎn)換文章語(yǔ)氣、生成周報(bào)草稿可以全自動(dòng)但仍要保留自動(dòng)校驗(yàn)日志以便事后抽查。9. 總結(jié)與后續(xù)學(xué)習(xí)方向回到標(biāo)題“Dont Let LLMs Play Telephone with Your Ideas”。這句話不是一句口號(hào)而是一條工程紀(jì)律。LLM 是概率生成器不是可靠的信息信道。你發(fā)給它的每一句話都有可能在某一個(gè)角落被微妙地改寫。如果我們能在架構(gòu)上把“原始意圖”隔離出來(lái)、用結(jié)構(gòu)化約束固定關(guān)鍵字段、用校驗(yàn)?zāi)_本即時(shí)發(fā)現(xiàn)問題、用審計(jì)日志定位節(jié)點(diǎn)、用人工復(fù)核守住最后關(guān)口那么 LLM 就不會(huì)變成傳話游戲里那個(gè)越傳越歪的傳聲筒而更像是一個(gè)表達(dá)能力極強(qiáng)但必須被管理的執(zhí)行器。下一步值得深入的方向包括基于事實(shí)核對(duì)fact verification的方法來(lái)檢測(cè)模型輸出與原文的矛盾利用知識(shí)圖譜約束生成讓實(shí)體之間的關(guān)系可驗(yàn)證以及針對(duì)更多開源小模型設(shè)計(jì)輕量化的保真率評(píng)測(cè)方案。如果你正在做 LLM 應(yīng)用、Agent 或內(nèi)容自動(dòng)化項(xiàng)目建議先從文中最小的“保真測(cè)試臺(tái)”開始挑一條容易出錯(cuò)的原始需求跑一遍腳本看看模型有沒有真的弄丟你的想法。如果它丟了你就知道為什么需要護(hù)欄了。