当前位置: 首页 > news >正文

第14章:多模态AI实战 —— 让AI“看懂“图片和文档

本章目标:掌握多模态 AI 的核心概念,使用阿里云百炼 Qwen-VL 模型实现图像理解、视觉问答、结构化信息提取等实际场景,能够将多模态能力集成到生产 AI 应用中。


前期回顾

AI入门开发系列文章合集


本章你将学到

  • 多模态 AI 与纯文本 AI 的本质区别和应用场景
  • Qwen-VL 视觉语言模型的能力边界与调用方式
  • 用 OpenAI SDK 和 LangChain 两种方式调用多模态 API
  • 从图像中提取结构化 JSON 数据(零代码图像解析)
  • 链式思维(CoT)视觉推理:让模型"分步思考"图像
  • 实际生产场景:电商图文描述、文档数字化、质量检测

一、什么是多模态AI?

1.1 文本AI vs 多模态AI

以往,AI 只能理解文字。你输入"描述一只猫",它输出文字描述。但它"看不见"图片,无法告诉你一张照片里的猫是什么颜色、多大、在做什么。

多模态 AI打破了这一限制——它能同时理解文字、图片(部分模型还支持视频、音频)。

文本 AI: 输入:文字 → 输出:文字 多模态 AI: 输入:图片 + 文字 → 输出:文字(或结构化数据) 图片 + 图片 + 文字 → 输出:对比分析

1.2 如果不使用多模态AI,会有什么问题?

场景没有多模态AI使用多模态AI
电商商品上架人工写商品描述,耗时 5-10 分钟/商品上传图片,1 秒自动生成描述
用户发图咨询客服人工查看图片回复,响应慢AI 自动理解图片并回复
扫描文档数字化人工录入,出错率高AI 自动识别提取结构化信息
产品质量检测人工对比,主观差异大AI 客观比较标准图与实物

1.3 多模态AI能做什么?


二、核心模型:Qwen-VL 系列

2.1 模型选择

阿里云百炼提供 Qwen-VL 系列视觉语言模型,通过 OpenAI 兼容端点调用:

模型特点适用场景
qwen-vl-plus均衡性能,速度快,成本低大多数视觉任务(本章示例)
qwen-vl-max最强视觉理解,支持复杂推理高精度场景、复杂图表解析

💡建议:开发和测试阶段用qwen-vl-plus,生产上线前评估是否需要升级到qwen-vl-max

2.2 多模态消息格式

与纯文本 API 的关键区别:content字段不再是字符串,而是一个混合节点列表

# 纯文本(第1章的格式)messages=[{"role":"user","content":"你好"}]# 多模态(第14章的格式)messages=[{"role":"user","content":[# 节点1:图像{"type":"image_url","image_url":{"url":"https://example.com/photo.jpg"}},# 节点2:文字指令{"type":"text","text":"描述这张图片"}]}]

关键点

  • content变成列表,可以混合多个节点
  • 图像节点:{"type": "image_url", "image_url": {"url": "..."}}
  • 文字节点:{"type": "text", "text": "..."}
  • 一次调用可以包含多张图片(在列表中放多个图像节点)

三、快速上手:基础图像理解

3.1 初始化客户端

# lessons/14_multimodal/01_vision_basics.pyimportosimportsysfromopenaiimportOpenAIdefcreate_client()->OpenAI:"""创建百炼 API 客户端,多模态与纯文本使用相同的客户端。"""api_key=os.getenv("DASHSCOPE_API_KEY")ifnotapi_key:print("错误:请设置环境变量 DASHSCOPE_API_KEY")sys.exit(1)returnOpenAI(api_key=api_key,base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",)

📌 多模态模型与文本模型使用同一个客户端,只是model参数和content格式不同。

3.2 Demo 1:基础图像描述

