化實戰(zhàn))
先從一起賬單異常說起。有一個功能上線兩周日活用戶幾乎沒有波動可費用賬單莫名其妙翻了快一倍。我最初的直覺是哪里出現(xiàn)了調(diào)用泄露或者有人掃了接口地址在做批量請求結(jié)果查了一圈日志發(fā)現(xiàn)調(diào)用量只漲了百分之十幾。真正的問題出在我自己寫的 Prompt 上——前一天下午我把系統(tǒng)提示詞從原來的三百多個字“優(yōu)化”成了滿滿兩頁的結(jié)構(gòu)化模板還隨手加了十幾條 few-shot 例子。然后整晚沒合眼反復盯著計費后臺確認了一個讓所有 AI 應用開發(fā)者都需要警惕的事實Prompt 越長越要按每次調(diào)用重復付費這個錢比你想象中燒得快得多。這篇文章不聊宏大的技術趨勢只聊和賬單直接相關的 Token 計費機制、隱形開銷和優(yōu)化手段。適合正在做大模型 API 集成、做聊天機器人、做內(nèi)容生成工具或者單純想把 API 成本壓下來的人??赐曛竽阒辽倌芑卮鹑齻€問題為什么 Prompt 會越寫越貴貴的部分到底貴在哪里以及改怎么把不必要的“字數(shù)成本”降到最低。1. 從一次讓賬單翻倍的排查開始1.1 一次 API 調(diào)用到底按什么收費所有主流大模型 API 都不是按“字數(shù)”計費而是按Token收費。你可以把 Token 粗略理解為模型處理文本時的最小顆粒度它可能是半個詞、一個詞也可能是一小段標點。每次請求的賬單由三部分組成單次調(diào)用費用 輸入 Token 數(shù) × 輸入單價 輸出 Token 數(shù) × 輸出單價輸入單價和輸出單價不一樣通常是輸出比輸入貴兩到三倍。比如某模型定價是輸入 $1/百萬 Token、輸出 $2/百萬 Token那么一次請求輸出了 5000 Token光輸出部分就要花一美分左右——聽起來不多但如果每秒有幾十次調(diào)用一天就是幾十上百美元的量級。我在排查那次賬單翻倍時算了一筆賬系統(tǒng)提示詞從 350 字擴到 2200 字對應的 Token 增量大約是 3500 到 4000 個。平臺每分鐘平均有大約 2000 次調(diào)用每天近 300 萬次。多出來的 4000 Token × 300萬次 額外計費 120億 Token。哪怕按輸入單價很低算也足以讓月度費用直接翻倍。很多團隊的誤區(qū)是只看 Prompt 的“最終效果”把 Prompt 當作文檔來維護卻忘了它每一次都會被完整計費。1.2 一個中文字符不等于一個 Token字數(shù)錯覺帶來的成本誤判絕大多數(shù)人在預估 Prompt 長度時都是拿“字數(shù)”去衡量的這在英文場景里還湊合在中文場景里特別容易踩坑。主流平臺的 Tokenizer 對英文文本大致是 4 個字符對應 1 個 Token中文則往往是一個漢字對應 1 到 2 個 Token具體取決于分詞器實現(xiàn)和上下文窗口類型。這意味著同樣長度的一段中英文混合文本實際 Token 數(shù)差別很大。我做過一個小實驗同一句話分別用中英文表達統(tǒng)計出來的 Token 數(shù)常常差一倍以上內(nèi)容大致文本長度大概 Token 數(shù)英文“Please write a Python function to sort a list”約 46 字符約 10中文“請寫一個Python函數(shù)來給列表排序”約 18 個字符約 14結(jié)構(gòu)化模板中文為主約 800 字約 1200結(jié)構(gòu)化模板中英混合、含代碼塊約 800 字約 1600注意上面只是示意數(shù)據(jù)不同模型的實際切分結(jié)果會有差異但規(guī)律是明確的不要用“字數(shù)”去估 Prompt 成本要用 Tokenizer 跑一遍真實 Token 數(shù)。平臺的控制臺或者本地 SDK 基本都提供了可視化 Token 統(tǒng)計接口展示一次請求消耗了多少輸入 Token 和輸出 Token排查費用問題時第一件事就是把這些數(shù)值拉出來看而不是對著 Prompt 文本猜。實操提醒給團隊定一個規(guī)矩任何 Promot 改動上線前都必須記錄修改前后的 Token 總量并用一天高峰期調(diào)用量做一次費用預估。這個習慣至少能避免一半以上的“Prompt 優(yōu)化導致成本激增”事故。2. 每次調(diào)用都在重復付費的“固定開銷”系統(tǒng)提示詞、few-shot 與歷史消息很多人以為 Prompt 只是用戶輸入的那句話但真正燒錢的往往是你看不見的那部分。2.1 靜態(tài) Prompt 部分如何被反復計費一個典型的 API 聊天請求傳進去的是一個消息數(shù)組大致長這樣{ model: chat-model, messages: [ {role: system, content: 你是一個專業(yè)的寫作助手……此處省略大量字數(shù)}, {role: system, content: 使用以下格式輸出標題/正文/摘要}, {role: user, content: 今天想寫一篇關于AI計費的文章}, {role: assistant, content: 好的我來幫你寫} ] }問題的關鍵在于system里的所有內(nèi)容每當用戶發(fā)起一次新請求都會原封不動地發(fā)送給模型并完整計費。它不會因為你上一次已經(jīng)告訴過模型就被“記住”API 本身是無狀態(tài)的。除非你主動把這份靜態(tài)內(nèi)容放進緩存、或者用平臺提供的前綴緩存機制命中折扣否則這個代價是剛性支出。我見過不少團隊把企業(yè)文化、產(chǎn)品說明、安全規(guī)范、語氣風格指南、行業(yè)知識庫摘要、甚至幾十條實體抽取規(guī)則全部塞進 system 提示詞里一條 Prompt 輕松超過 10000 Token。這類 Prompt 在單次調(diào)用時看著不貴但一旦業(yè)務進入穩(wěn)定期每天幾萬次調(diào)用Prompt 固定開銷 靜態(tài) Token 數(shù) × 調(diào)用次數(shù)就是一個不斷放大的乘法公式。要注意同一份靜態(tài) Prompt 并不會因為內(nèi)容完全相同而自動打折。不少平臺推出的“提示詞緩存”也需要符合條件的完整前綴匹配并不只是“內(nèi)容沒變就行”。2.2 多輪對話歷史成本像滾雪球一樣增長多輪對話是成本增長的第二大來源。每次新請求都會把之前的對話歷史重新拼在 messages 數(shù)組里發(fā)出去。對話持續(xù)輪次越多攜帶的歷史越長。假設每輪用戶消息加助手回復平均 500 Token第 20 次請求時僅歷史部分就有大約 9500 Token這還沒算新的用戶輸入和系統(tǒng)提示詞。模型在理解上下文時也確實需要看到之前的對話但這個機制有一個很隱蔽的成本遞增規(guī)律每一次請求的輸入 Token 數(shù)量都是當前全部歷史的累計值。從第 1 輪到第 N 輪輸入側(cè)總費用近似與對話輪數(shù)的平方相關。也就是說如果一個用戶跟你聊了 30 輪他在后面幾輪里每一句話所牽動的“背景開銷”都遠大于前面幾輪。這還沒完Assistant 在歷史里生成的內(nèi)容通常偏長二次或多次生成后累計歷史會迅速膨脹。實測經(jīng)驗是10 輪以內(nèi)對話還算可控一旦超過 20 輪輸入部分的 Token 會增長到讓人肉疼的程度——尤其是這些歷史還經(jīng)常包含大量重復說明性的內(nèi)容。2.3 函數(shù)定義、工具描述和 few-shot 也占輸入 Token除了系統(tǒng)提示詞和對話歷史凡是走 Function Calling 或 Tool Use 方案的函數(shù)聲明也會完整出現(xiàn)在每次請求的輸入里。函數(shù)簽名、參數(shù)描述、字段類型說明一個都沒法省。有些接口一次同時傳 20 個工具定義輸入 Token 瞬間多個幾千。few-shot 示例同理。你給每條示例都可能被完整換算成輸入 Token。有些做法是把一整套“高質(zhì)量輸出范例”全量塞進 Prompt美其名曰讓模型參考實際上一句話的信息增量只有幾十 Token卻讓整個 Prompt 多出 3000 Token。這類“示范型”靜態(tài)內(nèi)容是 Prompt 變貴最常見的隱性原因。3. 同一個任務兩種 Prompt 寫法費用差多少一次實測對比只看理論夠不著痛處下面我用實際可復現(xiàn)的對比來說話。3.1 詳細版 Prompt 與精簡版 Prompt 的差異假設任務很簡單從用戶評論里抽取情感傾向并輸出 JSON。我分別寫了兩個版本。詳細版約 1200 字純中文系統(tǒng) 你是一個具備深度情感分析能力的專業(yè)客服輿情分析助手你的任務是分析用戶評論的情感傾向。 請嚴格遵循以下要求 1. 首先仔細閱讀用戶評論內(nèi)容 2. 判斷該評論的情感極性可選值是positive、negative、neutral 3. 如果評論屬于正面輸出positive 4. 如果評論屬于負面輸出negative 5. 如果無法判斷輸出neutral 6. 不要輸出任何多余內(nèi)容 7. 以下是幾個例子 用戶評論這個app太好用了強烈推薦 情感傾向positive 用戶評論垃圾產(chǎn)品再也不用了 情感傾向negative 此處省略更多示例 現(xiàn)在請分析以下評論精簡版約 60 字系統(tǒng) 你是情感分析器。僅輸出JSON{sentiment:positive|negative|neutral} 用戶 這個app太好用了強烈推薦Token 數(shù)估算如下版本用戶輸入 Token 數(shù)輸出 Token 數(shù)詳細版約 300約 25精簡版約 45約 25單次調(diào)用差不了幾厘錢但乘上調(diào)用量就完全不一樣了。3.2 放大到真實業(yè)務量費用差距有多大假設輸入單價 $1/百萬 Token輸出單價 $2/百萬 Token每天調(diào)用 100 萬次版本單次輸入費用單次輸出費用每天費用詳細版300 × 1 ÷ 1000000 $0.000325 × 2 ÷ 1000000 $0.00005約 $350精簡版45 × 1 ÷ 1000000 $0.00004525 × 2 ÷ 1000000 $0.00005約 $95同樣一個任務只是把 Prompt 寫短寫干凈每天能省約 70% 的輸入成本。再疊加多輪對話歷史差距還會拉大因為詳細版經(jīng)過幾輪之后歷史中的“靜態(tài)廢話”會不斷增加每一次后續(xù)請求的 Token 數(shù)。3.3 詳細版容易誘導模型輸出更多內(nèi)容這才是賬單爆炸的真正推手上面對比里輸出端暫時一致但現(xiàn)實中詳細版 Prompt 往往會導致輸出更長。比如詳細版里寫了“請逐步分析”“先思考再回答”這類引導詞模型輸出時就會按照思維鏈的形式生成大段推理內(nèi)容。如果最終產(chǎn)品只要求一個 JSON 字段這部分“思考過程”就完全是額外費用。有一次我在調(diào)試一個分類功能輸入 Prompt 加了一句“讓我們一步一步來分析”某模型的輸出 Token 直接從 80 漲到 1200效果還沒有任何提升。后來把推理過程關掉、改成要求只輸出結(jié)構(gòu)化 JSON輸出端成本立刻降到原來的十分之一。把 Prompt 寫長并不等于把效果寫好它經(jīng)常只是把“公共場合說話”時的解釋性內(nèi)容無限放大同時給額外扣費。4. 把 Prompt 做“薄”的五種實操手段聊完問題根源下面是我實際落地過的優(yōu)化方法按收益從高到低排列。4.1 善用平臺自帶的前綴緩存把靜態(tài)內(nèi)容放前面現(xiàn)在不少模型服務商提供自動或手動的 Prompt 前綴緩存命中后輸入價格會大幅降低某些平臺的緩存命中價格只有原價的十分之一左右。關鍵在于緩存的匹配通常是基于前綴完全一致的所以必須把穩(wěn)定不變的內(nèi)容放在 messages 數(shù)組最前面。我現(xiàn)在的做法是系統(tǒng)提示詞固定放在第一段最少量的靜態(tài)示例緊隨其后然后把動態(tài)變化的用戶消息、工具結(jié)果放在末尾。這樣每次請求的公網(wǎng)前綴都能命中緩存長期下來靜態(tài)那一大段花的錢就幾乎可以忽略。注意如果系統(tǒng)提示詞每次都在變比如塞了當前時間、隨機數(shù)字、每次都會變化的動態(tài)指令緩存就會頻繁失效費用立刻飆升。不建議為了湊緩存故意把 Prompt 順序調(diào)得很別扭。先保證邏輯順序再考慮緩存。4.2 精簡系統(tǒng)提示詞只留“必須做什么”刪掉“解釋為什么”我復盤之前那版膨脹的系統(tǒng)提示詞時發(fā)現(xiàn)大量內(nèi)容屬于“解釋性文字”“本工具旨在提升客服團隊的響應效率因此你要……”“考慮到不同用戶的表達習慣存在差異……”“你的回答應當體現(xiàn)專業(yè)、耐心的服務態(tài)度……”模型不需要知道業(yè)務背景它只需要明確的指令。那些說明背景的句子占用的是你每次調(diào)用的輸入 Token。把它直接刪掉用更短的祈使句替代通常不會降低效果。一個通用的精簡公式是角色 任務 輸出格式約束 邊界條件而不是大段背景介紹 角色設定 開放式要求 冗余例子 補充說明4.3 控制 few-shot 數(shù)量從二十條壓到兩三條few-shot 是消耗輸入 Token 的大戶。每加一條示例輸入 Token 就固定增加幾百效果收益卻往往邊際遞減。我的經(jīng)驗是90% 的任務里3 條以內(nèi)高質(zhì)量、覆蓋邊界的示例效果等同于 20 條示例。真正需要模型參考的往往不是“通用例子”而是“邊界情況”。比如做情感分類與其貼“這個很好”和“這個很壞”不如貼一個“這個產(chǎn)品價格便宜但質(zhì)量一般有一點失望”這種模糊案例。把一個有信息量的邊界示例放進去比十個明晃晃的正例有用得多。多出來的邊界描述也只用一條示例就夠了。4.4 給歷史消息做摘要壓縮而不是無限堆積多輪對話場景里最有效的手段不是每條歷史都全量帶回而是把早期歷史以摘要形式存儲并在合適的時機替換掉原文。我在實際項目中常用兩層策略最近 5 輪對話保留全文保證模型對近期用戶意圖的精確理解更早的對話由另一個輕量模型定期生成一段 50 到 100 Token 的摘要或者直接用規(guī)則抽取關鍵信息然后替換掉完整原文。這樣做的好處是用戶聊到 50 輪時輸入 Token 不會從 5 輪時的 2500 Token 線性漲到 20000 Token而是基本穩(wěn)定在 5000 Token 左右。如果產(chǎn)品形態(tài)允許也可以直接限制單次會話的最長輪數(shù)比如 20 輪后提示用戶開啟新會話。雖然體驗上有點“硬”但對成本控制特別有效。4.5 用結(jié)構(gòu)化輸出與參數(shù)卡住輸出長度每次調(diào)用時設置合理的max_tokens上限并盡量要求模型以 JSON 或其他結(jié)構(gòu)化格式輸出可以從源頭壓低輸出端費用。比如做信息抽取輸出格式{summary: 不超過50字, keywords: [最多3個]}再配合 API 參數(shù)里的溫度調(diào)低、開啟 JSON 模式模型就不太會在回答里加無關的“好的我來處理”之類的客套話和解釋。輸出 Token 少了費用自然就降。寫一個小工具做日常審計可以預判改動后的成本def estimate_cost(prompt_token, output_token, input_price, output_price, daily_calls): daily_input_cost prompt_token * daily_calls * input_price daily_output_cost output_token * daily_calls * output_price return daily_input_cost daily_output_cost # 修改 Prompt 后運行一次即可看到費用預估 print(estimate_cost(300, 25, 1/1_000_000, 2/1_000_000, 1_000_000))5. 計費文檔不會主動提醒你的三個細節(jié)結(jié)合我個人的排查經(jīng)驗和讀過的計費文檔還有幾個容易忽略的細節(jié)需要單獨列出來。5.1 報錯與中斷也可能照樣扣費請求如果已經(jīng)進入模型推理階段即使網(wǎng)絡中斷、客戶端主動取消、或者模型在中途觸發(fā)了某個審核規(guī)則已生成并計費的部分可能仍然會出現(xiàn)在賬單里。不同平臺的結(jié)算規(guī)則不一樣但不少是按“已處理 Token”計費的而不是按“最終正常返回”計費。我在某個項目里做過一次對比對同一個請求重試 5 次其中有 3 次中斷最終賬單里多扣的正是中斷那一刻已生成的 Token。解決辦法是非關鍵路徑上盡可能使用超時重試策略不要無限重試對實時性要求不高的任務盡量走異步接口或批量接口通常這類接口在失敗時更容易拿到明確不計費的保障。5.2 緩存命中和未命中的價格差“必須完全一致”的前綴規(guī)則前面提過緩存這里補充一個關鍵細節(jié)不同平臺的緩存粒度差異很大。有的平臺只要前 1024 個 Token 完全一致就能命中有的平臺要求整個輸入完全相同才能命中。最實用的判斷方法是查看計費日志里的緩存命中標記如果沒有這個標記就手動對照線上實際每輪請求的清單一查便知。需要特別小心的是開場白或模板里的動態(tài)變量比如“今天是 2026 年 5 月 12 日”這種如果放在系統(tǒng)提示詞的固定前綴中每次都會破壞緩存命中。把這類動態(tài)內(nèi)容挪到消息末尾或者干脆不放比讓模型知道“今天是哪天”更重要——除非這個日期對輸出有實質(zhì)影響。5.3 max_tokens 不是省錢開關理解生成停止條件把 max_tokens 從 4096 改到 128確實能限制輸出長度但它的副作用是如果任務本身的正確輸出就超過這個長度模型會在截斷處停止返回一個不完整的結(jié)果甚至產(chǎn)生格式損壞、JSON 截斷等問題反而增加下一次糾錯請求的成本。所以正確用法是先摸清每個任務的實際輸出 Token 分布再設置一個“略高于正常值”的 max_tokens而不是為了省錢而壓得太狠。我一般取正常輸出 Token 分布的 95 分位再乘以 1.2 作為上限。5.4 貴模型做難事便宜模型做雜事如果項目里同時依賴不同檔位的模型建議按任務拆分配置而不是讓所有請求都走向最貴的大模型。我接觸過的一個內(nèi)容審核系統(tǒng)原來統(tǒng)一用最貴模型跑全文審核流量一到高峰期賬單直線上升。后來改成先用便宜的小模型做粗篩把明顯安全的評論直接通過只有置信度較低的評論才送進貴模型做二次判斷總費用降了接近一半準確率甚至還有小幅提升。這套思路同樣適用于 Prompt讓“長任務”走需要深度推理的模型讓“短任務、強約束、格式固定”的請求走便宜模型。很多平臺不同檔位間的價格差能到幾倍甚至十倍選型帶來的成本差異遠超 Prompt 微調(diào)。6. 每次改完 Prompt 之后我還會做的一道審計這節(jié)其實是我自己的一個習慣也算給本文一個自然的落點。在每次修改 Prompt、上線新功能、或者調(diào)整模型參數(shù)之前我會打開一個簡單的清單用 Tokenizer 統(tǒng)計當前完整 messages 的輸入 Token 數(shù)統(tǒng)計其中靜態(tài)系統(tǒng)提示詞 靜態(tài) few-shot 的 Token 占比再統(tǒng)計歷史消息的平均 Token 數(shù)和最大對話輪數(shù)按昨日有效調(diào)用量估算一次單日成本檢查動態(tài)變量是否破壞前綴緩存確認 max_tokens 是否合理、是否允許結(jié)構(gòu)化輸出。這套動作花不了五分鐘但已經(jīng)幫我攔住過三次差點上線的成本事故。尤其是第一和第二條只要靜態(tài)部分在整體輸入里的占比超過 30%我就會重新考慮拆分任務、縮精提示詞或者換更便宜模型。實際上最深刻的體會是Prompt 越寫越貴通常不是因為它真的需要我們付費那么多而是因為我們把“告訴模型一句有用的話”和“把一本書塞進模型腦子里”混為一談。大模型 API 的計費本質(zhì)是按計算資源消耗來收取只要模型還在處理那堆不會產(chǎn)生增量應該的冗余文字賬單就會繼續(xù)增長。與其糾結(jié)一個詞一個詞的措辭不如定期回到 Token 數(shù)和調(diào)用量這兩項基礎指標上做體檢。希望這次的解構(gòu)對你手上的項目也有幫助。如果你也在為 API 賬單上的陡增曲線頭疼可以試著從靜態(tài) Prompt 開始減重多數(shù)情況下效果會來得比想象中更快。