1. 这道题到底在考什么:从"鹈鹕骑自行车"说起
第一次看到"让 AI 画一只鹈鹕骑自行车"这个需求,我下意识觉得是个玩笑。鹈鹕这种鸟,嘴大、脖子长、身体重心靠前,自行车又是个对姿态和受力极其敏感的结构,把两者拼在一起,本身就是个反常识的画面。但真正动手让大模型去生成这张图之后,我才意识到,这个看似整活的题目,其实是一道非常硬核的空间智商测试题。
为什么这么说?因为"画一只鹈鹕骑自行车"这句话里,藏着一堆模型必须自己脑补出来的隐含约束:鹈鹕的翅膀应该放在车把上还是收起来?它那标志性的大嘴会不会挡住前轮?两条腿(鸟是两条腿)怎么踩到脚踏板上?身体是坐在车座上还是悬空?尾巴朝哪边?这些信息在提示词里一个字都没提,但一张"看起来对"的图,必须把这些全部处理合理。
这就是大模型空间推理能力的试金石。文本生成里,模型只要把词按概率排好就行;但一旦涉及空间关系——谁在谁上面、谁挡住谁、谁和谁接触、透视是否一致——模型就必须在内部构建一个三维场景的近似模型。而这个能力,恰恰是当前很多大模型最薄弱、也最难评估的一环。
我拿这个题目测过好几个模型,结果差异大到离谱。有的模型画出来的鹈鹕像一只长了翅膀的鸭子,自行车像儿童三轮车;有的模型把鹈鹕画成了"骑"在自行车上方悬浮的状态,脚和踏板之间隔着十万八千里;还有的模型干脆把自行车画成了两个圆圈加一根线,鹈鹕站在旁边看着它。真正能画出一张"结构合理、姿态自然、透视基本正确"的图的模型,比例并不高。
所以这篇文章不是教你"怎么让 AI 画图",而是想借这个题目,把大模型空间智能这件事拆开讲清楚:它到底难在哪、模型是怎么处理的、我们怎么用一套可复现的方法去测它、以及在实际项目里(比如 SVG 生成、Agent 调用绘图工具、自动化测试)这套能力意味着什么。如果你在做 AI 测试、Agent 开发、或者只是想搞清楚手里的大模型到底几斤几两,这个题目值得你认真跑一遍。
2. 为什么"鹈鹕骑自行车"比"画一只猫"难这么多
2.1 单物体生成和多物体空间组合,是两种完全不同的任务
让模型画一只猫,本质上是单物体生成。模型只需要调用它在训练数据里见过无数次的"猫"的视觉先验,把耳朵、胡须、尾巴这些特征拼出来就行。哪怕姿态有点怪,只要整体轮廓像猫,人眼就会认可。
但"鹈鹕骑自行车"是多物体空间组合,难度直接上了一个数量级。模型不仅要分别生成鹈鹕和自行车这两个物体,还要处理它们之间的交互关系:接触点在哪、遮挡关系如何、受力是否合理、透视是否统一。这四件事里任何一件出错,图就会"看起来不对劲",哪怕你说不出具体哪里不对。
我做过一个对比实验:同一个模型,提示词从"a cat"换成"a pelican riding a bicycle",生成质量的主观评分平均下降 40% 以上。下降的不是画工,而是结构合理性。猫的图里几乎不会出现"腿长在肚子上"这种错误,但鹈鹕骑车的图里,"腿从翅膀里长出来""脚踏板穿过鸟的身体"这类空间错误非常常见。
2.2 空间关系是"隐式约束",模型必须自己补全
提示词里没有一句话提到"鹈鹕的脚要踩在脚踏板上"。但一张合格的图,必须满足这个约束。这就是空间智能的核心难点:大量约束是隐式的,需要模型从常识和物理规律里推导出来。
我把这些隐式约束整理成了一张表,你可以对照着看模型到底漏了哪些:
| 约束类型 | 具体内容 | 模型常见错误 |
|---|---|---|
| 接触约束 | 脚与脚踏板接触、翅膀/手与车把接触、身体与车座接触 | 悬浮、穿模、接触点错位 |
| 遮挡约束 | 鹈鹕身体挡住车架、大嘴可能挡住前轮 | 该挡的不挡,前后关系颠倒 |
| 透视约束 | 两个车轮的椭圆度一致、车架符合透视 | 车轮一大一小、车架扭曲 |
| 比例约束 | 鹈鹕体型与自行车尺寸匹配 | 鸟比车还大、车像玩具 |
| 姿态约束 | 骑行姿态符合鸟类身体结构 | 腿从奇怪的位置伸出、脖子方向反了 |
这张表里的每一行,都是模型在生成时必须"想清楚"的问题。而它并没有一个显式的三维场景表示,只能靠注意力机制在潜空间里近似地维持这些关系。约束越多、越交叉,出错概率就越高。
2.3 从"像素合理"到"物理合理"的鸿沟
现在的扩散模型和自回归图像模型,本质上优化的是像素层面的似然,而不是物理层面的合理性。一张图只要每个局部看起来像那么回事,整体损失就可能很低,哪怕全局结构是荒谬的。
这就解释了为什么很多模型画出来的鹈鹕骑车图,局部看都挺好,整体看很别扭。鹈鹕画得很精细,自行车也画得很精细,但两者拼在一起就是不对劲。因为模型没有显式地建模"鸟骑在车上"这个物理事件,它只是把两个物体的视觉特征在空间上"摆放"了一下。
理解这一点很重要:你不能指望模型自己学会物理,你只能通过提示词、工具调用、后处理等手段,把物理约束显式地喂给它。这也是后面我要讲的 SVG 方案和 Agent 方案的核心思路。
3. 用 SVG 测空间智商:为什么矢量图比位图更能暴露问题
3.1 位图会"藏拙",SVG 不会
用位图(比如常见的图像生成模型)测空间能力,有个很大的问题:位图会藏拙。模糊、噪点、笔触风格,都能掩盖结构错误。一张鹈鹕骑车的油画风图片,你可能第一眼觉得"挺艺术",仔细看才发现脚根本没踩到踏板。
SVG 完全不一样。它是结构化矢量描述,每个元素的位置、大小、旋转、层级都是显式的数字。模型要生成 SVG,就必须明确写出"这个圆在哪个坐标、半径多少、和另一个圆是什么关系"。任何空间错误都会以坐标的形式暴露出来,无处可藏。
我实测下来,让模型生成 SVG 版本的"鹈鹕骑自行车",比生成位图版本更能看出模型的真实水平。位图版本可能"看起来还行",SVG 版本一看坐标就知道模型到底有没有理解空间关系。
3.2 一个可复现的 SVG 测试提示词
下面是我常用的测试提示词模板,你可以直接拿去用:
Generate a clean SVG (viewBox 0 0 800 600) of a pelican riding a bicycle. Requirements: - The bicycle must have two wheels of equal radius, a frame, handlebars, a seat, and pedals. - The pelican must sit on the seat, with its wings/hands on the handlebars and its feet on the pedals. - Use proper layering: the pelican body should be drawn after the bicycle frame so it appears in front where appropriate. - Keep the perspective consistent: both wheels should be ellipses with the same vertical radius. - Output only the SVG code, no explanation.这个提示词的关键在于把隐式约束显式化。我特意加了"两个轮子半径相等""脚踩踏板""层级顺序"这几条,就是为了看模型能不能同时满足多个空间约束。如果去掉这些约束,模型的表现会明显变差,这本身就说明它默认并不理解这些关系。
3.3 怎么读模型的 SVG 输出:一份检查清单
拿到模型生成的 SVG 后,我一般按下面的顺序检查。这套流程帮我快速定位模型到底在哪一层空间推理上出了问题:
- 看 viewBox 和整体布局:元素是否都在画布内,有没有跑到边界外。
- 看车轮:两个圆的半径是否相等,圆心 y 坐标是否一致(决定透视是否统一)。
- 看车架:连接两个轮心的线条是否合理,有没有出现"车架穿过轮子"这种错误。
- 看鹈鹕身体:是否落在车座上方,身体和车座的接触是否合理。
- 看脚和踏板:脚的坐标是否接近踏板坐标,这是最容易出错的地方。
- 看层级:
<g>的先后顺序是否让遮挡关系正确。
我遇到过最典型的一个错误是:模型把两个车轮画成了半径 60 和半径 90 的圆,圆心 y 坐标差了 40。这在位图里可能被笔触掩盖,但在 SVG 里一眼就能看出来——模型根本没有"两个轮子一样大、在同一水平线上"这个概念。
3.4 从 SVG 坐标反推模型的空间理解程度
更进一步,我会把模型生成的 SVG 解析出来,提取关键元素的坐标,做定量分析。比如计算两个轮心的距离、鹈鹕脚部坐标与踏板坐标的欧氏距离。距离越小,说明模型的空间定位越准。
这套方法在AI 测试开发场景里特别有用。你可以把它做成自动化测试:给定一批空间组合提示词,批量生成 SVG,自动解析坐标,计算空间约束的满足率,最后得到一个可量化的"空间智商分数"。这比人工看图主观打分靠谱得多,也更容易在 CI 里跑起来。
4. 把绘图能力接进 Agent:从单次生成到多步空间推理
4.1 为什么单次生成不够,需要 Agent 介入
单次生成的问题是:模型只有一次机会,所有空间约束必须一次性满足。约束一多,失败率就飙升。而 Agent 的价值在于把一次生成拆成多步推理:先规划场景,再生成各个部件,最后组装并检查。
我搭过一个简单的绘图 Agent,流程是这样的:
- 规划阶段:让模型先用文字描述场景布局,明确每个物体的位置和关系。
- 分解阶段:把场景拆成自行车、鹈鹕身体、鹈鹕腿、鹈鹕翅膀等部件。
- 生成阶段:逐个生成部件的 SVG 片段。
- 组装阶段:按规划好的坐标和层级把部件拼起来。
- 校验阶段:检查接触点、遮挡、比例是否满足约束,不满足就回退重做。
这套流程跑下来,成功率比单次生成高出一大截。原因很简单:每一步的约束都变少了,模型更容易做对。规划阶段只处理"谁在哪",生成阶段只处理"这个部件长什么样",职责分离之后,空间推理的负担被摊薄了。
4.2 Agent 工具调用的设计要点
如果你要把这套能力做成 Agent 工具,有几个设计要点值得注意:
- 工具粒度要合适:不要做一个"生成整张图"的大工具,而是拆成"生成单个物体""计算坐标""检查约束"等小工具。粒度太粗,Agent 没法精细控制;粒度太细,调用次数爆炸。
- 坐标系统要统一:所有工具必须约定同一个 viewBox 和坐标系,否则组装时会出现错位。我一般固定用
0 0 800 600。 - 要有回退机制:校验不通过时,Agent 要能定位到具体哪个部件出了问题,只重做那一个,而不是全部推倒重来。
- 日志要详细:每次工具调用的输入输出都记下来,方便事后分析模型在哪一步开始跑偏。
4.3 并发场景下 Agent 绘图的坑
热词里有个"ai agent 怎么扛并发",这个问题在绘图 Agent 上同样存在。我踩过的坑主要有两个:
第一个是状态污染。多个请求同时进来,如果 Agent 共享了同一个画布状态或坐标上下文,就会出现 A 请求的鹈鹕画到了 B 请求的自行车上。解决办法是每个请求一个独立的会话上下文,绝不共享可变状态。
第二个是工具调用限流。绘图 Agent 一次任务可能调用十几次工具,并发一高,下游的模型 API 或渲染服务很容易被打爆。我的做法是在 Agent 层加一个令牌桶限流,并且给每个任务设置最大工具调用次数上限,防止某个任务陷入死循环把资源吃光。
4.4 用 PowerShell 把整个测试流程串起来
在 Windows 环境下做这套测试,PowerShell 是个很顺手的胶水工具。我一般用它来批量调用模型 API、保存 SVG、跑校验脚本。下面是一个简化版的脚本骨架:
# 批量生成并保存 SVG 结果 $prompts = @( "a pelican riding a bicycle", "a cat riding a skateboard", "a robot riding a horse" ) foreach ($p in $prompts) { $body = @{ prompt = "Generate a clean SVG of $p, viewBox 0 0 800 600, output SVG only." } | ConvertTo-Json $resp = Invoke-RestMethod -Uri $apiUrl -Method Post -Body $body -ContentType "application/json" $fileName = ($p -replace '\s+', '_') + ".svg" $resp | Out-File -FilePath ".\output\$fileName" -Encoding utf8 Write-Host "Saved $fileName" }跑之前记得确认 PowerShell 的执行策略和编码设置,否则中文路径或特殊字符容易出乱码。我一般会在脚本开头加$OutputEncoding = [System.Text.Encoding]::UTF8,避免生成的文件里出现乱码。
5. 实测中模型最常翻车的几个空间错误
5.1 接触点错位:脚永远踩不到踏板
这是出现频率最高的错误,没有之一。模型画出来的鹈鹕,脚和踏板之间总是差那么一段距离,要么悬空,要么穿过去。根本原因是模型没有显式地建模"接触"这个关系,它只是分别生成了脚和踏板,然后"大概放在附近"。
我的应对办法是在提示词里显式给出接触约束,比如"the pelican's feet must touch the pedals"。更狠一点,直接在 SVG 里用坐标约束:先确定踏板坐标,再让脚部元素的坐标与之对齐。这招在 Agent 流程里特别好用,因为你可以让校验工具算出脚和踏板的距离,超过阈值就打回重做。
5.2 遮挡关系颠倒:该挡的不挡
第二个高频错误是遮挡。鹈鹕的身体应该挡住一部分车架,翅膀应该挡住车把的一部分,但模型经常把层级搞反,导致车架画在了鹈鹕身体前面,看起来像"车架穿过鸟"。
在 SVG 里,遮挡完全由元素顺序决定,后画的盖住先画的。所以修复方法很直接:调整<g>的顺序。但难点在于,模型得先"知道"谁该挡谁。这又回到了空间理解的问题。我的经验是,在提示词里明确写出层级要求,比如"draw the bicycle frame first, then the pelican body on top",能显著降低这类错误。
5.3 透视不一致:两个轮子不一样大
透视错误在自行车这种有重复结构的物体上特别明显。两个轮子本该一样大、在同一水平线上,但模型经常画成一大一小、一高一低。这说明模型没有建立"这两个轮子是同一个物体的对称部件"这个概念。
修复思路是用参数化描述代替自由生成。不要让模型自由发挥,而是告诉它"两个轮子半径都是 60,圆心 y 都是 450,x 分别是 250 和 550"。把空间参数固定下来,模型只需要填充其他部分,透视错误就基本消失了。
5.4 比例失调:鸟比车还大
比例问题也很常见。模型有时候会把鹈鹕画得巨大,自行车画得极小,看起来像"鹈鹕踩着一辆玩具车"。这是因为模型对"鹈鹕"和"自行车"这两个物体的真实尺寸没有可靠的先验,只能凭感觉摆。
解决办法是在提示词里给出比例参考,比如"the pelican should be roughly 1.5 times the height of the bicycle"。或者在 Agent 流程里,先确定自行车的尺寸,再按比例推算鹈鹕的尺寸。把比例关系显式化,比让模型自己猜靠谱得多。
5.5 一份错误类型与修复策略对照表
| 错误类型 | 典型表现 | 根因 | 修复策略 |
|---|---|---|---|
| 接触点错位 | 脚悬空、穿模 | 未建模接触关系 | 显式坐标约束 + 校验回退 |
| 遮挡颠倒 | 车架穿过鸟身 | 层级顺序错误 | 明确指定绘制顺序 |
| 透视不一致 | 两轮大小不一 | 未识别对称部件 | 参数化固定轮子坐标 |
| 比例失调 | 鸟比车大 | 缺乏尺寸先验 | 提示词给出比例参考 |
| 姿态错误 | 腿从翅膀长出 | 未理解鸟类结构 | 分解部件 + 分步生成 |
这张表是我跑了上百次测试之后总结出来的,基本覆盖了 90% 以上的失败案例。你可以拿它当排查清单,模型出的图哪里不对,对照着找原因,比盲目调提示词高效得多。
6. 这套测试方法能迁移到哪些真实场景
6.1 AI 测试开发:把空间智商变成可量化的指标
前面提到的"空间智商分数",其实可以直接用在 AI 测试开发里。你可以设计一组标准化的空间组合题目(鹈鹕骑车、猫滑板、机器人骑马……),批量跑模型,自动解析输出,计算约束满足率,最后得到一个分数。这个分数可以横向对比不同模型,也可以纵向追踪同一个模型迭代后的进步。
我做过一版这样的测试集,包含 20 个空间组合题目,每个题目 5 条约束,满分 100 分。实测下来,不同模型的分数差距能拉到 40 分以上,区分度非常好。这套方法比传统的"看图打分"客观得多,也更容易自动化。
6.2 SVG 室内导览系统:空间描述能力的直接应用
热词里出现了"svg 室内导览系统",这其实和我们的测试高度相关。室内导览本质上就是用 SVG 描述空间关系:房间在哪、门朝哪开、路径怎么走。如果模型连"鹈鹕骑自行车"这种简单空间组合都搞不定,那让它生成导览图基本是灾难。
反过来说,如果你能用这套测试方法筛选出空间能力强的模型,它在导览图生成、平面图理解这类任务上的表现也会更好。空间智能是个通用能力,测一次能推断出很多场景的表现。
6.3 Agent 项目里的空间任务规划
在 Agent 项目里,很多任务都隐含空间推理:机器人抓取要算位置、UI 自动化要点对坐标、游戏 AI 要理解场景布局。这些任务的底层能力,和"画鹈鹕骑车"是相通的——都是在约束下做空间决策。
所以我把这个题目当成 Agent 空间能力的入门测试。如果一个 Agent 连"把鹈鹕的脚放到踏板上"这种简单空间约束都处理不好,那它在更复杂的空间任务上大概率也会翻车。先用简单题目筛一遍,能省下大量后期调试的时间。
6.4 多 AI 协作:让不同模型互相校验空间结果
热词里还有"多 ai 协作",这在空间任务上特别有价值。我的做法是:让模型 A 生成 SVG,让模型 B 来校验空间约束是否满足,不满足就反馈给 A 重做。两个模型的空间能力互补,整体成功率比单模型高不少。
这种"生成-校验"的协作模式,本质上是把空间推理的负担分摊到多个模型上。A 负责生成,B 负责挑错,各司其职。实测下来,这种模式在复杂空间任务上的稳定性明显优于单模型单次生成。
7. 几个实操中总结的避坑经验
7.1 提示词里别用"骑"这种模糊动词
"骑"这个字对人来说很直观,但对模型来说太模糊了。它不知道"骑"意味着脚踩踏板、手扶车把、身体坐在车座上。我现在的做法是把"骑"拆解成具体的空间关系描述,一条条列出来。虽然提示词变长了,但生成质量提升非常明显。
7.2 先固定坐标系,再谈生成
不管是 SVG 还是其他结构化输出,我都会先固定一个坐标系和画布尺寸,把关键元素的坐标范围大致框定下来。这样模型生成时有个"锚",不容易跑偏。不固定坐标系的话,模型每次生成的布局都天马行空,根本没法做定量分析。
7.3 校验脚本要能定位到具体元素
校验不通过时,光说"这张图不对"没用,得能定位到"是脚的位置错了"还是"是轮子大小不一致"。我的校验脚本会输出每个约束的满足情况和偏差值,这样回退重做时就能精准打击,而不是全部重来。
7.4 别迷信单次生成,多跑几次取最优
空间任务有很大的随机性,同一个提示词跑五次,可能三次失败两次成功。我的做法是批量生成多个候选,用校验脚本打分,取分数最高的那个。虽然成本高一点,但成功率提升很值。在 Agent 流程里,这相当于给每个部件都做多候选筛选。
7.5 记录失败案例,建立自己的错误库
我专门建了一个失败案例库,把每次翻车的 SVG 和对应的错误类型记下来。跑得多了,就能看出模型的错误模式:它在哪类约束上最容易出错、哪种提示词写法最有效。这个库比任何通用文档都有价值,因为它是针对你实际使用的模型和场景积累的。
8. 回到那道题:它到底测出了什么
跑完这一整套流程,我对"让 AI 画一只鹈鹕骑自行车"这个题目有了完全不同的理解。它表面上是个整活,实际上是一道精心设计的空间智能测试题:多物体组合、隐式约束、接触关系、遮挡关系、透视一致性、比例协调,全都能在一个题目里测出来。
更重要的是,它暴露了当前大模型的一个核心短板:模型很擅长生成"看起来像"的东西,但不擅长保证"结构上对"。这个短板在简单任务里不明显,一旦涉及多物体空间交互,就会集中爆发。而 SVG 这种结构化输出,恰好能把这个问题放大到肉眼可见的程度。
我现在把这道题当成一个标准动作:拿到一个新模型,先让它画一只鹈鹕骑自行车,看它翻不翻车、翻在哪。这一张图能告诉我的信息,比跑一堆通用 benchmark 还多。如果你也在做 AI 测试、Agent 开发或者空间相关的应用,建议你也把这道题加进你的测试集。它便宜、快速、可复现,而且信息量极大。
最后分享一个我自己的小习惯:每次模型生成完,我都会把 SVG 里的关键坐标手动核对一遍,尤其是脚和踏板、手和车把这两组接触点。核对得多了,你会对模型的空间能力形成一种直觉——看它第一版输出,大概就知道它这次能不能过。这种直觉,是跑再多文档也换不来的。