去年我在内部启动了一个代号为 DeepTutor 的项目目标是做一套真正意义上的“终身个性化 AI 家教”。不是那种套着大模型外壳的聊天机器人而是能从一个学生第一次进入系统开始持续跟踪他的知识掌握、遗忘规律、做题习惯、专注状态直到几年后他离开——这期间所有教学策略都随他个人动态调整。这篇文章我想把整体设计思路、关键技术拆解、实操中踩过的坑以及对“AI 家教”这个方向的一些真实判断一次性讲透。先说结论做一个“看起来智能”的家教系统并不难难的是让它长期稳定地“对你有效”。DeepTutor 的核心差异点在于三件事——动态知识画像、个性化路径生成、以及可干预的对话式讲解。这三个模块单独拆出来都有成熟方案但把它们串成一个能跑通“感知-建模-决策-行动-反馈”闭环的终身系统中间藏着大量工程细节。这篇文章适合正在做教育产品、学习类 App、私域教学工具的开发者也适合想理解下一代个性化学习系统内部逻辑的产品经理。1. 整体设计思路为什么把知识掌握建模成“动态地图”而不是“错题台账”终身个性化家教的第一性问题是怎么表示“学生当前会什么、不会什么、快要忘掉什么”。绝大多数学习产品把个性化做成了错题本和知识点标签的堆叠这本质上是一种静态台账。短时间内够用但时间一长就失灵——学生一旦跨过某个阶段旧标签就不再代表他当前的真实水平。我在 DeepTutor 里换了一套思路把学生建模成一张持续演化的知识地图地图上每一个知识点不是一个布尔值“会/不会”而是一个带置信区间的连续掌握度。这个掌握度不只在做题后更新在每次浏览讲义、每次对话提问、甚至每次犹豫和修改答案时都会产生更新信号。整张图不是一次建好而是每一轮交互都在“预测-检验-修正”的小循环里滚动演进。1.1 传统“错题本式”设计到底卡在哪里先拆一下为什么静态标签不够用。举个常见的场景学生学过一次“一元二次方程求根公式”三天后做对了三道题系统打上“已掌握”标签。但两周后他遇到一道带参数的求根问题卡住了——并不是因为他没学过公式而是因为他从未在迁移情境下使用过这个知识点。静态标签系统在这里无能为力因为标签本身没有状态更新机制。更麻烦的是知识依赖。学生“因式分解”薄弱可能直接导致“二次函数图像与 x 轴交点”相关的题不断出错。如果系统只看到表象错误把它标成“二次函数未掌握”那么下一次教学就会重复讲解二次函数却从没补因式分解的底子。这种误诊在传统系统里非常普遍。DeepTutor 之所以要建立知识图谱核心目的是让系统具备“归因诊断”能力。出错时不是更新一个孤立标签而是把错误信号沿知识依赖关系传播给多个上游知识点。比如某道题涉及“二次函数求最值”它依赖“配方”“顶点式”“二次函数图像性质”。如果学生卡在配方系统会把掌握度下降的信号同时传播给“配方”和“顶点式”再通过对后续题目的试探来定位真正的根因。1.2 DeepTutor 的分层架构与数据闭环为了让这套机制可落地整个系统分成了四层感知层、画像层、决策层、行动层外加一个贯穿始终的评估回环。感知层负责把每次交互转成结构化事件。原始日志可能是“用户点击下一题”“输入框填入答案”“停留了 12 秒”“主动发起一次追问”这些在感知层统一标准化成带时间戳的交互事件。画像层维护知识地图和各类状态变量。决策层根据画像输出下一步动作——出什么题、给哪种提示、跳过还是停下。行动层执行具体的教学动作包括生成讲解、推送练习、制造间隔复习。四层之间靠异步消息解耦。学生在前端答题感知层把事件写入消息队列画像层消费事件并更新状态决策引擎基于最新画像计算动作指令行动层再渲染具体内容。整个过程不要求同步完成哪怕画像更新延迟两三秒也不影响体验——这给复杂计算留出了余地也让系统更容易水平扩展。我当时特别坚持的一点是画像层必须是“写多读多”的服务而且要支持实时读取。决策层每次出题前都要读一次画像不能靠缓存扛。理由很简单教育场景里基于过期画像做出的推荐比随机推荐危害更大。你让一个刚刚突破薄弱点的学生继续做旧难度的题他很快会失去动力。2. 终身画像知识掌握度、遗忘曲线与多模态行为建模画像层是整个 DeepTutor 的心脏。它不仅记录“这个学生学到哪里”更记录“这个学生如何学习、何时遗忘、什么条件下表现最好”。下面把几个关键模型拆开来讲。2.1 从 IRT 到贝叶斯推断掌握度到底怎么算我给掌握度选的核心估计算法不是简单的正确率而是项目反应理论IRT的变体配合贝叶斯更新。IRT 的核心直觉是一道题能反映出学生水平多少取决于题目本身的难度、区分度和猜测系数。同样一道题学渣做错和学霸做错诊断价值完全不同。在这个框架里学生能力值是一个潜在变量每次答题结果是一次带噪声的观测。我们用贝叶斯公式不断更新对能力值的后验分布。初始化时可以给能力值一个弱先验——比如均值为 0、方差较大的正态分布随着观测增多后验会越来越集中系统对学生的判断也越来越准。关键技巧是不直接使用后验均值作为掌握度而是使用“后验概率低于某个阈值的评估”。比如某知识点能力值分布的 95% 可信区间下限高于题目难度阈值时才标注为“已掌握”。这个保守策略看似让系统进步变慢但实际能显著减少误判带来的复习浪费。为了避免纯贝叶斯方法在多知识点场景下的组合爆炸我为每个知识点单独维护一个轻量模型同时用知识图谱中的条件依赖关系做传播。一个知识点被观测到错误时不仅更新自身的后验还会以衰减系数去更新其依赖链上的相邻节点。衰减系数的取值我一般设在 0.3 到 0.6 之间具体用历史数据回归校准。2.2 遗忘曲线让画像拥有“时间维度”终身个性化离不开时间。学生今天会做这道题不代表下周还会。心理学里的艾宾浩斯遗忘曲线给了我们一个基础形状——遗忘先快后慢但我们不能只套一个固定函数因为不同学生、不同知识点的遗忘速率差别很大。我在 DeepTutor 里为每个知识点维护了一个“记忆强度”变量并与掌握度分开处理。掌握度回答“会不会”记忆强度回答“多久不练会忘”。每次正确作答后记忆强度提升每次错误作答后掌握度和记忆强度同步下降并触发复习。更新记忆强度的公式借鉴了间隔重复领域的成熟思路。新增一个指数衰减因子时间间隔越长单次复习对记忆强度的提升幅度越大但提升上限递减。还要加入一个特殊行为信号如果学生在没有提示的情况下连续两次正确作答记忆强度会额外增加一个奖励系数如果学生用了提示才做对奖励系数几乎为零。这个设计背后是一个很朴素的教学直觉独立完成和辅助完成的巩固效果完全不同。系统必须把这种差异量化为数值才能避免“看似全对实际依赖提示”的假性掌握。2.3 多模态行为数据答题之外的隐藏信号只靠对错来建模数据密度太低。DeepTutor 接入了三类辅助信号。第一类是时序行为信号包括单题停留时间、答题过程中的编辑次数、从题目出现到首次点击输入框的延迟。这些信号经过归一化后作为“流畅度”特征。我观察到一个稳定的规律熟练作答的停留时间分布非常集中而不熟练的作答往往表现为两个极端——要么极快乱猜要么极慢犹豫。极端值都会拉低流畅度得分。第二类是交互反馈信号包括学生主动点击“看不懂”“换一题”“提示一下”等按钮以及聊天对话中出现的困惑表达。这类信号权重很高因为它通常是学生主观意识的清晰表达。第三类是元认知信号包括学生对自己作答的确认行为、检查行为的频率、请求查看解析的次数。我把自律性作为画像侧写的一个重要维度——它不直接决定出题难度但影响讲解策略。高自律学生可以给更简短的提示低自律学生需要更高频的即时反馈。这三类信号在特征层拼接后进入一个轻量级的打分模型输出“当前状态置信度”。这个置信度不用于给学生排名而是用于调节决策引擎的激进程度。状态置信度高时系统更愿意推进新知识点置信度低时系统倾向于返回已学内容做巩固。3. 个性化学习路径从约束求解到强化学习的混合理念画像负责描述“我是谁”路径生成负责回答“下一步该学什么”。我把它拆成两个层次宏观路径和微观动作。宏观路径决定知识点的学习顺序微观动作决定当前这一步的难度、提示力度和呈现方式。3.1 为什么单一推荐算法跑不通教育场景的推荐和电商推荐差别极大主要体现在三个层面。第一学习路径存在严格前驱依赖你不能让一个没学过导数的学生去做泰勒展开的题目——这在电商里不存在类似约束。第二学生同时存在多个待巩固知识点推荐不仅要考虑相关性还要考虑负载均衡避免某一薄弱点被反复强化而其他薄弱点被遗忘。第三推荐的收益不是即时的一次推荐可能要在几天后才能评估效果。DeepTutor 的宏观路径生成采用的是“约束满足 评分排序”的混合方案而不是端到端强化学习。先构建当前学习目标所需的知识点依赖拓扑然后做拓扑排序得到合法序列。序列中的每个位置上可能有多个候选知识点再用一个评分函数选出最合适的一个。评分函数综合了掌握度差距、与当前目标的相关性、距上次练习时间、预估学习时长的匹配度。这套方案相比纯强化学习更可控也更好调试。端到端强化学习在对话式教学场景里经常会陷入奖励稀疏和动作空间过大的问题训练不稳定出了问题还不好定位。约束满足方案保证了基本教学法不被违背评分函数则负责个性化微调。3.2 强化学习只用在“提示决策”这一个窄场景虽然宏观路径没有用强化学习但微观动作里有一处我最终用了强化学习——提示力度决策。原因很简单提示力度没有一个绝对正确的静态答案。同一个学生今天状态好时可能只需要一个方向性提示明天状态差时需要逐步拆解。这本质上是一个序列决策问题。具体做法是把提示分成六级0 级为无提示1 级为方向提示2 级为分解提示3 级为示例提示4 级为过程引导5 级为直接讲解。决策模型观察当前画像特征、题目特征和学生近期的交互行为输出一个合适的提示力度。奖励信号是综合计算出来的如果学生给出正确作答且用时合理给予正奖励如果学生表现出明显困惑或放弃给予负奖励如果学生完全不看提示就做对了说明提示过度也给予轻微负反馈。实际训练时遇到了几个坑。奖励信号延迟性很高一道题的完整交互可能要几分钟才结束而且中途学生可能多次请求提示。我用了一个简化技巧把一次完整做题过程切成多段状态-动作-结果样本而非等到整题结束后再统一计算。比如学生点击提示按钮就是一个决策点下一次状态变化作答、继续请求提示、放弃就是这次决策的短时结果。这样能产生足够密度的训练信号。3.3 实时调整节奏预测学生“快要崩了”的瞬间终身个性化系统必须具备节奏感知能力。我发现最有价值的信号不是单个行为而是行为序列的模式。比如一个学生连续三道题都在第三级提示下才完成这比“某一道题做错”更能说明他正在疲劳或知识点衔接出问题。DeepTutor 维护了一个滑动窗口状态监测器统计最近 20 次交互中的流畅度均值、正确率、提示使用率、以及时间间隔分布。这些特征通过一组简单规则触发保护机制如果正确率低于 30% 且提示使用率高于 50%系统自动降难度或者切换复习模式如果流畅度连续下降但正确率尚可系统会插入一道带变式的巩固题如果间隔时间异常拉长系统会主动缩小讲解篇幅。这套实时调整机制没有用特别复杂的模型靠的是精心调过的规则阈值和异常检测组合。在工程上它的优点是极其稳定、响应快、不会出现模型在极端情况下的不确定性。我会在知识图谱中的每个节点上单独记录“最近一次练习时间”和“活力值”活力值高说明这个知识点近期被高频激活低则进入了遗忘风险区。4. 实操DeepTutor 核心模块实现要点与关键参数这部分把最关键的工程决策整理出来。代码层面的思路可以给参考具体实现里有不少值得注意的细节。4.1 画像服务的状态存储选型画像数据有鲜明的特点结构复杂、读写频繁、需要版本管理。我一开始试过直接存在 MySQL 里但很快发现掌握度更新涉及图上多个节点的批量写操作用关系型数据库的表连接实现非常别扭而且并发更新同一学生画像时容易产生竞态问题。最终我选用了 Redis 定期快照落库的混合方案。热数据存 Redis使用哈希结构表示知识地图的节点集合每个节点的 key 是知识点 IDvalue 是一个包含掌握度均值、方差、记忆强度、更新时间戳等字段的小对象。操作时用 Lua 脚本保证多字段原子更新避免并发覆盖。冷数据落到 ClickHouse 做历史分析和离线重放。快照周期我设置在短视频会话级别——每 30 秒将变更写入写缓冲会话结束后合并成一次快照。这样即使是学生中途遇到网络波动恢复后也能从最近一次快照继续。有一点要特别提醒画像服务必须与业务服务做好隔离。出题和讲解的业务逻辑不能直接改画像数据只能通过事件总线提交更新请求。我在早期版本里图省事让业务侧直接调用画像服务的方法结果在并发和数据一致性的坑里反复挣扎。换成事件驱动后不仅问题消失了业务逻辑和画像逻辑也就自然解耦了。4.2 推荐引擎的召回与重排推荐引擎的召回阶段从知识图谱中筛选候选知识点。我设置了三个召回通道薄弱知识点召回、濒临遗忘召回、以及当前学习目标的关联知识点召回。每个通道有独立评分最终用线性加权合并。权重设定不是拍脑袋定的我在离线数据集上做了一轮简单的参数搜索发现薄弱知识点权重的合理区间是 0.4 到 0.6濒临遗忘权重在 0.2 到 0.3 时效果最好关联知识点在 0.2 到 0.4 之间波动。重排阶段要考虑题目层面的难度适配。每个知识点下的题目池会先标记难度系数再根据学生画像里的能力值选择难度区间。我采用的策略是“邻近挑战区”——难度略高于学生能力值但不超过某个容忍阈值。这个阈值我设成能力值标准差的 0.7 倍既保证有挑战性又不至于劝退学生。关键工程细节是去重和交替。同一知识点连续出现三道题会造成枯燥感所以重排时加入限制同一知识点的题目间隔至少要插入两道其他知识点的题。学生已经做过的题目会在 30 天内默认不重复除非该知识点掌握度出现显著下滑。这些约束直接写进重排逻辑里避免模型侧反复试错。4.3 自然语言讲解的生成策略与质量护栏讲解生成部分我选用的方案不是让大模型自由发挥而是走“脚手架 约束生成”路线。具体来说系统先生成一份结构化的讲解脚本包含目标知识点、学生已知的前驱概念、当前题目的关键步骤、以及需要避开的常见误解。这份脚本作为提示词里不可被覆盖的约束再让大模型基于它生成自然语言。我在提示词里明确要求讲解长度不超过 200 字、每个推理步骤单独成行、涉及公式时必须附带文字说明。这样生成内容在结构上稳定可预期。生成之后还要过一个规则过滤器。它检查是否存在超纲术语、步骤跳变、以及与前驱知识矛盾的内容。有一个我后来补的规则很重要如果学生的画像里显示某个前驱知识的记忆强度很低讲解里就不能默认它——必须先用一句话快速复习再进入当前题目的讲解。这个系统的第一版完全靠大模型直接生成结果各种“话痨”和“跳步”问题让人头大。换成脚手架方案后质量虽然谈不上惊艳但稳定性和可控性提升了好几个量级出错率显著下降。5. 常见问题与排查技巧实录5.1 画像漂移学生进步了系统还在用旧画像这是最容易遇到也最难发现的问题。学生可能连续一周状态极好系统却还在按旧数据出简单题导致他明显感觉“没意思”。排查思路是先看画像事件的更新链路有没有延迟。有一次我发现某个画像服务结点宕机了事件积压在消息队列里等恢复后一次性重放把学生的掌握度瞬间推高了好几档反而导致后续推荐混乱。后来我加了重放限流和时间窗口衰减时间超过 30 分钟的事件不再原样重放而是只衰减式更新。另一个常见原因是画像更新逻辑里只使用了“最近一次答题结果”而没有综合滑动窗口内的表现。解决办法是在更新公式里引入时间衰减平均当前值 历史值 0.7 最近窗口平均 0.3避免单次偶发因素被过度放大。5.2 生成讲解要么啰嗦要么跳步这问题几乎无法靠提升模型参数彻底解决必须靠结构约束。如果你用的是提示词方式那么在提示词里加上“不解释学生已经掌握的概念”“每一步必须引用学生已知的某个前驱知识点”这类约束会有效很多。我实战中比较有效的方法是让讲解模块先输出一个 JSON 结构包含步骤列表、每步骤的解释、以及可选的提问点。然后根据学生画像里的记忆强度做二次裁剪——记忆强度高的步骤直接折叠成一句话记忆强度低的步骤才展开详细说明。这个方案比单次提示词生成要复杂但对终局质量的提升非常明显。5.3 长周期会话的状态恢复学生可能隔几天才回到系统这时画像应该延续但会话上下文需要更新。我踩过一个大坑系统在恢复会话时把旧画像和旧对话上下文一起拿了出来结果学生在中断前刚做完一道难题恢复后系统以为他还在那个状态马不停蹄地继续推进。实际上几天过去他早就忘了。解决方案是画像保持长期对话上下文保持短期。恢复会话时不加载任何上次对话的具体内容只加载画像和一段系统生成的“状态摘要”。摘要里写清楚上次学到哪里、哪些知识点需要重点复习、哪些已熟练但完全不含具体题面和讲解内容。这个摘要相当于老师的备课笔记而不是课堂录音。5.4 冷启动新学生没有任何历史数据冷启动几乎是所有个性化系统的死穴。我的处理方式是分阶段初始化。前 20 道题进入“探测模式”题目覆盖广泛但难度较低目的是快速建立基础画像。期间不推荐新知识点不安排复习所有产出都服务于画像冷启动。探测题目选择有讲究不能随机抽。我用了一批在区分度上经过预测试的“锚点题”每个知识点安排 2 到 3 道覆盖信息量最大。等 20 道题跑完画像服务已经可以对主力知识点提供可用的初始掌握度估计。如果学生能主动提供更多信息比如选择所在年级、学习目标、偏好的讲解风格我会把这些作为贝叶斯先验输入大幅缩小初期的探测范围。这样做还能给用户一种“从第一天起就被理解”的体验实际留存率明显高于冷启动阶段全盲猜的系统。6. 给想复刻类似系统的开发者几条实在建议如果你希望做一版类似 DeepTutor 的系统我的建议是不要一上来就追求大而全。先做一个只支持单知识点、3 个学生、2 类题型的最小闭环把“做题-画像更新-出题决策-讲解生成”这条链路完整跑通。这个闭环的价值在于它能暴露出数据标准化的所有问题——你会发现就算只有 3 个学生事件定义不一致、画像更新延迟、推荐结果不稳定的问题也都会冒出来。第二步才是扩展知识点图谱。这一步不要自己手工建大规模图谱先以教科书目录为基础自动生成粗粒度结构再通过学生答题数据反哺细分依赖关系。知识和知识之间的依赖关系不是一成不变的在数据分析中短期内使用者定义的依赖与真实数据表现不一致时要以真实数据为准。还有一条工程经验尽早建立可观测性体系。我在 DeepTutor 里埋了三个核心指标——画像更新延迟、推荐动作执行率、以及学生每轮交互产生的画像修改次数。这三个指标能帮你快速定位系统到底是因为数据不全还是策略错误导致推荐不理想。个人在实际操作中体会最深的一点是终身个性化系统的成就感其实来自细水长流。第一周跑通 demo 觉得非常惊艳但真正让人愿意一直用下去的是——连续使用到了第二个月、第三个月系统开始预测到你哪些知识快忘、哪些概念容易混淆并在你还没开口问之前给出恰好的提醒。那一刻你会觉得自己和系统之间形成了一种默契这正是我一直追求的 AI 家教体验。最后再分享一个经验不要迷信单一算法更不要迷信“端到端深度模型搞定一切”。教育场景的特殊性在于教学法本身是一种强大的先验约束把它变成规则和结构注入系统远比让算法从零开始学习要高效得多。DeepTutor 的整体设计就是规则先验和统计学习互相配合的结果——规则保证下限学习负责上限这大概是所有教育 AI 产品都要走的路。
阅读完成 · 觉得有帮助?