# 公共测试图像(DashScope 官方示例图)IMAGE_DOG_AND_GIRL="https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"defdemo_image_description(client:OpenAI)->str:"""让模型用自然语言描述一张图片。"""print("\n🖼️ Demo 1:基础图像描述")print(f" 图像 URL:{IMAGE_DOG_AND_GIRL}")response=client.chat.completions.create(model="qwen-vl-plus",messages=[{"role":"user","content":[{"type":"image_url","image_url":{"url":IMAGE_DOG_AND_GIRL}},{"type":"text","text":"请详细描述这张图片的内容,包括人物、动物、环境和氛围。"}],}],)description=response.choices[0].message.contentprint(f" 📝 描述结果:\n{description}")returndescription

运行效果:

🖼️ Demo 1:基础图像描述 图像 URL:https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg 📝 描述结果: 图片中是一位女孩和一只金毛猎犬在户外草地上互动...

3.3 Demo 2:视觉问答

IMAGE_ANT="https://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpg"defdemo_visual_qa(client:OpenAI)->str:"""针对图像提出具体问题,获取精准答案。"""print("\n❓ Demo 2:视觉问答")response=client.chat.completions.create(model="qwen-vl-plus",messages=[{"role":"user","content":[{"type":"image_url","image_url":{"url":IMAGE_ANT}},{"type":"text","text":("请回答以下问题:\n""1. 这是什么动物?\n""2. 图中有几只?\n""3. 它们在做什么?\n""4. 图像风格是什么(特写/全景/微距等)?")},],}],)answer=response.choices[0].message.contentprint(f" 💡 回答:\n{answer}")returnanswer

为什么视觉问答有价值:

  • 用户上传产品图片,AI 自动回答"这个零件的型号是多少"
  • 用户拍照上传病历单,AI 提取关键检查指标
  • 自动审核用户上传内容是否符合平台规范

3.4 Demo 3:多图对比

同一次调用传入两张图片,让模型对比分析:

