从反馈真空到AI写作教练:一款英语写作APP的技术实现与成本优化

📅 发布时间:2026/10/17 3:07:01
从反馈真空到AI写作教练:一款英语写作APP的技术实现与成本优化
很多人学英语卡住的地方不是词汇量不够而是写完之后“没人管”。上大学那会儿我写英文作文交上去要等老师好几天才能返回来批注还多半是几句“注意时态”“表达不地道”这类笼统的话。工作以后写英文邮件自己读三遍觉得没毛病发给母语同事再一看还是在礼貌程度、句式自然度上被委婉地挑出问题。这种“缺乏即时反馈”的困境恰恰是AI英语写作APP最值得解决的核心痛点。于是我自己动手做了一个面向英语学习者的写作训练工具定位是“随叫随到的AI写作教练”而不是“一键帮你写完全文”的生成器。这篇文章会把整个项目的需求分析、技术选型、Prompt工程、成本控制、踩坑记录和评测方法完整拆出来讲内容会偏向实操适合想用大模型做垂直应用的开发者、独立开发者或者正在规划AI教育类产品的产品经理参考。1. 需求洞察先搞清楚用户到底要什么1.1 英语写作的反馈真空才是真痛点市面上的翻译工具解决的是“我不会表达”但写作训练的最大问题不是“不会表达”而是“表达之后没有高质量反馈”。我梳理了三类核心用户痛点差异很明显学生群体写作文、写申请文书老师批改周期长而且批改集中在扣分点上很少有人告诉你“这句话为什么不对、下次怎么避免”。职场人群英文邮件、会议纪要用户往往不是不懂语法而是担心语气不礼貌、表达不简洁、用词不专业这类反馈恰恰是普通语法工具给不了的。备考人群雅思、托福等考试有现成评分维度用户需要知道自己“为什么是6分而不是7分”需要的是维度化诊断和提升路径。三类用户的共同诉求是即时反馈、解释清楚、给出可执行的修改方向。这就决定了产品不能只做一个“查错工具”而要做成一个能解释、能示范、能打分的辅助教练。1.2 MVP功能边界只做输入、批改、反馈的闭环项目启动时其实很容易犯“功能越多越好”的毛病。我们最早列了十几个功能包括智能扩写、全文重写、风格模仿、语音朗读、生词标注、长难句分析等等后来全部砍掉第一版只保留了三个核心能力语法与拼写纠错、表达润色、维度评分。理由很简单先验证“AI写作教练”这个体验模型是否成立再谈功能的宽度。就拿润色来说我们尝试过“一键改写全文”这种激进方案结果内测用户反馈并不好。原因是当AI把整篇作文全部改写之后用户根本不知道哪些地方需要学反而产生了一种挫败感。后来我们把润色拆成“逐句可选的修改建议”让用户自己决定接不接受接受率反而大幅提升。这个细节后来成为整个产品的设计基石AI建议是可交互的建议不是替代你的终稿。1.3 坚决不做“一键代写”的考量说句实在话以现在大模型的能力做“用户输入一个中文题目AI直接生成一篇地道英文作文”是技术上最容易实现的。但我们最终没有把它放进主流程原因有三层第一这个功能会诱导学术不端尤其在学生用户中会带来严重的合规风险第二从产品价值看它培养的不是写作能力而是对AI的依赖第三从调性和留存看真正让用户持续打开APP的是“我自己改出来的句子”带来的成就感。所以整条产品线走的是“教练”路线用户必须自己写AI负责发现问题、解释问题、示范更好的表达但绝不在没有用户参与的情况下直接产出整篇成品。这样的工具才经得起时间的检验。2. 技术架构选型规则引擎在前大模型在后2.1 整体架构客户端、业务服务、模型层三层分离项目第一版就采用了清晰的分层架构而不是把所有逻辑塞进客户端。核心考量是大模型调度、敏感内容过滤、用户数据缓存、评测日志这些能力必须集中在服务端否则客户端每次发版都会阻塞产品迭代。客户端跨端开发框架同时覆盖小程序和移动端首版以微信小程序为主降低用户获取成本。客户端只负责文本输入、结果渲染和交互反馈不直接调用大模型。业务服务层用Python异步框架搭建负责用户鉴权、文章解析、缓存判断、规则引擎检测、大模型调用编排、结果格式校验。所有业务逻辑都在这一层收敛。模型层统一封装大模型API网关和开源自托管模型的接口上层业务无感知切换。文本安全审核也在这里以插件形式接入。这个分层在项目后期帮了大忙。我们尝试替换不同模型服务商时业务服务层几乎没动只改了模型层的一个适配接口。2.2 模型选型商业API先跑通开源私有化再降本模型选型的核心不是“谁的分数高”而是“你的业务对数据敏感性、成本、延迟的容忍度”。我第一版全部走商业大模型API因为上线速度最快、效果最稳定到第二版访问量上来之后才开始调研开源自托管方案。商业API文本质量好多语言理解能力强不需要自己维护推理集群适合冷启动阶段。开源自托管模型一次付费后边际成本低数据不出内网适合用户量稳定后分流一部分高频简单请求。缺点是需要自己解决推理部署、并发和负载问题。这里有个小经验不要急着私有化全部流量。我们一开始把低难度请求切到开源模型发现某些复杂语法句法场景下质量下降明显于是改成“按文本难度分流”简单文本走开源模型复杂文本走商业API两端各发挥优势。2.3 为什么要在前面加一道规则引擎很多同行做AI写作产品时把“纠错”完全交给大模型。这是让成本失控最常见的原因。我们第一版上线一周发现账单增长比用户增长还快仔细分析之后决定在所有大模型调用之前加一个“规则引擎前置过滤器”。规则引擎负责处理那些确定性很强的基础错误单词拼写、主谓一致、冠词缺失、时态基础错误、明显的中式搭配等等。这类错误大约占用户文本错误总量的35%到45%而且在规则库中已经覆盖得不错不需要大模型介入。我做过一笔粗略的账假设每次用户提交一篇150词的短文输入约1800个token如果全部走大模型一次请求成本在某个档位加上规则引擎之后约40%的请求可以在只返回规则检测结果、不调用大模型的情况下完成——也就是说这部分请求的成本直接从单次计费降到几乎为零。同时规则引擎返回结果速度更快、可解释性更强用户能看到“这是固定搭配问题”这种确定性反馈。在不动体验的前提下这个大前置让整体API成本下降了约30%。聊技术的人常说“降低延迟、降低成本”我觉得真正有效的降本手段永远是架构级的能不用大模型的地方就不用。3. 核心功能拆解与实现从“找出错误”到“给出可行动的反馈”3.1 分句与预处理为什么不能整篇丢给模型早期原型图省事用户提交整篇作文后直接拼进Prompt发给模型结果出现两类问题第一输入超长导致接口超时第二模型对长文的关注度被稀释经常出现漏改、误改。后来我把处理流程改成先分句再逐句或按句组送入模型最后合并结果。分句没有直接用第三方库而是自己维护了一套规则原因是有个坑英文论文里常见的缩写词“Prof.”“e.g.”“Mr.”后面那个点在通用分词器那里往往被判定为句子结束符。我们早期就因为这个问题把人家一句话拦腰截成两半喂给模型结果模型在断句处脑补了一堆不存在的错误。后来加了缩写词白名单只在词尾点号后跟随大写字母且该词不属于白名单时才判定为句子边界。分块方面如果单个句子特别长超过80个词我们还会按从句边界再切成子句块并保留前后各一小段上下文作为“重叠窗口”防止模型因为缺少语境而误判指代关系。这套预处理逻辑虽然不起眼但直接影响后续所有环节的准确率。3.2 批注式输出纠错结果的数据结构设计为了让前端能稳定渲染修改建议我们跟模型约定了一种结构化的返回格式。每次检测一个句子模型需要返回包括错误类别、原文片段、修改建议、解释说明、严重程度在内的JSON数组。这个设计很好用前端拿到之后可以直接渲染成“错误列表 文本高亮”的复合视图。比如这样一条返回{ sentence_id: 3, original_sentence: He go to school yesterday., issues: [ { error_type: 主谓一致, error_severity: high, original_text: go, suggestion: went, explanation: 根据yesterday判断时态应为一般过去时go的过去式是went。, is_grammar_error: true } ] }这种结构化设计最大的好处是“可解释”。用户看到的不只是“go错了”而是每一处错误都有类型标签、等级、建议和解释点开还能看到这句话为什么错。这也帮助我们后续做用户错题本和薄弱点分析因为所有错误类型都是结构化存储的可以直接做数据聚合。3.3 三种强度的润色模式从“改对”到“改好”纠错解决的是“对错”问题润色解决的是“好坏”问题。我们给润色设计了三个强度级别用户可以选择保守型只调整明显不自然、不地道但不算错的表达保留原句结构和学习者的用词偏好。适合日常笔记、初稿练习。均衡型在保留原意基础上优化句式结构、替换更准确或更正式的用词适合邮件、申请书、作文定稿场景。大胆型允许大幅度重构句式使表达更贴近母语者习惯适合润色自己反复写了但始终不满意的句子。这个设计背后有一个很关键的洞察改写的强度越大用户的学习收获就越难保证。如果你直接把一句普通英语改成高级长难句用户多半只会觉得“哇好厉害”但完全不知道是怎么变的。所以我们给每个润色建议都附带了“改动原因”并且在“大胆型”模式下额外给出“原句-过渡句-最终句”三阶段展示让用户能看到一条清晰的变化路径。实测下来均衡型的使用率最高保守型次之大胆型用得最少但用户粘性最强——因为能啃下这种句子的用户学习动机本来就很高。3.4 维度评分从“一个分数”到“一幅画像”评分功能我们参考了常见英语写作评分维度设计了五个评分项语法准确性、词汇丰富度、句式多样性、内容连贯性、任务完成度。每个维度输出四个等级并附带一句简短评语和两个改进方向。为什么不用单一总分因为单一分值对提升没有指导意义。用户看见一个6分没有任何行动方向但如果告诉他“词汇丰富度处于C等原因是重复使用了good和important建议替换为significant、essential、crucial”他就知道下一步该干什么。这也是整个产品“教练感”的核心体现给出诊断给出处方而不是只有一个判决。这里有一个技术细节我们要求模型在评分时必须引用原文中的具体例子作为依据比如“你在第2段重复使用了3次important”。这样可以防止模型给出一堆通用废话。如果模型找不到依据宁可判定为“样本不足”也不会硬凑理由这也是Prompt工程里重点约束的内容。4. Prompt工程与输出控制驯服不稳定的LLM是核心功课4.1 从自由文本到结构化JSON的版本演进很多人第一次接大模型都喜欢让AI“自然回答”结果前端没法稳定解析。我们在这块也走过弯路Prompt工程一共经历了四个大的版本迭代v1自由文本。让模型直接输出“第X句有个错误应该改成XX”。结果格式五花八门前端解析成本极高经常漏掉后半段建议。v2增加格式要求。明确要求“以JSON数组返回”效果好很多但偶尔模型会夹杂解释文字导致解析失败。v3增加示例。在Prompt里给出1到2个输入输出的few-shot示例输出稳定性明显提升格式符合率超过95%。v4字段级约束与降级兜底。进一步限定每个字段的候选枚举值比如error_type只能从给定集合取并在业务层加入正则解析兜底彻底解决了解析率的问题。最终版纠错任务的系统指令大概长这样分享一个简化版本你是一名专业的英语写作导师。你的任务是帮助学习者修改英文句子。 要求 1. 只处理英文文本不要改变原文意图不要重写整句。 2. 找出所有需要修改的错误包括语法错误、词汇搭配、表达不自然。 3. 使用UTF-8 JSON数组返回不要输出任何解释文字。 4. 每个错误对象必须包含以下字段 - error_type只能是 [拼写, 时态, 主谓一致, 搭配不当, 冠词, 介词, 句式冗余, 表达不地道] - original_text原文错误片段 - suggestion修改后的正确表达 - explanation用中文解释为什么这样改不超过20个字 5. 如果没有错误返回空数组。 示例输入He go to school yesterday. 示例输出[{error_type: 时态, original_text: go, suggestion: went, explanation: 由yesterday可知应为一般过去时}]这类结构化约束的Prompt本质上是把大模型当成一个需要写清接口文档的组件来用。我在实际调试中发现在Prompt里给枚举值和示例的效果远比增加命令性措辞比如“务必”“绝对不能”要好。模型更擅长模仿例子而不是服从抽象指令。4.2 JSON解析容错不能只靠一次解析成功就算Prompt写得很规范模型偶尔也会输出带markdown代码块标记、或者某个字段多了一个逗号的非法JSON。我们在业务层做了三层容错第一层尝试标准JSON解析器第二层用正则剥离多余文本比如 json 开头和结尾标记提取出最外层中括号内的内容再解析第三层如果还是失败把这次请求标记为“解析失败”自动发起一次带“请严格只输出JSON数组”补充指令的重试。整套兜底下来最终解析失败的比例被压到了0.1%以下。这里还有个隐藏问题——模型返回空结果不一定是没错误也可能是懒。我们在内测中遇到过几次明显有错误模型却返回空数组。查了日志发现是用户文本里包含中文字符模型把它当成“不要处理中文”的指令于是跳过整句。后来在Prompt里加了一条“中文部分只是背景说明不需要修改但英文句子中的错误仍然必须找出”情况才改善。这类细节很难在通用文档里查到全靠真实语料踩出来。4.3 中英混杂文本的特殊处理中国用户的写作习惯和纯英文母语者差别很大——很多人写英文作文时会夹杂中文备注比如“这里我觉得用让步关系更好”或者干脆整段思维是中文的逻辑。这类文本如果直接丢给模型往往会出现两种极端要么模型忽略错误只回复中文要么模型把中文拿过来强行改成英文句子。我们的处理策略是在预处理层先把中文和英文分离开识别出“纯中文段落”和“中英混合句子”。对纯中文段落不做纠错只提示“本篇仅检测英文内容”对中英混合句子在Prompt中明确告知模型“忽略中文部分仅检测英文部分但误解中文会干扰原文意图”。事实证明明确告知“忽略某部分内容”能显著减少模型的误操作。这一点对所有做“多语言夹杂场景”的开发者都有参考价值。5. 上下文管理与成本优化1万日活背后的账单控制5.1 多轮改写的历史管理用户在产品里不会只改一遍。往往一次提交之后他会根据建议改一回、再改一回反复两三轮。如果不做历史管理第二轮的输入就会带上第一轮的全文上下文越来越长到第三轮可能就把整个会话的历史都拼进去了token消耗翻倍。我们的做法是服务端保存用户的每一版文本但每次调用模型时只传入“上一版全文 当前版本中发生变化的句子列表”。这样既保留了改动脉络又不会把历史垃圾全部灌进Prompt。一个用户修改三次同一篇文章总token消耗大约是直线拼接方式的60%左右。5.2 文本指纹缓存相同文本不重复调用写作工具场景其实天然存在大量重复提交用户改了某个句子、重新粘贴全文同一个班级的老师给学生安排同一篇作文几十个学生会提交相似度极高的文本还有用户自己反复提交同一篇文章测试效果。这类请求如果每次都走大模型其实就是白烧钱。我们在业务层加了一层缓存对提交文本做归一化转小写、去多余空白然后计算哈希值作为指纹命中缓存就直接返回结果只有新内容才触发真实调用。这个策略上线后API调用量直接降了30%而且用户的响应速度从原来的3秒变成毫秒级。这里的关键是缓存不能只存结果还要存住结果的过期时间因为模型升级后旧结果不一定还准确我们给缓存设置了7天有效期模型版本更新时自动清空。5.3 分级调用简单任务走规则模型复杂任务上大模型前文提到规则引擎前置过滤这里展开讲讲更细的分级策略。经过对线上数据的分析我们发现用户提交的文本里大约40%的基础错误如拼写、简单主谓一致用规则引擎就能高质量解决另外30%需要上下文理解如搭配、时态选择只有剩下的复杂场景才真正需要大模型的语义能力。于是我们设计了一个三级漏斗级别处理方式适用错误类型单次请求成本特征一级规则引擎直接返回拼写、简单语法、固定搭配几乎为零毫秒级二级开源自托管小模型时态选择、介词用法、中等改写极低私有化部署三级商业大模型API复杂句式重构、地道性、维度评分正常计费这套漏斗把一个典型的100词短文批改请求从“全量走商业API”改为“80%的请求仅走到第一或第二级”综合成本下降了接近一半。我认为这是所有AI应用开发者都应该优先考虑的架构先用低成本方案消化大部分请求让昂贵的大模型只处理它真正擅长的复杂任务——语义理解与创造性表达。6. 上线前后踩坑实录那些文档里查不到的教训6.1 缩写词把句子拆成两半这个坑在前面提过但值得单独再强调一遍。我们在分句逻辑里遇到的最大意外就是缩写词。像“Prof. Smith”“e.g. Apple”“Mr. Zhang”这些词通用分句规则会把缩写符当成句子结束。处理方式看起来很简单——加一个缩写词白名单但实际维护起来特别麻烦各学科缩写词持续增长而且用户在写作中可能用不标准的缩写。后来我们想了一个更稳的方案根据两个特征同时判断——点号后是否有空格and下一个词是否以大写字母开头再结合白名单做加权判断。这样一来被误拆的句子比例大幅下降。即便偶尔判断错误后续也会被合并逻辑兜底把相邻两个过短句子块重新拼成一句保证模型不会在断句处产生幻觉错误。6.2 用户整篇粘贴导致超时和截断上线的第一个星期就有用户反馈“为什么我贴了500词的文章转圈半天告诉我超时”查了日志发现模型的输出长度上限是写死的而一篇500词的作文解析结果远超这个上限于是接口直接截断前端解析失败进入重试循环又造成更大的并发压力。我们调整了策略按句子粒度分批请求并行度控制在3到5个并发用队列机制削峰。前端拿到结果时可以一条一条渲染用户看到的是“第一句改完了第二句正在检查”的渐进式体验心理感知明显更好。同时给整个请求链路设置了总超时时间如果某个批次失败只重试那一批不影响整个文章的其余部分。6.3 模型把学习者的“简单风格”过度改写成“炫技风格”这个问题的发现很有意思某内测用户提交了一篇用简单句写得很清晰的作文结果系统在润色模式下把大半句子都改成了复杂从句叠加的“炫技文”。用户反馈“这不是我的文风了我根本读不下去”。我们复盘后认为问题出在Prompt里“让表达更地道”这个指令被模型理解成了“让句式更复杂”。调整方案有两个层面第一在润色要求中增加“保留作者原有风格与句式偏好除非原表达有明显问题”第二在业务层加入“最小必要改动”的控制逻辑——用diff算法计算建议文本与原文本的修改跨度跨度过大时降低推荐优先级并主动给用户展示两种方案最小改动版和优化版。这个设计后来成了润色功能的体验护城河用户信任你是因为你尊重他的表达而不是把他变成另一个人。6.4 安全审核与写作用途引导做教育类产品内容和合规问题不能回避。我们上线时就接入了内容安全检测接口对用户提交的文本做前置过滤出现不合规内容时给出统一提示不让这类文本进入大模型检测流程。同时产品内设置了对应的使用协议和免责声明明确说明“AI建议仅供学习参考涉及学术提交或正式场合使用时请自觉遵守相应规范”。刚开始我们担心做内容过滤会影响用户体验毕竟用户只是来学英语的。但实际运行后发现问题概率极低而且一旦出现就必须严格处理不然产品的社会责任边界就模糊了。这里想提醒所有做类似产品的同行功能上线之前先想清楚边界比上线后补救容易得多。7. 评测与迭代把“我觉得好用”变成“数据说了算”7.1 建一个属于自己的评测集别只看Demo效果大模型产品迭代最怕的就是“凭感觉”。今天换一个Prompt觉得效果好一点明天换一个模型又觉得差一点但到底是好是坏说不清楚。我们第二个月就在内测用户群里征集了一批匿名作文样本重建了一整套评测流程。评测集由约300篇真实学生作文组成覆盖不同水平、不同题材并且由英语老师参与标注了“正确修改”和“错误级别”。每次迭代模型或调整Prompt我们都会在这套评测集上跑一遍对比修改精确率、漏改率、误报率等指标。评测集的价值是让你摆脱“某个例子看着好”的错觉。7.2 关键指标Precision/Recall、采纳率、改写幅度这个产品要看的核心指标我认为有三个维度修改精确率与召回率建议修改中真正正确的比例原文中实际错误被发现的百分比。这两个指标互相制约Prompt太激进则精确率下降太保守则召回率下降。用户采纳率用户对AI建议点击“接受”的比例反映了建议的合理性和可操作性。我们实测正常范围在45%到60%之间。端到端延迟从用户点击按钮到完整渲染结果的时间。我们设定的目标是平均2.5秒内完成一篇100词短文。尤其是用户采纳率这个指标比模型在离线评测集上的分数更能说明问题——毕竟离线分数高不意味着用户愿意接受你的改法。我们做了一次比较大的版本升级后离线指标提升了8%但用户采纳率反而下降了3%就是因为新版本建议偏“语感化”而偏离了用户的认知水平后来回退了部分改动。7.3 灰度发布与实时反馈闭环每个新Prompt或模型参数上线前我们都走“小流量灰度-数据对比-全量发布”的流程。灰度比例一般是5%观察一两天内关键指标的变化再做决策。此外每个建议条目后面都带一个“有帮助/没帮助”的轻量反馈按钮用户点击结果会回流到埋点系统用来持续修正Prompt用词和模型选型。这个反馈闭环的效果非常明显。比如我们发现“解释过长导致用户不看”这个问题就是在反馈数据里看到的——很多用户对长解释直接划掉。后来我们把解释压缩到20个字以内并且优先展示“错的点正确用法”采纳率回升了7个百分点。让用户用行为投票比任何内部讨论都可靠。写在最后回头看这个项目最深刻的体会不是“用了多先进的大模型”而是“如何让AI成为一个负责任的学习伙伴”。这中间有太多细节需要平衡既要纠正错误又不能破坏学习动机既要提升表达又不能替代用户思考既要追求效果又要把成本控制在可持续的范围内。整条链路里真正的工程量有一半在模型之外的业务层——分句、缓存、降级、评测、反馈闭环——这些看起来“不性感”的部分恰恰决定了用户体验的下限。如果你也在规划类似的AI教育应用我给一个非常具体的建议留出专门的时间建一套离线评测集把评测自动化脚本写到项目工程里。有了这套东西你后面做Prompt迭代、模型替换才能大胆去试。再就是尽早把成本画像算清楚哪怕只是一个估算表都能让你在做架构决策时少走很多弯路。这个项目后续还有很多可以扩展的方向比如针对不同考试风格学术写作、商务邮件、日常表达定制评分模型或者根据用户历次错误记录自动生成个性化练习。技术上都可行但优先级要取决于用户反馈会指向哪里。做产品就是这样——听数据的声音尊重用户的真实需求然后一步步把“看起来能用”打磨成“用了就离不开”。