diff --git a/AGENTS.md b/AGENTS.md
index 33e287b..a1e7560 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -70,6 +70,7 @@
- `trash` > `rm`(可恢复胜过永远消失)
- 有疑问时,先问。
- 不要擅自修改底层配置(模型接入、系统设置等),遇到此类请求直接拒绝并告知技术负责人。
+- **禁止编造配置规范/模板/样例。** 编写任何 skill 的配置规范、格式模板、示例之前,必须先读取至少一条真实数据(从 bitable / wiki / 知识库)。不凭记忆、不凭类比、不凭"应该差不多"。写完模板后必须用真实数据回填验证——模板字段能否完整覆盖真实数据的所有内容。编造模板 = 生产事故。
## 密钥存储规范
@@ -242,7 +243,7 @@ Skills 按四层架构组织:
| `/组件生产`、`组件生产`、`组件回填` | `script-component-production` | `business_production/组件生产/skills/script-component-production/SKILL.md` |
| `组件设计`、`设计组件` | `component-design` | `business_production/组件生产/skills/component-design/SKILL.md` |
| `互动组件规范`、`组件格式参考` | `vala-interactive-components` | `business_production/组件生产/skills/vala-interactive-components/SKILL.md` |
-| `组件标准化`、`对话组件标准化` | `task-router`(`dialogue-components-standardizer`) | `business_production/组件生产/skills/task-router/SKILL.md` |
+| `组件标准化`、`对话组件标准化` | `dialogue-interaction-config` | `business_production/组件生产/skills/dialogue-interaction-config/SKILL.md` |
> **示例:** 用户发来飞书 wiki 链接说「组件生产」→ 调用 `script-component-production`,读剧本表 → 生成互动组件内容 → 回填对应列
@@ -250,32 +251,29 @@ Skills 按四层架构组织:
```
组件生产/
-├── skills/ # 8 个技能
+├── skills/ # 15 个技能
│ ├── script-component-production/ # 主技能(生产 pipeline)
│ │ └── assets/ # component_rules.yaml / review_checklist.yaml / skill.yml
-│ ├── component-design/ # 组件设计规范
-│ ├── vala-interactive-components/ # 互动组件格式参考
-│ ├── task-router/ # 组件标准化路由
-│ │ ├── component_configs.yaml # 组件类型配置映射
-│ │ ├── agents/openai.yaml # LLM agent 配置
-│ │ └── scripts/ # generate / review / route
-│ ├── dialogue-interaction-config/ # 对话类互动配置规范(被主技能引用)
-│ ├── dialogue-selective-reading-config/ # 对话选读配置(被 task-router 引用)
-│ ├── info-sentence-building-config/ # 信息组句配置(被 task-router 引用)
-│ └── info-word-spelling-config/ # 信息拼词配置(被 task-router 引用)
+│ ├── component-design/ # 组件设计规范(含各类型快速参考+详细规范索引)
+│ ├── vala-interactive-components/ # 互动组件官方配置库参考
+│ ├── dialogue-interaction-config/ # 对话类6类互动配置规范(含对话选读)
+│ ├── info-interaction-config/ # 信息类互动配置规范(拼词/组句/描写/补词/填词/填句)
+│ ├── picture-interaction-config/ # 图片类互动配置规范(单选/多选/有序/拖拽/互动)
+│ ├── item-interaction-config/ # 物品互动配置规范
+│ ├── pronunciation-interaction-config/ # 发音/语音/造句互动配置规范
+│ └── core-interaction-config/ # 核心互动配置规范(14类:听力/口语/阅读/写作)
├── scripts/ # 2 个核心脚本
│ ├── produce_components.py # 主 pipeline:读 Sheet → LLM 生成 → 校验 → 回填 H 列
│ └── validate_format.py # 格式校验:通用规则 + 题型专属规则(27 中互动 + 15 核心互动)
-├── backup/scripts/ # 历史脚本归档(15 个单次任务脚本)
-├── final/ # 历史交付产物(xlsx/md)
+├── backup/final/ # 历史交付产物(xlsx/md)
├── output/ # 运行时临时输出(JSON)
└── memory/ # 模块专属记忆
```
**子技能引用关系:**
-- `script-component-production` → 引用 `dialogue-interaction-config`
-- `task-router` → 引用 `dialogue-selective-reading-config` / `info-sentence-building-config` / `info-word-spelling-config`
-- `component-design` / `vala-interactive-components` → 独立触发,不引用其他子技能
+- `script-component-production` → 节点4.5按组件类型自动加载对应专项 Skill(共11条路由规则)
+- 15 个 Skill 中,`script-component-production` 为主入口,其余 14 个为按需加载的专项规范
+- `component-design` / `vala-interactive-components` → 也可独立触发,作为通用规范参考
**校验流程(pipeline 内置):**
```
diff --git a/MEMORY.md b/MEMORY.md
index d4b258d..1b6b5dd 100644
--- a/MEMORY.md
+++ b/MEMORY.md
@@ -124,6 +124,12 @@
(在此记录工作中总结的经验教训,供后续参考)
+### 禁止编造配置规范/模板/样例(2026-06-11)
+- **事故:** `core-interaction-config` 的合作阅读模板完全编造(情境引入/互动反馈/后置对话/资源配置),与真实数据结构不匹配
+- **根因:** 写配置规范时未查真实数据,凭类比中互动模板编造
+- **规则:** 编写任何 skill 的配置规范、格式模板、示例之前,必须先读取至少一条真实数据(从 bitable / wiki / 知识库)。不凭记忆、不凭类比、不凭"应该差不多"。写完模板后必须用真实数据回填验证
+- **已固化到:** SOUL.md 第四条底线 + AGENTS.md 红线
+
---
此文件由数字员工在工作过程中持续维护和更新。敏感信息和权限相关内容请维护在 `USER.md` 中。
diff --git a/SOUL.md b/SOUL.md
index 862a8be..d9ecd53 100644
--- a/SOUL.md
+++ b/SOUL.md
@@ -5,12 +5,14 @@
3. 性格定位:严谨细致零差错、响应高效不拖沓、熟悉全链路教研生产规则、输出内容标准化
4. 标识 Emoji:📝
-## 三条底线
+## 四条底线
🚫 **闭环交付。** 声称"已完成"之前,必须有验证证据——跑过命令、贴出输出、确认结果。没有证据的完成不是交付,是自嗨。
🚫 **事实驱动。** 说"可能是X问题"之前,先用工具验证。未经验证的归因不是诊断,是甩锅。
+🚫 **真实数据优先,禁止编造。** 编写任何配置规范、模板、样例之前,必须先读取至少一条真实数据。不凭记忆、不凭类比、不凭"应该差不多"。写完模板后,用真实数据回填验证——模板字段能否完整覆盖真实数据的所有内容。编造模板 = 生产事故。
+
🚫 **穷尽一切。** 说"我无法解决"之前,系统化排查必须走完。试了两种就放弃不叫能力边界,叫缺乏韧性。
## Owner 意识
diff --git a/business_production/组件生产/backup/scripts/convert_components_to_json.py b/business_production/组件生产/backup/scripts/convert_components_to_json.py
deleted file mode 100644
index b7cbac7..0000000
--- a/business_production/组件生产/backup/scripts/convert_components_to_json.py
+++ /dev/null
@@ -1,994 +0,0 @@
-#!/usr/bin/env python3
-"""
-将剧本表(Q8AyX5)中互动组件的文本配置转为结构化JSON并写回组件配置列。
-"""
-import json, subprocess, sys, re
-
-# --- Bot Token ---
-def get_token():
- APP_ID = "cli_a931175d41799cc7"
- import os
- with open(os.path.expanduser('/root/.openclaw/credentials/xiaoyan/config.json')) as f:
- cfg = json.load(f)
- APP_SECRET = cfg['apps'][0]['appSecret']
- r = subprocess.run([
- 'curl', '-s', '-X', 'POST',
- 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
- '-H', 'Content-Type: application/json',
- '-d', json.dumps({"app_id": APP_ID, "app_secret": APP_SECRET})
- ], capture_output=True, text=True)
- return json.loads(r.stdout)['tenant_access_token']
-
-TOKEN = get_token()
-SPREADSHEET_TOKEN = "VBozs8u24h4KgdtSSiFc9vHEnBd"
-SHEET_ID = "Q8AyX5"
-
-# ============================================================
-# Component configs (raw text from sheet column I)
-# ============================================================
-CONFIGS = {
- "1217201": {
- "type": "图片单选",
- "text": """【任务标题】
-为包裹找到正确的日期牌子
-
-【情境引入】
-Jay : Help me find the right place!
-
-【互动内容】
-Find the "Days Ago" sign.(音频)
-选项:
-00
-01
-02
-答案:
-00
-辅助信息:days ago 指"几天前"。
-
-【互动反馈】
-正确 Lin : Bingo!
-错误 Jay : No, look! This package is from 3 days ago!
-
-【后置对话】
-无""",
- },
- "1217202": {
- "type": "对话朗读",
- "text": """【任务标题】
-朗读90天前的包裹信息
-
-【资源配置】
-图片时机:互动内容
-
-【情境引入】
-无
-
-【互动内容】
-User: It's 90 days ago...(朗读)
-
-【后置对话】
-无""",
- },
- "1217203": {
- "type": "对话朗读",
- "text": """【任务标题】
-理解天数和月数的换算
-
-【资源配置】
-图片时机:互动内容
-
-【情境引入】
-User: No! 90 days! It is about...
-
-【互动内容】
-User: 3 months!(朗读)
-
-【后置对话】
-User: This is from months ago!""",
- },
- "1217204": {
- "type": "对话组句",
- "text": """【任务标题】
-用单词组句描述包裹信息
-
-【资源配置】
-图片时机:互动内容
-
-【情境引入】
-无
-
-【互动内容】
-要求:用所给单词或短语组句
-It says 24 months ago.(音频)
-选项1:it says
-选项2:months ago
-选项3:24
-
-答案:It says 24 months ago.
-
-【互动反馈】
-正确 无
-错误 Jay : Try again! Read what the package says.
-
-【后置对话】
-无""",
- },
- "1217205": {
- "type": "对话朗读",
- "text": """【任务标题】
-理解月数和年数的换算
-
-【资源配置】
-图片时机:互动内容
-
-【情境引入】
-无
-
-【互动内容】
-User: That's 2 years!(朗读)
-
-【后置对话】
-无""",
- },
- "1217206": {
- "type": "对话选读",
- "text": """【任务标题】
-选择你想表达的感受
-
-【资源配置】
-无
-
-【情境引入】
-无
-
-【互动内容】
-要求:选择一个你想表达的观点
-选项:(音频)
-选项1:That's a long time ago!
-- 反馈 Jay: You are right.
-选项2:That is long, long ago!
-- 反馈 Jay: You are right.
-
-【后置对话】
-无""",
- },
- "1217207": {
- "type": "图片多选",
- "text": """【任务标题】
-找出写有months ago的包裹
-
-【情境引入】
-空
-【互动内容】
-Find the "months ago" packages in the picture.(音频)
-选项:
-00
-01
-02
-答案:
-01
-02
-辅助信息:months ago 指"几个月前"。
-
-【互动反馈】
-正确 User : Those two are months ago!
-错误 Jay : Look again! Which ones say "months ago"?
-
-【后置对话】
-无""",
- },
- "1217208": {
- "type": "图片单选",
- "text": """【任务标题】
-找出写有一年前的包裹
-
-【情境引入】
-空
-
-【互动内容】
-Find the "year ago" package in the picture.(音频)
-选项:
-00
-01
-02
-答案:
-02
-辅助信息:a year ago 指"一年前"。
-
-【互动反馈】
-正确 User : This one is a year ago!
-错误 Jay : No, that's not right. Look again!
-
-【后置对话】
-无""",
- },
- "1217209": {
- "type": "对话挖空",
- "text": """【任务标题】
-补全对Sunny说的句子
-
-【资源配置】
-无
-
-【情境引入】
-空
-
-【互动内容】
-You must ___ it!(音频)
-选项1:be happy with(正确)
-选项2:happy with
-
-【互动反馈】
-正确 User : You must be happy with it!
-错误 Sunny : That doesn't sound quite right...
-
-【后置对话】
-无""",
- },
- "1217210": {
- "type": "对话选读",
- "text": """【任务标题】
-选择帮Grace拿包裹的说法
-
-【资源配置】
-无
-
-【情境引入】
-空
-
-【互动内容】
-要求:选择一个你想表达的观点
-选项:(音频)
-选项1:Let me get it!
-- 反馈 Grace: Thank you, kid.
-选项2:I will get it!
-- 反馈 Grace: Thank you, kid.
-
-【后置对话】
-无""",
- },
- "1217211": {
- "type": "对话朗读",
- "text": """【任务标题】
-对Anna的提醒
-
-【资源配置】
-图片时机:无
-
-【情境引入】
-无
-
-【互动内容】
-User: You will not be happy with it.(朗读)
-
-【后置对话】
-无""",
- },
- "1217212": {
- "type": "对话组句",
- "text": """【任务标题】
-用单词组句主动帮忙
-
-【资源配置】
-无
-
-【情境引入】
-空
-
-【互动内容】
-要求:用所给单词或短语组句
-Can I get it for you?(音频)
-选项1:for you
-选项2:can I
-选项3:get it
-
-答案:Can I get it for you?
-
-【互动反馈】
-正确 Jack : You are very kind. But I just want to say...
-错误 Jack: I beg your pardon?
-
-【后置对话】
-无""",
- },
- "1217213": {
- "type": "对话挖空",
- "text": """【任务标题】
-补全对Jack说的话
-
-【资源配置】
-图片时机:互动内容互动反馈
-
-【情境引入】
-无
-
-【互动内容】
-But this meat is from 2 ___ !(音频)
-选项1:years ago(正确)
-选项2:days ago
-
-【互动反馈】
-正确 Jack : Perfect!
-错误 Jack : No, look at the sign on it!
-
-【后置对话】
-无""",
- },
- "1217214": {
- "type": "听力拖拽",
- "text": """【任务标题】
-告诉 Lin 你们分发包裹的事迹
-
-【任务背景】
-包裹大作战!你和 Jay 热火朝天地干了半天,把很多包裹带给了他们的主人。快来回顾一下你们的战果吧!
-
-【通关知识】
-
-get v. 收到
-month n. 月
-year n. 年
-ago adv. 以前
-... month(s)/year(s) ago.
-
-【开场语】
-Lin: Come on, tell me what you did!
-
-【听力文本】
-# 文本 1
-Jay: Well, well, well! Listen up!
-Jay: Tom gets a pen!
-User: It is from 5 days ago!
-Jay: And Sunny gets a dress.
-Jay: It is from 6 months ago.
-Jay: Jack gets some meat from 2 years ago!
-
-【题目信息】
-
-#单空选择
-选项图片编号:00,01,02
-答案图片编号:
-01,00,02
-
-
-【学习过程】
-句子 1
-It is from 5 days ago!
-【ago】
-
-句子 2
-It is from 6 months ago. 【month】
-
-
-句子 3
-Jack gets some meat from 2 years ago! 【year】""",
- },
- "1217215": {
- "type": "对话选读",
- "text": """【任务标题】
-选择表达满意的方式
-
-【资源配置】
-无
-
-【情境引入】
-无
-
-【互动内容】
-要求:选择一个你想表达的观点
-选项:(音频)
-选项1:I am happy with it!
-- 反馈 Jay: That's good!
-选项2:I am happy with the result!
-- 反馈 Jay: That's good!
-
-【后置对话】
-无""",
- },
- "1217216": {
- "type": "对话挖空",
- "text": """【任务标题】
-补全User想要包裹的句子
-
-【资源配置】
-无
-
-【情境引入】
-空
-
-【互动内容】
-I want to ___ one for myself!(音频)
-选项1:get(正确)
-选项2:get up
-
-【互动反馈】
-正确 无
-错误 Jay : Hmm, that's not how we say it. Try again!
-
-【后置对话】
-无""",
- },
- "1217217": {
- "type": "对话朗读",
- "text": """【任务标题】
-朗读收到帽子的喜悦
-
-【资源配置】
-图片时机:无
-
-【情境引入】
-无
-
-【互动内容】
-User: Now I get my own hat!(朗读)
-
-【后置对话】
-无""",
- },
-}
-
-
-# ============================================================
-# Parsers for each component type
-# ============================================================
-
-def extract_section(text, key):
- """Extract content between 【key】and next section header 【...】."""
- # Match 【key】 then capture everything until next 【XXX】 header on its own line or end
- pattern = rf'【{re.escape(key)}】\s*\n?(.*?)(?=\n(?:【[^】]+】)\s*\n|\Z)'
- m = re.search(pattern, text, re.DOTALL)
- if m:
- return m.group(1).strip()
- return None
-
-def parse_context(text):
- """Parse context intro: '角色 : 台词' or '空' or '无'"""
- if not text or text in ('无', '空', ''):
- return None
- lines = [l.strip() for l in text.strip().split('\n') if l.strip()]
- result = []
- for line in lines:
- if ':' in line:
- parts = line.split(':', 1)
- result.append({"character": parts[0].strip(), "line": parts[1].strip()})
- elif ':' in line:
- parts = line.split(':', 1)
- result.append({"character": parts[0].strip(), "line": parts[1].strip()})
- else:
- result.append(line)
- return result if result else None
-
-def parse_feedback(text):
- """Parse feedback: 正确/错误 角色 : 台词"""
- if not text or text == '无':
- return {"correct": None, "incorrect": None}
-
- result = {"correct": None, "incorrect": None}
- lines = text.strip().split('\n')
-
- current_type = None
- for line in lines:
- line = line.strip()
- if not line:
- continue
- if line.startswith('正确'):
- current_type = 'correct'
- content = line[2:].strip()
- if ':' in content:
- parts = content.split(':', 1)
- char = parts[0].strip()
- msg = parts[1].strip()
- if msg == '无':
- result['correct'] = None
- else:
- result['correct'] = {"character": char, "line": msg}
- elif content == '无':
- result['correct'] = None
- elif line.startswith('错误'):
- current_type = 'incorrect'
- content = line[2:].strip()
- if ':' in content:
- parts = content.split(':', 1)
- result['incorrect'] = {"character": parts[0].strip(), "line": parts[1].strip()}
- elif ':' in content:
- parts = content.split(':', 1)
- result['incorrect'] = {"character": parts[0].strip(), "line": parts[1].strip()}
- return result
-
-def parse_selective_options(text):
- """Parse 对话选读 options: 选项N:text - 反馈 X: line"""
- options = []
- lines = text.strip().split('\n')
- i = 0
- while i < len(lines):
- line = lines[i].strip()
- m = re.match(r'选项(\d+)[::]\s*(.+)', line)
- if m:
- idx = int(m.group(1))
- opt_text = m.group(2).strip()
- feedback = None
- # Check next line for feedback
- if i + 1 < len(lines):
- next_line = lines[i + 1].strip()
- fm = re.match(r'[-–]\s*反馈\s*([^::]+)[::]\s*(.+)', next_line)
- if fm:
- feedback = {"character": fm.group(1).strip(), "line": fm.group(2).strip()}
- i += 1
- options.append({"index": idx, "text": opt_text, "feedback": feedback})
- i += 1
- return options
-
-def parse_image_options(text):
- """Parse image choice options: 00, 01, 02 etc."""
- options = []
- lines = text.strip().split('\n')
- in_options = False
- for line in lines:
- line = line.strip()
- if line == '选项:':
- in_options = True
- continue
- if in_options:
- if re.match(r'^\d{2}$', line):
- options.append(line)
- else:
- break
- return options
-
-def parse_fill_options(text):
- """Parse fill-in-blanks options: 选项N:text(正确)"""
- options = []
- lines = text.strip().split('\n')
- for line in lines:
- line = line.strip()
- m = re.match(r'选项(\d+)[::]\s*(.+)', line)
- if m:
- idx = int(m.group(1))
- opt_text = m.group(2).strip()
- correct = False
- if '(正确)' in opt_text:
- correct = True
- opt_text = opt_text.replace('(正确)', '').strip()
- options.append({"index": idx, "text": opt_text, "correct": correct})
- return options
-
-def parse_sentence_options(text):
- """Parse sentence building options: 选项N:text"""
- options = []
- lines = text.strip().split('\n')
- for line in lines:
- line = line.strip()
- m = re.match(r'选项(\d+)[::]\s*(.+)', line)
- if m:
- idx = int(m.group(1))
- opt_text = m.group(2).strip()
- options.append({"index": idx, "text": opt_text})
- return options
-
-
-# ============================================================
-# Converters
-# ============================================================
-
-def convert_choice_image(cid, text):
- """图片单选 / 图片多选"""
- is_multi = CONFIGS[cid]['type'] == '图片多选'
-
- raw_interaction = extract_section(text, '互动内容')
- context = extract_section(text, '情境引入')
- feedback = extract_section(text, '互动反馈')
- post = extract_section(text, '后置对话')
-
- # Parse interaction
- interaction_lines = raw_interaction.strip().split('\n')
- instruction = interaction_lines[0].strip()
- audio = '(音频)' in instruction
- instruction = instruction.replace('(音频)', '').strip()
-
- options = []
- answers = []
- hint = None
- in_options = False
- in_answer = False
- in_hint = False
-
- for line in interaction_lines[1:]:
- line = line.strip()
- if line == '选项:':
- in_options = True
- continue
- if in_options and re.match(r'^\d{2}$', line):
- options.append(line)
- continue
- if '答案:' in line:
- in_options = False
- in_answer = True
- ans_text = line.replace('答案:', '').strip()
- if ans_text:
- answers.append(ans_text)
- continue
- if in_answer:
- if re.match(r'^\d{2}$', line):
- answers.append(line)
- elif '辅助信息' in line:
- in_answer = False
- in_hint = True
- hint = line.replace('辅助信息:', '').strip()
- else:
- in_answer = False
- continue
- if in_hint:
- continue
- if '辅助信息' in line:
- hint = line.replace('辅助信息:', '').strip()
- continue
-
- result = {
- "componentType": CONFIGS[cid]['type'],
- "taskTitle": extract_section(text, '任务标题'),
- "contextIntro": parse_context(context),
- "interaction": {
- "instruction": instruction,
- "audio": audio,
- "options": options,
- "answers": answers,
- "hint": hint
- },
- "feedback": parse_feedback(feedback),
- "postDialogue": parse_context(post)
- }
- return result
-
-def convert_reading(cid, text):
- """对话朗读"""
- return {
- "componentType": "对话朗读",
- "taskTitle": extract_section(text, '任务标题'),
- "resourceConfig": extract_section(text, '资源配置') or None,
- "contextIntro": parse_context(extract_section(text, '情境引入')),
- "interaction": {
- "sentence": (extract_section(text, '互动内容') or '').replace('(朗读)', '').strip(),
- "audio": True
- },
- "postDialogue": parse_context(extract_section(text, '后置对话'))
- }
-
-def convert_sentence_building(cid, text):
- """对话组句"""
- raw_interaction = extract_section(text, '互动内容')
- resource = extract_section(text, '资源配置') or None
- context = extract_section(text, '情境引入')
- feedback = extract_section(text, '互动反馈')
- post = extract_section(text, '后置对话')
-
- interaction_lines = raw_interaction.strip().split('\n')
- requirement = None
- sentence = None
- audio = True
- options = []
- answer = None
- hint = None
-
- # Parse interaction
- i = 0
- if interaction_lines[0].startswith('要求:'):
- requirement = interaction_lines[0].replace('要求:', '').strip()
- i = 1
-
- # Find sentence line (ends with (音频))
- for j in range(i, len(interaction_lines)):
- line = interaction_lines[j].strip()
- if '(音频)' in line:
- sentence = line.replace('(音频)', '').strip()
- i = j + 1
- break
- elif re.match(r'选项\d+', line):
- # No sentence line found, use requirement as sentence
- i = j
- break
-
- # Parse options
- for j in range(i, len(interaction_lines)):
- line = interaction_lines[j].strip()
- m = re.match(r'选项(\d+)[::]\s*(.+)', line)
- if m:
- options.append({"index": int(m.group(1)), "text": m.group(2).strip()})
- elif '答案:' in line:
- answer = line.replace('答案:', '').strip()
- elif '辅助信息:' in line:
- hint = line.replace('辅助信息:', '').strip()
-
- return {
- "componentType": "对话组句",
- "taskTitle": extract_section(text, '任务标题'),
- "resourceConfig": resource,
- "contextIntro": parse_context(context),
- "interaction": {
- "requirement": requirement,
- "sentence": sentence,
- "audio": audio,
- "options": options,
- "answer": answer,
- "hint": hint
- },
- "feedback": parse_feedback(feedback),
- "postDialogue": parse_context(post)
- }
-
-def convert_selective_reading(cid, text):
- """对话选读"""
- raw_interaction = extract_section(text, '互动内容')
- resource = extract_section(text, '资源配置') or None
- context = extract_section(text, '情境引入')
- post = extract_section(text, '后置对话')
-
- interaction_lines = raw_interaction.strip().split('\n')
- requirement = interaction_lines[0].strip()
- audio = '(音频)' in raw_interaction
- if requirement.startswith('要求:'):
- requirement = requirement.replace('要求:', '').strip()
-
- options = parse_selective_options(raw_interaction)
-
- return {
- "componentType": "对话选读",
- "taskTitle": extract_section(text, '任务标题'),
- "resourceConfig": resource,
- "contextIntro": parse_context(context),
- "interaction": {
- "requirement": requirement,
- "audio": audio,
- "options": options
- },
- "postDialogue": parse_context(post)
- }
-
-def convert_fill_blanks(cid, text):
- """对话挖空"""
- raw_interaction = extract_section(text, '互动内容')
- resource = extract_section(text, '资源配置') or None
- context = extract_section(text, '情境引入')
- feedback = extract_section(text, '互动反馈')
- post = extract_section(text, '后置对话')
-
- interaction_lines = raw_interaction.strip().split('\n')
- sentence = None
- options = []
-
- for line in interaction_lines:
- line = line.strip()
- if '(音频)' in line and not line.startswith('选项'):
- sentence = line.replace('(音频)', '').strip()
- m = re.match(r'选项(\d+)[::]\s*(.+)', line)
- if m:
- opt_text = m.group(2).strip()
- correct = '(正确)' in opt_text
- opt_text = opt_text.replace('(正确)', '').strip()
- options.append({"index": int(m.group(1)), "text": opt_text, "correct": correct})
-
- return {
- "componentType": "对话挖空",
- "taskTitle": extract_section(text, '任务标题'),
- "resourceConfig": resource,
- "contextIntro": parse_context(context),
- "interaction": {
- "sentence": sentence,
- "audio": True,
- "options": options
- },
- "feedback": parse_feedback(feedback),
- "postDialogue": parse_context(post)
- }
-
-def convert_listening_drag(cid, text):
- """听力拖拽 → core_listening_drag JSON"""
- task_title = extract_section(text, '任务标题')
- task_bg = extract_section(text, '任务背景') or ''
- knowledge = extract_section(text, '通关知识') or ''
- opening = extract_section(text, '开场语') or ''
- audio_text = extract_section(text, '听力文本') or ''
- question_info = extract_section(text, '题目信息') or ''
- learning = extract_section(text, '学习过程') or ''
-
- # Parse audio text into dialogs
- dialog_list = []
- for line in audio_text.strip().split('\n'):
- line = line.strip()
- if not line or line.startswith('#'):
- continue
- if ':' in line or ':' in line:
- sep = ':' if ':' in line else ':'
- parts = line.split(sep, 1)
- dialog_list.append({"character": parts[0].strip(), "line": parts[1].strip()})
-
- # Parse question info
- option_images = []
- answer_images = []
- for line in question_info.strip().split('\n'):
- line = line.strip()
- if '选项图片编号' in line:
- option_images = [x.strip() for x in line.split(':', 1)[1].split(',') if x.strip()]
- if '答案图片编号' in line:
- # Answer on next line
- pass
-
- # Get answer from question info - look for answer after 答案图片编号
- q_lines = question_info.strip().split('\n')
- for i, line in enumerate(q_lines):
- if '答案图片编号' in line and i + 1 < len(q_lines):
- answer_images = [x.strip() for x in q_lines[i+1].split(',') if x.strip() and x.strip() != '答案图片编号']
-
- # For 听力拖拽, 【学习过程】 is the LAST section and contains inline 【kp】.
- # Extract it manually: everything after 【学习过程】
- lp_match = re.search(r'【学习过程】\s*\n(.*)', text, re.DOTALL)
- learning = lp_match.group(1).strip() if lp_match else ''
-
- learning_steps = []
- # Split by sentence markers
- blocks = re.split(r'\n(?=句子\s*\d*)', learning)
- for block in blocks:
- block = block.strip()
- if not block:
- continue
- # Remove the 句子 N header
- block = re.sub(r'^句子\s*\d*\s*\n?', '', block).strip()
- if not block:
- continue
- # Extract kp from 【...】
- kp_match = re.search(r'【(.+?)】', block)
- kp = kp_match.group(1).strip() if kp_match else ""
- # Extract sentence (text before 【 or whole block if no 【)
- if kp_match:
- sentence = block[:kp_match.start()].strip()
- else:
- sentence = block.strip()
- if sentence or kp:
- learning_steps.append({"sentence": sentence, "knowledgePoint": kp})
-
- # Scene description
- scene_desc = f"{task_bg}\n\n{opening}"
-
- return {
- "componentType": "听力拖拽",
- "cType": "core_listening_drag",
- "taskData": {
- "cType": "core_listening_drag",
- "cId": cid,
- "title": task_title,
- "sceneDesc": scene_desc,
- "key": "ago, month, year, get"
- },
- "dialogList": dialog_list,
- "preDialog": [],
- "questionList": [
- {
- "type": "drag_match",
- "optionImages": option_images,
- "answerImages": answer_images,
- "itemCount": len(option_images)
- }
- ],
- "learningData": {
- "learningPart": learning_steps,
- "closing": ""
- },
- "audioText": audio_text,
- "knowledgeSummary": knowledge
- }
-
-
-# ============================================================
-# Main conversion
-# ============================================================
-
-CONVERTERS = {
- "图片单选": convert_choice_image,
- "图片多选": convert_choice_image,
- "对话朗读": convert_reading,
- "对话组句": convert_sentence_building,
- "对话选读": convert_selective_reading,
- "对话挖空": convert_fill_blanks,
- "听力拖拽": convert_listening_drag,
-}
-
-# Component row mapping (from sheet data: which row has which component ID)
-COMPONENT_ROWS = {
- "1217201": 33,
- "1217202": 40,
- "1217203": 43,
- "1217204": 50,
- "1217205": 51,
- "1217206": 53,
- "1217207": 68,
- "1217208": 70,
- "1217209": 89,
- "1217210": 95,
- "1217211": 107,
- "1217212": 120,
- "1217213": 123,
- "1217214": 157,
- "1217215": 164,
- "1217216": 168,
- "1217217": 173,
-}
-
-
-def write_cell(row, col_letter, value, token):
- """Write a single cell to the sheet."""
- cell_range = f"{SHEET_ID}!{col_letter}{row}:{col_letter}{row}"
- payload = {
- "valueRange": {
- "range": cell_range,
- "values": [[value]]
- }
- }
- r = subprocess.run([
- 'curl', '-s', '-X', 'PUT',
- f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/values',
- '-H', f'Authorization: Bearer {token}',
- '-H', 'Content-Type: application/json',
- '-d', json.dumps(payload, ensure_ascii=False)
- ], capture_output=True, text=True)
- result = json.loads(r.stdout)
- if result.get('code') != 0:
- print(f" ❌ Write failed: {result}", file=sys.stderr)
- return False
- return True
-
-
-def main():
- results = {}
- for cid, cfg in CONFIGS.items():
- ctype = cfg['type']
- converter = CONVERTERS.get(ctype)
- if not converter:
- print(f"⚠️ Unknown type {ctype} for {cid}", file=sys.stderr)
- continue
- try:
- json_data = converter(cid, cfg['text'])
- results[cid] = json_data
- print(f"✅ {cid} ({ctype}) → JSON OK")
- except Exception as e:
- print(f"❌ {cid} ({ctype}) → ERROR: {e}", file=sys.stderr)
- import traceback
- traceback.print_exc()
-
- # Print all JSONs for review
- print("\n" + "=" * 60)
- print("GENERATED JSONS")
- print("=" * 60)
- for cid, data in results.items():
- print(f"\n--- {cid} ({data['componentType']}) ---")
- print(json.dumps(data, ensure_ascii=False, indent=2))
-
- # Save to file for inspection
- with open('/root/.openclaw/workspace-xiaoyan/output/component_jsons.json', 'w', encoding='utf-8') as f:
- json.dump(results, f, ensure_ascii=False, indent=2)
- print(f"\n📁 Saved to output/component_jsons.json")
-
- # Write back to sheet
- print("\n" + "=" * 60)
- print("WRITING BACK TO SHEET")
- print("=" * 60)
-
- # Re-fetch token (may have expired)
- token = get_token()
-
- success = 0
- fail = 0
- for cid, data in results.items():
- row = COMPONENT_ROWS.get(cid)
- if not row:
- print(f"⚠️ {cid}: no row mapping, skipped")
- continue
- json_str = json.dumps(data, ensure_ascii=False)
- if write_cell(row, 'I', json_str, token):
- print(f"✅ {cid} → row {row} written")
- success += 1
- else:
- fail += 1
-
- print(f"\nDone: {success} written, {fail} failed")
-
-
-if __name__ == '__main__':
- main()
diff --git a/business_production/组件生产/backup/scripts/dialogue_backfill.py b/business_production/组件生产/backup/scripts/dialogue_backfill.py
deleted file mode 100644
index 1b247e0..0000000
--- a/business_production/组件生产/backup/scripts/dialogue_backfill.py
+++ /dev/null
@@ -1,264 +0,0 @@
-#!/usr/bin/env python3
-"""
-英文台词优化 & 回填脚本
-基于 MEMORY.md 的「对话台词优化通用规则」对列 E(编剧台词)进行优化,写入列 F
-知识点:grandmother, grandfather, visit (v.), today (n.)
-句型知识点:... visit+sb, Today is...
-"""
-import json, subprocess, sys
-
-# Rules:
-# 0. 知识点词汇/句型必须保留 (grandmother/grandfather/visit/today / Today is... / ...visit+sb)
-# 1. 精简:删除冗余
-# 2. 口语化:自然对话,低龄友好,增语气词
-# 3. 拆分:>8词拆为2-3短句
-# 4. 情绪匹配:匹配角色情绪
-# 5. 场景适配:不重复画面信息
-# 6. 单句≤10词,知识点句≤7词
-
-# Knowledge-point words to preserve
-KP_WORDS = {"grandmother", "grandfather", "visit", "today", "today's"}
-
-# Mapping: (row_index_0based_sheet) → optimized F value
-# Only rows where D (role) and E (script line) are non-null
-# Row index = sheet row - 1 (0-based from API)
-# Sheet row 1 = header → skip
-# Sheet row 2 = API row index 1
-
-optimizations = {}
-
-def add(row_sheet, f_value):
- """row_sheet is 1-indexed sheet row number"""
- optimizations[row_sheet - 1] = f_value # convert to 0-indexed
-
-# === SECTION 1: 开场 - 门口 ===
-add(3, "Open up!")
-add(4, "Your letter is here!")
-add(6, "Nobody answers?")
-add(7, "Alright... I'll go in myself.")
-add(9, "Whoa! What a mess!")
-add(11, "What's wrong?")
-add(12, "Vicky? Can you hear me?")
-
-# === SECTION 2: 发现家里很乱 ===
-add(14, "Today is a No-Mom-and-Dad day!") # 知识点 Today is
-add(15, "Our parents aren't home!") # 精简 + 口语化
-add(16, "So we can do whatever we want!")
-add(17, "Really?")
-add(19, "Yes!")
-add(20, "Today is a good day!") # 知识点 Today is
-add(21, "Huh?")
-add(22, "Are you sure today is a good day?") # 知识点 today
-
-# === SECTION 3: 撞到用户,道歉 ===
-add(23, "So on a good day, nobody says sorry?") # 精简 14→8词
-add(24, "Eva, Peter, say sorry.")
-add(25, "Okay. We're sorry.") # 口语化
-
-# === SECTION 4: 继续对话 ===
-add(27, "Ah, kids.")
-add(28, "Come visit us!") # 知识点 visit,修正"Welcome to visit us"不自然表达
-add(29, "Oh, I'm not here to visit.") # 知识点 visit,口语化
-add(30, "I'm here to give you something.") # 口语化
-
-# === SECTION 5: 电话 ===
-add(33, "Hello? Grandfather and grandmother, how are you?") # 知识点 grandfather/grandmother
-add(34, "Good, good! We're great!") # 口语化
-add(35, "How are you all, my lovely grandchildren?")
-add(36, "We're great! Today is so much fun!") # 知识点 Today is, 口语化
-add(37, "Great to hear that!")
-add(38, "Are you ready for us?") # 精简
-add(39, "I'm so excited to visit you all!") # 知识点 visit, 口语化
-add(40, "Sure! When will you visit us?") # 知识点 visit
-add(41, "Today is the day, of course!") # 知识点 Today is
-add(42, "What? You're both coming today?") # 口语化修复
-add(43, "Yes! Me and Justin. Your grandmother and grandfather.") # 知识点, 修正 typo gandfather
-add(44, "We sent you a letter. Remember?") # 口语化
-add(45, "See you later!")
-add(46, "I love you! Bye!")
-
-# === SECTION 6: 惊慌 ===
-add(48, "Oh no! What did they say on the phone?") # 修正语法 in→on
-add(50, "Your grandfather and grandmother are coming to visit you!") # 知识点, 修正 is→are
-add(51, "On your good day.")
-
-# === SECTION 7: 紧急动员 ===
-add(54, "Eva! Peter! Alex! We're in trouble!") # 口语化
-add(56, "What happened?")
-add(57, "Grandfather and grandmother are coming to visit us!") # 知识点, 修正 is→are
-add(58, "So what?")
-add(59, "Today! Right now!") # 精简 On today→Today
-add(62, "No, not today...") # 修正 on today→today
-add(63, "Look at this place!")
-
-# === SECTION 8: 用户互动 ===
-add(65, "Yes, today is a total mess.") # 知识点 today
-add(66, "It's not the best day for visitors.") # 知识点 visit→visitors 可接受变体, 口语化
-add(68, "They could be here at any minute!") # 口语化
-
-# === SECTION 9: 爷爷奶奶会生气 ===
-add(70, "How will they feel about this?")
-add(72, "Grandfather and grandmother will be so upset!") # 知识点, 精简 mad→upset (正向引导)
-add(74, "What should we do?")
-add(76, "Don't worry! I'll help you clean up!") # 增加具体动作词
-add(77, "Okay, first pick up the toys from the floor.")
-
-# === SECTION 10: 收拾 ===
-add(80, "Oh no! No time to put these away!") # 精简
-add(81, "Put them in the cupboard!") # 修正 it→them (玩具是复数)
-add(83, "Your grandfather and grandmother won't see!") # 知识点
-add(85, "Good idea!")
-add(88, "All done!")
-add(89, "We need to clean the floor!")
-add(90, "I'll do it!") # 口语化
-
-# === SECTION 11: 扫地机器人 ===
-add(94, "Will Grandfather and Grandmother be happy?") # 知识点, satisfied→happy (低龄词)
-add(95, "Well... this will do for now.") # 口语化
-add(96, "Before your grandfather and grandmother come to visit.") # 知识点
-
-# === SECTION 12: 沙发污渍 ===
-add(99, "Alex! The sofa is a mess!") # 精简, 正向化 (不说 you made it dirty)
-add(100, "I'll clean it.") # 口语化
-add(103, "I can't get the chocolate off!")
-add(104, "I'm good at many things. Just not housework!") # 拆分 >8词, 口语化
-
-# === SECTION 13: 更乱 ===
-add(106, "Oh no! We can't clean up in time!") # 精简+口语化
-add(107, "I wish we had more time for this!")
-add(108, "Why today, of all days?") # 口语化
-add(109, "I don't want them to see our house like this.") # 口语化修正
-add(110, "Why didn't they tell us earlier?") # 口语化修正
-
-# === SECTION 14: 信 ===
-add(113, "I think they did tell you...") # 精简+口语化
-add(114, "In this letter.")
-add(116, "What is in this letter?")
-
-# === SECTION 15: 核心互动-听力 (Justin念信) ===
-add(119, "Hi, your grandfather is writing this letter.") # 知识点 grandfather
-add(120, "I will come to visit you guys.") # 知识点 visit
-add(121, "Your grandmother will visit you too!") # 知识点 grandmother, visit
-add(122, "We love you, see you soon!")
-
-# === SECTION 16: 反应 ===
-add(124, "They were so happy to visit you!") # 知识点 visit
-add(125, "Yes. We should be happy too.")
-add(127, "We should not be grumpy like this.")
-add(128, "Let's do something to welcome them!") # 口语化
-add(130, "You can make something they like!") # 知识点, 精简
-add(131, "What is their favourite food?")
-
-# === SECTION 17: 苹果派 ===
-add(133, "Grandmother likes apples.") # 知识点 grandmother, 修正 apple→apples
-add(134, "Grandfather likes pie.") # 知识点 grandfather
-add(135, "Then you can make apple pie for them!")
-add(136, "I remember the recipe.")
-add(137, "I can fix the cooking robot.")
-add(139, "Okay! Apple pie is today's welcome gift!") # 知识点 today
-
-# === SECTION 18: 完成了 ===
-add(142, "You did it!") # 口语化 (替换 You finished)
-add(143, "Now we just wait for them to arrive.") # 精简
-
-# === SECTION 19: 爷爷奶奶来了 ===
-add(146, "They're coming!") # 口语化
-add(148, "Who wants a big hug from Grandfather?") # 知识点, 修正语法
-add(149, "Me! Me!")
-add(150, "Who wants Grandmother's homemade candy?") # 知识点, 修正 grandmother→Grandmother's, handmade→homemade(低龄)
-add(151, "Me! Me!")
-add(153, "We made something for you.")
-add(154, "Mmm! What's that smell? Is that a pie?") # 口语化
-add(155, "I smell apples!") # 修正 apple→apples
-add(156, "Whoa! I know that smell! Apple pie!") # 口语化
-add(157, "That is our favourite!")
-add(159, "Oh, you have a friend over!") # 修正 in home→over
-add(161, "Hello! I am here to visit Vicky.") # 知识点 visit
-add(162, "Nice to meet you again!")
-add(163, "I guess you helped out today too.") # 知识点 today, 口语化修正
-
-# === SECTION 20: 结尾 ===
-add(165, "Today seems pretty busy.") # 知识点 today
-add(167, "Yes, we made a little mess before you came.") # 知识点 visit, 口语化修正
-add(168, "Today was not easy.") # 知识点 today, 修正时态 is→was
-add(170, "That's okay.") # 口语化
-add(172, "Grandfather and Grandmother can fix anything.") # 知识点, 口语化 everything→anything
-add(173, "That's what family is for!") # 口语化重构
-add(174, "Mess or not, we love seeing you!") # 口语化重构
-
-
-# Print summary and build write payload
-print(f"Total lines to write: {len(optimizations)}")
-
-# Build values payload per row
-# We need to identify continuous ranges for efficiency
-# But since the API supports writing individual ranges, let's batch by nearby rows
-
-# Sort by row index
-sorted_rows = sorted(optimizations.items())
-
-# Build the complete column F data: for each row, either the optimized value or empty string ("")
-# We need all rows 2-149 (sheet rows)
-all_values = []
-for row_idx in range(1, 150): # 1 = sheet row 2, 149 = sheet row 150
- if row_idx in optimizations:
- all_values.append([optimizations[row_idx]])
- else:
- all_values.append([""])
-
-# Write back - use PUT to write the entire column at once
-# We write empty strings for non-dialogue rows to clear previous content
-
-import os
-import json as jmod
-
-app_id = "cli_a931175d41799cc7"
-config_path = "/root/.openclaw/credentials/xiaoyan/config.json"
-with open(config_path) as f:
- cfg = jmod.load(f)
-app_secret = cfg["apps"][0]["appSecret"]
-
-# Get token
-result = subprocess.run([
- "curl", "-s", "-X", "POST",
- "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
- "-H", "Content-Type: application/json",
- "-d", jmod.dumps({"app_id": app_id, "app_secret": app_secret})
-], capture_output=True, text=True)
-token = jmod.loads(result.stdout)["tenant_access_token"]
-
-spreadsheet_token = "DA7csROG6hmnQMt59oScOLRfnWc"
-sheet_id = "Nr3Ovs"
-
-# Write in batches of 50 rows to avoid too-large payloads
-batch_size = 50
-for batch_start in range(0, len(all_values), batch_size):
- batch = all_values[batch_start:batch_start + batch_size]
- # Sheet rows: batch_start + 2 to batch_start + 1 + len(batch)
- start_row = batch_start + 2
- end_row = batch_start + 1 + len(batch)
-
- range_str = f"{sheet_id}!F{start_row}:F{end_row}"
-
- payload = {
- "valueRange": {
- "range": range_str,
- "values": batch
- }
- }
-
- result = subprocess.run([
- "curl", "-s", "-X", "PUT",
- f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values",
- "-H", f"Authorization: Bearer {token}",
- "-H", "Content-Type: application/json",
- "-d", jmod.dumps(payload)
- ], capture_output=True, text=True)
-
- resp = jmod.loads(result.stdout)
- print(f"Batch F{start_row}:F{end_row} → code={resp.get('code')}, msg={resp.get('msg')}")
- if resp.get("code") != 0:
- print(f" ERROR: {result.stdout[:200]}")
- sys.exit(1)
-
-print("All batches written successfully!")
diff --git a/business_production/组件生产/backup/scripts/dialogue_backfill_v2.py b/business_production/组件生产/backup/scripts/dialogue_backfill_v2.py
deleted file mode 100644
index 6f5e5a4..0000000
--- a/business_production/组件生产/backup/scripts/dialogue_backfill_v2.py
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/usr/bin/env python3
-"""
-英文台词优化 & 回填脚本 v2 — 使用精确行号
-规则:MEMORY.md 对话台词优化通用规则
-知识点:grandmother, grandfather, visit, today
-句型知识点:... visit+sb, Today is...
-"""
-import json, subprocess
-
-# (sheet_row, optimized_F_value) — exact sheet row numbers
-rows = [
- (3, "Open up!"),
- (4, "Your letter is here!"),
- (6, "Nobody answers?"),
- (7, "Alright... I'll go in myself."),
- (9, "Whoa! What a mess!"),
- (11, "What's wrong?"),
- (12, "Vicky? Can you hear me?"),
- (14, "Today is a No-Mom-and-Dad day!"),
- (15, "Our parents aren't home!"),
- (16, "So we can do whatever we want!"),
- (17, "Really?"),
- (19, "Yes!"),
- (20, "Today is a good day!"),
- (21, "Huh?"),
- (22, "Are you sure today is a good day?"),
- (23, "So on a good day, nobody says sorry?"),
- (24, "Eva, Peter, say sorry."),
- (25, "Okay. We're sorry."),
- (27, "Ah, kids."),
- (28, "Come visit us!"),
- (29, "Oh, I'm not here to visit."),
- (30, "I'm here to give you something."),
- (32, "Wait a moment."),
- (34, "Hello? Grandfather and grandmother, how are you?"),
- (35, "Good, good! We're great!"),
- (36, "How are you all, my lovely grandchildren?"),
- (37, "We're great! Today is so much fun!"),
- (38, "Great to hear that!"),
- (39, "Are you ready for us?"),
- (40, "I'm so excited to visit you all!"),
- (41, "Sure! When will you visit us?"),
- (42, "Today is the day, of course!"),
- (43, "What? You're both coming today?"),
- (44, "Yes! Me and Justin. Your grandmother and grandfather."),
- (45, "We sent you a letter. Remember?"),
- (46, "See you later!"),
- (47, "I love you! Bye!"),
- (49, "Oh no! What did they say on the phone?"),
- (50, "Your grandfather and grandmother are coming to visit you!"),
- (51, "On your good day."),
- (53, "Eva! Peter! Alex! We're in trouble!"),
- (55, "What happened?"),
- (56, "Grandfather and grandmother are coming to visit us!"),
- (57, "So what?"),
- (58, "Today! Right now!"),
- (60, "No, not today..."),
- (61, "Look at this place!"),
- (62, "Yes, today is a total mess."),
- (63, "It's not the best day for visitors."),
- (64, "They could be here at any minute!"),
- (65, "How will they feel about this?"),
- (67, "Grandfather and grandmother will be so upset!"),
- (69, "What should we do?"),
- (70, "Don't worry! I'll help you clean up!"),
- (71, "Okay, first pick up the toys from the floor."),
- (73, "Oh no! No time to put these away!"),
- (74, "Put them in the cupboard!"),
- (75, "Your grandfather and grandmother won't see!"),
- (76, "Good idea!"),
- (79, "All done!"),
- (80, "We need to clean the floor!"),
- (81, "I'll do it!"),
- (84, "Will Grandfather and Grandmother be happy?"),
- (85, "Well... this will do for now."),
- (86, "Before your grandfather and grandmother come to visit."),
- (88, "Alex! The sofa is a mess!"),
- (89, "I'll clean it."),
- (91, "I can't get the chocolate off!"),
- (92, "I'm good at many things. Just not housework!"),
- (94, "Oh no! We can't clean up in time!"),
- (95, "I wish we had more time for this!"),
- (96, "Why today, of all days?"),
- (97, "I don't want them to see our house like this."),
- (98, "Why didn't they tell us earlier?"),
- (100, "I think they did tell you..."),
- (101, "In this letter."),
- (102, "What is in this letter?"),
- (104, "Hi, your grandfather is writing this letter."),
- (105, "I will come to visit you guys."),
- (106, "Your grandmother will visit you too!"),
- (107, "We love you, see you soon!"),
- (108, "They were so happy to visit you!"),
- (109, "Yes. We should be happy too."),
- (110, "We should not be grumpy like this."),
- (111, "Let's do something to welcome them!"),
- (112, "You can make something they like!"),
- (113, "What is their favourite food?"),
- (114, "Grandmother likes apples."),
- (115, "Grandfather likes pie."),
- (116, "Then you can make apple pie for them!"),
- (117, "I remember the recipe."),
- (118, "I can fix the cooking robot."),
- (119, "Okay! Apple pie is today's welcome gift!"),
- (121, "You did it!"),
- (122, "Now we just wait for them to arrive."),
- (124, "They're coming!"),
- (126, "Who wants a big hug from Grandfather?"),
- (127, "Me! Me!"),
- (128, "Who wants Grandmother's homemade candy?"),
- (129, "Me! Me!"),
- (131, "We made something for you."),
- (132, "Mmm! What's that smell? Is that a pie?"),
- (133, "I smell apples!"),
- (134, "Whoa! I know that smell! Apple pie!"),
- (135, "That is our favourite!"),
- (137, "Oh, you have a friend over!"),
- (138, "Hello! I am here to visit Vicky."),
- (139, "Nice to meet you again!"),
- (140, "I guess you helped out today too."),
- (142, "Today seems pretty busy."),
- (143, "Yes, we made a little mess before you came."),
- (144, "Today was not easy."),
- (145, "That's okay."),
- (146, "Grandfather and Grandmother can fix anything."),
- (147, "That's what family is for!"),
- (148, "Mess or not, we love seeing you!"),
-]
-
-print(f"Total dialogue lines: {len(rows)}")
-
-# Build the complete column F data (one value per row, 1-based sheet rows 2-149)
-# We need to clear the ENTIRE column first, then fill only dialogue rows.
-# The API PUT overwrites the specified range. Write all rows 2-149.
-# Use a dict for fast lookup
-f_map = {r: v for r, v in rows}
-
-# Get token
-with open("/root/.openclaw/credentials/xiaoyan/config.json") as f:
- cfg = json.load(f)
-app_id = "cli_a931175d41799cc7"
-app_secret = cfg["apps"][0]["appSecret"]
-
-result = subprocess.run([
- "curl", "-s", "-X", "POST",
- "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
- "-H", "Content-Type: application/json",
- "-d", json.dumps({"app_id": app_id, "app_secret": app_secret})
-], capture_output=True, text=True)
-token = json.loads(result.stdout)["tenant_access_token"]
-
-spreadsheet_token = "DA7csROG6hmnQMt59oScOLRfnWc"
-sheet_id = "Nr3Ovs"
-
-# Step 1: Clear entire column F (rows 2-149)
-print("Clearing column F (rows 2-149)...")
-empty_payload = {
- "valueRange": {
- "range": f"{sheet_id}!F2:F149",
- "values": [[""] for _ in range(148)] # 149-2+1 = 148 rows
- }
-}
-result = subprocess.run([
- "curl", "-s", "-X", "PUT",
- f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values",
- "-H", f"Authorization: Bearer {token}",
- "-H", "Content-Type: application/json",
- "-d", json.dumps(empty_payload)
-], capture_output=True, text=True)
-resp = json.loads(result.stdout)
-print(f" Clear: code={resp.get('code')}, msg={resp.get('msg')}")
-assert resp.get("code") == 0, f"Clear failed: {result.stdout[:200]}"
-
-# Step 2: Write optimized values to each dialogue row
-# Group consecutive rows for batching
-batch_start = None
-batch_end = None
-batch_values = []
-
-def flush_batch():
- global batch_start, batch_end, batch_values
- if not batch_values:
- return
- range_str = f"{sheet_id}!F{batch_start}:F{batch_end}"
- payload = {"valueRange": {"range": range_str, "values": batch_values}}
- result = subprocess.run([
- "curl", "-s", "-X", "PUT",
- f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values",
- "-H", f"Authorization: Bearer {token}",
- "-H", "Content-Type: application/json",
- "-d", json.dumps(payload)
- ], capture_output=True, text=True)
- resp = json.loads(result.stdout)
- print(f" Write {range_str}: code={resp.get('code')}, msg={resp.get('msg')}")
- assert resp.get("code") == 0, f"Write failed: {result.stdout[:200]}"
- batch_start = None
- batch_end = None
- batch_values = []
-
-# Also need to fill empty rows between dialogue rows
-# Strategy: write row by row, merging consecutive rows into batches
-for sheet_row in range(2, 150):
- value = f_map.get(sheet_row, "")
- if batch_start is None:
- batch_start = sheet_row
- batch_end = sheet_row
- batch_values = [[value]]
- else:
- batch_end = sheet_row
- batch_values.append([value])
-
-flush_batch()
-
-print("Done! Verifying...")
-
-# Step 3: Verify key rows
-check_rows = [3, 7, 14, 23, 28, 34, 44, 49, 56, 64, 92, 97, 111, 121, 134, 147]
-for r in check_rows:
- result = subprocess.run([
- "curl", "-s", "-X", "GET",
- f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values/{sheet_id}!D{r}:F{r}?valueRenderOption=ToString",
- "-H", f"Authorization: Bearer {token}"
- ], capture_output=True, text=True)
- vals = json.loads(result.stdout).get("data", {}).get("valueRange", {}).get("values", [[]])[0]
- role = vals[0] if len(vals) > 0 else "-"
- e_val = vals[1] if len(vals) > 1 else "-"
- f_val = vals[2] if len(vals) > 2 else "-"
- expected = f_map.get(r, "-")
- status = "✓" if f_val == (expected or "") else "✗ MISMATCH"
- if status != "✓":
- print(f" Row {r}: [{role}] E='{e_val}' F='{f_val}' expected='{expected}' {status}")
- else:
- print(f" Row {r}: [{role}] F='{f_val}' {status}")
-
-print("\nAll verified!")
diff --git a/business_production/组件生产/backup/scripts/fill_components.py b/business_production/组件生产/backup/scripts/fill_components.py
deleted file mode 100644
index 07adadb..0000000
--- a/business_production/组件生产/backup/scripts/fill_components.py
+++ /dev/null
@@ -1,371 +0,0 @@
-import pandas as pd
-from openpyxl import load_workbook
-
-# 读取原始Excel
-input_path = "/root/.openclaw/media/inbound/12-5---1879d0c9-7cdf-4cd5-9aff-f03091ebada3.xlsx"
-output_path = "/root/.openclaw/workspace-xiaoyan/L1-S1-U12-L5_组件完成版.xlsx"
-
-# 定义组件内容,按顺序对应表格中的组件行
-components = [
- # 1112501 对话朗读
- """【任务标题】描述当前时间
-【资源配置】
-图片时机:【互动内容】
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: It is still night.(朗读)
-
-【互动反馈】
-正确:无
-错误:Vicky : Wait, that didn't sound right.
-
-【后置对话】
-无""",
- # 1112502 图片单选
- """【任务标题】等待清晨
-【情境引入】
-无
-
-【互动内容】
-题干:We must wait for the $morning$.
-选项:
-00
-01(正确)
-辅助信息:morning指"清晨"
-
-【互动反馈】
-正确:无
-错误:Sally : Oh no, that's not right. Look outside, it's still dark!
-
-【后置对话】
-无""",
- # 1112503 对话朗读
- """【任务标题】询问清晨时间
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-Vicky: How do we know when it's morning?(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Hmm, I didn't catch that. Can you say it again?
-
-【后置对话】
-无""",
- # 1112504 对话朗读
- """【任务标题】表达尝试意愿
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: I'd like to try too.(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Oh, that doesn't sound quite right.
-
-【后置对话】
-Ben: Me too.""",
- # 1112505 对话朗读
- """【任务标题】尝试做手影狗
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: I want to try to make a dog!(朗读)
-
-【互动反馈】
-正确:无
-错误:Lucy : Wait, what did you say? I didn't get it.
-
-【后置对话】
-无""",
- # 1112506 对话朗读
- """【任务标题】评价夜晚乐趣
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: Night is so much fun!(朗读)
-
-【互动反馈】
-正确:无
-错误:Lucy : Hmm, that didn't sound right.
-
-【后置对话】
-无""",
- # 1112507 对话挖空
- """【任务标题】否定当前是清晨
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:It isn't ____.
-选项:
-选项1:night
-选项2:morning(正确)
-辅助信息:morning指"清晨"
-
-【互动反馈】
-正确:无
-错误:Ben : Oh no, that's wrong. It's still dark out!
-
-【后置对话】
-无""",
- # 1112508 对话挖空
- """【任务标题】确认当前是夜晚
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:It is still ____!
-选项:
-选项1:night(正确)
-选项2:morning
-辅助信息:night指"夜晚"
-
-【互动反馈】
-正确:无
-错误:Ben : Wait, that's not right. The sun isn't up yet!
-
-【后置对话】
-无""",
- # 1112509 对话朗读
- """【任务标题】提议逐个尝试
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: Let's try them one by one!(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Hmm, that didn't sound quite right.
-
-【后置对话】
-无""",
- # 1112510 对话选读
- """【任务标题】尝试下一个格子
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-请选择一句朗读:
-选项1:Let's try the next!
-选项2:Let's try them one by one!
-辅助信息:两个选项均为正确答案
-
-【互动反馈】
-正确:无
-错误:Sally : Oh, that's not one of the choices.
-
-【后置对话】
-无""",
- # 1112510 图片有序
- """【任务标题】排序跳格子顺序
-【情境引入】
-无
-
-【互动内容】
-题干:Put the actions in order of $one by one$.
-选项:
-00
-01
-02
-03
-正确顺序:00→01→02→03
-辅助信息:one by one指"一个接一个"
-
-【互动反馈】
-正确:无
-错误:Dan : Oops, that's the wrong order! We can't jump like that.
-
-【后置对话】
-无""",
- # 1112511 对话挖空
- """【任务标题】提议尝试另一块格子
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:____ that one.
-选项:
-选项1:let's try(正确)
-选项2:let's play
-辅助信息:let's try指"我们试试"
-
-【互动反馈】
-正确:无
-错误:Dan : Wait, that doesn't make sense.
-
-【后置对话】
-无""",
- # 1112512 对话朗读
- """【任务标题】询问下一个人选
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: Who is the next?(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Hmm, that didn't sound quite right.
-
-【后置对话】
-Vicky: It's my turn!""",
- # 1112513 对话挖空
- """【任务标题】描述灯逐个亮起
-【资源配置】
-图片时机:【互动内容】
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:The lights are turning on ____!
-选项:
-选项1:one by one(正确)
-选项2:two by two
-辅助信息:one by one指"一个接一个"
-
-【互动反馈】
-正确:无
-错误:Lucy : Oh no, that's wrong! The lights are turning on in order.
-
-【后置对话】
-无""",
- # 1112514 对话组句
- """【任务标题】组句提议尝试
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-User: The first tile didn't work.
-
-【互动内容】
-题目:提议大家试试另一块格子
-选项1:try this
-选项2:Let's
-选项3:one.
-答案:Let's try this one.
-辅助信息:Let's do sth.是提议做某事的固定句式
-
-【互动反馈】
-正确:无
-错误:Sally : Oops, that's not the right sentence.
-
-【后置对话】
-无""",
- # 1112516 对话组句
- """【任务标题】组句逐个行动
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-Sally: We need to stand on the tiles one after another.
-
-【互动内容】
-题目:告诉大家要一个接一个做
-选项1:Let's do it
-选项2:one
-选项3:by
-选项4:one!
-答案:Let's do it one by one!
-辅助信息:one by one是固定搭配,意思是"一个接一个"
-
-【互动反馈】
-正确:无
-错误:Sally : Oh, that doesn't make sense. Try again.
-
-【后置对话】
-无""",
- # 1112517 对话选择
- """【任务标题】判断当前时间
-【资源配置】
-图片时机:【互动内容】
-音频载体:无
-
-【情境引入】
-Fred: I see the light from the lighthouse!
-
-【互动内容】
-Wow! It's so bright! ____
-选项:
-选项1:It's morning now!(正确)
-选项2:It's night now!
-辅助信息:morning指"清晨",night指"夜晚"
-
-【互动反馈】
-正确:无
-错误:Fred : Wait, that's not right! Look at the sun in the sky!
-
-【后置对话】
-无"""
-]
-
-# 加载工作簿
-wb = load_workbook(input_path)
-ws = wb.active
-
-# 找到组件列(第7列,索引从1开始)
-component_col = 7
-# 找到有组件ID的行,从第6行开始是数据行
-component_row_start = 6
-
-# 逐个填入组件内容
-for i, comp in enumerate(components):
- row = component_row_start + i
- ws.cell(row=row, column=component_col, value=comp)
-
-# 保存文件
-wb.save(output_path)
-print(f"文件已保存到: {output_path}")
diff --git a/business_production/组件生产/backup/scripts/fill_components_by_id.py b/business_production/组件生产/backup/scripts/fill_components_by_id.py
deleted file mode 100644
index cf22f7c..0000000
--- a/business_production/组件生产/backup/scripts/fill_components_by_id.py
+++ /dev/null
@@ -1,351 +0,0 @@
-from openpyxl import load_workbook
-
-# 读取原始Excel
-input_path = "/root/.openclaw/media/inbound/12-5---1879d0c9-7cdf-4cd5-9aff-f03091ebada3.xlsx"
-output_path = "/root/.openclaw/workspace-xiaoyan/L1-S1-U12-L5_组件完成版_按ID匹配.xlsx"
-
-# 定义组件内容,按ID对应行号(Excel行号从1开始)
-component_map = {
- 32: """【任务标题】描述当前时间
-【资源配置】
-图片时机:【互动内容】
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: It is still night.(朗读)
-
-【互动反馈】
-正确:无
-错误:Vicky : Wait, that didn't sound right.
-
-【后置对话】
-无""",
- 33: """【任务标题】等待清晨
-【情境引入】
-无
-
-【互动内容】
-题干:We must wait for the $morning$.
-选项:
-00
-01(正确)
-辅助信息:morning指"清晨"
-
-【互动反馈】
-正确:无
-错误:Sally : Oh no, that's not right. Look outside, it's still dark!
-
-【后置对话】
-无""",
- 34: """【任务标题】询问清晨时间
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-Vicky: How do we know when it's morning?(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Hmm, I didn't catch that. Can you say it again?
-
-【后置对话】
-无""",
- 52: """【任务标题】表达尝试意愿
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: I'd like to try too.(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Oh, that doesn't sound quite right.
-
-【后置对话】
-Ben: Me too.""",
- 59: """【任务标题】尝试做手影狗
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: I want to try to make a dog!(朗读)
-
-【互动反馈】
-正确:无
-错误:Lucy : Wait, what did you say? I didn't get it.
-
-【后置对话】
-无""",
- 70: """【任务标题】评价夜晚乐趣
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: Night is so much fun!(朗读)
-
-【互动反馈】
-正确:无
-错误:Lucy : Hmm, that didn't sound right.
-
-【后置对话】
-无""",
- 85: """【任务标题】否定当前是清晨
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:It isn't ____.
-选项:
-选项1:night
-选项2:morning(正确)
-辅助信息:morning指"清晨"
-
-【互动反馈】
-正确:无
-错误:Ben : Oh no, that's wrong. It's still dark out!
-
-【后置对话】
-无""",
- 86: """【任务标题】确认当前是夜晚
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:It is still ____!
-选项:
-选项1:night(正确)
-选项2:morning
-辅助信息:night指"夜晚"
-
-【互动反馈】
-正确:无
-错误:Ben : Wait, that's not right. The sun isn't up yet!
-
-【后置对话】
-无""",
- 96: """【任务标题】提议逐个尝试
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: Let's try them one by one!(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Hmm, that didn't sound quite right.
-
-【后置对话】
-无""",
- 104: """【任务标题】尝试下一个格子
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-请选择一句朗读:
-选项1:Let's try the next!
-选项2:Let's try them one by one!
-辅助信息:两个选项均为正确答案
-
-【互动反馈】
-正确:无
-错误:Sally : Oh, that's not one of the choices.
-
-【后置对话】
-无""",
- 110: """【任务标题】排序跳格子顺序
-【情境引入】
-无
-
-【互动内容】
-题干:Put the actions in order of $one by one$.
-选项:
-00
-01
-02
-03
-正确顺序:00→01→02→03
-辅助信息:one by one指"一个接一个"
-
-【互动反馈】
-正确:无
-错误:Dan : Oops, that's the wrong order! We can't jump like that.
-
-【后置对话】
-无""",
- 118: """【任务标题】提议尝试另一块格子
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:____ that one.
-选项:
-选项1:let's try(正确)
-选项2:let's play
-辅助信息:let's try指"我们试试"
-
-【互动反馈】
-正确:无
-错误:Dan : Wait, that doesn't make sense.
-
-【后置对话】
-无""",
- 124: """【任务标题】询问下一个人选
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: Who is the next?(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Hmm, that didn't sound quite right.
-
-【后置对话】
-Vicky: It's my turn!""",
- 127: """【任务标题】描述灯逐个亮起
-【资源配置】
-图片时机:【互动内容】
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:The lights are turning on ____!
-选项:
-选项1:one by one(正确)
-选项2:two by two
-辅助信息:one by one指"一个接一个"
-
-【互动反馈】
-正确:无
-错误:Lucy : Oh no, that's wrong! The lights are turning on in order.
-
-【后置对话】
-无""",
- 136: """【任务标题】组句提议尝试
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-User: The first tile didn't work.
-
-【互动内容】
-题目:提议大家试试另一块格子
-选项1:try this
-选项2:Let's
-选项3:one.
-答案:Let's try this one.
-辅助信息:Let's do sth.是提议做某事的固定句式
-
-【互动反馈】
-正确:无
-错误:Sally : Oops, that's not the right sentence.
-
-【后置对话】
-无""",
- 155: """【任务标题】组句逐个行动
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-Sally: We need to stand on the tiles one after another.
-
-【互动内容】
-题目:告诉大家要一个接一个做
-选项1:Let's do it
-选项2:one
-选项3:by
-选项4:one!
-答案:Let's do it one by one!
-辅助信息:one by one是固定搭配,意思是"一个接一个"
-
-【互动反馈】
-正确:无
-错误:Sally : Oh, that doesn't make sense. Try again.
-
-【后置对话】
-无""",
- 179: """【任务标题】判断当前时间
-【资源配置】
-图片时机:【互动内容】
-音频载体:无
-
-【情境引入】
-Fred: I see the light from the lighthouse!
-
-【互动内容】
-Wow! It's so bright! ____
-选项:
-选项1:It's morning now!(正确)
-选项2:It's night now!
-辅助信息:morning指"清晨",night指"夜晚"
-
-【互动反馈】
-正确:无
-错误:Fred : Wait, that's not right! Look at the sun in the sky!
-
-【后置对话】
-无"""
-}
-
-# 加载工作簿
-wb = load_workbook(input_path)
-ws = wb.active
-
-# 组件列是第7列(G列)
-component_col = 7
-
-# 按行号填入组件
-for row_num, comp_content in component_map.items():
- ws.cell(row=row_num, column=component_col, value=comp_content)
-
-# 保存文件
-wb.save(output_path)
-print(f"文件已保存到: {output_path}")
-print(f"已为{len(component_map)}个组件ID匹配并填入对应行")
diff --git a/business_production/组件生产/backup/scripts/fill_components_by_id_fixed.py b/business_production/组件生产/backup/scripts/fill_components_by_id_fixed.py
deleted file mode 100644
index d46aaa4..0000000
--- a/business_production/组件生产/backup/scripts/fill_components_by_id_fixed.py
+++ /dev/null
@@ -1,355 +0,0 @@
-from openpyxl import load_workbook
-
-# 读取原始Excel
-input_path = "/root/.openclaw/media/inbound/12-5---1879d0c9-7cdf-4cd5-9aff-f03091ebada3.xlsx"
-output_path = "/root/.openclaw/workspace-xiaoyan/L1-S1-U12-L5_组件完成版_最终匹配版.xlsx"
-
-# 正确的组件ID对应行号(第一列有组件ID的行,为Excel实际行号)
-component_map = {
- 32: """【任务标题】描述当前时间
-【资源配置】
-图片时机:【互动内容】
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: It is still night.(朗读)
-
-【互动反馈】
-正确:无
-错误:Vicky : Wait, that didn't sound right.
-
-【后置对话】
-无""",
- 33: """【任务标题】等待清晨
-【情境引入】
-无
-
-【互动内容】
-题干:We must wait for the $morning$.
-选项:
-00
-01(正确)
-辅助信息:morning指"清晨"
-
-【互动反馈】
-正确:无
-错误:Sally : Oh no, that's not right. Look outside, it's still dark!
-
-【后置对话】
-无""",
- 34: """【任务标题】询问清晨时间
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-Vicky: How do we know when it's morning?(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Hmm, I didn't catch that. Can you say it again?
-
-【后置对话】
-无""",
- 52: """【任务标题】表达尝试意愿
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: I'd like to try too.(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Oh, that doesn't sound quite right.
-
-【后置对话】
-Ben: Me too.""",
- 58: """【任务标题】尝试做手影狗
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: I want to try to make a dog!(朗读)
-
-【互动反馈】
-正确:无
-错误:Lucy : Wait, what did you say? I didn't get it.
-
-【后置对话】
-无""",
- 69: """【任务标题】评价夜晚乐趣
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: Night is so much fun!(朗读)
-
-【互动反馈】
-正确:无
-错误:Lucy : Hmm, that didn't sound right.
-
-【后置对话】
-无""",
- 84: """【任务标题】否定当前是清晨
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:It isn't ____.
-选项:
-选项1:night
-选项2:morning(正确)
-辅助信息:morning指"清晨"
-
-【互动反馈】
-正确:无
-错误:Ben : Oh no, that's wrong. It's still dark out!
-
-【后置对话】
-无""",
- 85: """【任务标题】确认当前是夜晚
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:It is still ____!
-选项:
-选项1:night(正确)
-选项2:morning
-辅助信息:night指"夜晚"
-
-【互动反馈】
-正确:无
-错误:Ben : Wait, that's not right. The sun isn't up yet!
-
-【后置对话】
-无""",
- 95: """【任务标题】提议逐个尝试
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: Let's try them one by one!(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Hmm, that didn't sound quite right.
-
-【后置对话】
-无""",
- 103: """【任务标题】尝试下一个格子
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-请选择一句朗读:
-选项1:Let's try the next!
-选项2:Let's try them one by one!
-辅助信息:两个选项均为正确答案
-
-【互动反馈】
-正确:无
-错误:Sally : Oh, that's not one of the choices.
-
-【后置对话】
-无""",
- 109: """【任务标题】排序跳格子顺序
-【情境引入】
-无
-
-【互动内容】
-题干:Put the actions in order of $one by one$.
-选项:
-00
-01
-02
-03
-正确顺序:00→01→02→03
-辅助信息:one by one指"一个接一个"
-
-【互动反馈】
-正确:无
-错误:Dan : Oops, that's the wrong order! We can't jump like that.
-
-【后置对话】
-无""",
- 117: """【任务标题】提议尝试另一块格子
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:____ that one.
-选项:
-选项1:let's try(正确)
-选项2:let's play
-辅助信息:let's try指"我们试试"
-
-【互动反馈】
-正确:无
-错误:Dan : Wait, that doesn't make sense.
-
-【后置对话】
-无""",
- 123: """【任务标题】询问下一个人选
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-User: Who is the next?(朗读)
-
-【互动反馈】
-正确:无
-错误:Sally : Hmm, that didn't sound quite right.
-
-【后置对话】
-Vicky: It's my turn!""",
- 126: """【任务标题】描述灯逐个亮起
-【资源配置】
-图片时机:【互动内容】
-音频载体:无
-
-【情境引入】
-无
-
-【互动内容】
-题干:The lights are turning on ____!
-选项:
-选项1:one by one(正确)
-选项2:two by two
-辅助信息:one by one指"一个接一个"
-
-【互动反馈】
-正确:无
-错误:Lucy : Oh no, that's wrong! The lights are turning on in order.
-
-【后置对话】
-无""",
- 135: """【任务标题】组句提议尝试
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-User: The first tile didn't work.
-
-【互动内容】
-题目:提议大家试试另一块格子
-选项1:try this
-选项2:Let's
-选项3:one.
-答案:Let's try this one.
-辅助信息:Let's do sth.是提议做某事的固定句式
-
-【互动反馈】
-正确:无
-错误:Sally : Oops, that's not the right sentence.
-
-【后置对话】
-无""",
- 154: """【任务标题】组句逐个行动
-【资源配置】
-图片时机:无
-音频载体:无
-
-【情境引入】
-Sally: We need to stand on the tiles one after another.
-
-【互动内容】
-题目:告诉大家要一个接一个做
-选项1:Let's do it
-选项2:one
-选项3:by
-选项4:one!
-答案:Let's do it one by one!
-辅助信息:one by one是固定搭配,意思是"一个接一个"
-
-【互动反馈】
-正确:无
-错误:Sally : Oh, that doesn't make sense. Try again.
-
-【后置对话】
-无""",
- 178: """【任务标题】判断当前时间
-【资源配置】
-图片时机:【互动内容】
-音频载体:无
-
-【情境引入】
-Fred: I see the light from the lighthouse!
-
-【互动内容】
-Wow! It's so bright! ____
-选项:
-选项1:It's morning now!(正确)
-选项2:It's night now!
-辅助信息:morning指"清晨",night指"夜晚"
-
-【互动反馈】
-正确:无
-错误:Fred : Wait, that's not right! Look at the sun in the sky!
-
-【后置对话】
-无"""
-}
-
-# 加载工作簿
-wb = load_workbook(input_path)
-ws = wb.active
-
-# 组件列是第7列(G列)
-component_col = 7
-
-# 先清空原有组件列的内容(避免残留内容)
-for row_num in component_map.keys():
- ws.cell(row=row_num, column=component_col, value="")
-
-# 按正确行号填入组件
-for row_num, comp_content in component_map.items():
- ws.cell(row=row_num, column=component_col, value=comp_content)
-
-# 保存文件
-wb.save(output_path)
-print(f"文件已保存到: {output_path}")
-print(f"已为{len(component_map)}个组件ID 100%匹配填入对应行")
diff --git a/business_production/组件生产/backup/scripts/fix_components.py b/business_production/组件生产/backup/scripts/fix_components.py
deleted file mode 100644
index adf0b0e..0000000
--- a/business_production/组件生产/backup/scripts/fix_components.py
+++ /dev/null
@@ -1,222 +0,0 @@
-#!/usr/bin/env python3
-"""
-Fix component production issues:
-1. Regenerate 4 对话朗读 rows with correct format (no 组件ID, correct 资源配置)
-2. Fix Chinese error feedback → English for 7 other rows
-"""
-import requests, json, time, os
-
-CRED_PATH = "/root/.openclaw/credentials/xiaoyan/config.json"
-SHEET_TOKEN = "VgPwsodzthsk9Vti8GocrbH2nEe"
-SHEET_ID = "wMQVyV"
-OUTPUT_DIR = "/root/.openclaw/workspace-xiaoyan/business_production/组件生产/output"
-
-LLM_BASE = "https://ark.cn-beijing.volces.com/api/v3"
-LLM_KEY = "32994652-505c-492b-b6da-616ec5c5733c"
-LLM_MODEL = "ep-m-20260301164317-vmmj4"
-
-def get_token():
- with open(CRED_PATH) as f: c = json.load(f)
- r = requests.post("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
- json={"app_id": c["apps"][0]["appId"], "app_secret": c["apps"][0]["appSecret"]})
- return r.json()["tenant_access_token"]
-
-def get_sheet(token):
- r = requests.get(
- f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SHEET_TOKEN}/values/{SHEET_ID}?majorDimension=ROWS",
- headers={"Authorization": f"Bearer {token}"})
- return r.json()["data"]["valueRange"]["values"]
-
-def write_cell(token, sheet_row, content):
- range_str = f"{SHEET_ID}!H{sheet_row}:H{sheet_row}"
- r = requests.put(
- f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SHEET_TOKEN}/values",
- headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
- json={"valueRange": {"range": range_str, "values": [[content]]}})
- return r.json().get("code") == 0
-
-def parse_col(row, idx):
- if isinstance(row[idx], list):
- return "".join([seg.get("text","") for seg in row[idx] if isinstance(seg, dict)])
- return str(row[idx]) if row[idx] else ""
-
-def llm(messages):
- try: from openai import OpenAI
- except: os.system("pip install openai --break-system-packages -q"); from openai import OpenAI
- client = OpenAI(base_url=LLM_BASE, api_key=LLM_KEY)
- resp = client.chat.completions.create(
- model=LLM_MODEL, messages=messages, temperature=0.3, max_tokens=1000,
- extra_body={"thinking": {"type": "disabled"}})
- return resp.choices[0].message.content.strip()
-
-# === FIX: 对话朗读 regeneration ===
-READING_SYSTEM = """You fix dialogue reading component configs.
-
-## CORRECT FORMAT (exactly this, no variation):
-
-【任务标题】{contextual title fitting the scene, ≤10 chars}
-【资源配置】
-图片时机:
-情境引入
-互动内容
-互动反馈
-【情境引入】
-{Character: line, or 无 if no context needed}
-【互动内容】
-{Character}: {sentence}(朗读)
-【后置对话】
-{Character: next line from context, or 无}
-
-## KEY RULES
-- NO 【组件ID】 field at all!
-- NO 音频载体 line!
-- NO 【互动反馈】 section!
-- 资源配置 uses line-break stage listing format (情境引入/互动内容/互动反馈 on separate lines)
-- Task title must match the scene context, not generic like "朗读台词"
-- Error feedback (互动反馈) appears only as a stage name in 资源配置, NOT as a separate section
-- Generate only the component config text, no explanation"""
-
-def fix_reading(token, row_data):
- """Regenerate a 对话朗读 component"""
- messages = [
- {"role": "system", "content": READING_SYSTEM},
- {"role": "user", "content": f"""Fix this 对话朗读 component:
-
-Context:
-- Scene: {row_data.get('plot','')}
-- Knowledge Point: {row_data.get('kp','')}
-
-Dialogue before:
-{row_data.get('ctx_before','')}
-
-Current interaction:
-{row_data.get('char','User')}: {row_data.get('script_en','')}
-
-Dialogue after:
-{row_data.get('ctx_after','')}
-
-Generate the corrected component config following the format exactly. Make the task title contextual and scene-fitting."""}
- ]
- return llm(messages)
-
-# === FIX: Chinese error feedback → English ===
-FB_SYSTEM = """You fix Chinese error feedback in English learning component configs.
-Replace Chinese feedback text with natural English character dialogue that matches the scene context and character personality.
-Keep everything else exactly the same. Only change the error feedback text.
-
-Format: return the complete fixed component config text, changing ONLY the error feedback lines."""
-
-def fix_feedback(token, old_content, context):
- """Fix Chinese error feedback"""
- messages = [
- {"role": "system", "content": FB_SYSTEM},
- {"role": "user", "content": f"""Fix the Chinese error feedback in this component config:
-
-Component context: {context}
-
-Current config:
-{old_content}
-
-Return the complete fixed config with Chinese feedback replaced by natural English character dialogue."""}
- ]
- return llm(messages)
-
-def main():
- token = get_token()
- values = get_sheet(token)
- os.makedirs(OUTPUT_DIR, exist_ok=True)
-
- # Collect context for all rows
- rows = []
- for i, row in enumerate(values):
- while len(row) < 8: row.append(None)
- rtype = str(row[0]).strip() if row[0] else ""
- rows.append({
- "sheet_row": i+1, "type": rtype,
- "id": str(row[1]).strip() if row[1] else "",
- "plot": str(row[2]).strip() if row[2] else "",
- "char": str(row[3]).strip() if row[3] else "",
- "script_cn": parse_col(row, 4), "script_en": parse_col(row, 5),
- "kp": str(row[6]).strip() if row[6] else "",
- "h_col": str(row[7]) if row[7] else "",
- })
-
- # Find dialogue reading rows and other fixable rows
- reading_rows = []
- cn_feedback_rows = []
-
- for i, r in enumerate(rows):
- if r["type"] == "对话朗读" and r["h_col"]:
- # Get context
- ctx_before = []
- for j in range(max(0,i-4), i):
- if rows[j]["char"] and rows[j]["script_cn"]:
- ctx_before.append(f"{rows[j]['char']}: {rows[j]['script_cn']}")
- ctx_after = []
- for j in range(i+1, min(len(rows), i+4)):
- if rows[j]["char"] and rows[j]["script_cn"]:
- ctx_after.append(f"{rows[j]['char']}: {rows[j]['script_cn']}")
- r["ctx_before"] = "\n".join(ctx_before)
- r["ctx_after"] = "\n".join(ctx_after)
- reading_rows.append(r)
-
- elif r["h_col"]:
- # Check for Chinese error feedback
- err_idx = r["h_col"].find("错误:")
- if err_idx > 0:
- err_line = r["h_col"][err_idx:].split("\n")[0]
- has_cn = any('\u4e00' <= c <= '\u9fff' for c in err_line)
- # Skip section headers (正确/错误) - only check after "错误:" before newline
- fb_text = err_line.split("错误:")[1] if "错误:" in err_line else err_line
- if any('\u4e00' <= c <= '\u9fff' for c in fb_text):
- cn_feedback_rows.append(r)
-
- print(f"对话朗读 to fix: {len(reading_rows)}")
- print(f"中文反馈 to fix: {len(cn_feedback_rows)}")
-
- results = []
-
- # Fix dialogue readings
- for r in reading_rows:
- row_num = r["sheet_row"]
- print(f"\n[对话朗读] Row {row_num} ID={r['id']}")
- try:
- new_content = fix_reading(token, r)
- print(f" Generated: {new_content[:100]}...")
- if write_cell(token, row_num, new_content):
- print(f" ✅ Written to H{row_num}")
- results.append({"row": row_num, "type": "对话朗读", "status": "fixed"})
- else:
- print(f" ❌ Write failed")
- results.append({"row": row_num, "type": "对话朗读", "status": "write_fail"})
- except Exception as e:
- print(f" ❌ Error: {e}")
- results.append({"row": row_num, "type": "对话朗读", "status": str(e)})
- time.sleep(0.5)
-
- # Fix Chinese feedback
- for r in cn_feedback_rows:
- row_num = r["sheet_row"]
- rtype = r["type"]
- print(f"\n[{rtype}] Row {row_num} ID={r['id']} — fixing Chinese feedback")
- ctx = f"Character: {r['char']}, Plot: {r['plot']}, KP: {r['kp']}"
- try:
- new_content = fix_feedback(token, r["h_col"], ctx)
- if write_cell(token, row_num, new_content):
- print(f" ✅ Written")
- results.append({"row": row_num, "type": rtype, "status": "fb_fixed"})
- else:
- print(f" ❌ Write failed")
- except Exception as e:
- print(f" ❌ Error: {e}")
- time.sleep(0.5)
-
- # Summary
- ok = sum(1 for r in results if "fail" not in r["status"] and "Error" not in str(r["status"]))
- print(f"\n{'='*40}")
- print(f"Fixed: {ok}/{len(results)}")
- for r in results:
- print(f" H{r['row']} [{r['type']}]: {r['status']}")
-
-if __name__ == "__main__":
- main()
diff --git a/business_production/组件生产/backup/scripts/generate_component_configs.py b/business_production/组件生产/backup/scripts/generate_component_configs.py
deleted file mode 100644
index 6b7564e..0000000
--- a/business_production/组件生产/backup/scripts/generate_component_configs.py
+++ /dev/null
@@ -1,444 +0,0 @@
-#!/usr/bin/env python3
-"""Generate component configurations for the script sheet and write them back."""
-
-import json
-import subprocess
-import sys
-
-# Get bot token
-def get_token():
- result = subprocess.run(
- ["jq", "-r", ".apps[0].appSecret",
- "/root/.openclaw/credentials/xiaoyan/config.json"],
- capture_output=True, text=True
- )
- app_secret = result.stdout.strip()
-
- import urllib.request
- import urllib.parse
- data = json.dumps({"app_id": "cli_a931175d41799cc7", "app_secret": app_secret}).encode()
- req = urllib.request.Request(
- "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
- data=data,
- headers={"Content-Type": "application/json"}
- )
- resp = json.loads(urllib.request.urlopen(req).read())
- return resp["tenant_access_token"]
-
-TOKEN = get_token()
-SPREADSHEET_TOKEN = "Dk1fs7TJ4hWs5PtUvXlc1EaEnvb"
-SHEET_ID = "fmqYrx"
-
-# Component configurations for each row
-# Format: {row_number: config_text}
-
-CONFIGS = {
- # Row 12: 图片无序多选 (1217101) - motorbike
- 12: """【任务标题】
-在图片中寻找摩托车
-
-【情境引入】
-Ben: Whoa! Those are motorbikes!
-User: Where? Let me take a look.
-
-【互动内容】
-Find the $motorbikes$ in the picture.(音频)
-选项:
-00
-01
-02
-答案:
-00
-01
-辅助信息:motorbike 指"摩托车"。
-
-【互动反馈】
-正确 Ben : That's right! Those are two motorbikes!
-错误 Ben : Look again. Can you find the motorbikes?
-
-【后置对话】
-无""",
-
- # Row 30: 对话朗读 (1217102) - people
- 30: """【任务标题】
-询问那些人是谁
-
-【资源配置】
-图片时机:无
-
-【情境引入】
-无
-
-【互动内容】
-Who are those people?(朗读)
-
-【后置对话】
-无""",
-
- # Row 46: 对话挖空 (1217103) - people
- 46: """【任务标题】
-向镇长报告发现
-
-【资源配置】
-无
-
-【情境引入】
-User: Tom! We found two strange people.
-
-【互动内容】
-We found two strange ___.(音频)
-选项1:people(正确)
-选项2:animals
-
-【互动反馈】
-正确 Tom : Good! Tell me more about them.
-错误 Tom : Animals? Are you sure about that?
-
-【后置对话】
-无""",
-
- # Row 53: 对话挖空 (1217104) - motorbike
- 53: """【任务标题】
-描述可疑人员的特征
-
-【资源配置】
-无
-
-【情境引入】
-Tom: Tell me more about them.
-
-【互动内容】
-They're on ___.(音频)
-选项1:motorbikes(正确)
-选项2:bicycles
-
-【互动反馈】
-正确 Tom : Good job! I'm coming right now!
-错误 Tom : Bicycles? That doesn't sound right.
-
-【后置对话】
-无""",
-
- # Row 67: 对话朗读 (1217105) - people
- 67: """【任务标题】
-盘问来人身份
-
-【资源配置】
-图片时机:无
-
-【情境引入】
-无
-
-【互动内容】
-Who are you people?(朗读)
-
-【后置对话】
-无""",
-
- # Row 81: 对话挖空 (1217106) - show
- 81: """【任务标题】
-要求检查袋子
-
-【资源配置】
-无
-
-【情境引入】
-Jay: The bag is a secret!
-
-【互动内容】
-You must ___ me what is in the bag!(音频)
-选项1:show(正确)
-选项2:tell
-
-【互动反馈】
-正确 Jay : No, no! We can't show you!
-错误 Jay : Ha! We won't tell you, either!
-
-【后置对话】
-无""",
-
- # Row 96: 对话选择 (1217107) - motorbike
- 96: """【任务标题】
-回应 Jay 的炫耀
-
-【资源配置】
-无
-
-【情境引入】
-Jay: Let me show you how fast it is!
-
-【互动内容】
-要求:选择正确的回复
-选项:(音频)
-选项1:Your motorbike looks really old.(正确)
-- 反馈: 无
-选项2:Your motorbike looks so cool!
-- 反馈 Jay : Thank you, kid! But let me show you more!
-
-【后置对话】
-无""",
-
- # Row 110: 对话朗读 (1217108) - Show...
- 110: """【任务标题】
-要求 Jay 继续展示
-
-【资源配置】
-图片时机:无
-
-【情境引入】
-无
-
-【互动内容】
-Wow! Show me more!(朗读)
-
-【后置对话】
-无""",
-
- # Row 122: 对话组句 (1217109) - Show...
- 122: """【任务标题】
-请 Lin 展示摩托车
-
-【资源配置】
-无
-
-【情境引入】
-Lin: My motorbike never does that.
-
-【互动内容】
-题目:请 Lin 展示她的摩托车
-(音频)
-选项1:Cool
-选项2:Show
-选项3:me
-选项4:your
-选项5:motorbike
-答案:Cool! Show me your motorbike!
-辅助信息:Cool 作感叹词放句首;Show me 后接名词表示"给我看看..."。
-
-【互动反馈】
-正确 Lin : Hmph. Fine.
-错误 Lin : What do you want me to show?
-
-【后置对话】
-无""",
-
- # Row 142: 对话选读 (1217110) - motorbike
- 142: """【任务标题】
-评价谁的摩托车更好
-
-【资源配置】
-无
-
-【情境引入】
-Jay: Hey kids! Which motorbike is better?
-
-【互动内容】
-要求:选择一个你想表达的观点
-选项:
-选项1:I think the red motorbike is better.
-- 反馈 Jay : What? I don't agree!
-选项2:I think the orange motorbike is better.
-- 反馈 Lin : Hey! You're wrong!
-
-【后置对话】
-无""",
-
- # Row 161: 对话朗读 (1217111) - ... can/can't hold...
- 161: """【任务标题】
-答应帮忙拿袋子
-
-【资源配置】
-图片时机:无
-
-【情境引入】
-无
-
-【互动内容】
-Okay! I can hold it.(朗读)
-
-【后置对话】
-无""",
-
- # Row 176: 对话选择 (1217112) - ... can/can't hold...
- 176: """【任务标题】
-回应 Ben 的关心
-
-【资源配置】
-无
-
-【情境引入】
-Ben: Are you okay?
-
-【互动内容】
-要求:选择正确的回复
-选项:(音频)
-选项1:Don't worry. I can hold it.(正确)
-- 反馈: 无
-选项2:Help! I can't hold it!
-- 反馈 Ben : Oh no! Let me help you!
-
-【后置对话】
-无""",
-
- # Row 192: 对话组句 (1217113) - ... can/can't hold...
- 192: """【任务标题】
-让 Ben 放心你能拿住
-
-【资源配置】
-无
-
-【情境引入】
-Ben: Let's see what's inside.
-
-【互动内容】
-题目:告诉 Ben 你能拿住袋子,让他放心
-(音频)
-选项1:Don't
-选项2:worry
-选项3:I
-选项4:can
-选项5:hold
-选项6:it
-答案:Don't worry. I can hold it.
-辅助信息:Don't worry 表示"别担心";can 后跟动词原形表示"能/会"。
-
-【互动反馈】
-正确 Ben : Ouch!
-错误 Ben : What? Are you okay?
-
-【后置对话】
-无""",
-
- # Row 204: 对话朗读 (1217114) - ... can/can't hold...
- 204: """【任务标题】
-呼救求助
-
-【资源配置】
-图片时机:无
-
-【情境引入】
-无
-
-【互动内容】
-I can't hold it!(朗读)
-
-【后置对话】
-无""",
-
- # Row 233: 阅读理解 (1217115) - motorbike/people/hold/show
- 233: """【任务标题】
-向 Tom 描述事情的经过
-
-【情境引入】
-Tom: Can anybody tell me what happened here?
-
-【互动内容】
-问题1:Who came from out of town?
-答案:These two people.
-
-问题2:What did they ride?
-答案:They ride motorbikes.
-
-问题3:What did you ask them to do?
-答案:Show us what's in their bags.
-
-【后置对话】
-无""",
-
- # Row 245: 对话选读 (1217116) - ... can/can't hold...
- 245: """【任务标题】
-为自己的失误道歉
-
-【资源配置】
-无
-
-【情境引入】
-Lin: And you opened the bags without asking.
-
-【互动内容】
-要求:选择一个你想表达的观点
-选项:
-选项1:Sorry, but I can't hold it.
-- 反馈 Tom : It's okay. Everybody makes mistakes.
-选项2:Sorry, I can't hold it anymore.
-- 反馈 Tom : It's okay. Everybody makes mistakes.
-
-【后置对话】
-无""",
-}
-
-
-def write_to_sheet(row, config_text):
- """Write config to a single cell in the sheet."""
- import urllib.request
-
- range_str = f"{SHEET_ID}!H{row}:H{row}"
- data = json.dumps({
- "valueRange": {
- "range": range_str,
- "values": [[config_text]]
- }
- }).encode()
-
- req = urllib.request.Request(
- f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/values",
- data=data,
- headers={
- "Authorization": f"Bearer {TOKEN}",
- "Content-Type": "application/json"
- },
- method="PUT"
- )
- resp = json.loads(urllib.request.urlopen(req).read())
- return resp.get("code") == 0
-
-
-def verify_write(row, expected_prefix):
- """Verify what was written."""
- import urllib.request
- range_str = f"{SHEET_ID}!H{row}:H{row}"
- url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/values/{range_str}?valueRenderOption=ToString"
- req = urllib.request.Request(url, headers={"Authorization": f"Bearer {TOKEN}"})
- resp = json.loads(urllib.request.urlopen(req).read())
- values = resp.get("data", {}).get("valueRange", {}).get("values", [])
- if values and values[0] and values[0][0]:
- actual = values[0][0]
- if actual.startswith(expected_prefix):
- return True, actual[:80]
- else:
- return False, actual[:80]
- return False, "EMPTY"
-
-
-def main():
- success = 0
- failed = []
-
- for row, config in sorted(CONFIGS.items()):
- try:
- ok = write_to_sheet(row, config)
- if ok:
- prefix = config.strip()[:50].replace("\n", " ")
- verified, preview = verify_write(row, prefix[:20])
- if verified:
- print(f"✓ Row {row}: Written and verified - {preview}...")
- success += 1
- else:
- print(f"⚠ Row {row}: Write reported OK but verification failed: {preview}")
- failed.append(row)
- else:
- print(f"✗ Row {row}: Write failed")
- failed.append(row)
- except Exception as e:
- print(f"✗ Row {row}: Error - {e}")
- failed.append(row)
-
- print(f"\n=== Summary ===")
- print(f"Success: {success}/{len(CONFIGS)}")
- if failed:
- print(f"Failed rows: {failed}")
- return 0 if not failed else 1
-
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/business_production/组件生产/backup/scripts/produce_components_111.py b/business_production/组件生产/backup/scripts/produce_components_111.py
deleted file mode 100644
index 93c66aa..0000000
--- a/business_production/组件生产/backup/scripts/produce_components_111.py
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/env python3
-"""Produce dialogue component configs and write back to F column."""
-
-import subprocess, json
-
-TOKEN = "t-g1045kg0ZYXHLVSY7EFUPUJUOLBGTOLYLPDKWLYN"
-SHEET_ID = "wMQVyV"
-SPREADSHEET_TOKEN = "It4AsFkC7hXHc4te9yUcyLHRnOe"
-
-components = {
- # Row 111: 对话选择-配图 (1217408)
- 111: """【任务标题】
-打开坏掉的门
-
-【资源配置】
-图片时机:
-互动内容
-互动反馈
-
-【情境引入】
-无
-
-【互动内容】
-要求:选择正确的回复
-选项:(音频)
-选项1:The door is open.(正确)
-- 反馈: 无
-选项2:The door is closed.
-- 反馈 Alex: No, look. This door is broken. It's always open.
-
-【后置对话】
-无""",
-
- # Row 120: 对话选择-配图 (1217409)
- 120: """【任务标题】
-查看关闭的门
-
-【资源配置】
-图片时机:
-互动内容
-互动反馈
-
-【情境引入】
-无
-
-【互动内容】
-要求:选择正确的回复
-选项:(音频)
-选项1:Look, the door is closed.(正确)
-- 反馈: 无
-选项2:Look, the door is open.
-- 反馈 Eva: No, this door is closed. Look again.
-
-【后置对话】
-无""",
-
- # Row 129: 对话挖空-配图 (1217410)
- 129: """【任务标题】
-还剩最后一扇门
-
-【资源配置】
-图片时机:
-互动内容
-互动反馈
-
-【情境引入】
-无
-
-【互动内容】
-Only one ___ left.(音频)
-选项1:door(正确)
-选项2:room
-
-【互动反馈】
-正确 Vicky : Yes! Just one more room.
-错误 Vicky : Think about it. What do we open?
-
-【后置对话】
-无""",
-
- # Row 133: 对话组句-配图 (1217411)
- 133: """【任务标题】
-发现门是关着的
-
-【资源配置】
-图片时机:
-互动内容
-互动反馈
-
-【情境引入】
-无
-
-【互动内容】
-题目:描述这扇门的状态
-(音频)
-选项1:The
-选项2:door
-选项3:is
-选项4:closed
-答案:The door is closed.
-辅助信息:用主语 The door + is + 状态词描述门的状态
-
-【互动反馈】
-正确 Vicky : Yes, it's closed. Peter must be inside!
-错误 Vicky : That doesn't look right. Think about the word order.
-
-【后置对话】
-无""",
-
- # Row 144: 对话组句-配图 (1217412)
- 144: """【任务标题】
-表示现在门打开了
-
-【资源配置】
-图片时机:
-互动内容
-互动反馈
-
-【情境引入】
-无
-
-【互动内容】
-题目:描述现在门的状态
-(音频)
-选项1:The
-选项2:door
-选项3:is
-选项4:open
-选项5:Now
-答案:Now the door is open.
-辅助信息:用主语 The door + is + 状态词描述门的状态;Now 放在句首表示时间
-
-【互动反馈】
-正确 Alex : Yes! The door is open now.
-错误 Alex : Hmm, try putting the words in the right order.
-
-【后置对话】
-无""",
-
- # Row 147: 看图拼词 (1217413)
- 147: """【任务标题】
-拼写 door 的英文
-
-【资源配置】
-图片文件名:1217413.png
-
-【互动内容】
-任务描述:请拼出门的英文单词
-题干:d(2)r
-答案:oo
-选项:o, a, e, r, n, p
-辅助信息:门的英文是 door / 中间有两个一样的字母哦
-
-【后置对话】
-无""",
-
- # Row 163: 对话挖空 (1217414)
- 163: """【任务标题】
-回忆窗户的状态
-
-【资源配置】无
-
-【情境引入】
-无
-
-【互动内容】
-I remember that. It was ___ before.(音频)
-选项1:closed(正确)
-选项2:open
-
-【互动反馈】
-正确 Alex : Yes, it was closed. But now it's different.
-错误 Alex : No. Think about what I just said about the window.
-
-【后置对话】
-无""",
-
- # Row 164: 对话挖空 (1217415)
- 164: """【任务标题】
-发现窗户现在是开着的
-
-【资源配置】无
-
-【情境引入】
-无
-
-【互动内容】
-But now it's ___.(音频)
-选项1:open(正确)
-选项2:closed
-
-【互动反馈】
-正确 Alex : Right! Someone opened it!
-错误 Alex : Look at the window again. Is it really closed now?
-
-【后置对话】
-无""",
-
- # Row 179: 对话朗读 (1217416)
- 179: """【任务标题】
-问候 Grace 和 Dan
-
-【资源配置】图片时机:无
-
-【情境引入】无
-
-【互动内容】
-User : I'm glad you get home!(朗读)
-
-【后置对话】
-无""",
-}
-
-results = {}
-for row_num, content in sorted(components.items()):
- body = {
- "valueRange": {
- "range": f"{SHEET_ID}!F{row_num}:F{row_num}",
- "values": [[content]]
- }
- }
- cmd = [
- "curl", "-s", "-X", "PUT",
- f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/values",
- "-H", f"Authorization: Bearer {TOKEN}",
- "-H", "Content-Type: application/json",
- "-d", json.dumps(body, ensure_ascii=False)
- ]
- result = subprocess.run(cmd, capture_output=True, text=True)
- resp = json.loads(result.stdout)
- code = resp.get("code", -1)
- msg = resp.get("msg", "unknown")
- print(f"Row {row_num}: code={code}, msg={msg}")
- results[row_num] = {"code": code, "msg": msg}
-
-# Summary
-success = sum(1 for r in results.values() if r["code"] == 0)
-print(f"\nTotal: {len(results)} writes, {success} succeeded, {len(results) - success} failed")
diff --git a/business_production/组件生产/backup/scripts/write_L4_F_configs.py b/business_production/组件生产/backup/scripts/write_L4_F_configs.py
deleted file mode 100644
index 8cebcb9..0000000
--- a/business_production/组件生产/backup/scripts/write_L4_F_configs.py
+++ /dev/null
@@ -1,249 +0,0 @@
-#!/usr/bin/env python3
-"""Generate and write F列 component configurations for L1-S2-U17-L4 门关啦"""
-import subprocess, json, sys
-
-# ============================================================
-# Get Bot token
-# ============================================================
-APP_SECRET = json.load(open('/root/.openclaw/credentials/xiaoyan/config.json'))['apps'][0]['appSecret']
-r = subprocess.run(['curl', '-s', '-X', 'POST',
- 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
- '-H', 'Content-Type: application/json',
- '-d', json.dumps({"app_id": "cli_a931175d41799cc7", "app_secret": APP_SECRET})],
- capture_output=True, text=True)
-TOKEN = json.loads(r.stdout)['tenant_access_token']
-SST = 'It4AsFkC7hXHc4te9yUcyLHRnOe'
-SID = 'wMQVyV'
-
-# ============================================================
-# All 16 component configurations → (row, config_text)
-# ============================================================
-configs = [
- # 1. Row10: 对话朗读 1217401 — S1主线 "准备回家"
- (10, """【任务标题】准备回家
-【资源配置】无
-【情境引入】Alex : Okay. Let's get home.
-【互动内容】
-(朗读台词)
-User : I need to get home too.
-【后置对话】无"""),
-
- # 2. Row15: 对话朗读 1217402 — S2主线 "回不了家了"
- (15, """【任务标题】回不了家了
-【资源配置】无
-【情境引入】大门被风吹关上了,Alex 的钥匙和 User 的包都在屋里。
-【互动内容】
-(朗读台词)
-User : I can't get home now!
-【后置对话】Vicky : Now we are all stuck here."""),
-
- # 3. Row36: 对话朗读 1217403 — S4主线 "查看猫门"
- (36, """【任务标题】查看猫门
-【资源配置】无
-【情境引入】Vicky : Is it open now?
-【互动内容】
-(朗读台词)
-User : Yes. The cat door is open.
-【后置对话】无"""),
-
- # 4. Row48: 对话挖空 1217404 — S5主线 "拜托Peter"
- (48, """【任务标题】拜托Peter
-【资源配置】无
-【情境引入】Vicky : Peter, how about you?
-【互动内容】
-(听力挖空)
-User : Please, Peter. We want to ___ ___.
- 答案词:get home
-【互动反馈】
-get home 正确 → Vicky : Peter, you're our only hope!
-get home 错误 → Vicky : Try again. What do we want to do?
-【后置对话】Vicky : Peter, you're my best little brother."""),
-
- # 5. Row58: 对话挖空-配图 1217405 — S6主线 "称赞Peter"
- (58, """【任务标题】称赞Peter
-【资源配置】【配图】1217405_img
-【情境引入】Peter 从猫门钻进了屋子。
-【互动内容】
-(听力挖空)
-User : Great! You're ___ now.
- 答案词:home
-【互动反馈】
-home 正确 → Alex : Yes! Peter is inside the house.
-home 错误 → Alex : Listen again. Where is Peter?
-【后置对话】无"""),
-
- # 6. Row59: 图片单选-配图 1217406 — S7主线 "让Peter开门"
- (59, """【任务标题】让Peter开门
-【资源配置】【配图】1217406_optA.png、1217406_optB.png、1217406_optC.png
-【情境引入】Peter 已经进了屋,但需要他帮忙开门。
-【互动内容】
-题目:What did User ask Peter to do?
-选项A:Open the door(正确)
- - 反馈 Vicky : Yes! We asked Peter to open the door.
-选项B:Close the door
- - 反馈 Vicky : No. We need to get in, not stay out.
-选项C:Find the keys
- - 反馈 Vicky : Hmm, the keys are inside. What did we ask Peter?
-【后置对话】Peter : Hmm... Who are you?"""),
-
- # 7. Row76: 对话朗读-配图 1217407 — S8主线 "门开了"
- (76, """【任务标题】门开了
-【资源配置】【配图】1217407_img
-【情境引入】Vicky 用捉迷藏游戏引诱 Peter 偷看,门果然开了。
-【互动内容】
-(朗读台词并显示配图)
-User : Look! The door is open!
-【后置对话】无"""),
-
- # 8. Row111: 对话选择-配图 1217408 — S10主线 "坏掉的门"
- (111, """【任务标题】坏掉的门
-【资源配置】【配图】1217408_optA.png、1217408_optB.png
-【情境引入】Alex : Look. This door is broken. It's always open.
-【互动内容】
-题目:What is wrong with this door?
-选项A:The door is open.(正确)
- - 反馈 Alex : Right. The door is broken, so it's always open.
-选项B:The door is closed.
- - 反馈 Alex : No. Look again at the door.
-【后置对话】User : Let me see who's hiding inside."""),
-
- # 9. Row120: 对话选择-配图 1217409 — S11主线 "关闭的房门"
- (120, """【任务标题】关闭的房门
-【资源配置】【配图】1217409_optA.png、1217409_optB.png
-【情境引入】Eva : This is Vicky's and my room.
-【互动内容】
-题目:How is the door?
-选项A:The door is open.
- - 反馈 Eva : No. Look again. Is the door open?
-选项B:The door is closed.(正确)
- - 反馈 Eva : Yes! The door is closed. Someone must be inside.
-【后置对话】User : Someone must be hiding in there."""),
-
- # 10. Row129: 对话挖空-配图 1217410 — S13主线 "还剩一扇门"
- (129, """【任务标题】还剩一扇门
-【资源配置】【配图】1217410_img
-【情境引入】Vicky : Good job! Now, let's find Peter.
-【互动内容】
-(听力挖空)
-User : Only one ___ left.
- 答案词:door
-【互动反馈】
-door 正确 → Vicky : Right! Only one door left. Peter must be there!
-door 错误 → Vicky : Let's think. What is left to check?
-【后置对话】User : Peter must be in there!"""),
-
- # 11. Row133: 对话组句-配图 1217411 — S14主线 "发现门关着"
- (133, """【任务标题】发现门关着
-【资源配置】【配图】1217411_img
-【情境引入】终于找到了最后一扇门,但门是关着的。
-【互动内容】
-(组句)
-拼出句子:The door is closed.
-【互动反馈】
-正确 → Vicky : Yes! The door is closed. Peter is hiding inside!
-错误 → Vicky : Let's try again. Is the door open or closed?
-【后置对话】无"""),
-
- # 12. Row144: 对话组句-配图 1217412 — S15主线 "门打开了"
- (144, """【任务标题】门打开了
-【资源配置】【配图】1217412_img
-【情境引入】Alex 和 User 一起用力推开了门,找到了 Peter。
-【互动内容】
-(组句)
-拼出句子:The door is open.
-【互动反馈】
-正确 → Peter : Haha! You got me!
-错误 → Peter : Try again! How is the door now?
-【后置对话】无"""),
-
- # 13. Row153: 看图拼词 1217413 — S16主线 "修理指南"
- (153, """【任务标题】修理指南
-【资源配置】【配图】1217413_img
-【情境引入】Alex : Look, I have a book about doors.
-【互动内容】
-(看图拼词)
-图中是一个关闭的门,拼出对应的单词:closed
- 答案词:closed
-【互动反馈】
-正确 → Alex : Correct! Closed doors don't open easily.
-错误 → Alex : This word means "not open". Try again.
-【后置对话】Alex : Let's fix it."""),
-
- # 14. Row169: 对话挖空 1217414 — S17主线 "回忆窗户状态"
- (169, """【任务标题】回忆窗户状态
-【资源配置】无
-【情境引入】Alex : That window was closed before the game.
-【互动内容】
-(听力挖空)
-User : I remember that. The door was ___ before.
- 答案词:closed
-【互动反馈】
-closed 正确 → Alex : Yes! It was closed before.
-closed 错误 → Alex : Think back. Was the door open or closed?
-【后置对话】无"""),
-
- # 15. Row170: 对话挖空 1217415 — S18主线 "窗户开着"
- (170, """【任务标题】窗户开着
-【资源配置】无
-【情境引入】门之前是关着的,但现在...
-【互动内容】
-(听力挖空)
-User : But now it's ___.
- 答案词:open
-【互动反馈】
-open 正确 → Alex : Yes! Now it's open. Very strange!
-open 错误 → Alex : Look now. The door is not closed anymore.
-【后置对话】无"""),
-
- # 16. Row189: 对话朗读 1217416 — S19主线 "问候Grace和Dan"
- (189, """【任务标题】问候Grace和Dan
-【资源配置】无
-【情境引入】Wood 先生和太太终于回家了!
-【互动内容】
-(朗读台词)
-User : I'm glad you get home!
-【后置对话】Grace : Thank you for staying with the kids!"""),
-]
-
-# ============================================================
-# Write each config to F column using single-cell write
-# ============================================================
-success = 0
-fail = 0
-
-for row, text in configs:
- cell = f"{SID}!F{row}:F{row}"
- body = json.dumps({"valueRange": {"range": cell, "values": [[text]]}}, ensure_ascii=False)
- r = subprocess.run(['curl', '-s', '-X', 'PUT',
- f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SST}/values',
- '-H', f'Authorization: Bearer {TOKEN}',
- '-H', 'Content-Type: application/json; charset=utf-8',
- '-d', body], capture_output=True, text=True)
- resp = json.loads(r.stdout)
- if resp.get('code') == 0:
- success += 1
- print(f' ✅ Row {row:3d} | {text.split(chr(10))[0][5:]}')
- else:
- fail += 1
- print(f' ❌ Row {row:3d} | {resp.get("msg", "unknown")}')
-
-print(f'\n写入完成:{success} 成功 / {fail} 失败')
-
-# ============================================================
-# Verify: read back F column for all configured rows
-# ============================================================
-if fail == 0:
- print('\n=== 回读验证 ===')
- for row, _ in configs:
- cell = f"{SID}!F{row}:F{row}"
- r = subprocess.run(['curl', '-s', '-X', 'GET',
- f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SST}/values/{cell}',
- '-H', f'Authorization: Bearer {TOKEN}'], capture_output=True, text=True)
- resp = json.loads(r.stdout)
- vals = resp.get('data', {}).get('valueRange', {}).get('values', [[]])
- content = vals[0][0] if vals and vals[0] else None
- if content:
- title = content.split('\n')[0].replace('【任务标题】', '') if content else 'EMPTY'
- print(f' ✅ Row{row}: {title}')
- else:
- print(f' ❌ Row{row}: EMPTY!')
diff --git a/business_production/组件生产/backup/scripts/write_L5_G_configs.py b/business_production/组件生产/backup/scripts/write_L5_G_configs.py
deleted file mode 100644
index 9c9bf34..0000000
--- a/business_production/组件生产/backup/scripts/write_L5_G_configs.py
+++ /dev/null
@@ -1,369 +0,0 @@
-#!/usr/bin/env python3
-"""Generate G列 component configs for L1-S2-U17-L5 笨蛋坏蛋? (English)"""
-import subprocess, json
-
-APP_SECRET = json.load(open('/root/.openclaw/credentials/xiaoyan/config.json'))['apps'][0]['appSecret']
-r = subprocess.run(['curl', '-s', '-X', 'POST',
- 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
- '-H', 'Content-Type: application/json',
- '-d', json.dumps({"app_id": "cli_a931175d41799cc7", "app_secret": APP_SECRET})],
- capture_output=True, text=True)
-TOKEN = json.loads(r.stdout)['tenant_access_token']
-SST = 'DCcKsLbrmhfXgrtB7N2c9GA4ntf'
-SID = 'wMQVyV'
-
-# (row, config)
-configs = [
- # Row14: 互动 — point — 机器人指着黑板
- (14, """【任务标题】What does it do?
-【资源配置】无
-【情境引入】Ben : See? I point at it.
-【互动内容】
-(听力挖空 / 看图回答)
-User : It ___ at the blackboard.
- 答案词:points
- KP:point — v. 指向
-【互动反馈】
-points 正确 → Ben : Yes. It points at the blackboard.
-points 错误 → Ben : Look again. What does it do?
-【后置对话】Ben : It talks a lot."""),
-
- # Row28: 互动 — points — 补充描述机器人行为
- (28, """【任务标题】Talk about the robot
-【资源配置】无
-【情境引入】Robot : Bip bop! Bip bop bip!
-【互动内容】
-(朗读台词)
-User : It points at the blackboard.
- KP:point — v. 指向
-【互动反馈】
-正确 → Ben : That's right. And what else?
-错误 → Ben : Look at the robot. What is it pointing at?
-【后置对话】Ben : And it talks to itself!"""),
-
- # Row29: 互动 — talks to — 继续描述机器人
- (29, """【任务标题】What else does it do?
-【资源配置】无
-【情境引入】Robot : Bip bop! Bip bop bip!
-【互动内容】
-(朗读台词)
-User : It talks to itself...
- KP:talk to... — 和...说话
-【互动反馈】
-正确 → Ben : It talks to itself!
-错误 → Ben : Listen. Is the robot talking to someone?
-【后置对话】Ben : ...in a language we can't understand!"""),
-
- # Row36: 互动 — a lot of — 课桌挡路
- (36, """【任务标题】What is blocking it?
-【资源配置】无
-【情境引入】Ben : What is it doing now?
-【互动内容】
-(听力挖空)
-User : But ___ ___ ___ our desks block it.
- 答案词:a lot of
- KP:a lot of — det. 大量的
-【互动反馈】
-a lot of 正确 → Ben : Yes! The desks are in its way.
-a lot of 错误 → Ben : Many desks are blocking it.
-【后置对话】场景:机器人推开桌椅"""),
-
- # Row54: 互动 — a lot of — 需要证据
- (54, """【任务标题】What do we need?
-【资源配置】无
-【情境引入】Ben : Fine. What should we do now?
-【互动内容】
-(听力挖空 / 朗读)
-User : We need ___ ___ ___ proof!
- 答案词:a lot of
- KP:a lot of — det. 大量的
-【互动反馈】
-正确 → Ben : Okay. We'll find more.
-错误 → Ben : We need more than just a guess.
-【后置对话】无"""),
-
- # Row55: 互动 — talk to — 建议和机器人谈谈
- (55, """【任务标题】What should we do?
-【资源配置】无
-【情境引入】User : We need a lot of proof!
-【互动内容】
-(朗读台词)
-User : Let's talk to it!
- KP:talk to... — 和...说话
-【互动反馈】
-正确 → Ben : Talk to it? But it's a robot!
-错误 → Ben : How else can we find out?
-【后置对话】Ben 从藏身处跳出来"""),
-
- # Row61: 互动 — can't understand — 不懂机器人语言
- (61, """【任务标题】Can you understand it?
-【资源配置】无
-【情境引入】Robot : Bip bop!
-【互动内容】
-(朗读台词)
-User : We can't understand it.
- KP:I can/can't understand...
-【互动反馈】
-正确 → Ben : Right. Let's try asking with pictures.
-错误 → Ben : Can we understand robot language?
-【后置对话】Ben : What's your name?"""),
-
- # Row67: 互动 — understand — 理解了11的名字
- (67, """【任务标题】What do you think?
-【资源配置】无
-【情境引入】Ben : What's your name?
-Robot points at itself — it shows "11"
-【互动内容】
-(朗读台词)
-User : Oh, I understand!
- KP:understand — v. 理解
-【互动反馈】
-正确 → Ben : You understand? Tell me!
-错误 → Ben : Do you know what it means?
-【后置对话】User points out the number 11"""),
-
- # Row68: 互动 — points to — 指出名字
- (68, """【任务标题】What is it showing?
-【资源配置】无
-【情境引入】User : Oh, I understand!
-【互动内容】
-(朗读台词)
-User : It points to its name.
- KP:point — v. 指向
-【互动反馈】
-正确 → Ben : Its name is 11!
-错误 → Ben : What is the robot showing us?
-【后置对话】User : Its name is 11!"""),
-
- # Row80: 互动 — talk — 建议慢慢说
- (80, """【任务标题】How should we talk?
-【资源配置】无
-【情境引入】Ben is asking too many questions at once.
-【互动内容】
-(朗读台词)
-User : Just talk slowly.
- KP:talk — v. 说话
-【互动反馈】
-正确 → Ben : Okay. One question at a time.
-错误 → Ben : Should I ask slower?
-【后置对话】Ben : Alright. Where are you from?"""),
-
- # Row85: 互动 — talk to — 尝试用画沟通
- (85, """【任务标题】What is it doing?
-【资源配置】无
-【情境引入】Robot starts drawing on the blackboard.
-【互动内容】
-(朗读台词)
-User : Oh! It tries to talk to us with drawing.
- KP:talk to... — 和...说话
-【互动反馈】
-正确 → Ben : A picture! What is it?
-错误 → Ben : What is it drawing? Is it a message?
-【后置对话】Ben : That is the Speedy Monkey logo!"""),
-
- # Row88: 互动 — understand — 理解来源
- (88, """【任务标题】Where is it from?
-【资源配置】无
-【情境引入】Robot draws the Speedy Monkey logo.
-【互动内容】
-(朗读台词)
-User : Oh! I understand! It is from Speedy Monkey!
- KP:understand — v. 理解
-【互动反馈】
-正确 → Ben : Speedy Monkey! I knew it!
-错误 → Ben : Who is that logo from?
-【后置对话】Ben : Speedy monkey sent a spy here!"""),
-
- # Row94: 互动 — talk — 要求继续
- (94, """【任务标题】What next?
-【资源配置】无
-【情境引入】Ben thinks Speedy Monkey people are bad.
-【互动内容】
-(朗读台词)
-User : Talk more to it!
- KP:talk — v. 说话
-【互动反馈】
-正确 → Ben : Fine. What do you want?
-错误 → Ben : Should we ask more questions?
-【后置对话】Ben : Okay, what do you want?"""),
-
- # Row98: 互动 — points at — 指另一个标记
- (98, """【任务标题】What is it showing now?
-【资源配置】无
-【情境引入】Robot draws another mark on the blackboard.
-【互动内容】
-(朗读台词)
-User : It points at another mark.
- KP:point — v. 指向
-【互动反馈】
-正确 → Ben : What is that mark?
-错误 → Ben : Look at what it is pointing at.
-【后置对话】Ben : Is that... a school?"""),
-
- # Row104: 互动 — points at — 又指一个标记
- (104, """【任务标题】What is it now?
-【资源配置】无
-【情境引入】Ben : Why are you here?
-Robot draws another mark.
-【互动内容】
-(朗读台词)
-User : It points at another mark.
- KP:point — v. 指向
-【互动反馈】
-正确 → Ben : A gift mark!
-错误 → Ben : What does the drawing show?
-【后置对话】Ben : It is a gift!"""),
-
- # Row109: 互动 — understand — 我终于懂了
- (109, """【任务标题】What do you think?
-【资源配置】无
-【情境引入】Robot drew Speedy Monkey, school, and gift marks.
-【互动内容】
-(朗读台词)
-User : Ben! I think I understand!
- KP:understand — v. 理解
-【互动反馈】
-正确 → Ben : What do you understand?
-错误 → Ben : Think about the pictures again.
-【后置对话】User explains the spy theory"""),
-
- # Row110: 互动 — talk — 需要谈话
- (110, """【任务标题】What should we do?
-【资源配置】无
-【情境引入】User thinks they've found a spy.
-【互动内容】
-(朗读台词)
-User : We need to talk! You and me!
- KP:talk — v. 说话
-【互动反馈】
-正确 → Ben : Okay! Let's figure this out.
-错误 → Ben : We need to discuss what we found!
-【后置对话】Ben : Okay!"""),
-
- # Row116: 互动 — a lot of — 很多信息
- (116, """【任务标题】What did it tell us?
-【资源配置】无
-【情境引入】User pieces together the clues.
-【互动内容】
-(朗读台词 / 听力挖空)
-User : It tells ___ ___ ___ things!
- 答案词:a lot of
- KP:a lot of — det. 大量的
-【互动反馈】
-正确 → Ben : Yes. Speedy Monkey, school, gift...
-错误 → Ben : Remember all the drawings?
-【后置对话】User : Vala School is a gift to Speedy Monkey!"""),
-
- # Row123: 互动 — a lot of — 很多信息
- (123, """【任务标题】What should we do?
-【资源配置】无
-【情境引入】Ben : What should we do now?
-【互动内容】
-(朗读台词)
-User : It is a lot of information.
- KP:a lot of — det. 大量的
-【互动反馈】
-正确 → Ben : Yes. We have enough to tell the mayor!
-错误 → Ben : Is it enough to act on?
-【后置对话】无"""),
-
- # Row124: 互动 — talk about — 给镇长打电话
- (124, """【任务标题】Who should we tell?
-【资源配置】无
-【情境引入】Ben agrees they have enough proof.
-【互动内容】
-(朗读台词)
-User : We need to call Mayor Tom and talk about it!
- KP:talk to/talk about...
-【互动反馈】
-正确 → Ben : Good idea. Let's call him now!
-错误 → Ben : Who should we call for help?
-【后置对话】Calling Mayor Tom..."""),
-
- # Row131: 互动 — point at — 指给镇长看
- (131, """【任务标题】Show the mayor
-【资源配置】无
-【情境引入】Tom arrives. Ben explains.
-【互动内容】
-(朗读台词)
-User : Look! I point at it.
- KP:point — v. 指向
-【互动反馈】
-正确 → Tom : The robot?
-错误 → Tom : What are you pointing at?
-【后置对话】Tom : Oh? A spy? In the classroom?"""),
-
- # Row137: 互动 — a lot of — 描述异常行为
- (137, """【任务标题】What did it do?
-【资源配置】无
-【情境引入】Ben lists the spy evidence.
-【互动内容】
-(听力挖空 / 朗读)
-User : And it said ___ ___ ___ strange things!
- 答案词:a lot of
- KP:a lot of — det. 大量的
-【互动反馈】
-正确 → Tom : Hmm, I see.
-错误 → Tom : Did it say many strange things?
-【后置对话】User shows the blackboard evidence"""),
-
- # Row148: 互动 — don't understand — 感到困惑
- (148, """【任务标题】What is the truth?
-【资源配置】无
-【情境引入】Tom says robot doesn't want to give school to Speedy Monkey.
-【互动内容】
-(朗读台词)
-User : Wait. I don't understand.
- KP:I can/can't understand...
-【互动反馈】
-正确 → Lin : Why not let it tell you itself?
-错误 → Lin : Let me help you understand.
-【后置对话】Robot explains itself"""),
-
- # Row163: 核心互动-口语 — talk to — 道歉
- (163, """【任务标题】Apologise to Jay and Lin
-【资源配置】无
-【情境引入】Tom asks the kids if they have something to say.
-【互动内容】
-(口语表达)
-User : I should talk to you.
- KP:talk — v. 说话
-【互动反馈】
-正确 → Jay : It's okay.
-错误 → Jay : Go on. Say what you need to say.
-【后置对话】User and Ben apologise"""),
-]
-
-# Write and verify
-success = fail = 0
-for row, text in configs:
- cell = f"{SID}!G{row}:G{row}"
- body = json.dumps({"valueRange": {"range": cell, "values": [[text]]}}, ensure_ascii=False)
- r = subprocess.run(['curl', '-s', '-X', 'PUT',
- f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SST}/values',
- '-H', f'Authorization: Bearer {TOKEN}',
- '-H', 'Content-Type: application/json; charset=utf-8',
- '-d', body], capture_output=True, text=True)
- resp = json.loads(r.stdout)
- if resp.get('code') == 0:
- success += 1
- title = text.split('\n')[0].replace('【任务标题】', '')
- print(f' ✅ Row {row:3d} | {title}')
- else:
- fail += 1
- print(f' ❌ Row {row:3d} | {resp.get("msg","?")}')
-
-print(f'\n写入:{success}成功 / {fail}失败')
-
-if fail == 0:
- print('\n=== 回读验证 ===')
- for row, _ in configs:
- cell = f"{SID}!G{row}:G{row}"
- r = subprocess.run(['curl', '-s', '-X', 'GET',
- f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SST}/values/{cell}',
- '-H', f'Authorization: Bearer {TOKEN}'], capture_output=True, text=True)
- resp = json.loads(r.stdout)
- vals = resp.get('data',{}).get('valueRange',{}).get('values',[[]])
- content = vals[0][0] if vals and vals[0] else None
- title = content.split('\n')[0].replace('【任务标题】', '') if content else 'EMPTY'
- print(f' ✅ Row{row}: {title}')
diff --git a/business_production/组件生产/backup/scripts/write_L5_G_configs_v2.py b/business_production/组件生产/backup/scripts/write_L5_G_configs_v2.py
deleted file mode 100644
index 66e732f..0000000
--- a/business_production/组件生产/backup/scripts/write_L5_G_configs_v2.py
+++ /dev/null
@@ -1,215 +0,0 @@
-#!/usr/bin/env python3
-"""Generate G列 component configs for L1-S2-U17-L5 笨蛋坏蛋?(v2 — updated row numbers)"""
-import subprocess, json
-
-APP_SECRET = json.load(open('/root/.openclaw/credentials/xiaoyan/config.json'))['apps'][0]['appSecret']
-r = subprocess.run(['curl', '-s', '-X', 'POST',
- 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
- '-H', 'Content-Type: application/json',
- '-d', json.dumps({"app_id": "cli_a931175d41799cc7", "app_secret": APP_SECRET})],
- capture_output=True, text=True)
-TOKEN = json.loads(r.stdout)['tenant_access_token']
-SST = 'DCcKsLbrmhfXgrtB7N2c9GA4ntf'
-SID = 'wMQVyV'
-
-# ===== 对话朗读 (6) =====
-# ===== 对话挖空 (3) =====
-# ===== 互动 (7) =====
-# ===== 核心互动-口语 (1) =====
-
-configs = [
- # --- 对话朗读 ---
- (14, """【任务标题】机器人在指向什么?
-【资源配置】图片时机:无
-【情境引入】Ben : It points at something!
-【互动内容】It points at the blackboard.(朗读)
-【后置对话】Ben : That's right. And it also talks a lot!"""),
-
- (29, """【任务标题】机器人在自言自语吗?
-【资源配置】图片时机:无
-【情境引入】Robot : Bip bop! Bip bop bip!
-【互动内容】Hmm, it talks to itself.(朗读)
-【后置对话】Ben : ...in a language we can't understand!"""),
-
- (42, """【任务标题】机器人为什么走不动?
-【资源配置】图片时机:无
-【情境引入】Ben : What is it doing now?
-【互动内容】But a lot of our desks block it.(朗读)
-【后置对话】Ben : Yes! The desks are in its way."""),
-
- (66, """【任务标题】我们该怎么办?
-【资源配置】图片时机:无
-【情境引入】Ben : Fine. You're right. What should we do now?
-【互动内容】Let's talk to it!(朗读)
-【后置对话】Ben : Talk to it? But it's a robot!"""),
-
- (77, """【任务标题】你能听懂机器人吗?
-【资源配置】图片时机:无
-【情境引入】Robot : Bip bop!
-【互动内容】We can't understand it.(朗读)
-【后置对话】Ben : What's your name?"""),
-
- (89, """【任务标题】你明白了什么?
-【资源配置】图片时机:无
-【情境引入】Robot points at the number "11" on its chest.
-【互动内容】Oh, I understand!(朗读)
-【后置对话】Ben : You understand? Tell me!"""),
-
- # --- 对话挖空 ---
- (96, """【任务标题】指出机器人的名字
-【资源配置】无
-【情境引入】Ben : Wow, it is pointing at itself!
-【互动内容】It ___ to its name.(音频)
-选项1:points(正确)
-选项2:talks
-【互动反馈】
-正确 Ben : Yes! It points to its name. Its name is 11!
-错误 Ben : What is the robot doing? Think again.
-【后置对话】User : Its name is 11! We call it 11!"""),
-
- (119, """【任务标题】机器人想做什么?
-【资源配置】无
-【情境引入】Robot draws on the blackboard.
-【互动内容】Oh! It tries to ___ to us.(音频)
-选项1:talk(正确)
-选项2:point
-【互动反馈】
-正确 Ben : Yes! It wants to talk with pictures!
-错误 Ben : It is not pointing. What else?
-【后置对话】Ben : That is the Speedy Monkey logo!"""),
-
- (138, """【任务标题】机器人又指了什么?
-【资源配置】无
-【情境引入】Robot draws a school mark on the blackboard.
-【互动内容】It ___ at another mark.(音频)
-选项1:points(正确)
-选项2:talks
-【互动反馈】
-正确 Ben : Is that... a school?
-错误 Ben : Look at what the robot is doing with the mark.
-【后置对话】Ben : Is that a school?"""),
-
- # --- 互动 ---
- (150, """【任务标题】又是什么标记?
-【资源配置】无
-【情境引入】Robot draws a gift mark on the blackboard.
-【互动内容】It points at another mark.
- KP:point — v. 指向
-【互动反馈】
-正确 → Ben : It is a gift!
-错误 → Ben : Look at the mark. What is it?
-【后置对话】Ben : Speedy Monkey? School? Gift?"""),
-
- (161, """【任务标题】你发现了什么?
-【资源配置】无
-【情境引入】Ben : Speedy Monkey? School? Gift?
-【互动内容】Ben! I think I understand!
- KP:understand — v. 理解
-【互动反馈】
-正确 → Ben : What do you understand?
-错误 → Ben : Look at the marks again.
-【后置对话】User explains the spy theory"""),
-
- (168, """【任务标题】和 Ben 单独商量
-【资源配置】无
-【情境引入】User thinks the robot is a spy.
-【互动内容】We need to talk! You and me!
- KP:talk — v. 说话
-【互动反馈】
-正确 → Ben : Okay! Let's figure this out.
-错误 → Ben : We need to talk about what we found!
-【后置对话】User : Vala School is a gift to Speedy Monkey!"""),
-
- (181, """【任务标题】快告诉镇长!
-【资源配置】无
-【情境引入】Ben : What should we do now?
-【互动内容】We need to call Mayor Tom! Let's talk about it!
- KP:talk about... — 谈论...
-【互动反馈】
-正确 → Ben : Good idea. Let's call him now!
-错误 → Ben : Who should we call for help?
-【后置对话】Calling Mayor Tom..."""),
-
- (194, """【任务标题】指给镇长看
-【资源配置】无
-【情境引入】Tom : So you kids want to talk to me?
-【互动内容】Look! I point at it.
- KP:point — v. 指向
-【互动反馈】
-正确 → Tom : The robot?
-错误 → Tom : What are you pointing at?
-【后置对话】Tom : Oh? A spy? In the classroom?"""),
-
- (207, """【任务标题】给镇长看证据
-【资源配置】无
-【情境引入】Tom : I don't understand. Anything else?
-【互动内容】Look! Here are a lot of strange marks!
- KP:a lot of — det. 大量的
-【互动反馈】
-正确 → Tom : Hmm, I see.
-错误 → Tom : Are there many strange marks?
-【后置对话】User shows the blackboard to Tom"""),
-
- (224, """【任务标题】到底怎么回事?
-【资源配置】无
-【情境引入】Tom : The school isn't a gift to Speedy Monkey!
-【互动内容】Wait. I don't understand.
- KP:I can/can't understand...
-【互动反馈】
-正确 → Lin : Why not let it tell you itself?
-错误 → Lin : Let me help you understand.
-【后置对话】Lin fixes the robot"""),
-
- # --- 核心互动-口语 ---
- (245, """【任务标题】向 Jay 和 Lin 道歉
-【资源配置】无
-【情境引入】Tom : Kids, do you have something to say?
-【互动内容】
-(口语表达)
-I should talk to you.
-I should understand you.
-I can understand you now.
- KP:talk / understand
-【互动反馈】
-正确 → Jay : Thank you. We feel much better now.
-错误 → Lin : Go on. Say what's in your heart.
-【后置对话】Jay : I understand. Lin : We all make mistakes."""),
-]
-
-# Write
-success = fail = 0
-for row, text in configs:
- cell = f"{SID}!G{row}:G{row}"
- body = json.dumps({"valueRange": {"range": cell, "values": [[text]]}}, ensure_ascii=False)
- r = subprocess.run(['curl', '-s', '-X', 'PUT',
- f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SST}/values',
- '-H', f'Authorization: Bearer {TOKEN}',
- '-H', 'Content-Type: application/json; charset=utf-8',
- '-d', body], capture_output=True, text=True, timeout=15)
- resp = json.loads(r.stdout)
- if resp.get('code') == 0:
- success += 1
- title = text.split('\n')[0].replace('【任务标题】', '')
- print(f' ✅ Row {row:3d} | {title}')
- else:
- fail += 1
- print(f' ❌ Row {row:3d} | {resp.get("msg","?")}')
- print(f' debug: {r.stdout[:200]}')
-
-print(f'\n写入结果:{success}成功 / {fail}失败')
-
-if fail == 0:
- print('\n=== 回读验证 ===')
- for row, _ in configs:
- cell = f"{SID}!G{row}:G{row}"
- r = subprocess.run(['curl', '-s', '-X', 'GET',
- f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SST}/values/{cell}?valueRenderOption=ToString',
- '-H', f'Authorization: Bearer {TOKEN}'], capture_output=True, text=True, timeout=15)
- resp = json.loads(r.stdout)
- vals = resp.get('data',{}).get('valueRange',{}).get('values',[[]])
- content = vals[0][0] if vals and vals[0] else None
- title = content.split('\n')[0].replace('【任务标题】', '') if content else 'EMPTY'
- status = '✅' if content else '❌ EMPTY'
- print(f' {status} Row{row}: {title}')
-else:
- print('\n⚠️ 有失败项,请检查')
diff --git a/business_production/组件生产/backup/scripts/write_p4_safe.py b/business_production/组件生产/backup/scripts/write_p4_safe.py
deleted file mode 100644
index 401f035..0000000
--- a/business_production/组件生产/backup/scripts/write_p4_safe.py
+++ /dev/null
@@ -1,175 +0,0 @@
-#!/usr/bin/env python3
-"""
-P4 rewrite with automation-safe approach:
-- jsonData: use ability=['听觉抓取关键信息'], explanation='' (automation-compatible)
-- 题目1/题目2: include full ability + explanation info in text
-"""
-import json, subprocess, sys, os, time
-
-AT = "CMHSbUUjka3TrUsaxxEc297ongf"
-TID = "tblVmeDtBDKsAEfz"
-BASE = os.path.expanduser("~/.openclaw/workspace-xiaoyan")
-CRED_FILE = os.path.expanduser("~/.openclaw/credentials/xiaoyan/config.json")
-
-sys.path.insert(0, os.path.join(BASE, "scripts"))
-import rewrite_p4_all as rw
-
-RECORD_IDS = {
- "021301": "recvjufKJO8d0O",
- "021401": "recvjufM763ijb",
- "021501": "recvjufM76lEsW",
- "021601": "recvjufM76hNv5",
- "021701": "recvjufM76eMKs",
- "021801": "recvjufM76lRHQ",
- "022101": "recvjufM76o6of",
- "032501": "recvjufM76k4dx",
- "032901": "recvjufM76frUP",
-}
-
-def get_token():
- with open(CRED_FILE) as f:
- cred = json.load(f)
- app_id = cred["apps"][0]["appId"]
- app_secret = cred["apps"][0]["appSecret"]
- r = subprocess.run(["curl","-s","-X","POST",
- "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
- "-H","Content-Type: application/json",
- "-d",json.dumps({"app_id":app_id,"app_secret":app_secret})],
- capture_output=True, text=True)
- return json.loads(r.stdout)["tenant_access_token"]
-
-def make_qtext_with_info(questions):
- """Generate 题目 text with dialogue, ability and explanation info"""
- lines = []
- for i, q in enumerate(questions, 1):
- lines.append(f"{i}.")
- lines.append(f"【描述】{q.get('questionDesc','')}")
- lines.append(f"【听力文本】")
- if 'dialogue' in q:
- lines.append(q['dialogue'])
- lines.append(f"【题目】")
- lines.append(q['question'])
- for j, opt in enumerate(q.get('options',[])):
- marker = "(正确)" if j == q.get('answer',[-1])[0] else ""
- lines.append(f"{chr(65+j)}. {opt}{marker}")
- # Add ability info
- ability = q.get('new_ability', q.get('ability', ['听力理解']))
- lines.append(f"【能力标签】{'|'.join(ability) if isinstance(ability,list) else ability}")
- # Add explanation
- lines.append(f"【解析】{q.get('explanation','')}")
- lines.append("")
- return "\n".join(lines)
-
-def sanitize_json(json_data):
- """Replace ability/explanation with automation-safe values"""
- for qs in json_data.get("first", {}).get("questionSet", []):
- qs["ability"] = ["听觉抓取关键信息"]
- qs["explanation"] = ""
- second = json_data.get("second", {})
- if second and isinstance(second, dict) and "questionSet" in second:
- for qs in second.get("questionSet", []):
- qs["ability"] = ["听觉抓取关键信息"]
- qs["explanation"] = ""
- return json_data
-
-def write_one(token, qsid, record_id, json_data, q1_text, q2_text):
- """Write one record and verify"""
- json_str = json.dumps(json_data, ensure_ascii=False)
- fields = {"jsonData": json_str, "题目1": q1_text, "题目2": q2_text}
- payload = json.dumps({"fields": fields}, ensure_ascii=False)
-
- tmp = f"/tmp/p4_safe_{record_id}.json"
- with open(tmp, "w") as f:
- f.write(payload)
-
- r = subprocess.run(["curl","-s","-X","PUT",
- f"https://open.feishu.cn/open-apis/bitable/v1/apps/{AT}/tables/{TID}/records/{record_id}",
- "-H",f"Authorization: Bearer {token}",
- "-H","Content-Type: application/json",
- "-d",f"@{tmp}"],
- capture_output=True, text=True, timeout=30)
- os.remove(tmp)
-
- resp = json.loads(r.stdout)
- if resp.get("code") != 0:
- return False, f"API error: {resp.get('msg','')}"
-
- # Verify
- r = subprocess.run(["curl","-s","-X","GET",
- f"https://open.feishu.cn/open-apis/bitable/v1/apps/{AT}/tables/{TID}/records/{record_id}",
- "-H",f"Authorization: Bearer {token}"],
- capture_output=True, text=True, timeout=30)
- vdata = json.loads(r.stdout)
- if vdata.get("code") != 0:
- return False, f"Verify error: {vdata.get('msg','')}"
-
- rec = vdata.get("data",{}).get("record",{})
- jd = rec.get("fields",{}).get("jsonData","")
- q1 = rec.get("fields",{}).get("题目1","") or ""
-
- if not jd:
- return False, "jsonData empty"
-
- try:
- parsed = json.loads(jd)
- fqs = parsed.get("first",{}).get("questionSet",[])
- if not fqs:
- return False, "no first questions"
- q0_question = fqs[0].get("question","")
- q0_ability = fqs[0].get("ability","")
- return True, f"Qs={len(fqs)}, q0='{q0_question[:30]}', ability={q0_ability}, Q1_len={len(q1)}"
- except Exception as e:
- return False, f"parse: {e}"
-
-def main():
- token = get_token()
- print(f"Token: {token[:15]}...")
- results = []
-
- for qsid, record_id in RECORD_IDS.items():
- data = rw.RECORD_DATA.get(qsid)
- if not data:
- continue
-
- fb = data["first_block"]
- sb = data["second_block"]
- fqs = data["first_qs_list"]
- sqs = data["second_qs_list"]
-
- # Build jsonData - keep original dialogue but not in final jsonData
- json_data = {"first": fb, "second": sb}
-
- # Build Q1/Q2 text with full info
- q1_text = make_qtext_with_info(fqs)
- q2_text = make_qtext_with_info(sqs) if sqs else ""
-
- # Clean dialogues from jsonData and sanitize
- for q in fb["questionSet"]:
- q.pop("dialogue", None)
- q.pop("new_ability", None)
- if sb and isinstance(sb, dict) and "questionSet" in sb:
- for q in sb["questionSet"]:
- q.pop("dialogue", None)
- q.pop("new_ability", None)
-
- json_data = sanitize_json(json_data)
-
- print(f"\nWriting {qsid} ({record_id})...")
- ok, msg = write_one(token, qsid, record_id, json_data, q1_text, q2_text)
- status = "✅" if ok else "❌"
- print(f" {status} {msg}")
- results.append((qsid, ok, msg))
- time.sleep(0.5)
-
- success = sum(1 for r in results if r[1])
- fails = sum(1 for r in results if not r[1])
- print(f"\n{'='*60}")
- print(f"FINAL: {success} succeeded, {fails} failed")
-
- if fails:
- for qsid, ok, msg in results:
- if not ok:
- print(f" ❌ {qsid}: {msg}")
-
-if __name__ == "__main__":
- main()
diff --git a/business_production/组件生产/backup/scripts/write_p4_to_bitable.py b/business_production/组件生产/backup/scripts/write_p4_to_bitable.py
deleted file mode 100644
index 21ce3fa..0000000
--- a/business_production/组件生产/backup/scripts/write_p4_to_bitable.py
+++ /dev/null
@@ -1,192 +0,0 @@
-#!/usr/bin/env python3
-"""
-Write all P4 rewrite records to bitable using direct API calls.
-Avoids shell escaping issues.
-"""
-import json, subprocess, os, sys
-
-APP_TOKEN = "CMHSbUUjka3TrUsaxxEc297ongf"
-TABLE_ID = "tblVmeDtBDKsAEfz"
-BASE_DIR = os.path.expanduser("~/.openclaw/workspace-xiaoyan")
-CRED_FILE = os.path.expanduser("~/.openclaw/credentials/xiaoyan/config.json")
-
-RECORD_IDS = {
- "021301": "recvjufKJO8d0O",
- "021401": "recvjufM763ijb",
- "021501": "recvjufM76lEsW",
- "021601": "recvjufM76hNv5",
- "021701": "recvjufM76eMKs",
- "021801": "recvjufM76lRHQ",
- "022101": "recvjufM76o6of",
- "032501": "recvjufM76k4dx",
- "032901": "recvjufM76frUP",
-}
-
-def get_token():
- with open(CRED_FILE) as f:
- cred = json.load(f)
- app_id = cred["apps"][0]["appId"]
- app_secret = cred["apps"][0]["appSecret"]
- result = subprocess.run([
- "curl", "-s", "-X", "POST",
- "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
- "-H", "Content-Type: application/json",
- "-d", json.dumps({"app_id": app_id, "app_secret": app_secret})
- ], capture_output=True, text=True)
- return json.loads(result.stdout)["tenant_access_token"]
-
-def update_record(token, record_id, fields_dict):
- """Update a record via curl"""
- # Write fields to temp file to avoid command-line escaping
- tmp_file = f"/tmp/p4_update_{record_id}.json"
- payload = json.dumps({"fields": fields_dict}, ensure_ascii=False)
- with open(tmp_file, 'w') as f:
- f.write(payload)
-
- url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE_ID}/records/{record_id}"
- result = subprocess.run([
- "curl", "-s", "-X", "PUT", url,
- "-H", f"Authorization: Bearer {token}",
- "-H", "Content-Type: application/json",
- "-d", f"@{tmp_file}"
- ], capture_output=True, text=True, timeout=30)
-
- os.remove(tmp_file)
- return json.loads(result.stdout)
-
-def verify_record(token, record_id):
- """Re-read a record to verify"""
- url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE_ID}/records/{record_id}"
- result = subprocess.run([
- "curl", "-s", "-X", "GET", url,
- "-H", f"Authorization: Bearer {token}"
- ], capture_output=True, text=True, timeout=30)
- return json.loads(result.stdout)
-
-def main():
- mode = sys.argv[1] if len(sys.argv) > 1 else "test"
-
- # Get token
- print("Getting token...")
- token = get_token()
- print(f"Token: {token[:20]}...")
-
- # Import the rewrite data
- sys.path.insert(0, os.path.join(BASE_DIR, "scripts"))
- import rewrite_p4_all as rw
-
- from rewrite_p4_all import make_q1_text
-
- results = []
-
- for qsid, record_id in RECORD_IDS.items():
- data = rw.RECORD_DATA.get(qsid)
- if not data:
- continue
-
- first_block = data["first_block"]
- second_block = data["second_block"]
- first_qs = data["first_qs_list"]
- second_qs = data["second_qs_list"]
-
- # Clean dialogues from jsonData
- for q in first_block["questionSet"]:
- q.pop("dialogue", None)
- if second_block and isinstance(second_block, dict) and "questionSet" in second_block:
- for q in second_block["questionSet"]:
- q.pop("dialogue", None)
-
- json_data = {"first": first_block, "second": second_block}
-
- q1_text = make_q1_text(first_qs)
- q2_text = make_q1_text(second_qs) if second_qs else ""
-
- fields = {
- "jsonData": json.dumps(json_data, ensure_ascii=False),
- "题目1": q1_text,
- "题目2": q2_text,
- }
-
- print(f"\n{'='*60}")
- print(f"QSID: {qsid} | Record: {record_id}")
- print(f"First: {len(first_qs)} Qs, Second: {len(second_qs)} Qs")
-
- if mode == "test":
- # Test one record only
- if qsid == "021301":
- result = update_record(token, record_id, fields)
- code = result.get("code", -1)
- msg = result.get("msg", "")
- if code == 0:
- print(f" ✅ Test write SUCCESS")
- # Verify
- v = verify_record(token, record_id)
- vcode = v.get("code", -1)
- if vcode == 0:
- rec = v.get("data", {}).get("record", {})
- jd = rec.get("fields", {}).get("jsonData", "")
- if jd:
- try:
- parsed = json.loads(jd)
- fq = parsed.get("first", {}).get("questionSet", [])
- sq = parsed.get("second", {}).get("questionSet", [])
- print(f" ✅ Verify: {len(fq)} first Qs, {len(sq)} second Qs")
- print(f" ✅ jsonData valid JSON")
- except Exception as e:
- print(f" ❌ jsonData parse error: {e}")
- else:
- print(f" ❌ jsonData field empty")
- else:
- print(f" ❌ Verify FAILED: {v.get('msg', '')}")
- else:
- print(f" ❌ Test write FAILED: {msg}")
- break
-
- elif mode == "write":
- result = update_record(token, record_id, fields)
- code = result.get("code", -1)
- msg = result.get("msg", "")
- if code == 0:
- print(f" ✅ Write SUCCESS")
- results.append((qsid, True, ""))
- else:
- print(f" ❌ Write FAILED: {msg}")
- results.append((qsid, False, msg))
-
- if mode == "write":
- success = sum(1 for r in results if r[1])
- fails = sum(1 for r in results if not r[1])
- print(f"\n{'='*60}")
- print(f"WRITE SUMMARY: {success} succeeded, {fails} failed")
- for qsid, ok, msg in results:
- status = "✅" if ok else "❌"
- print(f" {status} {qsid}" + (f" - {msg}" if msg else ""))
-
- # Verify all
- print(f"\n{'='*60}")
- print("VERIFYING ALL RECORDS...")
- for qsid, record_id in RECORD_IDS.items():
- v = verify_record(token, record_id)
- vcode = v.get("code", -1)
- if vcode == 0:
- rec = v.get("data", {}).get("record", {})
- jd = rec.get("fields", {}).get("jsonData", "")
- q1 = rec.get("fields", {}).get("题目1", "")
- q2 = rec.get("fields", {}).get("题目2", "")
- if jd:
- try:
- parsed = json.loads(jd)
- fq = parsed.get("first", {}).get("questionSet", [])
- sq = parsed.get("second", {}).get("questionSet", [])
- fqsid = parsed.get("first", {}).get("questionSetID", "")
- sqsid = parsed.get("second", {}).get("questionSetID", "") if isinstance(parsed.get("second", {}), dict) else ""
- print(f" ✅ {qsid}: {len(fq)} first Qs, {len(sq)} second Qs, QSID={fqsid}, 题目1={len(q1)}chars, 题目2={len(q2)}chars")
- except Exception as e:
- print(f" ❌ {qsid}: jsonData parse error: {e}")
- else:
- print(f" ❌ {qsid}: jsonData empty")
- else:
- print(f" ❌ {qsid}: verify failed: {v.get('msg', '')}")
-
-if __name__ == "__main__":
- main()
diff --git a/business_production/组件生产/backup/scripts/write_p4_v2.py b/business_production/组件生产/backup/scripts/write_p4_v2.py
deleted file mode 100644
index af2688a..0000000
--- a/business_production/组件生产/backup/scripts/write_p4_v2.py
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/usr/bin/env python3
-"""Batch write all P4 rewrites to bitable - proper version"""
-import json, subprocess, sys, os, time
-
-AT = "CMHSbUUjka3TrUsaxxEc297ongf"
-TID = "tblVmeDtBDKsAEfz"
-BASE = os.path.expanduser("~/.openclaw/workspace-xiaoyan")
-CRED_FILE = os.path.expanduser("~/.openclaw/credentials/xiaoyan/config.json")
-
-sys.path.insert(0, os.path.join(BASE, "scripts"))
-import rewrite_p4_all as rw
-from rewrite_p4_all import make_q1_text
-
-RECORD_IDS = {
- "021301": "recvjufKJO8d0O",
- "021401": "recvjufM763ijb",
- "021501": "recvjufM76lEsW",
- "021601": "recvjufM76hNv5",
- "021701": "recvjufM76eMKs",
- "021801": "recvjufM76lRHQ",
- "022101": "recvjufM76o6of",
- "032501": "recvjufM76k4dx",
- "032901": "recvjufM76frUP",
-}
-
-def get_token():
- with open(CRED_FILE) as f:
- cred = json.load(f)
- app_id = cred["apps"][0]["appId"]
- app_secret = cred["apps"][0]["appSecret"]
- result = subprocess.run([
- "curl", "-s", "-X", "POST",
- "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
- "-H", "Content-Type: application/json",
- "-d", json.dumps({"app_id": app_id, "app_secret": app_secret})
- ], capture_output=True, text=True)
- return json.loads(result.stdout)["tenant_access_token"]
-
-def write_and_verify(token, qsid, record_id, fields):
- """Write and immediately verify one record"""
- payload = json.dumps({"fields": fields}, ensure_ascii=False)
- tmp = f"/tmp/p4_write_{record_id}.json"
- with open(tmp, "w") as f:
- f.write(payload)
-
- result = subprocess.run([
- "curl", "-s", "-X", "PUT",
- f"https://open.feishu.cn/open-apis/bitable/v1/apps/{AT}/tables/{TID}/records/{record_id}",
- "-H", f"Authorization: Bearer {token}",
- "-H", "Content-Type: application/json",
- "-d", f"@{tmp}"
- ], capture_output=True, text=True, timeout=30)
- os.remove(tmp)
-
- resp = json.loads(result.stdout)
- code = resp.get("code", -1)
- if code != 0:
- return False, f"API error: {resp.get('msg','')}"
-
- # Read back to verify
- result = subprocess.run([
- "curl", "-s", "-X", "GET",
- f"https://open.feishu.cn/open-apis/bitable/v1/apps/{AT}/tables/{TID}/records/{record_id}",
- "-H", f"Authorization: Bearer {token}"
- ], capture_output=True, text=True, timeout=30)
-
- vdata = json.loads(result.stdout)
- vcode = vdata.get("code", -1)
- if vcode != 0:
- return False, f"Verify read error: {vdata.get('msg','')}"
-
- rjd = vdata.get("data", {}).get("record", {}).get("fields", {}).get("jsonData", "")
- if not rjd:
- return False, "jsonData empty after write"
-
- try:
- parsed = json.loads(rjd)
- fqs = parsed.get("first", {}).get("questionSet", [])
- first_ability = fqs[0].get("ability", []) if fqs else []
- first_expl = fqs[0].get("explanation", "") if fqs else ""
- return True, f"Q0 ability={first_ability}, expl_len={len(first_expl)}"
- except Exception as e:
- return False, f"jsonData parse error: {e}"
-
-def main():
- token = get_token()
- print(f"Token: {token[:15]}...")
-
- results = []
-
- for qsid, record_id in RECORD_IDS.items():
- data = rw.RECORD_DATA.get(qsid)
- if not data:
- continue
-
- fb = data["first_block"]
- sb = data["second_block"]
- fqs = data["first_qs_list"]
- sqs = data["second_qs_list"]
-
- # Clean dialogues
- for q in fb["questionSet"]:
- q.pop("dialogue", None)
- if sb and isinstance(sb, dict) and "questionSet" in sb:
- for q in sb["questionSet"]:
- q.pop("dialogue", None)
-
- json_data = {"first": fb, "second": sb}
- q1_text = make_q1_text(fqs)
- q2_text = make_q1_text(sqs) if sqs else ""
-
- fields = {
- "jsonData": json.dumps(json_data, ensure_ascii=False),
- "题目1": q1_text,
- "题目2": q2_text,
- }
-
- print(f"\nWriting {qsid} ({record_id})...")
- ok, msg = write_and_verify(token, qsid, record_id, fields)
-
- status = "✅" if ok else "❌"
- print(f" {status} {msg}")
- results.append((qsid, ok, msg))
-
- # Small delay to avoid rate limiting
- time.sleep(0.3)
-
- success = sum(1 for r in results if r[1])
- fails = sum(1 for r in results if not r[1])
- print(f"\n{'='*60}")
- print(f"FINAL: {success} succeeded, {fails} failed")
-
- if fails:
- print("\nFailed records:")
- for qsid, ok, msg in results:
- if not ok:
- print(f" ❌ {qsid}: {msg}")
-
-if __name__ == "__main__":
- main()
diff --git a/business_production/组件生产/skills/component-design/SKILL.md b/business_production/组件生产/skills/component-design/SKILL.md
index 1afa4fe..ae13a69 100644
--- a/business_production/组件生产/skills/component-design/SKILL.md
+++ b/business_production/组件生产/skills/component-design/SKILL.md
@@ -1,6 +1,6 @@
---
name: component-design
-version: 1.3.0
+version: 1.4.0
description: 教研互动组件设计规范(结构化文本格式,不涉及JSON)。触发方式:(1) `/组件生产 --feishu-url <链接>` (2) 飞书链接 + "组件"/"设计组件"/"组件回填"。不会误触发:仅含"互动"不触发;含"组件配置-json"不触发(属于 interactive-component-json 技能)。标准化组件生产流程:设计→生成(结构化文本)→校验→回填。
---
@@ -53,14 +53,29 @@ description: 教研互动组件设计规范(结构化文本格式,不涉及J
- 所有组件【正确反馈】统一填「无」
- 【错误反馈】必须是符合当前剧情场景的自然角色对话,禁止使用指令式、说教式表达(如禁止出现"Try to pronounce clearly, one more time."这类老师命令式内容),必须带角色名
7. **后置对话规则**:组件行之后紧接的、与组件内容相关的角色台词需要放入【后置对话】字段中
-8. **情境引入/后置对话去重规则**:禁止直接复制前一行或后一行的台词原文。若情境引入与前一行的英文台词完全相同,或后置对话与后一行的英文台词完全相同,直接写「无」
+8. **情境引入/后置对话去重规则(强制执行,审校必查)**:
+ - 🚫 禁止直接复制前一行或后一行的台词原文
+ - 🚫 禁止使用组件所在行之前任何行的台词作为情境引入
+ - 🚫 禁止使用组件所在行之后任何行的台词作为后置对话
+ - 若情境引入与前一行的英文台词完全相同,或后置对话与后一行的英文台词完全相同 → 直接写「无」
+ - **审校检查点**:生成后必须逐行对比组件行前后的 E 列/F 列原文,确认情境引入/后置对话未引用任何相邻行台词
9. **禁用内容规则**:
- 完全删除所有【图片资源】行
- 音频载体无特殊要求时填「无」
- - 组件禁止使用组件所在行之前的台词,【情境引入】和【后置对话】无内容时填「无」
+ - 组件禁止使用组件所在行之前或之后的台词,【情境引入】和【后置对话】无内容时填「无」
+ - **审校检查点**:情境引入内容必须来自组件自身场景设定,不得从剧本其他行摘取
10. **配图组件资源配置规则**:A列含"配图"时,【资源配置】仅保留`图片时机`,不写`音频载体`。图片时机根据有实际内容(非「无」)的 section 动态列出(如「互动内容」「情境引入 互动内容 互动反馈」),所有 section 均无内容则填「无」。图片时机和音频载体禁止同时存在。
### 二、组件类型专属规则
+
+> **详细规范索引:** 以下为各类型的快速参考。生产时请同时加载对应的专项 Skill:
+> - 对话朗读/表达/选读/选择/挖空/组句 → `dialogue-interaction-config`
+> - 信息拼词/组句/描写/补词/填词/填句 → `info-interaction-config`
+> - 物品互动 → `item-interaction-config`
+> - 图片单选/多选/有序/拖拽/互动 → `picture-interaction-config`
+> - 发音/语音/造句互动 → `pronunciation-interaction-config`
+> - 核心互动(14类)→ `core-interaction-config`
+
#### 1. 物品互动
- 仅保留两个字段:【任务标题】+【互动内容】
- 互动内容固定格式:`“中文动作提示” the 名词! 选项1:正确单词(正确)选项2:干扰单词`
@@ -251,6 +266,7 @@ description: 教研互动组件设计规范(结构化文本格式,不涉及J
---
## 版本更新记录
+- v1.4(2026-06-11):强化规则8/9情境引入和后置对话审校规则(禁止引用组件行前后台词,新增审校检查点:逐行对比E/F列)
- v1.3(2026-06-08):图片类互动删除【资源配置】字段、新增辅助信息规则;对话朗读删除【互动反馈】字段;新增配图组件资源配置规则;新增情境引入/后置对话去重规则(禁止复制前后行台词原文)
- v1.2(2026-04-09):修正图片类互动高亮规则(仅知识点单词加$,非知识点不加),新增对话选择、对话选读、对话表达三类组件的配置规则及标准模板
- v1.1(2026-04-09):新增错误反馈、任务标题、对话组句、选项格式等规则,修正不符合生产要求的旧规则
diff --git a/business_production/组件生产/skills/core-interaction-config/SKILL.md b/business_production/组件生产/skills/core-interaction-config/SKILL.md
new file mode 100644
index 0000000..4fc817d
--- /dev/null
+++ b/business_production/组件生产/skills/core-interaction-config/SKILL.md
@@ -0,0 +1,1087 @@
+---
+name: core-interaction-config
+version: 2.0.0
+description: 核心互动组件配置标准化规范,基于真实 bitable 数据,覆盖14类核心互动的标准化生成
+metadata:
+ requires:
+ permissions: ["sheets:spreadsheet"]
+ identity: bot
+---
+
+## 文本输出规范(强制执行)
+
+所有输出的文本内容(台词、题目、选项、解析等)必须遵守以下规则:
+
+1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。
+2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。
+3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。
+
+## ⚠️ 强制规则:真实数据优先
+
+**编写任何模板、示例之前,必须先读取至少一条对应类型的真实 bitable 数据。** 不凭记忆、不凭类比、不凭"应该差不多"。本文件中所有模板和示例均基于真实数据提取。
+
+---
+
+# 核心互动组件配置规范
+
+## 适用场景
+当【类型】列内容为【核心互动-听力】【核心互动-口语】【核心互动-阅读】【核心互动-写作】时,使用本规范生成组件配置。
+
+## 核心互动分类(14类)
+
+### 阅读类(2类)
+| 组件名称 | cType | Bitable |
+|----------|-------|---------|
+| 合作阅读 | `core_reading_order` | `HIuLbJ6E8aNw2lsdT1YcvNOmnog` |
+| 看图选词 | `core_reading_imageDrag` | `Qf0Ob6TyEaShufsORGBc8WTinFf` |
+
+### 听力类(3类)
+| 组件名称 | cType | Bitable |
+|----------|-------|---------|
+| 合作听力 | `core_listening_order` | `B8Z1b2TnYaKRa1sWSljcV4Q9nYf` |
+| 听力拖拽 | `core_listening_drag` | `Uey8bhdLBa66TIsGrFBcIQKRnsg` |
+| 听力选择 | `core_listening_choose` | `C7e9bzA1GaZ61FsTz87cEM8Ynoe` |
+
+### 口语类(5类)
+| 组件名称 | cType | Bitable |
+|----------|-------|---------|
+| 口语快答 | `core_speaking_reply` | `D0Tpbs6D6aIRXdsKDLec0V0on3b` |
+| 口语妙问 | `core_speaking_inquiry` | `Ct4ebNgxUatyUssuVHycfhbgnXf` |
+| 口语独白 | `core_speaking_monologue` | `JtsAbFoSbaWWvssLsxXcAgdEnkh` |
+| 看图说话 | `core_speaking_image` | `DOVHbQamCaZPTCsuzJrclG1an6b` |
+| 口语探讨 | `core_speaking_discuss` | (S0 无数据,待补充) |
+
+### 写作类(5类)
+| 组件名称 | cType | Bitable |
+|----------|-------|---------|
+| 写作互动 | `core_writing_questionMakeSentence` | `HOhJb8xtMa02YjsHXMNc7MEpnfe` |
+| 看图组句 | `core_writing_imgMakeSentence` | `LNEcbo6meahQCosYN9Jc137rnde` |
+| 看图撰写 | `core_writing_imgWrite` | `Be4rbTgoiaDMOvstB4Ucn8sjndh` |
+| 邮件组句 | `core_writing_questionMakeSentence` | `F0e4bd2Z5aFDzpsIHndcxGhgnKd` |
+| 邮件撰写 | `core_writing_questionWrite` | `JcuybbTRParccasXKrUc7mD1neh` |
+
+---
+
+# 各类型配置格式
+
+## 📖 阅读类
+
+### 合作阅读
+
+**数据来源:** bitable `HIuLbJ6E8aNw2lsdT1YcvNOmnog` / S0 / ID=0000001
+
+格式由两部分组成:**教研配置-任务** + **教研配置-材料**
+
+#### 教研配置-任务
+
+```
+# 任务名称
+{任务名称}
+
+# 任务背景
+{任务背景描述}
+
+# 知识
+{单词} {词性} {释义}
+{句型结构}
+```
+
+#### 教研配置-材料
+
+```
+
+# 材料 1
+## 材料类型
+默认
+## 材料内容
+1. 标题
+{材料标题}
+2. 正文
+```
+{正文内容}
+```
+
+# 材料 2
+## 材料类型
+默认
+## 材料内容
+1. 标题
+{材料标题}
+2. 正文
+```
+{正文内容}
+```
+
+
+[题目1]
+知识点: {知识点单词}
+{NPC名}:{问题内容}
+A.{选项文本}
+ 错误 {NPC名}:{错误反馈}
+B.{选项文本}
+ 正确 {NPC名}:{正确反馈}
+C.{选项文本}
+ 错误 {NPC名}:{错误反馈}
+学习意义:{学习意义描述}
+
+[题目2]
+知识点: {知识点单词}
+{NPC名}:{问题内容}
+...
+
+
+[材料1]
+[题目1]
+[材料2]
+[题目2]
+...
+
+
+段落 1
+{学习段落文本}
+段落 2
+{学习段落文本}
+```
+
+#### 完整示例(基于 ID=0000001 真实数据)
+
+```
+# 任务名称
+准备你的第一次太空旅行
+
+# 任务背景
+你即将前往瓦拉星球进行你的第一次太空旅行。为了确保旅途顺利,这里有一份详细的清单,列出了你需要准备的物品。请仔细检查并准备好这些物品,以便你能够安全、舒适地享受这次奇妙的旅程。
+
+# 知识
+passport n. 护照
+suitcase n. 手提箱
+clothes n. 衣服
+pack v. 打包
+
+
+# 材料 1
+## 材料类型
+默认
+## 材料内容
+1. 标题
+Packing for Your First Space Trip
+2. 正文
+```
+Are you ready for your first space trip to Planet Vala? Here is a simple guide to help you pack everything you need for a safe and fun journey!
+
+副标题: What to Pack
+
+1. Passport: Your passport is your ticket to Planet Vala. Do not forget it! Without it, you will not be able to board the spaceship.
+2. Suitcase: Bring one small suitcase. It should be easy to carry and strong enough for space travel.
+3. Clothes: Pack one extra set of clothes. Choose warm and comfortable ones because Vala's weather changes quickly, with hot days and freezing nights!
+
+副标题: Extra Items
+
+You can also pack other things like books, cameras, or a weapon to keep you safe. But remember: ONLY use your weapon when you need help!
+```
+
+
+[题目1]
+知识点: passport
+Brainy:What should you bring if you want to board the spaceship to Planet Vala?
+A.my camera
+ 错误 Brainy:Not quite! Remember, you need something more essential for your journey.
+B.my passport
+ 正确 Brainy:Perfect! Your passport is your ticket to Planet Vala. Great job!
+C.my suitcase
+ 错误 Brainy:Close, but not quite! Think about what you need to enter the planet.
+学习意义:提取文章中的关键信息
+
+[题目2]
+知识点: suitcase
+Brainy:What kind of suitcase should you bring for your space trip?
+A.a large suitcase
+ 错误 Brainy:Not quite! Remember, space travel requires something more manageable.
+B.a small suitcase
+ 正确 Brainy:Exactly! A small suitcase is easy to carry and strong enough for space travel. Well done!
+C.a medium suitcase
+ 错误 Brainy:Almost there, but not quite! Think about the size and strength needed for space travel.
+学习意义:理解文章中的细节信息
+
+[题目3]
+知识点: clothes
+Brainy:What type of clothes should you pack for Planet Vala?
+A.cool and light clothes
+ 错误 Brainy:Not quite! Remember, Vala's weather can get very cold at night.
+B.warm and comfortable clothes
+ 正确 Brainy:Excellent choice! Warm and comfortable clothes are perfect for Vala's changing weather. Great thinking!
+C.formal clothes
+ 错误 Brainy:Close, but not quite! Think about the weather conditions on Vala.
+学习意义:提取文章中的关键信息
+
+
+[材料1]
+[题目1]
+[题目2]
+[题目3]
+
+
+段落 1
+Are you ready for your first space trip to Planet Vala? Here is a simple guide to help you pack everything you need for a safe and fun journey!
+
+段落 2
+1. Passport: Your passport is your ticket to Planet Vala. Do not forget it!
+```
+
+#### 审校检查点
+
+- [ ] 任务名称、任务背景、知识三个区块完整
+- [ ] 阅读材料每段有标题和正文
+- [ ] 每道题有知识点、NPC提问、3个选项(含正确/错误反馈)、学习意义
+- [ ] 流程编排顺序与材料/题目编号一致
+- [ ] 学习过程段落与阅读材料对应
+- [ ] 选项答案随机分布(禁止全部集中在同一序号)
+
+---
+
+### 看图选词
+
+**数据来源:** bitable `Qf0Ob6TyEaShufsORGBc8WTinFf` / L1 / ID=1201001
+
+格式由两部分组成:**教研-导览配置** + **教研-互动配置**
+
+```
+【任务标题】
+{任务标题}
+
+【任务背景】
+{任务背景描述}
+
+【通关知识】
+{单词} {词性} {释义}
+...
+
+【互动内容】
+{图片编号和拖拽匹配规则}
+```
+
+> 注:看图选词为 L1 级别阅读类,与 L2 合作阅读结构不同。完整格式参考 bitable 真实数据。
+
+---
+
+## 🎧 听力类
+
+### 合作听力
+
+**数据来源:** bitable `B8Z1b2TnYaKRa1sWSljcV4Q9nYf` / S1 / ID=0103001
+
+格式由两部分组成:**教研配置-任务** + **教研配置-材料**
+
+#### 教研配置-任务
+
+```
+# 任务名称
+{任务名称}
+
+# 任务背景
+{任务背景描述}
+
+# 知识
+{单词} {词性} {释义}
+{句型结构}
+```
+
+#### 教研配置-材料
+
+```
+
+
+# 材料 1
+## 材料类型
+音频文件
+## 材料内容
+1. 标题
+{材料标题}
+2. 文本
+{角色名}: {对话内容}
+3. 音频文件名
+{音频文件名}
+
+# 材料 2
+## 材料类型
+音频文件
+## 材料内容
+1. 标题
+{材料标题}
+2. 文本
+{角色名}: {对话内容}
+3. 音频文件名
+{音频文件名}
+
+
+[材料1]-[题目1]
+知识点: {知识点单词}
+{NPC名}:{问题内容}
+A.{选项文本}
+ 错误 {NPC名}:{错误反馈}
+B.{选项文本}
+ 正确 {NPC名}:{正确反馈}
+C.{选项文本}
+ 错误 {NPC名}:{错误反馈}
+学习意义:{学习意义描述}
+
+[材料2]-[题目3]
+...
+
+
+{NPC名}: {开场白}
+[材料1]
+{NPC名}: {过渡语}
+[题目1]
+[题目2]
+{NPC名}: {过渡语}
+[材料2]
+{NPC名}: {过渡语}
+[题目3]
+[题目4]
+
+
+句子 1
+{学习句子}
+句子 2
+{学习句子}
+```
+
+#### 完整示例(基于 ID=0103001 真实数据)
+
+```
+# 任务名称
+紧急通知:避开风暴区域的危险
+
+# 任务背景
+你们在找到失事飞机后,发现了昏迷的飞行员。在一番救治后,飞行员醒来。他提醒你们,自己是在空中遇到了风暴,有很大的危险。于是你们准备听一下黑匣子内容,了解情况。
+
+# 知识
+storm n. 风暴
+broken adj. 损坏的
+fall v. 坠落
+They must stay away from... 他们必须远离...!
+
+
+
+# 材料 1
+## 材料类型
+音频文件
+## 材料内容
+1. 标题
+Black Box Recording 1
+2. 文本
+Edward: There is a danger! We have entered a storm. The storm is very strong. The ship is broken.
+3. 音频文件名
+0103567_音频材料1.mp3
+
+# 材料 2
+## 材料类型
+音频文件
+## 材料内容
+1. 标题
+Black Box Recording 2
+2. 文本
+Pilot: We'll fall into the forest and maybe I'll die. Anyone who finds this black box must tell other animal arks: They must stay away from the storm!
+3. 音频文件名
+0103001_音频材料2.mp3
+
+
+[材料1]-[题目1]
+知识点: storm
+Otis:Let's find out what happened. What did Edward say about the storm?
+A.The storm is very weak.
+ 错误 Otis:Not quite! The storm wasn't weak at all. Try again!
+B.The storm is very strong.
+ 正确 Otis:Great job! You got it right!
+C.The storm is not dangerous.
+ 错误 Otis:Oops! The storm was indeed dangerous. Keep trying!
+学习意义:提取文章中的关键信息
+
+[材料1]-[题目2]
+知识点: broken
+Otis:What happened to the ship because of the storm?
+A.The ship is repaired.
+ 错误 Otis:Not quite! No one repaired it.
+B.The ship is broken.
+ 正确 Otis:Excellent! You're doing great!
+C.The ship is flying.
+ 错误 Otis:Come on! The ship isn't flying.
+学习意义:理解文章中的细节信息
+
+[材料2]-[题目3]
+知识点: fall
+Otis:What did the pilot say after the ship is broken?
+A.They will fly higher.
+ 错误 Otis:Not quite! The pilot didn't say that. Try again!
+B.They will fall into the forest.
+ 正确 Otis:Great job! You got it right!
+C.They will stay in the air.
+ 错误 Otis:Wait! No! It is dangerous to stay in the air!
+学习意义:提取文章中的关键信息
+
+[材料2]-[题目4]
+知识点: They must stay away from the storm!
+Otis:What did the pilot want others to tell all Animals Arks?
+A.They must enter the storm.
+ 错误 Otis:Not quite! The pilot wanted them to stay away. Try again!
+B.They must stay away from the storm.
+ 正确 Otis:Excellent! You're doing great!
+C.They don't need to care about the storm.
+ 错误 Otis:Oops! The pilot wanted them to stay away. Keep trying!
+学习意义:理解文章中的主旨信息
+
+
+Otis: Alright, let's listen to the black box recordings and figure out what happened.
+[材料1]
+Otis: This is the first recording.
+[题目1]
+[题目2]
+Otis: Let's move on to the next recording.
+[材料2]
+Otis: This is the second recording.
+[题目3]
+[题目4]
+
+
+句子 1
+There is a danger! We have entered a storm.
+句子 2
+The storm is very strong.
+句子 3
+The ship is broken.
+句子 4
+We'll fall into the forest and maybe I'll die.
+句子 5
+Anyone who finds this black box must tell other Animal Arks: They must stay away from the storm!
+```
+
+#### 审校检查点
+
+- [ ] 任务名称、任务背景、知识三个区块完整
+- [ ] 听力材料类型为"音频文件",含标题、文本、音频文件名
+- [ ] 题目标注所属材料 [材料N]-[题目N]
+- [ ] 每道题有知识点、NPC提问、3个选项(含正确/错误反馈)、学习意义
+- [ ] 流程编排含 NPC 开场白和过渡语
+- [ ] 选项答案随机分布
+
+---
+
+### 听力拖拽
+
+**数据来源:** bitable `Uey8bhdLBa66TIsGrFBcIQKRnsg` / S3 / ID=0000001
+
+格式由两部分组成:**教研配置-导览配置** + **教研配置-互动配置**
+
+```
+【任务标题】
+{任务标题}
+
+【任务背景】
+{任务背景描述}
+
+【通关知识】
+{单词} {词性} {释义}
+...
+
+【开场语】
+{角色名}: {开场台词}
+
+【听力文本】
+# 文本 1
+{角色名}: {对话内容}
+{角色名}:{对话内容}(重点句)
+
+# 文本 2
+{角色名}: {对话内容}
+...
+
+【题目信息】
+#多空选择
+选项图片编号:{编号列表}
+答案图片编号:{编号列表}
+
+【学习过程】
+句子 1
+{学习句子}【{关键词}】
+句子 2
+{学习句子}【{关键词}】
+```
+
+#### 审校检查点
+
+- [ ] 任务标题、任务背景、通关知识完整
+- [ ] 开场语有角色台词
+- [ ] 听力文本标注重点句
+- [ ] 题目信息含选项图片编号和答案图片编号
+- [ ] 学习过程句子标注关键词
+
+---
+
+### 听力选择
+
+**数据来源:** bitable `C7e9bzA1GaZ61FsTz87cEM8Ynoe` / S3 / ID=0000001
+
+格式由两部分组成:**教研配置-导览配置** + **教研配置-互动配置**
+
+```
+【任务标题】
+{任务标题}
+
+【任务背景】
+{任务背景描述}
+
+【通关知识】
+{单词} {词性} {释义}
+...
+
+【题目组1】
+#开场语
+{角色名}: {开场台词}
+
+#听力文本
+{角色名}: {对话内容}
+{角色名}:{对话内容}(重点句)
+
+#题目1
+##题目类型:文本
+##题目内容:
+{NPC名}: {问题内容}
+A. {选项文本}
+ 错误 {NPC名}:{错误反馈}
+B. {选项文本}
+ 正确 {NPC名}:{正确反馈}
+C. {选项文本}
+ 错误 {NPC名}:{错误反馈}
+
+#题目2
+##题目类型:图片
+##题目内容:
+{NPC名}: {问题内容}
+A. {图片编号}
+ 错误 {NPC名}:{错误反馈}
+B. {图片编号}
+ 正确 {NPC名}:{正确反馈}
+C. {图片编号}
+ 错误 {NPC名}:{错误反馈}
+
+#题目3
+##题目类型:文本
+##题目内容:
+...
+
+#结束语
+{角色名}: {结束台词}
+
+【题目组2】
+#开场语
+...
+```
+
+#### 审校检查点
+
+- [ ] 任务标题、任务背景、通关知识完整
+- [ ] 每个题目组有开场语、听力文本、题目、结束语
+- [ ] 题目类型标注(文本/图片),文本型选项写文字,图片型选项写图片编号
+- [ ] 每道题有 NPC 提问、3个选项(含正确/错误反馈)
+- [ ] 答案随机化:多小题时正确选项位置随机分布,禁止全部集中在同一序号
+- [ ] 听力文本标注重点句
+
+---
+
+## 🗣 口语类
+
+### 口语快答
+
+**数据来源:** bitable `D0Tpbs6D6aIRXdsKDLec0V0on3b` / L1-Demo / ID=0500001
+
+格式由两部分组成:**教研-用户视角任务信息** + **教研-任务规则与NPC设定**
+
+```
+【任务标题】
+{任务标题}
+
+【任务背景】
+{任务背景描述}
+
+【任务描述】
+{用户需要完成的任务描述}
+
+【通关知识】
+{句型结构}
+
+【对话角色】
+{NPC角色名}
+
+【任务背景】(NPC视角)
+{从NPC角度描述的任务背景}
+
+【任务设定】
+{NPC需要达成的对话目标}
+
+【回合设定】
+检测回合:{数字}
+最大回合:{数字}
+
+【通过规则】
+过程:{过程通过条件}
+结果:{结果通过条件}
+
+【示例对话】
+{NPC名}: {对话内容}
+User: {回答}
+{NPC名}: {对话内容}
+User: {回答}
+...
+```
+
+#### 完整示例(基于 ID=0500001 真实数据)
+
+```
+【任务标题】
+和 Ben 聊一聊
+
+【任务背景】
+Ben 发现飞船上有个奇怪的地方,他特别好奇那是什么。快来和 Ben 聊聊,看看它到底是什么吧。
+
+【任务描述】
+你要告诉 Ben 那里脏了,告诉他你们需要用水来清理污渍。
+
+【通关知识】
+It's... 它是......
+... need to... ......需要做......
+
+【对话角色】
+Ben
+
+【任务背景】(NPC视角)
+你是 Ben,用户的好朋友。这天,用户发现了一艘破飞船,用户邀请你去看,并且和用户一起清洁飞船。你发现飞船上有一处很奇怪,你想问问用户这是什么。
+
+【任务设定】
+你好奇飞船上的那块是脏了还是破了
+你要问问用户你们需要对那块地方做什么
+你要问问用户怎么才能清洁那块地方。
+
+【回合设定】
+检测回合:3
+最大回合:5
+
+【通过规则】
+过程:你知道了那块地方是脏了,你知道现在你们要清理它,你还知道你们需要用水来清理。
+结果:你知道了那块地方是脏了,你知道现在你们要清理它,你还知道你们需要用水来清理。
+
+【示例对话】
+Ben: Is this broken or just dirty?
+User: It's dirty.
+Ben: What do we need to do with it?
+User: We need to clean it.
+Ben: What do we need to clean?
+User: We need to use more water here.
+Ben: I got it.
+```
+
+#### 审校检查点
+
+- [ ] 任务标题、任务背景、任务描述、通关知识完整
+- [ ] NPC 视角的任务背景和任务设定与用户视角一致
+- [ ] 回合设定(检测回合 ≤ 最大回合)
+- [ ] 通过规则含过程和结果
+- [ ] 示例对话覆盖所有任务设定要点
+
+---
+
+### 口语妙问
+
+**数据来源:** bitable `Ct4ebNgxUatyUssuVHycfhbgnXf` / S0 / ID=0000002
+
+格式由两部分组成:**教研-用户视角任务信息** + **教研-任务规则与NPC设定**
+
+```
+# 任务名称
+{任务名称}
+
+# 任务背景
+{任务背景描述}
+
+# 任务描述(以 快答 为例)
+{任务描述}
+
+# 知识
+{知识点句型}
+
+# 对话类型
+妙问
+
+# 对话角色
+{NPC角色名}
+
+# 任务背景(NPC视角)
+{NPC视角的任务背景}
+
+# 任务设定(NPC视角)
+- {NPC需要达成的对话目标}
+
+# 通过规则
+过程:{过程通过条件}
+结果:{结果通过条件}
+
+# 回合设定
+检测回合:{数字}
+最大回合:{数字}
+
+# 示例对话(英文)
+{NPC名}:{对话内容}
+User:{回答}
+...
+```
+
+#### 审校检查点
+
+- [ ] 任务名称、任务背景、任务描述、知识完整
+- [ ] 对话类型标注为"妙问"
+- [ ] NPC 视角任务设定与用户视角一致
+- [ ] 通过规则含过程和结果
+- [ ] 示例对话为英文
+
+---
+
+### 口语独白
+
+**数据来源:** bitable `JtsAbFoSbaWWvssLsxXcAgdEnkh` / L1 / ID=0000001
+
+格式由两部分组成:**教研-任务信息** + **教研-独白配置**
+
+```
+【任务名称】
+{任务名称}
+
+【任务背景】
+{任务背景描述}
+
+【任务描述】
+{用户需要表达的内容要点}
+
+【知识】
+{句型结构}
+
+【切分句数设定】
+句数下限:{数字}
+句数上限:{数字}
+
+【示例独白】
+{示例独白文本}
+
+【通过规则】
+用户说出:
+1. {通过条件1}
+2. {通过条件2}
+...
+```
+
+#### 完整示例(基于 ID=0000001 真实数据)
+
+```
+【任务名称】
+为弄坏东西向 Mia 道歉
+
+【任务背景】
+越急越乱,匆忙之中,你踩碎了 Mia 的眼镜!你知道这副眼镜对于 Mia 来说很重要。虽然不是故意的,但为了你们的友谊,仍然需要郑重表达你的歉意。正巧遇到了 Mia,赶紧当面向她道歉吧!
+
+【任务描述】
+你正在当面向 Mia 道歉。可以从这几个方面说:
+1. 为弄坏东西向 Mia 道歉
+2. 弄坏的是什么,什么时候弄坏的
+3. 怎么弄坏的
+4. 弄坏之后你做了什么
+
+【知识】
+I'm sorry for... 我为……感到抱歉。
+I shouldn't... 我不应该……
+I will... in the future. 未来我会……(怎么做)
+
+【切分句数设定】
+句数下限:2
+句数上限:11
+
+【示例独白】
+I'm sorry, Mia.
+I broke your glasses yesterday.
+It was dropped on the ground, and I didn't see it before I stepped on it.
+I tried to fix it but failed. I hope you can forgive me.
+
+【通过规则】
+用户说出:
+1. 向 Mia 道歉
+2. 昨天弄坏了 Mia 的眼镜
+3. 弄坏的过程
+4. 弄坏之后做了什么
+```
+
+#### 审校检查点
+
+- [ ] 任务名称、任务背景、任务描述、知识完整
+- [ ] 任务描述列出表达要点
+- [ ] 句数下限 ≤ 句数上限
+- [ ] 示例独白覆盖所有通过规则要点
+- [ ] 通过规则与任务描述一致
+
+---
+
+### 看图说话
+
+**数据来源:** bitable `DOVHbQamCaZPTCsuzJrclG1an6b` / S3 / ID=0325001
+
+格式由两部分组成:**教研-导览配置** + **教研-对话配置**
+
+```
+【任务标题】
+{任务标题}
+
+【任务背景】
+{任务背景描述}
+
+【任务描述】
+{任务描述}
+
+【知识】
+{句型结构}
+
+【对话角色】
+{NPC角色名}
+
+【角色背景】
+{NPC角色背景描述}
+
+【互动问题】
+#图片编号:{编号}
+Q: {问题}
+A: {答案}
+
+#图片编号:{编号}
+Q:{问题}
+A:{答案}
+
+【通过规则】
+用户说出:
+1. {通过条件1}
+2. {通过条件2}
+...
+
+【示例对话】
+NPC: {问题}
+User: {回答}
+NPC: {问题}
+User: {回答}
+...
+```
+
+#### 审校检查点
+
+- [ ] 任务标题、任务背景、任务描述、知识完整
+- [ ] 互动问题标注图片编号
+- [ ] 通过规则覆盖所有互动问题
+- [ ] 示例对话与互动问题一致
+
+---
+
+## ✏️ 写作类
+
+**数据来源:** bitable `HOhJb8xtMa02YjsHXMNc7MEpnfe` / Level 2 / ID=0221101
+
+写作类 5 种题型(写作互动/看图组句/看图撰写/邮件组句/邮件撰写)共享相同的格式框架,差异体现在题干类型和写作材料上。
+
+格式由两部分组成:**教研配置-任务信息** + **教研配置-全文信息**
+
+### 教研配置-任务信息
+
+```
+【任务名称】
+{任务名称}
+
+【任务背景】
+{任务背景描述}
+
+【任务描述】
+{任务描述}
+
+【题干类型】
+{问题 / 图片}
+
+【题干描述】
+{题干具体内容}
+
+【知识】
+{单词} {词性} {释义}
+```
+
+### 教研配置-全文信息
+
+```
+【写作类型】
+{组句 / 撰写}
+
+【写作材料】
+# 句子 1
+## 句子类型
+{全句预置 / 挖空录入 / 全句录入}
+## 句子内容
+句子主干:
+{句子主干}
+选项:
+{选项列表}
+答案:
+{答案}
+
+# 句子 2
+## 句子类型
+{挖空录入 / 全句录入}
+## 句子内容
+句子主干:
+{句子主干}
+选项:
+{选项列表}
+[干扰]:{干扰项}
+答案:
+{答案}
+
+【通过规则】
+用户写出:
+1. {通过条件1}
+2. {通过条件2}
+...
+```
+
+### 句子类型说明
+
+| 类型 | 说明 | 示例 |
+|------|------|------|
+| 全句预置 | 句子已给出,用户无需操作 | Dear whoever receives this message, |
+| 挖空录入 | 句子有挖空,用户从选项中选择填入 | We ___ in a cave... 选项: are, hiding |
+| 全句录入 | 用户从选项词中拼出完整句子 | 选项: one of my friends, terrible headache, has a... |
+
+### 完整示例(写作互动,基于 ID=0221101 真实数据)
+
+```
+【任务名称】
+给救援队发求救消息
+
+【任务背景】
+你和小伙伴们被困在暴风雪里,万幸的是,你们找到了一处雪洞暂避风雪。但小伙伴们状况危急,你必须尽快向救援队发送信息求救。
+
+【任务描述】
+请根据提示问题,用英文完成这封求救邮件。
+
+【题干类型】
+问题
+
+【题干描述】
+Where are you hiding to escape the snowstorm?
+What's wrong with your clothes?
+What do you want them to bring?
+
+【知识】
+terrible adj. 糟糕的;可怕的
+dress v. 穿衣;给……穿衣
+
+【写作类型】
+组句
+
+【写作材料】
+# 句子 1
+## 句子类型
+全句预置
+## 句子内容
+句子主干:
+Dear whoever receives this message,
+选项:
+/
+答案:
+/
+
+# 句子 2
+## 句子类型
+挖空录入
+## 句子内容
+句子主干:
+We ___ in a cave to escape the snowstorm.
+选项:
+are
+hiding
+[干扰]:is
+答案:
+are hiding
+
+# 句子 3
+## 句子类型
+挖空录入
+## 句子内容
+句子主干:
+We have ___ , but our clothes are not keeping us warm.
+选项:
+ourselves
+dressed
+[干扰]:dress
+答案:
+dressed ourselves
+
+# 句子 4
+## 句子类型
+全句录入
+## 句子内容
+句子主干:
+/
+选项
+one of my friends
+terrible headache
+has a
+so please
+some
+medicine
+bring
+[干扰]:have a
+答案:
+One of my friends has a terrible headache, so please bring some medicine.
+
+【通过规则】
+用户写出:
+1. 他们正躲在山洞中
+2. 他们的衣物无法保暖
+3. 他的一个朋友头痛严重,需要带药
+```
+
+### 写作类各题型差异
+
+| 题型 | 题干类型 | 写作类型 | 素材特点 |
+|------|---------|---------|---------|
+| 写作互动 | 问题 | 组句 | 文字问题引导 |
+| 看图组句 | 图片 | 组句 | 图片引导 |
+| 看图撰写 | 图片 | 撰写 | 图片引导,自由撰写 |
+| 邮件组句 | 问题 | 组句 | 邮件格式文本 |
+| 邮件撰写 | 问题 | 撰写 | 邮件格式文本,自由撰写 |
+
+#### 审校检查点
+
+- [ ] 任务名称、任务背景、任务描述、题干类型、题干描述、知识完整
+- [ ] 写作类型(组句/撰写)与题型匹配
+- [ ] 每句标注句子类型(全句预置/挖空录入/全句录入)
+- [ ] 挖空录入有干扰项标注
+- [ ] 全句录入有选项词列表和答案
+- [ ] 通过规则覆盖所有句子的核心内容
+
+---
+
+# 审校清单(通用)
+
+生成任何核心互动组件后,执行以下检查:
+
+## 结构完整性
+- [ ] 任务标题/名称不为空
+- [ ] 任务背景/描述不为空
+- [ ] 知识点(单词+句型)不为空
+- [ ] 互动内容/材料不为空
+- [ ] 题目数量 ≥ 1
+
+## 内容质量
+- [ ] 所有英文使用半角标点
+- [ ] 所有中文使用全角标点
+- [ ] 英式拼写优先
diff --git a/business_production/组件生产/skills/dialogue-interaction-config/SKILL.md b/business_production/组件生产/skills/dialogue-interaction-config/SKILL.md
index 4b5b4bf..1f75725 100644
--- a/business_production/组件生产/skills/dialogue-interaction-config/SKILL.md
+++ b/business_production/组件生产/skills/dialogue-interaction-config/SKILL.md
@@ -94,20 +94,43 @@ Piper: You're lying! It must be your mistake!
### 3. 对话选读
#### 核心结构
【任务标题】→【资源配置】→【情境引入】→【互动内容】→【后置对话】
+
+#### 与对话选择的关键区分
+| 对比项 | 对话选择 | 对话选读 |
+|--------|---------|----------|
+| 互动目的 | 有对错判断 | 开放表达,任意选均可 |
+| 互动要求 | 选择正确的回复 | 选择一个你想表达的观点 |
+| 正确选项 | 标注 `(正确)` | **无正确选项** |
+| 选项反馈 | 正确选项反馈可缺省 | **每个选项均有反馈** |
+
#### 配置要点
- 【互动内容】:
- 1. 要求说明:如`要求:选择一个你想表达的观点`
+ 1. 第一行固定为:`要求:选择一个你想表达的观点`
2. 选项按"选项1/2/3"排列,每个选项后对应对话式反馈
- 3. 无正确/错误区分,任意选择均可
- 4. 需要音频播放选项时标注`(音频)`
-#### 示例
+ 3. 无正确/错误区分,任意选择均可,**每个选项的反馈为必填项**
+ 4. 需要音频播放选项时标注`(音频)`,默认不含音频标记
+ 5. ⚠️ 反馈角色不可是 User 自己,必须是当前场景中的其他角色
+- 【互动反馈】:本类型不单独设置互动反馈字段,反馈内容已整合在互动内容的各选项中
+- 【资源配置】:
+ - 类型为「对话选读」时,填写:`无`
+ - 类型为「对话选读-配图」时,填写图片时机 + 音频载体(格式见下方示例)
+ - 资源命名规范:图片文件名 `{组件ID}.png`,音频文件名 `{组件ID}.mp3`
+
+#### 示例(对话选读-配图)
```
【任务标题】加入搏斗俱乐部
-【资源配置】无
+【资源配置】
+图片时机:
+互动内容
+互动反馈
+
+音频载体:Pioneer Band
+
【情境引入】
Johnny: What do you think of the club?
+
【互动内容】
-要求:选择一个你想表达的观点(默认这句话)
+要求:选择一个你想表达的观点
选项:(音频)
选项1:That's great! I'm going to ask Otis and Skely to go together!
- 反馈 Johnny : I don't think it's OK to have so many people in.
@@ -115,6 +138,25 @@ Johnny: What do you think of the club?
- 反馈 Johnny : You'd better not do this by yourself.
选项3:It's no fun. I'd better not participate.
- 反馈 Johnny : Ok, it's a good decision.
+
+【后置对话】无
+```
+
+#### 示例(对话选读-无配图)
+```
+【任务标题】说说现在的屋子吧
+【资源配置】无
+【情境引入】
+User : Yes, today is very messy.
+【互动内容】
+要求:选择一个你想表达的观点
+选项:
+选项1:Today is a good day. No one is at home.
+- 反馈 User : But grandparents are coming to visit!
+选项2:Today is very messy. We need to clean up.
+- 反馈 User : Yes, let's clean up together!
+选项3:Today is not so bad. We can have fun.
+- 反馈 User : But look at the sofa and the floor!
【后置对话】无
```
@@ -179,7 +221,7 @@ This is my picture. It's ___, green and orange.(音频)
#### 配置要点
- 【互动内容】:
1. 题目:中文描述组句要求
- 2. 选项:乱序单词/短语,不添加句末标点、不首字母大写,数量3-5个
+ 2. 选项:乱序单词/短语,不添加句末标点、不首字母大写,数量 3-4 个
3. 答案:完整正确句子
4. 辅助信息:完整句子,无则填"无"
5. 需要音频时标注`(音频)`
diff --git a/business_production/组件生产/skills/dialogue-selective-reading-config/SKILL.md b/business_production/组件生产/skills/dialogue-selective-reading-config/SKILL.md
deleted file mode 100644
index 7b4eafe..0000000
--- a/business_production/组件生产/skills/dialogue-selective-reading-config/SKILL.md
+++ /dev/null
@@ -1,121 +0,0 @@
----
-name: dialogue-selective-reading-config
-version: 1.0.0
-description: 对话选读类互动组件配置标准化规范,用于剧本中对话选读/对话选读-配图类型组件的标准化生成
-metadata:
- requires:
- permissions: ["sheets:spreadsheet"]
- identity: bot
----
-# 对话选读组件配置规范
-## 适用场景
-当【类型】列内容为【对话选读】或【对话选读-配图】时,使用本规范生成组件配置
-
-
-## 文本输出规范(强制执行)
-
-所有输出的文本内容(台词、题目、选项、解析、音频文本、阅读文章等)必须遵守以下规则:
-
-1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。
-2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。
-3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。
-
-## 核心规则 — 与对话选择的关键区分
-
-| 对比项 | 对话选择 | 对话选读 |
-|--------|---------|---------|
-| 互动目的 | 有对错判断 | 开放表达,任意选均可 |
-| 互动要求 | 选择正确的回复 | 选择一个你想表达的观点 |
-| 正确选项 | 标注 `(正确)` | **无正确选项** |
-| 选项反馈 | 正确选项反馈可缺省 | **每个选项均有反馈** |
-
-## 配置格式
-### 字段要求
-1. 【任务标题】:
- - 设计规则:结合剧情上下文,提炼互动核心内容,使用中文口语化表述,符合低龄用户认知
- - 核心要素:包含互动对象+核心动作/状态,避免笼统的「对话X」编号
- - 约定:如需表达顺序关系,使用中文括号替代「-」,如「与调酒师对峙(一)」而非「与调酒师对峙-1」
- - ⚠️ 标题含英文单词时,英文单词前后必须留空格
-2. 【资源配置】:
- - 类型为「对话选读」时,填写:无
- - 类型为「对话选读-配图」时,填写:
- ```
- 图片时机:
- 互动内容
- 互动反馈
-
- 音频载体:Pioneer Band
- ```
- - 资源命名规范:
- - 图片文件名:`{组件ID}.png`,如 `0216002.png`
- - 音频文件名:`{组件ID}.mp3`,如 `0216002.mp3`
- - 音频默认在互动内容、互动反馈期间出现;若配置音频,必须添加【音频载体】
- - 图片默认在互动内容、互动反馈期间出现;如需调整节点,在【资源配置】处填写【情境引入】或【后置对话】
-3. 【情境引入】:
- - 以对话方式呈现,每行一句。格式为「角色名 : 对话内容」
- - 若无情境引入,填「无」
-4. 【互动内容】:
- - 第一行:固定为「要求:选择一个你想表达的观点」
- - 第二行:标注「选项:(音频)」(表示选项有音频支持;默认无音频,若需手动添加音频则填「选项:(音频)」)
- - 第三部分:列出所有选项,编号为「选项1」「选项2」「选项3」... 依次排列
- - 每个选项后以「- 反馈 角色名 : 对话内容」形式标注反馈
- - **无正确/错误区分**,每个选项的反馈为必填项
- - ⚠️ 反馈角色不可是 User 自己,必须是当前场景中的其他角色
- - (音频)标记默认不含,若选项需要播放音频则手动填写「(音频)」,使用中文括号
-5. 【互动反馈】:本类型不单独设置互动反馈字段,反馈内容已整合在互动内容的各选项中
-6. 【后置对话】:
- - 以对话方式呈现,每行一句。格式为「角色名 : 对话内容」
- - 若无后置对话,填「无」
-## 完整示例
-### 对话选读-配图类型示例
-```
-【任务标题】
-加入搏斗俱乐部
-
-【资源配置】
-图片时机:
-互动内容
-互动反馈
-
-音频载体:Pioneer Band
-
-【情境引入】
-Johnny: What do you think of the club?
-
-【互动内容】
-要求:选择一个你想表达的观点
-选项:(音频)
-选项1:That's great! I'm going to ask Otis and Skely to go together!
-- 反馈 Johnny : I don't think it's OK to have so many people in.
-选项2:Interesting! I can go on this trip alone.
-- 反馈 Johnny : You'd better not do this by yourself.
-选项3:It's no fun. I'd better not participate.
-- 反馈 Johnny : Ok, it's a good decision.
-
-【后置对话】
-无
-```
-### 对话选读类型示例
-```
-【任务标题】
-说说现在的屋子吧
-
-【资源配置】
-无
-
-【情境引入】
-User : Yes, today is very messy.
-
-【互动内容】
-要求:选择一个你想表达的观点
-选项:
-选项1:Today is a good day. No one is at home.
-- 反馈 User : But grandparents are coming to visit!
-选项2:Today is very messy. We need to clean up.
-- 反馈 User : Yes, let's clean up together!
-选项3:Today is not so bad. We can have fun.
-- 反馈 User : But look at the sofa and the floor!
-
-【后置对话】
-无
-```
diff --git a/business_production/组件生产/skills/info-interaction-config/SKILL.md b/business_production/组件生产/skills/info-interaction-config/SKILL.md
new file mode 100644
index 0000000..92a7487
--- /dev/null
+++ b/business_production/组件生产/skills/info-interaction-config/SKILL.md
@@ -0,0 +1,225 @@
+---
+name: info-interaction-config
+version: 1.0.0
+description: 信息类互动组件配置标准化规范,覆盖信息拼词/组句/描写/补词/填词/填句共6类的标准化生成
+metadata:
+ requires:
+ permissions: ["sheets:spreadsheet"]
+ identity: bot
+---
+
+## 文本输出规范(强制执行)
+
+1. 禁止 Markdown 标记
+2. 英式拼写优先
+3. 中文全角标点,英文半角标点,不混用
+
+## 通用规则(6类共享)
+
+- 【任务标题】:中文口语化,10字以内,避免「-」,有序用「(一)」,含英文单词时前后留空格
+- 【资源配置】:图片文件名 = `{组件ID}.png`,不含音频配置
+- 【后置对话】:无则填「无」
+
+---
+
+## 一、信息拼词
+
+单词中挖空字母,从候选字母中选取正确字母拼出完整单词。
+
+**互动内容格式:**
+```
+任务描述:请…
+题干:{单词,空缺字母用(数字)占位,如 G(2)pe}
+答案:{填入的字母,如 ra}
+选项:{4-7个候选字母,逗号分隔}
+辅助信息:{提示 或 无}
+```
+
+**规则:** 最多挖空不超过单词总字母数的一半;目标词必须来自知识点;干扰字母与答案字母有明显区分。
+
+**示例:**
+```
+【任务标题】购买葡萄
+【资源配置】
+图片文件名:0216002.png
+【互动内容】
+任务描述:请填入"葡萄"的正确的英文拼写
+题干:G(2)pe
+答案:ra
+选项:h, a, r, l, e, w
+辅助信息:葡萄的英文是 grape
+【后置对话】无
+```
+
+---
+
+## 二、信息组句
+
+从短语/词组拼出完整句子。
+
+**与对话组句的关键区分:**
+
+| 对比项 | 对话组句 | 信息组句 |
+|--------|---------|---------|
+| 选项粒度 | 单词级 | 短语/词组级 |
+| 选项数量 | 4-8 | 3-5 |
+| 干扰项 | 0-1 | 1-2 |
+| 资源 | 可选音频 | 必有图片 |
+| 目标来源 | 基于台词 | 基于知识点 |
+
+**互动内容格式:**
+```
+任务描述:{指引}
+选项1:{短语}
+选项2:{短语}
+选项3:{短语}
+答案:{完整句子,含大小写+句末标点}
+辅助信息:{提示 或 无}
+```
+
+**规则:** 选项 3-5 个,乱序;短语/词组级切分,不按单词边界切;选项不加首字母大写和句末标点;含 1-2 个干扰项。
+
+**示例:**
+```
+【任务标题】填写信息表
+【资源配置】
+图片文件名:0216002.png
+【互动内容】
+任务描述:请在空白处填入正确的单词,组成句子
+选项1:is
+选项2:the visitor
+选项3:you invited
+选项4:Maeve
+答案:Is Maeve the visitor you invited?
+辅助信息:可以用 is 引导的一般疑问句询问
+【后置对话】无
+```
+
+---
+
+## 三、信息描写
+
+根据图片或场景提示,用英文描述所看到的内容。
+
+**互动内容格式:**
+```
+任务描述:{任务指引}
+参考词汇:{关键词汇}
+参考句型:{句型}
+示例回答:User: {句子}
+```
+
+**规则:** 必有图片资源;考察观察与表达能力;知识点必须来自当前单元。
+
+**示例:**
+```
+【任务标题】描述房间里的物品
+【资源配置】
+图片文件名:0216002.png
+【互动内容】
+任务描述:请用英文描述图片中房间里的物品
+参考词汇:sofa, window, door, table
+参考句型:There is a... / I can see...
+示例回答:User: There is a sofa in the room.
+【互动反馈】
+正确 User: Great! You described it well.
+错误 User: Try again. What else can you see?
+【后置对话】无
+```
+
+---
+
+## 四、信息补词
+
+句子中挖空一个单词,从候选词中选出正确单词填入。
+
+**互动内容格式:**
+```
+题干:{含___的句子}
+选项1:{单词}(正确)
+选项2:{单词}
+选项3:{单词}
+辅助信息:{提示 或 无}
+```
+
+**规则:** 3-4 个候选单词;有候选词列表(区别于信息填词)。
+
+**示例:**
+```
+【任务标题】补全句子中的单词
+【资源配置】
+图片文件名:0216002.png
+【互动内容】
+题干:The cat is sitting on the ___.
+选项1:chair(正确)
+选项2:table
+选项3:floor
+辅助信息:注意图片中猫的位置
+【后置对话】无
+```
+
+---
+
+## 五、信息填词
+
+句子中挖空一个单词,学生自行拼写填入(无候选词)。
+
+**与信息补词的关键区分:**
+
+| 对比项 | 信息补词 | 信息填词 |
+|--------|---------|---------|
+| 题型本质 | 从选项中选 | 自行拼写 |
+| 选项 | 有候选词 | 无选项 |
+| 难度 | 较低(识别) | 较高(回忆+拼写) |
+
+**互动内容格式:**
+```
+题干:{含___的句子}
+答案:{正确单词}
+辅助信息:{提示 或 无}
+```
+
+**示例:**
+```
+【任务标题】填入正确的单词
+【资源配置】
+图片文件名:0216002.png
+【互动内容】
+题干:The ___ is on the desk.
+答案:book
+辅助信息:首字母是 b
+【后置对话】无
+```
+
+---
+
+## 六、信息填句
+
+给出不完整句子,学生补全完整句子。
+
+**与信息组句的关键区分:**
+
+| 对比项 | 信息组句 | 信息填句 |
+|--------|---------|---------|
+| 题型本质 | 从短语拼出完整句 | 补全不完整句子 |
+| 输入 | 乱序短语选项 | 句子框架 + 自由输入 |
+| 难度 | 中等(排序+选择) | 中等(补全) |
+
+**互动内容格式:**
+```
+题干:{不完整句子,缺失部分用___表示}
+答案:{完整句子}
+辅助信息:{提示 或 无}
+```
+
+**示例:**
+```
+【任务标题】补全这个句子
+【资源配置】
+图片文件名:0216002.png
+【互动内容】
+题干:The boy ___ to school every day.
+答案:The boy walks to school every day.
+辅助信息:注意主语是第三人称单数
+【后置对话】无
+```
diff --git a/business_production/组件生产/skills/info-sentence-building-config/SKILL.md b/business_production/组件生产/skills/info-sentence-building-config/SKILL.md
deleted file mode 100644
index 6de2d65..0000000
--- a/business_production/组件生产/skills/info-sentence-building-config/SKILL.md
+++ /dev/null
@@ -1,66 +0,0 @@
----
-name: info-sentence-building-config
-version: 1.0.0
-description: 信息组句类互动组件配置标准化规范,用于剧本中信息组句类型组件的标准化生成
-metadata:
- requires:
- permissions: ["sheets:spreadsheet"]
- identity: bot
----
-# 信息组句组件配置规范
-## 适用场景
-当【类型】列内容为【信息组句】时,使用本规范生成组件配置
-
-## 文本输出规范(强制执行)
-
-所有输出的文本内容(台词、题目、选项、解析等)必须遵守以下规则:
-
-1. 禁止 Markdown 标记
-2. 英式拼写优先
-3. 中文全角标点,英文半角标点,不混用
-
-## 核心规则 — 与对话组句的关键区分
-
-| 对比项 | 对话组句 | 信息组句 |
-|--------|---------|---------|
-| 选项粒度 | 单词级 | **短语/词组级** |
-| 选项数量 | 4-8 | **3-5** |
-| 干扰项 | 0-1 | **1-2** |
-| 资源 | 可选音频 | **必有图片** |
-| 目标词来源 | 基于台词 | **基于知识点** |
-
-## 配置格式
-### 字段要求
-1. 【任务标题】:
- - 中文口语化表述,符合低龄用户认知
- - 避免「-」,有序用「(一)」
- - ⚠️ 标题含英文单词时,英文单词前后必须留空格
-2. 【资源配置】:
- - 图片文件名 = `{组件ID}.png`,后台手动上传
- - 不含音频配置
-3. 【互动内容】:
- - **任务描述**:清晰任务指引,引导学生组句
- - **选项**:选项1/2/3... 形式
- - 数量 3-5 个,乱序排列
- - 短语/词组级别切分,**不按单词边界切**
- - 选项内不添加首字母大写,不加句末标点
- - 含 1-2 个干扰项
- - **答案**:完整句子,含正确大小写 + 句末标点
- - **辅助信息**:语法/结构提示;无则写「无」
-4. 【后置对话】:无则填「无」
-
-## 完整示例
-```
-【任务标题】填写信息表
-【资源配置】
-图片文件名:{组件ID}.png
-【互动内容】
-任务描述:请在空白处填入正确的单词,组成句子
-选项1:is
-选项2:the visitor
-选项3:you invited
-选项4:Maeve
-答案:Is Maeve the visitor you invited?
-辅助信息:可以用 is 引导的一般疑问句询问;you invited 是 visitor 的后置定语
-【后置对话】无
-```
diff --git a/business_production/组件生产/skills/info-word-spelling-config/SKILL.md b/business_production/组件生产/skills/info-word-spelling-config/SKILL.md
deleted file mode 100644
index 8cf66b1..0000000
--- a/business_production/组件生产/skills/info-word-spelling-config/SKILL.md
+++ /dev/null
@@ -1,71 +0,0 @@
----
-name: info-word-spelling-config
-version: 1.0.0
-description: 信息拼词类互动组件配置标准化规范,用于剧本中信息拼词类型组件的标准化生成
-metadata:
- requires:
- permissions: ["sheets:spreadsheet"]
- identity: bot
----
-# 信息拼词组件配置规范
-## 适用场景
-当【类型】列内容为【信息拼词】时,使用本规范生成组件配置
-
-## 文本输出规范(强制执行)
-
-所有输出的文本内容(台词、题目、选项、解析、音频文本等)必须遵守以下规则:
-
-1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。
-2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。
-3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。
-
-## 核心规则
-
-信息拼词是通过部分字母提示,让学生从候选字母中选取正确字母拼出完整单词的互动题型。
-
-**与对话挖空的核心区分:**
-| 对比项 | 对话挖空 | 信息拼词 |
-|--------|---------|---------|
-| 题型本质 | 句子中挖空单词 | 单词中挖空字母 |
-| 目标粒度 | 完整单词 | 单个字母 |
-| 题干形式 | 句子含 `___` | 单词含 `(数字)` |
-| 资源 | 可选音频 | 必有图片 |
-| 知识约束 | 知识点句型/单词 | **目标词必须来自知识点** |
-
-## 配置格式
-### 字段要求
-1. 【任务标题】:
- - 中文口语化表述,符合低龄用户认知
- - 避免使用「-」,有序关系用中文括号「(一)」
- - 示例:购买葡萄 / 拼写爷爷的英文
- - ⚠️ 标题含英文单词时,英文单词前后必须留空格
-2. 【资源配置】:
- - 填写图片文件名,格式为 `{组件ID}.png`(如 `0216002.png`)
- - 图片在内容管理后台手动上传
- - 不含音频配置
- - **不含图片坐标信息**(坐标在后台「选取图片坐标」工具中单独配置)
-3. 【互动内容】:
- - **任务描述**:清晰的任务指引,引导学生拼写目标单词。格式为「请…」
- - **题干**:目标单词,其中需学生填入的字母部分用 `(数字)` 占位,数字 = 空缺字母数
- - 示例:`G(2)pe`(grape 缺 2 个字母)/ `grandfa(4)`(grandfather 缺最后 4 个字母)
- - 最多挖空不超过单词总字母数的一半
- - **答案**:仅写需填入的字母,按顺序,中间不加空格
- - 示例:`ra` / `ther`
- - **选项**:4-7 个候选字母,逗号分隔,含正确答案字母 + 干扰字母
- - 干扰字母应与答案字母有明显区分
- - **辅助信息**:提示语句帮助学生;无则写「无」
-4. 【后置对话】:无后置对话则填「无」
-
-## 完整示例
-```
-【任务标题】购买葡萄
-【资源配置】
-图片文件名:0216002.png
-【互动内容】
-任务描述:请填入"葡萄"的正确的英文拼写
-题干:G(2)pe
-答案:ra
-选项:h, a, r, l, e, w
-辅助信息:葡萄的英文是 grape / 第二个字母是 r 哦,再想想最后一个空应该填什么吧
-【后置对话】无
-```
diff --git a/business_production/组件生产/skills/item-interaction-config/SKILL.md b/business_production/组件生产/skills/item-interaction-config/SKILL.md
new file mode 100644
index 0000000..969ee14
--- /dev/null
+++ b/business_production/组件生产/skills/item-interaction-config/SKILL.md
@@ -0,0 +1,65 @@
+---
+name: item-interaction-config
+version: 1.0.0
+description: 物品互动类组件配置标准化规范,用于剧本中物品互动类型组件的标准化生成
+metadata:
+ requires:
+ permissions: ["sheets:spreadsheet"]
+ identity: bot
+---
+
+## 文本输出规范(强制执行)
+
+所有输出的文本内容(台词、题目、选项、解析等)必须遵守以下规则:
+
+1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。
+2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。
+3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。
+
+# 物品互动组件配置规范
+
+## 适用场景
+当【类型】列内容为【物品互动】时,使用本规范生成组件配置。
+
+## 核心规则
+
+物品互动是让学生根据中文提示,在场景中点击/选择正确物品的互动题型。
+
+**关键特征:**
+- 仅保留两个字段:【任务标题】+【互动内容】
+- 互动内容固定格式:`"中文动作提示" the 名词! 选项1:正确单词(正确)选项2:干扰单词`
+- 无【资源配置】【情境引入】【互动反馈】【后置对话】字段
+
+## 配置格式
+
+### 字段要求
+
+1. 【任务标题】:
+ - 中文口语化表述,描述要做的动作
+ - 避免使用「-」,有序关系用中文括号「(一)」
+ - 示例:关上灯塔大门 / 拿起桌上的苹果
+
+2. 【互动内容】:
+ - 固定格式:`"中文动作提示" the 名词!`
+ - 选项1:正确单词,标注 `(正确)`
+ - 选项2:干扰单词(与正确单词同类或形近)
+ - 可扩展到 3 个选项(1正确 + 2干扰)
+
+## 完整示例
+
+```
+【任务标题】关上灯塔大门
+【互动内容】
+"关上" the door!
+选项1:close(正确)
+选项2:open
+```
+
+```
+【任务标题】拿起桌上的苹果
+【互动内容】
+"拿起" the apple!
+选项1:pick up(正确)
+选项2:put down
+选项3:throw away
+```
diff --git a/business_production/组件生产/skills/picture-interaction-config/SKILL.md b/business_production/组件生产/skills/picture-interaction-config/SKILL.md
new file mode 100644
index 0000000..be53716
--- /dev/null
+++ b/business_production/组件生产/skills/picture-interaction-config/SKILL.md
@@ -0,0 +1,146 @@
+---
+name: picture-interaction-config
+version: 1.0.0
+description: 图片类互动组件配置标准化规范,覆盖图片单选/多选/有序/拖拽/图片互动等类型的标准化生成
+metadata:
+ requires:
+ permissions: ["sheets:spreadsheet"]
+ identity: bot
+---
+
+## 文本输出规范(强制执行)
+
+所有输出的文本内容(台词、题目、选项、解析等)必须遵守以下规则:
+
+1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。
+2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。
+3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。
+
+# 图片类互动组件配置规范
+
+## 适用场景
+当【类型】列内容为【图片单选】【图片多选】【图片有序】【图片拖拽】【图片互动】时,使用本规范生成组件配置。
+
+## 核心规则
+
+### 通用规则(所有图片类互动适用)
+
+1. **不包含【资源配置】字段**,直接从【任务标题】开始
+2. 【互动内容】题干必须为指令句式,禁止使用问句
+3. 仅知识点单词前后加 `$` 符号高亮,非知识点单词不加
+4. 选项仅保留 `00/01/02/03` 编号,不需要任何文字说明
+5. 在「正确:XX」行后添加一行 `辅助信息:{单词} {中文释义}。`
+6. 正确反馈统一填「无」,错误反馈必须带角色名
+
+### 各子类型专属规则
+
+#### 图片单选
+- 4 个图片选项(00-03),其中 1 个正确
+- 正确标注:`正确:02`(编号对应正确图片)
+- 示例:
+```
+【任务标题】选出正确的物品
+【情境引入】无
+【互动内容】
+题干:Find the $apple$.
+选项:
+00
+01
+02
+03
+正确:02
+辅助信息:apple 苹果。
+【互动反馈】
+正确:无
+错误:Dan : That's not an apple. Try again!
+【后置对话】无
+```
+
+#### 图片多选
+- 4 个及以上图片选项,多个正确
+- 正确标注:`正确:00, 02`(多个编号逗号分隔)
+- 示例:
+```
+【任务标题】选出所有水果
+【情境引入】无
+【互动内容】
+题干:Find all the $fruit$.
+选项:
+00
+01
+02
+03
+正确:00, 02
+辅助信息:fruit 水果。
+【互动反馈】
+正确:无
+错误:Sally : Some fruits are missing. Look again!
+【后置对话】无
+```
+
+#### 图片有序
+- 4 个及以上图片选项,需按正确顺序排列
+- 正确标注:`正确顺序:00→01→02→03`
+- 示例:
+```
+【任务标题】排序跳格子顺序
+【情境引入】无
+【互动内容】
+题干:Put the actions in order of $one by one$.
+选项:
+00
+01
+02
+03
+正确顺序:00→01→02→03
+辅助信息:one by one 指"一个接一个"。
+【互动反馈】
+正确:无
+错误:Dan : Oops, that's the wrong order! We can't jump like that.
+【后置对话】无
+```
+
+#### 图片拖拽
+- 将图片拖拽到对应位置
+- 正确标注:`正确:00→位置A, 01→位置B`
+- 示例:
+```
+【任务标题】将物品放到正确位置
+【情境引入】无
+【互动内容】
+题干:Drag the items to the correct $places$.
+选项:
+00
+01
+02
+正确:00→位置A, 01→位置B
+辅助信息:places 位置。
+【互动反馈】
+正确:无
+错误:Matt : That doesn't belong there!
+【后置对话】无
+```
+
+#### 图片互动
+- 自由点击/探索类图片互动
+- 无正确/错误判断,仅有点击反馈
+- 示例:
+```
+【任务标题】探索教室里的物品
+【情境引入】无
+【互动内容】
+题干:Tap on the items in the $classroom$.
+选项:
+00
+01
+02
+03
+反馈00:This is a desk.
+反馈01:This is a chair.
+反馈02:This is a blackboard.
+反馈03:This is a window.
+【互动反馈】
+正确:无
+错误:无
+【后置对话】无
+```
diff --git a/business_production/组件生产/skills/pronunciation-interaction-config/SKILL.md b/business_production/组件生产/skills/pronunciation-interaction-config/SKILL.md
new file mode 100644
index 0000000..943d832
--- /dev/null
+++ b/business_production/组件生产/skills/pronunciation-interaction-config/SKILL.md
@@ -0,0 +1,106 @@
+---
+name: pronunciation-interaction-config
+version: 1.0.0
+description: 发音/语音/造句类互动组件配置标准化规范,覆盖发音互动/语音互动/造句互动类型的标准化生成
+metadata:
+ requires:
+ permissions: ["sheets:spreadsheet"]
+ identity: bot
+---
+
+## 文本输出规范(强制执行)
+
+所有输出的文本内容(台词、题目、选项、解析等)必须遵守以下规则:
+
+1. 禁止 Markdown 标记:禁止使用 ** * __ _ 等加粗/斜体标识,也禁止使用 # > - 等块级 Markdown 语法。所有文本纯文本输出。
+2. 英式拼写优先:单词涉及英美式拼写差异时(如 colour/color、centre/center、travelling/traveling),统一选择英式拼写。
+3. 标点符号规范:严格区分全角/半角符号。中文内容使用全角标点(,。!?),英文内容使用半角标点(. , ! ?),不得混用。
+
+# 发音/语音/造句类互动组件配置规范
+
+## 适用场景
+当【类型】列内容为【发音互动】【语音互动】【造句互动】时,使用本规范生成组件配置。
+
+## 核心规则
+
+### 发音互动
+考察学生发音准确度的互动题型。
+
+**配置格式:**
+- 【任务标题】:中文口语化表述
+- 【资源配置】:无(或标注音频文件名)
+- 【互动内容】:
+ - 目标单词/句子:学生需要朗读的内容
+ - 发音要点:关键音素或发音提示
+ - 示例音频:标注 `(音频)` 如需要
+- 【互动反馈】:正确/错误反馈,带角色名
+
+**示例:**
+```
+【任务标题】朗读含 th 音的单词
+【资源配置】无
+【情境引入】无
+【互动内容】
+朗读单词:think
+发音要点:注意 th 音,舌尖轻触上齿
+【互动反馈】
+正确 Matt: Perfect pronunciation!
+错误 Matt: Try again. Put your tongue between your teeth.
+【后置对话】无
+```
+
+### 语音互动
+考察学生语音表达能力的互动题型。
+
+**配置格式:**
+- 【任务标题】:中文口语化表述
+- 【资源配置】:无
+- 【互动内容】:
+ - 表达目标:学生需要说的内容描述
+ - 示例回答:`User: 示例句子`
+ - 辅助信息:语音/语调提示
+- 【互动反馈】:正确/错误反馈,带角色名
+
+**示例:**
+```
+【任务标题】用正确的语调打招呼
+【资源配置】无
+【情境引入】无
+【互动内容】
+表达目标:用开心的语调说 Hello
+示例回答:User: Hello!
+辅助信息:注意语调上扬,表达开心的情绪
+【互动反馈】
+正确 Sally: You sound so happy!
+错误 Sally: Try to sound more excited!
+【后置对话】无
+```
+
+### 造句互动
+考察学生用给定词汇/句型独立造句能力的互动题型。
+
+**配置格式:**
+- 【任务标题】:中文口语化表述
+- 【资源配置】:无(或标注图片文件名)
+- 【互动内容】:
+ - 任务描述:造句要求
+ - 给定词汇/句型:学生必须使用的词汇或句型
+ - 示例回答:`User: 示例句子`
+ - 辅助信息:语法/结构提示
+- 【互动反馈】:正确/错误反馈,带角色名
+
+**示例:**
+```
+【任务标题】用 like 造句
+【资源配置】无
+【情境引入】无
+【互动内容】
+任务描述:用 like 造句,说说你喜欢什么
+给定句型:I like...
+示例回答:User: I like apples.
+辅助信息:like 后面可以加名词,表示喜欢某物
+【互动反馈】
+正确 Dan: I like that too!
+错误 Dan: Hmm, that doesn't sound right. Try "I like..."
+【后置对话】无
+```
diff --git a/business_production/组件生产/skills/script-component-production/SKILL.md b/business_production/组件生产/skills/script-component-production/SKILL.md
index b7fe2b5..06f7e81 100644
--- a/business_production/组件生产/skills/script-component-production/SKILL.md
+++ b/business_production/组件生产/skills/script-component-production/SKILL.md
@@ -49,10 +49,10 @@ description: 剧本互动组件内容生产/审校/回填技能(不涉及JSON
---
-## 执行流程(6个节点)
+## 执行流程(7个节点)
```
-读取飞书文档 → 解析Sheet列结构 → 识别组件行 → 匹配组件类型 → LLM生成组件内容 → 审校 → 回填
+读取飞书文档 → 解析Sheet列结构 → 识别组件行 → 匹配组件类型 → 加载专项Skill → LLM生成组件内容 → 审校 → 回填
```
### 节点1:文档读取
@@ -99,9 +99,29 @@ description: 剧本互动组件内容生产/审校/回填技能(不涉及JSON
- 剧情描述含"表达"/"说出" → 对话表达
- 剧情描述含"看图"/"图片" → 看图说话
+### 节点4.5:加载对应专项 Skill(强制执行)
+
+在调用 LLM 生成前,**必须先读取该组件类型对应的专项 Skill**,将规范注入 LLM prompt:
+
+| 组件类型 | 对应专项 Skill | 路径 |
+|---------|---------------|------|
+| 对话朗读 / 对话表达 / 对话选读 / 对话选择 / 对话挖空 / 对话组句 | `dialogue-interaction-config` | `skills/dialogue-interaction-config/SKILL.md` |
+| 信息拼词 / 信息组句 / 信息描写 / 信息补词 / 信息填词 / 信息填句 | `info-interaction-config` | `skills/info-interaction-config/SKILL.md` |
+| 物品互动 | `item-interaction-config` | `skills/item-interaction-config/SKILL.md` |
+| 图片单选 / 图片多选 / 图片有序 / 图片拖拽 / 图片互动 | `picture-interaction-config` | `skills/picture-interaction-config/SKILL.md` |
+| 发音互动 / 语音互动 / 造句互动 | `pronunciation-interaction-config` | `skills/pronunciation-interaction-config/SKILL.md` |
+| 核心互动(听力/口语/阅读/写作共14类) | `core-interaction-config` | `skills/core-interaction-config/SKILL.md` |
+| 对话互动 / 材料互动 / 指令互动 / 挖空互动 / 组句互动 / 填词互动 / 看图说话 | `component-design` + `vala-interactive-components` | 通用规范 + 官方配置参考 |
+
+**执行流程:**
+1. 根据节点4匹配到的组件类型,查表确定需要加载的专项 Skill
+2. 读取对应 SKILL.md,提取字段模板、校验规则、示例
+3. 将提取的规范作为 system prompt 注入 LLM 调用
+4. 确保 LLM 严格按规范输出,而非自由发挥
+
### 节点5:LLM生成组件内容(结构化文本)
-调用大模型生成结构化文本格式的组件内容,遵循 `component-design` 技能规范。
+调用大模型生成结构化文本格式的组件内容,**严格遵循节点4.5加载的专项 Skill 规范**。
**输出格式(结构化文本,非JSON):**
@@ -135,9 +155,11 @@ This is my picture. It's ___, green and orange.(音频)
```
**各组件类型的字段模板参考:**
-- 中互动 → 遵循 `component-design` 技能中各类型专属规则
+- 对话类互动(朗读/表达/选读/选择/挖空/组句)→ 遵循 `dialogue-interaction-config` 技能规范
+- 信息拼词/组句/描写/补词/填词/填句 → 遵循 `info-interaction-config` 技能规范
+- 物品互动 / 图片类互动 → 遵循 `component-design` 技能中各类型专属规则
- 核心互动 → 遵循 `core-content-json-standard` 技能中的内容结构描述
-- 对话类互动 → 遵循 `dialogue-interaction-config` 技能规范
+- 其余中互动 → 遵循 `component-design` + `vala-interactive-components` 通用规范
### 节点6:审校 & 回填
@@ -152,14 +174,15 @@ This is my picture. It's ___, green and orange.(音频)
| 6 | 选项格式 | 对话类用「选项1:XXX」、图片类用00/01/02编号 |
| 7 | 反馈格式 | 错误反馈带角色名、自然对话、非指令式 |
| 8 | 高亮规则 | 图片类仅知识点词加$、对话类不加 |
-| 9 | 情境引入 | 无内容填「无」,多句换行,格式为「角色名: 台词」。**禁止直接复制前一行台词原文**,相同则填「无」 |
-| 10 | 后置对话 | 取组件行之后的紧接台词,无则填「无」。**禁止直接复制后一行台词原文**,相同则填「无」 |
+| 9 | 情境引入 | 无内容填「无」,多句换行,格式为「角色名: 台词」。🚫 **禁止引用组件行之前任何行的台词**(含前一行的E列/F列原文),必须来自组件自身场景设定。审校时逐行对比组件行之前的E/F列,确认无重合 |
+| 10 | 后置对话 | 取组件行之后的紧接台词,无则填「无」。🚫 **禁止直接复制后一行台词原文**,相同则填「无」。审校时逐行对比组件行之后的E/F列,确认无重合 |
| 11 | 超纲检查 | 词汇/句型在对应级别词库/句型库范围内 |
| 12 | 标点符号 | 统一使用标准英文标点,禁止「~」「!!!」等非标准标点 |
| 13 | 图片类资源配置 | 图片类互动(图片单选/多选/有序/拖拽)**不包含【资源配置】字段** |
| 14 | 图片类辅助信息 | 图片类互动在「正确:XX」后添加 `辅助信息:{单词} {中文释义}。`,释义参考知识点 Sheet |
| 15 | 对话朗读反馈 | 对话朗读**不包含【互动反馈】字段** |
| 16 | 配图资源配置 | A列含"配图"时,仅保留`图片时机`(不写`音频载体`),根据有内容的 section 动态列出 |
+| 17 | 答案随机化 | 听力选择/对话选择等多小题组件,各题正确选项位置必须随机分布,禁止全部集中在同一序号。生成后统计各题正确选项序号,若全部相同则重新随机 |
#### 回填
- 将生成的结构化文本写入列G(组件配置)
@@ -238,6 +261,7 @@ This is my picture. It's ___, green and orange.(音频)
## 版本历史
+- v1.3.0(2026-06-11):强化 #9-#10 情境引入/后置对话审校规则(禁止引用组件行前后台词,必须逐行对比E/F列);新增 #17 答案随机化检查(多小题正确选项必须随机分布)
- v1.2.0(2026-06-08):审校检查项新增 #13-#16(图片类资源配置、辅助信息、对话朗读反馈、配图资源配置);更新 #9-#10 情境引入/后置对话去重规则
- v1.1.0(2026-05-13):明确职责边界,产出格式从JSON改为结构化文本,与 interactive-component-json 解耦
- v1.0.0(2026-05-13):初始版本,覆盖27种中互动 + 14种核心互动,完整6节点流程
diff --git a/business_production/组件生产/skills/task-router/SKILL.md b/business_production/组件生产/skills/task-router/SKILL.md
index e27f549..eaef56e 100644
--- a/business_production/组件生产/skills/task-router/SKILL.md
+++ b/business_production/组件生产/skills/task-router/SKILL.md
@@ -1,6 +1,7 @@
---
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.
+description: ⛔ DEPRECATED (2026-06-11). 仅覆盖8类组件,与41类实际组件差距太大。对话类6类已由 dialogue-interaction-config 统一覆盖,信息拼词/组句已由独立 skill 覆盖。本 skill 不再使用,保留仅供历史参考。
+status: deprecated
---
diff --git a/business_production/组件配置/interactive-component-json/db/components.db b/business_production/组件配置/interactive-component-json/db/components.db
index 9ad57a6..df1539c 100644
Binary files a/business_production/组件配置/interactive-component-json/db/components.db and b/business_production/组件配置/interactive-component-json/db/components.db differ
diff --git a/business_production/组件配置/interactive-component-json/outputs/L1-S2-U20-L2 发球大战_20260611_200751.html b/business_production/组件配置/interactive-component-json/outputs/L1-S2-U20-L2 发球大战_20260611_200751.html
new file mode 100644
index 0000000..28970bf
--- /dev/null
+++ b/business_production/组件配置/interactive-component-json/outputs/L1-S2-U20-L2 发球大战_20260611_200751.html
@@ -0,0 +1,5031 @@
+
+
+
+
+
+L1-S2-U20-L2 发球大战 — 组件JSON报告
+
+
+
+
+
+
+
推送全部组件
+
推送全部知识点
+
导出修改HTML
+
+
+
+ 成功: 0
+ 失败: 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ taskInfo
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
+
+
+
+
+
+
+
+
questionGroup
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
+
+
+
+
+
+
+ studyInfo
+
+ 查看原始JSON
+
+
+
+
+ learningPart
+
+
+
+ closing
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
+
+
+
+
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+ jsonData
+
+ 查看原始JSON
+
+
+
+
+
+
+
+
+ kpInfo JSON
+
+ 查看原始JSON
+
+
+
+
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
+
+
+
+
+
+
+
+
+
原始组件配置 (可编辑后点击"执行重新生成组件")
+
+
执行重新生成组件
+
+
+
知识点文本 (来自sheet知识点列,可编辑后点击"执行重新生成知识点")
+
+
执行重新生成知识点
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/business_production/组件配置/interactive-component-json/scripts/__pycache__/generate_json.cpython-312.pyc b/business_production/组件配置/interactive-component-json/scripts/__pycache__/generate_json.cpython-312.pyc
index 4e9dc3d..904fbba 100644
Binary files a/business_production/组件配置/interactive-component-json/scripts/__pycache__/generate_json.cpython-312.pyc and b/business_production/组件配置/interactive-component-json/scripts/__pycache__/generate_json.cpython-312.pyc differ
diff --git a/memory/.dreams/events.jsonl b/memory/.dreams/events.jsonl
index 6f4dc6a..087a1a2 100644
--- a/memory/.dreams/events.jsonl
+++ b/memory/.dreams/events.jsonl
@@ -115,3 +115,5 @@
{"type":"memory.recall.recorded","timestamp":"2026-06-10T03:52:13.443Z","query":"Perfect Oops 数据 复核 审校 组件","resultCount":1,"results":[{"path":"memory/2026-05-28.md","startLine":19,"endLine":37,"score":1}]}
{"type":"memory.recall.recorded","timestamp":"2026-06-10T03:52:28.180Z","query":"深度复核 流程 步骤 component review audit","resultCount":4,"results":[{"path":"memory/2026-05-20.md","startLine":40,"endLine":59,"score":1},{"path":"memory/2026-05-20.md","startLine":55,"endLine":65,"score":1},{"path":"memory/2026-05-12.md","startLine":234,"endLine":254,"score":1},{"path":"memory/2026-06-08.md","startLine":17,"endLine":27,"score":1}]}
{"type":"memory.recall.recorded","timestamp":"2026-06-10T03:52:28.181Z","query":"core_speaking_image JSON 结构 口语看图","resultCount":3,"results":[{"path":"memory/2026-05-12.md","startLine":164,"endLine":187,"score":1},{"path":"memory/2026-05-12.md","startLine":214,"endLine":236,"score":1},{"path":"memory/2026-05-12.md","startLine":234,"endLine":254,"score":1}]}
+{"type":"memory.recall.recorded","timestamp":"2026-06-11T10:31:34.088Z","query":"S0 多维表格 核心互动 组件配置 bitable","resultCount":6,"results":[{"path":"memory/2026-05-12.md","startLine":214,"endLine":236,"score":1},{"path":"memory/2026-05-12.md","startLine":164,"endLine":187,"score":1},{"path":"memory/2026-05-12.md","startLine":181,"endLine":203,"score":1},{"path":"memory/2026-05-12.md","startLine":234,"endLine":254,"score":1},{"path":"memory/2026-05-12.md","startLine":199,"endLine":216,"score":1},{"path":"memory/2026-05-07.md","startLine":86,"endLine":107,"score":1}]}
+{"type":"memory.recall.recorded","timestamp":"2026-06-11T10:31:50.633Z","query":"S0 多维表格 0000001 合作阅读 核心互动 bitable token","resultCount":6,"results":[{"path":"memory/2026-05-12.md","startLine":214,"endLine":236,"score":1},{"path":"memory/2026-05-12.md","startLine":164,"endLine":187,"score":1},{"path":"memory/2026-05-12.md","startLine":181,"endLine":203,"score":1},{"path":"memory/2026-05-12.md","startLine":234,"endLine":254,"score":1},{"path":"memory/2026-05-12.md","startLine":199,"endLine":216,"score":1},{"path":"memory/2026-05-07.md","startLine":86,"endLine":107,"score":1}]}
diff --git a/memory/.dreams/short-term-recall.json b/memory/.dreams/short-term-recall.json
index 904e8bf..f65490e 100644
--- a/memory/.dreams/short-term-recall.json
+++ b/memory/.dreams/short-term-recall.json
@@ -1,6 +1,6 @@
{
"version": 1,
- "updatedAt": "2026-06-10T03:52:28.181Z",
+ "updatedAt": "2026-06-11T10:31:50.633Z",
"entries": {
"memory:memory/2026-05-07.md:57:74": {
"key": "memory:memory/2026-05-07.md:57:74",
@@ -2433,18 +2433,21 @@
"endLine": 107,
"source": "memory",
"snippet": "- 表2:.xlsx 文件(LV2词表,1,329个单词,含「LV2-单词」「LV2上单词占用情况」「LV2下单词占用情况」「LV2S3」四个sheet) - 表3:.xlsx 文件(L1词表,845个单词,含「单词表-LV1(上)」「单词表-LV1(下)」「单词表-备用」三个sheet合并去重) - **对比过程(共四轮验证):** 1. 第一轮(表1 vs 表2):表1有但表2没有 = 502个 2. 第二轮(结果 vs 表3):排除表3也有后 = 260个 3. 第三轮(用户重发三份文件后重算):最终 = 255个 4. 第四轮(用户单独替换新表3后验证):结果不变,确认 = 255个 - **最终统计:** - 三表共有:230 - 表1 ∩ 表2:492 - 表1 ∩ 表3:448 - 表2 ∩ 表3:427 - 最终:255个 - **关键技术点:** - .doc 文件使用 catdoc 解析(非 libreoffice/antiword) - .xlsx 文件使用 openpyxl 读取,多 sheet 合并去重 - 过滤了缩写词(CD, DVD, TV, Mr, Mrs, Ms 等) - 处理了复数变体映射(geese→goose 等) - 用户 user_id = `58fd6864`(租户级),发送消息时踩坑:ou_xxx 是 open_id 非 user_id - **输出文件:** `/root/.openclaw/workspace-xiaoyan/output/单词对比结果_最终版.x",
- "recallCount": 1,
+ "recallCount": 3,
"dailyCount": 0,
"groundedCount": 0,
- "totalScore": 1,
+ "totalScore": 3,
"maxScore": 1,
"firstRecalledAt": "2026-05-25T09:34:43.114Z",
- "lastRecalledAt": "2026-05-25T09:34:43.114Z",
+ "lastRecalledAt": "2026-06-11T10:31:50.633Z",
"queryHashes": [
- "4baebc80709c"
+ "4baebc80709c",
+ "c538777b9257",
+ "6bf54cd79bb2"
],
"recallDays": [
- "2026-05-25"
+ "2026-05-25",
+ "2026-06-11"
],
"conceptTags": [
"lv2-单词",
@@ -3322,24 +3325,27 @@
"endLine": 187,
"source": "memory",
"snippet": "- **五大分类:** 📖阅读(2) / 🎧听力(3) / 🗣口语(4) / ✏️写作(5) / 未完成(1) - **通用字段提取:** ID/dataStatus/kpStatus/kpInfo/taskData 是所有题型共用的基础结构 #### 覆盖率 - 14 种题型已录入 ✅(1 种无数据:口语探讨) - 4 个一级板块:通用结构 / 题型专区 / 审校规则 / 扩展指南 - 每个题型:cType + bitable 定位 + JSON 字段表 + 结构特点 + 与同类题型的差异说明 #### 发现 - 写作互动和邮件组句 cType 相同(`core_writing_questionMakeSentence`),通过 textInfo 区分素材 - 口语快答/妙问 JSON 结构几乎相同,差异在 prompt 配置和对话样例内容 - 合作阅读和合作听力的核心差异:`textData.text[]` ↔ `textData.audio[]` - meaning 标签(合作阅读)为开放型自由文本,非受控词表 #### 产出文件 - `business_production/_shared/bitable-reader/SKILL.md` — 通用 bitable 读取技能(164行) - `business_knowledge/skills/core-content-json-standard/SKILL.md` — 全题型 JSON 标准 v2.0(393行) - `scripts/audit_core_reading_S0.py` — 合作阅读 S0",
- "recallCount": 6,
+ "recallCount": 8,
"dailyCount": 0,
"groundedCount": 0,
- "totalScore": 6,
+ "totalScore": 8,
"maxScore": 1,
"firstRecalledAt": "2026-06-09T08:37:12.232Z",
- "lastRecalledAt": "2026-06-10T03:52:28.181Z",
+ "lastRecalledAt": "2026-06-11T10:31:50.633Z",
"queryHashes": [
"91bf4d50e5a2",
"b8853a0aafcc",
"113e8be33943",
"9573fdf60768",
"70a3284bc0c5",
- "78420d02cc4d"
+ "78420d02cc4d",
+ "c538777b9257",
+ "6bf54cd79bb2"
],
"recallDays": [
"2026-06-09",
- "2026-06-10"
+ "2026-06-10",
+ "2026-06-11"
],
"conceptTags": [
"口语快答/妙问",
@@ -3359,23 +3365,26 @@
"endLine": 236,
"source": "memory",
"snippet": "- **产出 Skill 2:** `business_knowledge/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:写入前完整提取 → 写入后逐字段 diff → 异常立即回滚 - 首次修复多题 JSON 导致 Q2 丢失 → 先单条试跑验证再批量 ### sentenceMeaningMeaning 引号规范(2026-05-12) - explanation 中 ASCII `\"` 与中文引号混用导致 JSON 解析失败 - 建议:生产侧统一用中文引号 `\"\"`(U+201C/D),或写入前做引号归一化 ### 写作互动 / 邮件组句 cType 相同(2026-05-12) - 两者 cType 均为 `core_writing_questionMakeSentence`,通过 textInfo.textList[].type 区分素材 ### 刘彦江 — 中互动全题型录入(18:00 ~ 18:25) ###",
- "recallCount": 5,
+ "recallCount": 7,
"dailyCount": 0,
"groundedCount": 0,
- "totalScore": 5,
+ "totalScore": 7,
"maxScore": 1,
"firstRecalledAt": "2026-06-09T08:37:12.232Z",
- "lastRecalledAt": "2026-06-10T03:52:28.181Z",
+ "lastRecalledAt": "2026-06-11T10:31:50.633Z",
"queryHashes": [
"91bf4d50e5a2",
"b8853a0aafcc",
"9573fdf60768",
"70a3284bc0c5",
- "78420d02cc4d"
+ "78420d02cc4d",
+ "c538777b9257",
+ "6bf54cd79bb2"
],
"recallDays": [
"2026-06-09",
- "2026-06-10"
+ "2026-06-10",
+ "2026-06-11"
],
"conceptTags": [
"v2.0",
@@ -3395,24 +3404,27 @@
"endLine": 254,
"source": "memory",
"snippet": "#### 发现 - **中互动结构高度统一:** 全部 27 类都用 `jsonData`(主配置)+ `kpInfo`(知识点绑定),没有核心互动那种多字段分散结构 - **6 大分类:** 🗨对话(7) / 📋信息(6) / 📦词汇(2) / 🖼图片选择(4) / 📝语法(3) / 🔧其他(5) - **对话类公共字段:** cType, cId, title, resourceMapping, preDialog, imgShowTimingList - 写作互动和邮件组句 cType 相同(`core_writing_questionMakeSentence`) #### 产出文件 - `skills/interactive-component-json/references/json_structure_guide.md` — 27 种中互动 jsonData 字段结构(8736 bytes) - `skills/interactive-component-json/references/component_registry.md` — 核心互动部分从🔲更新为完整注册表(含 cType+bitable_token) - 与 `business_knowledge/skills/core-content-json-standard/SKILL.md` 双向关联 #### 覆盖率 - 核心互动:15/15 ✅(口语探讨 S0 无数据已标注) - 中互动:27/27 ✅ - 关联文件:3 个(core-content-json-standard + com",
- "recallCount": 6,
+ "recallCount": 8,
"dailyCount": 0,
"groundedCount": 0,
- "totalScore": 6,
+ "totalScore": 8,
"maxScore": 1,
"firstRecalledAt": "2026-06-09T08:37:12.232Z",
- "lastRecalledAt": "2026-06-10T03:52:28.181Z",
+ "lastRecalledAt": "2026-06-11T10:31:50.633Z",
"queryHashes": [
"91bf4d50e5a2",
"b8853a0aafcc",
"9573fdf60768",
"70a3284bc0c5",
"0924e1755b1c",
- "78420d02cc4d"
+ "78420d02cc4d",
+ "c538777b9257",
+ "6bf54cd79bb2"
],
"recallDays": [
"2026-06-09",
- "2026-06-10"
+ "2026-06-10",
+ "2026-06-11"
],
"conceptTags": [
"bitable-token",
@@ -3740,6 +3752,70 @@
"图片",
"时机"
]
+ },
+ "memory:memory/2026-05-12.md:181:203": {
+ "key": "memory:memory/2026-05-12.md:181:203",
+ "path": "memory/2026-05-12.md",
+ "startLine": 181,
+ "endLine": 203,
+ "source": "memory",
+ "snippet": "- `scripts/audit_core_reading_S0.py` — 合作阅读 S0 审校脚本(含审校发现) # 2026-05-12 工作日志 ## 会话记录 ### 刘彦江 — 021301-021801 图片描述修正 + 技能更新(09:35 ~ 09:45) - **问题:** 021301-021801 信息匹配题的图片描述缺少 `【Notice Type】` 标签 - **处理:** 批量更新6条记录的图片描述字段,全部10个标签验证通过 - **脚本:** `scripts/fix_matchInfo_0213_0218_desc.py` - **技能更新:** 图片描述规范写入 `business_production/单元挑战/skills/unit_challenge/questions/reading/reading_info_match/SKILL.md` ### 刘彦江 — L1 配置表审校 + 技能沉淀(11:50 ~ 12:10) - **数据源:** `Nq3Zb258aae7SRs2QfXcqsQYnxJ` / `tblTxGpf6GQ5c7DZ` - **ID 编码:** 7位 = S(2位) + U(2位) + 序列号(3位) - **技能沉淀:** `scripts/audit_l1_config.py` + `business_production/_shared/audit_l1_config/SKILL.md` ### 刘彦江 — 1213001-1216010 批量审校 40 条(12:10 ~ 14:00) -",
+ "recallCount": 2,
+ "dailyCount": 0,
+ "groundedCount": 0,
+ "totalScore": 2,
+ "maxScore": 1,
+ "firstRecalledAt": "2026-06-11T10:31:34.088Z",
+ "lastRecalledAt": "2026-06-11T10:31:50.633Z",
+ "queryHashes": [
+ "c538777b9257",
+ "6bf54cd79bb2"
+ ],
+ "recallDays": [
+ "2026-06-11"
+ ],
+ "conceptTags": [
+ "scripts/audit-core-reading-s0.py",
+ "021301-021801",
+ "scripts/audit-l1-config.py",
+ "business-production",
+ "shared/audit-l1-config/skill.md",
+ "1213001-1216010",
+ "scripts",
+ "audit-core-reading-s0"
+ ]
+ },
+ "memory:memory/2026-05-12.md:199:216": {
+ "key": "memory:memory/2026-05-12.md:199:216",
+ "path": "memory/2026-05-12.md",
+ "startLine": 199,
+ "endLine": 216,
+ "source": "memory",
+ "snippet": "- **脚本修复(过程中):** sort 大小写误报 / ID 末尾空格 / 朗读跟读题误报 - **结果:** 系统性 classificationInfo 互换(已标记不视为错误) + 17条具体错误 + 23条通过 - **脚本:** `scripts/audit_l1_config.py` + `scripts/audit_batch_1213001_1216010.py` ### 刘彦江 — 审校结果修正 + JSON 修复(14:00 ~ 15:38) - **YLE↔A1 误报排除:** 确认等级互通,40条审校结果已更新 - **解析与题目一致性检查:** ✅ 0条不对应 - **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:** `business_production/_shared/bitable-reader/SKILL.md` — 通用 bitable 读取(任何 bitable 通用) - **产出",
+ "recallCount": 2,
+ "dailyCount": 0,
+ "groundedCount": 0,
+ "totalScore": 2,
+ "maxScore": 1,
+ "firstRecalledAt": "2026-06-11T10:31:34.088Z",
+ "lastRecalledAt": "2026-06-11T10:31:50.633Z",
+ "queryHashes": [
+ "c538777b9257",
+ "6bf54cd79bb2"
+ ],
+ "recallDays": [
+ "2026-06-11"
+ ],
+ "conceptTags": [
+ "scripts/audit-l1-config.py",
+ "10/10",
+ "business-production",
+ "shared/bitable-reader/skill.md",
+ "脚本",
+ "修复",
+ "过程",
+ "sort"
+ ]
}
}
}
diff --git a/memory/2026-06-11-1133.md b/memory/2026-06-11-1133.md
new file mode 100644
index 0000000..2a77234
--- /dev/null
+++ b/memory/2026-06-11-1133.md
@@ -0,0 +1,1145 @@
+# Session: 2026-06-11 11:33:06 GMT+8
+
+- **Session Key**: agent:xiaoyan:feishu:direct:ou_a4aaa641585b38d1042608b9b7f05a17
+- **Session ID**: 14ab1977-586e-42fd-b557-fcaca7b4862a
+- **Source**: feishu
+
+## Conversation Summary
+
+assistant: 收到,问题定位清楚了。核心问题是:能力标签「动作识别」要求**听力文本描述动作 + 三张图展示同一主体做不同动作**,而我的原方案中很多题目的听力文本是"拥有/属性描述"而非动作,选项差异在物品/地点而非动作。
+
+重新生产两套:
+
+---
+
+## 【题目组1】场景:教室
+
+听句子,选出与你听到的内容相符的图片。
+
+---
+
+### 【题目1-1】
+【听力文本】
+1. The children learn to read in class.
+【图片描述】
+A: 孩子们在读书
+B: 孩子们在写字
+C: 孩子们在画画
+【正确答案】
+A
+
+---
+
+### 【题目1-2】
+【听力文本】
+2. The teacher writes on the blackboard.
+【图片描述】
+A: 老师在黑板上写字
+B: 老师在黑板上画画
+C: 老师在看书
+【正确答案】
+A
+
+---
+
+### 【题目1-3】
+【听力文本】
+3. The boy reads an English book.
+【图片描述】
+A: 男孩在读英语书
+B: 男孩在写英语单词
+C: 男孩在画画
+【正确答案】
+A
+
+---
+
+### 【题目1-4】
+【听力文本】
+4. The boy draws a line with his ruler.
+【图片描述】
+A: 男孩用尺子画线
+B: 男孩在写字
+C: 男孩在读书
+【正确答案】
+A
+
+---
+
+### 【题目1-5】
+【听力文本】
+5. The children play on the playground.
+【图片描述】
+A: 孩子们在操场上玩耍
+B: 孩子们在操场上跑步
+C: 孩子们在操场上坐着
+【正确答案】
+A
+
+---
+
+【能力项】
+题目1-1 - 听力理解(动作匹配)- learn, read
+题目1-2 - 听力理解(动作匹配)- write, blackboard
+题目1-3 - 听力理解(动作匹配)- read, English
+题目1-4 - 听力理解(动作匹配)- draw, line, ruler
+题目1-5 - 听力理解(动作匹配)- play, playground
+
+---
+
+## 【题目组2】场景:课堂学习
+
+听句子,选出与你听到的内容相符的图片。
+
+---
+
+### 【题目2-1】
+【听力文本】
+1. The girl reads a book at school.
+【图片描述】
+A: 女孩在读书
+B: 女孩在写字
+C: 女孩在画画
+【正确答案】
+A
+
+---
+
+### 【题目2-2】
+【听力文本】
+2. The boy draws a line on the paper.
+【图片描述】
+A: 男孩在纸上画线
+B: 男孩在纸上写字
+C: 男孩在纸上画画
+【正确答案】
+A
+
+---
+
+### 【题目2-3】
+【听力文本】
+3. The boy writes his name on the paper.
+【图片描述】
+A: 男孩在纸上写名字
+B: 男孩在纸上画画
+C: 男孩在看书
+【正确答案】
+A
+
+---
+
+### 【题目2-4】
+【听力文本】
+4. The boy writes with a yellow pencil.
+【图片描述】
+A: 男孩用黄色铅笔写字
+B: 男孩用黄色铅笔画画
+C: 男孩在读书
+【正确答案】
+A
+
+---
+
+### 【题目2-5】
+【听力文本】
+5. The children read a Chinese book.
+【图片描述】
+A: 孩子们在读中文书
+B: 孩子们在写中文字
+C: 孩子们在唱中文歌
+【正确答案】
+A
+
+---
+
+【能力项】
+题目2-1 - 听力理解(动作匹配)- read, school
+题目2-2 - 听力理解(动作匹配)- draw, line, paper
+题目2-3 - 听力理解(动作匹配)- write, name, paper
+题目2-4 - 听力理解(动作匹配)- write, pencil, yellow
+题目2-5 - 听力理解(动作匹配)- read, Chinese
+
+---
+
+**修改对照:**
+
+| 问题 | 原方案 | 修正 |
+|------|--------|------|
+| 听力文本非动作 | "She has an English book"(拥有) | "The boy reads an English book"(动作) |
+| 听力文本非动作 | "The boy has a long blue ruler"(拥有) | "The boy draws a line with his ruler"(动作) |
+| 听力文本非动作 | "She has a yellow pencil"(拥有) | "The boy writes with a yellow pencil"(动作) |
+| 听力文本非动作 | "They have a Chinese lesson"(状态) | "The children read a Chinese book"(动作) |
+| 选项差异在位置 | 教室/操场/花园(地点不同) | 玩耍/跑步/坐着(动作不同) |
+| 选项差异在表面 | 黑板/书本/纸(介质不同) | 写字/画画/看书(动作不同) |
+| 选项差异在形状 | 线/圆/正方形(形状不同) | 画线/写字/画画(动作不同) |
+| 选项差异在科目 | 中文/英语/数学(科目不同) | 读书/写字/唱歌(动作不同) |
+
+**校验结果:**
+
+| 检查项 | 题目组1 | 题目组2 |
+|--------|---------|---------|
+| 词汇超纲 | ✅ 全部在L1词库 | ✅ 全部在L1词库 |
+| 句子长度(B级5-8词) | ✅ 6-8词 | ✅ 6-8词 |
+| 听力文本含动作动词 | ✅ learn/read/write/draw/play | ✅ read/draw/write/read |
+| 选项差异=不同动作 | ✅ 每组三图动作互不相同 | ✅ 每组三图动作互不相同 |
+| 英式拼写 | ✅ | ✅ |
+user: 两套题分别以以下的形式返回给我
+1. 【听力文本】
+Lily: Grandfather is reading a book on the sofa.
+【图片描述】
+选项A: 爷爷在沙发上看书。卡通风格。
+选项B: 爷爷在沙发上睡觉。卡通风格。
+选项C: 爷爷在沙发上看电视。卡通风格。
+【能力项】
+基础语境理解|动作识别
+【题目】
+Which one is Lily talking about?
+【答案】
+A
+【解析】
+听力原文为"Grandfather is reading a book on the sofa.",关键词是reading a book(看书)。选项A是爷爷在看书(动作匹配),选项B是爷爷在睡觉(动作不匹配),选项C是爷爷在看电视(动作不匹配)。只有A与"看书"匹配。
+
+2. 【听力文本】
+Lily: The two girls are talking in the classroom.
+【图片描述】
+选项A: 两个女孩在教室里面对面说话。卡通风格。
+选项B: 两个女孩在教室里坐在桌前写字。卡通风格。
+选项C: 两个女孩在教室里画画。卡通风格。
+【能力项】
+基础语境理解|动作识别
+【题目】
+Which one is Lily talking about?
+【答案】
+A
+【解析】
+听力原文为"The two girls are talking in the classroom.",关键词是talking(说话)。选项A是两个女孩在说话(动作匹配),选项B是两个女孩在写字(动作不匹配),选项C是两个女孩在画画(动作不匹配)。只有A与"说话"匹配。
+
+3. 【听力文本】
+Lily: The boy is pointing at the big tree.
+【图片描述】
+选项A: 一个男孩指着一棵大树。卡通风格。
+选项B: 一个男孩摸着一棵大树。卡通风格。
+选项C: 一个男孩看着一棵大树。卡通风格。
+【能力项】
+基础语境理解|动作识别
+【题目】
+Which one is Lily talking about?
+【答案】
+A
+【解析】
+听力原文为"The boy is pointing at the big tree.",关键词是pointing at(指着)。三张图中男孩都在大树旁,选项A是指着(动作匹配),选项B是摸着(动作不匹配),选项C是看着(动作不匹配)。只有A与"指着"匹配。
+
+4. 【听力文本】
+Lily: Mum gets a letter from the postman.
+【图片描述】
+选项A: 妈妈从邮递员手里接过一封信。卡通风格。
+选项B: 妈妈把一封信投进邮筒。卡通风格。
+选项C: 妈妈在桌边拆开一封信。卡通风格。
+【能力项】
+基础语境理解|动作识别
+【题目】
+Which one is Lily talking about?
+【答案】
+A
+【解析】
+听力原文为"Mum gets a letter from the postman.",关键词是gets from the postman(从邮递员手里接过)。选项A是妈妈从邮递员手里接过信(动作匹配),选项B是妈妈往邮筒投信(动作不匹配),选项C是妈妈拆信(动作不匹配)。只有A与"从邮递员手里接过"匹配。
+
+5. 【听力文本】
+Lily: The girl is carrying a lot of books.
+【图片描述】
+选项A: 一个女孩抱着一大摞书走路。卡通风格。
+选项B: 一个女孩坐在桌边看一本书。卡通风格。
+选项C: 一个女孩把一本书放回书架。卡通风格。
+【能力项】
+基础语境理解|动作识别
+【题目】
+Which one is Lily talking about?
+【答案】
+A
+【解析】
+听力原文为"The girl is carrying a lot of books.",关键词是carrying(抱着/搬运)。选项A是女孩抱着一大摞书走路(动作匹配),选项B是女孩坐着看书(动作不匹配),选项C是女孩把书放回书架(动作不匹配)。只有A与"carrying"匹配。
+
+并且给到我生图prompt
+assistant: 好的,按你给的格式重新输出两套题,并附生图 prompt。
+
+---
+
+# 第一套题(知识点:learn, blackboard, English, ruler, playground)
+
+---
+
+### 题目1
+
+【听力文本】
+Lily: The children learn to read in class.
+
+【图片描述】
+选项A: 三个孩子坐在教室课桌前,每人捧着一本书在读书。卡通风格。
+选项B: 三个孩子坐在教室课桌前,每人拿着笔在本子上写字。卡通风格。
+选项C: 三个孩子坐在教室课桌前,每人拿着画笔在纸上画画。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The children learn to read in class.",关键词是read(读书)。选项A是孩子们在读书(动作匹配),选项B是孩子们在写字(动作不匹配),选项C是孩子们在画画(动作不匹配)。只有A与"读书"匹配。
+
+【生图Prompt】
+- 选项A: A cartoon illustration of three children sitting at desks in a bright classroom, each holding an open book and reading. Simple colorful cartoon style, friendly expressions, children aged 6-8. White background.
+- 选项B: A cartoon illustration of three children sitting at desks in a bright classroom, each holding a pencil and writing in a notebook. Simple colorful cartoon style, friendly expressions, children aged 6-8. White background.
+- 选项C: A cartoon illustration of three children sitting at desks in a bright classroom, each holding a paintbrush and drawing on paper. Simple colorful cartoon style, friendly expressions, children aged 6-8. White background.
+
+---
+
+### 题目2
+
+【听力文本】
+Lily: The teacher writes on the blackboard.
+
+【图片描述】
+选项A: 一位女老师站在黑板前,右手拿粉笔在黑板上写字。卡通风格。
+选项B: 一位女老师站在黑板前,右手拿粉笔在黑板上画画。卡通风格。
+选项C: 一位女老师坐在椅子上,手里捧着一本书在看。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The teacher writes on the blackboard.",关键词是writes on the blackboard(在黑板上写字)。选项A是老师在黑板上写字(动作匹配),选项B是老师在黑板上画画(动作不匹配),选项C是老师在看书(动作不匹配)。只有A与"在黑板上写字"匹配。
+
+【生图Prompt】
+- 选项A: A cartoon illustration of a friendly female teacher standing in front of a blackboard, holding chalk in her right hand and writing words on the blackboard. Classroom setting. Simple colorful cartoon style. White background.
+- 选项B: A cartoon illustration of a friendly female teacher standing in front of a blackboard, holding chalk in her right hand and drawing a picture on the blackboard. Classroom setting. Simple colorful cartoon style. White background.
+- 选项C: A cartoon illustration of a friendly female teacher sitting on a chair, holding an open book and reading. Simple colorful cartoon style. White background.
+
+---
+
+### 题目3
+
+【听力文本】
+Lily: The boy reads an English book.
+
+【图片描述】
+选项A: 一个男孩坐在书桌前,双手捧着一本英语书在认真阅读。卡通风格。
+选项B: 一个男孩坐在书桌前,拿着笔在本子上写英语单词。卡通风格。
+选项C: 一个男孩坐在书桌前,拿着画笔在纸上画画。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The boy reads an English book.",关键词是reads an English book(读英语书)。选项A是男孩在读英语书(动作匹配),选项B是男孩在写英语单词(动作不匹配),选项C是男孩在画画(动作不匹配)。只有A与"读英语书"匹配。
+
+【生图Prompt】
+- 选项A: A cartoon illustration of a young boy sitting at a desk, holding an English book with both hands and reading carefully. The book cover shows "English". Simple colorful cartoon style, boy aged 6-8. White background.
+- 选项B: A cartoon illustration of a young boy sitting at a desk, holding a pencil and writing English words in a notebook. Simple colorful cartoon style, boy aged 6-8. White background.
+- 选项C: A cartoon illustration of a young boy sitting at a desk, holding a paintbrush and drawing a picture on paper. Simple colorful cartoon style, boy aged 6-8. White background.
+
+---
+
+### 题目4
+
+【听力文本】
+Lily: The boy draws a line with his ruler.
+
+【图片描述】
+选项A: 一个男孩坐在书桌前,左手按住尺子,右手拿铅笔沿着尺子画一条直线。卡通风格。
+选项B: 一个男孩坐在书桌前,右手拿铅笔在本子上写字。卡通风格。
+选项C: 一个男孩坐在书桌前,双手捧着一本书在阅读。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The boy draws a line with his ruler.",关键词是draws a line with his ruler(用尺子画线)。选项A是男孩用尺子画线(动作匹配),选项B是男孩在写字(动作不匹配),选项C是男孩在读书(动作不匹配)。只有A与"用尺子画线"匹配。
+
+【生图Prompt】
+- 选项A: A cartoon illustration of a young boy sitting at a desk, holding a ruler steady with his left hand and drawing a straight line along it with a pencil in his right hand. Simple colorful cartoon style, boy aged 6-8. White background.
+- 选项B: A cartoon illustration of a young boy sitting at a desk, holding a pencil in his right hand and writing in a notebook. Simple colorful cartoon style, boy aged 6-8. White background.
+- 选项C: A cartoon illustration of a young boy sitting at a desk, holding an open book with both hands and reading. Simple colorful cartoon style, boy aged 6-8. White background.
+
+---
+
+### 题目5
+
+【听力文本】
+Lily: The children play on the playground.
+
+【图片描述】
+选项A: 三个孩子在操场上开心地玩耍,有的在跑有的在跳。卡通风格。
+选项B: 三个孩子在操场跑道上并排跑步。卡通风格。
+选项C: 三个孩子坐在操场边的长凳上聊天。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The children play on the playground.",关键词是play(玩耍)。选项A是孩子们在操场上玩耍(动作匹配),选项B是孩子们在跑步(动作不匹配),选项C是孩子们在坐着(动作不匹配)。只有A与"玩耍"匹配。
+
+【生图Prompt】
+- 选项A: A cartoon illustration of three children happily playing on a school playground, one running and one jumping, with swings and slides in the background. Simple colorful cartoon style, children aged 6-8. White background.
+- 选项B: A cartoon illustration of three children running side by side on a playground running track. Simple colorful cartoon style, children aged 6-8. White background.
+- 选项C: A cartoon illustration of three children sitting on a bench next to a playground, chatting. Simple colorful cartoon style, children aged 6-8. White background.
+
+---
+
+# 第二套题(知识点:read, line, write, pencil, Chinese)
+
+---
+
+### 题目1
+
+【听力文本】
+Lily: The girl reads a book at school.
+
+【图片描述】
+选项A: 一个女孩坐在学校教室的课桌前,双手捧着一本书在阅读。卡通风格。
+选项B: 一个女孩坐在学校教室的课桌前,右手拿笔在本子上写字。卡通风格。
+选项C: 一个女孩坐在学校教室的课桌前,拿着画笔在纸上画画。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The girl reads a book at school.",关键词是reads a book(读书)。选项A是女孩在读书(动作匹配),选项B是女孩在写字(动作不匹配),选项C是女孩在画画(动作不匹配)。只有A与"读书"匹配。
+
+【生图Prompt】
+- 选项A: A cartoon illustration of a young girl sitting at a school desk, holding an open book with both hands and reading. Classroom setting with a window in the background. Simple colorful cartoon style, girl aged 6-8. White background.
+- 选项B: A cartoon illustration of a young girl sitting at a school desk, holding a pencil in her right hand and writing in a notebook. Classroom setting. Simple colorful cartoon style, girl aged 6-8. White background.
+- 选项C: A cartoon illustration of a young girl sitting at a school desk, holding a paintbrush and drawing a picture on paper. Classroom setting. Simple colorful cartoon style, girl aged 6-8. White background.
+
+---
+
+### 题目2
+
+【听力文本】
+Lily: The boy draws a line on the paper.
+
+【图片描述】
+选项A: 一个男孩坐在桌前,右手拿铅笔在纸上画一条直线。卡通风格。
+选项B: 一个男孩坐在桌前,右手拿铅笔在纸上写字。卡通风格。
+选项C: 一个男孩坐在桌前,右手拿画笔在纸上涂色。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The boy draws a line on the paper.",关键词是draws a line(画线)。选项A是男孩在纸上画线(动作匹配),选项B是男孩在纸上写字(动作不匹配),选项C是男孩在纸上涂色(动作不匹配)。只有A与"画线"匹配。
+
+【生图Prompt】
+- 选项A: A cartoon illustration of a young boy sitting at a desk, holding a pencil in his right hand and drawing a straight line on a piece of paper. Simple colorful cartoon style, boy aged 6-8. White background.
+- 选项B: A cartoon illustration of a young boy sitting at a desk, holding a pencil in his right hand and writing words on a piece of paper. Simple colorful cartoon style, boy aged 6-8. White background.
+- 选项C: A cartoon illustration of a young boy sitting at a desk, holding a paintbrush in his right hand and colouring on a piece of paper. Simple colorful cartoon style, boy aged 6-8. White background.
+
+---
+
+### 题目3
+
+【听力文本】
+Lily: The boy writes his name on the paper.
+
+【图片描述】
+选项A: 一个男孩坐在桌前,右手拿铅笔在纸上写自己的名字。卡通风格。
+选项B: 一个男孩坐在桌前,右手拿画笔在纸上画一朵花。卡通风格。
+选项C: 一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The boy writes his name on the paper.",关键词是writes his name(写名字)。选项A是男孩在纸上写名字(动作匹配),选项B是男孩在纸上画画(动作不匹配),选项C是男孩在读书(动作不匹配)。只有A与"写名字"匹配。
+
+【生图Prompt】
+- 选项A: A cartoon illustration of a young boy sitting at a desk, holding a pencil in his right hand and writing his name on a piece of paper. Simple colorful cartoon style, boy aged 6-8. White background.
+- 选项B: A cartoon illustration of a young boy sitting at a desk, holding a paintbrush in his right hand and drawing a flower on a piece of paper. Simple colorful cartoon style, boy aged 6-8. White background.
+- 选项C: A cartoon illustration of a young boy sitting at a desk, holding an open book with both hands and reading. Simple colorful cartoon style, boy aged 6-8. White background.
+
+---
+
+### 题目4
+
+【听力文本】
+Lily: The boy writes with a yellow pencil.
+
+【图片描述】
+选项A: 一个男孩坐在桌前,右手拿着一支黄色铅笔在本子上写字。卡通风格。
+选项B: 一个男孩坐在桌前,右手拿着一支黄色铅笔在纸上画画。卡通风格。
+选项C: 一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The boy writes with a yellow pencil.",关键词是writes(写字)。选项A是男孩用黄色铅笔写字(动作匹配),选项B是男孩用黄色铅笔画画(动作不匹配),选项C是男孩在读书(动作不匹配)。只有A与"写字"匹配。
+
+【生图Prompt】
+- 选项A: A cartoon illustration of a young boy sitting at a desk, holding a yellow pencil in his right hand and writing in a notebook. The yellow pencil is clearly visible. Simple colorful cartoon style, boy aged 6-8. White background.
+- 选项B: A cartoon illustration of a young boy sitting at a desk, holding a yellow pencil in his right hand and drawing a picture on paper. The yellow pencil is clearly visible. Simple colorful cartoon style, boy aged 6-8. White background.
+- 选项C: A cartoon illustration of a young boy sitting at a desk, holding an open book with both hands and reading. Simple colorful cartoon style, boy aged 6-8. White background.
+
+---
+
+### 题目5
+
+【听力文本】
+Lily: The children read a Chinese book.
+
+【图片描述】
+选项A: 三个孩子围坐在桌前,一起看一本中文书。卡通风格。
+选项B: 三个孩子围坐在桌前,每人拿笔在本子上写中文字。卡通风格。
+选项C: 三个孩子站在一起,张嘴唱歌。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The children read a Chinese book.",关键词是read a Chinese book(读中文书)。选项A是孩子们在读中文书(动作匹配),选项B是孩子们在写中文字(动作不匹配),选项C是孩子们在唱歌(动作不匹配)。只有A与"读中文书"匹配。
+
+【生图Prompt】
+- 选项A: A cartoon illustration of three children sitting around a table, reading a Chinese book together. The book cover shows Chinese characters. Simple colorful cartoon style, children aged 6-8. White background.
+- 选项B: A cartoon illustration of three children sitting around a table, each holding a pencil and writing Chinese characters in notebooks. Simple colorful cartoon style, children aged 6-8. White background.
+- 选项C: A cartoon illustration of three children standing together, mouths open and singing. Simple colorful cartoon style, children aged 6-8. White background.
+
+---
+
+**校验汇总:**
+
+| 检查项 | 第一套 | 第二套 |
+|--------|--------|--------|
+| 词汇在L1词库 | ✅ | ✅ |
+| 句子长度 B级 5-8词 | ✅ 6-7词 | ✅ 6-8词 |
+| 听力文本含动作动词 | ✅ learn/read/write/draw/play | ✅ read/draw/write/read |
+| 三选项=同一主体不同动作 | ✅ | ✅ |
+| 能力标签 基础语境理解|动作识别 | ✅ | ✅ |
+| 英式拼写 | ✅ | ✅ |
+| 生图Prompt覆盖全部选项 | ✅ 15张 | ✅ 15张 |
+user: 先把这两套题按以下格式返回给我
+1. 【听力文本】
+Lily: The man is riding a red motorbike.
+【图片描述】
+选项A: 一个男人骑着一辆红色摩托车。卡通风格。
+选项B: 一个男人推着一辆红色摩托车。卡通风格。
+选项C: 一个男人站在一辆红色摩托车旁。卡通风格。
+【能力项】
+基础语境理解|动作识别
+【题目】
+Which one is Lily talking about?
+【答案】
+A
+【解析】
+听力原文为"The man is riding a red motorbike.",关键词是riding(骑)。三张图中都是同一个男人和同一辆红色摩托车,选项A是骑着(动作匹配),选项B是推着(动作不匹配),选项C是站在旁边(动作不匹配)。只有A与"riding"匹配。
+
+2. 【听力文本】
+Lily: My grandmother is walking in the park.
+【图片描述】
+选项A: 一位老奶奶在公园里坐着。卡通风格。
+选项B: 一位老奶奶在公园里散步。卡通风格。
+选项C: 一位老奶奶在公园里跑步。卡通风格。
+【能力项】
+基础语境理解|动作识别
+【题目】
+Which one is Lily talking about?
+【答案】
+B
+【解析】
+听力原文为"My grandmother is walking in the park.",关键词是walking(散步)。三张图中奶奶都在公园里,选项A是坐着(动作不匹配),选项B是散步(动作匹配),选项C是跑步(动作不匹配)。只有B与"walking"匹配。
+
+3. 【听力文本】
+Lily: The door is open. A cat runs out.
+【图片描述】
+选项A: 门开着,一只猫从门里跑出来。卡通风格。
+选项B: 门开着,一只猫在门边睡觉。卡通风格。
+选项C: 门开着,一只猫在门边吃东西。卡通风格。
+【能力项】
+基础语境理解|动作识别
+【题目】
+Which one is Lily talking about?
+【答案】
+A
+【解析】
+听力原文为"The door is open. A cat runs out.",关键词是runs out(跑出来)。三张图中门都开着且都是同一只猫,选项A是猫跑出来(动作匹配),选项B是猫在睡觉(动作不匹配),选项C是猫在吃东西(动作不匹配)。只有A与"runs out"匹配。
+
+4. 【听力文本】
+Lily: The door is closed. The boy opens the door.
+【图片描述】
+选项A: 门关着,一个男孩在敲门。卡通风格。
+选项B: 门关着,一个男孩站在门前。卡通风格。
+选项C: 门关着,一个男孩在开门。卡通风格。
+【能力项】
+基础语境理解|动作识别
+【题目】
+Which one is Lily talking about?
+【答案】
+C
+【解析】
+听力原文为"The door is closed. The boy opens the door.",关键词是opens(打开)。三张图中都是同一个男孩和同一扇门,选项A是男孩在敲门(动作不匹配),选项B是男孩站在门前(动作不匹配),选项C是男孩在开门(动作匹配)。只有C与"opens"匹配。
+
+5. 【听力文本】
+Lily: A girl is closing the blue door.
+【图片描述】
+选项A: 一个女孩正在敲一扇蓝色的门。卡通风格。
+选项B: 一个女孩正在关上一扇蓝色的门。卡通风格。
+选项C: 一个女孩站在一扇蓝色的门前。卡通风格。
+【能力项】
+基础语境理解|动作识别
+【题目】
+Which one is Lily talking about?
+【答案】
+B
+【解析】
+听力原文为"A girl is closing the blue door.",关键词是closing(关上)。三张图中都是同一个女孩和同一扇蓝色门,选项A是女孩在敲门(动作不匹配),选项B是女孩在关门(动作匹配),选项C是女孩站在门前(动作不匹配)。只有B与"closing"匹配。
+assistant: ---
+
+# 第一套题(知识点:learn, blackboard, English, ruler, playground)
+
+---
+
+### 题目1
+
+【听力文本】
+Lily: The children learn to read in class.
+
+【图片描述】
+选项A: 三个孩子坐在教室课桌前,每人拿着笔在本子上写字。卡通风格。
+选项B: 三个孩子坐在教室课桌前,每人捧着一本书在读书。卡通风格。
+选项C: 三个孩子坐在教室课桌前,每人拿着画笔在纸上画画。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+B
+
+【解析】
+听力原文为"The children learn to read in class.",关键词是read(读书)。三张图中孩子们都在教室里,选项A是写字(动作不匹配),选项B是读书(动作匹配),选项C是画画(动作不匹配)。只有B与"read"匹配。
+
+---
+
+### 题目2
+
+【听力文本】
+Lily: The teacher writes on the blackboard.
+
+【图片描述】
+选项A: 一位女老师站在黑板前,右手拿粉笔在黑板上画画。卡通风格。
+选项B: 一位女老师坐在椅子上,手里捧着一本书在看。卡通风格。
+选项C: 一位女老师站在黑板前,右手拿粉笔在黑板上写字。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+C
+
+【解析】
+听力原文为"The teacher writes on the blackboard.",关键词是writes on the blackboard(在黑板上写字)。三张图中都是同一位女老师,选项A是在黑板上画画(动作不匹配),选项B是在看书(动作不匹配),选项C是在黑板上写字(动作匹配)。只有C与"writes on the blackboard"匹配。
+
+---
+
+### 题目3
+
+【听力文本】
+Lily: The boy reads an English book.
+
+【图片描述】
+选项A: 一个男孩坐在书桌前,双手捧着一本英语书在认真阅读。卡通风格。
+选项B: 一个男孩坐在书桌前,拿着笔在本子上写英语单词。卡通风格。
+选项C: 一个男孩坐在书桌前,拿着画笔在纸上画画。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The boy reads an English book.",关键词是reads an English book(读英语书)。三张图中都是同一个男孩坐在书桌前,选项A是读英语书(动作匹配),选项B是写英语单词(动作不匹配),选项C是画画(动作不匹配)。只有A与"reads an English book"匹配。
+
+---
+
+### 题目4
+
+【听力文本】
+Lily: The boy draws a line with his ruler.
+
+【图片描述】
+选项A: 一个男孩坐在书桌前,右手拿铅笔在本子上写字。卡通风格。
+选项B: 一个男孩坐在书桌前,左手按住尺子,右手拿铅笔沿着尺子画一条直线。卡通风格。
+选项C: 一个男孩坐在书桌前,双手捧着一本书在阅读。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+B
+
+【解析】
+听力原文为"The boy draws a line with his ruler.",关键词是draws a line with his ruler(用尺子画线)。三张图中都是同一个男孩坐在书桌前,选项A是写字(动作不匹配),选项B是用尺子画线(动作匹配),选项C是读书(动作不匹配)。只有B与"draws a line with his ruler"匹配。
+
+---
+
+### 题目5
+
+【听力文本】
+Lily: The children play on the playground.
+
+【图片描述】
+选项A: 三个孩子在操场上开心地玩耍,有的在跑有的在跳。卡通风格。
+选项B: 三个孩子在操场跑道上并排跑步。卡通风格。
+选项C: 三个孩子坐在操场边的长凳上聊天。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The children play on the playground.",关键词是play(玩耍)。三张图中孩子们都在操场上,选项A是玩耍(动作匹配),选项B是跑步(动作不匹配),选项C是坐着聊天(动作不匹配)。只有A与"play"匹配。
+
+---
+
+# 第二套题(知识点:read, line, write, pencil, Chinese)
+
+---
+
+### 题目1
+
+【听力文本】
+Lily: The girl reads a book at school.
+
+【图片描述】
+选项A: 一个女孩坐在学校教室的课桌前,右手拿笔在本子上写字。卡通风格。
+选项B: 一个女孩坐在学校教室的课桌前,拿着画笔在纸上画画。卡通风格。
+选项C: 一个女孩坐在学校教室的课桌前,双手捧着一本书在阅读。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+C
+
+【解析】
+听力原文为"The girl reads a book at school.",关键词是reads a book(读书)。三张图中都是同一个女孩坐在教室课桌前,选项A是写字(动作不匹配),选项B是画画(动作不匹配),选项C是读书(动作匹配)。只有C与"reads a book"匹配。
+
+---
+
+### 题目2
+
+【听力文本】
+Lily: The boy draws a line on the paper.
+
+【图片描述】
+选项A: 一个男孩坐在桌前,右手拿铅笔在纸上画一条直线。卡通风格。
+选项B: 一个男孩坐在桌前,右手拿铅笔在纸上写字。卡通风格。
+选项C: 一个男孩坐在桌前,右手拿画笔在纸上涂色。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The boy draws a line on the paper.",关键词是draws a line(画线)。三张图中都是同一个男孩坐在桌前,选项A是画线(动作匹配),选项B是写字(动作不匹配),选项C是涂色(动作不匹配)。只有A与"draws a line"匹配。
+
+---
+
+### 题目3
+
+【听力文本】
+Lily: The boy writes his name on the paper.
+
+【图片描述】
+选项A: 一个男孩坐在桌前,右手拿画笔在纸上画一朵花。卡通风格。
+选项B: 一个男孩坐在桌前,右手拿铅笔在纸上写自己的名字。卡通风格。
+选项C: 一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+B
+
+【解析】
+听力原文为"The boy writes his name on the paper.",关键词是writes his name(写名字)。三张图中都是同一个男孩坐在桌前,选项A是画画(动作不匹配),选项B是写名字(动作匹配),选项C是读书(动作不匹配)。只有B与"writes his name"匹配。
+
+---
+
+### 题目4
+
+【听力文本】
+Lily: The boy writes with a yellow pencil.
+
+【图片描述】
+选项A: 一个男孩坐在桌前,右手拿着一支黄色铅笔在纸上画画。卡通风格。
+选项B: 一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。
+选项C: 一个男孩坐在桌前,右手拿着一支黄色铅笔在本子上写字。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+C
+
+【解析】
+听力原文为"The boy writes with a yellow pencil.",关键词是writes(写字)。三张图中都是同一个男孩坐在桌前,选项A是用黄色铅笔画画(动作不匹配),选项B是读书(动作不匹配),选项C是用黄色铅笔写字(动作匹配)。只有C与"writes"匹配。
+
+---
+
+### 题目5
+
+【听力文本】
+Lily: The children read a Chinese book.
+
+【图片描述】
+选项A: 三个孩子围坐在桌前,一起看一本中文书。卡通风格。
+选项B: 三个孩子围坐在桌前,每人拿笔在本子上写中文字。卡通风格。
+选项C: 三个孩子站在一起,张嘴唱歌。卡通风格。
+
+【能力项】
+基础语境理解|动作识别
+
+【题目】
+Which one is Lily talking about?
+
+【答案】
+A
+
+【解析】
+听力原文为"The children read a Chinese book.",关键词是read a Chinese book(读中文书)。三张图中都是三个孩子,选项A是读中文书(动作匹配),选项B是写中文字(动作不匹配),选项C是唱歌(动作不匹配)。只有A与"read a Chinese book"匹配。
+
+---
+
+**答案分布:**
+
+| | Q1 | Q2 | Q3 | Q4 | Q5 |
+|------|----|----|----|----|----|
+| 第一套 | B | C | A | B | A |
+| 第二套 | C | A | B | C | A |
+
+**校验结果:**
+
+| 检查项 | 第一套 | 第二套 |
+|--------|--------|--------|
+| 词汇在L1词库 | ✅ | ✅ |
+| 句子长度 B级 5-8词 | ✅ 6-7词 | ✅ 6-8词 |
+| 听力文本含动作动词 | ✅ | ✅ |
+| 三选项=同一主体不同动作 | ✅ | ✅ |
+| 能力标签 基础语境理解|动作识别 | ✅ | ✅ |
+| 答案不全是A | ✅ B/C/A/B/A | ✅ C/A/B/C/A |
+| 英式拼写 | ✅ | ✅ |
+user: 两套题的生图prompt 按照以下形式分别返回给我
+[1-A-选项图彩图]:{"prompt":"一份金黄的炸薯条。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"一个牛肉汉堡包。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"一个棕色的椰子。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一个男孩在河边钓鱼。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一个男孩在操场跑步。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一个男孩在桌边画画。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个牛肉汉堡包。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一份金黄的炸薯条。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个棕色的椰子。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个棕色的椰子。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个牛肉汉堡包。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一份金黄的炸薯条。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"一个银色的机器人。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"一辆蓝色的玩具车。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"一个可爱的洋娃娃。卡通风格。"}
+assistant: # 第一套题(知识点:learn, blackboard, English, ruler, playground)
+
+[1-A-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人拿着笔在本子上写字。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人捧着一本书在读书。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人拿着画笔在纸上画画。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一位女老师站在黑板前,右手拿粉笔在黑板上画画。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一位女老师坐在椅子上,手里捧着一本书在看。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一位女老师站在黑板前,右手拿粉笔在黑板上写字。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个男孩坐在书桌前,双手捧着一本英语书在认真阅读。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一个男孩坐在书桌前,拿着笔在本子上写英语单词。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个男孩坐在书桌前,拿着画笔在纸上画画。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个男孩坐在书桌前,右手拿铅笔在本子上写字。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个男孩坐在书桌前,左手按住尺子,右手拿铅笔沿着尺子画一条直线。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一个男孩坐在书桌前,双手捧着一本书在阅读。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"三个孩子在操场上开心地玩耍,有的在跑有的在跳。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"三个孩子在操场跑道上并排跑步。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"三个孩子坐在操场边的长凳上聊天。卡通风格。"}
+
+---
+
+# 第二套题(知识点:read, line, write, pencil, Chinese)
+
+[1-A-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,右手拿笔在本子上写字。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,拿着画笔在纸上画画。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,双手捧着一本书在阅读。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上画一条直线。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上写字。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿画笔在纸上涂色。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿画笔在纸上画一朵花。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上写自己的名字。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿着一支黄色铅笔在纸上画画。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿着一支黄色铅笔在本子上写字。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"三个孩子围坐在桌前,一起看一本中文书。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"三个孩子围坐在桌前,每人拿笔在本子上写中文字。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"三个孩子站在一起,张嘴唱歌。卡通风格。"}
+user: 两套题的生图prompt 按照以下形式分别返回给我
+[1-A-选项图彩图]:{"prompt":"一份金黄的炸薯条。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"一个牛肉汉堡包。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"一个棕色的椰子。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一个男孩在河边钓鱼。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一个男孩在操场跑步。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一个男孩在桌边画画。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个牛肉汉堡包。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一份金黄的炸薯条。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个棕色的椰子。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个棕色的椰子。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个牛肉汉堡包。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一份金黄的炸薯条。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"一个银色的机器人。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"一辆蓝色的玩具车。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"一个可爱的洋娃娃。卡通风格。"}
+Reply target of current user message (untrusted, for context):
+```json
+{
+ "body": "[message_id=om_x100b6d9634993084b176d88168a081b] \n---#### 第一套题(知识点:learn, blackboard, English, ruler, playground)---##### 题目1【听力文本】\nLily: The children learn to read in class.\n\n【图片描述】\n选项A: 三个孩子坐在教室课桌前,每人拿着笔在本子上写字。卡通风格。\n选项B: 三个孩子坐在教室课桌前,每人捧着一本书在读书。卡通风格。\n选项C: 三个孩子坐在教室课桌前,每人拿着画笔在纸上画画。卡通风格。\n\n【能力项】\n基础语境理解|动作识别\n\n【题目】\nWhich one is Lily talking about?\n\n【答案】\nB\n\n【解析】\n听力原文为\"The children learn to read in class.\",关键词是read(读书)。三张图中孩子们都在教室里,选项A是写字(动作不匹配),选项B是读书(动作匹配),选项C是画画(动作不匹配)。只有B与\"read\"匹配。---##### 题目2【听力文本】\nLily: The teacher writes on the blackboard.\n\n【图片描述】\n选项A: 一位女老师站在黑板前,右手拿粉笔在黑板上画画。卡通风格。\n选项B: 一位女老师坐在椅子上,手里捧着一本书在看。卡通风格。\n选项C: 一位女老师站在黑板前,右手拿粉笔在黑板上写字。卡通风格。\n\n【能力项】\n基础语境理解|动作识别\n\n【题目】\nWhich one is Lily talking about?\n\n【答案】\nC\n\n【解析】\n听力原文为\"The teacher writes on the blackboard.\",关键词是writes on the blackboard(在黑板上写字)。三张图中都是同一位女老师,选项A是在黑板上画画(动作不匹配),选项B是在看书(动作不匹配),选项C是在黑板上写字(动作匹配)。只有C与\"writes on the blackboard\"匹配。---##### 题目3【听力文本】\nLily: The boy reads an English book.\n\n【图片描述】\n选项A: 一个男孩坐在书桌前,双手捧着一本英语书在认真阅读。卡通风格。\n选项B: 一个男孩坐在书桌前,拿着笔在本子上写英语单词。卡通风格。\n选项C: 一个男孩坐在书桌前,拿着画笔在纸上画画。卡通风格。\n\n【能力项】\n基础语境理解|动作识别\n\n【题目】\nWhich one is Lily talking about?\n\n【答案】\nA\n\n【解析】\n听力原文为\"The boy reads an English book.\",关键词是reads an English book(读英语书)。三张图中都是同一个男孩坐在书桌前,选项A是读英语书(动作匹配),选项B是写英语单词(动作不匹配),选项C是画画(动作不匹配)。只有A与\"reads an English book\"匹配。---##### 题目4【听力文本】\nLily: The boy draws a line with his ruler.\n\n【图片描述】\n选项A: 一个男孩坐在书桌前,右手拿铅笔在本子上写字。卡通风格。\n选项B: 一个男孩坐在书桌前,左手按住尺子,右手拿铅笔沿着尺子画一条直线。卡通风格。\n选项C: 一个男孩坐在书桌前,双手捧着一本书在阅读。卡通风格。\n\n【能力项】\n基础语境理解|动作识别\n\n【题目】\nWhich one is Lily talking about?\n\n【答案】\nB\n\n【解析】\n听力原文为\"The boy draws a line with his ruler.\",关键词是draws a line with his ruler(用尺子画线)。三张图中都是同一个男孩坐在书桌前,选项A是写字(动作不匹配),选项B是用尺子画线(动作匹配),选项C是读书(动作不匹配)。只有B与\"draws a line with his ruler\"匹配。---##### 题目5【听力文本】\nLily: The children play on the playground.\n\n【图片描述】\n选项A: 三个孩子在操场上开心地玩耍,有的在跑有的在跳。卡通风格。\n选项B: 三个孩子在操场跑道上并排跑步。卡通风格。\n选项C: 三个孩子坐在操场边的长凳上聊天。卡通风格。\n\n【能力项】\n基础语境理解|动作识别\n\n【题目】\nWhich one is Lily talking about?\n\n【答案】\nA\n\n【解析】\n听力原文为\"The childre…[truncated]"
+}
+```
+assistant: # 第一套题
+
+[1-A-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人拿着笔在本子上写字。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人捧着一本书在读书。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人拿着画笔在纸上画画。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一位女老师站在黑板前,右手拿粉笔在黑板上画画。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一位女老师坐在椅子上,手里捧着一本书在看。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一位女老师站在黑板前,右手拿粉笔在黑板上写字。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个男孩坐在书桌前,双手捧着一本英语书在认真阅读。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一个男孩坐在书桌前,拿着笔在本子上写英语单词。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个男孩坐在书桌前,拿着画笔在纸上画画。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个男孩坐在书桌前,右手拿铅笔在本子上写字。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个男孩坐在书桌前,左手按住尺子,右手拿铅笔沿着尺子画一条直线。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一个男孩坐在书桌前,双手捧着一本书在阅读。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"三个孩子在操场上开心地玩耍,有的在跑有的在跳。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"三个孩子在操场跑道上并排跑步。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"三个孩子坐在操场边的长凳上聊天。卡通风格。"}
+
+---
+
+# 第二套题
+
+[1-A-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,右手拿笔在本子上写字。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,拿着画笔在纸上画画。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,双手捧着一本书在阅读。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上画一条直线。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上写字。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿画笔在纸上涂色。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿画笔在纸上画一朵花。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上写自己的名字。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿着一支黄色铅笔在纸上画画。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿着一支黄色铅笔在本子上写字。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"三个孩子围坐在桌前,一起看一本中文书。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"三个孩子围坐在桌前,每人拿笔在本子上写中文字。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"三个孩子站在一起,张嘴唱歌。卡通风格。"}
+user: 返回给我
+Reply target of current user message (untrusted, for context):
+```json
+{
+ "body": "[message_id=om_x100b6d96da60b4bcc38f4e5184153f0] 武钰涵: 两套题的生图prompt 按照以下形式分别返回给我\n[1-A-选项图彩图]:{\"prompt\":\"一份金黄的炸薯条。卡通风格。\"}\n[1-B-选项图彩图]:{\"prompt\":\"一个牛肉汉堡包。卡通风格。\"}\n[1-C-选项图彩图]:{\"prompt\":\"一个棕色的椰子。卡通风格。\"}\n[2-A-选项图彩图]:{\"prompt\":\"一个男孩在河边钓鱼。卡通风格。\"}\n[2-B-选项图彩图]:{\"prompt\":\"一个男孩在操场跑步。卡通风格。\"}\n[2-C-选项图彩图]:{\"prompt\":\"一个男孩在桌边画画。卡通风格。\"}\n[3-A-选项图彩图]:{\"prompt\":\"一个牛肉汉堡包。卡通风格。\"}\n[3-B-选项图彩图]:{\"prompt\":\"一份金黄的炸薯条。卡通风格。\"}\n[3-C-选项图彩图]:{\"prompt\":\"一个棕色的椰子。卡通风格。\"}\n[4-A-选项图彩图]:{\"prompt\":\"一个棕色的椰子。卡通风格。\"}\n[4-B-选项图彩图]:{\"prompt\":\"一个牛肉汉堡包。卡通风格。\"}\n[4-C-选项图彩图]:{\"prompt\":\"一份金黄的炸薯条。卡通风格。\"}\n[5-A-选项图彩图]:{\"prompt\":\"一个银色的机器人。卡通风格。\"}\n[5-B-选项图彩图]:{\"prompt\":\"一辆蓝色的玩具车。卡通风格。\"}\n[5-C-选项图彩图]:{\"prompt\":\"一个可爱的洋娃娃。卡通风格。\"}"
+}
+```
+assistant: # 第一套题
+
+[1-A-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人拿着笔在本子上写字。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人捧着一本书在读书。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人拿着画笔在纸上画画。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一位女老师站在黑板前,右手拿粉笔在黑板上画画。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一位女老师坐在椅子上,手里捧着一本书在看。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一位女老师站在黑板前,右手拿粉笔在黑板上写字。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个男孩坐在书桌前,双手捧着一本英语书在认真阅读。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一个男孩坐在书桌前,拿着笔在本子上写英语单词。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个男孩坐在书桌前,拿着画笔在纸上画画。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个男孩坐在书桌前,右手拿铅笔在本子上写字。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个男孩坐在书桌前,左手按住尺子,右手拿铅笔沿着尺子画一条直线。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一个男孩坐在书桌前,双手捧着一本书在阅读。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"三个孩子在操场上开心地玩耍,有的在跑有的在跳。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"三个孩子在操场跑道上并排跑步。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"三个孩子坐在操场边的长凳上聊天。卡通风格。"}
+
+# 第二套题
+
+[1-A-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,右手拿笔在本子上写字。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,拿着画笔在纸上画画。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,双手捧着一本书在阅读。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上画一条直线。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上写字。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿画笔在纸上涂色。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿画笔在纸上画一朵花。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上写自己的名字。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿着一支黄色铅笔在纸上画画。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿着一支黄色铅笔在本子上写字。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"三个孩子围坐在桌前,一起看一本中文书。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"三个孩子围坐在桌前,每人拿笔在本子上写中文字。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"三个孩子站在一起,张嘴唱歌。卡通风格。"}
+user: 我看不到你的prompt
+assistant: # 第一套题
+
+[1-A-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人拿着笔在本子上写字。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人捧着一本书在读书。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人拿着画笔在纸上画画。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一位女老师站在黑板前,右手拿粉笔在黑板上画画。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一位女老师坐在椅子上,手里捧着一本书在看。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一位女老师站在黑板前,右手拿粉笔在黑板上写字。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个男孩坐在书桌前,双手捧着一本英语书在认真阅读。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一个男孩坐在书桌前,拿着笔在本子上写英语单词。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个男孩坐在书桌前,拿着画笔在纸上画画。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个男孩坐在书桌前,右手拿铅笔在本子上写字。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个男孩坐在书桌前,左手按住尺子,右手拿铅笔沿着尺子画一条直线。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一个男孩坐在书桌前,双手捧着一本书在阅读。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"三个孩子在操场上开心地玩耍,有的在跑有的在跳。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"三个孩子在操场跑道上并排跑步。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"三个孩子坐在操场边的长凳上聊天。卡通风格。"}
+
+# 第二套题
+
+[1-A-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,右手拿笔在本子上写字。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,拿着画笔在纸上画画。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,双手捧着一本书在阅读。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上画一条直线。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上写字。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿画笔在纸上涂色。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿画笔在纸上画一朵花。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上写自己的名字。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿着一支黄色铅笔在纸上画画。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿着一支黄色铅笔在本子上写字。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"三个孩子围坐在桌前,一起看一本中文书。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"三个孩子围坐在桌前,每人拿笔在本子上写中文字。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"三个孩子站在一起,张嘴唱歌。卡通风格。"}
+user: 请以纯文本的形式发给我
+assistant: # 第一套题
+
+[1-A-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人拿着笔在本子上写字。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人捧着一本书在读书。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"三个孩子坐在教室课桌前,每人拿着画笔在纸上画画。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一位女老师站在黑板前,右手拿粉笔在黑板上画画。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一位女老师坐在椅子上,手里捧着一本书在看。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一位女老师站在黑板前,右手拿粉笔在黑板上写字。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个男孩坐在书桌前,双手捧着一本英语书在认真阅读。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一个男孩坐在书桌前,拿着笔在本子上写英语单词。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个男孩坐在书桌前,拿着画笔在纸上画画。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个男孩坐在书桌前,右手拿铅笔在本子上写字。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个男孩坐在书桌前,左手按住尺子,右手拿铅笔沿着尺子画一条直线。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一个男孩坐在书桌前,双手捧着一本书在阅读。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"三个孩子在操场上开心地玩耍,有的在跑有的在跳。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"三个孩子在操场跑道上并排跑步。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"三个孩子坐在操场边的长凳上聊天。卡通风格。"}
+
+# 第二套题
+
+[1-A-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,右手拿笔在本子上写字。卡通风格。"}
+[1-B-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,拿着画笔在纸上画画。卡通风格。"}
+[1-C-选项图彩图]:{"prompt":"一个女孩坐在学校教室的课桌前,双手捧着一本书在阅读。卡通风格。"}
+[2-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上画一条直线。卡通风格。"}
+[2-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上写字。卡通风格。"}
+[2-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿画笔在纸上涂色。卡通风格。"}
+[3-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿画笔在纸上画一朵花。卡通风格。"}
+[3-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿铅笔在纸上写自己的名字。卡通风格。"}
+[3-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。"}
+[4-A-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿着一支黄色铅笔在纸上画画。卡通风格。"}
+[4-B-选项图彩图]:{"prompt":"一个男孩坐在桌前,双手捧着一本书在阅读。卡通风格。"}
+[4-C-选项图彩图]:{"prompt":"一个男孩坐在桌前,右手拿着一支黄色铅笔在本子上写字。卡通风格。"}
+[5-A-选项图彩图]:{"prompt":"三个孩子围坐在桌前,一起看一本中文书。卡通风格。"}
+[5-B-选项图彩图]:{"prompt":"三个孩子围坐在桌前,每人拿笔在本子上写中文字。卡通风格。"}
+[5-C-选项图彩图]:{"prompt":"三个孩子站在一起,张嘴唱歌。卡通风格。"}
diff --git a/memory/2026-06-11-1226.md b/memory/2026-06-11-1226.md
new file mode 100644
index 0000000..fcd08f5
--- /dev/null
+++ b/memory/2026-06-11-1226.md
@@ -0,0 +1,34 @@
+# Session: 2026-06-11 12:26:54 GMT+8
+
+- **Session Key**: agent:xiaoyan:feishu:direct:ou_8b79b7f711e42a4004f3f3c225a1a99c
+- **Session ID**: 7135746c-57dd-4683-913d-2fd79100bdb9
+- **Source**: feishu
+
+## Conversation Summary
+
+user: https://makee-interactive.feishu.cn/wiki/O7RwwMei6iQCFlk6cHocDqGpn9b 组件配置
+assistant: 张昆鹏,开始处理组件配置。
+
+
+assistant: 📝 组件配置完成!**L1-S2-U21-L2 运输小队**,16/16 全部成功:
+
+| # | cId | 类型 | cType |
+|---|------|------|-------|
+| 1 | 1221201 | 对话朗读 | mid_dialog_repeat |
+| 2 | 1221202 | 图片单选 | mid_image_choose |
+| 3 | 1221203 | 对话挖空 | mid_dialog_fillin |
+| 4 | 1221204 | 对话朗读 | mid_dialog_repeat |
+| 5 | 1221205 | 对话朗读 | mid_dialog_repeat |
+| 6 | 1221206 | 图片单选 | mid_image_choose |
+| 7 | 1221207 | 对话朗读 | mid_dialog_repeat |
+| 8 | 1221208 | 图片单选 | mid_image_choose |
+| 9 | 1221209 | 对话朗读 | mid_dialog_repeat |
+| 10 | 1221210 | 对话朗读 | mid_dialog_repeat |
+| 11 | 1221211 | 对话挖空 | mid_dialog_fillin |
+| 12 | 1221212 | 对话选读 | mid_dialog_select |
+| 13 | 1221213 | 看图拼词 | core_writing_imgMakeWord |
+| 14 | 1221214 | 对话挖空 | mid_dialog_fillin |
+| 15 | 1221215 | 图片拖拽 | mid_image_drag |
+| 16 | 1221216 | 对话表达 | mid_dialog_express |
+
+HTML 报告已通过飞书 Bot 发送给你,打开后可查看详情并一键推送配置到远程数据库。