通用试卷生成技能。支持任意年级、科目、考试类型的模拟试卷生成。 当用户提到出题、模拟卷、期中/期末考试、单元测试、试卷生成时触发。
目标:在给定科目/年级/考试范围的前提下,生成结构与分值严格匹配、答案唯一、难度梯度合理的模拟试卷。
当用户未指定"题型结构/分值"时:
web_search 搜索关键词(示例):
"{地区}" "{年级}" "{学期}" "{科目}" 期末 试卷 题型 分值"{年级}" "{科目}" 模拟卷 题型结构 选择题 填空题 解答题 分值原则:宁可多问一句,也不凭空编结构。结构错误会导致整卷不可用。
每次生成试卷前,必须完成"三查":
"{地区} {年级} {学期} 数学 考试范围 教学进度"references/ 目录下已有该科目该年级的参考资料文件,优先读取,不必重新搜索"{教材版本} {册次} 目录 知识点""{年份} {地区} {年级} {学期} {科目} 期末/模拟 试卷"gaokao/下载试卷/ 目录下有相关真题PDF,用 pdfplumber 提取文本skills/exam-gen/references/{年级}_{学期}_{科目}_参考资料.md用三个不同模型各自独立生成一份完整试卷(题目+答案+解析):
| 子代理 | 推荐模型 | 说明 |
|---|---|---|
| 卷A | openai/gpt-5.2 | 擅长长内容生成 |
| 卷B | github-copilot/claude-opus-4.5 | 推理严谨 |
| 卷C | github-copilot/claude-opus-4.6 | 综合能力强 |
每个子代理的 prompt 必须包含(完整约束列表):
收齐三份试卷后,进行逐题交叉质询。这不是简单的"挑最好的",而是层层追问式的深度审查。
第1轮:结构核验
第2轮:逐题答案比对 对每道题,比对三份的答案:
分歧: 卷A和卷C答案为B,卷B答案为D
Why 1: 卷B的解题过程哪一步和A/C不同?
→ 定位具体分歧步骤
Why 2: 该步骤的推导是否正确?代入验算
→ 确认谁对谁错
Why 3: 错误版本的题目本身是否有问题(条件不足/多解)?
→ 如果是题目问题,三份可能都不对
结论: 采纳正确版本,或修正题目后重新求解
Why 1: 三个不同答案分别是怎么得出的?
Why 2: 题目条件是否充分?是否存在多解?
Why 3: 如果题目有缺陷,能否微调条件使答案唯一?
结论: 修正题目 或 从备选题库替换
第3轮:硬伤扫描 检查每题是否存在以下致命问题:
第4轮:难度梯度审查
第5轮:最终组卷
推荐 spawn 一个审查子代理(用与生成不同的模型),给它:
{题号: {选用版本: A/B/C/修正, 问题: "...", 修正内容: "..."}}审查子代理完成后,再 spawn 一个组卷子代理,按审查结果拼装最终试卷。
整个流程中,主对话必须主动向用户汇报进度,不能让用户干等无反馈。
| 时机 | 汇报内容 |
|---|---|
| 任务启动 | "开始生成X科试卷,预计N分钟,流程:三路生成→交叉质询→组卷" |
| 每个子代理完成 | "卷A(GPT-5.2)已完成/卷B(Opus-4.5)已完成,还剩X个" |
| 交叉质询开始 | "三份试卷已收齐,开始交叉质询..." |
| 质询完成 | "质询完成,X题需修正/替换,开始组卷" |
| 最终交付 | "试卷已生成,文件路径:...,附质检摘要" |
规则:
试卷生成是长任务(三路生成+质询+组卷,通常15-30分钟),必须起cron定时追踪进度,避免主对话被阻塞、用户干等。
在spawn第一个子代理后,立即创建一个cron job:
cron add:
name: "exam-progress-{科目}"
schedule: { kind: "every", everyMs: 120000 } # 每2分钟
sessionTarget: "isolated"
payload:
kind: "agentTurn"
message: |
检查试卷生成进度。
用 sessions_list 查看以下label的子代理状态:
- {route-A-label}
- {route-B-label}
- {route-C-label}
- {review-label}(如已启动)
- {assemble-label}(如已启动)
对每个子代理:
1. 是否已完成?(看sessions_list的状态)
2. 如已完成,用sessions_history读最后一条消息,提取关键信息(结构是否合规、有无硬伤)
3. 如还在跑,报告已用时间
汇总后发飞书通知用户,格式:
📝 {科目}试卷生成进度
✅ 路A(GPT-5.2): 已完成,结构合规
⏳ 路B(Opus-4.5): 进行中(已2分钟)
⏳ 路C(Opus-4.6): 排队中
下一步: 等路B/C完成后启动交叉质询
如果全部子代理已完成且组卷也完成,发送最终通知并自行删除此cron job(cron remove)。
model: "github-copilot/gpt-4.1" # 轻量模型够用
timeoutSeconds: 60
delivery: { mode: "none" } # 由任务自己发飞书,不要announce
cron remove 删除自己生成试卷是长任务,必须主动向用户汇报进度:
不要让用户干等无反馈。 哪怕只是一句"第2路完成了,正在等第3路"也比沉默好。
试卷必须用LaTeX+TikZ生成,不要用Markdown。 Markdown无法嵌入图形,而真实试卷(尤其数学/物理/化学)必须有大量配图。
.tex 源文件 → xelatex 编译 → PDF/root/.openclaw/workspace/gaokao/LaTeX版/ 目录下有现成模板ctex 宏包处理中文tikz、pgfplots 画图geometry 控制页边距\newpage)\documentclass[12pt,a4paper]{article}
\usepackage[UTF8]{ctex}
\usepackage{geometry}
\usepackage{amsmath,amssymb,amsthm}
\usepackage{tikz,pgfplots}
\usepackage{enumitem}
\usepackage{fancyhdr}
\usetikzlibrary{calc,patterns,angles,quotes,arrows.meta,3d,positioning}
\pgfplotsset{compat=1.18}
\geometry{left=2.5cm,right=2.5cm,top=2.5cm,bottom=2.5cm}
% ... 题目内容 ...
% \newpage
% ... 参考答案与解析 ...
\end{document}
xelatex -interaction=nonstopmode 试卷.tex
# 如需交叉引用,跑第二遍
xelatex -interaction=nonstopmode 试卷.tex
LaTeX试卷通常600-1000行,子代理必须用分段写入法:
cat > file.tex << 'LATEX_EOF' 写前半部分(到填空题结束)cat >> file.tex << 'LATEX_EOF' 追加后半部分(解答题+答案+\end{document})只在明确不需要图形的场景(如语文作文、英语阅读理解纯文字部分)才用Markdown。即使用Markdown,也必须用pandoc+xelatex转PDF(不要用weasyprint)。
web_search 找近年真题或权威样卷的"结构与分值"/root/.openclaw/workspace/gaokao/LaTeX版/ 有成熟模板,子代理必须先读模板再出题,保持排版风格一致gaokao/下载试卷/),提取文本给子代理参考出题风格和难度,但不要抄题Markdown转PDF(支持LaTeX公式、中文):
pandoc 试卷.md -o 试卷.pdf \
--pdf-engine=xelatex \
-V CJKmainfont="Noto Sans CJK SC" \
-V geometry:margin=2cm \
-V geometry:a4paper \
-V fontsize=11pt \
-V linestretch=1.3 \
--columns=80
如果公式复杂,确保md文件中的LaTeX公式格式正确:
$...$$$...$$\( \) 或 \[ \],pandoc对$符号支持最好weasyprint是HTML/CSS引擎,不支持LaTeX数学公式渲染。之前尝试pandoc→html→weasyprint→pdf,所有$...$公式都显示为原始TeX文本,会出大量warning。
xelatex -interaction=nonstopmode 试卷.tex
# 如需交叉引用,跑第二遍
xelatex -interaction=nonstopmode 试卷.tex
在生成Markdown试卷时,公式格式必须统一:
# 正确示例
行内公式用单美元号:已知 $a_n = 2n - 1$,求 $S_n$。
独立公式用双美元号:
$$S_n = \frac{n(a_1 + a_n)}{2}$$
# 错误示例(pandoc不兼容)
行内公式用 \(a_n = 2n - 1\) ← 不要用
独立公式用 \[S_n = ...\] ← 不要用
子代理prompt中必须包含这条规则:"公式用 $...$ 和 $$...$$ 格式,不要用 \(\) 或 \[\]"