
拍照解题这个场景听起来像是学生党的刚需但把它当成一个正经的大模型应用实验来做其实特别能锻炼人。整个链路涉及图像输入、文字提取、模型推理、工作流编排每一步都有坑也都有优化空间。我这次用 DeepSeek 作为推理模型配合 Dify 的可视化工作流平台把“拍照 → 识别题目 → 智能解题 → 输出解析”这条流水线完整地搭了出来。这篇文章就是这次实验的完整手册不光是配置步骤还包括我踩过的坑、调试思路和一些优化技巧给想动手做类似应用的朋友一份可以直接抄作业的参考。1. 项目设计与技术选型为什么是 Dify DeepSeek1.1 拍照解题的技术链路拆解先把这个项目的技术链路拆开看。拍照解题本质上是一个典型的“多模态输入 文本推理”复合任务。用户上传一张题目图片系统需要完成三个核心动作第一从图片中提取出题目文字这一步属于 OCR 和文档解析第二理解题目内容判断学科类型和考察知识点第三调用大模型进行推理生成解题步骤和最终答案。如果走纯代码路线我需要自己处理图片上传、调用 OCR 服务、对接大模型 API、设计提示词、处理并发和日志……工作量不小而且大部分代码都是胶水代码。这类实验项目更适合用 LLMOps 平台来做可以让应用开发者把精力集中在提示词设计和流程优化上而不是重复造轮子。Dify 正好是这一类平台里比较成熟、社区活跃度也高的选择。1.2 Dify DeepSeek 组合的优势与取舍选 Dify 而不是直接用 LangChain 或者自己写脚本核心原因有三个。第一可视化编排。Dify 的工作流编辑器是拖拽式的开始节点、文档提取器、LLM 节点、结束节点连线就能跑通。调试的时候每个节点的输入输出都看得见哪个环节出了问题一目了然。这对于快速验证想法来说太重要了不用在日志里翻来翻去找问题。第二内置文档提取能力。Dify 工作流里的“文档提取器”节点原生支持从图片中提取文字这帮我省掉了单独接 OCR 服务的麻烦。虽然它的识别能力比不上专业的 OCR 引擎但对于印刷体题目来说已经够用而且完全在同一个平台内完成流程更紧凑。第三应用发布一体化。Dify 调试完可以直接发布成 WebApp也能以 API 形式对外提供服务甚至能一键接入企业微信、飞书这类 IM 工具。这意味实验做完可以直接给真实用户用而不是停留在脚本演示阶段。模型侧选 DeepSeek是因为它的 API 兼容 OpenAI 格式接入成本极低而且推理能力在同级别模型里属于第一梯队特别是 deepseek-reasoner 这类推理模型处理数理题目的思维链质量很高。价格方面也友好做实验频繁调用不会心疼。当然这个组合也有取舍。Dify 的工作流在极端复杂的业务逻辑面前表达力不如纯代码灵活DeepSeek 的部分高级参数在 Dify 里可能没法全部暴露。但对于“拍照解题”这个场景Dify 加 DeepSeek 的组合绰绰有余。1.3 实验环境与整体流程预览我的实验环境是这样的一台 4 核 8G 的 Linux 服务器安装了 Docker 和 Docker ComposeDify 社区版通过官方 docker 目录一键部署。模型侧注册了 DeepSeek 开放平台的账号申请了 API Key。整体流程预览如下用户在 Web 页面点击上传题目图片Dify 工作流接收文件文档提取器自动提取文字提取结果传入 LLM 节点DeepSeek 根据预设的解题提示词进行推理输出结构化答案包含题目分析、解题步骤、最终答案和知识点总结结果渲染回 Web 界面用户直接查看2. 环境准备Dify 本地部署与 DeepSeek 模型接入2.1 Dify 社区版 Docker 部署实操Dify 社区版可以直接在 GitHub 上拉取源码用 Docker Compose 一键启动。安装过程本身不复杂但有几个细节需要注意。先确认服务器上装好了 Docker 和 Docker Compose 插件。我用的是 Docker 24 和 Compose v2直接用docker compose命令而不是docker-compose。然后拉取 Dify 源码git clone https://github.com/langgenius/dify.git cd dify/docker cp .env.example .env这里有个关键点.env文件是整个部署的核心配置里面包含了数据库密码、Redis 配置、端口映射等信息。默认配置就能跑起来但如果你的服务器 80 端口被占用了提前改一下EXPOSE_NGINX_PORT这个变量比如改成 8080。启动服务docker compose up -d首次启动会拉取很多镜像包括 API 服务、Worker、数据库、Redis、Sandbox、Web 前端等时间取决于网络速度。启动完成后用docker compose ps查看容器状态等所有容器都变成 healthy就可以访问了。访问http://服务器IP:端口第一次打开会进入管理员账号设置页面设置完账号密码就进入了 Dify 控制台。我在这里踩过的第一个坑是容器启动顺序。如果数据库还没初始化完成Web 页面就打开了会出现“数据库连接失败”的提示。解决办法是等docker compose ps里 db 容器变为 healthy 之后再刷新页面别急。另一个和部署相关的提示如果你用的是群晖 NAS同样可以通过 Docker 套件运行 Dify原理一样但要注意群晖的端口转发设置以及容器与宿主机之间的目录挂载权限。Dify 升级的时候直接git pull拉最新代码然后重新docker compose up -d它会自动重建变更的容器但数据库数据会保留不用太担心迁移问题。2.2 DeepSeek API 密钥申请与模型供应商配置模型侧的准备更简单。去 DeepSeek 开放平台注册账号创建一个 API Key然后充值少量金额就可以开始调用。DeepSeek 的接口是 OpenAI 兼容格式所以 Dify 里不必选择“DeepSeek”这个专属供应商——虽然 Dify 确实内置了 DeepSeek 选项但我个人更推荐用通用方式接入自由度更高。在 Dify 控制台左侧菜单进入“设置 → 模型供应商”找到“OpenAI-API-Compatible”点击添加模型API 端点 URL 填https://api.deepseek.com/v1API Key 填你申请的 Key模型类型选“LLM”模型名称填deepseek-chat这里要注意Dify 的 OpenAI-API-Compatible 需要先“添加模型”才能创建实例添加完模型后回到模型列表把刚添加的模型“设为默认”或者在工作流里显式指定。我实际测试下来deepseek-chat应对常规题目已经足够推理速度快成本低。如果是复杂的数理证明题可以再添加一个deepseek-reasoner模型它的思维链推理更强但响应时间也会相应拉长。2.3 模型接入常见报错处理模型接入这一步最常见的报错就是热词里那串经典提示An error occurred during credentials validation。这个错误的出现原因基本逃不出三个第一API Key 本身无效。检查有没有复制完整、有没有多余空格去 DeepSeek 平台重新复制一次再试。第二网络不通。服务器如果部署在境外或者本地网络无法访问api.deepseek.com自然校验失败。先在服务器上用curl测一下curl https://api.deepseek.com/v1/models -H Authorization: Bearer 你的APIKey能返回模型列表说明网络和 Key 都没问题。如果 curl 超时或报 SSL 错误那就是网络层面的问题。第三Base URL 路径写错。OpenAI 兼容接口的路径是/v1有些朋友只填了域名没带/v1也会校验失败。这不是 Dify 的锅是 OpenAI 兼容规范本身的路径要求。我自己还碰到过一种比较隐蔽的情况Dify 版本较老对自定义模型的支持有 bug升级到最新社区版就好了。所以如果你配置步骤完全正确但始终报错优先考虑升级 Dify 版本。3. 工作流搭建从图片上传到题目解析3.1 开始节点与文件上传设计登录 Dify 控制台后点击“创建空白应用”选择“工作流”类型。工作流里第一个节点是“开始”它的输入参数决定了用户能传什么数据进来。拍照解题场景下开始节点需要设计一个文件类型的输入参数。在“输入类型”里选择“文件”设置允许的文件类型为图片常见格式比如 jpg、jpeg、png、webp。如果是自由的“问题补充”还可以加一个文本类型的参数让用户在上传图片的同时手动补充题目描述方便那些图片识别不完整的情况。变量命名上我给文件参数取名为files文本参数取名为question_notes这样在后面节点引用时语义清晰。这里有一个值得养成的习惯每个节点都要写清晰的描述Dify 工作流节点多了以后节点描述就是你的代码注释否则过两天回来看根本不记得某个节点当初设计的意图。3.2 文档提取器图片转文字的细节与局限拖入一个“文档提取器”节点把开始节点的files变量接进去。这个节点会自动对上传的图片做文字提取。实测下来的感受是清晰印刷体题目的识别率非常高但有两个明显局限。一个局限是手写体识别不稳定。拍照解题最常见的场景其实是拍手写作业本这时候提取器经常会把潦草的数字识别错比如把“6”识别成“8”把“x”识别成“×”后续的大模型推理就会基于错误的文本结果自然不对。另一个局限是数学公式和特殊符号容易乱码。平方、根号、分数这类符号OCR 提取出来经常变成普通文本或者乱码比如x²被提取成x2。这道题还算能猜但遇到复杂的分式方程提取结果可能完全不可读。针对这两个问题我的处理策略是先接受提取器的输出在提示词阶段让模型做“题目复原”。也就是说不期望 OCR 完全准确而是让 DeepSeek 根据上下文推断原本的题目是什么。这个方法在实际测试中效果不错因为模型本身对数学题有很强的先验理解能把残缺信息补全。3.3 变量传递与节点编排的几个关键点工作流节点之间传递数据靠的是变量引用。Dify 的引用格式是{{#节点名.输出字段#}}比如文档提取器的输出是文本在 LLM 节点的提示词里就可以写{{#docExtractor.text#}}把它接进来。这个环节有几个容易出错的地方。第一个是节点 ID 与节点名的区别。Dify 里每个节点有个系统生成的 ID显示名是你自己填的名字引用变量时靠的是节点名。如果节点重命名了旧引用会失效需要手动更新。第二个是变量类型不匹配。文档提取器输出的是字符串LLM 节点的输入提示词也是字符串直接拼接没问题。但如果你试图把文件变量直接塞给 LLM就会报类型错误因为 LLM 节点不能直接处理二进制图片文件。第三个是分支判断的条件写法。后面如果要加“题目分类”分支判断条件里引用变量时要选择对应的运算方式。比如判断“题目类型等于数学题”要用“包含”或“等于”操作符注意中文文本的等值判断在个别版本里对空格敏感建议先用“包含”过渡。我一般习惯在工作流画布上把节点连好线之后逐个节点检查输入输出面板确认变量引用没有红色报错再测试。Dify 的调试模式可以一行一行模拟运行用一张测试图片从头跑到底哪个节点的输出不对立刻就能发现。4. 解题提示词工程让 DeepSeek 稳定输出高质量解题过程4.1 解题提示词的核心结构拍照解题的实验里最考验功力的其实是提示词设计。同样的 OCR 文本提示词写得粗糙和写得精细输出质量天差地别。我给 LLM 节点设计的提示词包含三层结构角色设定、任务规则、输出格式要求。角色设定我写的是“你是一名拥有二十年初高中理科教学经验的资深教师擅长数学、物理、化学等学科的题目解答。你讲解题目时逻辑清晰、步骤完整、语言通俗会根据学生的理解水平调整表达方式。”任务规则包括首先根据 OCR 文本复原完整、准确的题目如果文本存在乱码或缺失根据数学逻辑推断并修正但在答案开头标注“题目可能为”。分析题目所属学科和考察知识点。分步推导每步必须写明计算过程或推理依据不得直接跳步。如果题目存在多种解法选择最常规、最容易理解的一种。最终答案用加粗和方括号明确标注。输出格式要求是题目复述学科与知识点解题步骤最终答案易错点提示这套结构跑下来DeepSeek 的输出非常稳定。关键是先复原题目再解题这一条。OCR 出来的题目文字不完整是常态让模型先做一次“文本修复”再做“数学推理”整个链路的容错性高了很多。4.2 学科分类与分支处理的进阶设计基础版的工作流是“一套提示词走天下”。进阶版可以加一个 LLM 节点专门做“题目分类”识别学科和题型然后根据分类结果走不同的解题提示词分支。比如数学题和英语题解题逻辑完全不同。数学题要求计算步骤英语题要求语法分析和翻译不可能用同一套提示词达到最好效果。Dify 的条件分支节点可以这样配置节点“题目分类器”输出学科字段如果学科等于“数学”走“数学解题提示词”分支如果学科包含“英语”走“英语解析提示词”分支默认分支走通用解题逻辑这样做的好处是每个分支的提示词可以高度定制输出更贴合学科特点。缺点是工作流复杂度上升节点数变多调试成本也增加。对于初版实验来说先用单分支跑通后续再逐步加分支是最务实的路线。4.3 输出格式控制与结构化处理另一个我踩过坑的点是输出格式。早期的测试里我让模型自由输出结果答案格式五花八门有的只给答案不给过程有的过程写得像论文有的把所有文字堆在一段里用户根本没法看。解决办法是在提示词里附加严格的输出模板并用 Markdown 语法锚定结构。例如请严格按以下格式输出 ## 题目复述 [完整题目内容] ## 考点 [学科知识点不超过50字] ## 解题步骤 1. ... 2. ... ## 最终答案 [加粗标注] ## 易错提示 [一句话]这样约束之后输出稳定性和可读性都大幅提升。如果后续想把结果接入其他系统做结构化存储可以在提示词里要求模型输出 JSONDify 的 LLM 节点支持设置“响应格式”为 JSON模型会尽量按 JSON 格式输出解析起来更方便。但要注意JSON 模式下模型偶尔会漏掉大括号建议在提示词末尾加一句“请确保输出是合法 JSON不要包含其他文字”。5. 应用发布与实测调优5.1 发布为 WebApp 与 API 的完整流程工作流调试通过后就可以发布了。Dify 应用发布有两种常用方式。第一种是发布为 WebApp。在应用概览页面点击“发布”Dify 会生成一个独立的网页链接。用户打开链接就能上传图片、查看解题结果完全不需要懂任何技术。这种方式适合快速让朋友体验也适合学生实际使用。第二种是发布为 API。Dify 会生成 API 端点支持通过 HTTP 请求调用工作流。这意味着你可以把这个能力嵌到自己的网站、小程序或者 IM 机器人里。企业微信接入 DeepSeek 的常见做法就是在 Dify 里创建应用然后通过企业微信机器人回调地址指向 Dify 的 API。我这次实验先把应用发布成 WebApp方便真实用户测试。WebApp 的访问地址是一个长链接Dify 也支持自定义域名和路径如果你有域名可以配置反向代理体验更好。5.2 实测一道初一数学题的完整处理过程我用手机拍了一道七年级数学题做端到端测试题目是“已知关于 x 的方程 2x 3 11求 x 的值。”这个过程走完文档提取器识别出的文字基本正确2x 3 11这个关键等式完整提取出来了。LLM 节点接到文本后按照提示词输出如下## 题目复述 已知关于 x 的方程 2x 3 11求 x 的值。 ## 考点 一元一次方程代数运算。 ## 解题步骤 1. 方程两边同时减去 3得到 2x 8。 2. 方程两边同时除以 2得到 x 4。 3. 代入检验2×4311等式成立。 ## 最终答案 【x 4】 ## 易错提示 移项时注意符号变化不要漏乘系数。整个调用耗时大约 3 秒体验流畅。从这个简单例子可以看出提示词里“分步推导 代入检验”的设计确实让模型输出了更完整的推理过程而不是只甩一个答案。5.3 基于日志反馈的迭代调优Dify 应用后台自带日志和标注功能这是调优最有力的工具。每次用户调用都会记录完整的输入输出你可以随时查看某一次调用的工作流每个节点发生了什么。我的调优方法是每次测试都回到日志里看原始 OCR 文本和最终输出找出系统性偏差。比如有一次用户拍的是题目在草稿纸上的照片背景杂乱文档提取器把草稿纸上的其他计算过程也提取进去了导致模型在解题时被干扰。针对这个问题我在提示词里加了一条规则“如果 OCR 文本中包含与题目无关的草稿内容请忽略它们只关注具有明确题目结构的文本。”加上这条之后结果明显改善。另一类高频问题出现在上传图片质量差的时候。用户手机拍得歪歪扭扭、光线昏暗OCR 提取效果大打折扣。这时候我会让模型根据残缺文本猜测题目并在输出里坦白说明“以下答案基于推断的题目”避免误导用户。实测下来DeepSeek 的猜测准确率比想象中高因为常见题型的模式太明显了。6. 常见问题排查与扩展建议6.1 拍照解题高频问题速查表我在整个实验过程中整理了一个问题速查表按出现频率排序现象可能原因解决方案文档提取器输出大量乱码图片模糊、手写体、复杂公式引导用户重新拍摄提示词中要求模型推断修复模型返回结果不是解题步骤提示词缺少格式约束在提示词中强加输出模板要求分步推导调用报错an error occurred during credentials validationAPI Key 错误、网络不通、Base URL 路径错按 2.3 节三步排查工作流运行成功但输出为空LLM 节点输出变量引用错误检查结束节点是否引用了正确的 LLM 输出字段响应速度慢deepseek-reasoner 推理耗时长超时设置太短简单题目用 deepseek-chat复杂题目单独用 reasoner 并调高超时上传图片失败文件类型不在允许列表开始节点中补充 png/jpg 等格式多人同时使用后应用卡顿服务器资源不足增加服务器配置在 Dify 中限制并发或启用排队用户反馈答案错误OCR 关键信息识别错误在日志中比对 OCR 原文调整提示词中的题目复原逻辑这张表基本覆盖了我遇到过的全部问题。特别提醒一下“响应速度慢”这个项目DeepSeek 的 reasoner 模型和 chat 模型响应时间差距很大如果你默认配置的是 reasoner每次调用都可能等上十几秒严重影响用户体验。建议把默认模型设为 deepseek-chat只有在需要深度推理的复杂题目才切 reasoner。6.2 实验拓展从解题工具到学习助手这个实验手册做到这里已经是一个可以日常使用的拍照解题工具了。但它的价值不止于此基于同样的工作流底座可以往几个方向扩展。第一个方向是错题本与知识库。Dify 原生支持知识库功能可以把历次解题记录和错题整理成文档导入知识库后在解题前先用知识库检索相似题目和知识点给 LLM 提供参考材料。这等于从单次解题升级成了个性化学习助手能根据历史错题给出针对性的复习建议。第二个方向是多模态升级。目前链路里图片识别靠的是文档提取器本质上还是 OCR 文本。如果换成多模态大模型直接看图解题对图表题、几何图形题、化学实验装置题的适用性会大幅提升。DeepSeek 目前没有开源的多模态模型但这个方向是明确的技术趋势后续可以接其他支持视觉的模型。第三个方向是Agent 化。Dify 支持 Agent 模式可以让模型自主决定是否需要搜索题目库、是否需要查询公式、是否需要调用计算器工具。这比固定工作流更灵活但对应的调试复杂度也更高。对于实验项目来说先把固定流程做到极致再考虑 Agent 化是更稳妥的路径。做这个实验给我最大的感受是大模型应用开发的难点其实不在模型本身而在于如何用合适的工程手段把模型能力组织和包装成一个完整、可靠的产品。Dify 提供了让想法快速落地的框架DeepSeek 提供了高质量的推理底座而提示词和流程设计才是拉开差距的地方。现在这个拍照解题工作流我已经跑了快一个月日常用来检查孩子作业、整理题库都够用稳定性超过预期。接下来我准备把错题知识库接进来让它在解题之外还能帮孩子把薄弱知识点梳理成体系。