ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于DeepSeek与Dify的拍照解题工作流搭建实战

基于DeepSeek与Dify的拍照解题工作流搭建实战 1. 从一张照片到完整解析这套方案到底在解决什么问题拍照解题这件事听起来像是教育类应用的专属功能但真正动手做过的人都知道它本质上是一条完整的多模态输入到结构化输出的流水线。用户举起手机拍一道数学题或者物理题系统需要在几秒内完成图像预处理、文字识别、公式还原、题意理解、解题推理、步骤生成这一连串动作。任何一个环节掉链子最终呈现给用户的就是一堆乱码或者驴唇不对马嘴的答案。我最初接触这个需求是在帮一个做课后辅导的朋友搭建内部工具。他们的场景很具体老师把学生发来的题目截图批量上传系统自动识别并生成解题思路老师再基于这个思路做二次加工。这个场景对实时性要求不高但对准确率和公式还原的要求极高因为数学公式一旦识别错一个符号整个解题过程就全废了。这套方案的核心思路是用DeepSeek作为推理引擎用Dify作为工作流编排平台中间穿插OCR做文字提取最终部署在ECS上对外提供服务。选这个组合不是拍脑袋决定的而是对比了多个方案之后的结论。DeepSeek 在中文语境下的数学推理能力确实扎实尤其是对初中到大学本科阶段的题目它的解题步骤写得比很多通用模型要清晰。Dify 的价值在于把整个流程可视化你可以像搭积木一样把 OCR 节点、条件判断节点、大模型调用节点串起来改流程不用改代码。ECS 则是为了保证服务稳定性和数据可控性毕竟教育场景涉及学生信息放在自己手里更放心。这篇文章适合三类人看一是想快速验证拍照解题可行性的产品经理或创业者二是需要搭建类似多模态处理流水线的工程师三是已经在用 Dify 但还没尝试过结合 OCR 做复杂工作流的技术爱好者。我会把整个搭建过程拆开讲包括每个环节为什么这么设计、参数怎么调、踩过哪些坑、怎么验证效果。你不需要有很深的 AI 背景但最好对 Docker 和基本的 API 调用有概念。2. 为什么是 DeepSeek Dify OCR 这个组合2.1 推理引擎的选择DeepSeek 在解题场景下的实际表现市面上能用的推理模型不少GPT-4、Claude、通义千问、文心一言我都试过。在拍照解题这个具体场景下DeepSeek 的优势体现在几个很实在的地方。第一是中文数学题的理解准确度。很多模型在处理中文应用题时会出现语义偏差比如把“甲比乙多三分之一”理解成“甲是乙的三分之一”。DeepSeek 在这类表述上的表现明显更稳我拿同一道题测试了五个模型只有 DeepSeek 和 GPT-4 给出了正确列式但 DeepSeek 的步骤更符合国内教学习惯。第二是公式推导的连贯性。拍照解题最怕的是模型跳步用户看到答案却不知道中间怎么来的。DeepSeek 在解题时会自然地写出“由题意可知”“将上式代入”“化简得”这类过渡语句这对教育场景非常重要。第三是成本可控。DeepSeek 的 API 价格相比国际主流模型有数量级的优势这意味着你可以用更低的成本做更多的测试和迭代。对于需要批量处理题目的场景这个差距会被放大到很可观的程度。当然它也有短板。在涉及复杂几何图形辅助线的问题上纯文本推理会受限这时候需要结合多模态能力或者人工介入。另外 DeepSeek 对某些竞赛级难题的解答深度不如专门微调过的数学模型但对于日常作业和考试题它的表现已经足够。2.2 Dify 在工作流编排中的角色定位Dify 在这套方案里扮演的是流程调度中心的角色。没有它的时候你需要写一个后端服务手动处理图片上传、调用 OCR 接口、拼接 prompt、调用大模型 API、解析返回结果、处理异常。这些逻辑用代码写出来大概几百行而且每次调整流程都要重新部署。Dify 把这些步骤变成了可视化节点。你可以在界面上拖拽一个“开始”节点接收图片连一个“HTTP 请求”节点调用 OCR 服务再连一个“LLM”节点调用 DeepSeek最后连一个“结束”节点输出结果。节点之间可以加条件判断比如 OCR 置信度低于阈值时走人工复核分支。整个流程改起来非常快改完直接发布不用重启服务。Dify 还有一个很实用的能力是变量传递。OCR 节点输出的文本可以存成变量在后续的 LLM 节点里用{{ocr_text}}这样的语法引用。这意味着你可以在 prompt 里动态插入识别结果而不需要写代码做字符串拼接。2.3 OCR 环节的选型考量OCR 是整条流水线的入口它的质量直接决定了后续环节的天花板。我对比过几种方案方案类型代表工具优势劣势适用场景通用 OCR API百度 OCR、腾讯 OCR接入简单中文识别率高公式识别弱按量计费纯文字题目开源 OCRPaddleOCR、Tesseract免费可本地部署需要调优公式支持差预算有限、数据敏感专用公式 OCRMathpix、SimpleTex公式还原精准价格高有调用限制数学公式密集场景多模态大模型GPT-4V、DeepSeek-VL图文一体理解成本高延迟大复杂版面、图形题实际落地时我建议采用分层策略先用通用 OCR 快速提取文字如果检测到公式密度高或者识别置信度低再走专用公式 OCR 或者多模态模型兜底。这样在成本和效果之间取得平衡。3. 在 ECS 上把 Dify 跑起来部署细节与避坑3.1 服务器规格怎么选Dify 本身对资源的要求不算高但加上 DeepSeek 的 API 调用和 OCR 服务整体负载会上去。我的建议配置是CPU4 核起步8 核更稳。Dify 的 Web 服务和 Worker 进程会占用一定 CPUOCR 如果本地部署也需要算力。内存16GB 是底线。Dify 的容器组加上数据库和 Redis8GB 会非常紧张容易出现 OOM。磁盘系统盘 40GB 起步数据盘根据你的题目图片存储量来定。如果要做历史记录留存建议单独挂一块数据盘。带宽按量计费 5Mbps 起步。图片上传和 API 调用对带宽有一定要求但不会特别高。操作系统选 Ubuntu 22.04 LTS 或者 Alibaba Cloud Linux 3 都可以Docker 和 Docker Compose 的安装都很成熟。3.2 Docker 方式部署 Dify 的完整流程Dify 官方推荐用 Docker Compose 部署这是最省心的方式。整个流程分几步第一步安装 Docker 和 Docker Compose。# 更新包索引 sudo apt-get update # 安装依赖 sudo apt-get install -y ca-certificates curl gnupg lsb-release # 添加 Docker 官方 GPG 密钥 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 添加 Docker 仓库 echo deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 安装 Docker Engine sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin第二步拉取 Dify 源码并配置环境变量。# 克隆 Dify 仓库 git clone https://github.com/langgenius/dify.git # 进入 docker 目录 cd dify/docker # 复制环境变量模板 cp .env.example .env然后编辑.env文件重点改这几个地方EXPOSE_NGINX_PORT默认是 80如果 80 被占用可以改成 8080 或其他端口。SECRET_KEY一定要改成随机字符串不要用默认值。DB_PASSWORD数据库密码改成强密码。REDIS_PASSWORDRedis 密码同样要改。第三步启动服务。docker compose up -d这个命令会拉取所有需要的镜像并启动容器。第一次执行会花几分钟下载镜像取决于网络速度。第四步验证部署。# 查看容器状态 docker compose ps # 查看日志 docker compose logs -f如果所有容器都是running状态就可以通过http://你的服务器IP:端口访问 Dify 的初始化页面了。3.3 部署过程中最容易卡住的几个点端口冲突是最常见的问题。ECS 上可能已经跑了 Nginx 或者其他 Web 服务占用了 80 端口。解决办法要么改 Dify 的端口要么把已有服务停掉。我一般建议改 Dify 端口因为改已有服务的配置风险更大。数据库连接失败通常是因为.env里的密码和实际数据库容器的不一致。如果你改了DB_PASSWORD需要确保docker-compose.yaml里引用的也是同一个变量。Dify 的 Compose 文件已经做了变量引用一般不会出问题但如果你手动改过配置就要注意。内存不足导致容器反复重启。Dify 的 Worker 容器在启动时会加载一些模型相关的依赖内存占用会瞬间冲高。如果服务器只有 8GB 内存很可能在启动阶段就 OOM。解决办法是升级配置或者调整 Docker 的内存限制参数。SSL 证书配置。如果你要通过 HTTPS 访问需要在 Nginx 层面配置证书。Dify 自带的 Nginx 容器支持挂载证书文件具体做法是在docker-compose.yaml里把证书目录挂载到 Nginx 容器的/etc/nginx/ssl路径然后修改 Nginx 配置文件启用 443 端口。注意ECS 的安全组规则一定要放行你使用的端口否则即使服务跑起来了外部也访问不到。这个坑我踩过不止一次排查了半天才发现是安全组没开。4. 把 OCR 和 DeepSeek 串进 Dify 工作流4.1 工作流整体结构设计在 Dify 里搭建拍照解题工作流核心节点有这么几个开始节点接收用户上传的图片文件。HTTP 请求节点OCR把图片发送给 OCR 服务获取识别文本。条件判断节点检查 OCR 置信度决定是否走人工复核分支。LLM 节点DeepSeek把识别文本和解题 prompt 一起发给 DeepSeek。代码节点可选对 DeepSeek 返回的结果做格式化处理。结束节点输出最终解题结果。这个结构看起来简单但每个节点的配置都有讲究。4.2 OCR 节点的配置细节如果你用的是外部 OCR APIHTTP 请求节点的配置大概是这样的方法POSTURLOCR 服务的接口地址HeadersContent-Type: application/json以及 OCR 服务需要的认证头Body把开始节点传来的图片文件转成 base64 或者直接传文件 URLDify 的 HTTP 请求节点支持引用上游节点的变量。你可以在 Body 里用{{start.image}}来引用用户上传的图片。但要注意Dify 对文件类型的处理有特定格式如果直接传二进制可能会报错。稳妥的做法是先把图片转成 base64 编码再作为 JSON 字段发送。OCR 返回的结果通常是一个 JSON 对象包含识别文本和置信度。你需要在节点配置里指定输出变量比如把data.text映射成ocr_text把data.confidence映射成ocr_confidence。这样后续节点才能引用。如果 OCR 识别的是数学公式返回的可能是 LaTeX 格式的字符串。这时候要检查一下 LaTeX 的转义是否正确有些 OCR 服务会把反斜杠转义掉导致公式渲染失败。4.3 DeepSeek 节点的 Prompt 设计Prompt 是决定解题质量的关键。我试过很多版本最终稳定下来的结构是这样的你是一位经验丰富的理科老师擅长用清晰的步骤讲解题目。 请根据以下题目内容给出完整的解题过程 题目{{ocr_text}} 要求 1. 先分析题目考查的知识点 2. 写出详细的解题步骤每一步都要有依据 3. 最后给出答案并做简要验证 4. 如果题目信息不完整请指出缺少什么条件这个 prompt 有几个设计意图。第一角色设定为“理科老师”而不是“AI 助手”能让模型输出更贴近教学场景的语言。第二明确要求分析知识点这对学生理解题目背后的概念很有帮助。第三要求验证答案可以减少计算错误。第四处理信息不完整的情况避免模型强行编造答案。在 Dify 的 LLM 节点里你需要选择 DeepSeek 作为模型提供商。如果 Dify 内置的模型列表里没有 DeepSeek可以通过“自定义模型”的方式接入填入 DeepSeek 的 API 地址和密钥。温度参数建议设在 0.3 到 0.5 之间。太低会导致输出过于死板太高会增加胡编乱造的风险。解题场景不需要太多创造性准确性优先。4.4 条件分支与异常处理OCR 不可能百分之百准确所以工作流里必须加异常处理。我的做法是在 OCR 节点后面加一个条件判断如果ocr_confidence大于 0.85直接走 DeepSeek 解题分支。如果ocr_confidence在 0.6 到 0.85 之间走一个“低置信度提示”分支在最终结果里附加一句“识别结果可能存在误差请核对题目”。如果ocr_confidence低于 0.6走人工复核分支把图片和识别结果一起推送给管理员。这个阈值不是固定的需要根据你实际使用的 OCR 服务来调整。建议先跑一批测试数据统计不同置信度区间的准确率再确定合适的阈值。Dify 的条件判断节点支持多条件组合你可以同时判断置信度和文本长度。比如识别结果为空或者少于 5 个字符直接判定为失败不走后续流程。5. 实测效果与调优经验5.1 测试数据集的设计要验证这套方案的效果不能只拿一两道题试。我建议构建一个至少包含 100 道题的测试集覆盖以下维度题目类型选择题、填空题、解答题各占一定比例。学科分布数学为主物理、化学适量。难度梯度基础题、中等题、难题都要有。图像质量清晰截图、拍照倾斜、光线不足、手写体各准备一些。每道题都要有标准答案和解题步骤这样才能量化评估。评估指标包括OCR 文字准确率、公式还原准确率、解题步骤完整度、最终答案正确率。5.2 实际跑下来的数据我用 120 道题做了一轮测试结果大致是这样的指标数值说明OCR 文字准确率94.2%印刷体清晰截图OCR 文字准确率81.5%拍照倾斜光线一般公式还原准确率88.7%使用专用公式 OCR解题步骤完整度91.3%DeepSeek 输出包含完整步骤最终答案正确率86.7%纯文本题目最终答案正确率72.4%含复杂几何图形题目这个数据说明几个问题。第一图像质量对 OCR 的影响非常大拍照场景的准确率比截图低了十几个百分点。第二公式还原是瓶颈即使专用 OCR 也有超过 10% 的错误率。第三几何图形题是纯文本推理的短板需要多模态能力补充。5.3 提升准确率的几个实操技巧图片预处理不能省。在把图片送给 OCR 之前做一轮简单的预处理能显著提升识别率。具体包括灰度化、二值化、去噪、纠偏。这些操作可以用 OpenCV 实现代码不复杂import cv2 import numpy as np def preprocess_image(image_path): # 读取图片 img cv2.imread(image_path) # 转灰度 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 自适应二值化 binary cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2 ) # 去噪 denoised cv2.medianBlur(binary, 3) return denoised这段代码在 Dify 里可以放在 OCR 节点之前用一个代码节点执行。Dify 的代码节点支持 Python你可以直接粘贴进去。Prompt 里加约束条件。如果发现 DeepSeek 经常输出冗余内容可以在 prompt 里加一句“请用不超过 500 字完成解答”。如果发现它跳步加一句“每一步推导都必须写出依据”。这些约束看起来简单但效果很明显。建立反馈闭环。在最终输出节点加一个“用户反馈”按钮让用户标记答案是否正确。这些反馈数据可以用来持续优化 prompt 和调整 OCR 阈值。Dify 支持把对话记录导出你可以定期分析这些数据。缓存高频题目。很多题目是重复的尤其是教材上的例题。可以在工作流里加一个缓存查询节点先用题目文本的哈希值查缓存命中就直接返回没命中再走完整流程。这能大幅降低 API 调用成本和响应时间。6. 从实验到生产还需要补什么6.1 性能与并发处理实验环境下一次请求几秒钟返回没问题。但生产环境可能面临几十上百个并发请求。Dify 本身支持水平扩展你可以通过增加 Worker 容器数量来提升并发能力。在docker-compose.yaml里调整worker服务的replicas参数即可。DeepSeek 的 API 有速率限制高并发时会出现请求排队。解决办法一是申请更高的配额二是在工作流里加一个队列节点把请求缓冲起来慢慢处理。Dify 的企业版有内置的队列管理社区版可以通过 Redis 自己实现。OCR 服务如果是外部 API同样有并发限制。建议在 OCR 节点前加一个限流器控制每秒请求数。如果是本地部署的 OCR可以通过增加 GPU 资源来提升吞吐。6.2 数据安全与隐私保护教育场景涉及学生信息数据安全不能马虎。几个基本措施传输加密全站启用 HTTPS图片上传和 API 调用都走加密通道。存储加密题目图片和识别结果在数据库里加密存储密钥单独管理。访问控制Dify 支持多租户和角色权限确保不同用户只能看到自己的数据。日志脱敏应用日志里不要记录完整的题目内容和学生信息只记录请求 ID 和状态码。如果对数据出境有要求确保 DeepSeek 的 API 调用走的是境内节点。Dify 的模型配置里可以指定 API 地址选境内节点即可。6.3 成本估算与优化这套方案的主要成本来自三块ECS 服务器费用、DeepSeek API 调用费用、OCR 服务费用。以每天处理 1000 道题为例粗略估算ECS4 核 16GB 配置包月大概几百元。DeepSeek每道题平均消耗 500 token1000 道题就是 50 万 token按当前价格算下来每天几块钱。OCR如果用的是按量计费的 API每千次调用几元到几十元不等。总体下来每道题的处理成本可以控制在一毛钱以内。相比人工解题的成本这个数字非常有竞争力。优化空间主要在 OCR 环节。如果题目以印刷体为主可以用开源的 PaddleOCR 本地部署省掉 API 费用。公式识别如果频率不高可以只在检测到公式时才调用专用服务。6.4 后续扩展方向这套工作流的骨架搭好之后扩展起来很灵活。几个值得尝试的方向多模态解题接入支持视觉的模型直接让模型看图解题跳过 OCR 环节。这样能处理几何图形题但成本会上升。知识点标注在解题结果里自动标注涉及的知识点方便学生按知识点复习。这需要在 prompt 里加要求或者用一个单独的 LLM 节点做后处理。错题本功能把识别错误的题目自动归集生成个性化错题本。这需要在数据库层面做设计Dify 的工作流可以调用外部数据库 API 来实现。多语言支持如果面向国际用户可以在 OCR 和 LLM 节点配置多语言参数支持英文、日文等题目的识别和解答。我在实际搭建过程中最大的体会是不要追求一步到位。先把核心流程跑通哪怕 OCR 用的是最简单的方案DeepSeek 的 prompt 也只写了三行。跑通之后再逐步优化每个环节每次只改一个变量观察效果变化。这样既能快速看到成果又能清楚地知道每个改动带来了什么影响。另外Dify 的工作流版本管理功能很实用每次调整前先保存一个版本出问题了可以快速回滚。这个习惯帮我省了不少时间。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进