news 2026/10/23 3:39:11

用Dify与DeepSeek搭建拍照解题工作流:OCR+提示词设计实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Dify与DeepSeek搭建拍照解题工作流:OCR+提示词设计实战

1. 先说说我为什么折腾这套拍照解题

起因其实挺简单。我那段时间经常要帮家里小孩看作业,从小学数学到初中物理都混着来。试过市面上一些拍照搜题App,答案倒是快,但有两件事让我很不爽:一是它只给答案不解释思路,小孩看一眼答案抄上去,下次照样不会;二是碰到稍微偏一点的题,它就给你匹配出莫名其妙的相似题,答案驴唇不对马嘴。

后来我干脆想,既然手头有DeepSeek的API,又一直在用Dify做各种自动化流程,能不能自己搭一个"拍照→识别题目→大模型分步讲解"的闭环?DeepSeek负责逻辑推理和讲解,Dify负责把图像识别、问题重构、模型调用这些环节串起来。这套东西不用写多复杂的代码,Dify的可视化编排能省掉我大量的工程时间,最后落地确实比我想象中顺利。

这篇文章就是那份实验手册的整理版。我默认你和我一样,用过或者至少听说过Dify,知道它是个能编排大模型应用的开源平台;也知道DeepSeek是个API价格相对亲民、推理能力在线的对话模型。如果你完全没接触过这两样,也能照着手册跑通,只是中间有些概念需要自己补一下课。

我要把整套系统的拆解思路、Dify里的具体配置步骤、以及我跑了一周之后遇到的各种识别翻车案例,全部分享出来。适合谁看?想用现有大模型能力捣鼓一个实际工具的开发者、教育行业里想给内部做答疑系统的朋友,还有那些"手里有API但不知道该做什么"的玩家。这套东西的价值不在于"解题"本身,而在于它演示了一条完整的路径:怎么把图片内容变成模型能读懂的文本,怎么让模型按照你想要的格式输出,怎么在不写后端代码的情况下把它变成一个可调用的服务。

2. 照片怎么变成DeepSeek能看懂的东西:链路拆解

2.1 大模型不直接吃图片,这是第一个要解决的问题

DeepSeek的对话模型目前只吃文本,你没法直接把一张试卷照片扔给它。所以第一步必须想清楚:图片里的题干怎么变成文字?

这里有个常见的认知误区:很多人以为"OCR识别一下就行",实际做起来根本不是那么回事。试卷和作业题里不只有印刷体汉字,还混着数学公式、几何图形、分数表达式、上下标,普通OCR引擎对纯文本的识别率很高,但一碰到公式就乱套。我最早拿通用文字识别接口试过,把一道二次函数题拍进去,识别出来的是"g = ax2 + bx + c"这种半死不活的文本,公式里的指数全部变成了普通数字,模型拿到这种输入,推理方向直接偏了。

所以在系统设计一开始,就要把"识别"拆成两路:一路走通用OCR识别题干文字,另一路单独处理公式和图形信息。很多OCR服务商都提供了公式识别专用的接口,对数学符号的重建能力远好于通用接口。如果你不想接第三方服务,也可以考虑用开源的离线公式识别模型,但部署成本会高一些,作为实验项目我建议先走商用接口,跑通再优化。

2.2 Dify里的流程图:识别、清洗、推理三段式

整个工作流在Dify里分成三个逻辑段。

第一段是预处理:把用户上传的图片交给OCR能力,拿到原始文本。这一步的关键不是"怎么调接口",而是"怎么把OCR返回的结果整理成模型能用的输入"。OCR返回的内容往往带坐标信息、段落标记、甚至误识别的符号,这些噪声一边会让DeepSeek理解困难,一边还会白白消耗token。我习惯在Dify里用一个"文本处理"节点做清洗:去坐标、去空行、把全角符号统一成半角、把明显的OCR错误做一轮字典映射(比如把"0"误识别成"O"、把"l"误识别成"1"这些高频错误先替换掉)。

