Skip to content

Puzzle 谜题对象规范

Puzzle 是 HeurAMS 中用于生成具体复习题目的对象. 它将记忆内容转化为可交互的练习题目, 支持多种题型和自定义配置.

谜题类型概览

HeurAMS 目前支持三种谜题类型:

类型类名描述适用场景
MCQMCQPuzzle多项选择题含义选择、语法判断、概念区分
ClozeClozePuzzle填空题(完形填空)句子补全、单词填空、短语填空
RecognitionRecognitionPuzzle识别题(占位符)单词识别、概念识别、简单回忆

通用接口

所有谜题类型都继承自 BasePuzzle 基类, 实现以下接口:

python
class BasePuzzle:
    def refresh(self) -> None:
        """刷新谜题, 生成新的题目"""
        raise NotImplementedError
    
    def __str__(self) -> str:
        """返回谜题的字符串表示"""
        return f"谜题: {type(self).__name__}"

公共属性

每个谜题实例都有以下公共属性:

属性类型描述
wordingUnion[str, List[str]]题目文本
answerUnion[str, List[str]]正确答案
optionsList[List[str]]选项列表(仅 MCQ)

MCQ(选择题)

类定义

python
class MCQPuzzle(BasePuzzle):
    def __init__(
        self,
        mapping: Dict[str, str],
        jammer: List[str],
        max_riddles_num: int = 2,
        prefix: str = "",
    ) -> None:

构造函数参数

参数类型必需默认值描述
mappingDict[str, str]-问题到正确答案的映射字典
jammerList[str]-干扰项列表
max_riddles_numint2最大题目数量(范围 1-5)
prefixstr""题目前缀文本

配置示例(TOML)

在 Orbital 中配置 MCQ:

toml
"VocabularyQuiz" = {
  __origin__ = "mcq",
  __hint__ = "选择单词的正确含义",
  mapping = "eval:nucleon['word_meaning_pairs']",
  jammer = "eval:nucleon['distractor_words']",
  max_riddles_num = "eval:default['mcq']['max_riddles_num']",
  prefix = "词汇测试: "
}

谜题生成逻辑

  1. 题目选择:从 mapping 中随机选择 max_riddles_num 个问题
  2. 选项生成:为每个问题生成 4 个选项(1 个正确答案 + 3 个干扰项)
  3. 干扰项来源:从 jammer 列表中选取, 排除正确答案
  4. 选项随机化:打乱选项顺序
  5. 格式输出:添加前缀和编号

示例输出

词汇测试:
  1. "Ubiquitous" 的含义是?
  A) 稀有的
  B) 普通的  
  C) 无处不在的 ✓
  D) 暂时的

  2. "Ephemeral" 的含义是?
  A) 短暂的 ✓
  B) 永恒的
  C) 复杂的
  D) 简单的

额外方法

方法返回类型描述
get_question_count()int获取当前题目数量
get_correct_answer_for_question(question_index)Optional[str]获取指定题目的正确答案
get_options_for_question(question_index)Optional[List[str]]获取指定题目的选项列表

Cloze(填空题)

类定义

python
class ClozePuzzle(BasePuzzle):
    def __init__(self, text: str, min_denominator: int, delimiter: str = "/") -> None:

构造函数参数

参数类型必需默认值描述
textstr-原始文本(用分隔符分割)
min_denominatorint-最小概率倒数(控制填空密度)
delimiterstr"/"文本分隔符

配置示例(TOML)

在 Orbital 中配置 Cloze:

toml
"SentenceCompletion" = {
  __origin__ = "cloze",
  __hint__ = "完成句子填空",
  text = "eval:nucleon['sentence']",
  delimiter = "eval:metadata['formation']['delimiter']",
  min_denominator = "eval:default['cloze']['min_denominator']"
}

