```html TestMadeEasy:拍照生成试卷,当天完成 TestMadeEasy:拍照生成试卷,当天完成
Hacktoberfest Open-Source AI Challenge · Week 2 (Side Hustle)
我做了什么
我的朋友 Akash Agrawal 在一家辅导中心教书。每次他需要为某个班级、某个科目或某个单元出一份测试卷,流程几乎固定:从参考书和旧卷子里挑题,截图,做标记,然后把一堆截图丢给排版员。
排版员的工作,是把这些截图重新敲成一份卷子——用规范的数学符号重打每道题,重画图表,套进机构带 logo 的品牌模板,导出 PDF 再回传审核、打印。Akash 的中心普通题付 ₹5 一道,带图的题 ₹10 起。时间上大约一周:老师挑题 2 天,等排版员 5 天。
TestMadeEasy 想砍掉的,就是中间这一层。老师拍下一页书(或框选其中一段),应用把每道题还原成干净、格式统一的文本:
- 题目转成 LaTeX,让数学和化学符号看起来像真正的考卷
- 选项与题干分开
- 自动生成答案与解析
- 标注学科、章节、知识点、难度和分值
- 图表直接从照片里裁出来
之后老师选题、套上机构品牌(logo、配色、页眉、水印),打印试卷和答案卷。当天完成,不需要排版员。
还有一个让系统越用越聪明的设计:共享题库。每道提取出来的题都会和题库比对,已经有人扫过的题会被匹配同步,而不是重复提取。题库越大,需要重新扫描的内容越少——老师开始改现有题目的数值,而不是从头敲新题。
谁在为这件事付钱
目标是小型辅导机构,那种几个老师、每周跑 JEE、NEET 和 board exam 测试的机构。他们今天已经在为这项工作付费:按题付给排版员,或者付成工资——有些排版员一个考试周期拿 ₹15,000 到 20,000。
定价按订阅分层:
- 免费版:5 份试卷,永久保留在账户里。
- 付费版:教师账号,每月最多 100 份试卷,按生成的试卷计费。每份 10 到 15 道题,目标做到每题 ₹1 到 2,对比现在付的 ₹5 到 ₹10 以上。
- 高级版:接入共享主题库,可以用其他老师已经提取过的题来组卷。
- 自带密钥:更大的中心可以接入自己的 API key 和更强的模型。
₹1 到 2 这个数字能成立,靠的是这周重建所跑的模型。在 Gemini 3 Flash 上,一页的 token 成本约 $0.003——单看很小,直到一位老师扫完一本 200 页的题册。Gemma 4 目前在 Gemini API 上不收费,这才让每题 ₹1 到 2(以及一个真正的免费层)算得过来。应用仍在每道题上记录 token 数,一旦收费变化能立刻看到。
演示
在线地址:testmadeeasy.tech
评审登录(一个已加载示例数据的教师账号):
- 邮箱:testinguseramrit@gmail.com
- 密码:hacktoberfest
账号里有从 4 张练习卷提取的 18 道题、一个“Shree Science Academy”品牌,以及 3 份带答案的试卷。想自己试的话,去 Add Questions 上传任意一页(或仓库里的示例卷)。一页通常不到一分钟。
代码
amrit-dash / testmadeeasy
把一页教科书照片变成带品牌、可打印的试卷。Gemma 4 把题目提取成 LaTeX。
TestMadeEasy 是给辅导老师的试卷生成器。你拍下一页参考书,开放权重的 Gemma 4 模型把每道题拉成干净的 LaTeX:选项、学科、章节、知识点、难度、分值,以及图表所在位置。题目进入你自己的题库。你挑出想要的题,加上机构的 logo、配色和水印,打印试卷和答案卷。
它是为印度那些每周跑 JEE、NEET 和 board exam 测试、目前花钱请排版员逐题重打的小型辅导机构做的。
演示视频:youtu.be/lA2mvoYwOtQ
想不用自己的页面试试?docs/images 里的 4 张练习卷(物理、化学、数学、生物,全部原创题)就是演示所用的素材。
这周的位置
我想把时间线说清楚。TestMadeEasy 始于 2026 年早些时候的一个私人项目,建在 Gemini 上。Akash 在 Replit 里搭了第一版 UI,我搭了后端、AI 流水线和周边基础设施。
我们以 ₹5,000 向一家 IIT 备考辅导中心做了推介。他们没有说不。他们付了 ₹1,000 做试用,我们给他们开了账号,导入他们之前的试卷,还抓了往年 IIT 试卷来预填共享题库。提取效果足够好,试卷出来是对的。
但他们并没有真正用起来。他们继续通过 WhatsApp 把试卷发给我们,于是我们自己跑平台再把卷子发回去。他们真正想要的是一个 WhatsApp 机器人:发照片,回一份卷子。这是习惯,加上一个他们始终没太用顺的平台,我们没有走出试用阶段。不过 Akash 每天用自己的课在用,也传给了其他在用的老师。
那次推介给我的教训是价格。对一个习惯按题付费给排版员的中心,₹5,000 很难卖。这周是转折点:我们把 AI 核心重建在开放权重的 Gemma 4 上,把成本压到下次能报每题 ₹1 到 2,同时把代码开源。
我怎么搭的
前端 React 和 Vite,后端 Express,Postgres、认证和图片存储用 Supabase。整体作为一个容器跑在 Google Cloud Run 上,前面是 Firebase Hosting,挂在 .tech 域名下。
换入 Gemma 4
此前所有 AI 调用都走 Gemini。Gemma 4 通过同一个 Gemini API、同一把 key 提供,接受相同的系统提示词和 JSON 响应结构,所以第一步基本是配置:
- gemma-4-31b-it 负责提取、答题和图表重绘。
- gemma-4-26b-a4b-it(混合专家,4B 激活)给老师对共享题的修改打分。
- 管理员可以从下拉菜单把任一任务切回 Gemini 模型,代码其他部分不需要知道当前跑的是哪个。
然后我们在真实页面上测试,工作就在这里。
不生成图像的图表
Gemma 不生成图像,我们也不希望它生成。重画图表会丢细节还烧 token。模型只负责指出每张图在哪,我们从原照片里裁出来,什么都不丢,成本也低。
旧提示词要求用百分比返回 {x, y, width, height}。Gemma 老是返回半个框(只有 {x: 61, y: 158},没有宽高)或原始像素,应用没东西可裁,只能显示整页。我们换成 0 到 1000 网格上的 [ymin, xmin, ymax, xmax]。这是 Google 视觉模型做检测时训练用的格式;Google AI 的 Detecting and Editing Visual Objects with Gemini 和 Native Bounding Boxes Changes Everything for Visions Devs(作者 amirhosseinghanipour)都解释得很好。服务端把框转回百分比:
// [ymin, xmin, ymax, xmax] on a 0-1000 grid -> {x, y, width, height} in percentfunction boxToBounds(box: unknown, padPct: number) { if (!Array.isArray(box) || box.length !== 4) return null; const [ymin, xmin, ymax, xmax] = box.map((v) => Math.min(1000, Math.max(0, v)) / 10); const x = Math.max(0, xmin - padPct); const y = Math.max(0, ymin - padPct); return { x, y, width: Math.min(100, xmax + padPct) - x, height: Math.min(100, ymax + padPct) - y };}框第一次就从不靠谱变得贴合。
模型还倾向于把题目的框早停一行,最后一行选项被切掉。服务端没有再加一段“请包含选项”的提示词,而是用几何方式把每个框往下扩:取题目自己的图表,往下扩到同列下一道题的上方为止。
让 Gemma 可靠
还有几处坏了,每处修起来都不大,但都得先找到:
- 页面无缘无故“失败”。Gemma 有时即使在 JSON 模式下也会把 JSON 包进 markdown 代码块。我们的“是否被截断”检查在找闭合的 },找到的是代码块围栏,重试两次就放弃。剥掉围栏后,4 张测试页里修好了 2 张。
- 4 道题只回来 1 道。现在 schema 要求模型先列出页面上所有题号再提取。列了 4 道只返回 1 道,服务端重试一次并告知漏了什么。
- 调用挂了 15 分钟。每次 AI 调用现在有 150 秒超时,卡住的请求会重试而不是堵住任务。
- 任务中途冻住。提取在上传请求返回后于后台运行。Cloud Run 默认只在请求进行中给容器 CPU,没人轮询时任务就爬。一个 --no-cpu-throttling 标志解决。
- 免费层限制。Gemma 在 Gemini API 上有较低的每分钟 token 上限,一页要花 3 到 5k token,所以 Gemma 调用改成同时跑 2 个。
这一轮下来:4 张练习卷输入,18 道题全部输出,每道都带可用的裁图。
为什么开放创新在这里重要
成本就是整个生意。我们的推介部分败在价格上。在 Gemini 3 Flash 上一页 token 成本约 $0.003,单看很小,直到一位老师扫完一本 200 页的题册。Gemma 4 目前在 Gemini API 上不收费,这才让每题 ₹1 到 2(以及一个真正的免费层)算得过来。应用仍在每道题上记录 token 数,一旦收费变化能立刻看到。
关键的东西不被锁定。题库才是产品。如果免费层消失,权重是开放的:我们可以在自己的 GPU 上跑同一个 Gemma 4,提示词和 schema 原样保留,因为是同一个模型,不是“相似”的模型。
隐私是下一步,我也说清楚:目前托管免费层是把成本压到零的原因,而 Google 表示免费层的提示词可能被用于改进其产品。对于不希望试卷离开大楼的学校,自托管同一个开放模型是诚实的答案,这在待办清单上。
接下来想做的:试用中心要的 WhatsApp 流程(发照片,回一份卷子),以及把低质量手机照片裁出的图表做超分。
奖项类别
- 最佳 Gemma 使用:Gemma 4 31B 和 Gemma 4 26B A4B 默认跑所有 AI 任务:把照片读成结构化题目、找题目和图表框用于裁剪、生成答案、把简单图表重绘成 TikZ、给共享题库的修改打分。
- 最佳 .tech 域名使用:应用在 testmadeeasy.tech。
由 Amrit Dash 和 Akash Agrawal 搭建(Akash 没有 DEV 账号)。
热门跟贴