第二段是结构重构:把清洗后的文本组合成一道完整题目的描述。这里不要直接扔给模型就完事,而是要上一段提示词,让DeepSeek先做"题目转述"——也就是把OCR文本重新组织成一句完整、语义明确的问题陈述。为什么要多此一举?因为OCR文本本身可能顺序混乱,或者把题目条件拆得七零八落,模型直接基于这种文本推理,准确性没有保障。经过一轮转述之后,模型自己先理解了题目在说什么,后续的推理质量会明显提升。

第三段才是真正的解题:把重构后的问题交给DeepSeek,要求它按"已知条件→解题思路→分步计算→最终答案"的结构输出。这一步的提示词设计我后面单开一章详细讲,这里先记住一个总原则:给模型的指令一定要具体到输出格式,最好让它返回结构化内容,而不是自由发挥。

2.3 为什么选Dify而不是自己写代码

如果只做一次性的脚本,自己写代码当然更直接。但如果要长期维护,并且让不懂代码的同事也能改流程,Dify的价值就出来了。

我自己最初就是用Python脚本调的API,写得很爽,但真正用起来发现几个问题:每换一个OCR厂商就要改代码;题目进来了想加一个"先判断学科、再走不同解题模板"的逻辑,得重写分支;最重要的是,家里人想用,总不可能让他们去跑命令行。Dify把这些都变成了可视化操作,OCR节点、模型节点、分支判断节点都做成了积木,想改哪块就改哪块。此外Dify本身提供WebApp和API两种调用方式,手机浏览器打开就能拍照上传,比什么客户端都好使。

3. 在Dify里编排解题工作流的完整过程

3.1 先把应用骨架搭起来

我当时在Dify里新建的是一个"工作流"类型的应用,不是"聊天助手"类型。原因很简单:聊天助手偏自由对话,工作流可以严格控制节点顺序和分支走向,每一步做什么都是确定的,不会跑偏。

骨架信息如下:

  • 应用类型:工作流
  • 输入变量:image(文件类型,接收用户上传的拍照图片)
  • 输出变量:结构化解题结果,包含题目重述、分步解答、最终答案三个字段

新建完之后,第一件事是配置模型供应商。Dify支持接入DeepSeek的方式有两种:一种是在模型供应商列表里直接选DeepSeek,填入API Key;另一种是通过OpenAI兼容模式接入。用第一种更省事,它会自动帮你把模型列表拉出来,对话模型直接勾选即可。当时我把温度调成了0.2,因为这个场景需要的是稳定推理而不是发散创造,温度太高模型容易给自己加戏,明明条件不足还硬凑一个答案。

然后按顺序拖入节点,第一个节点是"工具类型"的HTTP请求节点,用来调OCR接口。Dify里有现成的工具市场,也可以直接配置自定义HTTP节点,把图片base64编码后POST给你的OCR服务商。这一步需要注意,你传过去的图片最好先压一下尺寸,手机原图动不动几MB,网上传太慢也会浪费OCR服务商的流量额度。我一般控制在1200px以内,JPG格式,质量80%就行,识别率几乎不掉。

3.2 核心节点配置:连接SamplingResponse与OCR实现

在Dify的工作流里,OCR这块可以写成HTTP节点串接SamplingResponse节点。SamplingResponse本质上是把HTTP调用返回的响应体按你的需求提取出来喂给下一个节点。我在HTTP节点里设置的响应体结构是JSON,内容大致长这样:

{ "words_result": ["文字块1", "文字块2"], "formula_result": ["公式1", "公式2"] }

然后处理节点里做清洗与拼接。清洗逻辑我写了一段简单的伪代码思路:

  • 把数组中所有文字块合并成一个大字符串
  • 去掉两两之间的空行和多余空格
  • 英文符号统一转半角
  • 对一组高频OCR混淆词做替换(如"r1"→"x1"之类的)
  • 公式结果单独拼到文本末尾,标记为[公式区域]

这些写起来不复杂,但在Dify里要找到对应的"代码执行"节点。Dify的代码节点支持Python,我在里面写了这段清洗逻辑,有几步是直接能跑通的。