谜题生成逻辑

  1. 文本分割:使用 delimiter 将文本分割成单词/短语列表
  2. 填空数量计算填空数 = max(1, 总词数 // min_denominator)
  3. 填空位置选择:随机选择填空位置
  4. 答案记录:记录被替换的原始内容
  5. 填空生成:用下划线替换选中位置的内容

示例输出

原始文本: "The/quick/brown/fox/jumps/over/the/lazy/dog/"
生成填空: "The quick brown ______ jumps over the ______ dog"
正确答案: ["fox", "lazy"]

参数说明

  • min_denominator:控制填空密度

    • 值 = 2:大约 1/2 的内容会被填空
    • 值 = 5:大约 1/5 的内容会被填空
    • 值 ≥ 总词数:只填空 1 个位置
  • delimiter:文本分隔符

    • 常用:"/"" "(空格)、"|"
    • 确保文本末尾也有分隔符

Recognition(识别题)

类定义

python
class RecognitionPuzzle(BasePuzzle):
    def __init__(self) -> None:

配置示例(TOML)

在 Orbital 中配置 Recognition:

toml
"WordRecognition" = {
  __origin__ = "recognition",
  __hint__ = "",
  primary = "eval:nucleon['word']",
  secondary = ["eval:nucleon['definition']", "eval:nucleon['example']"],
  top_dim = ["eval:nucleon['translation']"]
}

参数说明

参数类型必需描述
primarystr主要识别内容
secondaryList[str]次要识别内容列表
top_dimList[str]顶部维度内容列表

谜题生成逻辑

Recognition 是占位符谜题, 当前版本仅用于内容展示, 不生成交互式题目.

使用场景

  1. 单词识别:显示单词, 要求回忆含义
  2. 概念识别:显示概念, 要求回忆定义
  3. 简单回忆:显示提示, 要求回忆完整内容

谜题生命周期

1. 配置解析

从 Orbital 配置中解析参数, 创建谜题实例.

python
# 伪代码示例
puzzle_config = orbital["puzzles"]["VocabularyQuiz"]
if puzzle_config["__origin__"] == "mcq":
    puzzle = MCQPuzzle(
        mapping=parse_macro(puzzle_config["mapping"], nucleon),
        jammer=parse_macro(puzzle_config["jammer"], nucleon),
        max_riddles_num=int(parse_macro(puzzle_config["max_riddles_num"], nucleon)),
        prefix=parse_macro(puzzle_config["prefix"], nucleon)
    )

2. 谜题刷新

调用 refresh() 方法生成新题目.

python
puzzle.refresh()  # 生成新的题目和答案

3. 题目展示

通过 wording 属性获取题目文本.

python
question_text = puzzle.wording
if isinstance(question_text, list):
    for i, q in enumerate(question_text):
        print(f"{i+1}. {q}")
else:
    print(question_text)

4. 答案验证

通过 answer 属性验证用户回答.

python
user_answer = get_user_input()
correct_answer = puzzle.answer
if isinstance(correct_answer, list):
    is_correct = user_answer in correct_answer
else:
    is_correct = user_answer == correct_answer

宏表达式支持

谜题配置支持宏表达式, 用于动态生成内容.

常用宏模式

  1. 直接引用 Nucleon 字段

    toml
    text = "eval:nucleon['sentence']"
  2. 处理嵌套结构

    toml
    mapping = "eval:{pair.split(':')[0]: pair.split(':')[1] for pair in nucleon['word_pairs'].split(';')}"
  3. 数组处理

    toml
    jammer = "eval:nucleon['distractors'].split(',')"
  4. 条件逻辑

    toml
    text = "eval:nucleon.get('sentence_en', nucleon.get('sentence', ''))"

宏执行上下文

变量类型可用字段
nucleonNucleonNucleon 的所有字段
metadatadict[__metadata__] 内容
defaultdict系统默认配置

自定义谜题开发

创建新谜题类型

  1. 继承 BasePuzzle 基类
  2. 实现 refresh() 方法
  3. 定义构造函数参数
  4. 注册到谜题注册器(如果支持)
python
from heurams.kernel.puzzles.base import BasePuzzle

class NewPuzzle(BasePuzzle):
    def __init__(self, param1: str, param2: int):
        self.param1 = param1
        self.param2 = param2
        self.wording = "新谜题 - 尚未刷新"
        self.answer = ["未设置"]
    
    def refresh(self):
        # 生成新题目的逻辑
        self.wording = f"问题: {self.param1}"
        self.answer = [f"答案: {self.param2}"]

配置集成

在 Orbital 配置中添加新类型:

toml
"CustomPuzzle" = {
  __origin__ = "newpuzzle",  # 需要注册的标识符
  __hint__ = "自定义谜题",
  param1 = "eval:nucleon['content']",
  param2 = "eval:42"
}

最佳实践

1. 谜题设计原则

  • 难度适中:避免过于简单或复杂的题目
  • 多样性:混合使用不同谜题类型
  • 相关性:谜题内容与学习目标紧密相关
  • 反馈明确:提供清晰的正确答案和解释

2. 参数调优建议

  • MCQmax_riddles_num 建议 2-3, 避免认知负荷
  • Clozemin_denominator 建议 3-5, 平衡挑战性和完成度
  • 干扰项:确保与正确答案相似但可区分

3. 性能考虑

  • 预生成:可以在后台提前生成谜题
  • 缓存:对相同内容缓存生成的谜题
  • 懒加载:需要时才调用 refresh()

版本历史

  • v1 (当前版本):支持三种谜题类型, 宏表达式系统
  • v0:基础谜题框架(已弃用)

相关文档