
在使用 DeepSeek 的过程中很多同学很快会遇到一个尴尬场景身边有一张截图、一份合同拍照件、或者一张包含业务数据的表格图片想直接扔给 DeepSeek 让它总结分析结果得到一句“我只能理解文本无法查看图片”。这是因为 DeepSeek 的 API 和官方对话产品目前核心能力仍然集中在文本理解与推理上并不像某些原生多模态模型那样可以直接接收图片字节流。不过这并不代表我们没有办法。通过组合 OCR 文字提取、外部视觉理解模型、以及合理的调用编排完全可以给 DeepSeek“安上一双眼睛”让它间接获得看图能力。这套思路通常被称作“伪多模态”模型本身不是多模态的但通过外围模块把图片转换成文本再把文本送入模型最终让用户感受到“它能看图”。这篇文章会从概念讲起给出 3 种可落地的实现方案并配有完整可运行的 Python 代码、环境搭建步骤、常见报错排查和工程化建议。不管你是准备做私有知识库、自动化办公工具还是想在自己的项目里接入图片理解能力都可以直接参考这套方案。1. 为什么说 DeepSeek 需要一副“眼睛”1.1 纯文本模型的瓶颈先明确一个事实DeepSeek 系列模型的强项是语言理解、逻辑推理、代码生成和数学计算它接收的输入是文本 token而不是图片像素。即使是最新版本的 DeepSeek API目前也不支持像 GPT-4o 那样直接上传图片并返回图片内容描述。所以当你把一张图片的 base64 编码直接塞进 DeepSeek 的 messages 里大概率会得到参数错误或“不支持该内容类型”的提示。这不是代码写错了而是模型本身的输入格式限制。1.2 什么是“伪多模态”真正的多模态模型是模型内部完成了视觉编码器和语言模型的联合训练能够直接把图像特征映射为文本语义。而“伪多模态”是一种工程层面的替代方案我们保持大模型不变在它前面增加一个“图片转文字”的中间层。可以这样理解真正的多模态看图 → 模型直接理解 → 输出文本。伪多模态看图 → 中间模块转成文字 → 大模型理解文字 → 输出文本。这个中间层可以是 OCR 工具也可以是独立的视觉理解模型甚至可以是人工标注。只要最终能把图片信息压缩成文本DeepSeek 就能发挥作用。1.3 典型适用场景伪多模态方案在很多实际项目中已经足够用常见的包括合同、发票、身份证等扫描件的字段抽取与总结。产品截图、报错弹窗的识别与分析。技术架构图、流程图转换为文本描述后做解释。表格图片直接转成 Markdown 表格交给模型做数据汇总。本地图片库的自动化管理比如根据图片内容自动生成标签。这些场景的共同特点是图片中包含的信息可以被转述成文字且文字表达不会丢失关键语义。如果图片要求细粒度识别比如人脸、具体物体形状那就不适合用伪多模态方案建议直接使用专用视觉模型。2. 整体方案设计2.1 三条技术路线对比给 DeepSeek 加“眼睛”常见的有三条路线按实现成本和效果不同适合不同阶段。方案核心思路适合场景缺点OCR DeepSeek先用 OCR 提取图片中的文字再把文字发送给 DeepSeek截图、文档、表格、车牌号等文字密集型图片无法理解非文字内容视觉模型 API DeepSeek先调用视觉模型生成图片的整体描述再把描述交给 DeepSeek 做推理需要理解图片语义、物体关系、场景内容的场景依赖外部 API有成本和网络要求本地视觉模型 DeepSeek在本地部署视觉模型或目标检测模型生成文本后交给 DeepSeek隐私要求高、离线环境需要 GPU 资源部署成本高我的建议是初期需求如果只是“图里有字”直接用 OCR 方案如果希望模型能理解“图里发生了什么事”就上视觉模型 API如果项目有数据合规要求或者完全内网部署再考虑本地模型。2.2 推荐的项目结构为了不让代码乱成一团建议按下面的结构组织项目deepseek-vision/ ├── config.py # 配置文件读取环境变量 ├── requirements.txt # Python 依赖 ├── ocr_utils.py # OCR 相关封装 ├── vision_utils.py # 视觉模型相关封装 ├── deepseek_utils.py # DeepSeek 调用封装 ├── processor.py # 主流程图片 - 文本 - DeepSeek └── examples/ ├── sample_receipt.jpg └── demo_ocr.py模块拆分的价值在于当你想把 OCR 换成视觉模型时只需要替换processor.py中的中间层函数主流程不需要大改。3. 环境准备3.1 运行环境说明本文代码以 Python 3.9 为例操作系统可以是 Windows、Linux 或 macOS。涉及 GPU 加速的部分不是必须的OCR 可以用 CPU 跑但性能会慢一些。版本需要根据你的项目实际情况调整本文示例以常见环境为例重点演示配置思路。不要照抄版本号建议创建虚拟环境后重新安装最新稳定版。3.2 安装 Python 依赖创建虚拟环境并安装依赖python -m venv venv source venv/bin/activate # Windows 使用 venv\Scripts\activaterequirements.txt内容如下openai1.30.0 paddleocr2.7.0 paddlepaddle2.6.0 Pillow10.0.0 python-dotenv1.0.0 requests2.31.0安装命令pip install -r requirements.txt注意PaddleOCR 和 PaddlePaddle 的体积较大安装耗时可能较长。如果你只需要识别中文简体可以按需选择 lightweight 模型首次运行会自动下载模型文件。3.3 API Key 准备本教程会调用 DeepSeek API并在第二个方案中调用一个兼容 OpenAI 接口协议的视觉模型 API。为了安全请使用环境变量保存密钥而不是硬编码在代码里。在项目根目录创建.env文件DEEPSEEK_API_KEY你的deepseek_api_key DEEPSEEK_BASE_URLhttps://api.deepseek.com DEEPSEEK_MODELdeepseek-chat VISION_API_KEY你的视觉模型api_key VISION_BASE_URLhttps://你的视觉模型服务地址 VISION_MODEL你的视觉模型名称添加.env到.gitignore避免密钥泄露。4. 方案一OCR DeepSeek识别图片中的文字4.1 为什么先考虑 OCR大多数实际业务图片比如系统截图、文档翻拍、报销发票核心信息几乎全部以文字形式存在。这时候不需要让模型理解“图片美不美”只需要把文字准确提出来DeepSeek 就能完成后续的总结、分类、字段抽取。OCR 的优势是速度快、成本低、可离线部署而且对文字密集图片的识别精度已经非常高。PaddleOCR 是百度开源的一套 OCR 工具链支持中英文、竖排文本、表格结构识别等能力在 CPU 上也能跑。4.2 使用 PaddleOCR 提取文字我们先写一个 OCR 工具模块文件路径ocr_utils.py。# 文件路径ocr_utils.py from paddleocr import PaddleOCR ocr PaddleOCR(use_angle_clsTrue, langch, show_logFalse) def extract_text_from_image(image_path: str) - str: 从图片中提取文字返回按行拼接的纯文本。 result ocr.ocr(image_path, clsTrue) lines [] if not result: return for page in result: if not page: continue for item in page: text item[1][0] lines.append(text) return \n.join(lines)这里说明几个关键点use_angle_clsTrue表示启用方向分类器适合图片方向不固定的场景。langch表示中文识别模型如果你的图片以英文为主可以改为en。show_logFalse避免运行时打印大量日志。整体识别结果是一个嵌套列表每一条结果的item[1][0]就是识别出的文本内容。4.3 将文字交给 DeepSeek拿到图片文字后再把文本交给 DeepSeek。这里使用 OpenAI 官方 SDK 来调用 DeepSeek 的兼容接口文件路径deepseek_utils.py。# 文件路径deepseek_utils.py import os from dotenv import load_dotenv from openai import OpenAI load_dotenv() client OpenAI( api_keyos.getenv(DEEPSEEK_API_KEY), base_urlos.getenv(DEEPSEEK_BASE_URL, https://api.deepseek.com), ) def ask_deepseek(prompt: str, system_prompt: str 你是一个有帮助的助手) - str: 向 DeepSeek 发送对话请求返回模型回复。 resp client.chat.completions.create( modelos.getenv(DEEPSEEK_MODEL, deepseek-chat), messages[ {role: system, content: system_prompt}, {role: user, content: prompt}, ], temperature0.3, ) return resp.choices[0].message.content需要说明的是DeepSeek 的 API 采用 OpenAI 兼容格式所以用openai库可以把base_url指向 DeepSeek 的接口地址这样不需要额外引入多个 SDK。4.4 整合主流程把 OCR 和 DeepSeek 调用串起来文件路径processor.py。# 文件路径processor.py import argparse from ocr_utils import extract_text_from_image from deepseek_utils import ask_deepseek def process_image_with_ocr(image_path: str): # 第一步图片转文字 extracted_text extract_text_from_image(image_path) if not extracted_text.strip(): print(警告OCR 未提取到任何文字请检查图片内容。) return # 第二步构造提示词让 DeepSeek 基于文字内容回答 prompt f 我有一张图片通过 OCR 提取到以下文字内容 {extracted_text} 请根据这些内容完成以下任务 1. 概括图片的主要信息。 2. 整理成结构化的要点。 3. 如果图中包含数字、日期、金额等信息请单独列出。 请直接输出结果。 answer ask_deepseek(prompt) print( OCR 提取结果 ) print(extracted_text) print(\n DeepSeek 分析结果 ) print(answer) if __name__ __main__: parser argparse.ArgumentParser(descriptionOCR DeepSeek 图片文字分析) parser.add_argument(--image, requiredTrue, help图片路径) args parser.parse_args() process_image_with_ocr(args.image)运行效果python processor.py --image examples/sample_receipt.jpg预期输出包含两部分OCR 原样提取的文字以及 DeepSeek 基于这些文字生成的结构化总结。这个方案非常适合发票、报销单、合同扫描件等场景。4.5 方案一的局限OCR 方案最大的局限是如果图片中没有文字那么输出就是空模型什么也做不了。比如你想让模型分析一张产品外观图、一张风景照、一张软件界面截图里的图标布局OCR 就无能为力了。这时候需要第二种方案。5. 方案二调用视觉模型 API生成图片语义描述5.1 为什么 DeepSeek 不能直接接收图片你可能好奇既然 OpenAI 的 GPT-4o 可以直接传图片为什么 DeepSeek 不能这是因为深度求索目前没有开放图片输入接口。即使你传 base64 图片服务端也无法理解。所以第二个方案的核心思路是找一个支持图片输入的视觉模型先把图片变成一段详细的文字描述再让 DeepSeek 基于这段描述做推理和回答。这样用户只接触 DeepSeek 的交互层完全感知不到中间还有一次额外调用。5.2 视觉模型 API 的通用调用方式市面上很多国内大模型厂商提供视觉理解接口比如通义千问 VL、智谱 GLM-4V、MiniCPM-V 等。这些 API 大多兼容 OpenAI 接口协议只是base_url、model名称和调用格式略有差异。以下代码以“兼容 OpenAI 接口的视觉模型”为例实际使用时请根据你的服务商替换环境变量。文件路径vision_utils.py。# 文件路径vision_utils.py import base64 import os from dotenv import load_dotenv from openai import OpenAI load_dotenv() vision_client OpenAI( api_keyos.getenv(VISION_API_KEY), base_urlos.getenv(VISION_BASE_URL), ) def encode_image_to_base64(image_path: str) - str: with open(image_path, rb) as f: return base64.b64encode(f.read()).decode(utf-8) def describe_image(image_path: str, prompt: str 请用中文详细描述这张图片的内容) - str: 调用视觉模型生成图片描述。 base64_image encode_image_to_base64(image_path) resp vision_client.chat.completions.create( modelos.getenv(VISION_MODEL), messages[ { role: user, content: [ {type: text, text: prompt}, { type: image_url, image_url: {url: fdata:image/jpeg;base64,{base64_image}}, }, ], } ], max_tokens800, ) return resp.choices[0].message.content这段代码的关键点图片必须转成 base64然后以data:image/jpeg;base64,前缀构成图片 URL。视觉模型的messages结构里content是一个数组包含文本和图片两类内容。max_tokens要根据图片复杂度调整避免描述被截断。如果图片包含大量细节建议设为 1000 以上。5.3 把视觉描述接入 DeepSeek 分析流程得到了图片描述以后接下来的流程就与 OCR 方案类似只是输入从“图片里的文字”变成了“视觉模型对图片的整体描述”。文件路径processor_vision.py。# 文件路径processor_vision.py import argparse from vision_utils import describe_image from deepseek_utils import ask_deepseek def process_image_with_vision(image_path: str): # 第一步视觉模型生成图片描述 description describe_image( image_path, prompt请详细描述这张图片的内容包括主体、场景、文字、颜色、尺寸比例、人物动作等。, ) # 第二步将描述交给 DeepSeek 做进一步分析 prompt f 以下是某个视觉模型对一张图片的完整描述 {description} 请基于这个描述完成以下任务 1. 判断图片的类型和用途。 2. 提取关键信息并结构化展示。 3. 如果这是一张商品图请给出营销建议如果是一张截图请分析页面功能如果是图表请解读数据趋势。 请结合常识和逻辑推理给出尽可能详细的回答。 answer ask_deepseek(prompt) print( 视觉模型描述 ) print(description) print(\n DeepSeek 分析结果 ) print(answer) if __name__ __main__: parser argparse.ArgumentParser(description视觉模型 DeepSeek 图片语义分析) parser.add_argument(--image, requiredTrue, help图片路径) args parser.parse_args() process_image_with_vision(args.image)运行命令python processor_vision.py --image examples/architecture.png这个方案能回答“图片里是什么”“场景大概是怎样的”这类问题适用范围比 OCR 广很多。比如你上传一张系统架构图视觉模型会把连线、模块名、箭头方向描述出来DeepSeek 再基于这些信息解释架构设计。5.4 方案二的成本与延迟视觉模型 API 通常是按图片张数和输出 token 计费的因此成本会比纯 OCR 高。延迟也更高因为一次请求需要先经历视觉模型推理再到 DeepSeek 推理整体调用链路变长。如果对成本敏感可以优化描述提示词让视觉模型输出尽量精简比如“只列出关键元素不要发散描述”。如果是离线批量分析建议增加任务队列和失败重试机制。6. 方案三本地视觉模型 DeepSeek隐私优先6.1 本地部署的选型思路如果你的业务涉及用户隐私或企业敏感数据所有图片不能出内网那就不能依赖云端视觉 API。这种情况下可以考虑在本地 GPU 服务器上部署一个多模态模型让它代替云端 API 完成图片描述。可以选择开源的多模态模型例如 MiniCPM-V、Qwen2-VL 系列等。选型时主要看三个指标显存占用、推理速度、中文理解能力。项目起步建议先用参数量较小的模型验证流程待效果确认后再升级到更大版本。由于不同模型的启动方式和推理代码差异很大本文不展开具体部署命令只给出通用调用思路。6.2 本地推理服务的标准接口为了让本地模型对上层代码透明最稳妥的方式是用 vLLM 或 FastAPI 把本地模型包装成一个 OpenAI 兼容的 HTTP 服务。这样vision_utils.py里的调用代码完全不用改只需要把VISION_BASE_URL指到本机地址把VISION_MODEL改成部署的模型名即可。假设部署完成后本地服务地址为http://localhost:8000/v1那么.env中的配置可以调整为VISION_API_KEYlocal VISION_BASE_URLhttp://localhost:8000/v1 VISION_MODELlocal-vision-model这种方式的好处是上层业务代码与底层模型解耦。后续想从云端视觉 API 切换成本地模型只需要改环境变量不需要动处理器代码。6.3 隐私与性能的平衡本地部署并非没有成本。一个视觉模型至少需要 8GB 以上显存才能流畅运行如果图片分辨率较高还需要更大显存。CPU 推理速度会很慢不建议用于实时交互场景。更务实的做法是分级架构普通图片走云端视觉 API涉及敏感数据的图片走本地模型。这样既控制了成本又保护了关键数据。7. 常见问题与排查清单在实际开发中最容易出问题的并不是模型理解能力而是接口调用、环境依赖和图片预处理。下面整理了常见问题。问题现象常见原因解决思路OpenAI 库提示base_url错误环境变量没加载或路径写错确认.env文件是否被读取打印os.getenv检查DeepSeek 返回 401 错误API Key 无效或没有余额检查 key 是否正确去平台确认余额DeepSeek 返回 400 错误消息格式不对或传入图片字段确认 messages 只包含文本不要传 image_urlOCR 识别结果为空图片模糊、字体过小或模型未下载完成提高图片分辨率裁剪区域检查 PaddleOCR 模型文件视觉模型描述太短max_tokens太小或提示词不让发散提高 max_tokens换更详细的提示词本地视觉模型服务启动失败显存不足或依赖缺失使用nvidia-smi查看显存按文档检查 CUDA 版本API 调用超时图片太大或网络延迟压缩图片、设置合理的 timeout、增加重试机制7.1 图片过大导致请求失败很多视觉 API 对单张图片大小有限制通常建议控制在 1MB 以内。可以用 Pillow 做压缩在调用视觉模型之前先处理图片。from PIL import Image def compress_image(image_path: str, max_size: int 1024, quality: int 85) - str: 将图片压缩到指定最大边长和大小返回压缩后的临时文件路径。 img Image.open(image_path) img.thumbnail((max_size, max_size)) output_path image_path.replace(.jpg, _compressed.jpg) img.save(output_path, JPEG, qualityquality) return output_path这个步骤虽然不是必须但在批量处理时能明显降低请求失败率。7.2 提示词如何设计无论哪种方案中间层输出都是文本所以 DeepSeek 的分析质量很大程度上取决于提示词。建议把任务说清楚不要只是简单说“分析一下”。比如可以这样写请提取合同中的甲方、乙方、金额、签署日期。请把这张表格数据转换成 Markdown 格式。请判断这张截图中有哪些异常状态。提示词越具体输出越可控。8. 最佳实践与工程建议8.1 密钥管理与权限隔离API Key 是重要的敏感信息绝对不要提交到 Git 仓库。生产环境建议使用专门的密钥管理服务或者至少在服务器上通过环境变量注入。如果接入公司内部系统还要注意根据最小权限原则分配 API Key避免一个账号能访问所有模型。8.2 增加缓存避免重复调用图片分析往往具备重复性比如同一张商品图可能被多次请求。可以在 Redis 或本地文件中增加缓存键为图片的 MD5 值值为最终分析结果。这样可以极大节省 API 调用成本。import hashlib def get_image_md5(image_path: str) - str: with open(image_path, rb) as f: return hashlib.md5(f.read()).hexdigest()8.3 异常处理与重试机制调用外部 API 不可避免会发生网络抖动建议封装一个带重试的请求函数。import time from openai import OpenAI def request_with_retry(func, retries: int 3, delay: float 2.0, **kwargs): for i in range(retries): try: return func(**kwargs) except Exception as e: print(f第 {i 1} 次请求失败{e}) if i retries - 1: raise time.sleep(delay * (i 1))8.4 日志记录与数据追踪生产环境中一定要记录每次图片分析的来源、中间层模型、耗时、token 消耗量和结果状态。可以使用 Python 标准库logging或接入 ELK 等日志系统。这样一旦出现错误可以快速定位是哪一层出了问题。8.5 灰度发布与回滚如果这套能力面向线上用户建议先在小范围灰度开放。可以先对内部员工开放试用再逐步放大用户比例。因为伪多模态链路涉及两个模型任何一个上游模型升级或调整接口都可能影响下游输出质量。上线后要有监控面板关注调用成功率、平均延迟和用户反馈。8.6 不要让“伪”变成“劣”伪多模态方案虽然能解决“看不了图”的问题但毕竟不是真正的多模态理解。如果业务对图片识别精度要求极高比如自动驾驶、医疗影像、安防监控请直接选用专门的多模态模型。伪多模态更适合文本密集型图片或作为临时补充能力来使用。9. 总结与下一步通过这篇文章我们给 DeepSeek 补上了一条完整的“视觉链路”。方案一使用 OCR 提取图片文字适合发票、截图、文档等文字密集场景。方案二在外部视觉模型 API 的帮助下让 DeepSeek 间接理解图片语义适合需要整体描述的场景。方案三将视觉模型部署到本地满足隐私合规和离线部署要求。后续如果你想继续深入可以按照以下路线学习掌握 OpenAI 兼容接口的通用调用方式这能让你快速对接不同模型。研究提示词工程尤其是如何把中间层输出更好地组织成任务指令。了解 RAG 和 agent 框架把图片能力接入更复杂的自动化和问答系统。学习模型评测方法建立一套图片分析效果评估集避免靠感觉调参。最后提醒一句任何技术方案都要先明确业务边界。伪多模态适合快速补齐能力但如果你发现 80% 以上的图片需求都是强视觉理解那就应该考虑换用真正的多模态模型。动手搭建时建议先从你手里最常用的一类图片开始跑通后再逐步扩展到更多场景。