3.3 提示词设计:让DeepSeek的输出稳定可用

在整个环节里,提示词设计是最能拉开效果差距的地方。我最初的提示词写得特别随意,就一句"请解答这道题",结果模型输出格式五花八门:有的只回一句话,有的长篇大论写小作文,解析出来的答案还得靠人工二次整理,完全没法用。

后来我把提示词标准化成了这个结构:

你是一名严谨的理科教师。请基于以下题目信息完成解答。 题目文本: {{cleaned_text}} 要求: 1. 先用自己的话重述题目,确保不遗漏已知条件。 2. 判断题目的学科类型(数学/物理/化学等)。 3. 给出完整的解题思路,说明用到了哪个知识点。 4. 分步骤计算,每一步都保留推导过程。 5. 最终答案单独一行输出,格式为"答案:xxx"。 6. 如果题目信息不完整,不要强行猜测,直接指出缺失条件。

这里有几个细节值得说明一下。第一,"先重述题目"不是为了凑字数,而是让模型在输出之前先内化一遍题目的条件,能显著降低漏条件的情况。第二,"分步骤计算"对数学题几乎是必需的,模型如果一次性推出结果,中间很容易跳步出错。第三,"缺失条件时要直说"这一条,是我吃了好几张模糊照片的亏之后才加上的——有时候OCR识别出来的题干本身就少了几个字符,模型最怕的是在残缺信息下强行合理化,告诉你一句"如果按照你的题意"就编出一个答案来,这在教育场景里非常致命。

实践下来,这样设计的提示词让输出稳定性提升了一大截,而且天然适合解析——因为格式基本是固定的,我可以用一个简单的正则把"答案:"后面的内容摘出来,存到结构化字段里,这就为后续对接外部应用打好了基础。

3.4 工作流里最容易忽略的"失败出口"

工作流不是只有一条成功路径,你必须在设计之初就想到失败的情况。我在Dify里加了两个分支出口:

  • OCR节点返回空结果或者识别置信度过低时,走"识别失败"分支,输出一句提示告诉用户"照片不清晰,请重新拍摄",而不是让模型硬猜。
  • DeepSeek节点返回内容里没有"答案:"关键字时,走"解析失败"分支,把模型原始输出原样返回给用户,至少让用户看到推理过程。

这两个分支看上去不起眼,但它们决定了这个系统能不能日常使用而不闹笑话。没有失败出口的流程,一旦翻车,轻则返回垃圾内容,重则直接报错中断,体验极差。

4. 拍照端到端调试与识别失败的真实排查链路

4.1 第一轮翻车现场:白底纸上的红色批注

系统搭好之后我兴冲冲拍了一张数学卷子测,题目是"已知二次函数y = x² - 2x + 3,求顶点坐标"。结果OCR把题干里的数字"2"全部识别成了"?",整个题目文本变成"求顶点坐标?"这种状态,DeepSeek拿到之后直接告诉我"题目信息不足"。

排查第一步,我查看了OCR接口返回的原始JSON,发现识别框里把红笔批注"这题错了"也当成正文识别了,而且因为红色批注覆盖了部分印刷体,导致附近区域的字符识别度严重下降。这算是拍照场景的经典问题:试卷上往往有红笔痕迹、涂抹、折痕阴影,这些都会干扰OCR。

我的解决办法分两层:第一层是拍照引导,在应用前端上传页面写清楚"请尽量在光线均匀的环境下拍摄、避免红笔批注、保持纸面平整";第二层是图像预处理,在OCR之前先用代码做一次简单的亮度和对比度增强,并把饱和度降低,让红色批注在灰度图上和印刷体区分度变大。代码节点里我塞了一段基于OpenCV的灰度化与自适应二值化处理,代码不长但对改善识别率帮助非常明显。

4.2 第二轮翻车现场:公式的下标和分式

