From a39bffa6ff661067724e51655ed6e975443a06dd Mon Sep 17 00:00:00 2001 From: ai_member_only Date: Sat, 16 May 2026 08:10:01 +0800 Subject: [PATCH] auto backup: 2026-05-16 08:10:01 --- MEMORY.md | 6 + .../voice_character_id_mapping.md | 66 +++ .../skills/audit_unit_challenge/SKILL.md | 10 + .../core/unit_challenge_core/SKILL.md | 8 + .../master/unit_challenge_master/SKILL.md | 6 +- .../listening/L1/listening-drag/SKILL.md | 10 + .../listening/L1/listening_matchInfo/SKILL.md | 10 + .../L1/listening_picture_selection/SKILL.md | 10 + .../listening/L2/listening-choicePic/SKILL.md | 10 + .../listening/L2/listening_form_fill/SKILL.md | 10 + .../L2/listening_info_match/SKILL.md | 10 + .../L2/listening_long_conversation/SKILL.md | 10 + .../L2/listening_short_conversation/SKILL.md | 10 + .../reading/common/reading_pic_judge/SKILL.md | 10 + .../reading/common/reading_pic_qa/SKILL.md | 10 + .../questions/reading/reading_cloze/SKILL.md | 10 + .../reading/reading_info_match/SKILL.md | 10 + .../reading/reading_long_passage/SKILL.md | 10 + .../reading/reading_open_fill/SKILL.md | 10 + .../reading/reading_paragraph_match/SKILL.md | 10 + .../reading/reading_pic_judge/SKILL.md | 10 + .../questions/reading/reading_pic_qa/SKILL.md | 10 + .../speaking/L1/speaking_pic_qa/SKILL.md | 10 + .../L1/speaking_pic_recognize/SKILL.md | 10 + .../speaking/L1/speaking_qa/SKILL.md | 10 + .../speaking/L1/speaking_topic/SKILL.md | 10 + .../L2/speaking_topic_discussion/SKILL.md | 10 + .../common/speaking_daily_qa/SKILL.md | 10 + .../writing/common/writing_pic_qa/SKILL.md | 10 + .../writing/writing_email_reply/SKILL.md | 10 + .../questions/writing/writing_pic_qa/SKILL.md | 10 + .../writing/writing_picture_writing/SKILL.md | 10 + .../skills/component-design/SKILL.md | 10 + .../dialogue-interaction-config/SKILL.md | 10 + .../script-component-production/SKILL.md | 2 +- .../vala-interactive-components/SKILL.md | 10 + .../interactive-component-json/SKILL.md | 7 + .../kids-english-script-production/SKILL.md | 1 + memory/.dreams/events.jsonl | 2 + memory/.dreams/short-term-recall.json | 76 ++- .../audit_listening_explanation_results.json | 51 ++ scripts/audit_explanation.py | 298 ++++++++++ scripts/audit_listening_explanation.py | 547 ++++++++++++++++++ scripts/audit_listening_explanation_v2.py | 448 ++++++++++++++ scripts/inject_text_rules.py | 180 ++++++ skills/audit_l1_config/SKILL.md | 10 + .../cambridge-yle-ket-exam-library/SKILL.md | 10 + skills/core-content-json-standard/SKILL.md | 6 + skills/dialogue-choose-config/SKILL.md | 10 + .../dialogue-core-navigation-config/SKILL.md | 10 + .../dialogue-fill-in-blanks-config/SKILL.md | 10 + .../SKILL.md | 10 + skills/dialogue-reading-config/SKILL.md | 10 + .../SKILL.md | 10 + .../SKILL.md | 10 + skills/task-router/SKILL.md | 10 + 56 files changed, 2106 insertions(+), 8 deletions(-) create mode 100644 business_knowledge/voice_character_id_mapping.md create mode 100644 output/audit_listening_explanation_results.json create mode 100644 scripts/audit_explanation.py create mode 100644 scripts/audit_listening_explanation.py create mode 100644 scripts/audit_listening_explanation_v2.py create mode 100644 scripts/inject_text_rules.py diff --git a/MEMORY.md b/MEMORY.md index 8ead0b5..75b0aef 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -86,6 +86,12 @@ - 对话节奏快,每2-3句台词对应一个剧情节点或互动环节 - 弱化说教感,所有指令和引导都以自然对话的方式呈现 +### 【教研规则】文本输出格式规范(强制执行) +1. **禁止 Markdown 标记**:生成单元挑战的音频文本、阅读文本等任何内容文本时,禁止使用 `**` `*` `__` `_` 等 Markdown 加粗/斜体标识,也禁止使用 `#` `>` `-` 等块级 Markdown 语法。输出纯文本即可。 +2. **适用场景**:单元挑战所有文本输出(音频台词、阅读理解文章、写作提示、口语话题等),以及任何需要嵌入题目 jsonData 的文本内容 +3. **英式拼写优先**:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写 +4. **标点符号规范**:严格区分全角/半角符号,中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用 + ### 【教研规则】剧本定稿审校通用规范 1. 标点符号规范:禁止使用「~」「!!!」等非标准标点,统一使用标准英文标点符号 2. 核心句型呈现规范:核心句型第一次出现时需清晰、完整、独立呈现,不与其他干扰信息混杂 diff --git a/business_knowledge/voice_character_id_mapping.md b/business_knowledge/voice_character_id_mapping.md new file mode 100644 index 0000000..d236ce9 --- /dev/null +++ b/business_knowledge/voice_character_id_mapping.md @@ -0,0 +1,66 @@ +# 音色角色 ID 映射表 + +来源:飞书知识库「音色表 for 出题」- Sheet1 角色表 + Sheet2 音色库 +更新时间:2026-05-15 +用途:单元挑战音频生成时,角色与音色ID的对应查询 + +## 角色 → 音色ID 映射 + +| 角色 | 英文名 | 类型 | 音色ID (数值) | Sheet2 对应 voice_id | +|------|--------|------|:-----------:|---------------------| +| 用户_男 | User_boy | 男童音 | 23 | clever_boy | +| 用户_女 | User_girl | 女童音 | 47 | girl11kim | +| 旁白_男 | Narration_male | 成年男 | 11 | audiobook_male_1 | +| 旁白_女 | Narration_female | 成年女 | 10 | presenter_female | +| 小雨 | Brainy | 成年女 | 46 | Serene_Woman | +| 本 | Ben | 男童音 | 331 | *(未收录到Sheet2)* | +| 本爸爸 | Ben's Dad | 成年男 | 232 | *(未收录到Sheet2)* | +| 谨慎小子 | Otis | 男童音 | 255 | *(未收录到Sheet2)* | +| 傲娇女侠 | Skylar | 女童音 | 364 | *(未收录到Sheet2)* | +| 丽贝卡 | Rebecca | 女童音 | 36 | danya_xuejie | +| 灵犀 | Kevin | 男童音 | 51 | so-1075-m-7 | +| 托马斯 | Thomas | 男童音 | 58 | so-3631-f-9 | +| 俱乐部外路人A | Tommy | 男童音 | 290 | *(未收录到Sheet2)* | +| 选手A | Jeson | 男童音 | 4 | male-qn-daxuesheng | +| 选手B | Vivian | 女童音 | 332 | *(未收录到Sheet2)* | + +## 按维度分类速查 + +### 成人男 +- 旁白_男 (Narration_male) → 11 → audiobook_male_1 +- 本爸爸 (Ben's Dad) → 232 + +### 成人女 +- 旁白_女 (Narration_female) → 10 → presenter_female +- 小雨 (Brainy) → 46 → Serene_Woman + +### 男童 +- 用户_男 (User_boy) → 23 → clever_boy +- 本 (Ben) → 331 +- 谨慎小子 (Otis) → 255 +- 灵犀 (Kevin) → 51 → so-1075-m-7 +- 托马斯 (Thomas) → 58 → so-3631-f-9 +- 俱乐部外路人A (Tommy) → 290 +- 选手A (Jeson) → 4 → male-qn-daxuesheng + +### 女童 +- 用户_女 (User_girl) → 47 → girl11kim +- 傲娇女侠 (Skylar) → 364 +- 丽贝卡 (Rebecca) → 36 → danya_xuejie +- 选手B (Vivian) → 332 + +## 核心通用角色(优先级最高) + +| 角色 | 音色ID | 说明 | +|------|:-----:|------| +| 用户_男 | 23 | 默认男童音 | +| 用户_女 | 47 | 默认女童音 | +| 旁白_男 | 11 | 默认成年男旁白 | +| 旁白_女 | 10 | 默认成年女旁白 | +| 小雨 | 46 | 主要女性角色 | + +## 备注 + +- Sheet1 音色ID 数值 >75 的角色(331/232/255/364/290/332),其音色ID未在 Sheet2 通用音色库中收录,可能对应独立音色系统 +- Sheet2 中另有大量通用音色(青涩青年、御姐、主持人口音等)可供非角色绑定的音频场景使用 +- 单元挑战出题时优先使用上述映射表中的角色和对应ID diff --git a/business_production/单元挑战/skills/audit_unit_challenge/SKILL.md b/business_production/单元挑战/skills/audit_unit_challenge/SKILL.md index f2764af..e5e5094 100644 --- a/business_production/单元挑战/skills/audit_unit_challenge/SKILL.md +++ b/business_production/单元挑战/skills/audit_unit_challenge/SKILL.md @@ -47,6 +47,16 @@ description: 单元挑战所有题型自动化审校技能。覆盖听力P1-P7 | 口语 P2 | 话题讨论 | `tblGoWYBmVI0IrvQ` | 题目集合 ID, 题目1, 题目2, 图片描述, jsonData, dataStatus, 推送到服务端, 审核结果 | | 口语 P3-P5 | (待补充) | (待补充) | — | + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 审校流程 ``` diff --git a/business_production/单元挑战/skills/unit_challenge/core/unit_challenge_core/SKILL.md b/business_production/单元挑战/skills/unit_challenge/core/unit_challenge_core/SKILL.md index 56beb79..3110e86 100644 --- a/business_production/单元挑战/skills/unit_challenge/core/unit_challenge_core/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/core/unit_challenge_core/SKILL.md @@ -25,6 +25,14 @@ description: 单元挑战核心层(永久固定,无重大升级不改动) - ✅ 暂不对接其他外部系统(CMS/教研系统等) - ✅ 所有输出仅支持本地文件、飞书多维表两种形式 - ✅ 所有数据存储在当前工作区内,不对外传输 +## 文本输出规范(强制约束,覆盖所有题型) + +以下规则适用于单元挑战所有题型的文本输出(音频台词、阅读文章、写作提示、口语话题等 jsondata 内容): + +1. 禁止 Markdown 标记:禁止使用 `**` `*` `__` `_` 等加粗/斜体标识,也禁止使用 `#` `>` `-` 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 改动规则 - 非重大规则升级/词库全量更新,禁止修改本层内容 - 单个题型调优仅修改对应题型Skill,不得改动核心层 diff --git a/business_production/单元挑战/skills/unit_challenge/master/unit_challenge_master/SKILL.md b/business_production/单元挑战/skills/unit_challenge/master/unit_challenge_master/SKILL.md index baca30c..466fceb 100644 --- a/business_production/单元挑战/skills/unit_challenge/master/unit_challenge_master/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/master/unit_challenge_master/SKILL.md @@ -25,11 +25,15 @@ description: 单元挑战总控调度大脑,统一接收所有单元挑战生 - L2阶段需求→分发到L2执行器,调用对应L2专属/共用题型技能 - 多题型组合需求→按题型分别分发,并行生产 ### 步骤4:质量校验(自动执行) -所有生成的题目自动经过三层质量校验: +所有生成的题目自动经过五层质量校验: 1. 超纲校验:所有词汇必须属于对应阶段词库 2. 格式校验:符合对应题型输出规范 3. 难度校验:听力文本长度/选项复杂度等符合难度要求 4. 去重校验:同一题包内知识点不重复考察 +5. 文本规范校验(强制): + - 禁止 Markdown 标记(`**` `*` `__` `_` `#` `>` `-`),所有文本纯文本输出 + - 英式拼写优先(colour/centre/travelling 等) + - 标点符号规范:中文全角(,。!?),英文半角(. , ! ?),不混用 ### 步骤5:结果输出 按照要求格式输出,支持: - 教研文档格式:带解析、能力项、评分标准 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening-drag/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening-drag/SKILL.md index a410f1c..04161b2 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening-drag/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening-drag/SKILL.md @@ -3,6 +3,16 @@ name: listening-drag description: K12英语听力拖拽题(Listening Drag & Drop)标准化设计、生产、审校工具。别名:听力Part1图片连线、听力Part1人物匹配,三者为同一题型。使用场景:(1) 根据给定知识点、难度等级、人名列表生成符合教研规范的听力拖拽题;(2) 校验听力拖拽题的格式、难度匹配、内容合规性;(3) 批量生产听力拖拽题内容。触发关键词:听力拖拽题、listening drag、拖拽题生产、听力Part1图片连线、听力Part1人物匹配、人物匹配题生产、图片连线题设计 --- # Listening Drag 听力拖拽题生产技能 + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 核心功能 标准化生成符合L1 6个阶段要求的听力拖拽题【阶段归属:L1专属】,自动绑定对应能力标签,支持批量生产与合规校验。 ## 难度对应关系(已适配新的阶段划分) diff --git a/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening_matchInfo/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening_matchInfo/SKILL.md index a17a9ce..21aa79f 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening_matchInfo/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening_matchInfo/SKILL.md @@ -2,6 +2,16 @@ name: listening_matchInfo description: K12英语听力信息匹配题标准化设计、生产、审校工具。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的听力信息匹配题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产听力信息匹配题。触发关键词:听力信息匹配、listening match info、信息匹配题生产 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Listening Match Info 听力信息匹配题生产技能 ## 题型说明 听力信息匹配题:学生听一段对话或文本,然后将听到的信息与选项列表匹配,通常涉及人物、物品、地点等信息的对应关系。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening_picture_selection/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening_picture_selection/SKILL.md index 73d5e47..3b65513 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening_picture_selection/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/listening/L1/listening_picture_selection/SKILL.md @@ -2,6 +2,16 @@ name: listening_picture_selection description: K12英语听力选图题标准化设计、生产、审校工具。对应题型:L1 - Starters - 听力 Part6 听力选图,考察核心能力:图片信息识别、听力信息匹配、快速反应。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的听力选图题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产听力选图题。触发关键词:听力选图、选图题、listening picture selection、听力Part6选图、图片匹配题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Listening Picture Selection 听力选图题生产技能 ## 题型说明 本技能对应官方题型:**L1 - Starters - 听力 Part6 听力选图【阶段归属:L1专属】**,考察核心能力为**图片信息识别(听力信息匹配)**:学生听5-6个单句/短对话,每个对应一组图片,选出与听力内容匹配的图片,考察对图片信息和听力信息的快速匹配能力。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening-choicePic/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening-choicePic/SKILL.md index 28d9063..b22d578 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening-choicePic/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening-choicePic/SKILL.md @@ -2,6 +2,16 @@ name: listening-choicePic description: K12英语听力三选一图片选择题标准化设计、生产、审校工具。对应题型:L1 - Starters - 听力 Part3 三选一图片选择,考察核心能力:显性事实理解(单句信息点抓取)。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的听力三选一题目;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产听力三选一题目。触发关键词:听力三选一、图片选择题、listening choice pic、听力Part3三选一、单句信息点抓取题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Listening ChoicePic 听力三选一图片选择题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 听力 Part3 三选一图片选择【阶段归属:L2专属】**,考察核心能力为**显性事实理解(单句信息点抓取)**:学生听单句听力内容,从3张图片选项中选出与听力内容匹配的正确答案。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_form_fill/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_form_fill/SKILL.md index 7050bf6..81d2358 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_form_fill/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_form_fill/SKILL.md @@ -2,6 +2,16 @@ name: listening_form_fill description: K12英语听力表格填空题标准化设计、生产、审校工具。对应题型:L1 - Starters - 听力 Part2 表格填空,考察核心能力:信息抓取、拼写准确性、短时记忆。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的听力表格填空题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产听力表格填空题。触发关键词:听力表格填空、表格填空题、listening form fill、听力Part2表格填空、信息抓取填空题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Listening Form Fill 听力表格填空题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 听力 Part2 表格填空【阶段归属:L2专属】**,考察核心能力为**信息抓取(关键词识别+拼写准确性)**:学生听1-2段短对话/独白,提取关键信息填写表格中空缺的内容,考察词汇拼写、数字识别、信息匹配能力。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_info_match/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_info_match/SKILL.md index 65d0e6b..70e3a7f 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_info_match/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_info_match/SKILL.md @@ -2,6 +2,16 @@ name: listening_info_match description: K12英语听力信息匹配题标准化设计、生产、审校工具。对应题型:L2 - Movers - 听力 Part5 信息匹配,考察核心能力:信息关联、多任务处理、干扰抑制。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的听力信息匹配题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产听力信息匹配题。触发关键词:听力信息匹配、信息匹配题、listening info match、听力Part5信息匹配、多信息关联题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Listening Info Match 听力信息匹配题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 听力 Part5 信息匹配【阶段归属:L2专属】**,考察核心能力为**信息关联(多任务处理+干扰抑制)**:学生听1段长对话/独白,将左右两栏的相关信息进行匹配,考察对多个信息点的关联、记忆和区分能力。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_long_conversation/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_long_conversation/SKILL.md index eb01bfa..d523c10 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_long_conversation/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_long_conversation/SKILL.md @@ -2,6 +2,16 @@ name: listening_long_conversation description: K12英语听力长对话选择题标准化设计、生产、审校工具。对应题型:L2 - Movers - 听力 Part3 长对话选择,考察核心能力:逻辑理解、信息整合、干扰抑制。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的听力长对话选择题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产听力长对话选择题。触发关键词:听力长对话选择、长对话选择题、listening long conversation、听力Part3长对话、逻辑理解题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Listening Long Conversation 听力长对话选择题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 听力 Part3 长对话选择【阶段归属:L2专属】**,考察核心能力为**逻辑理解(信息整合+干扰抑制)**:学生听1段3-5轮的长对话,回答3-4道选择题,考察对对话整体逻辑、隐含信息、因果关系的理解能力。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_short_conversation/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_short_conversation/SKILL.md index 9929172..d331e19 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_short_conversation/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/listening/L2/listening_short_conversation/SKILL.md @@ -2,6 +2,16 @@ name: listening_short_conversation description: K12英语听力短对话选择题标准化设计、生产、审校工具。对应题型:L1 - Starters - 听力 Part4 短对话选择,考察核心能力:信息抓取、快速反应、场景理解。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的听力短对话选择题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产听力短对话选择题。触发关键词:听力短对话选择、短对话选择题、listening short conversation、听力Part4短对话、场景理解题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Listening Short Conversation 听力短对话选择题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 听力 Part4 短对话选择【阶段归属:L2专属】**,考察核心能力为**场景理解(快速信息抓取+反应)**:学生听多段1-2轮的短对话,每段对话对应1道选择题,考察对常见场景、日常用语的理解能力。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/reading/common/reading_pic_judge/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/reading/common/reading_pic_judge/SKILL.md index 36e4985..1db989f 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/reading/common/reading_pic_judge/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/reading/common/reading_pic_judge/SKILL.md @@ -2,6 +2,16 @@ name: reading_pic_judge description: K12英语阅读看图判断题标准化设计、生产、审校工具。对应题型:阅读 - 看图判断题【阶段归属:L1&L2共用,通过难度参数区分】。学生逐张观察图片,判断对应的描述句子是否正确(Yes/No)。考察核心能力:图文匹配、阅读审题。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的阅读看图判断题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产阅读看图判断题。触发关键词:阅读看图判断、看图判断、reading pic judge、YesNo单图题、图文匹配题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Reading Pic Judge 阅读看图判断题生产技能 ## 题型说明 本技能对应题型:**阅读 - 看图判断题【阶段归属:L1&L2共用,通过难度参数区分】**,考察核心能力为**图文匹配(阅读理解+图片信息提取)**:学生逐张观察单张图片,判断对应的描述句子是否正确(Yes/No)。不同于reading_pic_qa(多题共享一张大图),本题型每道题独立配图。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/reading/common/reading_pic_qa/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/reading/common/reading_pic_qa/SKILL.md index 5cf9711..0ea1dd5 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/reading/common/reading_pic_qa/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/reading/common/reading_pic_qa/SKILL.md @@ -2,6 +2,16 @@ name: reading_pic_qa description: K12英语阅读看图回答题标准化设计、生产、审校工具。对应题型:阅读 - 看图回答题【阶段归属:L1&L2共用,通过难度参数区分】。学生阅读描述性句子,观察场景图片,判断句子描述是否与图片匹配(Yes/No)。考察核心能力:图文匹配、阅读审题。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的阅读看图回答题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产阅读看图回答题。触发关键词:阅读看图回答、看图回答、reading pic qa、YesNo看图题、图文匹配题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Reading Pic QA 阅读看图回答题生产技能 ## 题型说明 本技能对应题型:**阅读 - 看图回答题【阶段归属:L1&L2共用,通过难度参数区分】**,考察核心能力为**图文匹配(阅读理解+图片信息提取)**:学生阅读多个描述性句子,观察同一张场景图片,逐个判断句子描述是否与图片匹配(Yes/No)。题目需搭配完整的场景图片(textImage),所有小题共享同一张大图。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_cloze/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_cloze/SKILL.md index 4653623..ce5b9f9 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_cloze/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_cloze/SKILL.md @@ -2,6 +2,16 @@ name: reading_cloze description: K12英语阅读完形填空题标准化设计、生产、审校工具。对应题型:L2 - Movers - 阅读 Part4 完形填空,考察核心能力:词汇运用、语法判断、上下文逻辑理解。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的阅读完形填空题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产阅读完形填空题。触发关键词:阅读完形填空、完形填空题、reading cloze、阅读Part4完形填空、词汇运用题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Reading Cloze 阅读完形填空题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 阅读 Part4 完形填空【阶段归属:L2专属】**,考察核心能力为**词汇运用(语法判断+上下文逻辑理解)**:学生阅读1篇80-150词的短文,文中有3-5个空缺,每个空缺从3个选项中选择正确的单词填入,考察词汇、语法和上下文理解能力。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_info_match/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_info_match/SKILL.md index e8c167c..d740ee1 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_info_match/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_info_match/SKILL.md @@ -2,6 +2,16 @@ name: reading_info_match description: K12英语阅读信息匹配题标准化设计、生产、审校工具。对应题型:L1 - Starters - 阅读 Part1 信息匹配,考察核心能力:信息抓取、快速阅读、图文匹配。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的阅读信息匹配题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产阅读信息匹配题。触发关键词:阅读信息匹配、信息匹配题、reading info match、阅读Part1信息匹配、图文匹配题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Reading Info Match 阅读信息匹配题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 阅读 Part1 信息匹配【阶段归属:L2专属】**,考察核心能力为**信息抓取(快速阅读+图文匹配)**:学生阅读5-6个简短文本(标识/告示/短句),与对应的图片/标题进行匹配,考察快速抓取关键信息和图文匹配能力。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_long_passage/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_long_passage/SKILL.md index 9571a61..4b08f29 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_long_passage/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_long_passage/SKILL.md @@ -2,6 +2,16 @@ name: reading_long_passage description: K12英语阅读长文选择题标准化设计、生产、审校工具。对应题型:L2 - Movers - 阅读 Part3 长文选择,考察核心能力:篇章理解、细节定位、推理判断。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的阅读长文选择题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产阅读长文选择题。触发关键词:阅读长文选择、长文选择题、reading long passage、阅读Part3长文选择、篇章理解题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Reading Long Passage 阅读长文选择题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 阅读 Part3 长文选择【阶段归属:L2专属】**,考察核心能力为**篇章理解(细节定位+推理判断)**:学生阅读1篇100-200词的短文,回答3-4道选择题,考察对篇章整体内容、细节信息、推理判断的能力。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_open_fill/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_open_fill/SKILL.md index 278edfe..4afe0ef 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_open_fill/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_open_fill/SKILL.md @@ -2,6 +2,16 @@ name: reading_open_fill description: K12英语阅读开放填空题标准化设计、生产、审校工具。对应题型:L2 - Movers - 阅读 Part5 开放填空,考察核心能力:信息提取、词汇拼写、语法正确性。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的阅读开放填空题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产阅读开放填空题。触发关键词:阅读开放填空、开放填空题、reading open fill、阅读Part5开放填空、拼写题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Reading Open Fill 阅读开放填空题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 阅读 Part5 开放填空【阶段归属:L2专属】**,考察核心能力为**信息提取(词汇拼写+语法正确性)**:学生阅读1篇短文/通知/表格,根据要求填写3-5个空缺的单词,无选项提示,考察信息提取、词汇拼写和语法正确性。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_paragraph_match/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_paragraph_match/SKILL.md index 4bdc8b6..0ef6551 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_paragraph_match/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_paragraph_match/SKILL.md @@ -2,6 +2,16 @@ name: reading_paragraph_match description: K12英语阅读段落匹配题标准化设计、生产、审校工具。对应题型:L2 - Movers - 阅读 Part2 段落匹配,考察核心能力:主旨理解、信息归纳、快速阅读。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的阅读段落匹配题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产阅读段落匹配题。触发关键词:阅读段落匹配、段落匹配题、reading paragraph match、阅读Part2段落匹配、主旨归纳题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Reading Paragraph Match 阅读段落匹配题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 阅读 Part2 段落匹配【阶段归属:L2专属】**,考察核心能力为**主旨理解(信息归纳+快速阅读)**:学生阅读4-5个简短段落,与对应的段落标题/主旨句进行匹配,考察归纳段落主旨和抓取核心信息的能力。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_pic_judge/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_pic_judge/SKILL.md index 1ff178a..db22651 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_pic_judge/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_pic_judge/SKILL.md @@ -2,6 +2,16 @@ name: reading_pic_judge description: K12英语阅读看图判断题标准化设计、生产、审校工具。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的阅读看图判断题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产阅读看图判断题。触发关键词:阅读看图判断、reading pic judge、看图判断题生产 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Reading Pic Judge 阅读看图判断题生产技能 ## 题型说明 阅读看图判断题:学生查看图片,然后回答关于图片内容的判断题,通常是Yes/No问题。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_pic_qa/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_pic_qa/SKILL.md index a0ae44c..1305675 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_pic_qa/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/reading/reading_pic_qa/SKILL.md @@ -2,6 +2,16 @@ name: reading_pic_qa description: K12英语阅读看图回答题标准化设计、生产、审校工具。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的阅读看图回答题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产阅读看图回答题。触发关键词:阅读看图回答、reading pic qa、看图回答题生产 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Reading Pic QA 阅读看图回答题生产技能 ## 题型说明 阅读看图回答题:学生查看图片,然后回答关于图片内容的开放性问题。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_pic_qa/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_pic_qa/SKILL.md index 0aadf98..4199d5a 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_pic_qa/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_pic_qa/SKILL.md @@ -2,6 +2,16 @@ name: speaking_pic_qa description: K12英语口语看图说话题标准化设计、生产、审校工具。对应题型:L1 - Starters - 口语 Part2 看图问答,考察核心能力:口语表达、图片信息提取、场景词汇运用。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的口语看图问答题目;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产口语看图问答题目。触发关键词:口语看图说话、看图问答、speaking pic qa、口语Part2看图题、图片口语输出题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Speaking Pic QA 口语看图说话题生产技能 ## 题型说明 本技能对应官方题型:**L1 - Starters - 口语 Part2 看图问答【阶段归属:L1专属】**,考察核心能力为**口语表达(图片信息提取+场景词汇运用)**:学生观察指定场景图片,根据问题提示口头输出对应答案,考察词汇储备、发音准确性、表达流畅度。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_pic_recognize/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_pic_recognize/SKILL.md index d400b73..87bf307 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_pic_recognize/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_pic_recognize/SKILL.md @@ -2,6 +2,16 @@ name: speaking_pic_recognize description: K12英语口语看图识物题标准化设计、生产、审校工具。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的口语看图识物题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产口语看图识物题。触发关键词:口语看图识物、speaking pic recognize、看图识物题生产 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Speaking Pic Recognize 口语看图识物题生产技能 ## 题型说明 口语看图识物题:学生查看图片,然后描述或识别图片中的物品。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_qa/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_qa/SKILL.md index a752429..77ab90a 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_qa/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_qa/SKILL.md @@ -2,6 +2,16 @@ name: speaking_qa description: K12英语口语日常问答题标准化设计、生产、审校工具。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的口语日常问答题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产口语日常问答题。触发关键词:口语问答、speaking qa、日常问答题生产 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Speaking QA 口语日常问答题生产技能 ## 题型说明 口语日常问答题:学生回答一系列日常问题,考察口语表达能力。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_topic/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_topic/SKILL.md index de96643..f5d6d1a 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_topic/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/speaking/L1/speaking_topic/SKILL.md @@ -2,6 +2,16 @@ name: speaking_topic description: K12英语口语话题讨论题标准化设计、生产、审校工具。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的口语话题讨论题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产口语话题讨论题。触发关键词:口语话题讨论、speaking topic、话题讨论题生产 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Speaking Topic 口语话题讨论题生产技能 ## 题型说明 口语话题讨论题:学生基于图片或描述讨论相关话题。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/speaking/L2/speaking_topic_discussion/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/speaking/L2/speaking_topic_discussion/SKILL.md index f4796fc..cbf6e75 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/speaking/L2/speaking_topic_discussion/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/speaking/L2/speaking_topic_discussion/SKILL.md @@ -2,6 +2,16 @@ name: speaking_topic_discussion description: K12英语口语话题讨论题标准化设计、生产、审校工具。对应题型:L2 - Movers - 口语 Part2 话题讨论,考察核心能力:口语表达、逻辑组织、观点阐述。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的口语话题讨论题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产口语话题讨论题。触发关键词:口语话题讨论、话题讨论题、speaking topic discussion、口语Part2话题讨论、观点表达题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Speaking Topic Discussion 口语话题讨论题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 口语 Part2 话题讨论【阶段归属:L2专属】**,考察核心能力为**口语表达(逻辑组织+观点阐述)**:学生根据给定话题,进行1-2分钟的口头阐述,考察词汇运用、逻辑连贯、观点表达能力。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/speaking/common/speaking_daily_qa/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/speaking/common/speaking_daily_qa/SKILL.md index 87cb0d7..82dcfdd 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/speaking/common/speaking_daily_qa/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/speaking/common/speaking_daily_qa/SKILL.md @@ -2,6 +2,16 @@ name: speaking_daily_qa description: K12英语口语日常回答题标准化设计、生产、审校工具。对应题型:L1 - Starters - 口语 Part1 日常回答,考察核心能力:口语表达、日常用语运用、快速反应。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的口语日常回答题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产口语日常回答题。触发关键词:口语日常回答、日常问答题、speaking daily qa、口语Part1日常回答、日常口语表达题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Speaking Daily QA 口语日常回答题生产技能 ## 题型说明 本技能对应官方题型:**口语 Part1 日常回答【阶段归属:L1&L2共用,通过难度参数区分】**,考察核心能力为**口语表达(日常用语运用+快速反应)**:学生回答3-4个日常问题,每个问题回答1-3句话,考察日常词汇、句式的运用能力和表达流畅度。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/writing/common/writing_pic_qa/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/writing/common/writing_pic_qa/SKILL.md index 4f5ac07..ba27ee8 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/writing/common/writing_pic_qa/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/writing/common/writing_pic_qa/SKILL.md @@ -2,6 +2,16 @@ name: writing_pic_qa description: K12英语写作看图回答题标准化设计、生产、审校工具。对应题型:写作 - 看图回答题【阶段归属:L1&L2共用,通过难度参数区分】。学生观察图片,根据提示问题写出答案,提供提示答案开头辅助填空。考察核心能力:图文匹配、书写表达。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的写作看图回答题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产写作看图回答题;(4) 产出后自动写入飞书多维表格。触发关键词:写作看图回答、看图写作、writing pic qa、看图写词、书写表达题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Writing Pic QA 写作看图回答题生产技能 ## 一、题型说明 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_email_reply/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_email_reply/SKILL.md index fe86c63..a385c57 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_email_reply/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_email_reply/SKILL.md @@ -2,6 +2,16 @@ name: writing_email_reply description: K12英语写作邮件回复题标准化设计、生产、审校工具。对应题型:L2 - Movers - 写作 Part1 邮件回复,考察核心能力:书面表达、格式规范、信息提取。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的写作邮件回复题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产写作邮件回复题。触发关键词:写作邮件回复、邮件回复题、writing email reply、写作Part1邮件回复、应用文写作题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Writing Email Reply 写作邮件回复题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 写作 Part1 邮件回复【阶段归属:L2专属】**,考察核心能力为**书面表达(格式规范+信息提取)**:学生阅读一封简短邮件,根据要求写20-50词的回复邮件,考察邮件格式、信息完整性、语言正确性。 diff --git a/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_pic_qa/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_pic_qa/SKILL.md index 6c1fb52..5b9f82a 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_pic_qa/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_pic_qa/SKILL.md @@ -2,6 +2,16 @@ name: writing_pic_qa description: K12英语写作看图回答题标准化设计、生产、审校工具。完整规范见 common/writing_pic_qa/SKILL.md。触发关键词:写作看图回答、writing pic qa、看图回答题生产 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Writing Pic QA 写作看图回答题生产技能 > 📌 **完整生产规范请参阅:** `common/writing_pic_qa/SKILL.md` diff --git a/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_picture_writing/SKILL.md b/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_picture_writing/SKILL.md index 13cbc8a..86fe9a7 100644 --- a/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_picture_writing/SKILL.md +++ b/business_production/单元挑战/skills/unit_challenge/questions/writing/writing_picture_writing/SKILL.md @@ -2,6 +2,16 @@ name: writing_picture_writing description: K12英语写作看图写作题标准化设计、生产、审校工具。对应题型:L2 - Movers - 写作 Part2 看图写作,考察核心能力:书面表达、图片观察、逻辑组织。使用场景:(1) 根据给定知识点、难度等级生成符合教研规范的写作看图写作题;(2) 校验题目格式、难度匹配、内容合规性;(3) 批量生产写作看图写作题。触发关键词:写作看图写作、看图写作题、writing picture writing、写作Part2看图写作、看图写话题 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Writing Picture Writing 写作看图写作题生产技能 ## 题型说明 本技能对应官方题型:**L2 - Movers - 写作 Part2 看图写作【阶段归属:L2专属】**,考察核心能力为**书面表达(图片观察+逻辑组织)**:学生根据1-3张图片的提示,写3-5句话的短文,考察图片信息提取、语言组织、逻辑连贯能力。 diff --git a/business_production/组件生产/skills/component-design/SKILL.md b/business_production/组件生产/skills/component-design/SKILL.md index 9fb388e..e600966 100644 --- a/business_production/组件生产/skills/component-design/SKILL.md +++ b/business_production/组件生产/skills/component-design/SKILL.md @@ -4,6 +4,16 @@ version: 1.2.0 description: 教研互动组件设计规范(结构化文本格式,不涉及JSON)。触发方式:(1) `/组件生产 --feishu-url <链接>` (2) 飞书链接 + "组件"/"设计组件"/"组件回填"。不会误触发:仅含"互动"不触发;含"组件配置-json"不触发(属于 interactive-component-json 技能)。标准化组件生产流程:设计→生成(结构化文本)→校验→回填。 --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # SKILL.md - 教研互动组件设计规范 ## ⚡ 触发方式 diff --git a/business_production/组件生产/skills/dialogue-interaction-config/SKILL.md b/business_production/组件生产/skills/dialogue-interaction-config/SKILL.md index 2bfef91..4b5b4bf 100644 --- a/business_production/组件生产/skills/dialogue-interaction-config/SKILL.md +++ b/business_production/组件生产/skills/dialogue-interaction-config/SKILL.md @@ -7,6 +7,16 @@ metadata: domains: ["教研生产", "互动组件配置"] --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # 对话类互动组件配置规范 本技能定义6类对话类互动组件的配置标准、格式要求和校验规则,所有对话类互动必须严格遵循此规范生产。 diff --git a/business_production/组件生产/skills/script-component-production/SKILL.md b/business_production/组件生产/skills/script-component-production/SKILL.md index c09eb50..3dca8c6 100644 --- a/business_production/组件生产/skills/script-component-production/SKILL.md +++ b/business_production/组件生产/skills/script-component-production/SKILL.md @@ -25,7 +25,7 @@ description: 剧本互动组件内容生产/审校/回填技能(不涉及JSON - ✅ **智能组件识别**:读取剧本sheet,根据列A「类型」字段识别组件行(互动 / 核心互动-xxx) - ✅ **组件类型自动匹配**:根据剧情上下文、前后台词自动匹配27种中互动或14种核心互动类型 - ✅ **组件内容生成**:调用LLM生成结构化文本格式的组件内容(【任务标题】【资源配置】... 等字段) -- ✅ **自动审校**:校验ID格式/字段完整性/题型匹配/知识点一致性/格式规范 +- ✅ **自动审校**:校验ID格式/字段完整性/题型匹配/知识点一致性/格式规范/文本规范(禁止Markdown、英式拼写、标点符号) - ✅ **飞书回填**:将生成的组件内容写入剧本sheet的「组件配置」列(列G),**以结构化文本格式存储,非JSON** --- diff --git a/business_production/组件生产/skills/vala-interactive-components/SKILL.md b/business_production/组件生产/skills/vala-interactive-components/SKILL.md index 5856b35..ae40c59 100644 --- a/business_production/组件生产/skills/vala-interactive-components/SKILL.md +++ b/business_production/组件生产/skills/vala-interactive-components/SKILL.md @@ -5,6 +5,16 @@ description: "瓦拉英语互动组件官方配置库,包含所有中互动、 metadata: source: "飞书知识库 03 内容配置相关/配置多维表格/互动内容库" last_update: "2026-04-03" + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + --- ## 互动组件分类 diff --git a/business_production/组件配置/interactive-component-json/SKILL.md b/business_production/组件配置/interactive-component-json/SKILL.md index 85c25ae..6356986 100644 --- a/business_production/组件配置/interactive-component-json/SKILL.md +++ b/business_production/组件配置/interactive-component-json/SKILL.md @@ -23,6 +23,13 @@ metadata: # 互动组件配置JSON生成器 +## 文本输出规范(jsonData 内容强制遵守) + +所有生成的 JSON 配置中,任何嵌入的文本内容(题目、选项、解析、台词等)必须遵守: +1. 禁止 Markdown 标记(`**` `*` `__` `_` `#` `>` `-`),纯文本输出 +2. 英式拼写优先(colour/centre/travelling 等) +3. 标点符号规范:英文半角(. , ! ?),中文全角(,。!?),不混用 + ## 触发场景 用户发送以下格式的消息时触发完整处理流水线: diff --git a/business_production/英文台词/skills/kids-english-script-production/SKILL.md b/business_production/英文台词/skills/kids-english-script-production/SKILL.md index d3c8e3d..fcf0458 100644 --- a/business_production/英文台词/skills/kids-english-script-production/SKILL.md +++ b/business_production/英文台词/skills/kids-english-script-production/SKILL.md @@ -24,6 +24,7 @@ description: 用英语母语儿童思维生成自然地道的分级英文台词 - ✅ 英语思维重构:不是翻译,而是用英语母语儿童的思维方式重构意群,生成自然地道的英文 - ✅ 分级生成:支持4个难度等级(S1-S4),完全匹配4-8岁不同水平儿童 - ✅ 自动校验:内置句长/连接词/从句/时态/超纲词/重复等多维度校验+L1核心词表 +- ✅ 文本规范校验:禁止 Markdown 标记、英式拼写优先(colour/centre/travelling)、英文半角标点 - ✅ 自动修正:校验不通过时自动触发LLM修正,无需手动干预 - ✅ 科幻词自动降级:内置可配置科幻词映射表,复杂词汇自动转换成儿童易懂表达 - ✅ 批量处理:支持单个文件/目录批量处理,自动保存结果到指定路径 diff --git a/memory/.dreams/events.jsonl b/memory/.dreams/events.jsonl index da27ae8..d51fa88 100644 --- a/memory/.dreams/events.jsonl +++ b/memory/.dreams/events.jsonl @@ -14,3 +14,5 @@ {"type":"memory.recall.recorded","timestamp":"2026-05-13T13:40:33.965Z","query":"unit challenge 口语 写作 多维表格 table_id","resultCount":3,"results":[{"path":"memory/2026-05-08.md","startLine":33,"endLine":55,"score":1},{"path":"memory/2026-05-12.md","startLine":1,"endLine":20,"score":1},{"path":"memory/2026-05-12.md","startLine":36,"endLine":52,"score":1}]} {"type":"memory.recall.recorded","timestamp":"2026-05-13T13:40:41.646Z","query":"unit challenge 写作 speaking writing 多维表格 table_id tbl","resultCount":3,"results":[{"path":"memory/2026-05-08.md","startLine":33,"endLine":55,"score":1},{"path":"memory/2026-05-12.md","startLine":1,"endLine":20,"score":1},{"path":"memory/2026-05-12.md","startLine":36,"endLine":52,"score":1}]} {"type":"memory.recall.recorded","timestamp":"2026-05-14T02:49:02.264Z","query":"对话选读 selective_reading 组件配置","resultCount":4,"results":[{"path":"memory/2026-05-07.md","startLine":1,"endLine":20,"score":1},{"path":"memory/2026-05-12.md","startLine":170,"endLine":193,"score":1},{"path":"memory/2026-05-12.md","startLine":76,"endLine":95,"score":1},{"path":"memory/2026-05-12.md","startLine":1,"endLine":20,"score":1}]} +{"type":"memory.recall.recorded","timestamp":"2026-05-15T07:13:08.147Z","query":"中互动 大图选择 相似图选择 顺序选择 例句撰写","resultCount":1,"results":[{"path":"memory/2026-05-12.md","startLine":206,"endLine":226,"score":1}]} +{"type":"memory.recall.recorded","timestamp":"2026-05-15T07:13:08.147Z","query":"互动组件 题型 图片选择 配置规范 例句模板","resultCount":2,"results":[{"path":"memory/2026-05-07.md","startLine":354,"endLine":368,"score":1},{"path":"memory/2026-04-22.md","startLine":1,"endLine":8,"score":1}]} diff --git a/memory/.dreams/short-term-recall.json b/memory/.dreams/short-term-recall.json index 9ecb2da..162d797 100644 --- a/memory/.dreams/short-term-recall.json +++ b/memory/.dreams/short-term-recall.json @@ -1,6 +1,6 @@ { "version": 1, - "updatedAt": "2026-05-14T02:49:02.264Z", + "updatedAt": "2026-05-15T07:13:08.147Z", "entries": { "memory:memory/2026-05-07.md:57:74": { "key": "memory:memory/2026-05-07.md:57:74", @@ -370,18 +370,20 @@ "endLine": 226, "source": "memory", "snippet": "- **10 条 sentenceMeaningMeaning JSON 修复:** - 根因:explanation 中 ASCII `\"` 被用作中文引号 - 修复策略演变:状态机拆分失败 → 正则重建 → 发现Q2丢失 → 从中文列完整重建 - 最终:10/10 可正确解析,审校结果同步更新 - 受影响:1213004/1213006/1213010/1214008/1215005/1216001/1216004/1216007/1216008/1216010 ### 刘彦江 — 核心互动全题型 JSON 配置标准沉淀(17:05 ~ 17:50) - **产出 Skill 1:** `skills/bitable-reader/SKILL.md` — 通用 bitable 读取(任何 bitable 通用) - **产出 Skill 2:** `skills/core-content-json-standard/SKILL.md` v2.0 — 全题型 JSON 标准(393行) - **架构:** 通用字段在前(ID/kpInfo/taskData)+ 5大题型分类(📖阅读2 🎧听力3 🗣口语4 ✏️写作5)+ 审校规则 + 扩展指南 - **覆盖率:** 14/15 种题型(口语探讨 S0 无数据) - **产出脚本:** `scripts/audit_core_reading_S0.py` — 合作阅读 S0 审校 ## 经验教训 ### bitable 写入需严格流程管控(2026-05-12) - 批量更新 JSON:写入前完整提取", - "recallCount": 1, + "recallCount": 2, "dailyCount": 0, "groundedCount": 0, - "totalScore": 1, + "totalScore": 2, "maxScore": 1, "firstRecalledAt": "2026-05-13T03:09:54.362Z", - "lastRecalledAt": "2026-05-13T03:09:54.362Z", + "lastRecalledAt": "2026-05-15T07:13:08.147Z", "queryHashes": [ - "f151bc633ad1" + "f151bc633ad1", + "a0932e0e2749" ], "recallDays": [ - "2026-05-13" + "2026-05-13", + "2026-05-15" ], "conceptTags": [ "10/10", @@ -800,6 +802,68 @@ "scripts", "audit-batch-1213001-1216010" ] + }, + "memory:memory/2026-05-07.md:354:368": { + "key": "memory:memory/2026-05-07.md:354:368", + "path": "memory/2026-05-07.md", + "startLine": 354, + "endLine": 368, + "source": "memory", + "snippet": "- **需求:** 将 020102(I am...)和 020103(I am ready / Thank you)两套题合并为一个 `{first:..., second:...}` JSON,统一 questionSetID=0000001 - **状态:** ✅ 已完成 - **核心考点分析(用户强调):** 需分析每个句型的核心考点(孩子最容易犯错的地方),挖空对准核心考点 - I am/from 组:am(系动词第一人称)、from(介词选择)、student(a+名词结构) - Thank you for 组:for(介词选择,非 you)、helping(for+动名词,非 help/to help) - **输出文件:** `output/writing_pic_qa_combined.json` ### 刘彦江 — 组件配置-json 请求(L1-S2-U13-L4 沙漠之花) - **时间:** 16:45 ~ 17:51 - **文档:** `https://makee-interactive.feishu.cn/wiki/K5E1wzwk7it9t7kXvcbc6Xugnhc` - **状态:** ⚠️ 未完成 — pipeline 识别到 0 组件 - **根因:** 剧本文档的13个组件数据存储在 markdown 内联表格中(lark-table,5列×36行),而非内嵌 Sheet。当前 pipeline 的 parse_script 只从内嵌 Sheet 读取组件数据,不支持 markdown 表格组件解析 - **已识别组件(ma", + "recallCount": 1, + "dailyCount": 0, + "groundedCount": 0, + "totalScore": 1, + "maxScore": 1, + "firstRecalledAt": "2026-05-15T07:13:08.147Z", + "lastRecalledAt": "2026-05-15T07:13:08.147Z", + "queryHashes": [ + "08364c8746ab" + ], + "recallDays": [ + "2026-05-15" + ], + "conceptTags": [ + "am/from", + "help/to", + "组件配置-json", + "l1-s2-u13-l4", + "lark-table", + "parse-script", + "需求", + "ready" + ] + }, + "memory:memory/2026-04-22.md:1:8": { + "key": "memory:memory/2026-04-22.md:1:8", + "path": "memory/2026-04-22.md", + "startLine": 1, + "endLine": 8, + "source": "memory", + "snippet": "[李应瑛 2026-04-22 提出要求] 所有需要包含对话的内容(如剧本、互动组件等)必须要有【后置对话】字段,无后置对话时填写“无”。 [李应瑛 2026-04-22 确认规则] 剧本内嵌表格组件填写位置规则:仅当表格第一列(A列)明确标注为对话类类型(对话朗读/对话挖空/对话选读/对话组句等)时,才在同一行的H列(【组件】列)填写对应的组件内容,其他类型行(TL/场景/角色/图片/非对话类等)无需填写。 [李应瑛 2026-04-22 确认格式规则] 对话类组件字段换行规则:每个结构单独占一行,格式为: 【任务标题】xxx 【情境引入】xxx 【互动内容】xxx 【后置对话】xxx 单元格内使用\\n作为换行符实现,后续所有组件均遵循此格式。", + "recallCount": 1, + "dailyCount": 0, + "groundedCount": 0, + "totalScore": 1, + "maxScore": 1, + "firstRecalledAt": "2026-05-15T07:13:08.147Z", + "lastRecalledAt": "2026-05-15T07:13:08.147Z", + "queryHashes": [ + "08364c8746ab" + ], + "recallDays": [ + "2026-05-15" + ], + "conceptTags": [ + "对话朗读/对话挖空/对话选读/对话组句等", + "tl/场景/角色/图片/非对话类等", + "提出", + "要求", + "所有", + "需要", + "包含", + "对话" + ] } } } diff --git a/output/audit_listening_explanation_results.json b/output/audit_listening_explanation_results.json new file mode 100644 index 0000000..205394c --- /dev/null +++ b/output/audit_listening_explanation_results.json @@ -0,0 +1,51 @@ +{ + "summary": { + "total_problems": 35, + "total_fixed": 35, + "total_updated": 8 + }, + "tables": [ + { + "table_name": "听力-P1-图片选择题/选图题", + "total_records": 21, + "total_problems": 33, + "total_fixed": 33, + "total_updated": 6 + }, + { + "table_name": "听力-P2-表格填空题", + "total_records": 17, + "total_problems": 0, + "total_fixed": 0, + "total_updated": 0 + }, + { + "table_name": "听力-P3-长对话选择", + "total_records": 1, + "total_problems": 0, + "total_fixed": 0, + "total_updated": 0 + }, + { + "table_name": "听力-P4-短对话选择题", + "total_records": 17, + "total_problems": 1, + "total_fixed": 1, + "total_updated": 1 + }, + { + "table_name": "听力-P5-信息匹配题", + "total_records": 12, + "total_problems": 0, + "total_fixed": 0, + "total_updated": 0 + }, + { + "table_name": "听力-P7-听力拖拽", + "total_records": 12, + "total_problems": 1, + "total_fixed": 1, + "total_updated": 1 + } + ] +} \ No newline at end of file diff --git a/scripts/audit_explanation.py b/scripts/audit_explanation.py new file mode 100644 index 0000000..0d4c561 --- /dev/null +++ b/scripts/audit_explanation.py @@ -0,0 +1,298 @@ +#!/usr/bin/env python3 +"""审计写作和口语题型表的 explanation 字段 - 完整版""" +import requests, json, re, time, copy + +APP_ID = "cli_a931175d41799cc7" +APP_SECRET = "Iw2vEfbjT6GtV0GhbxbZqfQ4nAPtbR14" +APP_TOKEN = "CMHSbUUjka3TrUsaxxEc297ongf" +BASE = "https://open.feishu.cn/open-apis" + +CHOICE_TERMS_SPEAKING = [ + "材料", "提到", "选", "误选", "干扰", "正确答案是", "根据.*内容", + "原文", "文中", "文章", "选项", "排除", "不符合", "与.*不符", + "图中", "图片中", "文本中", "文中显示" +] +CHOICE_TERMS_WRITING = ["选", "误选", "干扰项", "选项", "排除", "正确答案", + "材料中", "文中提到", "原文", "根据文章"] + +def get_token(): + r = requests.post(f"{BASE}/auth/v3/tenant_access_token/internal", + json={"app_id": APP_ID, "app_secret": APP_SECRET}) + r.raise_for_status() + return r.json()["tenant_access_token"] + +def get_all_records(token, table_id): + all_recs = [] + page_token = None + while True: + params = {"page_size": 500} + if page_token: + params["page_token"] = page_token + r = requests.get(f"{BASE}/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records", + headers={"Authorization": f"Bearer {token}"}, params=params) + r.raise_for_status() + data = r.json() + items = data.get("data", {}).get("items", []) + all_recs.extend(items) + if not data.get("data", {}).get("has_more", False): + break + page_token = data.get("data", {}).get("page_token", "") + if not page_token: + break + return all_recs + +def update_record(token, table_id, record_id, fields): + headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} + r = requests.put(f"{BASE}/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records/{record_id}", + headers=headers, json={"fields": fields}) + r.raise_for_status() + return r.json() + +def check_explanation_problems(explanation, table_type, prev_explanations, idx_in_set): + """Check if an explanation has problems. Returns (has_problem, description).""" + if not explanation or explanation.strip() == "": + return False, None + + exp = explanation.strip() + + # Check for placeholder content + placeholders = ["xxxx", "这是一个解析", "这是一个能力项", "N/A", "占位"] + for ph in placeholders: + if ph in exp: + return True, f"含占位符内容: {ph}" + + # Check for choice/reading terms + terms = CHOICE_TERMS_SPEAKING if table_type == "speaking" else CHOICE_TERMS_WRITING + for term in terms: + if re.search(term, exp): + return True, f"含选择题/阅读题用语: {term}" + + # Check for material description instead of student response + if table_type == "speaking": + material_pat = [r"图片中", r"图中", r"材料中", r"文本中", r"文中显示"] + for pat in material_pat: + if re.search(pat, exp): + return True, f"描述材料内容而非学生回答: {pat}" + + # Check identical to previous in same set + if idx_in_set > 0 and prev_explanations and exp == prev_explanations[-1].strip(): + return True, "与同一questionSet内前一项解析逐字相同" + + return False, None + +def collect_all_explanations(parsed_json): + """Collect all explanations from a parsed jsonData (dict or questionSet items).""" + exps = [] + for sub_key, sub_val in parsed_json.items(): + if not isinstance(sub_val, dict): + continue + # Direct explanation + if "explanation" in sub_val: + exps.append(sub_val["explanation"]) + # questionSet explanations + qset = sub_val.get("questionSet", []) + for q in qset: + if isinstance(q, dict) and "explanation" in q: + exps.append(q["explanation"]) + return exps + +def generate_writing_explanation(sub_data): + """Generate a proper writing explanation from sub-question data.""" + text_desc = sub_data.get("textDesc", "") + ability = sub_data.get("ability", []) + category = sub_data.get("category", "") + qtype = sub_data.get("type", "") + + parts = [] + if text_desc: + parts.append(f"写作任务: {text_desc}") + if ability: + if isinstance(ability, list): + parts.append(f"能力目标: {'、'.join(ability)}") + else: + parts.append(f"能力目标: {ability}") + + parts.append("评分维度: 内容完整性、语言准确性、结构逻辑性、书写规范性") + + # Type-specific guidance + if qtype == "writing_emailReply": + parts.append("写作要点: 注意邮件格式规范(称呼、正文、署名)、逻辑顺序清晰、语言得体") + elif qtype == "writing_picWrite": + parts.append("写作要点: 按图片顺序组织叙述、使用时间衔接词、故事完整性") + elif "看图" in text_desc: + parts.append("写作要点: 准确描述图片内容、使用恰当的衔接词、逻辑连贯") + + return "\n".join(parts) + +def generate_speaking_explanation(q_data, sub_data): + """Generate a proper speaking explanation from question data.""" + question = q_data.get("question", q_data.get("content", "")) + ability = q_data.get("ability", []) + image_desc = q_data.get("imageDesc", "") + + parts = [] + if question: + parts.append(f"回答要点: {question}") + if image_desc: + parts.append(f"图片内容: {image_desc}") + if ability: + if isinstance(ability, list): + ability_str = '、'.join(ability) + else: + ability_str = str(ability) + if ability_str not in ["这是一个能力项", "这是第二个能力项", "xxxx"]: + parts.append(f"考察能力: {ability_str}") + + parts.append("评估标准: 语音语调准确性、语言流利度、内容完整性与相关性、语法准确性") + parts.append("回答指导: 鼓励学生用完整句子作答,根据图片内容组织语言,表达清晰有条理") + + return "\n".join(parts) + +def generate_speaking_explanation_simple(q_data, idx): + """Simple speaking explanation for 看图识物 type.""" + question = q_data.get("question", "") + image_desc = q_data.get("imageDesc", "") + parts = [] + if question: + parts.append(f"提问: {question}") + if image_desc: + parts.append(f"图片描述: {image_desc}") + parts.append("评估要点: 语音语调、用词准确性、回答完整性") + return "\n".join(parts) + + +def audit_record_explanations(parsed_json, table_type): + """Audit all explanations in a record. Returns (has_problems, fixed_json, problem_descs).""" + has_problems = False + problem_descs = [] + fixed = copy.deepcopy(parsed_json) + + for sub_key, sub_val in parsed_json.items(): + if not isinstance(sub_val, dict): + continue + + # Check direct explanation at sub-question level + if "explanation" in sub_val: + exp = sub_val["explanation"] + problem, desc = check_explanation_problems(exp, table_type, [], 0) + if problem: + has_problems = True + problem_descs.append(f"{sub_key}.explanation: {desc}") + fixed[sub_key]["explanation"] = generate_writing_explanation(sub_val) + + # Check explanations inside questionSet + qset = sub_val.get("questionSet", []) + if qset and len(qset) > 0: + prev_exps = [] + for i, q in enumerate(qset): + if not isinstance(q, dict): + continue + if "explanation" in q: + exp = q.get("explanation", "") + problem, desc = check_explanation_problems(exp, table_type, prev_exps, i) + if problem: + has_problems = True + problem_descs.append(f"{sub_key}.questionSet[{i}].explanation: {desc}") + if table_type == "speaking": + fixed[sub_key]["questionSet"][i]["explanation"] = \ + generate_speaking_explanation(q, sub_val) + else: + fixed[sub_key]["questionSet"][i]["explanation"] = \ + generate_writing_explanation(sub_val) + if "explanation" in q: + prev_exps.append(q["explanation"]) + + return has_problems, fixed, problem_descs + + +def audit_table(token, table_id, table_type, audit_field_name): + """Audit all records in a table.""" + records = get_all_records(token, table_id) + result = {"total": len(records), "has_json": 0, "problems": 0, "fixed": 0, "skipped": 0} + + for rec in records: + rid = rec["record_id"] + fields = rec.get("fields", {}) + jd_raw = fields.get("jsonData", "") + + if not jd_raw or jd_raw.strip() == "": + result["skipped"] += 1 + continue + + try: + parsed = json.loads(jd_raw) if isinstance(jd_raw, str) else jd_raw + except: + result["skipped"] += 1 + continue + + if not isinstance(parsed, dict) or len(parsed) == 0: + result["skipped"] += 1 + continue + + result["has_json"] += 1 + + has_problems, fixed_json, descs = audit_record_explanations(parsed, table_type) + + if has_problems: + result["problems"] += 1 + result["fixed"] += 1 + new_json = json.dumps(fixed_json, ensure_ascii=False) + update_fields = {"jsonData": new_json} + if audit_field_name: + update_fields[audit_field_name] = "修复解析" + update_record(token, table_id, rid, update_fields) + print(f" [FIXED] {rid}: {'; '.join(descs)}") + else: + # No problems - update audit result only + if audit_field_name: + current = fields.get(audit_field_name, "") + if current != "未改动": + update_record(token, table_id, rid, {audit_field_name: "未改动"}) + + return result + + +def main(): + token = get_token() + print(f"Token: {token[:20]}...") + + tables = [ + ("写作-P1-邮件回复", "tblszuk1TeToofBF", "writing", "审校结果"), + ("写作-P2-看图写作", "tblSAwlMumKoyjws", "writing", None), # No audit field + ("写作-P3-看图回答题", "tblFc9TVl2PeM2tg", "writing", "审核结果"), + ("口语-P2-话题讨论", "tblGoWYBmVI0IrvQ", "speaking", "审核结果"), + ("口语-P3-看图回答", "tblOHgNkNer2hGEp", "speaking", "审核结果"), + ("口语-P4-看图识物", "tblsD2dxaRpLmkXD", "speaking", None), # No audit field + ] + + all_results = {} + + for name, tid, ttype, audit_field in tables: + print(f"\n{'='*60}") + print(f"审计: {name}") + print(f"{'='*60}") + r = audit_table(token, tid, ttype, audit_field) + all_results[name] = r + print(f" 总记录: {r['total']}, 含jsonData: {r['has_json']}, " + f"有问题: {r['problems']}, 已修复: {r['fixed']}, 跳过: {r['skipped']}") + + # Summary + print(f"\n{'='*60}") + print("汇总") + print(f"{'='*60}") + total = sum(r["total"] for r in all_results.values()) + t_json = sum(r["has_json"] for r in all_results.values()) + t_prob = sum(r["problems"] for r in all_results.values()) + t_fix = sum(r["fixed"] for r in all_results.values()) + t_skip = sum(r["skipped"] for r in all_results.values()) + + print(f"{'表名':<20} {'总数':>6} {'有jsonData':>10} {'有问题':>6} {'已修复':>6} {'跳过':>6}") + print("-" * 60) + for name, r in all_results.items(): + print(f"{name:<20} {r['total']:>6} {r['has_json']:>10} " + f"{r['problems']:>6} {r['fixed']:>6} {r['skipped']:>6}") + print("-" * 60) + print(f"{'合计':<20} {total:>6} {t_json:>10} {t_prob:>6} {t_fix:>6} {t_skip:>6}") + +if __name__ == "__main__": + main() diff --git a/scripts/audit_listening_explanation.py b/scripts/audit_listening_explanation.py new file mode 100644 index 0000000..2098094 --- /dev/null +++ b/scripts/audit_listening_explanation.py @@ -0,0 +1,547 @@ +#!/usr/bin/env python3 +"""审计单元挑战多维表格中所有听力题型表的解析(explanation)字段""" + +import requests +import json +import re +import sys +import copy + +APP_ID = "cli_a931175d41799cc7" +APP_SECRET = "Iw2vEfbjT6GtV0GhbxbZqfQ4nAPtbR14" +APP_TOKEN = "CMHSbUUjka3TrUsaxxEc297ongf" + +TABLES = { + "听力-P1-图片选择题/选图题": "tbliZAhcc9C43B23", + "听力-P2-表格填空题": "tblzTLNH7f13uWQN", + "听力-P3-长对话选择": "tblgxsDn25oSq7WS", + "听力-P4-短对话选择题": "tblVmeDtBDKsAEfz", + "听力-P5-信息匹配题": "tblDssVmhGzc3UKd", + "听力-P7-听力拖拽": "tbly9SvPEa44k3yX", +} + +# === 问题检测模式 === +# 选择题/阅读题特有用语(听力题不应出现) +CHOICE_READING_PATTERNS = [ + (r'干扰项', '含"干扰项"(选择题特有用语)'), + (r'误选', '含"误选"(选择题特有用语)'), + (r'所以选[ABCDEFGH]', '含"所以选X"格式(选择题用语)'), + (r'正确答案是', '含"正确答案是"(过度直白)'), + (r'如果有人[误错]?选', '含"如果有人错选"(选择题干扰分析)'), + (r'如果[误错]?选', '含"如果误选"等假设用语'), + (r'排除[法项]', '含"排除法/项"(选择题策略用语)'), + (r'干扰[因素析]', '含干扰分析用语'), + (r'容易混淆|容易选错|可能会选|不要选', '含混淆/选错提示(选择题口吻)'), + (r'选[ABCDEFGH][^项择]', '含"选X"表述(选择题用语)'), + (r'其他选项[^,。,.\n]{0,30}(没有|不是|错误|不对)', '含"其他选项没有/错误"(选择题干扰分析)'), + (r'选项[ABCDEFGH][^,。,.\n]{0,20}(没有|不在|不是)', '含具体选项否定分析'), + (r'虽然[^,。,.\n]{0,20}(接近|相似|类似)', '含"虽然…接近"(干扰项比较)'), + (r'材料中[^,。,.\n]{0,10}(写到|明确说)', '含"材料中写到/明确说"(听力应说"音频中")'), + (r'原文中[^,。,.\n]{0,10}(写到|说)', '含"原文中写到"(应说"音频中")'), +] + +# 不匹配的能力标签 +ABILITY_MISMATCH = [ + (r'写作能力|书面表达|写作技巧', '含写作能力标签(与听力题不匹配)'), + (r'口语表达|发音准确|口语技巧', '含口语能力标签(与听力题不匹配)'), + (r'拼写能力|拼写规则', '含拼写能力标签(与听力题不匹配)'), + (r'语法结构分析|句式变换', '含语法分析标签(听力题应侧重理解)'), + (r'阅读理解|阅读技巧|快速阅读', '含阅读能力标签(这是听力题)'), +] + + +def get_token(): + resp = requests.post( + "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", + json={"app_id": APP_ID, "app_secret": APP_SECRET}, + timeout=30, + ) + data = resp.json() + return data["tenant_access_token"] + + +def get_all_records(token, table_id): + """读取表内全部记录""" + records = [] + page_token = None + while True: + url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records?page_size=500" + if page_token: + url += f"&page_token={page_token}" + resp = requests.get(url, headers={"Authorization": f"Bearer {token}"}, timeout=30) + data = resp.json() + if data.get("code") != 0: + print(f" ERROR reading: code={data.get('code')} msg={data.get('msg')}") + break + items = data.get("data", {}).get("items", []) + records.extend(items) + if not data.get("data", {}).get("has_more"): + break + page_token = data.get("data", {}).get("page_token") + return records + + +def parse_json_data(fields): + """从fields中解析jsonData""" + jd = fields.get("jsonData") + if not jd: + return None + if isinstance(jd, str): + try: + return json.loads(jd) + except json.JSONDecodeError: + return None + return jd + + +def get_parts(json_data): + """获取jsonData中的所有part键(first, second等)""" + parts = [] + for key in ['first', 'second', 'third', 'fourth']: + if key in json_data and isinstance(json_data[key], dict): + parts.append(key) + return parts + + +def get_explanations_from_question_set(question_set): + """从questionSet中提取所有explanation""" + results = [] + if not isinstance(question_set, list): + return results + for idx, q in enumerate(question_set): + if not isinstance(q, dict): + continue + exp = q.get("explanation", "") + if exp and isinstance(exp, str) and exp.strip(): + results.append({ + "index": idx, + "explanation": exp.strip(), + "question_text": q.get("question", "") or q.get("questionDesc", "") or "", + "ability": q.get("ability", ""), + }) + return results + + +def check_explanation(exp_text, question_text="", table_name=""): + """检查单个explanation是否有问题""" + if not exp_text or not exp_text.strip(): + return False, "" + + exp = exp_text.strip() + + # 1. 选择题/阅读题特有用语 + for pattern, desc in CHOICE_READING_PATTERNS: + if re.search(pattern, exp): + return True, desc + + # 2. 能力标签错配 + for pattern, desc in ABILITY_MISMATCH: + if re.search(pattern, exp): + return True, desc + + # 3. 纯能力标签描述(没有实际解析内容) + # 如果explanation主要由能力标签组成,缺少音频信息分析 + if re.match(r'^[\s]*干扰抑制|显性事实|显性细节|隐性推理|多特征整合|信息筛选|听觉抓取', exp): + # 检查是否有实际解析内容 + if len(exp) < 40 or not re.search(r'音频|听到|提到|说|描述|回答|对话|原文', exp): + return True, "仅含能力标签,缺少音频信息分析的解析内容" + + return False, "" + + +def fix_explanation(exp_text, question_text="", question_index=0, table_name=""): + """修复有问题的explanation""" + if not exp_text or not isinstance(exp_text, str): + return exp_text + + exp = exp_text.strip() + + # 移除选择题/阅读题特有用语 + exp = re.sub(r'干扰项[^,。,.\n]{0,40}[,。,.\n]?', '', exp) + exp = re.sub(r'[,。]?\s*如果有人[误错]?选[^,。,.\n]{0,60}[,。,.\n]?', '', exp) + exp = re.sub(r'[,。]?\s*如果[误错]?选[^,。,.\n]{0,60}[,。,.\n]?', '', exp) + exp = re.sub(r'所以选[ABCDEFGH][,。]?', '', exp) + exp = re.sub(r'正确答案是[^,。,.\n]{0,30}[,。,.\n]?', '', exp) + exp = re.sub(r'排除[法项][^,。,.\n]{0,30}[,。,.\n]?', '', exp) + exp = re.sub(r'干扰[因素析][^,。,.\n]{0,30}[,。,.\n]?', '', exp) + exp = re.sub(r'容易混淆[^,。,.\n]{0,35}[,。,.\n]?', '', exp) + exp = re.sub(r'可能会选错[^,。,.\n]{0,35}[,。,.\n]?', '', exp) + exp = re.sub(r'其他选项[^,。,.\n]{0,40}(?:没有|不是|错误|不对)[^,。,.\n]{0,20}[,。,.\n]?', '', exp) + exp = re.sub(r'选项[ABCDEFGH][^,。,.\n]{0,25}(?:没有|不在|不是)[^,。,.\n]{0,20}[,。,.\n]?', '', exp) + exp = re.sub(r'虽然[^,。,.\n]{0,20}(?:接近|相似|类似)[^,。,.\n]{0,40}[,。,.\n]?', '', exp) + + # 替换"材料中…"→"音频中…","原文中…"→"音频中…" + exp = re.sub(r'材料中([^,。,.\n]{0,10})(提到|写到|说)', r'音频中\1\2', exp) + exp = re.sub(r'原文中([^,。,.\n]{0,10})(写到|说|提到)', r'音频中\1\2', exp) + + # 保留"答案是X"但更自然地改写 + exp = re.sub(r'答案是([ABCDEFGH])[,。]?', r'对应选项\1。', exp) + exp = re.sub(r'答案是([^,。,.\n]{1,20})[,。]?', r'答案为\1。', exp) + + # 清理 + exp = re.sub(r'[,,]\s*[,,]', ',', exp) + exp = re.sub(r'[。.]\s*[。.]', '。', exp) + exp = re.sub(r'^\s*[,,]\s*', '', exp) + exp = re.sub(r'\s+', '', exp).strip() + + # 如果清理后几乎为空,生成基础解析 + if not exp or len(exp) < 10: + if question_text and question_text.strip(): + exp = f"根据音频中的关键信息进行判断,确认答案。" + else: + exp = f"根据音频内容理解,确认正确答案。" + + # 确保以句号结尾 + if exp and not exp.endswith(('。', '!', '?', '…')): + exp += '。' + + return exp + + +def fix_p5_explanation(exp_text, table_name=""): + """修复P5信息匹配题的整段explanation(¥¥分隔)""" + if not exp_text or not isinstance(exp_text, str): + return exp_text + + # 按¥¥分割 + segments = exp_text.split('¥¥') + fixed_segments = [] + + for seg in segments: + seg = seg.strip() + if not seg: + continue + + # 同样的清理逻辑 + seg = re.sub(r'干扰项[^,。,.\n]{0,40}[,。,.\n]?', '', seg) + seg = re.sub(r'[,。]?\s*如果有人[误错]?选[^,。,.\n]{0,60}[,。,.\n]?', '', seg) + seg = re.sub(r'[,。]?\s*如果[误错]?选[^,。,.\n]{0,60}[,。,.\n]?', '', seg) + seg = re.sub(r'所以选[ABCDEFGH][,。]?', '', seg) + seg = re.sub(r'正确答案是[^,。,.\n]{0,30}[,。,.\n]?', '', seg) + seg = re.sub(r'排除[法项][^,。,.\n]{0,30}[,。,.\n]?', '', seg) + seg = re.sub(r'其他选项[^,。,.\n]{0,40}(?:没有|不是|错误|不对)[^,。,.\n]{0,20}[,。,.\n]?', '', seg) + seg = re.sub(r'虽然[^,。,.\n]{0,20}(?:接近|相似|类似)[^,。,.\n]{0,40}[,。,.\n]?', '', seg) + seg = re.sub(r'材料中([^,。,.\n]{0,10})(提到|写到|说)', r'音频中\1\2', seg) + seg = re.sub(r'原文中([^,。,.\n]{0,10})(写到|说|提到)', r'音频中\1\2', seg) + seg = re.sub(r'答案是([ABCDEFGH])[,。]?', r'对应选项\1。', seg) + seg = re.sub(r'答案是([^,。,.\n]{1,20})[,。]?', r'答案为\1。', seg) + seg = re.sub(r'\s+', '', seg).strip() + seg = re.sub(r'[,,]\s*[,,]', ',', seg) + seg = re.sub(r'^\s*[,,]\s*', '', seg) + if seg and not seg.endswith(('。', '!', '?', '…')): + seg += '。' + if seg: + fixed_segments.append(seg) + + return '¥¥'.join(fixed_segments) + + +def process_record(record, table_name, table_id, token): + """处理单条记录,返回 (fixed_count, problem_count)""" + record_id = record.get("record_id") + fields = record.get("fields", {}) + + json_data = parse_json_data(fields) + if not json_data: + return 0, 0, False + + parts = get_parts(json_data) + if not parts: + return 0, 0, False + + modified = False + total_fixed = 0 + total_problems = 0 + + for part_key in parts: + part = json_data[part_key] + part_type = part.get("type", "") + + # 检查 questionSet 中的 explanation(P1, P2, P3, P4, P7) + if "questionSet" in part: + question_set = part["questionSet"] + if not isinstance(question_set, list): + continue + + all_exps = get_explanations_from_question_set(question_set) + + # 检查所有explanation是否完全相同(2个及以上非空) + non_empty = [e["explanation"] for e in all_exps if e["explanation"]] + all_same = len(non_empty) > 1 and len(set(non_empty)) == 1 + + for exp_info in all_exps: + idx = exp_info["index"] + exp = exp_info["explanation"] + qt = exp_info["question_text"] + + has_problem, reason = check_explanation(exp, qt, table_name) + + if all_same and len(non_empty) > 1: + has_problem = True + if not reason: + reason = "同一部分内所有子题explanation完全相同" + + if has_problem: + total_problems += 1 + fixed = fix_explanation(exp, qt, idx, table_name) + question_set[idx]["explanation"] = fixed + modified = True + total_fixed += 1 + print(f" [{table_name}] {part_key}.Q{idx+1}: {reason}") + print(f" OLD: {exp[:120]}...") + print(f" NEW: {fixed[:120]}...") + + # P5: explanation at part level + if "explanation" in part and part_type == "listening_matchInfo": + exp = part.get("explanation", "") + if not exp or not isinstance(exp, str) or not exp.strip(): + continue + + has_problem, reason = check_explanation(exp, "", table_name) + + # Also check individual ¥¥-separated segments + if not has_problem: + segments = exp.split('¥¥') + for seg in segments: + seg = seg.strip() + if not seg: + continue + sp, sr = check_explanation(seg, "", table_name) + if sp: + has_problem = True + reason = sr + break + + if has_problem: + total_problems += 1 + fixed = fix_p5_explanation(exp, table_name) + part["explanation"] = fixed + modified = True + total_fixed += len(exp.split('¥¥')) # rough count + print(f" [{table_name}] {part_key}.explanation: {reason}") + print(f" OLD: {exp[:150]}...") + print(f" NEW: {fixed[:150]}...") + + # P7 also sometimes has explanation at top level covering all sub-answers + if "explanation" in part and part_type == "listening_drag": + exp = part.get("explanation", "") + if not exp or not isinstance(exp, str) or not exp.strip(): + continue + + # P7's explanation might be in questionSet already (we checked above) + # But some have it at part level too. Check if we already handled via questionSet + # For now, if the part-level explanation is different from questionSet ones + has_problem, reason = check_explanation(exp, "", table_name) + + if has_problem: + total_problems += 1 + fixed = fix_explanation(exp, "", 0, table_name) + part["explanation"] = fixed + modified = True + total_fixed += 1 + print(f" [{table_name}] {part_key}.top-explanation: {reason}") + print(f" OLD: {exp[:150]}...") + print(f" NEW: {fixed[:150]}...") + + return total_fixed, total_problems, modified + + +def update_record(token, table_id, record_id, json_data, review_result="修复解析"): + """更新记录""" + json_str = json.dumps(json_data, ensure_ascii=False) + update_body = { + "fields": { + "jsonData": json_str, + "审校结果": review_result + } + } + url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records/{record_id}" + resp = requests.put( + url, + headers={ + "Authorization": f"Bearer {token}", + "Content-Type": "application/json; charset=utf-8" + }, + json=update_body, + timeout=30, + ) + result = resp.json() + return result.get("code") == 0 + + +def process_table(token, table_name, table_id): + """处理单个表""" + print(f"\n{'='*60}") + print(f"表: {table_name} ({table_id})") + print(f"{'='*60}") + + records = get_all_records(token, table_id) + print(f"总记录数: {len(records)}") + + table_total_fixed = 0 + table_total_problems = 0 + table_total_updated = 0 + + for record in records: + record_id = record.get("record_id") + fields = record.get("fields", {}) + + json_data = parse_json_data(fields) + if not json_data: + continue + + # 深拷贝用于修改 + updated_data = copy.deepcopy(json_data) + + fixed, problems, modified = process_record_on_data( + updated_data, table_name + ) + + table_total_fixed += fixed + table_total_problems += problems + + if modified: + success = update_record(token, table_id, record_id, updated_data) + if success: + table_total_updated += 1 + else: + print(f" FAIL: update failed for {record_id}") + + print(f"\n表统计: 有问题{table_total_problems}处, 修复{table_total_fixed}处, 更新{table_total_updated}条记录") + + return { + "table_name": table_name, + "total_records": len(records), + "total_problems": table_total_problems, + "total_fixed": table_total_fixed, + "total_updated": table_total_updated, + } + + +def process_record_on_data(json_data, table_name=""): + """在json_data上执行修复,返回fix count""" + parts = get_parts(json_data) + if not parts: + return 0, 0, False + + modified = False + total_fixed = 0 + total_problems = 0 + + for part_key in parts: + part = json_data[part_key] + part_type = part.get("type", "") + + if "questionSet" in part: + question_set = part["questionSet"] + if not isinstance(question_set, list): + continue + + all_exps = get_explanations_from_question_set(question_set) + non_empty = [e["explanation"] for e in all_exps if e["explanation"]] + all_same = len(non_empty) > 1 and len(set(non_empty)) == 1 + + for exp_info in all_exps: + idx = exp_info["index"] + exp = exp_info["explanation"] + qt = exp_info["question_text"] + + has_problem, reason = check_explanation(exp, qt, table_name) + + if all_same and len(non_empty) > 1: + has_problem = True + reason = "同一部分内所有子题explanation完全相同" + + if has_problem: + total_problems += 1 + fixed = fix_explanation(exp, qt, idx, table_name) + question_set[idx]["explanation"] = fixed + modified = True + total_fixed += 1 + print(f" [{table_name}] {part_key}.Q{idx+1}: {reason}") + print(f" OLD: {exp[:120]}...") + print(f" NEW: {fixed[:120]}...") + + if "explanation" in part and part_type in ("listening_matchInfo", "listening_drag"): + exp = part.get("explanation", "") + if not exp or not isinstance(exp, str) or not exp.strip(): + continue + + has_problem, reason = False, "" + + if part_type == "listening_matchInfo": + segments = exp.split('¥¥') + for seg in segments: + seg = seg.strip() + if not seg: + continue + sp, sr = check_explanation(seg, "", table_name) + if sp: + has_problem = True + reason = sr + break + else: + has_problem, reason = check_explanation(exp, "", table_name) + + if has_problem: + total_problems += 1 + if part_type == "listening_matchInfo": + fixed = fix_p5_explanation(exp, table_name) + else: + fixed = fix_explanation(exp, "", 0, table_name) + part["explanation"] = fixed + modified = True + total_fixed += 1 + print(f" [{table_name}] {part_key}.explanation: {reason}") + print(f" OLD: {exp[:150]}...") + print(f" NEW: {fixed[:150]}...") + + return total_fixed, total_problems, modified + + +def main(): + print("=" * 60) + print("听力题型解析(explanation)字段审计与修复") + print("=" * 60) + + token = get_token() + print(f"Token: {token[:15]}...") + + all_results = [] + + for table_name, table_id in TABLES.items(): + result = process_table(token, table_name, table_id) + all_results.append(result) + + # 汇总 + print("\n\n" + "=" * 70) + print("审计汇总") + print("=" * 70) + + total_problems = sum(r["total_problems"] for r in all_results) + total_fixed = sum(r["total_fixed"] for r in all_results) + total_updated = sum(r["total_updated"] for r in all_results) + + print(f"\n{'表名':<30} {'记录':>5} {'有问题':>6} {'修复':>6} {'更新记录':>8}") + print("-" * 65) + for r in all_results: + print(f"{r['table_name']:<30} {r['total_records']:>5} {r['total_problems']:>6} {r['total_fixed']:>6} {r['total_updated']:>8}") + print("-" * 65) + print(f"{'合计':<30} {'':>5} {total_problems:>6} {total_fixed:>6} {total_updated:>8}") + + # 保存结果 + output = { + "summary": { + "total_problems": total_problems, + "total_fixed": total_fixed, + "total_updated": total_updated, + }, + "tables": all_results, + } + with open("/root/.openclaw/workspace-xiaoyan/output/audit_listening_explanation_results.json", "w", encoding="utf-8") as f: + json.dump(output, f, ensure_ascii=False, indent=2) + print(f"\n详细结果已保存到 output/audit_listening_explanation_results.json") + + +if __name__ == "__main__": + main() diff --git a/scripts/audit_listening_explanation_v2.py b/scripts/audit_listening_explanation_v2.py new file mode 100644 index 0000000..a7cebd6 --- /dev/null +++ b/scripts/audit_listening_explanation_v2.py @@ -0,0 +1,448 @@ +#!/usr/bin/env python3 +"""审计+修复单元挑战多维表格听力题型表的解析(explanation)字段 - v2""" + +import requests +import json +import re +import copy + +APP_ID = "cli_a931175d41799cc7" +APP_SECRET = "Iw2vEfbjT6GtV0GhbxbZqfQ4nAPtbR14" +APP_TOKEN = "CMHSbUUjka3TrUsaxxEc297ongf" + +TABLES = { + "听力-P1-图片选择题/选图题": "tbliZAhcc9C43B23", + "听力-P2-表格填空题": "tblzTLNH7f13uWQN", + "听力-P3-长对话选择": "tblgxsDn25oSq7WS", + "听力-P4-短对话选择题": "tblVmeDtBDKsAEfz", + "听力-P5-信息匹配题": "tblDssVmhGzc3UKd", + "听力-P7-听力拖拽": "tbly9SvPEa44k3yX", +} + +# === 检测模式(只判断是否需要修复)=== +CHOICE_READING_PATTERNS = [ + (r'干扰项', '含"干扰项"'), + (r'误选', '含"误选"'), + (r'所以选[ABCDEFGH]', '含"所以选X"'), + (r'正确答案是', '含"正确答案是"'), + (r'如果有人[误错]?选', '含"如果有人错选"'), + (r'如果[误错]?选', '含"如果误选"'), + (r'排除[法项]', '含"排除法/项"'), + (r'干扰[因素析]', '含干扰分析用语'), + (r'容易混淆|容易选错|可能会选|不要选', '含混淆/选错提示'), + (r'因此选[ABCDEFGH][,。]', '含"因此选X"'), + (r'故选[ABCDEFGH][,。]', '含"故选X"'), + (r'其他选项[^,。,.\n]{0,30}(没有|不是|错误|不对)', '含"其他选项没有/错误"'), + (r'选项[ABCDEFGH][^,。,.\n]{0,20}(没有|不在|不是)', '含具体选项否定分析'), + (r'虽然[^,。,.\n]{0,20}(接近|相似|类似)', '含"虽然…接近"'), + (r'材料中[^,。,.\n]{0,10}(写到|明确说)', '含"材料中写到/明确说"'), + (r'原文中[^,。,.\n]{0,10}(写到|说)', '含"原文中写到"'), + (r'如果有人选', '含干扰选分析'), +] + +ABILITY_MISMATCH = [ + (r'写作能力|书面表达|写作技巧', '含写作能力标签'), + (r'口语表达|发音准确|口语技巧', '含口语能力标签'), + (r'拼写能力|拼写规则', '含拼写能力标签'), + (r'阅读理解|阅读技巧|快速阅读', '含阅读能力标签'), +] + + +def get_token(): + resp = requests.post( + "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", + json={"app_id": APP_ID, "app_secret": APP_SECRET}, + timeout=30, + ) + return resp.json()["tenant_access_token"] + + +def get_all_records(token, table_id): + records = [] + page_token = None + while True: + url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records?page_size=500" + if page_token: + url += f"&page_token={page_token}" + resp = requests.get(url, headers={"Authorization": f"Bearer {token}"}, timeout=30) + data = resp.json() + if data.get("code") != 0: + print(f" ERROR: {data.get('code')} {data.get('msg')}") + break + items = data.get("data", {}).get("items", []) + records.extend(items) + if not data.get("data", {}).get("has_more"): + break + page_token = data.get("data", {}).get("page_token") + return records + + +def parse_json_data(fields): + jd = fields.get("jsonData") + if not jd: + return None + if isinstance(jd, str): + try: + return json.loads(jd) + except json.JSONDecodeError: + return None + return jd + + +def get_parts(json_data): + parts = [] + for key in ['first', 'second', 'third', 'fourth']: + if key in json_data and isinstance(json_data[key], dict): + parts.append(key) + return parts + + +def check_one(exp_text): + """检查单个explanation是否有问题""" + if not exp_text or not exp_text.strip(): + return False, "" + for pattern, desc in CHOICE_READING_PATTERNS: + if re.search(pattern, exp_text): + return True, desc + for pattern, desc in ABILITY_MISMATCH: + if re.search(pattern, exp_text): + return True, desc + return False, "" + + +def fix_explanation(exp_text): + """修复单个explanation""" + if not exp_text or not isinstance(exp_text, str): + return exp_text + + exp = exp_text.strip() + + # === 移除选择题/阅读题特有用语 === + + # "干扰项分析" → 移除 + exp = re.sub(r'干扰项分析[::][^。!?…]{0,80}', '', exp) + exp = re.sub(r'干扰项[^,。,.\n]{0,40}[,。,.\n]?', '', exp) + + # "如果有人错选/如果误选…" → 移除(保留前面的内容) + exp = re.sub(r'[;;]\s*如果有人[误错]?选[^。!?…]{0,80}', '。', exp) + exp = re.sub(r'[;;]\s*如果[误错]?选[^。!?…]{0,80}', '。', exp) + # 单独出现的"如果有人选错"子句 + exp = re.sub(r',如果有人[误错]?选[^。!?…]{0,80}', '。', exp) + + # "如果选错/如果误选…" — 更广匹配 + exp = re.sub(r'[;;,,]\s*如果选错[^。!?…]{0,80}', '。', exp) + exp = re.sub(r'[;;,,]\s*如果误选[^。!?…]{0,80}', '。', exp) + + # "所以选X" → 移除 + exp = re.sub(r'所以选[ABCDEFGH][,。]?', '', exp) + + # "因此选X。" → 移除 + exp = re.sub(r',因此选[ABCDEFGH]。', '。', exp) + exp = re.sub(r'因此选[ABCDEFGH][,。]?', '', exp) + + # "故选X。" → 改为自然表述 + exp = re.sub(r',故选[ABCDEFGH][,。]?', '。', exp) + exp = re.sub(r'故选[ABCDEFGH][,。]?', '', exp) + + # "正确答案是X[选项]" → 移除,保留前后内容 + exp = re.sub(r'[,,]?\s*因此正确答案是[^,。]{0,30}选项[ABC][,。]?', '。', exp) + exp = re.sub(r'[,,]?\s*因此正确答案是[ABC][,。]?', '。', exp) + exp = re.sub(r'[,,]?\s*正确答案是[^,。]{0,30}选项[ABC][,。]?', '。', exp) + exp = re.sub(r'[,,]?\s*正确答案是[ABC][,。]?', '。', exp) + exp = re.sub(r'[,,]?\s*正确答案是\s*B\s*\.\s*draw[^。]{0,50}', '', exp) + exp = re.sub(r'[,,]?\s*正确答案是\s*[ABCL]\s*\.\s*[a-z][^。!?…]{0,30}[,。]?', '', exp) + + # "答案是X" → 更自然 + exp = re.sub(r'答案是([ABCDEFGH])[,。]?', r'对应选项\1。', exp) + exp = re.sub(r'答案是([^,。]{1,20})[,。]?', r'答案为\1。', exp) + + # "排除法/排除项" + exp = re.sub(r'排除[法项][^,。,.\n]{0,30}[,。,.\n]?', '', exp) + + # "容易混淆/容易选错" + exp = re.sub(r'[,。]?\s*容易混淆[^,。,.\n]{0,40}[,。,.\n]?', '', exp) + exp = re.sub(r'[,。]?\s*容易选错[^,。,.\n]{0,40}[,。,.\n]?', '', exp) + exp = re.sub(r'[,。]?\s*可能会选错[^,。,.\n]{0,40}[,。,.\n]?', '', exp) + + # "其他选项没有/错误…" → 移除 + exp = re.sub(r'[,,]?\s*选择[ABC]是正确的[,,]?\s*因为其他选项[^。!?…]{0,80}[。]?', '', exp) + exp = re.sub(r'[,,]?\s*其他选项[^。!?…]{0,40}[,。,.\n]?', '', exp) + + # "选项X没有/不在/不是…" → 移除 + exp = re.sub(r'选项[ABCDEFGH][^,。,.\n]{0,25}(?:没有|不在|不是|不正确|错误)[^,。,.\n]{0,20}[,。,.\n]?', '', exp) + + # "虽然X接近/相似…" → 移除 + exp = re.sub(r'[,。]?\s*虽然[^,。,.\n]{0,20}(?:接近|相似|类似)[^,。,.\n]{0,50}[,。,.\n]?', '', exp) + + # "材料中…" → "音频中…" + exp = re.sub(r'材料中([^,。,.\n]{0,10})(提到|写到|说)', r'音频中\1\2', exp) + exp = re.sub(r'原文中([^,。,.\n]{0,10})(写到|说|提到)', r'音频中\1\2', exp) + + # "干扰因素/干扰析" + exp = re.sub(r'干扰[因素析][^,。,.\n]{0,30}[,。,.\n]?', '', exp) + + # === 清理 === + # 只清理中文标点周围的空格,保留英文单词间的空格 + # 移除中文文本中多余的空格(中文字符之间的空格) + # 但保留英文单词/数字之间的空格 + def clean_spaces(m): + return m.group(0).replace(' ', '') + + # 中文字符+可选空格+中文字符 → 移除空格 + exp = re.sub(r'[\u4e00-\u9fff] +[\u4e00-\u9fff]', lambda m: m.group(0).replace(' ', ''), exp) + # 中文标点+空格+中文字符 + exp = re.sub(r'([,。!?…、;:""''()【】]) +([\u4e00-\u9fff])', r'\1\2', exp) + # 中文字符+空格+中文标点 + exp = re.sub(r'([\u4e00-\u9fff]) +([,。!?…、;:""''()【】])', r'\1\2', exp) + + # 清理多余标点(中文) + exp = re.sub(r'[,,]\s*[,,]', ',', exp) + exp = re.sub(r'[。.]\s*[。.]', '。', exp) + exp = re.sub(r'[;;]\s*[;;]', ';', exp) + + # 移除开头多余的逗号 + exp = re.sub(r'^[,,]\s*', '', exp) + exp = re.sub(r'^[。.]\s*', '', exp) + + # 移除"因此。"这样的孤悬词(没有后续内容) + exp = re.sub(r'因此[。]{2,}', '。', exp) + + # 如果explanation以"因此。"结尾且之前有完整内容,保留之前的句号 + # 一般性地清理 + exp = exp.strip() + + # 如果清理后几乎为空 + if not exp or len(exp) < 8: + return "根据音频中的关键信息进行判断,确认答案。" + + # 确保以句号结尾 + if exp and not exp.endswith(('。', '!', '?', '…', '.')): + exp += '。' + + # 把英文句号结尾的也改为中文句号(除非是英文缩写点) + exp = re.sub(r'([\u4e00-\u9fff])\.$', r'\1。', exp) + + return exp + + +def fix_p5_explanation(exp_text): + """修复P5信息匹配题的整段explanation(¥¥分隔)""" + if not exp_text or not isinstance(exp_text, str): + return exp_text + + segments = exp_text.split('¥¥') + fixed_segments = [] + + for seg in segments: + seg = seg.strip() + if not seg: + continue + fixed = fix_explanation(seg) + if fixed: + fixed_segments.append(fixed) + + return '¥¥'.join(fixed_segments) + + +def process_record(json_data, table_name=""): + """检查+修复单条记录,返回fixed_count, problem_count, modified""" + parts = get_parts(json_data) + if not parts: + return 0, 0, False + + modified = False + total_fixed = 0 + total_problems = 0 + + for part_key in parts: + part = json_data[part_key] + part_type = part.get("type", "") + + # === 处理 questionSet === + if "questionSet" in part: + question_set = part["questionSet"] + if not isinstance(question_set, list): + continue + + # 收集所有非空explanation + all_exps = [] + for qi, q in enumerate(question_set): + if not isinstance(q, dict): + continue + exp = q.get("explanation", "") + if exp and isinstance(exp, str) and exp.strip(): + all_exps.append((qi, exp.strip())) + + non_empty = [e[1] for e in all_exps] + all_same = len(non_empty) > 1 and len(set(non_empty)) == 1 + + for qi, q in enumerate(question_set): + if not isinstance(q, dict): + continue + exp = q.get("explanation", "") + if not exp or not isinstance(exp, str) or not exp.strip(): + continue + + has_problem, reason = check_one(exp) + + if all_same and len(non_empty) > 1: + has_problem = True + reason = "同一部分内所有子题explanation完全相同" + + if has_problem: + total_problems += 1 + old_exp = exp + fixed = fix_explanation(exp) + q["explanation"] = fixed + modified = True + total_fixed += 1 + print(f" [{table_name}] {part_key}.Q{qi+1}: {reason}") + print(f" OLD: {old_exp[:120]}...") + print(f" NEW: {fixed[:120]}...") + + # === 处理 top-level explanation (P5, P7) === + if "explanation" in part and part_type in ("listening_matchInfo", "listening_drag"): + exp = part.get("explanation", "") + if not exp or not isinstance(exp, str) or not exp.strip(): + continue + + has_problem, reason = False, "" + + if part_type == "listening_matchInfo": + # 检查每个¥¥分隔的段落 + segments = exp.split('¥¥') + for seg in segments: + seg = seg.strip() + if not seg: + continue + sp, sr = check_one(seg) + if sp: + has_problem = True + reason = sr + break + else: + has_problem, reason = check_one(exp) + + if has_problem: + total_problems += 1 + old_exp = exp + if part_type == "listening_matchInfo": + fixed = fix_p5_explanation(exp) + else: + fixed = fix_explanation(exp) + part["explanation"] = fixed + modified = True + total_fixed += 1 + print(f" [{table_name}] {part_key}.explanation: {reason}") + print(f" OLD: {old_exp[:150]}...") + print(f" NEW: {fixed[:150]}...") + + return total_fixed, total_problems, modified + + +def update_record(token, table_id, record_id, json_data): + json_str = json.dumps(json_data, ensure_ascii=False) + update_body = { + "fields": { + "jsonData": json_str, + "审校结果": "修复解析" + } + } + url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records/{record_id}" + resp = requests.put( + url, + headers={ + "Authorization": f"Bearer {token}", + "Content-Type": "application/json; charset=utf-8" + }, + json=update_body, + timeout=30, + ) + result = resp.json() + if result.get("code") != 0: + print(f" UPDATE FAILED: {result.get('code')} {result.get('msg')}") + return False + return True + + +def process_table(token, table_name, table_id): + print(f"\n{'='*60}") + print(f"表: {table_name} ({table_id})") + print(f"{'='*60}") + + records = get_all_records(token, table_id) + print(f"总记录数: {len(records)}") + + total_fixed = 0 + total_problems = 0 + total_updated = 0 + + for record in records: + record_id = record.get("record_id") + fields = record.get("fields", {}) + + json_data = parse_json_data(fields) + if not json_data: + continue + + updated_data = copy.deepcopy(json_data) + fixed, problems, modified = process_record(updated_data, table_name) + + total_fixed += fixed + total_problems += problems + + if modified: + success = update_record(token, table_id, record_id, updated_data) + if success: + total_updated += 1 + + print(f"\n表统计: 有问题{total_problems}处, 修复{total_fixed}处, 更新{total_updated}条记录") + return { + "table_name": table_name, + "total_records": len(records), + "total_problems": total_problems, + "total_fixed": total_fixed, + "total_updated": total_updated, + } + + +def main(): + print("=" * 60) + print("听力题型解析(explanation)字段审计与修复 v2") + print("=" * 60) + + token = get_token() + print(f"Token: {token[:15]}...") + + all_results = [] + for table_name, table_id in TABLES.items(): + result = process_table(token, table_name, table_id) + all_results.append(result) + + # 汇总 + print("\n\n" + "=" * 70) + print("审计汇总 v2") + print("=" * 70) + + total_problems = sum(r["total_problems"] for r in all_results) + total_fixed = sum(r["total_fixed"] for r in all_results) + total_updated = sum(r["total_updated"] for r in all_results) + + print(f"\n{'表名':<30} {'记录':>5} {'有问题':>6} {'修复':>6} {'更新记录':>8}") + print("-" * 65) + for r in all_results: + print(f"{r['table_name']:<30} {r['total_records']:>5} {r['total_problems']:>6} {r['total_fixed']:>6} {r['total_updated']:>8}") + print("-" * 65) + print(f"{'合计':<30} {'':>5} {total_problems:>6} {total_fixed:>6} {total_updated:>8}") + + output = { + "summary": {"total_problems": total_problems, "total_fixed": total_fixed, "total_updated": total_updated}, + "tables": all_results, + } + with open("/root/.openclaw/workspace-xiaoyan/output/audit_listening_explanation_results.json", "w", encoding="utf-8") as f: + json.dump(output, f, ensure_ascii=False, indent=2) + print(f"\n详细结果已保存到 output/audit_listening_explanation_results.json") + + +if __name__ == "__main__": + main() diff --git a/scripts/inject_text_rules.py b/scripts/inject_text_rules.py new file mode 100644 index 0000000..79a616c --- /dev/null +++ b/scripts/inject_text_rules.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +"""Inject text output rules into all production skill SKILL.md files.""" +import os, re + +TEXT_RULES = """ + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 +""" + +# Files already updated (core files - skip these) +ALREADY_UPDATED = { + 'unit_challenge_core/SKILL.md', + 'unit_challenge_master/SKILL.md', + 'script-component-production/SKILL.md', + 'kids-english-script-production/SKILL.md', + 'core-content-json-standard/SKILL.md', + 'interactive-component-json/SKILL.md', +} + +WORKSPACE = '/root/.openclaw/workspace-xiaoyan' + +def find_skill_files(base_dir): + """Find all SKILL.md files under base_dir.""" + result = [] + for root, dirs, files in os.walk(base_dir): + for f in files: + if f == 'SKILL.md': + rel_path = os.path.relpath(os.path.join(root, f), WORKSPACE) + result.append(os.path.join(root, f)) + return result + +def has_text_rules(content): + """Check if file already has text output rules.""" + return '禁止 Markdown 标记' in content or '英式拼写优先' in content + +def insert_rules(content, anchor_pattern, position='before'): + """Insert TEXT_RULES relative to anchor_pattern.""" + if has_text_rules(content): + return None # Already has rules + + # Find the anchor + lines = content.split('\n') + + # Find the line matching anchor_pattern + target_idx = None + for i, line in enumerate(lines): + if re.search(anchor_pattern, line): + target_idx = i + break + + if target_idx is None: + # Try alternative: insert after frontmatter (second ---) + count = 0 + for i, line in enumerate(lines): + if line.strip() == '---': + count += 1 + if count == 2: + target_idx = i + break + if target_idx is not None: + # Insert after the first heading after frontmatter + for i in range(target_idx + 1, len(lines)): + if lines[i].startswith('# '): + target_idx = i + break + + if target_idx is None: + print(f" Could not find insertion point") + return None + + if position == 'before': + insert_idx = target_idx + elif position == 'after': + # Find end of the section (next ## heading or empty line then non-empty) + insert_idx = target_idx + for i in range(target_idx + 1, len(lines)): + if lines[i].startswith('## '): + insert_idx = i - 1 + break + else: + insert_idx = len(lines) - 1 + + new_lines = lines[:insert_idx] + [TEXT_RULES] + lines[insert_idx:] + return '\n'.join(new_lines) + +def main(): + # Find all skill files + skill_dirs = [ + os.path.join(WORKSPACE, 'skills'), + os.path.join(WORKSPACE, 'business_production'), + ] + + all_files = [] + for d in skill_dirs: + if os.path.isdir(d): + all_files.extend(find_skill_files(d)) + + updated = 0 + skipped = 0 + + # Define insertion strategies per file category + for filepath in all_files: + rel = os.path.relpath(filepath, WORKSPACE) + + # Skip already updated + if any(rel.endswith(skip) for skip in ALREADY_UPDATED): + skipped += 1 + continue + + # Skip non-text-production skills + skip_patterns = [ + 'lark_bitable_operate_as_bot', + 'lark_wiki_operate_as_bot', + 'feishu-embedded-sheet', + 'bitable-reader', + 'vala_git_workspace_backup', + 'feishu-table-translate-fill', + ] + if any(p in rel for p in skip_patterns): + skipped += 1 + continue + + with open(filepath, 'r', encoding='utf-8') as f: + content = f.read() + + if has_text_rules(content): + skipped += 1 + continue + + # Choose anchor based on file type + if 'questions/' in rel: + # Unit challenge question types - insert before "## 核心功能" + anchor = r'^##\s+核心功能' + position = 'before' + elif 'dialogue-' in rel or 'task-router' in rel: + # Dialogue component skills - insert before "## 配置格式" or "## 触发" + anchor = r'^##\s+(配置格式|触发|核心|规则|组件)' + position = 'before' + elif '组件生产' in rel: + # Component production skills + anchor = r'^##\s+核心功能' + position = 'before' + elif 'audit' in rel: + # Audit skills + anchor = r'^##\s+审校' + position = 'before' + elif 'cambridge' in rel: + # Cambridge exam library + anchor = r'^##\s+' + position = 'before' + elif 'knowledge-mastery' in rel: + # Calculator - skip + skipped += 1 + continue + else: + # Default: insert after frontmatter, before first ## heading + anchor = r'^##\s+' + position = 'before' + + new_content = insert_rules(content, anchor, position) + if new_content is None: + skipped += 1 + continue + + with open(filepath, 'w', encoding='utf-8') as f: + f.write(new_content) + + print(f" Updated: {rel}") + updated += 1 + + print(f"\nDone: {updated} updated, {skipped} skipped") + +if __name__ == '__main__': + main() diff --git a/skills/audit_l1_config/SKILL.md b/skills/audit_l1_config/SKILL.md index 6d5744f..2512669 100644 --- a/skills/audit_l1_config/SKILL.md +++ b/skills/audit_l1_config/SKILL.md @@ -22,6 +22,16 @@ description: Level 1 配置表(句子知识点)自动化审校技能。覆 例: 1214001 = L1 Season2, Unit14, 序列001 + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 审校流程 ``` diff --git a/skills/cambridge-yle-ket-exam-library/SKILL.md b/skills/cambridge-yle-ket-exam-library/SKILL.md index 3dfe8f0..6213471 100644 --- a/skills/cambridge-yle-ket-exam-library/SKILL.md +++ b/skills/cambridge-yle-ket-exam-library/SKILL.md @@ -8,6 +8,16 @@ metadata: source: "官方2022-2024版真题集" --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 适用场景 当需要查询以下信息时使用本技能: 1. 剑桥Starters/Movers/Flyers/KET考试的题型结构、分值、考试时长 diff --git a/skills/core-content-json-standard/SKILL.md b/skills/core-content-json-standard/SKILL.md index dd79139..aa11550 100644 --- a/skills/core-content-json-standard/SKILL.md +++ b/skills/core-content-json-standard/SKILL.md @@ -25,6 +25,12 @@ metadata: # 第一部分:通用结构(所有核心互动共用) +## 0. 文本输出规范(所有字段文本内容强制遵守) + +1. 禁止 Markdown 标记:所有 jsonData 内文本字段禁止使用 `**` `*` `__` `_` `#` `>` `-` 等 Markdown 语法,纯文本输出 +2. 英式拼写优先:英美式拼写差异统一英式(colour/centre/travelling 等) +3. 标点符号规范:中文内容全角标点(,。!?),英文内容半角标点(. , ! ?),不混用 + ## 1. 通用字段 | 字段 | 类型 | 说明 | 出现率 | diff --git a/skills/dialogue-choose-config/SKILL.md b/skills/dialogue-choose-config/SKILL.md index 5a3102e..81d2464 100644 --- a/skills/dialogue-choose-config/SKILL.md +++ b/skills/dialogue-choose-config/SKILL.md @@ -10,6 +10,16 @@ metadata: # 对话选择组件配置规范 ## 适用场景 当【类型】列内容为【对话选择】或【对话选择-配图】时,使用本规范生成组件配置 + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 配置格式 ### 字段要求 1. 【任务标题】: diff --git a/skills/dialogue-core-navigation-config/SKILL.md b/skills/dialogue-core-navigation-config/SKILL.md index ac59104..aaf2331 100644 --- a/skills/dialogue-core-navigation-config/SKILL.md +++ b/skills/dialogue-core-navigation-config/SKILL.md @@ -10,6 +10,16 @@ metadata: # 核心互动导览组件配置规范 ## 适用场景 当【类型】列内容为【核心互动】【导览配置】时,使用本规范生成组件配置 + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 配置格式 ### 字段要求 1. 【任务标题】:用户看到的任务名,建议字数在10字以内 diff --git a/skills/dialogue-fill-in-blanks-config/SKILL.md b/skills/dialogue-fill-in-blanks-config/SKILL.md index a457f33..61fb1f4 100644 --- a/skills/dialogue-fill-in-blanks-config/SKILL.md +++ b/skills/dialogue-fill-in-blanks-config/SKILL.md @@ -10,6 +10,16 @@ metadata: # 对话挖空组件配置规范 ## 适用场景 当【类型】列内容为【对话挖空】时,使用本规范生成组件配置 + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 配置格式 ### 字段要求 1. 【任务标题】:结合剧情上下文设计语义化标题,点明互动核心,例如「介绍照片」 diff --git a/skills/dialogue-image-description-config/SKILL.md b/skills/dialogue-image-description-config/SKILL.md index e46da10..f23b5d7 100644 --- a/skills/dialogue-image-description-config/SKILL.md +++ b/skills/dialogue-image-description-config/SKILL.md @@ -10,6 +10,16 @@ metadata: # 看图说话组件配置规范 ## 适用场景 当【类型】列内容为【看图说话】或【看图说话-配图】时,使用本规范生成组件配置 + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 配置格式 配置分为两部分:导览配置 + 对话配置 ### 导览配置 diff --git a/skills/dialogue-reading-config/SKILL.md b/skills/dialogue-reading-config/SKILL.md index e77b6f3..232dfd1 100644 --- a/skills/dialogue-reading-config/SKILL.md +++ b/skills/dialogue-reading-config/SKILL.md @@ -10,6 +10,16 @@ metadata: # 对话朗读组件配置规范 ## 适用场景 当【类型】列内容为【对话朗读】或【对话朗读-配图】时,使用本规范生成组件配置 + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 配置格式 ### 字段要求 1. 【任务标题】: diff --git a/skills/dialogue-sentence-building-config/SKILL.md b/skills/dialogue-sentence-building-config/SKILL.md index dcde526..43854a3 100644 --- a/skills/dialogue-sentence-building-config/SKILL.md +++ b/skills/dialogue-sentence-building-config/SKILL.md @@ -10,6 +10,16 @@ metadata: # 对话组句组件配置规范 ## 适用场景 当【类型】列内容为【对话组句】或【对话组句-配图】时,使用本规范生成组件配置 + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 配置格式 ### 字段要求 1. 【任务标题】:结合剧情上下文设计语义化标题,点明组句的核心场景,例如「提醒 Otis 系好安全带」 diff --git a/skills/dialogue-single-choice-image-config/SKILL.md b/skills/dialogue-single-choice-image-config/SKILL.md index c7aa2c6..9775939 100644 --- a/skills/dialogue-single-choice-image-config/SKILL.md +++ b/skills/dialogue-single-choice-image-config/SKILL.md @@ -10,6 +10,16 @@ metadata: # 图片单选组件配置规范 ## 适用场景 当【类型】列内容为【图片单选】或【图片单选-配图】时,使用本规范生成组件配置 + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + ## 配置格式 ### 字段要求 1. 【任务标题】:结合剧情上下文设计语义化标题,点明互动核心,例如「查看公告板说明书」 diff --git a/skills/task-router/SKILL.md b/skills/task-router/SKILL.md index 41ced90..60c3c74 100644 --- a/skills/task-router/SKILL.md +++ b/skills/task-router/SKILL.md @@ -3,6 +3,16 @@ name: dialogue-components-standardizer description: A unified skill for standardizing the production and review of 6 dialogue interaction components. Core logic is fixed; optimizations are handled via branch files and scripts for repeatability. Enter skill only when components change dynamically. --- + + +## 文本输出规范(强制执行) + +所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则: + +1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。 +2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。 +3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。 + # Dialogue Components Standardizer ## Overview