在评测多模态大模型时我们经常陷入一种“分数越高越好”的惯性思维。一张图表截图、一段产品界面、一张医学影像模型回答得头头是道指标刷得很漂亮。但你有没有想过一个问题它真的“看”了这张图吗还是仅仅依靠问题文本和训练时见过的相似答案就猜出了正确结果这不是抠字眼。这直接关系到你把它接入 Agent、自动化流程或数据分析管线后它是稳定可靠的视觉推理组件还是一个包装精美的“猜答案机器”。最近有一项研究以The Illusion of Visual Tool-Use: A Causal Audit of Thinking with Images为题把矛头对准了这种表面能力。它提出了一个很关键的概念视觉工具使用的幻觉。我对这个方向的判断是多模态模型目前真正的短板不是“看不见图像”而是“看见了但不必依赖图像也能作答”。传统评测方式用“准确率”衡量结果正确性却很难回答一个更本质的问题——输出究竟在多大程度上是由图像内容导致的。因果审计Causal Audit正是为回答这个问题而生的评测范式。这篇文章会把这个概念拆开讲清楚三个核心问题什么是 Visual Tool-Use它的“幻觉”到底产生在哪一层。因果审计Causal Audit是怎么通过干预和扰动把“相关性分数”变成“因果性证据”的。我们自己动手怎么用 Python 设计一个最小可用的视觉因果审计实验避免被模型表面的强表现误导。如果你正在做多模态 Agent、图像理解类的应用落地或者想建立一套更可靠的模型评测体系这篇文章可以帮你少走不少弯路。1. 这篇文章真正要解决的问题先不看概念看场景。假设你要做一个自动化数据分析助手。用户上传一张数据图表助手需要读取坐标轴、识别趋势、对比柱状高度最后生成结论。你选了一个多模态大模型拿公开榜单上的测试集跑了一遍准确率 85%看起来不错。于是你把它接进生产环境。结果上线第一天用户传了一张手绘草图信息量很少模型却仍然给出了一段非常完整的分析结论——里面有“环比下降”“峰值出现在 3 月”这类具体描述。你仔细一看数据图上根本没有这些信息。问题出在哪大概率是模型在训练阶段见过大量“图表加结论”的文本对它学会了从问题文本的统计线索里推断答案而不一定真的一步一步“看图”。当图像内容与文本提示高度相关时它还能蒙对一旦图像变成低信息量、模糊、故意误导的输入它就开始暴露真实水平。这个现象的学术表达就是视觉工具使用的幻觉模型表现上像是在调用视觉工具、利用图像信息进行推理实际上只是在套用文本先验和训练分布中的相关性。所以要解决的问题很明确为什么传统 benchmark 无法暴露这类问题用什么方法能区分“真看了图”和“没看图也能答”我们在实际项目中怎么验证一个多模态模型真的有视觉推理能力因果审计就是这个问题的答案。2. Visual Tool-Use 的核心概念模型到底有没有在“用眼睛”2.1 什么是 Visual Tool-Use“Visual Tool-Use”直译是“视觉工具使用”。要理解这个概念先看多模态模型的工作方式。现在主流的大语言模型在接收图像时通常会把图像切成 patch通过视觉编码器如 ViT转成视觉 token再与文本 token 一起送入语言模型。从工程上讲模型确实“看到”了图像——图像的像素信息进入了计算图。但“看到”不等于“利用”。在推理过程中模型回答问题时语言模型部分会根据所有 token包括视觉 token计算下一个词的概率。问题是这些视觉 token 到底贡献了多少决策权重如果模型在训练时见过海量“问题文本-答案文本”的配对它完全可以在视觉 token 信息量不足的情况下靠文本上下文猜出答案。举个例子用户问“这张图中哪个季度的销售额最高”模型如果能在图中找到“Q3 标签”并比较柱状图高度这是真正的视觉工具使用。 但如果模型只是根据“销售额 年度 季度”这类词直接预测答“Q3”因为它训练数据里“最高销售额”经常和“Q3”共现那它不是在看图是在猜。Visual Tool-Use 的理想状态是指模型主动地将视觉信息作为推理的证据来源。而幻觉状态是模型看似在模仿这个行为实际推理路径与图像内容无关。2.2 “Thinking with Images” 指的不是“看图”这个点很容易被误解值得单独解释。Thinking with Images 不是说模型有图像输入就叫“用图像思考”而是模型要能围绕图像进行多步骤推理第一步从图像里定位相关区域第二步提取区域中的数值、符号、空间关系第三步结合问题要求做逻辑推断第四步检查结论与图像显示是否一致。这是一个完整的认知链路。任何一个环节缺失模型都可能“跳步”。很多模型在单步任务上表现不错比如“图里有什么物体”“这是什么场景”。但这类任务对文本先验的要求很低模型只要捕捉到物体标签分布就能答对。而一旦进入“两个柱子的具体差异是多少”“这张图与那段文字描述是否矛盾”这类任务模型就必须真正利用视觉信息。所以判断模型是否具备 Thinking with Images 的能力不能只看它能不能对图说话还要看它能不能基于图完成因果推理。2.3 视觉工具使用的幻觉到底是怎么产生的根据我的理解幻觉的产生有三个层次第一层训练目标只要求“输出正确”多模态模型在大规模数据上做下一词预测训练信号是文本输出与标注是否一致而不是“模型在计算时是否真的参考了图像区域”。只要输出对了不管模型用的是文本捷径还是视觉证据都会得到奖励。第二层文本先验过于强大语言模型本身是在海量纯文本上预训练的。比如问“一张图表上有两条线描述趋势”哪怕看不到图模型也知道一般会写“先上升后下降”“整体波动”这类话。这种文本先验在视觉任务上形成了一种“隐藏的正确答案”。第三层评测指标不敏感传统评测计算准确率、F1 分数只关心输出与标签是否匹配。如果问题文本和答案之间有很强的统计相关模型即使完全不看图像也能拿高分。评测指标无法感知模型的“思考路径”。三个层次叠加就会出现令人困惑的现象模型在视觉 benchmark 上分数不错但当你把图像裁剪、旋转、替换成无关图时模型的输出几乎不变。这就像一个学生不看题目也能答对选择题——说明他背的是题库不是学会了知识。3. Causal Audit 因果审计把“猜对”和“做对”分开如果准确率不能区分“真看”和“猜对”该怎么办答案是做因果审计。3.1 因果审计的基本思想因果审计借鉴了因果推理Causal Inference的思路。它不满足于观察“输入图像 X输出答案 Y”之间的相关性而是通过干预输入观察输出是否发生预期的变化。核心逻辑是如果模型真的依赖图像内容来回答问题那么当我们改变图像的关键信息时模型的输出应该相应改变。如果改变图像后输出几乎不变说明图像输入对输出没有因果影响力——模型是在走文本捷径。用因果语言说相关性图像里有“红色圆形”模型回答“苹果”两者同时出现。因果性因为我改变了图像把“红色圆形”改成“绿色圆形”输出才从“苹果”变成“梨”。输出变化是由图像干预导致的。Causal Audit 要做的事就是系统地制造这种干预量化输出对图像变化的敏感程度。3.2 干预方式遮挡、扰动、替换、反事实我们不需要复杂设备用几类图像变换就能做因果审计。干预类型操作检测目标遮挡干预遮盖图像中的关键区域模型是否依赖关键视觉区域扰动干预添加噪声、模糊、改变颜色模型是否对像素变化过度敏感或完全不敏感替换干预用无关图像替换原图模型是否仍输出与文本相关的答案反事实干预修改图中具体数值、标签、空间关系模型是否能根据具体变化调整推理文图互换交换文本描述与图像匹配关系模型是否会“盲从文本”忽略图像矛盾其中“替换干预”最直观。如果你把一张“柱状图”换成一张“风景照”模型的回答仍然是一段完整的“数据趋势分析”那就可以断定视觉输入没有参与推理模型是在用文本自问自答。3.3 因果审计的量化指标为了让审计结果可衡量我建议引入一个简单的指标视觉依赖度Visual Dependency Score。定义方式S 1 - (扰动后答案与原答案的一致性 / 扰动前正确答案的基线一致率)当 S 接近 1说明模型输出高度依赖图像内容——它是真正在看图当 S 接近 0说明模型输出与图像变化无关——它在使用文本先验。这个指标不复杂但在工程评测里非常实用。它能帮你快速筛选出“高分低能”的模型。4. 设计一个最小因果审计实验理论知识说完了下面我们动手做实验。实验目标验证一个多模态模型在图表问答任务中是否真的依赖图像信息还是只是根据文本先验猜测答案。4.1 实验设计思路我们准备三组输入原始图一张柱状图Q1-Q4 季度销售额逐季上升。扰动图把图像上下翻转。无关图替换成完全无关的风景图。问题固定为“哪个季度的销售额最高”如果模型真在看图原始图回答 Q4翻转后的图回答 Q1无关图应该无法回答或给出“图中没有相关信息”。如果模型在猜三张图的回答会高度一致都是“Q4”。这个设计能直接暴露模型的推理路径是否依赖视觉内容。4.2 环境准备我建议使用 Python 3.9安装以下依赖pip install pillow torch transformers openai如果你的多模态模型通过 API 调用例如 OpenAI 的 GPT-4V、或者国内可用的多模态 API用openai库即可。如果是开源模型用transformers加载本地模型。下面代码示例已做了通用化处理你只需要替换成自己的模型封装函数。4.3 构造扰动图像# 文件路径build_distractor.py from PIL import Image, ImageOps def build_distractor_images(img_path, save_dir): 生成三种扰动图像 1. 原图 2. 上下翻转图 3. 高斯模糊图 img Image.open(img_path).convert(RGB) # 原图 img.save(f{save_dir}/original.png) # 上下翻转 flip_img ImageOps.flip(img) flip_img.save(f{save_dir}/flip.png) # 高斯模糊这里用 resize 模拟模糊效果避免额外依赖 small img.resize((img.width // 8, img.height // 8)) blur_img small.resize((img.width, img.height), Image.LANCZOS) blur_img.save(f{save_dir}/blur.png) print(扰动图像生成完成)这里用了两个简单的变换翻转和模糊。翻转会破坏柱状图的空间语义模糊会降低图像细节的可辨识度。两者都能有效测试模型对图像信息的敏感程度。4.4 调用模型并对比输出下面的代码是一个通用评测脚本。关键点是把“模型调用”封装成一个函数方便替换成你自己的模型客户端。# 文件路径causal_audit.py import base64 import json from openai import OpenAI # 这里的 client 需要根据你的实际模型服务配置 client OpenAI(base_urlhttps://your-api-endpoint/v1, api_keyyour-api-key) def image_to_base64(path: str) - str: with open(path, rb) as f: return base64.b64encode(f.read()).decode(utf-8) def ask_model(image_path: str, question: str) - str: 调用多模态模型输入图像 问题返回文本回答。 如果你用的是开源模型可以换成 transformers 的推理代码。 base64_image image_to_base64(image_path) response client.chat.completions.create( modelyour-model-name, messages[ { role: user, content: [ {type: text, text: question}, { type: image_url, image_url: {url: fdata:image/png;base64,{base64_image}} } ] } ], max_tokens100 ) return response.choices[0].message.content.strip() def run_audit(images: dict, question: str): 对多张图像运行同一问题输出对比结果。 results {} for name, path in images.items(): answer ask_model(path, question) results[name] answer print(f[{name}]: {answer}) return results if __name__ __main__: images { original: distractor/original.png, flip: distractor/flip.png, blur: distractor/blur.png } question 哪个季度的销售额最高请给出季度名称。 run_audit(images, question)这段代码的逻辑很简单同一问题三张图三次调用输出三次回答。真正有价值的是如何解读结果。4.5 判断实验结果我们需要制定一个判断标准。模型表现结论原图答 Q4翻转图答 Q1模糊图无法确定模型真正依赖视觉信息具备视觉推理能力三张图都答 Q4模型存在视觉工具使用幻觉输出不依赖图像翻转图和原图回答一致但模糊图回答不同模型依赖低层视觉特征但空间推理能力弱这只是最小实验但它已经能帮你筛掉相当一部分“假装看图”的模型。5. 从“能看图”到“会思考”严格任务设计与评测集上面的最小实验能测出模型是否依赖视觉信息但还不足以证明模型具备 Thinking with Images 的能力。要测试后者我们需要更严格的任务设计。5.1 任务一文图矛盾检测这是最容易被忽视的任务。给模型一张图同时给一段与图像内容矛盾的文本描述。例如图上是“销售额逐季上升”文本写“销售额逐季下降”。问模型“文本描述与图像内容是否一致”如果模型只依赖文本先验它会倾向于回答“一致”因为它看到文本描述很通顺。如果模型真正看图它应该回答“不一致”并指出区别。这类任务能拆掉“文本先行”模型的侥幸心理。5.2 任务二多步视觉推理单步任务只需要提取一个视觉线索。多步任务要求模型综合多个区域的信息。比如一张折线图上画了三条产品线的每月数据。问“哪条产品线在 7 到 9 月增长最快它的增长率是否超过全年平均增长率”这类问题要求定位三条折线的颜色分别提取 7 到 9 月的数值计算增长率对比全年均值。没有哪一步是能靠文本先验蒙对的。5.3 任务三图像引导的代码生成这对开发者更实际。让模型读取一张数据表截图并生成一段 Python 代码用于复现图中的可视化效果。这要求模型能理解图表的坐标轴含义识别图中的分组、数值范围将视觉信息翻译成数据结构。如果模型只是泛泛生成一段画柱状图的代码而没有体现图中的具体数值和分组说明它没有真正利用图像信息。# 示例评测提示词模板 prompt 请仔细观察这张数据表格的截图。基于图中的实际数据生成一段 Python 代码使用 matplotlib 绘制相同的柱状图。图中每个柱子的数值、标签必须与截图一致。如果无法辨认请直接说明哪些内容不清晰不要猜测。这个设计比单纯问“图里有什么”严格得多。它能考察模型是否能把视觉内容编码成可靠的程序逻辑。6. 多模态 Agent 中的视觉工具使用实践因果审计不仅能用来做离线评测还能指导我们在真实 Agent 系统里设计更可靠的视觉工具调用流程。6.1 Agent 场景为什么会放大幻觉在 Agent 场景中模型往往要调用多个工具读图、查数据库、执行代码、汇总报告。链路越长幻觉的传播效应越强。一个典型问题用户传一张数据截图Agent 第一步读图得到一个错误的季度数值第二步把这个错误数值写入 SQL 查询第三步基于错误的查询结果生成分析报告。最终报告看起来完整流畅但根因是第一步的视觉理解就是错的。更麻烦的是用户通常不会逐行检查报告中的数据错误会被直接采信。6.2 给视觉工具加一道“审核关卡”一个务实的做法是不把多模态模型当作“可靠的视觉事实来源”而是把它当作“候选线索生成器”。在 Agent 流程中增加一个校验环节。我建议的结构是三层视觉提取层模型从图像中提取候选信息但不直接作为最终答案。交叉验证层用其他工具OCR、数据分析代码、规则校验验证提取出的信息是否与图像原始内容一致。决策输出层只有通过校验的信息才能进入后续流程否则要求重新输入或返回“无法确定”而不是自动补全。# 文件路径agent_visual_tool.py def extract_visual_info(image_path: str, question: str) - dict: 第一层视觉模型提取候选信息。 注意这里返回的是候选信息不一定是可信事实。 raw_answer ask_model(image_path, question) return { candidate: raw_answer, confidence: estimate_confidence(raw_answer), } def cross_validate(image_path: str, candidate: str) - bool: 第二层交叉验证。 可以调用 OCR、图像处理库或者人工确认规则。 这里以简单的关键词匹配为例实际项目请替换成更可靠的方法。 ocr_text run_ocr(image_path) # 判断候选答案中的关键数字是否出现在 OCR 结果中 import re numbers re.findall(r\d(?:\.\d)?, candidate) if not numbers: return False return all(num in ocr_text for num in numbers) def safe_visual_query(image_path: str, question: str) - str: 第三层带校验的视觉工具调用。 如果校验失败返回“无法确认”而不是强行给答案。 result extract_visual_info(image_path, question) if not result[confidence]: return 图像信息不足无法给出可靠答案。 passed cross_validate(image_path, result[candidate]) if not passed: return 视觉信息与图像原始内容不一致需要人工复核。 return result[candidate]这段代码的工程价值在于它把“模型说对”和“模型确认对”分开了。在关键业务场景里这种保守策略比一味追求高准确率更可靠。6.3 置信度与回退机制不少多模态 API 会返回 logprobs 或 usage你可以用这些信息估算置信度。但要注意置信度并不等于视觉可靠性。一个模型可能对错误答案非常有信心也可能对正确答案非常犹豫。所以我更推荐把因果审计作为“模型上线前的体检”把交叉验证作为“运行时的安全带”。两者配合比单独依赖任何一条链路都更稳。7. 多模态视觉工具的常见问题与排查方法问题现象可能原因排查方式解决方案换图后答案不变模型依赖文本先验未使用图像信息对相同问题更换无关图像对比输出改用视觉推理能力更强的模型对关键场景增加交叉验证模糊图像仍给出精确数值模型在“脑补”数值从训练分布中采样检查输出中是否有图像中不存在的具体数值在提示词中强制要求“无法识别时说明不确定”接入数值校验图表细节与 OCR 不一致视觉编码器丢失了局部细节用 OCR 工具提取文本与模型输出对比对关键图表走 OCR 通道不依赖单一视觉模型提示词能提升分数但掩盖问题提示词增加了“看起来认真”的输出用相同提示词更换扰动图看输出是否变化把扰动测试纳入评测集不只看最终分数Agent 链路级联错误视觉环节错误被后续工具放大对链路中每层输出做记录和审计增加中间结果校验加入人工复核节点模型只答“整体趋势”不答具体差异模型未进行多步视觉推理拆分子问题逐项提问降低任务复杂度或换用更大参数的视觉推理模型在实际项目中我见过太多“分数够高但一上线就翻车”的案例绝大多数都和对视觉模型的盲目信任有关。上述排查表可以作为你评测流程的一个起点。8. 最佳实践与工程建议8.1 建立自己的因果审计回归集不要只依赖公开榜单。建议你针对自己的业务场景建立一个 100 到 300 条样本的回归集。每条样本包含原始图像翻转或裁剪后的扰动图无关替换图对应的标准答案和预期行为。每次模型版本升级时跑一遍回归集记录视觉依赖度得分的变化。这个得分比单纯看准确率更能反映模型是否在“走捷径”。8.2 区分“视觉任务”和“文本任务”很多任务名义上是视觉任务核心信息其实来自文本。例如一张截图里既有标题文字又有图表模型完全可能通过标题推断答案不需要细看图。这种任务应该被归为“文本增强的任务”不能用于测试视觉推理。在设计评测集时务必让问题必须依赖图像的非文本信息才能回答例如颜色、空间位置、几何形状、趋势斜率。8.3 使用“反事实提示”检验模型在业务中可以使用一个低成本的反事实检验把问题中的关键实体替换成相反词或者把图中的关键视觉信息替换掉然后对比回答。例如原问题“哪个区域销量最高” 反事实问题“哪个区域销量最低” 如果模型对两个问题的回答完全一样说明它很可能没有真正比较图中的数据。8.4 版本管理与日志记录多模态模型的响应延迟高、成本大更需要完善的日志记录。记录内容至少包括输入图像路径或哈希问题文本模型输出审计干预类型是否通过交叉验证。有日志才能做事后复盘否则出问题时无从下手。8.5 安全边界与最小权限如果你在多模态 Agent 中集成了视觉工具务必遵循最小权限原则。视觉模型不应当有直接执行数据库操作或修改生产环境的权限。它应该只负责“理解与提取”最终决策由具备权限校验的编排层完成。生产环境中的视觉工具调用建议加入人工审核开关。对于高风险操作如写库、发送消息、删除资源即使视觉理解置信度很高也应保留人工确认渠道。9. 总结与后续学习方向这篇文章的核心是帮助大家建立一个新的模型评测视角不要只看模型输出是否“看起来正确”还要看它的输出是否在因果层面依赖图像输入。视觉工具使用的幻觉提醒我们多模态模型的“看图能力”可能没有想象中可靠。传统准确率指标适合衡量最终结果但无法区分“真正推理”和“文本先验猜测”。Causal Audit 通过干预、扰动、反事实检测把这种隐藏的缺陷暴露出来而这恰恰是我们在工程落地中最需要警惕的部分。下一步如果你想继续深入可以从这几个方向入手因果推理基础学习干预、反事实、中介分析这能帮你设计更严谨的评测任务。多模态模型内部机制研究视觉 token 在注意力层的权重分布了解模型“看”到什么程度。Agent 评测体系把因果审计从单模型评测扩展到多工具链路评测测试视觉信息在链路中的传递是否失真。在真实项目里不要轻易相信任何单一模型的视觉输出。给你的视觉工具加上校验、加上回退、加上审计。记住一句工程上很朴素的话能确认自己不知道远比自信地给出错误答案更可靠。