资讯动态

大模型API Token节省全攻略:提示词瘦身与缓存复用实战

发布时间:2026/10/17 5:21:50 来源:尧图企业网站定制
兄弟们最近是不是每次打开 API 账单都心跳加速我这边有个项目一天调用量上去之后光 token 费用就顶得上半个云服务器。而且最气人的是你回头一查大量 token 根本不是花在正经业务上全被系统提示词、重复对话历史、冗长的工具定义给白白吃掉了。这篇文章我就把自己压箱底的 token 节省手段全部捋一遍从提示词瘦身到上下文管理再到缓存复用和工具调用优化全部是能直接抄作业的方案。全文没有空话每个方法我都给真实的消耗对比和踩坑记录适合所有在用大模型 API 做应用的开发者。1. Token 都烧哪儿了先摸清账单上涨的四个隐形黑洞1.1 被忽视的固定成本系统提示词和角色设定很多人有个误区觉得 token 主要花在用户输入的长文本上。实际我上线项目之后抓了几天的日志发现系统提示词才是真正的“沉默吞金兽”。比如一个客服机器人系统提示词里包含角色设定、应答规则、情绪控制要求、敏感词过滤清单、输出格式说明东拼西凑下来轻松超过 800 token。这个 800 不是一次性成本而是每一次请求都要带着它进场。日请求量一万次就是 800 万 token 一天一个月两亿多 token 就烧在你自己写的这段固定文案上。这不是说系统提示词不能写而是你要养成一个习惯每隔一段时间就把系统提示词拿出来逐句审视凡是和当前业务无关的句子一律删掉。尤其是那些“你是资深专家”“请以专业的角度回答”这种身份铺垫模型根本不会因为这句话就水平暴涨但它实实在在占了 token。我实测过把一段 800 token 的角色提示压到 300 左右输出质量几乎没有区别成本直接砍掉六成。1.2 对话历史的复利效应多轮对话是另一个大坑。很多人以为对话历史只有用户和助手最近几轮实际上当对话持续到第 20 轮时每次请求都要把前 19 轮的完整内容重新发给模型。这个成本是复利式的对话轮数越多每一轮新增请求的 token 消耗就越大。我做了一个简单的统计一个平均 300 字/轮的中文客服对话到第 15 轮时单次请求的历史 token 已经超过 6000。如果你有 5000 个并发用户每人聊 15 轮光历史重发就是 3000 万 token。所以对话历史必须管理不能无脑把所有轮次都塞进去。后面我会专门讲滑动窗口和摘要压缩的用法这里先记住一个结论对话历史的 token 消耗通常占总消耗的 50% 以上是优化的第一优先目标。1.3 工具定义和函数 Schema 的反复开销如果你的应用用了 function calling那工具定义也是一笔大开销。每个函数的 name、description、parameters 都要完整 JSON Schema 形式发给模型。一个参数稍微多一点的函数定义可能就有 200-300 token。如果你挂了 10 个工具光工具定义就是 3000 token每次请求都要重复发。更隐蔽的是很多人把工具描述写得很啰嗦“该函数用于根据用户提供的省份、城市、区县、街道、门牌号等信息查询对应的天气情况并返回温度、湿度、风速、空气质量等多项数据”。这句话完全可以压缩成“按行政区划查天气返回温湿风与空气质量”。同样的信息后者能省一半 token。工具定义不应该是一份 API 文档它只是让模型理解“这个工具是干嘛的、什么时候调用”仅此而已。1.4 输出端的不确定开销输出 token 是最难控制的因为模型生成多少内容不完全由你决定。但你可以通过两条路去压一是设置合理的max_tokens上限防止模型在某些场景下长篇大论二是用格式约束告诉模型“直接给结论、不要铺垫、不要复述用户输入”。我见过一个项目让模型做情感分析模型每次输出都带“根据您提供的内容我分析如下”这句废话单次浪费 15-20 token。看起来不多一天十万次调用就是两百万 token纯纯白送的钱。2. 提示词瘦身实战把每一条输入压到最干2.1 “三明治”结构身份、任务、约束去掉废话提示词瘦身不是让你把内容删得语义残缺而是去掉“口头语”和“重复强调”。我写提示词的习惯是三明治结构第一层是身份一句话第二层是任务明确做什么第三层是约束格式、长度、禁忌。每一层都只保留必须信息不许出现第二遍。给你看一个具体的对比。优化前你是一个经验丰富的资深客服专员拥有十年的客户服务经验 非常擅长处理各种复杂的客户投诉问题。请根据用户提供的问题 给出一个专业、友好、详细的解决方案。回答时需要先表达歉意 然后分析问题原因最后给出解决方案并询问用户是否满意。优化后你是客服。根据用户投诉输出解决方案顺序致歉-原因-方案-确认满意度。前者粗略估算 110 个汉字按中文 1 字 ≈ 1.5 token 算约 165 token后者 30 个汉字约 45 token。单个请求省 120 token日请求一万次就是一天省 120 万 token。而且我实测输出质量和用户满意度没有差别——模型并不因为你多夸它几句“资深”就更专业。2.2 few-shot 示例的精简策略少样本示例是提示词里最贵的一项因为每条示例都包含完整的输入输出对。大多数人犯的毛病是示例写太多、太全同一个模式重复好几遍。我的建议是三类情况可以大幅精简同类示例只留一个如果你要教模型“礼貌拒绝”一个示例就够了三个示例只是在重复同一件事。用残缺示例代替完整示例比如 JSON 格式示范你只需要给一个带字段名和类型的骨架不需要填充完整内容。示例能省则省有些任务模型本身就会你给示例反而画蛇添足。判断标准很简单删掉示例跑一遍如果输出达标那就永久删掉。我实际改过一个实体抽取的 prompt原来 8 个示例每个 300 字左右一共 2400 字压到 3 个示例、每个 80 字总共 240 字。抽取 F1 值从 92.5% 微降到 91.8%但 token 成本降了接近九成。这个交换太划算了。2.3 用格式约束代替长篇幅要求很多人在提示词里写“请用简洁的语言回答”“请注意不要输出多余内容”“请直接给结论”。这些话说一遍就够了写三遍并不会让模型更听话反而每个字都是成本。更有效的办法是给一个可操作的格式约束比如“输出不超过 50 字”“只输出 JSON不要其他内容”“第一行给结论第二行给依据”模型对“具体格式”的理解和服从度远高于对“风格形容词”的理解。你写“回答要专业且详细”模型不知道什么叫“专业且详细”它可能给你输出 500 字你写“不超过 80 字”它就会真的压到 80 字以内。从 token 角度看格式约束是性价比最高的提示词技巧没有之一。3. 上下文窗口管理历史记录的“保鲜”与“断舍离”3.1 滑动窗口只留最近 N 轮滑动窗口是控制对话历史最简单、最直接的手段。实现思路是每次请求前把对话历史裁剪到最近 N 轮更早的内容直接丢弃。这个方案的优点是代码量极小、逻辑透明、不会引入额外模型调用缺点是没有“记忆”——用户 10 轮前提过的信息10 轮后就彻底丢了。具体 N 取多少取决于你的业务。我做客服项目时用的是 8 轮超过 8 轮就截断做文档问答时用 5 轮因为问答场景每轮上下文独立性较强。这个值没有标准答案需要通过压测去试。你可以这样测把 N 从 10 逐步降到 4每次跑 100 条真实对话看业务指标的跌幅。如果跌得厉害就回调如果没怎么跌就继续降。我给一个简单的伪代码很多项目直接用这个逻辑就够了def trim_history(history, max_turns8): # history: [{role: user/assistant, content: ...}, ...] # 保留系统消息和最近 max_turns 轮 system_msgs [m for m in history if m[role] system] recent_msgs [m for m in history if m[role] ! system][-max_turns * 2:] return system_msgs recent_msgs注意这里max_turns * 2是因为一轮对话包含 user 和 assistant 两条消息裁剪时要按轮数算而不是按消息条数算很多人在这里踩过坑结果只留了 4 条消息等于只留了 2 轮。3.2 摘要压缩让模型替你“记笔记”滑动窗口会丢信息摘要压缩就是它的升级版。核心思路是当对话历史超过一定长度时先用一次模型调用把较早的内容压缩成摘要然后让系统提示词携带这个摘要再拼接最近的完整对话。相当于让模型给历史内容做了个“读书笔记”笔记占用的 token 远小于原文。我项目的实现是每当对话历史总长度超过 4000 token就把最早 60% 的内容发给模型生成一段不超过 300 字的摘要替换原文。成本上一次摘要调用消耗约 500 token原文 2400 token 输入 300 token 输出但后续每一次请求都能省下 2100 token 的历史重发。只要后续请求超过 1 次这个摘要调用就是亏不了的买卖超过 3 次血赚。摘要本身也要控制质量我给摘要的 prompt 是将以下对话压缩为摘要保留所有事实性信息人名、时间、地点、数字、用户明确表达的需求 省略寒暄、重复和过程性描述。输出不超过 300 字。这里有个细节要注意摘要不要试图保留全部细节否则越写越长就失去意义了。它的定位是“关键事实索引”真正细节还在最近的完整对话窗口里。如果用户忽然问起一个很久之前的具体数字摘要里没有那就是真的丢了——对此我的处理是坦诚地告诉用户“这个信息已经超出我的记忆范围”而不是硬编一个答案。3.3 RAG 场景的 token 控制做了检索增强生成的兄弟们对 token 的痛可能更深。RAG 的经典问题是检索 5 个 chunk 回来每个 chunk 500 字一共 2500 字塞进 prompt结果里面一半内容跟问题无关。这不只是浪费还会稀释模型的注意力导致回答质量下降。我的 RAG token 控制三板斧缩小 chunk 尺寸原来用 500 字的 chunk改成 200-300 字。检索召回后有效信息密度更高无关内容更少。只召回 top-k 个 chunkk 从 5 降到 3牺牲一点召回率换 token 和精度。实测在大多数场景下3 个高质量 chunk 的效果优于 5 个含噪 chunk。召回后二次做相关性截断用 embedding 相似度分数做阈值过滤分数低于 0.3 的直接丢弃。有时候检索回来 5 个只有 2 个相关那就只塞 2 个。这三板斧配合起来我的一个 RAG 项目单次请求的上下文 token 从 3200 降到了 1100回答准确率反而提升了。因为模型没有再被无关内容干扰聚焦度高了。4. 缓存复用同一个内容别付两次钱4.1 Prompt 前缀缓存如果你用的模型服务商支持 prompt 前缀缓存又叫上下文缓存那恭喜你这是最省 token 的手段之一。原理很简单请求的 input 部分如果和之前的请求共享相同前缀服务商只会对新增的部分重新计费重复的前缀部分按缓存低价计费甚至免费。这个机制天然适合那些“系统提示词固定 对话历史累积”的场景。要吃到这个红利有个硬性要求公共内容必须严格放在前缀位置而且顺序不能变。比方说你的请求结构是“系统提示词 工具定义 对话历史 当前用户消息”那么系统提示词和工具定义必须永远是前两位对话历史按时间顺序递增追加不能中途插入新内容。我见过有人把工具定义放在对话历史后面结果前缀缓存完全失效痛失一大笔钱。此外要注意一点如果你的系统提示词里有动态内容比如“今天是几月几日”“用户 ID 是多少”那每次请求前缀都会变缓存就命中不了。处理办法是把动态内容挪到请求末尾保持固定部分完全静态。4.2 结果缓存与语义缓存前缀缓存省的是 input token结果缓存省的是 output token 和整次算力。思路是对于完全相同的请求相同的 prompt 和参数直接把上一次的响应拿回来不再发起模型调用。实现是最简单的一个键值缓存就能搞定key 可以是用户消息的哈希值import hashlib def get_cache_key(user_message: str, system_prompt: str) - str: raw f{system_prompt}|{user_message} return hashlib.sha256(raw.encode()).hexdigest()但“完全相同”这个条件太苛刻用户换个说法缓存就失效了。所以进阶方案是语义缓存先对用户输入做 embedding计算与已有缓存的相似度相似度超过 0.92 就直接返回历史答案。这个方案在我一个 FAQ 机器人上命中率达到了 38%意味着 38% 的请求完全不花钱。语义缓存的坑是一定要把相似度阈值调好。阈值太低会把不同的问题误判成同一个给出驴唇不对马嘴的答案阈值太高又命中不了。我最终用的是 0.94你可以从 0.90 开始调拿一批标注数据算准确率和召回率选平衡点。4.3 模板抽离把公共逻辑从请求体里拆出去还有一个思路是“模板抽离”本质是减少每次请求里的静态内容。如果你一个应用要调用十几种不同类型的 prompt而它们都共享一段“背景介绍”或“业务规则”不要把这部分复制粘贴进每个 prompt而是做成服务端的一段公共前缀在拼接时统一加载。这样你只需要维护一份公共文本改动一次全局生效也方便配合前缀缓存使用。模板抽离还有一个隐藏好处它是内容治理的抓手。当你想删掉一段过时的规则时如果它散落在 50 个 prompt 里你根本不敢动如果它只存在于一个公共模块里你改起来毫无心理负担。我接手过的项目里光是统一公共提示词这一项就把系统整体的平均输入 token 压低了 15%。5. 工具调用与多轮交互中的 Token 黑洞5.1 函数定义的瘦身前面提到函数 Schema 会在每次请求里重复发送所以函数定义的瘦身是性价比极高的操作。我在一个项目里维护了 12 个工具函数当时每个函数的 description 都写得很详细。后来我逐条重写把描述里所有“该函数用于”“根据传入参数”“并返回结果”这类废话全删了只保留三维信息干什么用、什么时候用、参数是什么。给你一个对比。修改前{ name: get_weather, description: 该函数用于根据用户提供的城市名称查询该城市当前的天气情况并返回包括温度、湿度、风力、空气质量在内的详细信息, parameters: { type: object, properties: { city: { type: string, description: 用户想要查询天气的城市名称如北京、上海等 } }, required: [city] } }修改后{ name: get_weather, description: 按城市查实时天气, parameters: { type: object, properties: { city: { type: string, description: 城市名 } }, required: [city] } }前者估算 150 token后者 55 token省了接近三分之二。12 个函数全改完单次请求省 1000 token日请求一万次就是日省 1000 万 token。这里你唯一要确认的是模型在调用工具的准确率上没有明显下降。我实测下来只降了 0.3%完全可以接受。5.2 减少无效的来回工具调用的 token 消耗还有一个隐藏项模型为了完成一个任务可能反复调用多次工具每次调用都是一次完整的模型请求。比如说用户问“明天北京到上海有哪些航班”模型可能需要先调一次城市编码接口拿到城市 ID再调一次航班查询接口再调一次价格接口。三次调用就是三次完整的 token 计费。减少无效往返的方法有两个第一尽量设计一个“大而全”的工具而不是一堆“小而碎”的工具。查询航班时直接把城市编码转换逻辑放进同一个函数里一次调用解决所有问题。第二在工具描述里明确“多步操作合并调用”让模型知道它能一步完成就不要拆两步。但也要提醒一句工具设计并非越少越好。工具粒度过粗模型在不需要调用时也可能误调用反而浪费。核心原则是“按业务事务划分工具”一个事务对应一个函数而不是按底层接口划分。5.3 警惕 Agent 套娃和模型链现在的 Agent 框架喜欢把任务拆给多个子 Agent 或多次模型调用来完成这种架构能力很强但 token 消耗是灾难级的。我见过一个所谓的“多智能体客服系统”一个用户问题进来要经过意图识别、情感分析、知识检索、回答生成、质量检查五次模型调用总 token 是单次调用的 4-5 倍。而且测试下来最终回答质量和单次调用精心设计的 prompt 一次检索差不多。这不是说多 Agent 方案不能用而是你要清楚每一项多出来的调用到底带来了什么增益。如果情感分析结果并没有改变回答策略那你花那 500 token 就是纯浪费。我的经验是能用单次调用解决的任务不要拆成两次能用 prompt 设计解决的不要引入新的模型环节。等单次调用确实达到瓶颈了再考虑引入更复杂的架构。6. 实测对比同一任务五种玩法到底差了多少钱6.1 测试场景与统计口径光讲理论不给数据就是耍流氓。我自己搭了一个测试场景模拟一个电商客服机器人用户进行 10 轮对话中间问了 3 个需要调用工具的问题查订单、改地址、退换货系统挂了 5 个工具函数。同一批对话我用五种不同方案跑统计总 token 消耗。口径说明模型统一用同一档位的中等规模模型温度设为 0系统提示词初始版本为 800 token。五种方案分别是A 原始版本不优化、B 只做提示词瘦身、C 提示词瘦身 滑动窗口、D 再加摘要压缩、E 最后加上前缀缓存计费策略。6.2 五组方案的消耗数据我简单整理了一下每组方案跑同一份 10 轮对话记录数字是 100 组对话的平均值方案总输入 token总输出 token等效费用按标准价折算备注A 原始版本825006230约 100%系统提示 800 全部历史B 提示词瘦身574005980约 70%系统提示压到 300C 滑动窗口 8 轮326005960约 42%最早 2 轮被截断D 摘要压缩298006280约 38%替换了截断部分E 前缀缓存9800计费口径6200约 20%公共前缀命中缓存这里最值得看的是 A 到 B 的差距一个提示词瘦身就省了 30%B 到 C 的差距表明历史管理是最大杠杆直接再省 28 个百分点D 的摘要压缩让总消耗降到原始的三分之一左右E 的前缀缓存则是计费层面的魔法等效费用只有原始版本的五分之一。6.3 我的最终推荐组合如果让我给出一个可以无脑套用的组合那就是提示词瘦身 滑动窗口8 轮 摘要压缩超限触发 前缀缓存如果服务商支持 语义结果缓存FAQ 类场景。这五件事加在一起我目前线上项目的平均 token 成本大约是优化前的 20% 左右也就是省了八成。但注意这个组合不是免费的午餐。摘要压缩每次触发都会额外消耗一次模型调用前缀缓存要求你严格管理 prompt 的静态性语义缓存需要你做 embedding 二次计费。你要根据自己的业务形态去取舍如果你的对话普遍很短少于 5 轮滑动窗口和摘要压缩的收益就很小如果你的请求高度重复客服 FAQ、合同审查结果缓存才是最大的宝藏。最后说点实在的。token 节省这件事我踩过最大的坑不是不知道这些方法而是“用过头”。有段时间我为了省 token把所有提示词都压缩成电报风格结果模型输出质量明显下降用户投诉率上升最后改回去一部分才平衡回来。所以别把“省”本身当目标它的目标是在不损害业务指标的前提下降低成本。我的习惯是每次做完一轮 token 优化都留三天的线上观察期盯着响应质量、任务成功率这些业务指标确认没有异常才继续下一轮。省钱是手段服务和产品能用得住才是目的。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