2026-11-15-reading-answer-distribution.md 12 KB

阅读理解答案位置异常:排查与解决方案

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 消除阅读试卷正确答案集中在 A 的问题,并确保在线答题、打印试卷、答案解析使用一致的选项对应关系。

Architecture: 通过共享的、可复现的题组呈现函数控制正确选项位置,移动整个选项对象,保持正确内容及判分依据不变。在线答题和 PDF 使用同一个呈现版本;同时消除生成示例中的首项正确偏置,并处理解析里引用的原选项字母。首期兼容已有题目,不批量改写历史题目或成绩。

Tech Stack: Angular 18、TypeScript、Jasmine/Karma、现有 Parse 阅读接口。

Spec: 本文“调查结论”“目标与约束”是本方案的依据。当前用户请求为先查原因、再制定方案;本文任务均尚未实施。

调查结论

线上只读证据

核查截止:2026-11-15 18:05(Asia/Shanghai)。统计按北京时间自然日筛选 createdAt,不是服务器默认时区。

范围 阅读题数 关联文章/题组数 原始顺序正确答案 A/B/C/D 五题全 A 题组
11 月 15 日截至核查时 105 21 104 / 1 / 0 / 0 20
11 月 14 日全天 110 22 110 / 0 / 0 / 0 22
  • 今天的 21 组都有五个不同题号;105 道题均有四个不同选项、唯一 check=true,未标记删除。已单独回查关联文章,确认 21 篇存在。
  • 今天查询到的 SurveyLog(type=exam) 为 0;该结果仅说明未查到这种线上提交记录,不能据此判断学生未做纸质试卷,也不能证明用户反馈一定来自打印入口。
  • 今天至少 25 道题的题目级解析含显式的选项字母引用,如“B项张冠李戴,C项无中生有,D项时间倒置”。数字为规则命中数,不宣称覆盖全部自然语言引用。
  • 已抓取正式 H5 入口并沿依赖检查 63 个脚本,确认下面三处行为存在于当前线上产物,而非仅存在于本地源码。
  • 所有生产请求均为 GET;未生成新题、修改提示词、提交答案或调整成绩。私有证据存放于 /Users/mac/.local/state/xiaoshu/qa/2026-11-15-reading-answer-audit/,原始题目和线上代码不进入 Git。

原因链路

  1. 生成格式示例有明显的首项偏置。 english-reading.service.ts:153–159 为每道题都生成 check: optionIndex === 0 的示例;fmode-ai.service.ts 将这个示例追加到提示词末尾,并要求严格按结构返回。正式产物 chunk-62Y437QX.js 同样存在 check:m===0。这是强烈的首项示范偏置;本次未做在线模型对照实验,因此不能把模型内部因果量化为已独立证明。
  2. 程序没有纠正或校验答案位置分布。 createQuestions() 检查数量、题目重复、四个不同选项和唯一正确项,然后把 item.options 按原顺序保存。线上网关 readingCreate() 也按传入数组保存,没有补做位置分散。
  3. 打印入口直接展示原始顺序。 reading-pdf.component.ts:65–68 取回题目后直接 questions.set(questions);模板把数组第 0 项显示成 A。正式产物 chunk-NPVFXZFL.js 行为相同。因此数据库第一项正确会稳定成为打印的 A。
  4. 在线页与打印页存在两套顺序。 在线初次加载及“再做一次”都会打乱题目、选项;正式产物 chunk-KSDV6NJ6.js 也如此。因此现有证据可以直接解释打印/PDF 全 A,但不足以断言在线按钮显示一定全 A。若用户反馈来自在线按钮,须补查具体文章与客户端版本;若来自解析文字,则需重点核对第 5 点。
  5. 解析文字没有随选项移动。 在线页直接显示 question.answer 和 option.answer,其中 A/B/C/D 的文字仍指原顺序。单纯新增洗牌会扩大这个既有错位风险。

线上 PromptTemplate 已写明“正确选项随机分布(避免固定位置模式)”,最后更新于 2026-09-04。故“再加一句随机要求”不能构成可靠修复。11 月 14 日已出现同样分布,不能归因于今天的新发布。

本地复现与边界

读取今天一组真实的五道题,使用项目实际 reading.utils.ts 经 TypeScript 转译后的校验与洗牌函数:

  • 现有完整性检查通过,PDF 原顺序答案为 A A A A A。
  • 按在线页现有处理方式运行 100 次,500 道题的正确位置分布为 117 / 114 / 139 / 130,该轮无全 A 题组。
  • 原始题目未被修改,所有正确选项内容保持一致。

这是代码级复现,未冒充浏览器或实体手机验收;也未逐题审查 AI 答案的教学正确性。不能用“位置异常”推导全部答案内容错误或历史成绩算错。

目标与约束

  • 推荐对每套五题采用随机化的近均衡分布:A/B/C/D 各至少一次,额外一次随机分配;题序与位置不按固定 ABCD 循环。
  • 字母只是显示编号,正确性始终跟随选项内容及 check,禁止仅修改正确答案字母或互换 check。
  • 首次打开、刷新、PDF 预览、导出必须能复现同一版题序和选项顺序;“再做一次”可生成新版本,打印跟随该版本。
  • 已有题目无需重生成;历史作答仍按题目 ID 与所选内容恢复,保留成绩和文章。已下载或已打印的旧 PDF 无法被远程更新,需重新导出。
  • 原始选项顺序保留用于解释旧解析的字母;正常英文单词、Plan A、文章中人名首字母不被误改。
  • 不完整题组继续使用现有保护,不静默补题后覆盖已完成记录。
  • 本次只产出调查和方案;实施阶段再运行以下开发与发布步骤。

