第14章:多模态AI实战 —— 让AI“看懂“图片和文档
本章目标掌握多模态 AI 的核心概念使用阿里云百炼 Qwen-VL 模型实现图像理解、视觉问答、结构化信息提取等实际场景能够将多模态能力集成到生产 AI 应用中。前期回顾AI入门开发系列文章合集本章你将学到多模态 AI 与纯文本 AI 的本质区别和应用场景Qwen-VL 视觉语言模型的能力边界与调用方式用 OpenAI SDK 和 LangChain 两种方式调用多模态 API从图像中提取结构化 JSON 数据零代码图像解析链式思维CoT视觉推理让模型分步思考图像实际生产场景电商图文描述、文档数字化、质量检测一、什么是多模态AI1.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_keyos.getenv(DASHSCOPE_API_KEY)ifnotapi_key:print(错误请设置环境变量 DASHSCOPE_API_KEY)sys.exit(1)returnOpenAI(api_keyapi_key,base_urlhttps://dashscope.aliyuncs.com/compatible-mode/v1,) 多模态模型与文本模型使用同一个客户端只是model参数和content格式不同。3.2 Demo 1基础图像描述# 公共测试图像DashScope 官方示例图IMAGE_DOG_AND_GIRLhttps://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpegdefdemo_image_description(client:OpenAI)-str:让模型用自然语言描述一张图片。print(\n️ Demo 1基础图像描述)print(f 图像 URL{IMAGE_DOG_AND_GIRL})responseclient.chat.completions.create(modelqwen-vl-plus,messages[{role:user,content:[{type:image_url,image_url:{url:IMAGE_DOG_AND_GIRL}},{type:text,text:请详细描述这张图片的内容包括人物、动物、环境和氛围。}],}],)descriptionresponse.choices[0].message.contentprint(f 描述结果\n{description})returndescription运行效果️ Demo 1基础图像描述 图像 URLhttps://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg 描述结果 图片中是一位女孩和一只金毛猎犬在户外草地上互动...3.3 Demo 2视觉问答IMAGE_ANThttps://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpgdefdemo_visual_qa(client:OpenAI)-str:针对图像提出具体问题获取精准答案。print(\n❓ Demo 2视觉问答)responseclient.chat.completions.create(modelqwen-vl-plus,messages[{role:user,content:[{type:image_url,image_url:{url:IMAGE_ANT}},{type:text,text:(请回答以下问题\n1. 这是什么动物\n2. 图中有几只\n3. 它们在做什么\n4. 图像风格是什么特写/全景/微距等)},],}],)answerresponse.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多图对比分析)responseclient.chat.completions.create(modelqwen-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:请对比这两张图片从主体内容、拍摄风格、色调三个维度进行分析。},],}],)comparisonresponse.choices[0].message.contentprint(f 对比结果\n{comparison})returncomparison⚠️注意两张图片放在同一个content列表中API 会自动关联它们的上下文。四、进阶结构化信息提取4.1 为什么需要结构化输出视觉理解给你自然语言描述但业务系统需要结构化数据纯描述不可用于系统 这是一个红色的苹果手机8GB内存价格大约在5000元左右 结构化输出可直接写入数据库 { brand: Apple, color: 红色, memory: 8GB, estimated_price: 5000 }4.2 DemoJSON 结构化提取# lessons/14_multimodal/02_structured_extraction.pyimportjsonimportredefdemo_json_extraction(client:OpenAI)-dict:从图像中提取结构化 JSON 数据。print(\n DemoJSON 结构化提取)prompt请分析这张图片以 JSON 格式返回以下信息 { main_subject: 图片主体一句话, scene_type: 场景类型室内/室外/自然/城市等, lighting: 光线条件明亮/昏暗/自然光/人工光等, dominant_colors: [主要颜色列表], objects_count: 可见主要物体数量数字, image_quality: 图像质量高/中/低, mood: 整体氛围一个词 } 只返回 JSON不要其他文字。responseclient.chat.completions.create(modelqwen-vl-plus,messages[{role:user,content:[{type:image_url,image_url:{url:IMAGE_DOG_AND_GIRL}},{type:text,text:prompt},],}],)rawresponse.choices[0].message.content# 提取 JSON 块处理模型可能带 markdown 代码块的情况json_matchre.search(r\{.*\},raw,re.DOTALL)ifjson_match:datajson.loads(json_match.group())print(f ✅ 提取成功\n{json.dumps(data,ensure_asciiFalse,indent4)})returndatareturn{}关键技巧在提示词中明确说明 JSON 结构和字段含义用re.search(r\{.*\}, raw, re.DOTALL)提取 JSON因为模型可能带 markdown 代码块加上json.loads()的异常处理4.3 链式思维视觉推理对于复杂的视觉分析让模型分步思考比一步到位更准确defdemo_chain_of_thought_reasoning(client:OpenAI)-str:使用链式思维CoT引导模型进行深度视觉推理。print(\n Demo链式思维视觉推理)cot_prompt请按照以下步骤分析这张图片 步骤1 - 观察描述你看到的所有视觉元素物体、人物、背景 步骤2 - 分析分析这些元素之间的关系和图片的核心主题 步骤3 - 推断基于以上分析推断这张图片可能的用途或背景故事 请按步骤1、步骤2、步骤3的格式逐步输出。responseclient.chat.completions.create(modelqwen-vl-plus,messages[{role:user,content:[{type:image_url,image_url:{url:IMAGE_DOG_AND_GIRL}},{type:text,text:cot_prompt},],}],)reasoningresponse.choices[0].message.contentprint(f 推理过程\n{reasoning})returnreasoning4.4 LangChain 集成方式# LangChain 多模态调用方式fromlangchain_core.messagesimportHumanMessage,SystemMessagefromlangchain_openaiimportChatOpenAIdefdemo_langchain_multimodal()-str:使用 LangChain ChatOpenAI 进行多模态调用。llmChatOpenAI(modelqwen-vl-plus,base_urlhttps://dashscope.aliyuncs.com/compatible-mode/v1,api_keyos.getenv(DASHSCOPE_API_KEY),)# HumanMessage 的 content 同样是列表格式messageHumanMessage(content[{type:image_url,image_url:{url:IMAGE_DOG_AND_GIRL}},{type:text,text:这张图片里有什么请简洁描述。},])responsellm.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)流式输出streamTrue.stream()方法推荐场景简单视觉任务、快速原型复杂应用、需要与 Chain/Agent 集成# LangChain with_structured_output 示例frompydanticimportBaseModel,FieldclassImageMetadata(BaseModel):main_subject:strField(description图片主体描述)scene_type:strField(description场景类型)dominant_colors:list[str]Field(description主要颜色列表)mood:strField(description整体氛围)structured_llmllm.with_structured_output(ImageMetadata)resultstructured_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不要其他内容。responseclient.chat.completions.create(modelqwen-vl-plus,messages[{role:user,content:[{type:image_url,image_url:{url:product_image_url}},{type:text,text:prompt},]}])rawresponse.choices[0].message.content json_matchre.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。responseclient.chat.completions.create(modelqwen-vl-max,# 文档理解用更强的模型messages[{role:user,content:[{type:image_url,image_url:{url:document_image_url}},{type:text,text:prompt},]}])rawresponse.choices[0].message.content json_matchre.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需要转换为 Base64importbase64defimage_to_base64(image_path:str)-str:将本地图片转换为 base64 data URL。withopen(image_path,rb)asf:image_database64.b64encode(f.read()).decode(utf-8)# 推断 MIME 类型suffiximage_path.lower().split(.)[-1]mime_map{jpg:jpeg,jpeg:jpeg,png:png,gif:gif,webp:webp}mimemime_map.get(suffix,jpeg)returnfdata:image/{mime};base64,{image_data}# 使用方式data_urlimage_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:responseclient.chat.completions.create(modelqwen-vl-plus,messages[{role:user,content:[{type:image_url,image_url:{url:image_url}},{type:text,text:question},]}],timeout30,# 图像下载可能较慢设置合理超时)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 集成✅HumanMessagewith_structured_output下一步建议第15章 AI应用评估与测试 —— 如何评估多模态 AI 的输出质量尝试将视觉理解加入 RAG 管道图文混合索引探索更复杂场景多轮视觉对话、视频关键帧分析AI入门开发系列文章合集作者阿聪谈架构阿聪谈架构分享后端架构 / AI / Java 技术文章相关代码关注【阿聪谈架构】 回复AI专栏代码