defdemo_multi_image_comparison(client:OpenAI)->str:"""在一次 API 调用中传入两张图片,进行对比分析。"""print("\n🔍 Demo 3:多图对比分析")response=client.chat.completions.create(model="qwen-vl-plus",messages=[{"role":"user","content":[# 图像1{"type":"image_url","image_url":{"url":IMAGE_DOG_AND_GIRL}},# 图像2{"type":"image_url","image_url":{"url":IMAGE_ANT}},# 问题{"type":"text","text":"请对比这两张图片,从主体内容、拍摄风格、色调三个维度进行分析。"},],}],)comparison=response.choices[0].message.contentprint(f" 📊 对比结果:\n{comparison}")returncomparison

⚠️注意:两张图片放在同一个content列表中,API 会自动关联它们的上下文。


四、进阶:结构化信息提取

4.1 为什么需要结构化输出?

视觉理解给你自然语言描述,但业务系统需要结构化数据

纯描述(不可用于系统): "这是一个红色的苹果手机,8GB内存,价格大约在5000元左右" 结构化输出(可直接写入数据库): { "brand": "Apple", "color": "红色", "memory": "8GB", "estimated_price": 5000 }

4.2 Demo:JSON 结构化提取

# lessons/14_multimodal/02_structured_extraction.pyimportjsonimportredefdemo_json_extraction(client:OpenAI)->dict:"""从图像中提取结构化 JSON 数据。"""print("\n📋 Demo:JSON 结构化提取")prompt="""请分析这张图片,以 JSON 格式返回以下信息: { "main_subject": "图片主体(一句话)", "scene_type": "场景类型(室内/室外/自然/城市等)", "lighting": "光线条件(明亮/昏暗/自然光/人工光等)", "dominant_colors": ["主要颜色列表"], "objects_count": "可见主要物体数量(数字)", "image_quality": "图像质量(高/中/低)", "mood": "整体氛围(一个词)" } 只返回 JSON,不要其他文字。"""response=client.chat.completions.create(model="qwen-vl-plus",messages=[{"role":"user","content":[{"type":"image_url","image_url":{"url":IMAGE_DOG_AND_GIRL}},{"type":"text","text":prompt},],}],)raw=response.choices[0].message.content# 提取 JSON 块(处理模型可能带 markdown 代码块的情况)json_match=re.search(r"\{.*\}",raw,re.DOTALL)ifjson_match:data=json.loads(json_match.group())print(f" ✅ 提取成功:\n{json.dumps(data,ensure_ascii=False,indent=4)}")returndatareturn{}

关键技巧

  1. 在提示词中明确说明 JSON 结构和字段含义
  2. re.search(r"\{.*\}", raw, re.DOTALL)提取 JSON,因为模型可能带 markdown 代码块
  3. 加上json.loads()的异常处理

4.3 链式思维视觉推理

对于复杂的视觉分析,让模型"分步思考"比一步到位更准确:

defdemo_chain_of_thought_reasoning(client:OpenAI)->str:"""使用链式思维(CoT)引导模型进行深度视觉推理。"""print("\n🧠 Demo:链式思维视觉推理")cot_prompt="""请按照以下步骤分析这张图片: 步骤1 - 观察:描述你看到的所有视觉元素(物体、人物、背景) 步骤2 - 分析:分析这些元素之间的关系和图片的核心主题 步骤3 - 推断:基于以上分析,推断这张图片可能的用途或背景故事 请按"步骤1:"、"步骤2:"、"步骤3:"的格式逐步输出。"""response=client.chat.completions.create(model="qwen-vl-plus",messages=[{"role":"user","content":[{"type":"image_url","image_url":{"url":IMAGE_DOG_AND_GIRL}},{"type":"text","text":cot_prompt},],}],)reasoning=response.choices[0].message.contentprint(f" 🔍 推理过程:\n{reasoning}")returnreasoning

4.4 LangChain 集成方式

# LangChain 多模态调用方式fromlangchain_core.messagesimportHumanMessage,SystemMessagefromlangchain_openaiimportChatOpenAIdefdemo_langchain_multimodal()->str:"""使用 LangChain ChatOpenAI 进行多模态调用。"""llm=ChatOpenAI(model="qwen-vl-plus",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key=os.getenv("DASHSCOPE_API_KEY"),)# HumanMessage 的 content 同样是列表格式message=HumanMessage(content=[{"type":"image_url","image_url":{"url":IMAGE_DOG_AND_GIRL}},{"type":"text","text":"这张图片里有什么?请简洁描述。"},])response=llm.invoke([message])returnresponse.content

五、OpenAI SDK vs LangChain 调用方式对比

维度OpenAI SDK(直接调用)LangChain 封装
代码量少,更直观稍多,但更结构化
与LangChain集成需要手动桥接原生集成,可直接接 Chain
多模态消息格式client.chat.completions.create()ChatOpenAI.invoke([HumanMessage(...)])
结构化输出手动 JSON 解析可用with_structured_output(PydanticModel)
流式输出stream=True.stream()方法
推荐场景简单视觉任务、快速原型复杂应用、需要与 Chain/Agent 集成
# LangChain with_structured_output 示例frompydanticimportBaseModel,FieldclassImageMetadata(BaseModel):main_subject:str=Field(description="图片主体描述")scene_type:str=Field(description="场景类型")dominant_colors:list[str]=Field(description="主要颜色列表")mood:str=Field(description="整体氛围")structured_llm=llm.with_structured_output(ImageMetadata)result=structured_llm.invoke([HumanMessage(content=[{"type":"image_url","image_url":{"url":IMAGE_DOG_AND_GIRL}},{"type":"text","text":"分析这张图片"},])])# result 是 ImageMetadata 对象,result.main_subject 直接访问

六、实战场景演示

6.1 电商场景:自动生成商品描述

defgenerate_product_description(client:OpenAI,product_image_url:str)->dict:""" 给定商品图片 URL,自动生成电商商品描述。 实际使用时,替换 product_image_url 为真实商品图片。 """prompt="""你是一位专业的电商文案撰写员。 请分析这张商品图片,生成以下 JSON 格式的商品信息: { "title": "商品标题(15字以内,突出核心卖点)", "category": "商品分类", "key_features": ["核心特点1", "核心特点2", "核心特点3"], "target_audience": "目标用户群体", "selling_points": "营销文案(50字以内,吸引点击)", "tags": ["标签1", "标签2", "标签3"] } 只返回 JSON,不要其他内容。"""response=client.chat.completions.create(model="qwen-vl-plus",messages=[{"role":"user","content":[{"type":"image_url","image_url":{"url":product_image_url}},{"type":"text","text":prompt},]}])raw=response.choices[0].message.content json_match=re.search(r"\{.*\}",raw,re.DOTALL)ifjson_match:returnjson.loads(json_match.group())return{"error":"解析失败","raw":raw}

6.2 文档数字化:提取表单信息

defextract_form_data(client:OpenAI,document_image_url:str)->dict:""" 从文档/表单图片中提取结构化信息。 适用于:发票、合同、报告、申请表等。 """prompt="""请仔细阅读这张文档图片,提取所有可见的关键信息, 以 JSON 格式返回。根据文档类型自动判断提取哪些字段。 对于每个字段,如果图片中清晰可见,则提取;否则填 null。 只返回 JSON。"""response=client.chat.completions.create(model="qwen-vl-max",# 文档理解用更强的模型messages=[{"role":"user","content":[{"type":"image_url","image_url":{"url":document_image_url}},{"type":"text","text":prompt},]}])raw=response.choices[0].message.content json_match=re.search(r"\{.*\}",raw,re.DOTALL)ifjson_match:returnjson.loads(json_match.group())return{"raw_text":raw}

七、最佳实践与注意事项

7.1 图像质量要求

因素建议
分辨率最低 200×200 像素,推荐 800×600 以上
文件大小不超过 20MB(百炼限制)
格式JPEG、PNG、GIF(静态)、WEBP
清晰度关键内容需清晰,模糊或过度压缩会影响识别
光线避免过曝或过暗

7.2 本地图片:使用 Base64 编码

如果图片在本地(不是公网 URL),需要转换为 Base64:

importbase64defimage_to_base64(image_path:str)->str:"""将本地图片转换为 base64 data URL。"""withopen(image_path,"rb")asf:image_data=base64.b64encode(f.read()).decode("utf-8")# 推断 MIME 类型suffix=image_path.lower().split(".")[-1]mime_map={"jpg":"jpeg","jpeg":"jpeg","png":"png","gif":"gif","webp":"webp"}mime=mime_map.get(suffix,"jpeg")returnf"data:image/{mime};base64,{image_data}"# 使用方式:data_url=image_to_base64("/path/to/local/image.jpg")content=[{"type":"image_url","image_url":{"url":data_url}},{"type":"text","text":"描述这张图片"},]

7.3 视觉提示词技巧

技巧示例
明确任务类型“提取图中所有文字” vs “描述图片”
指定输出格式“以 JSON 格式返回” / “以列表形式”
限定关注范围“只分析图中的人物,忽略背景”
链式思维“先描述,再分析,最后给出结论”
角色设定“你是一位专业摄影师,请评价这张照片的构图”

7.4 错误处理

importhttpxdefsafe_vision_call(client:OpenAI,image_url:str,question:str)->str:"""带错误处理的视觉调用。"""try:response=client.chat.completions.create(model="qwen-vl-plus",messages=[{"role":"user","content":[{"type":"image_url","image_url":{"url":image_url}},{"type":"text","text":question},]}],timeout=30,# 图像下载可能较慢,设置合理超时)returnresponse.choices[0].message.contentexceptExceptionase:# 常见错误:图像 URL 无法访问、格式不支持、内容违规print(f"⚠️ 视觉调用失败:{type(e).__name__}:{e}")returnf"调用失败:{str(e)}"

7.5 成本与性能

  • 多模态调用比纯文本调用贵约 2-5 倍(图像 token 消耗较大)
  • 优先用qwen-vl-plus,只有在精度不够时升级到qwen-vl-max
  • 批量任务可用异步并发(asyncio.gather)提升吞吐量
  • 对于高频场景,考虑缓存已分析过的图像结果

八、快速运行本章代码

cdai-agent-test# 运行视觉基础演示uv run python lessons/14_multimodal/01_vision_basics.py# 运行结构化提取演示uv run python lessons/14_multimodal/02_structured_extraction.py

本章总结

学习路径回顾: 文字 AI(第1-5章) ↓ 加入图像输入 多模态 AI(第14章) ├── OpenAI SDK:直接、简洁 └── LangChain:可组合、可扩展 ↓ 视觉 Chain / 视觉 Agent(综合应用)
能力已掌握
图像描述demo_image_description()
视觉问答demo_visual_qa()
多图对比demo_multi_image_comparison()
结构化提取demo_json_extraction()
CoT 推理demo_chain_of_thought_reasoning()
LangChain 集成HumanMessage+with_structured_output

下一步建议

  • 第15章 AI应用评估与测试 —— 如何评估多模态 AI 的输出质量?
  • 尝试将视觉理解加入 RAG 管道(图文混合索引)
  • 探索更复杂场景:多轮视觉对话、视频关键帧分析

AI入门开发系列文章合集

作者:阿聪谈架构
阿聪谈架构(分享后端架构 / AI / Java 技术文章)
相关代码关注:【阿聪谈架构】 回复:AI专栏代码

http://www.gsyq.cn/news/1465668.html

相关文章:

  • 牙齿敏感又发黄,怎么选美白牙膏? - 资讯焦点
  • Dijkstra算法:单源最短路的贪心经典,稠密/稀疏图全解
  • 购买大批量广告账号 vs. 自主养号:核算 ROI 与潜在风险
  • LLM研究者的信息流操作系统:10个高信噪比技术博客实战指南
  • 拯救你的Dell G15:3分钟搞定过热降频,游戏本散热控制终极方案
  • VC6编写的ISO14443射频卡读写调试工具(含dcic32.dll驱动与完整工程)
  • 告别死记硬背:用思维导图与场景案例高效掌握贾俊平统计学第七版专业术语
  • 3步解锁CPU性能:Universal x86 Tuning Utility终极硬件优化指南
  • 手把手教你用Python解析Hex文件:自己写个简易烧录器脚本
  • 苏州传统零售私域直播系统怎么选?我会先看门店能不能接得住
  • 实战应用:在快马ai中设计并仿真mos管h桥电机驱动电路
  • Vision Transformer核心原理与PyTorch手撕实现
  • 零代码YouTube数据自动化:Google Sheets+Tableau可视化方案
  • Umi-OCR终极指南:免费开源离线文字识别软件,3分钟快速上手
  • 2026年最新白银市黄金回收白银回收铂金回收彩金回收TOP5靠谱门店甄选 识店+辨价+安全交易指南及联系方式推荐 - 前途无量YY
  • 在macos python中安装dlib
  • 2026年最新百色市黄金回收白银回收铂金回收彩金回收TOP5靠谱门店甄选 识店+辨价+安全交易指南及联系方式推荐 - 前途无量YY
  • 《珠宝改款定制镶嵌哪家好:排名前五深度测评》 - 服务品牌热点
  • 2026年最新蚌埠市黄金回收白银回收铂金回收彩金回收TOP5靠谱门店甄选 识店+辨价+安全交易指南及联系方式推荐 - 前途无量YY
  • Windows下pip install报SyntaxError?手把手教你配置环境变量与使用CMD/Anaconda Prompt
  • 江西小红书代理哪家好:排名前五 看完省选购时间 - 服务品牌热点
  • 六层上下文驱动的自校正SQL生成系统设计与实现
  • 【高频考点】回溯(暴力搜索)
  • 新手避坑指南:用JDBC连接MySQL数据库时,为什么你的PreparedStatement总报错?
  • 树枝粉碎机选型算法:基于场景与物料的博尚机型匹配指南 - 会飞的懒猪
  • 混合整数线性规划(MILP)实战入门:从排班优化到业务决策建模
  • 2026实测|5款在线协作白板横评,告别选型纠结
  • 会议平板哪家好:排名前五专业深度测评 - 服务品牌热点
  • 金仓V8数据库Win10安装后服务不见了?别慌,用这个工具一键搞定服务注册
  • Hotkey Detective:三步快速定位Windows热键冲突的终极解决方案