loading

Loading

探索与发现

首页 AI 开发实战

工具结果稀疏化回填:先抽骨架再补细节

字数: (3181)
阅读: (7)
0
摘要:统计说会话膨胀八成来自没压缩的工具输出。三种注入方式各有清晰的成本边界;稀疏骨架加按字段回填是一手资料能支撑的部分,压缩层该放在哪、哪些字段要读数,决定这套方案会不会让结构本身丢字段。

关键词是“稀疏化回填”,但我拿到手的一手资料主要讲的是工具输出的三种注入策略,以及压缩发生在上下文层的一个实际案例。所以这篇文章只谈第一手资料能支撑的部分:工具结果进入上下文前怎么变稀疏,稀疏之后靠什么把关键字段补回来,以及不同工具的压缩方式到底有哪些差别。凡是关于“检索时稀疏召回、重排再回填”的另一类技术路线,本文不作展开——资料不足。

问题不在上下文窗口大小

先看一组数字。有一篇讨论工具输出注入的文章提到,在2023年末,平均智能体会话长度不到2000个Token,到2025年末涨到5400个Token以上,增长的绝大部分来自工具结果的积累。同一个来源还指出,仅序列化格式不当(缩进、冗余包装、没人需要的元数据)就可能消耗40–70%的可用Token。

这是工具注入压缩问题:你要写入某条带表结构的交易记录时,不要先把整段JSON吐进上下文,而是先映射已使用的字段集合,再抽出交易记录的骨架与其它字段的空壳,然后把对应记录写入工作上下文。骨架保留原结构路径和字段名,未使用的字段只用计数表示,用于判断本次是否有新数据。真正参与判断的工作上下文反而更短。骨架有点像宽表的最稀疏子集,只保留参与结构、任务使用的字段,其余信息用“此处省略16834条记录”的表述代替。

代价是这套设计同时限制了正常路径与摘要路径,当筛选模型规模正好卡在稠密容量偏大的地方、schema可枚举、长期内存有用时,逐条回写需要两步:先拿骨架,再补细节。回写本身的缺省值、整数位宽与单次调用重复事务,都是只有接触真实数据时才暴露的问题,前期很难按消费端泛化出一套规划。

三种策略各自的边界

原文给出三种处理方式。原始注入不处理、直接塞进去;模型内压缩先用一个更小的模型概括;结构化字段提取按已知schema抽取需要的字段。

原文给出的启发式很直接:收敛所需输出且schema可确定的工具优先做结构化提取;输出本身就紧凑时用原始注入;两者都不适用再退回模型内压缩。注意这个顺序建立在一句话的前提上——“规范运行时链路不需要反向生成有效schema”。这条前提不解释完整会话里包含的各步骤为什么会出现、又会通向哪里,只看抽取能否稳定匹配已知解析逻辑。一条清洗管线把同一个关联ID的十几条原始记录汇总、取阈值判断、对嵌套轨迹做深层去重——这类变换输出的schema你说不清,只能走语义边界这条替代路径。

从读者视角看,模型内压缩会“平滑”掉数据里那些关键的边界情况。数值精度、丢失的位置边角数据都可能被静默丢掉。要用事实(见下文的重编技巧)来抵消这种解读:这部分只在压缩层算数。对大多数工作,摘要是按字段出现的层划定的;需要逐字精确回写的代码或ID没有被格式改成浮点或符号块之外的特殊字符,处理链路本身不会内建这种噪声。

成本结构也不一样。原始注入前期成本几乎为零,但下游往往被动叠加。模型内压缩在最坏情况下把每步成本翻倍,因为你付了一次生成、一次压缩两次钱。结构化字段提取在规则写好之后每次调用边际成本趋近于零,代价都花在前面(定义schema、梳理罕见分支、用真实输出测试)。还有一项隐性成本更容易被低估:工具改了输出字段之后,提取逻辑会悄悄失效,要等到上下文里的任务质量出现明显下降才会被发现。

模型已经在读什么,回填影响它在读的时候

有三种前端机制会让相同的写入在读者读到手时结果不一样。一种是按直接写复用的骨架档(真实数组直接补内容实现零拷贝);一种是包含深引用、同时作为判断依据的稀疏者。后一类里还能细分:模型原本可能先整体读出几条当参考,也可能先看到筛选后的嵌入——写成与查找的区别就在于读出与已有内容不一致的概率。