这个问题我在前文提过,但真正调试时比我想象的更麻烦。一道含分式、根号、下标的数学题,通用OCR往往把"x₁"识别成"x1"、"√x"识别成"Vx"、"3/4"识别成"3 4"。这种错乱对自然语言理解还没太大影响,但对数学符号来说是致命的。

我换成了带公式识别能力的OCR接口之后,情况好了不少,但依然有崩塌的时候。最常见的场景是"分数和括号混排",比如"1/(x+2)"被识别成"1/(x+2)"时括号丢失,变成"1/x+2",模型理解出来的公式完全变了。即便公式识别引擎也有自己的脾气。

针对这个情况,我在清洗代码里加了启发式修复规则:检测到分母位置后面没有括号闭合时,自动补括号;检测到连续数字之间有异常空白时,合并为乘号或小数点,再结合上下文判断。这个方案不是百分百准,但能把模型的误判率拉低一个档次。真要彻底解决,得走公式结构解析的专用模型,作为实验项目暂时不做这么重。

4.3 第三轮翻车现场:一个问题里有两个问号

然后是逻辑层面的翻车。一道应用题有第一问和第二问,OCR文本也识别得完整,但DeepSeek在重述题目的时候,没有区分两个子问题的不同条件,把两个问号的条件混在一起推导,最后自然是错的。

排查之后发现问题出在提示词上。我没有在重述环节要求"拆分子问题",模型默认把整段文本当作一个整体。修复方式简单粗暴:在重述要求里增加一条"如果题目包含多个小问,请以列表形式分别列出每个小问的已知条件"。这一改,模型输出结构立刻清晰了,后续的解题也能分别对应。

这个案例让我意识到,OCR只是把像素变成字符,模型真正需要的是"信息的结构化"。我们在工作流里做的一切清洗、重述、拆分,本质上都是在帮模型把非结构化的文本变成逻辑上可推理的知识单元。

4.4 排查方法论:先看哪一环节的问题

跑了两周之后我形成了一套排查顺序,遇到结果不对先定位问题在哪一段,效率会高很多:

  • 如果OCR返回的文本明显不通顺,先怀疑拍照条件和OCR选型,去看原始响应体,不要急着调提示词。
  • 如果OCR文本没问题但DeepSeek重述出来跑偏,去看提示词里有没有对输出结构的明确约束。
  • 如果重述没问题但解题结果不对,可能是模型对该题型自身能力不足,这时候换更强的模型版本,而不是继续调提示词。
  • 如果整个链路都正常但最终返回格式不对,去看工作流的代码节点里解析逻辑有没有bug。

这套排查思路大概帮我砍掉了百分之六十的无效调试时间。

5. 从解题器到答疑助手:实测数据、成本与还能怎么玩

5.1 我跑了两周的实测记录

我拿小学到初中的数学、物理题各测了五十道,整体情况统计下来比预期好。印刷体题目的端到端成功率达到八成以上,所谓成功是指:题目完整读出来、模型解题思路正确、最终答案和参考答案一致。手写体题目就明显吃力,尤其是手写数字潦草时,OCR识别率低一大截,成功率大致只有五成上下。

单次完整链路耗时差不多在三到六秒之间,大头花在图片上传和OCR返回上。DeepSeek本身的推理时间反而不长,因为题目文本量不大,生成内容也不长。如果用户网络环境好一点,体感上几乎是拍完照两三秒出答案,完全能达到日常使用标准。

成本这块,OCR按次计费,深度学习的识别模型也都便宜,单次几乎忽略不计;DeepSeek的API按token计费,一次解题生成的token数也就一千到两千之间,换算成钱基本是几厘到几分钱。哪怕每天测几十道题,成本也就是一杯饮料钱都不到。这个成本结构决定了你可以大胆地把它做成一个内部小工具,不用像商业搜题产品那样花大价钱。

5.2 这套架构还能长出什么

跑通解题不是终点,Dify工作流的架构给我的感觉是"解题只是第一个积木"。我后来在它基础上又加了几块逻辑,已经在内部实验了。

