ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

多模态Agent效果不佳?关键在上下文工程与Skill设计

多模态Agent效果不佳?关键在上下文工程与Skill设计 多模态 Skill 写好了效果却出不来十有八九问题不在模型本身而在于上下文工程没跟上。我做了大半年的 Agent 开发从单模态文本工具一步步演进到能看图、听音频、读文档的多模态 Skill最深的体会是Agent Skills 的核心竞争力不在“能调哪个模型”而在“你怎么把多模态信息塞进上下文塞得干净、省钱、不打架”。这一篇是 Agent Skills 系列的第六篇我把它单独拆出来写就是因为多模态和上下文工程这两件事天然是绑定的。纯文本时代上下文工程最多算是“提示词写得长一点短一点”的问题一旦进入多模态图片要占多少视觉 token、音频怎么切、视频抽几帧、OCR 结果和图像特征要不要都放进去每一个决定都直接影响 Agent 的响应质量、延迟和成本。这篇文章适合正在做 Agent 平台、工具调用体系或者想深入了解多模态 Agent 如何落地的人。1. 多模态 Skill 的定位与设计思路1.1 为什么单模态的 Skill 已经不够用了我先讲一个我实际踩过的场景。早期我做一个商品详情理解 Agent输入的只有文本描述效果还行。后来业务方要求直接丢商品主图进来让 Agent 判断商品卖点、违禁词、构图是否合规。我发现原来的文本 Skill 完全接不住图像里的文字需要 OCR款式、颜色、风格需要视觉理解如果图里还带 logo 或者背景乱入单靠文本身份描述根本对不上。这就是多模态 Skill 存在的意义。它不是一个普通的工具函数而是一个能接收图像、音频、视频帧、文档版面等非文本输入并能把这些输入转化为模型可理解的表征或者结构化信息的能力单元。在设计层面它要回答三个问题输入什么是原始图片 bytes还是先经过预处理的特征文件输出什么是自然语言结论还是带有坐标、置信度、来源片段的结构化结果边界在哪哪些多模态理解交给基础模型哪些交给外围工具哪些需要 Skill 自己维护状态我在实际架构里把多模态 Skill 分成两类。一类叫“感知型 Skill”负责把多模态输入变成紧凑的信息描述比如“提取图片中所有文字及位置”“识别音频中的说话人轮次”另一类叫“推理型 Skill”它把感知结果和用户问题联合起来做决策比如“根据商品图判断是否涉及违规宣传”。感知型 Skill 的特征是结果确定性高、需要结构化输出推理型 Skill 特征是需要结合上下文、输出开放性高。这两类在设计时接口规范完全不一样我后面在实操部分会展开。1.2 多模态 Skill 在 Agent 体系中的位置很多人会把多模态 Skill 理解为“给 Agent 加一个图像 API 调用”这是一个很容易走偏的认知。Skill 不是一次性的 API 封装它在 Agent 体系里至少承担三个职责消息转换、能力复用、上下文结构化。消息转换指的是用户给 Agent 发来一张图片、一段语音Agent 的对话模型并不一定原生支持这些输入Skill 要负责把原始输入转成模型能用的文本、向量或结构化对象。能力复用好理解同一个图像解析 Skill 可以被商品审核、工单记录、内容安全多个 Agent 场景调用不需要每次重写。上下文结构化是我认为最值钱的部分Skill 的产物不是一段随口描述而是带有 schema 的结果比如{ image_id: sku_001, ocr_texts: [ {text: 有效日期至2026.12, box: [12, 340, 210, 360], confidence: 0.98} ], visual_tags: [暖色调, 极简风格], risk_flags: [] }这样的结构化输出可以直接被后续的决策逻辑引用也可以写进上下文供多轮对话继续使用。我在实际开发中要求所有多模态 Skill 的输出必须 JSON Schema 可校验否则不允许注册进 Skill 清单。理由很简单Agent 的后续步骤经常需要程序化判断如果 Skill 返回的是散文式描述下游解析会非常痛苦。2. 上下文工程从“写提示词”到“全链路管理”2.1 上下文工程和提示词工程到底差在哪我见过很多团队把上下文工程等同于提示词工程这是个误解。提示词工程关心的是“一段指令怎么写模型才听话”上下文工程关心的是“整个对话窗口里哪些信息放进去、哪些不放、以什么顺序放、怎么压缩、怎么让模型在长对话中不迷失”。用生活化的类比提示词工程是教一个人“听问题时注意哪几个要点”上下文工程是管理一个人面前的书桌。书桌上摆了什么、哪些资料叠在最上面、哪些旧笔记该收进抽屉、哪张便签是最新指令这些都属于上下文工程的范畴。多模态信息一进来这张书桌就变得特别容易乱图片动辄上千 token、OCR 结果动辄几十行、音频转录文本经常超长稍有疏忽上下文窗口就被低价值信息占满。我在做上下文工程时给自己定了四个管理维度预算Budget、分层Staging、压缩Compaction、缓存Caching。预算决定一次请求最多消耗多少 token分层决定系统提示词、工具定义、对话历史、多模态产物的优先级压缩决定什么时候把旧消息摘要化缓存决定哪些公共上下文可以复用省去重复计算。2.2 多模态上下文的分层与优先级多模态场景下上下文的优先级排序是有一套基本逻辑的我现在的排序规则如下第一优先级系统提示词和 Skill 定义。这部分是 Agent 的“行为准则”一般稳定不变。第二优先级用户本次请求中附带的原始多模态输入。图片、音频、视频帧必须完整保留因为这是当前轮次的核心任务依据。第三优先级与本次任务直接相关的工具返回结果比如刚才那个 OCR 结果、风险标签、检索到的文档片段。第四优先级最近几轮的对话摘要和历史结论。最低优先级早期轮次的原始对话记录和早期多模态产物。这样的排序不是在所有场景下都绝对正确但它能保证一个核心原则当前任务所需的事实依据优先历史过程性信息退后。我见过一个失败案例团队把 10 分钟前的产品原图一直留在上下文中结果新的问题变了、图已经换过模型却还在分析旧图Agent 输出的严重跑偏。后来我们规定多模态输入默认只保留在触发它的那一轮上下文里若后续轮次需要引用则必须显式通过上下文引用接口重新传入而不是默认全局留存。2.3 窗口预算计算一张图到底值多少 token多模态上下文工程绕不开一个基础算术题图片进视觉模型要消耗多少 token进纯文本模型又要多少。我基于常用开源视觉模型的通用口径给团队定过一个粗略换算表方便大家估算输入类型计量口径token 估算备注纯文本字符数/4约每千字 250 token中文适当上浮图片视觉模型图像块分辨率越高块越多常见 512x512 约 150300 token由视觉编码器决定图片文本模型描述文本取决于描述详细度建议结构化短描述音频每秒帧数1 分钟约 20004000 token取决于采样策略视频每秒抽帧数每帧按图片单价计算优先抽关键帧这个估算不是为了精确而是为了做决策。比如一次对话要处理 3 张 1080P 图片、一段 5 分钟音频、外加 20 页文档如果全部原始塞进去窗口直接被干爆。我建议的做法是先预处理后入上下文。图片先做尺度归一化和特征提取音频先做转录和说话人分离文档先做版面解析把高密度信息提炼成紧凑的结构化描述再送进上下文。3. 多模态 Skill 实操从特征提取到融合调用3.1 一个多模态 Skill 的代码骨架我在实际项目中实现过多模态 Skill下面给一个真实可落地的骨架以“商品图审核 Skill”为例。这个 Skill 的职责是接收商品主图输出结构化审核结果并且把结果写回上下文。核心代码结构如下from pydantic import BaseModel, Field from typing import List, Optional class OCRText(BaseModel): text: str box: List[int] confidence: float class ProductImageSkillInput(BaseModel): image_base64: str Field(..., description商品主图 base64) product_name: Optional[str] Field(None, description商品名称可选) class ProductImageSkillOutput(BaseModel): ocr_texts: List[OCRText] visual_tags: List[str] risks: List[str] decision: str Field(..., descriptionpass/review/reject) class ProductImageSkill: 多模态 Skill 示例图像理解 结构化输出 def __init__(self, vision_model): self.vision_model vision_model self._register_schema() def _register_schema(self): # 在 Agent 系统中注册输入输出 schema self.input_schema ProductImageSkillInput.model_json_schema() self.output_schema ProductImageSkillOutput.model_json_schema() def _preprocess(self, image_base64: str): # 压缩到统一尺寸避免 token 爆炸 # 实际项目里这里会缩放到 768px 以内 return normalized_image def execute(self, inp: ProductImageSkillInput) - ProductImageSkillOutput: # 1. 调用视觉编码器提取特征 image_feature self.vision_model.encode(inp.image_base64) # 2. 调用 OCR 模型提取文字信息 ocr_results self.get_ocr(inp.image_base64) # 3. 结合特征和 OCR 结果做融合判断 decision self._fuse_and_judge(image_feature, ocr_results) return ProductImageSkillOutput(...)这个骨架的关键点在于输入输出都用 Pydantic 模型校验Agent 在调用 Skill 之前就能确认参数类型和范围。execute 内部先做图片归一化预处理避免原图过大导致视觉模型 token 成本失控。视觉特征提取和 OCR 解耦方便后续更换不同厂商模型或者离线缓存特征文件。我在团队里推广这个骨架之后最大的收益不是代码量减少而是多模态 Skill 的接口变得可测试了。过去大家写完 Skill 直接在 Agent 里跑出了问题分不清是模型问题还是调用问题现在先单测 Schema再 mock 模型返回最后再联调 Agent问题定位效率翻倍。3.2 视觉特征提取与文本-图像融合多模态 Skill 的融合策略直接影响结果质量。我踩过一个大坑一开始简单地把 OCR 文本和视觉标签全部拼接成一段文字送给大模型做判断结果模型经常出现幻觉比如图像里根本没有“保质期到期”字眼模型却根据商品名称脑补出一个风险。后来我改用特征对齐 结构化引用的方式视觉特征向量和 OCR 文本都先经由各自的编码器映射到统一空间再通过交叉注意力融合融合结果带原始坐标引用让模型知道某个风险判断来自图片哪个区域。这样模型在做最终决策时不是凭空发挥而是基于带空间锚点的证据链。在实际代码里我不会强迫所有人实现交叉注意力对多数应用场景一个更简单的级联方案已经够用先跑视觉理解输出图片的客观视觉描述颜色、构图、物体、风格。再跑 OCR输出所有文字和位置。把两者连同下游任务要求一起组装成“证据块”图片区域 A检测到“有效期至2026.12”置信 0.98视觉风格暖色调、极简构图大模型基于证据块做推理输出结论。注意这里的关键是“客观描述优先主观判断后置”。不要让模型先从图片里脑补意义再拿着脑补结果做二次推理要尽量把感知层和推理层隔开感知层只回答“图上有什么”推理层再回答“这意味着什么”。这样不仅能降低幻觉率还能让同一个感知结果服务多个推理场景比如同一个 OCR 结果既可以用来做违禁词检测也可以用来做信息抽取。3.3 Skill 产物的上下文持久化与引用多模态 Skill 的产物不应该只活在函数返回里它经常要在多轮对话中反复引用。比如用户第一次发来一张电路图纸Skill 识别出图纸类型和元件清单用户后续问“这个电阻的阻值是多少”Agent 如果重新解析一次图纸既慢又费 token。我的做法是引入一个“上下文引用 ID”机制每个多模态输入的产物都有一个唯一 ID比如ctx://skill/product_image/20260518_001Skill 返回结果时带上该 ID并将产物写进短期记忆存储。后续轮次如果需要引用Agent 直接传引用 ID系统自动从存储中调取结构化结果进入上下文而不是重新上传原始图片。这个机制让我在开发“图纸识别”这类多轮 Agent 时节省了将近 60% 的 token 成本而且响应速度明显提升。不过要注意引用 ID 不能无限制缓存我会给每个引用设置 TTL 和最大占用 token超时或者超限就自动淘汰避免存储膨胀之后反而拖慢上下文组装。4. 上下文工程实操预算、压缩与缓存策略4.1 上下文组装流程先算预算再排序内容我在项目里落地了一套上下文组装流程基本思路可以概括为“四步走”。第一步计算本次请求的 token 预算。假设模型窗口是 128k我通常预留 25% 的余量给模型生成回答剩下 96k 是可用的输入空间。从这里再扣除系统提示词占用假设 6k和 Skill 定义占用假设 8k实际可分配给动态内容的额度就是 82k。第二步估算动态内容的原始占用。把用户当前轮的多模态输入、历史消息、工具返回结果分别估算 token 数。如果总和小于可用额度直接全量组装如果超了进入第三步。第三步按优先级分层裁剪。从最低优先级开始先对早期轮次做摘要压缩再对工具返回的大段数据做截断或字段级精简最后再考虑是否降低图片的分辨率。整个裁剪过程要可观测我会把裁剪前后的 token 消耗记录到日志方便复盘哪些内容经常被裁、哪些内容其实可以不用放。第四步组装并发送。组装时注意顺序系统提示词在前、Skill 定义其次、当前任务输入紧随其后、再是证据块、最后是压缩后的历史摘要。这个顺序可以让模型在处理长上下文时更关注前面的关键指令避免被后续大量历史带偏。4.2 异步检索与上下文压缩的取舍上下文压缩不是简单的“把旧消息变成摘要”。我试过几种压缩方案最失败的是“每轮都把所有历史消息无脑摘要一遍”。这样做的结果有两个问题一是摘要本身消耗时间和 token二是模型每次看到的都是经过二次加工的信息细节失真很严重。我现在用的策略是分层压缩 按需检索。分层压缩指系统提示词和 Skill 定义从不压缩最近 N 轮直接保留原始内容更早的轮次按会话主题分桶每个桶生成摘要超过阈值的桶进入长期记忆存储只保留摘要。按需检索指模型在推理时如果发现当前问题需要某个早期细节比如用户第一轮提到过“预算不超过一万”可以通过检索 Skill 从长期记忆里把相关片段找回来重新注入上下文。这种设计的取舍在于短期对话追求“直接可用”不做过多的加工长期记忆追求“能找到”检索命中即注入。它比全量压缩的传统方案更适合多模态 Agent因为多模态产物往往不是几句话能概括完的摘要化处理经常损失空间坐标、置信度、边界框这些关键信息。我一般只对纯文本对话历史做摘要多模态产物优先保留结构化描述实在要压缩时会明确标注“这段内容是压缩后的近似描述引用前最好再核验”。4.3 上下文缓存的工程落地上下文缓存通常叫 prompt caching是控制成本的大杀器但在多模态场景下很多人用不对。缓存的核心逻辑是如果一段上下文在多个请求之间完全一致就可以复用模型侧的 KV 缓存省去重复计算前序 token 的时间。对文本 Agent最容易缓存的就是系统提示词和工具定义对多模态 Agent我还额外缓存了前三轮已处理过的图片特征。我在落地时遇到的第一个坑是图片 base64 每次上传都不同哪怕图片自己没变只要 base64 字符串里面有差异缓存就失效。后来我要求上层客户端对图片做内容哈希哈希相同就复用缓存特征文件不再重新上传。上传前的图片统一做归一化尺寸、压缩格式保持一致进一步增加缓存命中概率。第二个坑是缓存命中与上下文顺序强相关。如果两个请求的上下文前缀顺序不一致缓存很难命中。我为此把上下文组装做成了确定性流水线固定顺序、固定格式、固定分隔符任何变更都通过版本号管理。这样在调试缓存命中率时我能快速定位到底是哪一段前缀变了导致 cache miss。5. 常见问题与排查技巧实录5.1 多模态上下文“特征打架”与幻觉来源我梳理了几个多模态 Agent 上线后最容易翻车的场景按出现频率排序现象根因排查方向模型反复描述图片里并不存在的文字OCR 与图像描述不交叉校验模型相信了幻觉文本检查 OCR 置信度阈值低于阈值的文本加“疑似”标记历史图片影响当前轮判断早期图片未及时移出上下文检查上下文组装日志确认多模态输入是否超出了有效作用域图片信息丢失模型只说“看不清”图片压缩过度或分辨率设置过低查看预处理后的实际尺寸与 token 数多轮回复中前后矛盾上下文摘要压缩导致细节失真检查压缩轮次必要时强制保留证据块原文这里面最高频的就是第一个。我印象很深的一次事故是一张商品包装图上有处印刷模糊OCR 置信度只有 0.6模型却把它当成“保健食品”字样然后基于这个错误认知输出一堆风险提示。之后我给 Skill 加了规则OCR 置信度低于 0.9 的内容不能作为推理证据只能作为“待确认文本”列出。改完后同类问题大幅下降。5.2 多模态 Agent 的性能与成本优化清单结合我的实操经验整理一份可直接参考的性能与成本优化清单图片统一缩放到模型支持的最佳分辨率不要传原图。优先使用特征文件缓存相同内容哈希的图片不重复编码。音频先用 VAD 检测有效段落去掉静音后再转录能省 40% 左右的处理时间。视频做抽帧时先跑场景切分只保留切分关键帧避免全部帧平铺。Skill 的返回结果全部结构化同一能力不反复输出长篇文本。历史消息压缩前先统计 token 占用动态调整压缩触发线。无价值的历史工具调用记录比如失败的中间尝试直接丢弃不写入摘要。上线后持续监控上下文组装时间异常飙升时优先查缓存命中率。我把这些优化点固化成了一个“上下文工程基线”任何多模态 Skill 上线前都要过一遍这个清单。它能保证你不会在项目初期就背上无谓的成本和延迟同时把问题留到真正需要精细化的时候再逐项去调。6. 一点个人心得多模态 Skill 与上下文工程本质上都是在做同一件事让 Agent 在有限的信息空间里放最有价值的信息。模型能力决定上限上下文工程决定你实际能摸到多高的上限。我见过不少团队在模型选型上舍得花钱却在上下文设计上很草率几个 Skill 的结果不加整理地全堆在对话里最后效果还不如别人用差一档的模型但做了精细裁剪。从实际项目里走过来我最想分享的一句话是上下文工程没有一次性的完美方案它需要你持续观察、持续做减法。每加一个新的多模态 Skill都值得重新审视一次上下文预算、缓存策略和压缩规则。后续我还打算继续拆解 Agent 记忆机制和多模态特征文件的落地细节如果你也在做这方面的东西欢迎一起交流。
返回列表