这就是稀疏写入里一个不太直白的设计约束(并非结论,而是一条设计条件)。有人反复搬仓库里的“旁路拷贝、不要就地改”那段(`if src.len() < some_th && dst_is_src(&dst, blob) { fallback }`),只是想弄清重建原字段的时候是否需要逐片合并。就有一条评论提到了真正值得挖的东西:后端只用`u8`接收slice索引、大数组下面有个辅助元数据窗口的那类布局,你要逐片读零值判断边界根本没可能——你看不出这是真实发送产生的新字段还是从下游沿用过来的。还有一个最典型的解释错误,就是当复制行为只在数值差异比较大时才触发,于是后面小数据缺失,让人以为字段没变。工具侧和页面都需要同一枚正则出来的记录写进来。

动手可以上手的几个数

原文里提到的几条线上数据,拿去做内部讨论时的标尺很省事。

  • 原文提过一个和上下文塞满相关的数字:以70B量级的模型为参照,延迟随载荷规模变化显著。上下文被纯填塞之后,模型回答的第一步时间会明显抬升。这个数字(719%)我不会复述为毫无办法,它适用的范围是模型规模与查询集合都已经绑好的前提;在本管线的启发式建议下想复现前先用压缩方式分层。
  • ACON(长周期智能体上下文压缩框架)把结构化抽取和选择性摘要接起来,原文给出峰值内存占用减少26–54%、任务准确率保持95%以上的结果。比这些数更重要的是它的层级形态:摘要针对短时对话这类转瞬切换的损失写内容为主。
  • AutoTool做的另一件事是动态选一个工具子集、而非压缩输出,每步上下文Token减少95%,端到端成本降低70%。这是不同的约束取法:你可以丢掉一部分探测请求,也可以在已有探测请求上压字。

这些结果来自受控环境,我并不想说生产环境也一样。但像上下文任务跨度这类信息能被单独剥离(而且是预算固定的条件下)这本身就能换算成另外一件要求:交给技能上限未知的任务时,想扩大自动决策的边界就必须先做好可滚动回填的方案。

该盯哪几条线

等出了问题再上压缩已经太迟。原文给了三个可直接搬进监控看板的数:被占用的上下文Token数上限除以总预算,连续几周在没有新增任务复杂度的情况下持续上涨,就是积累、可能也说明压缩没有生效;每次工具调用的抽取成功率,成功还回落到原始注入的比例,比例下降意味着schema该改了;按分布着的会话长度取值时,该看板的结论是随会话变长场景下的任务准确率最直接。

还有一条与内部实现相关的外部可观测信号:首Token时间随会话长度上升,意味着问题出在上下文处理部分而不是算力本身。第三条是针对具体工具算预算:如果一条脚本平均要8000个Token,一次会话里调用它20次,那就说明这个脚本在哪个管道分支里都得套一层压缩,不能因为“有结构化提取的优先级”就放着跳过。

我会从哪种演进路径搭

先做分层而不是一次拍板。第一层,对schema本来就能稳定确定的工具上字段抽取,把这类工具的输出映射到智能体实际要用的字段。第二层,只有面对输出确实庞大、结构松散、用程序识别相关部分很不方便的那少数几种工具,才放进选择性摘要。第三层在会话状态边界管控整体预算,接近剩余额度上限时在旧记录上打摘要,把最近几轮的原文信息保护为核心,原文最后那10%不拿去做压缩使用。按原文对应到同一编码长文的写法是:把大工具结果以外部引用的方式卸载出去,需要时由智能体主动发起取,而不是按固定启发式一刀切。这条路线对我更有说服力的地方在于,什么时候靠什么来读取对相关内容的把握,智能体看得比你的规则准;更直接的层级按大小与位置加判断,上下文丢的时候只会让人感觉这套规则怎么是往外飘的。

真正“稀疏化回填”在文献里通常指把结构化骨干细节抽出来之后照着字段补回内容。压缩在前端文件里的落地方式,是否该用一个很省事的小模型按JSON Schema里的默认数组把每条消费出的一条集合想清楚,我暂时没在下够资料里找到答案;但按语言分析的归纳来看,读一遍语句后补回来并不改变语境。别只省Token,先想想丢掉的是“没用的元数据”,还是把字段本身给丢了。

转载请注明出处: 皮哈皮阿

本文的链接地址: https://blog.phpat.com/ai-dev/628.html

手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

您可能对以下文章感兴趣
1 / 1
预览图