一是学科分类分支。在题目重述之后先让DeepSeek判断学科和年级,然后不同学科走不同的解题模板,比如数学题强调分步推导,语文阅读题强调原文定位,物理题强调单位和公式引用。这样一套工作流可以服务多学科,而不是只有数学一条路。

二是错题本数据回流。Dify的工作流结果可以作为记录节点,把每次拍照识别出的题目文本、模型解答、用户反馈一起存到数据库或表格里。累积一段时间后,就能看出这个孩子错题集中在哪些知识点,甚至可以反向生成针对性的练习建议。

三是多轮追问机制。最初我把它做成纯拍照解题,后来发现小孩经常看完答案还要问一步"这一步为什么这么变",单纯一次性回答满足不了。于是在Dify里把输出结果的文本摘要和原始题目上下文都保留到会话变量中,下次用户追加问题时,工作流会带着上次的对话背景再次调用DeepSeek,形成连续的答疑对话。这个改动其实不大,但对使用体验的提升是质的。

5.3 如果你也想照葫芦画瓢,这几条经验先拿走

首先,OCR选型直接决定系统天花板。通用识别和公式识别的差距在这个场景里有质的区别,预算有限也至少要选带公式支持的接口,否则后面调试提示词的时间会让你怀疑人生。

其次,提示词里一定要包含"信息缺失时直说"的兜底指令。教育场景里最忌讳的就是生成幻觉答案,模型一本正经地编一个步骤,拿给小孩看就是误人子弟。加了兜底之后,虽然偶尔会得到"题目不完整无法解答"的回复,但这比错误的答案体面得多。

再次,别忘了给工作流加失败出口。任何一个环节都可能挂,挂的时候用户应该得到友好提示,而不是看到一个报错堆栈。这一点在Dify里做起来并不复杂,但很多人第一次设计流程时根本不考虑。

最后,自己动手之前先想清楚服务的对象。做给自家孩子用和做给全班用、做给机构老师用,设计逻辑完全不同。给自家孩子我可以牺牲点通用识别率,优先追求界面极简;做给机构用就得考虑批量导入、权限管理、结果存档这些杂七杂八的东西。别一上来就照着大而全做,做厚了反而难以坚持用下去。

我到现在还经常用这套系统拍小朋友的错题,每拍一次都能发现一点需要调优的细节。这大概就是这个项目最迷人的地方——它不是交付完就寿终正寝的Demo,而是一个能一直陪着实际生活迭代的工具。DeepSeek负责思考,Dify负责编排,我负责在旁边修修补补、踩坑排雷,这个过程本身就挺有成就感。如果你也在折腾类似的工具实验,希望这份手册能帮你少走几段弯路,尤其是那几轮"翻车现场",大概率你也躲不过。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 5:14:29

如何打造无可挑剔的项目:从标准到实践的完整方法论

1. 一个词引发的项目思考:为什么"impeccable"值得单独拿出来做第一次看到"impeccable"这个词被单独拎出来当作项目标题,我的直觉是:这要么是个文字游戏,要么背后藏着某种对"极致标准"的执念。impec…

作者头像 李华
网站建设 2026/10/19 16:43:31

Super账户与super文件:vivo/iQOO手机文件管理及数据迁移完全指南

换新手机的时候,最折腾人的往往不是挑选型号,而是旧手机里那一大堆照片、聊天记录、应用数据怎么完整搬过去。我身边用vivo和iQOO的朋友几乎都问过我同一个问题:手机里的系统文件到底哪些能删、哪些不能动,联系人备份到一半断了怎…

作者头像 李华
网站建设 2026/10/20 14:57:24

【ArkUI提高练中学】第7课:性能调优与稳定性治理

本节目标 掌握卡顿丢帧的根因分析方法,能够使用 Frame 模板、ArkUI 模板和 ArkUI Inspector 精准定位 UI 渲染瓶颈掌握 ArkTS 内存泄漏的检测与定位方法,能够使用 JSLeakWatcher 生成泄漏报告并分析引用链掌握 AppFreeze 冻屏故障的分析方法,…

作者头像 李华