Review Focus

  1. 旧题解析里的字母引用,以及无法无歧义识别的自然语言引用。
  2. “再做一次”、刷新、直接打开 PDF、返回在线页时的版本一致性。
  3. 历史成绩恢复、未答完重试、缺题、重复选项与多正确项。
  4. 选项内容依赖位置,如“Both A and B”“以上各项”,不能直接移动导致语义改变。
  5. 云端模板优先于内置模板、旧客户端缓存仍可能继续输出偏置数据。

实施任务

1. 统一题组呈现与解析映射

Files: 新建 projects/xiaoshu-mobile/src/app/features/english-reading/reading-presentation.ts 及对应 .spec.ts。

Interfaces:

  • presentReadingQuestions(questions: ReadingQuestion[], seed: string): ReadingQuestion[]:复制输入,校验完整题组,根据种子产生题序和近均衡位置,移动完整选项对象。
  • remapReadingExplanation(text: string, labels: Readonly<Record<string, string>>): string:仅映射无歧义选项引用;从原数组索引构造旧字母→新字母映射,单次替换,防止 A→B→C 的级联误替换。

  • [ ] 写失败测试:五题原始全 A;同一种子结果稳定;不同种子可产生不同结果;每个字母出现 1–2 次;正确内容、选项解析绑定和原始输入保持不变。

  • [ ] 写失败测试:A项/B项/选项A/option A 同步映射;Plan A 与普通单词保留;题目和各选项的解析都处理。

  • [ ] 写失败测试:不完整、重复内容、多正确项拒绝进入新题组编排;检测位置依赖选项,不直接重排导致含义变化。

  • [ ] 实现共享函数。对不能可靠转换的旧解析或位置依赖题逐题列入复核,不能用宽泛正则改写所有 A/B/C/D,也不能静默删除解释。

  • [ ] 运行专项测试并检查上述不变量后提交本任务文件。

2. 在线练习与 PDF 共用呈现版本

Files: 修改 reading-exercise.component.ts、reading-pdf.component.ts、reading.models.ts、reading.utils.ts 及相应测试;均位于上述 english-reading 目录。

Interfaces: 路由增加非敏感 presentationVersion(默认 v1);共享种子由文章 ID 与该版本组成。使用任务 1 的 presentReadingQuestions(),不再在两个组件内各自安排选项。

  • 写失败测试:同一文章同一版本的在线页、PDF 题目区、PDF 答案区逐题逐选项相同;直接进入未带版本的 PDF 使用默认版本。
  • 写失败测试:“再做一次”建立新版本,写入当前路由并在打印/返回时携带;刷新不改变当前顺序;切换文章不沿用上一文章答题内容。
  • 写失败测试:历史 answer 按题目 ID 和内容恢复,计算成绩与原结果一致;缺题保护与保存失败重试保持正确。
  • 接入共享呈现函数和版本参数,继续按内容保存答案,不修改历史 SurveyLog 数据。
  • 专项测试通过后提交;使用真实题目脱敏夹具在浏览器核对在线与 PDF,覆盖至少一组全 A 和一组含字母解析的旧题。

3. 消除生成示例偏置并加强校验

Files: 修改 english-reading.service.ts、reading-prompts.ts 及相应测试。云端 PromptTemplate 更新通过独立、单记录、带旧值校验的发布步骤执行,不运行会从旧源覆盖全部模板的同步脚本。

Interfaces: 保留现有题目 JSON 字段与接口;新生成题的题干、选项及解释以内容指代答案,不引用会随重排改变的选项字母和位置。

  • 写失败测试:格式示例不再每题固定首项 true;云端模板存在和缺失两条路径都附加“解释不依赖选项字母/位置”的要求。
  • 写失败测试:仅补齐缺失题目、生成重试、保存失败重试不会修改已有题目或破坏五题完整性。
  • 修改示例使用不同正确位置,校验生成结果里的位置引用。格式示例只能降低偏置,最终呈现分布由任务 1 保证。
  • 同步调整内置提示词,并准备云端该条模板的精确补丁和回滚副本;发布前核对模板 updatedAt 与旧内容,避免覆盖他人更新。
  • 专项测试通过后提交,保存脱敏生成样本核对内容正确性及解析独立性。

4. 验收与发布

  • 专项测试:npm run test:mobile:ci -- --include='projects/xiaoshu-mobile/src/app/features/english-reading/**/*.spec.ts',全部通过。
  • 全量移动端回归:npm run test:mobile:ci;构建:npm run build:mobile,均通过。
  • 把今天 21 套题作为私有只读样本验证:每套呈现后无全 A,四个位置分布符合约束,正确内容与原始 check 一致;含字母解析及位置依赖项逐题复核。
  • 浏览器验收在线选择、提交、历史恢复、再做、刷新、预览和 PDF 导出;提交测试使用专用隔离记录,不冒用真实学生成绩。PDF 逐页检查题目、答案和解析,完成至少一次实体手机/微信环境确认再报告相应覆盖。
  • 以发布时实际线上版本为基线,仅发布阅读改动,不能重新带入此前已回滚的性能候选。备份入口、资源与该条模板后进行发布和 CDN 版本核验。
  • 上线后只读观察新生成/呈现题组与错误日志;区分“原始生成位置统计”和“实际呈现位置统计”,不能用前者误判新展示修复失败。
  • 若需回滚,恢复本次前端入口及此次模板补丁;不回滚学生业务数据。先核对线上仍是本次发布,避免覆盖后续发布。

完成判据

相同版本的在线页、PDF 题目和答案逐项一致;五题正确位置符合约束;重排前后正确内容、历史选中内容和成绩一致;所有解析字母指向当前展示选项;旧题得到兼容;专项、全量和浏览器验收均有证据。当前仅调查与方案完成,以上修复与验收尚未执行。