跳转到内容
灵墨笔记

为了给娃打印空白试卷,我在手机上手搓了一个小程序

编辑本页

前段时间为了给娃辅导作业,需要把做过的试卷拍下来重新打印成空白卷。试了市面上几个大牌扫描件,套路出奇一致,要么需要开会员,要么加水印,不还限制导出次数。既然AI大模型已经这么牛X了,何不自己vibecoding 自己做一个呢。

评估了半天发现微信小程序上线最快,于是3 天跑通了原型,1 个月正式上线【喵出图】,目前支持试卷擦除笔迹还原空白卷、图片去水印以及视频号视频保存,全功能免费。

现在借助AI 开发一个app真的不算难了,不过要想做好一个app还是不容易的。本文主要是复盘这一个月攒下的全部心得,包括开发工作流、经验,还有一次很有意思的性能排查。希望对想做一款微信小程序的人有所启发。

说说系统架构选型和 AI 开发工作流

技术栈一句话说完,前端 Taro、React、TypeScript,后端 Python、FastAPI,算法层是轻量的 YOLO 和 OCR 加 Inpainting 模型,分别负责定位笔迹、印章、水印区域,和遮罩区域的像素填充。

值得一提的是大约 80% 的开发和改 Bug我都是在手机上完成的。家里Mac mini 上跑着一个 OpenCode Server 当远端代码引擎。手机上用 OpenCode 客户端 WhisperCode,后来换成了更顺手的 Paseo。

改完代码想看真机效果,就走 WeChat DevTools Skill 的自动化流程,一键构建,直接推到手机微信里预览。地铁上、沙发上,掏出手机就能敲指令、改代码、测小程序,开发过程本身比小程序产品还让我得意,呵呵。

移动端 AI 开发工作流

大模型全部国产,使用了三个模型各干各的活。GLM-5.3 当技术专家,需求拆解、架构设计、复杂问题的根因分析都由它完成。DeepSeek V4.1 Flash 负责函数编写、重构、常规代码生成,响应快,逻辑也严密。MiniMax-M3 打杂, 识别图片、做配置、读写文件等subagent执行的活都交给它。

核心算法研究

项目里两块最核心的算法能力,一个自己做成了,一个暂时妥协用了现成API。

先说做成的去水印功能:

去水印流水线:先检测再修复

图片去水印这个活不是拿个模型把图洗一遍就完事,真做起来是大概分为两步,先检测,再修复。检测算法主要是识别水印在哪。由于水印中文字型的占大部分,OCR算法把文字区域找出来,再用位置、透明度、重复度这些规则进行过滤,斜着平铺一排小字的也藏不住,重复性太明显了。图形和 logo 走另一条路,轻量分割模型直接吐像素级遮罩。检测在压缩后的小图上做,找到了再把遮罩按比例映回原图,算力省一个量级。

修复阶段主要处理水印去掉之后应该填充什么样的背景。LaMa 这类模型只修复遮罩盖住的那一小块,别的地方不碰,快,也不伤及无辜区域。补出来的图和原图做羽化混合再贴回去,不然边缘会留硬接缝。

再说试卷去手写,这条路走得曲折一些。我起初认为最理想的路是自己训个模型。你别说,我还真去试了很多次。训练流水线是 AI 搭的,数据增强、评估脚本、训练看护一应俱全。模型迭代了五代,检测方法换了好几版,连淡色笔迹这种边角场景都做了专项训练。五代下来,效果始终达不到能上线的水平。

此类模型训练这样的事情,代码占三成,七成是数据。要做到像素级的去除,需要海量的一对一配对训练数据,同一张卷子,一份带手写、一份干净,严格对齐,最好还是真实拍摄的。这种数据全网扒一圈就明白了,开源的少得可怜,质量像样的基本都被商业公司攥在手里闭源。公开能翻到的,要么只有千对上下的量级,要么是合成数据,真实场景效果要打折。这是整个方向共同的门槛,谁做都绕不开。

自训碰壁后,我又把 GitHub 上叫得上号的开源方案挨个实测了一遍。

先看了 inkstrip,也就是 handwritingRemover。它管线最完整,YOLO 检测加 LaMa 修复,本机跑得通。短板在默认检测模型,训练集只有 91 张亚美尼亚语听写纸,对中文试卷召回很低,中文印刷体容易被判成手写,M1 上一张图 23 秒。结论是工作流值得借鉴,检测器要自己训练。

