multimodal/前几篇介绍怎样传图片、识别文字、读取图表和处理多页文档。单独看都像 API 教程,直到crop_tool.ipynb才把共同的问题说清:图片已经传给模型,不代表图中的信息已经进入模型可判断的尺度。
视觉调用会把图片压进有限的视觉 token。图越大、内容越密,每条线、每个字占到的表示空间越少。此时继续强调“仔细看”没有用,因为缺少的不是注意力指令,而是分辨率。这个目录后半段所做的事情,都是由程序重新安排模型看图的尺度和顺序。
全图和细节不能同时保住
模型需要全图理解结构,也需要局部高分辨率辨认细节。把整张图缩小后发送,结构还在,细节可能已经不可恢复;直接切成许多局部图,细节保住了,模型又不知道每块在全图的什么位置。
crop_tool保留两份图:一份是高分辨率原图,只供裁剪;另一份提前缩放到模型实际接收的尺寸,用作首次观察和坐标系。模型先看缩放后的全图,判断哪里需要细看,再调用:
zoom(x1, y1, x2, y2, image_index)程序把模型给出的坐标映射回原图,截取那个区域,将裁剪结果放大到视觉 token 预算允许的最大尺寸,然后作为工具结果送回模型。模型可以继续缩小范围,直到读清标签或线条关系。
模型返回的是它所见缩放图上的像素位置,不是原图坐标。notebook 在上传前主动使用resized_size()生成与服务端一致的缩放结果,使模型坐标与本地缩放图一一对应;工具随后再按两张图的尺寸比例映射回原图。如果直接拿模型坐标裁原图,图片越大,裁剪位置偏得越远。
所以“放大镜”不只是一段图片裁剪代码。它建立了一个闭环:
全图定位 → 请求局部 → 原图裁剪并放大 → 重新观察 → 回答或继续裁剪模型决定下一步看哪里,程序保证坐标、像素和预算正确。视觉能力从一次识别变成了主动取证。
提示词修不好已经丢掉的像素
notebook 构造了一张多折线图,问第 48 个月 Widget-A 与 Widget-E 哪条更高。两条线在完整渲染图上只差约 8 个像素,小于一个 28×28 视觉 patch,附近还有一次真实交叉。单次看全图时,模型在 40 次测试中答错 36 次;允许反复裁剪后,40 次全部答对。
公开的 Chartography 测试也显示相同趋势。在 100 个密集图表问题上,一个模型从 29% 提升到 73%,另一个从 13% 提升到 44%。但每题平均成本也分别从 0.08 美元升到 0.95 美元、从 0.02 美元升到 0.64 美元。每次放大都会把已有对话和新的裁剪图再次送入模型,准确率来自更多观察,不是免费增加的能力。
放大也有上限。同一条近距离交叉线,较小模型即使有工具,十次只答对一次。裁剪能恢复被缩放压掉的像素,却不能替模型完成几何判断。这个区别很重要:如果问题来自信息没进入输入,应改造观察方式;如果清晰局部已经给到,模型仍判断错误,继续裁剪不会解决推理能力不足。
视觉 prompt 的作用因此有明确边界。要求逐项检查、规定输出格式、提供少量示例,可以改变模型处理已经看见的信息的方式;它们不能恢复缩放时消失的文字和线条。前几篇 notebook 主要在改“怎么看”,crop_tool开始改“实际给它看什么”。
多页文档的分工改变了信息边界
using_sub_agents.ipynb用另一个办法处理视觉容量:把 Apple 四个季度的财报 PDF 分给四次 Haiku 调用并行读取,再把四份抽取结果交给 Opus 汇总。每个 worker 只看一份文档,输入更短,总处理时间也更低。
保存下来的输出暴露了这种切分的代价。问题要求比较 2023 财年各季度的环比变化,但单个 worker 只拥有一个季度报告。报告中的比较列可能是上年同期,也可能是累计六个月数据,而不是上一个季度。结果里出现了这些判断:
- Q3 把 2023 年 7 月与 2022 年 6 月的数据称为 quarter-over-quarter;
- Q2 将三个月的 94,836 与六个月的 97,278 相减;
- Q1、Q4 同样把同比数据写成季度环比。
最终 Opus 没有回到原表核对,而是把四份局部结论整理成一段流畅的年度趋势。并行调用提高了吞吐量,却让跨文档关系断在了 worker 边界上。
问题并非“子模型不够强”,而是任务切法与问题结构冲突。抽取“每份报告中的净销售额”可以按文档并行;判断“季度之间如何变化”需要把四个季度放进同一个可比较结构后再计算。更稳妥的接口应该让 worker 只返回:
quarter period_start period_end period_type net_sales source_page汇总阶段再检查四行是否都是单季度口径,按日期排序后计算环比。跨文档结论不能由各自只见一份文档的 worker 提前生成。
这个例子说明,图片切块、PDF 分页和多 Agent 分工本质上在做同一件事:决定哪些信息能在一次判断中同时出现。边界切错以后,每个局部答案都可能成立,组合起来却回答了另一个问题。
视觉系统要管理观察过程
multimodal/真正值得留下的不是“模型可以读图片”,而是视觉输入同样需要调度。系统必须决定先给全貌还是细节,什么时候增加分辨率,长文档按页、按文档还是按问题拆,哪些关系必须在同一个上下文里比较。
crop_tool的亮点在于把不可见的细节变成一次可执行动作:模型指出区域,程序从原图取证,再让模型判断。using_sub_agents则留下了相反的提醒:把材料分开读取很容易,把分开的事实重新组成同一口径的问题要难得多。
因此,评测视觉系统时不能只问最终答案对不对,还要检查观察轨迹:模型最初收到的图被缩到多大,裁剪坐标是否落在正确区域,关键细节是否真的进入后续上下文,跨页和跨文档比较是否拥有共同口径。模型看到的世界不是上传文件本身,而是这条处理链最终让它看见的部分。