多模态Agent Skills上下文工程:特征对齐与Token预算管理 做过一段时间带多模态输入的 Agent Skills 落地之后我有一个很直接的体会真正的难点往往不在“技能内部应该怎么回答”而在“多模态信息以什么形式、什么顺序、多少体量进入技能上下文”。传统提示词工程关心的是“话术怎么组织”但多模态Skill加进来的图像、音频、传感器时序、视频帧逼着我们把注意力转移到上下文工程上。这篇文章会围绕Agent Skills框架梳理多模态处理与上下文组装的实操路径从特征抽取、时序对齐到token预算分配再穿插一个真实的多模态情感分析踩坑案例。适合正在为Agent设计多模态技能、或者被上下文混乱问题折磨的开发者阅读。1. 从提示词工程到上下文工程多模态技能为何重新定义边界1.1 提示词工程管不了多模态在纯文本Agent时代“提示词工程”的核心是把问题讲清楚。系统指令怎么写、Few-shot示例放几个、否定词如何措辞这些确实能显著改变模型输出。但纯粹文本输入只是大模型最舒服的一种形态一旦技能要接收一张设计图纸、一帧工业摄像头画面或者一段环境音频事情就完全不一样了。原因很直白模型做不到“凭文本理解像素”。一张1280乘以720的RGB图像落到模型视角里是几十万甚至上百万个数值即便视觉编码器压缩之后也仍然是一大块与文本完全不同分布的信息。音频切片更特殊它既没有自然语言那种词汇边界也没有图像那种空间结构不经过ASR或者音频编码器模型几乎无法直接消费。于是“把问题说清楚”变成“把输入变成模型能消化的信息结构”这就是上下文工程出现的背景。我自己的经验是提示词工程仍旧重要但它从主角变成了配角。多模态Skill的成败首先取决于你给模型装配了什么上下文其次才取决于你怎么在上下文中措辞。一份把“图像描述”“音频转录”“历史属性表”乱序堆叠的上下文即便提示词打磨得再精致模型也容易在里面迷失重点。1.2 上下文工程的三层操作把多模态技能做好我习惯把上下文工程拆成三层操作每层都有独立决策点。第一层是内容选择。不是所有多模态数据都有资格进上下文。5分钟的视频没必要把每一帧都塞进去30秒的音频也不是所有段落都要转录。我们要做的是抽帧、切片、过滤无效信号只保留包含任务关键信息的片段。这个阶段常常被忽略大家更愿意在模型侧想办法实际上在输入端少放垃圾比在模型侧做排除法有效得多。第二层是表达转换。选中的内容用什么形态表示直接决定模型的理解难度。这里有三条路线可以选路线A原生多模态直读直接把图像、音频交给原生多模态大模型。优点是信息损失最小缺点是token消耗高、延迟大而且很多上下文工程技巧无法施加在这类输入上。路线B外挂模型转文本用视觉模型生成图像描述用ASR生成语音转录再拼接成文本上下文。优点是可控性高适合结构化输出缺点是有信息损耗描述不出来的细节就丢了。路线C特征向量化检索用CLIP这类模型把不同模态映射到同一个向量空间存入特征文件任务到来时先检索相关性最高的片段再把片段转成上下文。第三层是装配策略。信息选定、形态确定之后还要决定排列顺序和层级。多项研究都表明模型对上下文开头和结尾的内容更敏感对中段内容容易“一带而过”。所以核心约束、输出格式、必须遵守的硬规则要放在上下文两端检索到的支撑细节放在中段而且要按重要性从高到低排布。这不是玄学是注意力机制带来的工程结论。2. 技能内部的上下文协议把多模态信息接口化2.1 给多模态Skill设计输入槽位Agent Skills真正有工程价值的点在于“可复用”和“可被调度”。多模态技能如果没有明确的输入协议调度器根本不知道这个技能能不能处理当前任务。所以我在项目里会给每个多模态技能定义输入槽位schema声明允许的模态类型、数量上限和时长限制。下面是一个情感评估技能的真实schema简化版本{ skill_name: multimodal_emotion_assessment, version: 0.2, input_slots: [ { name: transcript, type: text, required: true, description: 对话转写文本 }, { name: frame_paths, type: image_list, required: false, max_count: 8, description: 关键帧图片路径列表 }, { name: audio_segment, type: audio_segment, required: false, max_seconds: 30, description: 待分析的音频切片 }, { name: attribute_table, type: table, required: false, description: 说话人属性与历史状态 } ], context_policy: { compression: hierarchical, retrieval_key: clip_embedding, time_alignment: timestamp_tolerant } }定义这样的结构有两个直接收益。一是上层调度器可以精确判断“目前收集到的多模态数据是否匹配这个技能”二是在上下文组装前技能内部可以先执行一轮合规性校验防止把格式错误的数据交给模型。很多线上多模态技能输出不稳定查到最后都是输入校验缺失比如图片路径为空、音频切片时长超限导致模型看到一堆残缺上下文。2.2 上下文首尾块与中间检索块有了输入槽位下一步就是组装策略。我这里用“首尾块固定、中段按检索填充”的方式来组织上下文。首块放不可动摇的内容技能目标、任务约束、输出JSON结构。这部分必须完整、稳定不随输入变化而重写。尾块放“当前输入摘要”包括模态数量、各模态对应的文本总和以及硬性要求比如“如果音频与文本时间戳不一致请优先采用文本时间戳”。中间块才是检索出来的多模态片段描述。这样做的原因还是注意力分布。如果指令被淹没在大量图片描述和音频转录中间模型很可能在中途丢失约束。而把约束固定在两端即使中间做了上下文截断核心规则也不会被裁掉。这个细节几乎每次都能在效果评测里拉开差距。3. 多模态特征的对齐与统一表达3.1 为什么需要统一表达空间多模态任务麻烦的地方在于不同模态的信息密度和语义粒度不一致。文本说“画面中有一把雨伞”图像里可能还包括雨伞颜色、纹理、周围人行道积水等大量文本没提到的细节。如果只是简单拼接文本描述模型很难判断哪些信息可靠哪些信息只是辅助。统一表达空间是解决这个问题的常用方案。以CLIP为代表的图文对齐模型把图像和文本映射到同一个向量空间让“雨伞图片”和“雨伞文字描述”在空间距离上接近。这样技能内部就可以用余弦相似度计算输入与任务的关联程度先检索出真正相关的片段再组装上下文。换句话说多模态信息不是一股脑全塞给模型而是先做一轮“相关性排序”。这就像你同时拿到了几份不同语言的说明书先统一翻译成一份索引目录再找最相关的几页放进正文。3.2 特征文件与缓存设计在实际业务中特征抽取是计算密集操作。每一帧图像过CLIP视觉编码器单次并不贵但数量一多实时推理就会立刻拖慢整个Agent的响应速度。我的做法是离线预处理把所有候选图像、视频帧先行抽取特征保存为独立特征文件并建立缓存索引。一份特征文件通常包含三块内容模态ID与来源路径用于追溯原始数据特征向量本体一般是float数组维度视模型而定元信息包括时间戳、采集位置、清晰度标记等当Agent收到多模态请求技能先读取对应特征文件通过向量检索选出Top-K相关片段再把这些片段的描述文本组装进上下文。这样实时请求中就不再包含大矩阵计算延迟主要发生在向量检索阶段。配合向量数据库或者简单的numpy近似检索可以在几十毫秒内完成候选筛选。3.3 时序对齐与“多模态记忆是否包含4D”多模态任务里最隐蔽的坑就是时间轴不一致。文本转录里的一句话可能对应视频第10秒到第12秒而模型处理时如果不知道这个边界就会把这句话和完全无关的画面绑定在一起。所以技能内部必须做时序对齐。我的实操经验是三条规则第一统一时间戳精度。文本、图像、音频切片都必须用同一时间基准精确到毫秒级。如果ASR输出偏移先做一次整体漂移校正。第二设计一个容差窗口。比如“当前文本片段只与时间戳落在±2秒范围内的帧关联”超过窗口的帧不进上下文。容差窗口太大会引入噪声太小会丢失内容需要结合数据特性调整。第三建立回退策略。当对齐置信度不足时宁可丢弃强对齐要求也要保证主模态的完整性。比如音频与文本对不上那就退化为“文本全局视觉描述”而不是强行拼接出错误的时间对应关系。这引出一个经常在社区被问到的概念多模态记忆是否包括4D如果空间加时间一起算作第四维那答案是肯定的。但在工程实现里我不会把4D当成一个整体张量去存而是拆成“空间特征时间戳索引”。每个片段携带起始时间和结束时间检索时先按时间窗口过滤再按向量相似度排序。这个设计比单纯维护一个4D张量更灵活也更容易与现有检索链路集成。4. 上下文预算管理为多模态请求分配token配额4.1 token消耗到底怎么算多模态上下文和纯文本上下文最大的区别是体量不可控。一段5000字的文本token数基本可预估但一个图像列表、一段音频切片token消耗取决于编码器、分辨率、时长和模型版本。如果技能层不做预算管理上下文很容易在不知不觉中溢出然后触发截断策略把重要信息拦在窗外。我这里有一个粗略的估算表具体数值会随模型变化但量级可以用于预算规划输入类型体量约等于token数备注纯文本转录500字350-450 token中文按词粒度浮动单张图像224x22480-100 token取决于视觉编码器图像关键帧8帧640-800 token建议设置帧数上限音频切片转录30秒180-300 token以ASR输出字数为准检索结果片段3段150-250 token与向量维度无关拿到这张预算表实际评估就简单了。比如一个技能输入包含8帧图像、30秒音频转录和一段历史属性表粗略估算已经超过1500 token再加上系统指令和输出约束很可能逼近窗口上限。这时就必须压缩。4.2 分级压缩策略压缩不是简单裁剪而是分层降级。我给技能内部定义了三个压缩层级L0原始细节保留完整的图像描述、完整转录、全部属性字段。用于对细粒度信息有高要求的任务。L1摘要压缩图像只保留关键物体与空间关系转录只保留主谓宾和高置信情绪词属性表只保留与当前任务相关的字段。L2关键词级只输出模态类型、核心实体、情感极性三个维度其他全部丢弃。技能运行时会根据当前任务类型和上下文剩余长度自动选择合适的层级。任务要求“识别图纸上的标注文字”那图像必须走L0任务要求“判断这段对话里用户的整体情绪倾向”图像可以走L1音频转录甚至可以走L1把预算留给情绪关键词。4.3 截断时永远先保护指令无论预算怎么压缩总有可能遇到极端输入把窗口占满。此时截断顺序要有明确规则。我的原则是先裁检索结果片段再裁历史属性表再裁音频转录最后裁图像描述系统指令与当前输入摘要绝对不裁。原因不难理解。系统指令是底线规则裁掉之后模型可能连输出格式都保不住。当前输入摘要是本次请求的核心目的裁掉之后任务本身就失效了。而检索结果和历史属性属于辅助支撑缺失时模型仍然可以基于核心输入给出结果只是细节会粗糙一些。这个优先级顺序建议写死在技能上下文策略里不要每次现场判断。5. 一次真实踩坑多模态情感分析中的上下文破碎5.1 症状情感标签准确率直线下降有一次我在给一个多模态情感分析Agent技能做优化输入是对话转写文本、视频关键帧和音频切片输出是情感极性标签。初版上线后文本单模态准确率在可接受范围内但一旦加入关键帧和音频准确率反而显著下降。这个反直觉的结果很值得复盘。当时上下文组装顺序是“文本转录图像描述音频转录情感标签示例”。从排版看信息一个不少结构也算清晰。但真实效果是模型经常输出自相矛盾的结论比如文本说“很满意”图像里有皱眉动作模型最终给出负面情感。单独看每个模态都没错合在一起却拼出了一个错误结论。5.2 根因时间轴不一致导致上下文错位逐段排查后发现问题出在时间对齐而不是模型能力。ASR服务对这段对话的转写带有固定偏移某句话标在了第10秒实际发音发生在第8秒而关键帧抽取的时间戳来自另一套处理管线两套时间基准差了近3秒。于是模型看到的“文本第10秒的正面词”与“图像第8秒的负面表情”被强行配成了一对信息层面出现了矛盾。更深一层是技能上下文里没有声明时间戳边界。模型无从知道哪个片段该配哪个片段只能把几个模态全部视为围绕同一时刻。这就是典型的多模态上下文破碎每个片段本身没问题但时间关系断裂后上下文整体语义就失真了。5.3 修复容差窗口与模态优先回退修复分三步。第一步在文本片段和视频帧描述中统一加入时间戳前缀例如“[t10.2s]”。第二步在技能指令里写明对齐规则文本片段只与时间差小于2秒的帧关联超出容差窗口的帧视为噪声不参与当前片段推理。第三步增加模态回退逻辑当音频文本与视觉帧时间戳无法对齐时默认丢弃关键帧细节保留文本在情感判断中的优先权。修复前后对比非常明显项目修复前修复后时间戳无对齐随机错位统一时间基准加±2秒容差音频-文本-帧结合全量拼接按时间窗口动态关联文本情感准确率81%84%多模态结合准确率73%86%上下文token消耗15801120多模态结合的准确率不仅超过了纯文本还因为去掉了冗余帧token消耗也降低了四分之一。这个案例让我确信多模态技能优化的第一杠杆不是换更强的模型而是上下文结构是否真正做到对齐与收敛。6. 经验沉淀与工具链参考6.1 多模态技能不是越全越好我在项目里逐渐形成了一条原则技能处理哪种模态应当由任务目标倒推而不是由数据可得性决定。如果任务本身是文本语义判断音频和图像即使存在也不必全部编进上下文。增加模态意味着增加对齐难度和token消耗除非信息增量足以抵消成本否则保持克制更明智。以Agent Skills的调度场景为例一个优秀的多模态技能应该像一把专用工具而不是瑞士军刀。收到图像处理任务调用专门处理图像的技能收到语音任务调用带ASR转写和情绪关键词提取的技能。让同一个技能同时处理所有模态会变成“什么都处理什么都处理不精”。6.2 上下文构造链路要可测试多模态技能和纯文本技能在调试方式上有一个显著差异纯文本技能改提示词就能看到变化多模态技能则要验证中间数据。图像描述是否准确、音频转录是否漏词、时间戳是否一致这些都可能干扰最终结果。所以我会把每个多模态技能的上下文构造过程拆成独立函数并为每一步设计单元测试。比如模拟一段“转录文本包含皱眉帧”的输入断言组装后的上下文中是否出现时间戳并列结构。有了这层保障线上效果波动时就能快速定位是特征抽取问题还是装配顺序问题。6.3 常用工具链参考以下组合在我几个项目里都验证过稳定性供参考FFmpeg负责视频抽帧、音频切片、格式统一Whisper或同类ASR负责音频转文本与词级时间戳CLIP或SigLIP负责图像/文本统一向量化与检索排序向量检索件如轻量实现负责特征文件索引与相似度召回缓存数据库负责存储特征文件与中间描述文本重复请求直接命中整个链路排下来最值得花时间打磨的其实不是模型选择而是“特征文件怎么命名、时间戳怎么存储、检索结果怎么转上下文”这几个约定俗成的细节。把这些约定固定下来技能的可复用性会高很多。我个人体会是多模态Skill的复杂度是藏不住的它会把上下文工程的每个缺陷都放大。尽早定义输入协议、统一时间基准、建立压缩层级比临时调提示词要可靠得多。如果你正在做类似的多模态Agent技能建议先把上下文组装链路画清楚再考虑接更多模态源顺序颠倒的话大概率会掉进同一个坑里。