ad8d2f0739
Co-Authored-By: Claude Code <noreply@anthropic.com>
9.8 KiB
9.8 KiB
name, description
| name | description |
|---|---|
| exam | CS 知识应试强化 — 题目生成 Skill。 从 examination 仓库生成符合 JSON Schema 的题目文件,自动校验、合并、更新元数据,推送到远程。 当用户提到生成题目、考试题、练习题、CS 知识题、选择题、填空题、判断题时,使用此 skill。 |
CS 知识应试强化 — 题目生成 Skill
从 examination 仓库生成符合 JSON Schema 的题目文件,自动校验、合并、更新元数据,推送到远程。
前置条件
- Python 3.8+(用于校验和合并脚本)
- SSH 访问
git@47.121.181.112:222(用于 clone/push) topics/index.json包含子主题索引
仓库结构
examination/
├── schema/
│ ├── question.schema.json # 题目 JSON Schema (Draft-07)
│ ├── prompt-template.md # 题目生成提示词模板
│ └── templates/ # 各题型示例 JSON
├── topics/
│ ├── index.json # 主题索引
│ └── {group}/{subtopic}/
│ ├── meta.json # 子主题元信息
│ ├── fill_blank.json # 填空题
│ └── single_choice.json # 单选题
└── exam/ # 本 skill 目录
├── SKILL.md
├── schema/
│ └── question.schema.json
└── scripts/
├── validate.py
├── validate.mjs
├── merge_questions.py
├── update_meta.py
├── read_context.json
└── validate_and_merge.json
执行流程
重要:默认使用子代理(SubAgent)分批次处理。 生成题目是 token 密集型任务,为避免主会话上下文爆炸,应将每批题目的生成工作委派给子代理执行。主会话负责规划、确认和汇总。
阶段 0:与用户确认方案
在执行任何操作之前,必须先与用户确认以下信息。 不要假设默认值。
- 子主题(subtopic):读取仓库中的
topics/index.json,列出可用的子主题供用户选择。如果用户已经指定了子主题,验证其是否存在。 - 题型与数量:询问用户需要生成哪些题型、每种多少道。可以一次性给出建议(如「建议先生成 10 道单选题 + 5 道判断题」),但最终必须等用户确认。
- 展示确认摘要:在开始生成前,向用户展示如下摘要并等待确认:
📋 生成方案确认
━━━━━━━━━━━━━━
子主题:gc-jvm(JVM 垃圾回收)
分组: qunar-ai-fullstack
题型: 单选 × 10、判断 × 5
━━━━━━━━━━━━━━
确认后开始生成 ✅
用户确认后才进入下一阶段。
阶段 1:克隆仓库
REPO_DIR=$(mktemp -d)
git clone --depth 1 ssh://git@47.121.181.112:222/wonder/examination.git "$REPO_DIR"
阶段 2:读取上下文(子代理)
派发一个子代理,执行以下任务:
- 读取
topics/index.json确认子主题存在 - 读取该子主题的
meta.json(获取 tags、已有题目信息) - 读取同类型已有的题目文件(获取已有 ID,避免重复)
- 将汇总信息返回给主会话
使用本 skill 自带的批量脚本 scripts/read_context.json 可以一次完成上述读取:
run_tool_batch(
file_path="<skill_dir>/scripts/read_context.json",
args={
"topics_dir": "<REPO_DIR>/topics",
"group": "<用户确认的分组>",
"subtopic": "<用户确认的子主题>",
"question_type": "<用户确认的题型>"
}
)
阶段 3:生成题目(子代理)
这是 token 消耗最大的阶段,务必使用子代理处理。
根据阶段 2 返回的上下文,为每种题型分别派发子代理来生成题目。每个子代理的任务是:
- 根据子主题内容和已有题目,生成指定数量的新题目
- 严格遵循 Schema 格式(见下方「题目格式规范」)
- 将生成的 JSON 写入临时文件(如
/tmp/exam_gen_{type}_{batch}.json)
子代理提示词模板:
你是题目生成专家。请为子主题 "{subtopic_name}" 生成 {count} 道 {type_name} 题。
【上下文】
{从阶段 2 获取的 meta.json 和已有题目摘要}
【要求】
- 严格遵循 JSON Schema(见下方规范)
- ID 从 {next_id} 开始递增(如 fb-001, fb-002...)
- 难度分布在 1-5 之间,合理分布
- tags 参考子主题已有的 tags
- explanation 必须详细,解释为什么对/错
- source 填 null,related 填空数组
【输出】
将完整 JSON 写入文件 /tmp/exam_gen_{type}_{batch}.json,格式:
{
"topic": "{subtopic_slug}",
"type": "{question_type}",
"schema_version": "1.0.0",
"generated": "{ISO 8601 时间戳}",
"questions": [ ... ]
}
如果题目数量较多(如 > 15 道),建议拆分成多个批次,每批 5-10 道,分别派发子代理并行处理。
阶段 4:校验、合并、更新元数据(子代理)
所有批次的题目生成完成后,派发子代理执行校验与合并:
run_tool_batch(
file_path="<skill_dir>/scripts/validate_and_merge.json",
args={
"skill_dir": "<skill_dir>",
"topics_dir": "<REPO_DIR>/topics",
"group": "<group>",
"subtopic": "<subtopic>",
"question_type": "<question_type>",
"generated_file": "/tmp/exam_gen_{type}_{batch}.json"
}
)
如果是多批次生成,需要对每个批次依次执行合并,或者先合并各批次为一个临时文件,再统一合并到已有文件。
阶段 5:提交推送
cd "$REPO_DIR"
git add -A
git commit -m "feat: add {count} {type} questions for {subtopic}"
git push origin main
阶段 6:汇报结果
向用户展示生成结果摘要:
✅ 题目生成完成
━━━━━━━━━━━━━━━━━━━━━━
子主题:gc-jvm
新增: 单选 × 10、判断 × 5
累计: 35 题(单选 20、判断 10、填空 5)
提交: feat: add 15 questions for gc-jvm
━━━━━━━━━━━━━━━━━━━━━━
批量脚本参数
read_context.json
| 参数 | 说明 | 示例 |
|---|---|---|
topics_dir |
仓库内 topics/ 目录的绝对路径 |
/tmp/xxxxx/topics |
group |
主题分组名 | qunar-ai-fullstack |
subtopic |
子主题 slug | gc-jvm |
question_type |
题型 | single_choice |
validate_and_merge.json
| 参数 | 说明 | 示例 |
|---|---|---|
skill_dir |
本 skill 目录的绝对路径 | /home/.../skills/exam |
topics_dir |
同上 | 同上 |
group |
同上 | 同上 |
subtopic |
同上 | 同上 |
question_type |
同上 | 同上 |
generated_file |
生成的题目 JSON 文件绝对路径 | /tmp/exam_gen_sc_1.json |
批量执行失败处理
如果批量脚本执行失败:
- 首先检查所有参数是否正确传入,尤其是
args不能为空 - 根据错误信息修正参数后重试
- 如果脚本方式持续失败,回退到手动逐步执行(见下方「手动执行参考」)
- 完成任务后告知用户:「批量执行遇到了问题,已手动完成。是否需要调整 skill 的批量脚本以便下次正常使用?」
手动执行参考
读取上下文
cat "$REPO_DIR/topics/index.json"
cat "$REPO_DIR/topics/{group}/{subtopic}/meta.json"
cat "$REPO_DIR/topics/{group}/{subtopic}/{type}.json" # 如果存在
校验
python3 <skill_dir>/scripts/validate.py /tmp/exam_generated.json
合并
python3 <skill_dir>/scripts/merge_questions.py \
"$REPO_DIR/topics/{group}/{subtopic}/{type}.json" \
/tmp/exam_generated.json \
/tmp/exam_merged.json
cp /tmp/exam_merged.json "$REPO_DIR/topics/{group}/{subtopic}/{type}.json"
更新元数据
python3 <skill_dir>/scripts/update_meta.py \
"$REPO_DIR/topics" {group} {subtopic} {type}
题目格式规范
ID 格式:{type_short}-{seq},序号从已有最大值 +1 开始,三位数补零。
| 题型 | type | type_short | 关键字段 |
|---|---|---|---|
| 填空 | fill_blank |
fb |
answer: string[], answer_rule: "any"/"all"/"ordered" |
| 单选 | single_choice |
sc |
options: {A-D}, answer: string |
| 多选 | multiple_choice |
mc |
options: {A-D}, answer: string[] |
| 判断 | true_false |
tf |
answer: boolean |
| 简答 | short_answer |
sa |
answer: string, keywords: string[], scoring_rubric: string |
| 代码阅读 | code_reading |
cr |
code, language, sub_questions[] |
| 场景分析 | scenario |
sn |
context, sub_questions[] |
通用字段
每道题必须包含:
id— 唯一标识,格式type_short-NNNtype— 题型枚举值difficulty— 1 到 5 的整数tags— 标签数组,参考子主题 meta.jsonquestion— 题目文本explanation— 详细解析source— 填nullrelated— 填空数组[]
sub_questions 规范
code_reading 和 scenario 题型使用 sub_questions 数组,每个子问题需要:
index— 从 1 开始的序号type— 子问题的题型(通常是single_choice或short_answer)question— 子问题文本answer— 答案explanation— 解析- 选择题类子问题还需
options字段
备注
- 校验脚本优先使用
jsonschema库(Python),不可用时回退到基础校验 - Node.js 校验脚本(
validate.mjs)为纯内置模块,无外部依赖,可作为备选 - 合并脚本自动去重(基于 question ID),不会覆盖已有题目
- 元数据更新脚本自动计算
question_files和stats.by_type统计信息 - 所有脚本退出码:0=成功,1=有错误,2=用法错误
- Schema 文件已内置于
<skill_dir>/schema/question.schema.json,与仓库版本一致