单位成本降下来之后:那些省钱的减法该不该拆

发布时间:2026/10/25 9:35:08
单位成本降下来之后:那些省钱的减法该不该拆 说明本文讨论的是单位推理成本持续下行之后过去为压成本做过的那些减法该怎么处理属于工程取舍话题不涉及具体模型版本与价格。AI 领域版本迭代极快凡涉及版本号、价格、可用性请以你阅读时的官方页面为准。文中代码为结构示意请按自己的技术栈调整后再上生产。一、减法是有利息的2024 年初讨论成本议题通常只有一个把每次调用的开销压下去。做法高度雷同——历史按轮数截断、长文档先摘要再喂、能走小的就不走大的、缓存能命中就不回源、请求能攒批就攒批。当时的账很好算每一条都能在成本看板上换成一个看得见的降幅谁做得多谁的数字好看。2026 年中回头看那笔账的分子和分母都换了。单位推理成本在这两年间持续下行同样的输入在今天的开销跟 2024 年不是一个量级用量结构也变了长会话更多、工具回环更多、一个任务跑十几轮的地方更多。减法留下的却不是数字是结构。结构不会跟着单价一起下行。省下来的是本金付出去的是利息四类利息账期各不相同。质量利息账期最长。被截掉的那几轮历史在绝大多数会话里确实没用但在某一类任务里它是唯一的约束来源。这类失败看起来像模型偶尔犯傻不像我们少给了东西所以没人会去查配置。延迟利息账期最短当天就能感觉到。摘要要现算一遍缓存未命中要回源攒批要等窗口关闭。用户说的这玩意儿有点慢背后常常是三条减法叠出来的。可解释利息在复盘时才付。出了问题手上只有摘要没有原文只能推测大概是上下文不够。推测出来的结论会指导下一轮改动改错方向的机会就这么来的。维护利息是分期付款每加一条减法付一次。截断、摘要、缓存、分流四层叠起来一段输入最终长什么样要读四个配置才能推出来。新同事接手问的第一个问题通常是这里为什么要这么处理答案多半是当时为了省一点。利息类型典型表现最早暴露的位置可观测指标质量同一类任务偶发失败换个会话又好了失败样本复盘按意图分组的失败率延迟首字时间抖动长会话更明显端到端耗时看板分位耗时、缓存命中率可解释说不清为什么这次答错事故复盘记录复盘结论里疑似出现的次数维护改一处要读四个配置代码评审上下文组装的分支数当时的账为什么算得过来三条前提单次开销高省一次很值流量以短会话为主截断伤不到失败可以重试重试也不太贵。到 2026 年这三条至少变了两条。单次开销不再是最主要的成本项重试、返工、人工介入开始占更大份额会话变长之后截断伤到的比例上升。第三条最麻烦重试看起来还是那么便宜但重试带来的重复产物、重复副作用、用户重新描述需求这些成本不进调用账单。所以该不该拆不是问它省了多少是问它的利息有没有超过本金。这个判断要两个数这条减法在单位成本里占的比例和它造成的返工在总成本里占的比例。多数团队只有前一个数。第一步不是拆是给减法建账。二、先分清哪一类减法四类拆除成本差一个量级省输入截断、摘要、裁字段、压缩检索结果。拆的是组装逻辑改动集中在一个函数里。省调用语义缓存、结果复用、请求合并。拆的是缓存键和失效策略改错一次要么命中率归零要么把旧结果返回给新请求。省算力分流、低档位、量化。拆的是路由和默认参数牵动的是另一批人的评测集。省次数批量攒批、去重合并。拆的是时序动到 SLA 和上游的超时设置。拆省输入一个下午能改完当晚能灰度。拆省算力要重跑评测、要跟另一组人对齐、要改发布节奏。这不是工作量的差距是能不能一个人拍板的差距。所以拆除顺序基本由分类决定不由收益决定。类别典型做法拆的是哪一层拆除成本省输入截断、摘要、裁字段、压缩检索结果上下文组装一个函数当天能灰度省调用语义缓存、结果复用、请求合并缓存键与失效策略两处代码要预热后对比省算力分流、低档位、量化路由与默认参数换评测集跨组对齐省次数攒批、去重合并时序与超时设置动到 SLA 和上游契约判据关掉它输出会不会变错三个分支都能落到检查项上。关掉之后同一批样本从对变错它是结构性设计不进拆除队列。关掉之后结果一个字不变、只是更贵它是纯省钱减法最先拆连评测都不用等。关掉之后结果从能过变成更好成本上升可测它是省钱减法但需要评测排第二批。还有一类更边缘拆掉之后输出改善不明显成本上升也测不出来。这类减法当年可能真省过但省下的量被单价下行吃掉了留着只剩维护成本。它们该排在第一批的最前面——收益最快风险也最小。登记表只靠记忆拆不了。要一张表。⚠️ 代码待验证CREATETABLEsubtraction_ledger(idTEXTPRIMARYKEY,nameTEXTNOTNULL,-- 例如 history_truncateclassTEXTNOTNULL,-- input / call / compute / countscopeTEXTNOTNULL,-- global / by_intent / by_tenantdefault_onBOOLEANNOTNULL,kill_switch_keyTEXTNOTNULL,cost_shareNUMERIC(5,4)NOTNULL,-- 在单位成本里占的比例不是金额quality_evidenceTEXT,-- 当初有无开关对比无则留空evidence_refTEXT,-- 对比报告或评测批次added_at TIMESTAMPTZNOTNULL,ownerTEXTNOTNULL,remove_batchSMALLINT,-- 1 / 2 / 3未定为 NULLUNIQUE(kill_switch_key));cost_share记的是比例而不是金额。金额会随单价漂移一年后回头看那张表全是过时数字比例可以比较也直接决定先拆谁。quality_evidence记当初有没有做过开关对比。多数行会是空的。空着的这一列就是拆的时候没有依据的那批——要补测量再动手否则拆完你只能说感觉好了一点。scope决定灰度粒度。所有行都写global的表等于没有灰度能力第三批根本做不了。三、哪些减法拆了立刻见效截断历史按需放回默认全量当年最常见的一行配置是保留最近若干轮。设成三或者五很少有人算过为什么是五。判断被截掉的轮次有没有被用到三个信号够用。一是用户复述。用户在后续轮次里重新说了一遍前面给过的约束说明那一轮在他心里还在只是模型看不到了。二是工具入参。某次工具调用的参数依赖前面某一轮给出的值而这个值不在保留窗口里。三是下游断言。任务的验收条件引用了早期输入里的字段。三个信号都能从现有 trace 里算出来不需要新埋点。算出的比例就是截断在制造返工的概率。放回的方式不是把窗口调大。窗口调大只是把撞墙的位置推后长会话照样撞。做法是默认保留全量超过阈值才触发裁剪并且裁剪要落一条记录哪个会话、第几轮、裁掉多少。裁剪从一直开着的默认状态变成偶发事件它才有被观测的可能。摘要替代原文留着做检索摘要降级成索引摘要的问题不在准不准。摘要通常挺准。问题在它不可回溯某次回答里出现了一个摘要中没有的细节你没法判断是模型编的还是原文里有而摘要漏了。这个判断做不出来整条链路的可信度就没法评估。拆法不是删摘要是把两者的职责分开。原文留着供检索、引用、回溯摘要只做粗筛和路由——决定这一段要不要展开、展开哪一段。改完之后摘要的偏差不再直接进入生成它只影响召回够不够。召回不够可以补编造不能补。过度裁剪的上下文这一类最没道理。被裁掉的往往不是内容是结构工具返回里被砍掉的字段、检索结果里被切断的段落边界、附件里被去掉的表头。省下的输入很少造成的返工很多。检查项抽一批失败样本按原因归类看模型拿到的信息不全占多大比重。如果它明显高于其它原因裁剪就是净亏——省下的是输入赔进去的是一整次重跑。还原开关⚠️ 代码待验证fromdataclassesimportdataclassdataclassclassContextPolicy:max_turns:int200# 阈值放得很宽正常会话不触发max_chars:int120_000drop_tool_fields:boolFalsedefbuild_context(session,policy:ContextPolicy,flags:dict)-list:turnssession.turns# 开关粒度比策略细一级按租户 意图而不是全局一刀切keyfctx_restore:{session.tenant_id}:{session.intent_key}ifflags.get(key):policyContextPolicy()# 还原成默认全量iflen(turns)policy.max_turns:turnsturns[-policy.max_turns:]session.log_trim(len(session.turns)-len(turns))# 裁剪必须留痕returnassemble(turns,policy)开关粒度必须比策略细一级。策略是保留多少轮开关是对这个租户、这个意图关掉截断。两者粒度一样的话拆坏了只能整体回滚而整体回滚的代价常常比不拆还大。还原之后怎么判断这笔钱花得值看同一个任务的轮次有没有下降。历史放回去模型少问一次澄清、少一次工具回环轮次降下来总输入可能反而更少。如果轮次不变、输入只是变长这条还原就只是变贵了要重新判它值不值。这也是第一批只挑确定被用到的那几段的原因——整体放开的话值和不值混在一起你分不出来。四、哪些减法不能拆五条跟省钱无关的设计去重、幂等、批量合并写入、字段最小化、产物硬上限。前三条是正确性。同一个请求被处理两次会产生两份产物、两条副作用、两笔账重放不幂等补偿逻辑就没有立足点。批量合并写入不是为了少调几次接口是为了一次事务里写完关联的几张表中途失败不留半条记录。后两条是契约和合规。字段最小化指不把用不上的个人信息带进上下文这条跟省不省钱没关系跟能不能过审有关系。产物硬上限指单次输出必须有上限超了要分片否则下游解析会炸。一个判据能分开它们假设成本为零你还会不会这么做。会就说明它不是省钱减法。去重和复用也常被当成一件事。复用是不同请求共享同一份结果关掉最多变贵去重是同一请求不处理两次关掉会多出第二份产物和第二条副作用。缓存同时承担这两件事所以它必须被切开。混合设计要先切开缓存是最典型的混合。它既省调用又是同一输入得到同一输出的实现手段之一。拆缓存时一刀切会把幂等一起拆掉症状是重试开始产生重复产物而且不容易复现。切法给每个缓存条目记一个用途——是为了省一次调用还是为了保证同样的输入拿到同样的输出。前者可以按 TTL 和相似度阈值调可以关后者必须一直命中TTL 只能延长。截断也混。截断历史是省钱截断工具返回的超长字段是接口约束因为下游解析器有大小上限。这两件事经常写在同一个函数里两个 if 挨着看起来是一回事拆的时候一起被删。标记出来不靠记忆⚠️ 代码待验证{switches:[{key:ctx_restore,class:cost,removable:true,batch:1},{key:idem_dedup,class:correctness,removable:false,note:拆掉后重试会产生第二份产物},{key:tool_field_strip,class:contract,removable:false,note:下游解析器有字段上限},{key:pii_field_deny,class:compliance,removable:false,note:与成本无关属最小化要求}]}class只有四个取值removable只由class决定不留给讨论。这三类正确性、契约、合规不进拆除队列哪怕单位成本再降一轮。理由不是稳妥是拆了没有第二个地方补幂等在业务层补不回来字段最小化在合规侧补不回来产物上限在下游补不回来。五、拆除本身有成本一处减法牵动四样东西要改的东西具体改什么为什么必须同批漏了会怎样提示模板去掉以下为最近若干轮这类隐含假设输入长度变了原假设不成立模型行为漂移且不一定出现在抽查的样本上缓存键键里是否含策略版本含则命中率归零不含则旧结果被新请求命中前者像故障后者是静默错答评测基线基线要在新状态下重打或双跑对比老基线本身被减法压低得出明显变好的结论但不知道是否达标成本看板标注口径变更与生效时间输入变长、次数变多都是预期内图上看起来像事故被人叫停四样里最容易漏的是缓存键。它不在代码评审的视野里通常是一个字符串拼接函数改策略的人根本不知道它存在。怎么证明拆完没有变差三件事固定样本、双跑、规则判分。固定样本要包含当初被减法伤到的那批。如果样本全是短会话、全是单轮、工具返回永远用不满拆完必然没有差别——样本本身就在证明减法无害。双跑指同一批样本在开关打开和关闭两种状态下各跑一次比的是两次的差不是跟历史基线比。规则判分指判分标准不能是模型自评。提示变了自评偏好也会变两次分数不可比。能落到字段和断言的就落下去确实要人判也要同一批人、同一份评分表。三处不可比提示版本、上下文长度、缓存状态。控制不住这三处对比没有意义。缓存状态最容易被忽略——预热过的缓存和冷缓存跑出来的延迟和命中率完全是两套数。灰度⚠️ 代码待验证batch:1switch:ctx_restorebuckets:-dim:tenantvalues:[t_1024,t_2048]# 先挑低风险租户-dim:intentvalues:[doc_extract,faq_answer]-dim:session_lenrange:[1,20]# 先从短会话起长会话最后放ratio:0.2observe_window:72hguard:fail_rate_delta_max:0.005p95_latency_delta_max:0.15cost_per_success_delta_max:0.10on_guard_hit:revert比例和窗口之外guard里的三个阈值要事先写死不要等到灰度结束再讨论这样算不算变差。事先没写事后就会变成一次关于感受的会议。完整版资料清单本文用到的减法登记表、还原开关代码和灰度配置模板都整理在里面了扫码即可获取六、用量结构变了账也要重算分母换了2024 年的分母是调用次数。2026 年该用的分母是成功任务数。调用次数把重试、返工、工具回环都算成了用量。用这个分母任何减少调用次数的设计都会被奖励包括那些制造返工的。一条把输入压掉一半、却让重试率上升的减法在旧口径下非常漂亮。每个成功任务成本 模型开销 工具开销 重试开销 人工介入折算/ 成功任务数。前两项好取。重试开销要按 trace 里的尝试次数归集——注意是归集到任务不是归集到调用否则分母又变回次数。人工介入最难取但它常常是差值的主要来源一次人工补数据抵得上很多次调用。归集口径这里有个坑重试的开销摊到调用上重试就变成了用量跟当初用调用次数当分母是同一个错误摊到任务上重试才会体现为成本也才进得了减法该不该拆的判断。三种结论反转情形旧口径看新口径看为什么反过来省算力类分流重试上升单次开销下降很好看每成功任务成本上升重试的开销被摊进同一个成功任务摘要压输入轮次上升输入长度下降总量上升摘要本身是一次调用重问也是缓存高命中错答返工调用次数下降持平或上升命中在错答案上下游要重做一遍三种反转有一个共同点减法省下的是某一步的用量赔进去的是整条路径的用量。旧口径只量前者。看板要加的字段⚠️ 代码待验证defcost_per_success(events,human_rate:float)-float:ok[eforeineventsife.end_reasoncompleted]ifnotok:returnfloat(nan)total0.0foreinok:totale.model_coste.tool_cost totale.retry_cost# 重试归集到任务totale.human_seconds*human_rate# 人工折算口径要写进看板说明returntotal/len(ok)defcache_quality(events)-dict:hit[eforeineventsife.cache_hit_kind!miss]ifnothit:return{hit_rate:0.0,suspect_rate:0.0}suspect[eforeinhitife.cache_hit_kindhit_suspect]return{hit_rate:len(hit)/len(events),suspect_rate:len(suspect)/len(hit)}cache_hit_kind要能区分三种命中且被下游采纳、命中但下游重做、未命中。没有这一列缓存的收益永远算不清——你只看得到命中率看不到命中之后有没有被采纳。减法省下的那部分多数从没进过利润表。它进的是成本看板上的一个格子而那个格子的口径本身被减法影响过。用被减法影响过的口径评价减法结论必然是减法很好。七、落地顺序与观测三批拆批次范围前置条件验收回退方式第一批纯还原工具字段、检索边界、过短轮数窗口登记表填完cost_share双跑差异接近零返工率不升关开关当天可回第二批摘要替代原文、跨会话记忆、过度裁剪的少样本固定样本集、双跑能力通过率不低于基线成本变化可解释按租户回退保留前一批改动第三批省调用与省算力的默认值翻转、缓存键重构、批量粒度新口径看板上线、开关可按意图分一整周未触发回退按意图逐块回退第一批不需要重打基线因为预期输出不变。但要盯双跑差异差异不接近零说明你对这条减法的理解错了先停下查别继续往上加。第二批的验收标准里变化可解释比变化为正更重要。解释不了的变化无论方向都是问题——它意味着你有一个没被观测到的通路。第三批只动一层。省算力里的参数怎么调、路由表怎么排是另外的题目这里只定它在队列里的位置最后且一次只动一层。同时动两层回退时分不清是谁的锅。回退判断⚠️ 代码待验证defshould_revert(m:dict,base:dict)-tuple:ifm[fail_rate]-base[fail_rate]0.005:returnTrue,fail_rateifm[cost_per_success]base[cost_per_success]*1.10:returnTrue,cost_per_successifm[cache_suspect_rate]-base[cache_suspect_rate]0.01:returnTrue,cache_suspectreturnFalse,三个判据任一命中就回退不做加权。加权会给人留出综合判断的空间而综合判断在事故里等于拖时间。阈值是事先写进灰度配置的不是事后商量的。留下来的当降级档拆到最后代码不必删。每条减法留一个开关默认关容量紧张或者上游异常时打开。三个好处出问题有一档现成的降压手段省下来的逻辑不用重写减法从默认状态变成应急预案从此它有了归属——有人负责它的正确性有人负责它的触发条件。代价也要说清开关留着就有组合爆炸的风险。控制办法两条——同一时刻只允许打开同一类里的一个开关开关之间声明互斥每次打开都记一条事件带上触发原因和操作人。缺了这两条半年后你会有几十个谁也说不清状态的开关比当初那一堆减法更难维护。完整版资料清单三批拆除的顺序表、回退阈值清单和成本看板字段说明都在里面扫码即可获取附表 A关键取舍一览取舍本文结论判断依据位置该不该拆的判断标准看利息是否超过本金要两个比例多数团队只有一个第一章拆除顺序由什么决定由分类决定不由收益决定四类的可拍板层级不同第二章截断历史怎么处理默认全量超阈值才裁窗口调大只是推迟撞墙第三章摘要要不要保留原文原文留着做检索摘要降级成索引摘要不可回溯偏差直接进入生成第三章裁剪工具字段算不算省钱多数字段是结构不是内容省下的输入少返工多第三章去重与幂等能否拆不能假设成本为零也会这么做第四章缓存怎么拆不误伤先按用途分成省钱与一致性两类一刀切会把幂等一起拆掉第四章字段最小化能否拆不能与过审相关与成本无关第四章拆一处要动几样提示、缓存键、基线、看板漏掉任一项都会得出错结论第五章怎么证明没变差固定样本、双跑、规则判分历史基线被减法压低过第五章判分能否用模型自评不能提示变了自评偏好也变第五章成本分母用什么成功任务数调用次数把返工算成了用量第六章缓存看板加什么字段命中后是否被采纳只看命中率会高估收益第六章三批怎么分纯还原、需评测、动结构前置条件差别大第七章回退是否加权不加权任一命中即回加权等于拖时间第七章减法代码要不要删不删默认值翻过来留作降级档比删掉有用第七章开关数量怎么控同类同时只开一个且互斥否则组合爆炸第七章附表 B术语速查表术语含义减法为压成本而削减输入、调用、算力或次数的设计本金减法在当年省下的那部分开销利息减法带来的质量、延迟、可解释与维护代价省输入截断、摘要、裁字段、压缩检索结果一类做法省调用缓存、结果复用、请求合并一类做法省算力分流、低档位、量化一类做法省次数批量攒批、去重合并一类做法结构性减法关掉后输出会变错的设计不属于省钱手段纯省钱减法关掉后输出不变、只是更贵的设计减法登记表记录每条减法的比例、证据、归属与批次还原开关把某条减法按租户或意图单独关掉的开关双跑同一批样本在开关开与关两种状态下各跑一次缓存键决定一次请求能否复用存量结果的标识静默错答不报错但返回了按旧策略算出的结果每成功任务成本总开销除以成功任务数的口径降级档保留下来、默认关闭、异常时打开的减法写在最后这篇用到的资料写这篇文章时我把几个模型的官方文档、参数表和实测记录都对了一遍顺手整理成几份配套的东西大模型学习路线图从 LLM 基础到 Agent 开发各阶段该学什么、用什么资料大模型全套教程按主题分好的视频与文档清单大模型实战好书24 本附每本适合的阶段资料是我自己整理的放在下面这个码上扫码即可获取添加时备注「大模型」优先通过。拿到之后建议先看学习路线图那一份先定位自己在哪个阶段再决定学什么比一上来就啃框架效率高得多。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询