背景最近在做一个教育SaaS产品的学情诊断模块目标是根据学生的答题记录、学习行为数据自动生成个性化的学习建议。做到一半发现网上的参考方案大多是理论层面的真正落地时遇到的问题远比想象中多。把踩过的坑记录下来给同行参考。整体架构系统分三层数据采集层负责收集学生的答题记录、视频观看时长、作业提交时间、错题分布等原始数据。特征工程层把原始数据加工成模型可用的特征向量。推理服务层调用大模型API结合特征向量生成诊断报告。数据采集层的坑第一个坑是数据完整性问题。教育场景下数据缺失非常普遍。学生可能漏做作业、中途退出视频、请假缺课。如果直接用缺失数据做特征模型输出会很不稳定。解决方案是做数据插值但不能用简单的均值填充。我们用的是基于学生历史表现的中位数填充比全局均值更准确。具体来说如果一个学生某天的答题数据缺失就用他过去七天同类题型的中位数表现来填补。代码片段def fill_missing(data, student_id, date, feature): history data[ (data.student_id student_id) (data.feature feature) (data.date date - timedelta(days7)) (data.date date) ] if len(history) 0: return global_median(feature) return history.value.median()第二个坑是时区问题。我们的系统服务全国机构不同地区学生在同一天的学习行为时间戳可能差好几个小时。如果不做时区对齐晚上的学习行为可能被归到第二天的数据里。解决方法是在数据入库时就统一转成UTC时间展示时再按用户时区转换。听起来很简单但我们上线后第一周就因为这个问题导致诊断报告里的学习时间段全错了。特征工程层的坑特征工程是整个系统最花时间的部分。我们最终定义了四大类特征行为特征日均学习时长、学习时段分布、连续学习天数。答题特征正确率、平均答题时长、错题集中分布。进度特征课程完成度、作业按时提交率、预习完成率。社交特征课堂互动频次、提问次数。第三个坑是特征冗余。一开始我设计了三十多个特征后来发现很多特征之间相关性很高。比如日均学习时长和连续学习天数这两个特征都反映学习持续性同时使用反而会让模型困惑。最终通过相关性分析砍到了十五个核心特征。用Pearson相关系数做过滤阈值设为0.85以上就保留一个def filter_redundant_features(df, threshold0.85): corr_matrix df.corr() features_to_drop set() for i in range(len(corr_matrix.columns)): for j in range(i): if abs(corr_matrix.iloc[i, j]) threshold: colname corr_matrix.columns[i] features_to_drop.add(colname) return df.drop(columnslist(features_to_drop))推理服务层的坑推理层我们调用的是第三方大模型API把特征向量组装成prompt让模型生成诊断报告。第四个坑是prompt长度控制。十五个特征如果每个都详细描述prompt会非常长导致token成本飙升。我们做了特征压缩只把异常值和关键趋势传给模型正常范围内的特征只传摘要。比如某学生日均学习时长是45分钟系统判断这个值在正常范围内就只传学习时长正常。但如果某天突然降到10分钟就把这个异常点详细传给模型。这个优化让单次推理的token消耗降低了百分之六十左右。第五个坑是推理延迟。大模型API的响应时间不稳定快的时候两三秒慢的时候十几秒。如果学生在端上等诊断报告十几秒的等待体验非常差。解决方案是异步生成加缓存预生成。学生提交答题后系统先返回一个正在生成的提示后台异步调用API。同时对于高频场景比如某年级某单元的诊断系统会提前预生成一批模板报告命中缓存时直接返回。性能数据上线后跑了一个月的数据日均诊断请求量约3500次 平均响应时间缓存命中1.2秒未命中8.7秒 缓存命中率百分之七十二 单次推理成本优化前0.12元优化后0.05元总结做教育场景的AI应用最大的挑战不是模型能力而是数据质量和工程优化。教育数据天然存在缺失多、噪声大、分布不均的问题如果不在数据层做好处理再强的模型也白搭。另外推理成本是真金白银每一个不必要的token都是钱。在prompt设计和缓存策略上多花心思比换更大的模型管用得多。