又看了 HandWritingEraser-PyTorch。发布的权重是个早期版本,README 里说的三分类模型没有放出来,实际是二类版本。实测印刷体平均 32% 被标成手写,擦的时候印刷字跟着受影响。它也顺带说明了修复环节的上限,LaMa 这类区域级修复做不到像素级重建,铅笔浅痕会留下痕迹。

DocUnfold 是做文档矫正展开的,代码质量很好,M 芯片原生加速实测 8.7 倍。限制在于官方没放预训练权重,复现要从自训起步,推理脚本还有bug,16G 内存下一整张试卷切片推理要 80 秒上下。研究价值高,工程上还要再等等。

ENSExam-GAN 这类 GAN 路线也把源码和训练流程过了一遍,情况类似,暂时没有能直接落地的现成方案。

一圈测下来很清楚,这个方向卡在数据上,不在代码上。最后的解法朴素得很,碰巧找到了一个划算的商用接口接进去,效果立刻达标,成本比自训还低一个量级。

3 天跑通项目原型

AI 编程真正的省力点,不在一句话生成整套系统,而在架构定好之后的快速填充,语法和 API 不用自己记。

第一天搞后端和算法流水线,FastAPI 搭骨架,把 YOLO 检测、OCR 识别和 Inpainting 模型串起来,手机端通过 OpenCode 配合 DeepSeek 补全 NumPy、OpenCV 的图像张量转换代码。

第二天上前端,Taro 搭 Canvas 裁剪、相机拍照、对比展示这些页面,GLM-5.3 定布局方案,AI 填 Flex 样式和 TypeScript 类型。

第三天真机联调,靠 WeChat DevTools Skill 把代码直接推到真机预览,拍照、上传、算法处理、渲染,全链路走通。

从原型到上线:必须避开的工程与合规大坑

跑通 Demo 只占 20% 工作量,剩下的 80% 是小程序平台的工程细节和合规。

本地存储是第一课。真机上高频处理大图,试卷拍出来动不动 4K、好几个 MB,保存时频繁报错 saveFile:fail exceed storage limit,查下来是微信给本地临时文件的总额度只有 10MB。办法是引入 LRU 清理,上传前用 Taro 封装的 Canvas 先做降采样压缩,处理完的临时文件随手 unlink 掉。

内容安全是硬要求。用户能传图片和文本,就必须接微信官方的内容安全审核,这个没得商量。我搭了云函数通道,图片走 mediaCheckAsync 异步回调,先送审,安全回调回来了再把结果给用户,主流程不耽误。

备案和隐私协议也磨人。域名和 ICP 备案周期长,一般一两个星期,从写代码的第一天就得启动,别等写完才办。隐私协议按官方的结构来,每个权限都要覆盖到,比如相册写入权限,漏一个就可能被打回。

还有几条规则,我自己试了才知道的。 AI 给的答案往往会停留在官方规则上,其实:

  • 子域名解析到同云商、同主体的另一台主机,这次没有办备案变更,直接就能用。
  • 小程序改名跟着新版发布,这次没有重新走审核。
  • 而小程序不过审的话,用户搜都搜不到你,前面所有工程努力在搜索框里等于零。 平台规则这类信息,AI 目前只能给到保守答案,剩下的路要自己走一遍。

一个性能悬案:AI 预判翻车与 macOS 进程调度陷阱

这是整个项目里最有意思的一段。

由于算法服务包含卷积与深度学习推理,本地 Mac mini 跑完一次完整流程要 15 秒以上。为了把服务部署上云,我让 AI 做性能瓶颈分析。

它给出了一段很专业的分析,去水印与图像修复依赖深度学习矩阵运算,云端虚拟机通常没有 GPU 加速,单纯依赖 CPU 算力,计算延迟会增加,预计端到端耗时会到 20 秒以上,建议谨慎评估后再上云。

当我真正把同一套 Python 代码部署到一台普通的云端纯 CPU 实例上,实测处理时间只有 2.6 到 3 秒。

