抽象画的分析难点不在于图片里没有信息,而在于缺少一个稳定的解释框架。具象图像中,模型容易从‘猫’‘海滩’等实体继续推导;抽象画里,一块深红色可能同时是情绪、符号或纯粹的色彩构成。要让多模态模型给出有价值的解读,不能只发送一句‘请解释这幅画’,而需要把分析流程拆开,并明确哪些是可见证据、哪些是象征推断。

抽象画解释为什么需要专门的提示
多模态模型的预训练数据里包含大量艺术作品与评论,因此它并不是完全不懂抽象画。问题在于默认行为更偏向识别具体物体和场景。如果直接问‘这张画里有什么’,模型可能输出‘看起来像一片混乱的颜色’或者勉强套用一些模糊名词。抽象表现主义、色域绘画等流派的作品本来就不依赖再现性内容,模型如果没有被约束,容易从训练数据里抓取最常见描述,而不是依据当前画面。
另一个问题是象征意义具有高度上下文依赖性。同样的黑色矩形在马列维奇和罗斯科的作品中含义不同,甚至同一艺术家不同时期的类似构图也可能不同。仅靠图像像素无法确定这些含义,模型需要外部线索,比如作品标题、创作年代、艺术家声明和流派背景。提示词的任务就是把这些线索与图像分开,让模型先记录画面本身,再进入解释环节。
因此,专门的提示框架并不是让模型变得更‘懂艺术’,而是减少它跳过观察直接编造象征的倾向。好的提示词会限制输出顺序,并强制模型为每个解释提供视觉依据。这样即使最终解读不完全准确,读者也能看到推理路径,判断哪些内容可信。
三层提示词:从形式观察到象征推断
第一层是形式观察。提示词应明确要求只描述颜色、线条、形状、构图、笔触和材质,禁止使用任何具体物体名词。比如可以要求模型回答‘画面左上区域的主要色调是什么’‘笔触是急促还是平滑’‘是否有明显的视觉重心’。这一层输出应当尽量客观,即使人类观众也能在画面上找到对应元素。
第二层是情感与联想。模型需要基于第一层的形式特征,说明它们带来的节奏、张力和情绪倾向。关键约束是每个情感判断必须引用至少一个形式依据。例如不能只说‘这幅画很压抑’,而要写成‘大面积深蓝和黑色块集中在左侧,右侧留白较少,这种不平衡构图容易产生压抑感’。这样的输出既保留了主观感受,又具备可验证性。
第三层是象征推断。此时可以引入作品标题、艺术家和流派信息,让模型把形式特征与艺术史语境结合。提示词应要求模型输出象征含义时同时标注置信度,并区分‘可直接从画面推断’和‘需要外部知识才能成立’。例如‘红色可能暗示暴力或激情,但若没有创作背景,这只是常见联想而非确定结论’。
prompt_template = {
"system": "你是艺术评论助手。分析抽象画时必须按形式观察、情感联想、象征推断三层输出,并给出画面依据。",
"user_template": """
请依次完成:
1. 形式观察:只描述可见的色彩、线条、形状、构图、笔触和材质,不要猜测具体物体。
2. 情感联想:说明这些形式带来的情绪或节奏感,每个判断至少引用一个形式观察中的元素。
3. 象征推断:结合标题、流派和艺术家信息推测象征含义,标注置信度,并说明哪些是可见证据、哪些是外部知识。
输出JSON,字段为 formal_observation, emotional_association, symbolic_interpretation, uncertainty。
"""
}
多模态API调用示例
下面的Python脚本演示如何把一张本地抽象画图片发送给兼容OpenAI接口的多模态模型,并接收结构化JSON结果。代码先读取图片并做Base64编码,再构造包含系统提示和用户提示的消息体。用户消息里同时包含文本和图片URL,图片使用data:image/jpeg;base64,前缀,这是大多数视觉语言模型支持的内联格式。
请求中设置temperature=0.2可以降低随机性,让形式观察更稳定;如果所用模型支持response_format,可以要求直接返回JSON对象,后续解析更方便。实际项目中建议把API密钥放在环境变量里,不要把密钥写死在代码中。
import base64
import json
import os
import requests
api_key = os.getenv("OPENAI_API_KEY")
image_path = "abstract.jpg"
with open(image_path, "rb") as f:
image_base64 = base64.b64encode(f.read()).decode("utf-8")
payload = {
"model": "gpt-4o",
"temperature": 0.2,
"response_format": {"type": "json_object"},
"messages": [
{
"role": "system",
"content": "你是一名艺术评论助手。只依据图像和用户提示词输出JSON,不要添加额外解释。"
},
{
"role": "user",
"content": [
{"type": "text", "text": "请按照三层提示词分析这张抽象画。"},
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{image_base64}"
}
}
]
}
]
}
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
resp = requests.post(
"https://api.openai.com/v1/chat/completions",
headers=headers,
data=json.dumps(payload),
timeout=60
)
result = resp.json()
content = result["choices"][0]["message"]["content"]
print(content)
模型返回的JSON通常包含四个字段。以下是一个简化示例:
{
"formal_observation": "画面以深蓝和暗红为主,左侧有大面积黑色笔触,右侧留白较多,笔触粗犷。",
"emotional_association": "深蓝与黑色的挤压带来压抑感,右侧留白则形成短暂的呼吸感,整体节奏紧张。",
"symbolic_interpretation": "可能指向夜晚、孤独或内在冲突,但作品无标题且缺少艺术家声明,只能视为常见联想。",
"uncertainty": "高"
}
降低幻觉与提升解读一致性
抽象画解读最容易出现的问题是把模型的主观联想包装成确定事实。比如模型看到大面积红色就断言‘象征革命’,但艺术家可能只是想试验颜料厚度。缓解方法是在提示词中引入证据强度分级,要求模型把结论写成‘可能’‘或许’‘没有足够依据’等。还可以单独输出一个evidence_chain字段,让模型列出从视觉证据到象征结论的每一步推论。
另一种做法是固定输出JSON Schema,并在应用层校验字段类型和取值范围。例如uncertainty只能取低、中、高三档,formal_observation必须是字符串列表而不是自由文本。这样即使模型偶尔偏离约束,系统也能快速发现并重新请求。对于重要场景,可以让同一张图运行两到三次,比较形式观察是否一致;如果连基本色彩描述都不同,就不应采信象征推断部分。
如果需要更贴近艺术史背景,可以在系统提示中注入少量可靠资料,比如罗斯科对色彩与情绪关系的表述,或者某个流派对构图的基本主张。但要注意资料本身不能替代图像观察,最好放在提示词末尾,并标注为‘外部参考,仅在象征推断层使用’。这样可以避免模型把参考文字误认为当前画面的可见描述。