预判和现实差了 7 倍以上,为什么?后来复盘,原因有两个: 一是实际用到的轻量级 Inpainting 与 OCR 模型参数量并不大,现代 ONNX Runtime、PyTorch 在 CPU 上启用多线程并行加速后,吞吐效率比多数人的直觉高不少。 二是模型的常识偏向「深度学习推理必须依赖 GPU」,小模型在 CPU 上的优化空间容易被忽略。这条经验很通用,性能预判只能当作假设,进架构决策之前要实测。

新的疑问跟着来了。既然云端 CPU 只要 3 秒,那为什么 Mac mini 本地跑要 15 秒?

为了搞清楚,我把算法流水线做了毫秒级分段计时。在终端里直接跑,检测与定位部分非常快,YOLO 检测 1227 毫秒,OCR 定位 362 毫秒,轻量模型 16 毫秒,合计一点六秒左右,不慢。但同一份代码、同一个模型、同一台机器,从服务里走一遍,光检测段就从 1.2 秒膨胀到 10.6 秒。问题出在宿主运行环境上。

顺着这个方向排查本地进程托管,找到了原因。服务在 macOS 上是通过 launchd 守护进程启动的,配置文件 .plist 里写着,ProcessType 这一项的值是 Background。

这里得说说 macOS 的调度机制。系统有很细的电源与进程调度策略,进程被标成 Background 级别时,调度器把它归入与 Time Machine 备份、Spotlight 索引同类的「不紧急任务」,压低它的线程优先级,安排在 M 芯片的能效核上运行,性能核用不上,线程并发数也受限。在线服务挂在这个档位,等于全程戴着重镣跑步,而且从部署第一天起就这样,只是当时不知道。

验证用的是 macOS 自带的 taskpolicy,同一个脚本,正常策略 1.2 秒,套上 Background 策略 7.8 秒,实锤。

修复只要一行配置,把 .plist 里的 ProcessType 改成 Standard,重载服务,端到端耗时直接从 15.2 秒降到 2.6 秒,性能提升近 6 倍,代码一行没动。困扰多日的性能问题,根因是一行很少有人注意的配置。

一行配置 5.8 倍

QoS 调度:Background vs Standard

回头再看整个过程。AI 对云端性能的判断偏保守,但正是这次实测,我才注意到云端的三秒,才会追问 Mac mini 为什么慢,才一路查到 launchd 的调度配置。预判、实测、追问,三步缺一不可,这大概是人和 AI 协作的常态。

六、四条 AI 编程经验

经历了这次完整开发,我总结了 4 条实用的协作经验。

一,先写验收标准,再让 AI 写代码。明确做到什么程度算完成、边界在哪里,让它先出方案,确认无误再动手。方案里涉及平台规则的部分,AI 给不了确定答案,这部分自己定。

二,带着完整上下文修 Bug。报错时别只丢一句话,把完整日志、复现步骤和前后变化一起发它。它擅长顺着报错修表面,根因那一层,人带着挖会快很多。

三,主动做减法。我加过翻译功能,很快砍掉,因为偏离了辅导作业和去水印的主线。加功能太容易,判断标准就一条,它解决的是不是你最初那个麻烦。

四,分工清楚。AI 写具体逻辑又快又好,平台规则、架构取舍和产品体验,人来把关。

七、总结与【喵出图】体验

回顾整个过程,新的工具链(OpenCode、Paseo、多模型协作)加真机热推送,让一个人在手机上就能完成一个产品的大部分搭建。而进程调度、性能定位、平台规则这些环节,恰好是工程经验还在升值的地方。AI 像一个读完整座图书馆的实习生,懂得比你多,反应比你快,只是决定权不在它那,最后署名的还是你。

如果你也有给孩子处理试卷、图片去水印的需求,欢迎体验。

喵出图小程序截图:试卷去手写效果

喵出图小程序截图:空白卷还原效果

喵出图小程序截图:图片去水印效果

微信小程序搜索【喵出图】。试卷去手写,拍下做过的试卷,自动定位手写笔迹并消除,一键还原成干净的空白试卷。完全免费。

喵出图小程序页面截图

喵出图小程序页面截图

喵出图小程序页面截图

喵出图小程序页面截图

用着遇到什么问题或 Bug,评论区随时聊,顺手点个赞、收藏,或者转给想做小程序的朋友,都可以。


编辑本页
扫描二维码分享
打开应用扫一扫,即可分享