关于 masterytrace
masterytrace 是用于追踪学习者技能掌握情况的命令行工具和库,采用 BKT 与 2PL IRT 模型。其 MCP 服务通过一个通用工具,让 Agent 调用任意受支持的命令。
主要功能
- 01BKT 与 2PL IRT 评分
- 02支持 JSON 和 CSV 事件输入
- 03命令行输出机器可读数据
- 04生成学习者技能报告
- 05提供 TypeScript 和 Python 包
适用场景
- 01根据答题记录估算掌握度
- 02比较 BKT 与 IRT 评分
- 03生成学习进度报告
MCP 相关
MCP 服务提供一个 `run(args: list[str])` 工具,用于调用已安装的命令行程序并返回解析后的结果。它可执行任意受支持的子命令和选项。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
安装
MasteryTrace 提供两个独立且同等重要的一流软件包,它们实现相同的两种模型(BKT、2PL IRT),并遵循相同的 CLI 契约。
npm(TypeScript CLI + 库):
npm install -g masterytrace-cli
需要 Node.js 18 或更高版本。
pip(Python CLI + 库):python/ 中提供了一个完整且独立的 Python 版本,移植自本仓库的 TypeScript 源代码——包含相同的两种模型、相同的 CLI 契约、自带 75 个测试的 pytest 测试套件,并通过真实的 wheel 安装完成端到端构建和验证。
pip install masterytrace-cli
这会将相同的四个子命令(init、record、score、report)安装为 masterytrace 控制台脚本,并提供可导入的 masterytrace 库。这是本仓库 TypeScript 源代码真正独立的移植版本,而不是对 Node 二进制文件的封装。Python 专用用法请参阅 python/README.md。
说明
npm 和 pip 发行包返回等效的数据,但 JSON 键名大小写不同(TypeScript CLI 使用
camelCase,Python CLI 使用snake_case)。如果在同一条流水线中解析两者的输出,请注意这一点。
目录
功能
- 两种明确命名的心理测量模型,而非黑盒评分。 贝叶斯知识追踪会为每位学习者的每项技能输出后验掌握概率;2 参数逻辑 IRT 会为每位学习者输出连续的能力估计值(
theta),并为每项技能输出题目难度和区分度。可通过--model bkt|irt|both运行其中一种或同时运行两种模型。 - 两个独立且数值匹配的发行包。 npm 软件包(
masterytrace-cli,TypeScript)和 PyPI 软件包(masterytrace-cli,Python)是彼此逐行移植的真正独立版本,而不是对 Node 二进制文件的 Python 封装;本次审计使用两者处理了相同的 58 个事件样本,得到完全相同的掌握分数。 - 默认即可供 Agent 解析。 每条命令都接受全局
--json标志,report还支持--format markdown,并提供真正的三种退出码约定(0成功、1用法错误、2事件数据错误),而不是只有一个通用失败码。 - 162 个测试,语句/行/函数覆盖率达 100%。 包含 87 个 TypeScript 测试和 75 个 Python 测试,其中有一项合成数据 IRT 恢复测试:该测试使用已知真实参数拟合 4,000 条作答,得到的
theta、题目难度和区分度与真实值的差距均在 0.2 以内。 - 无需服务端,无需数据库。 状态保存在当前 CLI 运行目录下
.masterytrace/目录中的两个 JSON 文件里。在单核上为 100,000 条事件评分不到一秒。
快速开始
masterytrace init
masterytrace record events.json
masterytrace score
masterytrace report
init 会在当前目录中生成示例 events.json(包含 3 名学习者、3 项技能,每项有若干条回答)和默认的 masterytrace.config.json。该流程的实际输出:
$ masterytrace init
Created: events.json, masterytrace.config.json
Next: run 'masterytrace record events.json' to load it, then 'masterytrace score'.
$ masterytrace record events.json
Stored 58 event(s) to /path/to/.masterytrace/events.json
(record replaces any previously stored event log; see --help for details.)
$ masterytrace score
Scored 58 event(s) with model(s): both
Wrote /path/to/.masterytrace/scores.json
$ masterytrace report
learner skill model metric value responses
------------- --------------------- ----- ----------------------------- ------- ---------
learner-ada fractions bkt posterior_mastery_probability 0.9994 6
learner-ada fractions irt ability_theta 0.7349 6
learner-ada linear-equations bkt posterior_mastery_probability 0.9746 7
learner-brook fractions bkt posterior_mastery_probability 0.0612 6
learner-cyrus reading-comprehension bkt posterior_mastery_probability 0.9947 7
...
警告
masterytrace record总会替换此前存储的整个事件日志;没有追加模式。如果需要添加新回答且不丢失已有内容,请将它们合并到一个文件中,然后使用完整的合并日志重新运行record。
report 还接受 --format markdown 或 --format json,并且每条命令都接受全局 --json 标志,以便在 stdout 上输出机器可读的内容,同时提供实际的退出码约定(0 表示成功,1 表示一般错误或用法错误,2 表示事件数据错误),这样调用此 CLI 的脚本或 Agent 无需解析文本即可根据结果分支处理。
你自己的事件日志是一个由 { learnerId, skillId, correct, timestamp } 对象组成的 JSON 数组,或一个带有表头 learner_id,skill_id,correct,timestamp 的 CSV 文件。timestamp 必须为 ISO 8601 格式;correct 是布尔值(JSON),或 true/false/1/0(CSV)。CSV 的 correct 单元格中任何其他值都会被拒绝并产生验证错误,而不会被静默视为 false。超过 100 MB 的事件日志文件会被立即拒绝,并显示明确的错误;事件日志是小型结构化记录,没有正当理由接近这个大小。
CLI 命令参考
| 命令 | 参数 | 选项 | 功能 |
|---|---|---|---|
masterytrace init | --force | 在当前目录中生成示例 events.json 和 masterytrace.config.json。除非传入 --force,否则跳过已存在的文件。 | |
masterytrace record <path> | <path>:JSON 或 CSV 事件日志 | 验证事件日志并将其存储到 .masterytrace/events.json。总会替换此前存储的任何日志。 | |
masterytrace score | --model <bkt|irt|both>(默认 both) | 对存储的事件日志进行拟合和评分,并将结果写入 .masterytrace/scores.json。 | |
masterytrace report | --format <table|json|markdown>(默认 table) | 读取 .masterytrace/scores.json 并输出按学习者和技能划分的掌握度表。 |
全局选项:--json 强制任何命令在 stdout 上输出机器可读的 JSON,并覆盖 report 的 --format。
退出码:0 表示成功,1 表示一般错误或用法错误(无效标志、文件缺失),2 表示验证错误(事件日志本身格式错误)。

MCP 服务
MasteryTrace 附带一个 Model Context Protocol(MCP)服务,因此 Agent(Claude Desktop、Claude Code 或任何其他 MCP 客户端)可以直接调用 CLI,而不必自行通过 shell 执行命令。
使用 mcp extra 安装 Python 包:
pip install "masterytrace-cli[mcp]"
然后将 MCP 客户端指向 masterytrace-mcp 控制台脚本。Claude Desktop 配置示例(claude_desktop_config.json):
{
"mcpServers": {
"masterytrace": {
"command": "masterytrace-mcp"
}
}
}
该服务公开了一个工具 run(args: list[str]) -> dict,它会使用给定的参数列表调用已安装的 masterytrace CLI,并返回解析后的输出——CLI 支持的任何子命令或标志都可以通过它调用。例如:run(["score", "--model", "bkt", "--json"]) 会基于存储的事件日志拟合 BKT 模型,并返回解析后的 JSON 掌握度报告。
库 API 参考
以下所有内容均从 masterytrace-cli 的包入口导出(src/index.ts,重新导出 src/core/* 和 src/models/*):
import {
// Event schema and validation
ResponseEventSchema, parseResponseEvents, EventValidationError,
type ResponseEvent,
// Shared model types
type ScoringModel, type FittedModel, type MasteryReport,
type MasteryLearnerEntry, type MasterySkillEntry,
// Engine: runs one or both models
runScoring, type ModelSelector, type EngineConfig, type EngineResult,
// BKT
BktModel, BKT_DEFAULT_PARAMS, runForwardRecursion, fitSkillParamsByGridSearch,
type BktParams, type BktConfig, type BktFittedModel,
// IRT
IrtModel, probabilityCorrect,
type IrtItemParams, type IrtLearnerResult, type IrtConfig, type IrtFittedModel,
// Generic JSON/CSV event log adapter
genericAdapter, parseCsv, type EventAdapter,
} from 'masterytrace-cli';
最简库用法示例:
import { runScoring, parseResponseEvents } from 'masterytrace-cli';
const events = parseResponseEvents([
{ learnerId: 'l1', skillId: 'fractions', correct: true, timestamp: '2026-01-01T00:00:00Z' },
{ learnerId: 'l1', skillId: 'fractions', correct: false, timestamp: '2026-01-02T00:00:00Z' },
]);
const { reports } = runScoring(events, 'both');
// reports[0].model === 'bkt', reports[1].model === 'irt'
// each learner's report.learners[i].skills[j].value is the mastery estimate
BktModel 和 IrtModel 都实现相同的 ScoringModel 接口(先调用 fit(events),再调用 score(fittedModel)),因此引擎和你自己的代码都可以互换使用它们。
BKT 和 IRT 的工作原理
MasteryTrace 实现了两种相互独立的心理测量模型。它们回答不同的问题,并产生不同类型的数值,因此 masterytrace score --model both 会并排运行这两种模型,而不是从中选择一个。
贝叶斯知识追踪(BKT)
BKT 将单个学习者对一项技能的掌握情况建模为隐藏的二元状态(掌握/尚未掌握),并在每次作答后更新“已掌握”的概率,使用以下四个参数:
pInit:在没有任何证据之前,学习者已经掌握该技能的概率。pTransit:从一次尝试到下一次尝试之间学会该技能的概率。pSlip:尽管已掌握该技能,仍答错的概率。pGuess:尽管尚未掌握该技能,仍答对的概率。
对于每次作答,前向递归会先根据观察到的结果更新信念(贝叶斯规则),然后推进信念,以考虑学习者在下一次尝试前可能学会该技能的情况:
after correct: P(know | obs) = P(know) * (1 - pSlip) / [P(know) * (1 - pSlip) + (1 - P(know)) * pGuess]
after incorrect: P(know | obs) = P(know) * pSlip / [P(know) * pSlip + (1 - P(know)) * (1 - pGuess)]
P(know)_next = P(know | obs) + (1 - P(know | obs)) * pTransit
MasteryTrace 会按时间顺序,为每位学习者的每项技能分别运行此递归,并将最终后验概率作为该学习者掌握该技能的概率。如果在 masterytrace.config.json 中设置 "bkt": { "fit": true },则每项技能的四个参数都会根据你自己的数据,通过粗略网格搜索(7 x 7 x 5 x 5 种候选组合)进行拟合,以最小化预测正确率与实际正确率之间的平方误差,而不是使用教科书中的默认值(pInit=0.4, pTransit=0.3, pSlip=0.1, pGuess=0.2)。

项目反应理论(2PL IRT)
IRT 为每位学习者建模一个连续的学习者能力值(theta),并为每项被视为“题目”的技能建模两个参数:区分度(a,表示题目区分高能力与低能力学习者的敏锐程度)和难度(b)。在 2 参数逻辑模型下,答对的概率为:
P(correct) = sigmoid(a * (theta - b))
MasteryTrace 通过对对数似然进行梯度上升,联合拟合所有这些参数(联合 MLE),并使用较小的 L2 惩罚将 theta/b 拉向 0、将 a 拉向 1。对于所有作答均正确或均错误的学习者或技能,未正则化的似然原本会在无穷大处达到最大值;正是这一惩罚使拟合结果保持有限。由于 2PL 模型中的 theta 仅在平移和缩放意义下可识别(将 theta 和 b 同时平移相同常数,或缩放 theta/b 并相应地对 a 进行除法运算,都不会改变任何预测概率),因此拟合过程中每次迭代后都会重新调整 theta,使其均值为 0、标准差为 1。这是确定单一解的标准方法。
真实数据恢复检查
test/irt.test.ts 使用根据已知真实 theta/a/b 值生成的合成数据集拟合模型(5 位学习者和 4 项技能,共 4,000 次作答),并检查恢复出的参数在经过相同的规范化后是否接近真实值。本 README 实际运行时,theta 的最大绝对误差为 0.123,题目难度为 0.196,题目区分度为 0.114,均远低于测试的 0.3 容差;拟合耗时为 26 ms。
基准测试
在本地使用合成事件日志进行测试(Node 24,单核,以真实子进程方式调用 masterytrace score,包含 Node 启动时间):
| 数据集 | 事件数 | --model bkt | --model irt | --model both |
|---|---|---|---|---|
| 小型 | 10,000(50 位学习者 x 20 项技能 x 10 次作答) | 0.06s | 0.10s | 0.11s |
| 大型 | 100,000(100 位学习者 x 50 项技能 x 20 次作答) | 0.17s | 0.54s | 0.60s |
在包含 100,000 个事件的数据集上,BKT 使用按技能进行的网格搜索拟合("bkt": { "fit": true },每项技能进行 1,225 种组合的网格搜索)耗时 1.39s。所有数据均为完整 masterytrace score 子进程的实际运行时间,包含 Node 进程启动时间,因此反映了实际运行命令的体验,而不是单独拟合函数的微基准测试。
对比
MasteryTrace 的独特之处在于,它同时提供命令行工具和 TypeScript 库,且无需 Python 运行时。以下是它与功能最接近的成熟库的对比,每个项目的信息均根据其 GitHub 仓库和软件包注册页面核实:
| 项目 | 语言 | 许可证 | 类型 | 安装 | GitHub 星标数 |
|---|---|---|---|---|---|
| MasteryTrace | TypeScript/Node + Python | MIT | 命令行工具 + 库 | pip install masterytrace-cli / npm install -g masterytrace-cli | 新项目 |
| pyBKT | Python(C++ 核心) | MIT | 仅库 | pip install pyBKT | 272 |
| girth | Python | MIT | 仅库 | pip install girth | 124 |
| py-irt | Python(PyTorch/Pyro) | MIT | 命令行工具 + 库 | pip install py-irt | 170 |
| DeepTutor | Python + TypeScript | Apache-2.0 | 完整辅导应用 | pip install -U deeptutor | 32,000+ |
pyBKT(由加州大学伯克利分校的 CAHLR 实验室开发)是最成熟的 BKT 实现,支持的 BKT 变体(遗忘、题目顺序效应)也多于 MasteryTrace 单一的教科书模型加网格搜索方法。girth 和 py-irt 都是 IRT 库;py-irt 基于 PyTorch 和 Pyro 构建,是两者中更重量级的一个,可利用 GPU 加速拟合更大型的 IRT 模型(1PL/2PL/4PL),并自带命令行工具;girth 则是更轻量的纯 Python 选项,在理念上更接近 MasteryTrace 的正则化梯度上升 2PL 实现。这三个库都不是 Node.js 软件包,也没有提供与 masterytrace score/report 同类的通用命令行工具。
DeepTutor 并非与其竞争的测量库。它是一个规模庞大且持续积极开发的开源 AI 辅导平台,提供 Agent 编排、辅导工作区和记忆等功能;根据其 README,它本身并未实现 BKT 或 IRT。它是一个可行的集成目标:DeepTutor 可以记录作答事件,并将其交给 MasteryTrace,以完成它本身无法完成的掌握度估算。
什么是 MasteryTrace,它为何存在
MasteryTrace 是一个开源 TypeScript 命令行工具和库,可对学习者作答事件日志拟合贝叶斯知识追踪和项目反应理论模型,然后报告每位学习者在每项技能上的校准后掌握度估算。它之所以存在,是因为大多数开源 AI 辅导 Agent 都是为了进行对话和调整课程而构建的,而非衡量学习者实际掌握了什么;与此同时,能够严谨完成这项工作的两种心理测量模型几乎都只存在于 Python 库中,Node 或 TypeScript 技术栈没有对应方案,非 Python 工具也没有可供其调用的命令行工具。MasteryTrace 填补了这一特定空缺:将它指向 JSON 或 CSV 事件日志,即可获得掌握概率(BKT)和能力估算(IRT),输出格式可供任何脚本、辅导产品或 Agent 解析。
常见问题
为什么不直接使用 pyBKT 或 py-irt? 如果你需要更多 BKT 变体(遗忘、题目顺序效应)或 GPU 规模的 IRT 拟合,它们都是不错的选择,MasteryTrace 上方的对比表也明确说明了这一点。MasteryTrace 的 Python 包(pip install masterytrace-cli)涵盖了本仓库实现的相同简单教科书式 BKT 加网格搜索和正则化 2PL-IRT 模型,适用于纯 Python 工作流;TypeScript 包(npm install -g masterytrace-cli)还适用于你希望在 Node 代码库中进行掌握度评分、且完全不需要 Python 运行时的情况。
需要数据库吗? 不需要。状态存储在你运行 CLI 的位置旁边 .masterytrace/ 目录中的两个 JSON 文件里(events.json 和 scores.json)。运行时不需要服务或外部依赖。
可以接入我自己的辅导应用数据吗? 可以,只要你能生成由 { learnerId, skillId, correct, timestamp } 行组成的 JSON 数组或 CSV。目前还没有针对各应用的适配器;内置的 genericAdapter 支持这两种格式。如果你的数据结构不同,请先将其转换为这种结构(或对已符合该结构的行调用 parseResponseEvents),再调用 runScoring。
BKT/IRT 的数学模型可靠吗? 两种模型都通过了单元测试:BKT 使用手工计算的示例,IRT 使用已知真实参数的合成数据集;此外还通过了完整的 CLI 测试套件。有关真实参数恢复情况,请参阅上文的 BKT 和 IRT 的工作原理。
只有一条响应或完全没有响应时会怎样? 两种模型都能妥善处理,不会报错:BKT 对一条响应会返回单个后验值;事件日志为空时,任一模型都会返回空报告,而不是抛出异常。
用一句话来说,MasteryTrace 是什么? 它是一个 CLI 和库,以 TypeScript/Node 包和独立的 Python 移植版两种形式发布,可将学习者响应事件的 JSON 或 CSV 日志转换为按学习者和技能划分的掌握度评分,使用两种指定的心理测量模型(BKT、2PL IRT),而非原始正确率;它本身不会进行对话或授课。
支持哪些平台和语言运行时? TypeScript CLI/库需要 Node.js 18 或更高版本(参见 package.json 中的 engines.node),且不包含特定于操作系统的代码路径。Python 移植版需要 Python 3.9 至 3.13(参见 python/pyproject.toml 中的分类器),也声明为操作系统无关。两个发行包都不需要数据库或任何其他运行时依赖。
MasteryTrace 与 pyBKT 具体有何不同? pyBKT(CAHLR/UC Berkeley,截至上次查看有 272 个 GitHub 星标)是更成熟的 BKT 实现:它包含已编译的 C++ 拟合核心,并支持 MasteryTrace 不具备的 BKT 变体,例如遗忘和题目顺序效应。MasteryTrace 的 BKT 是单一的教科书式四参数模型,并可选择通过网格搜索进行拟合,设计上刻意保持简单。选择两者时,重要的区别是:pyBKT 仅支持 Python,而 MasteryTrace 也以 Node/TypeScript 包的形式发布,并通过一个 CLI(masterytrace score --model bkt|irt|both)提供这两个模型,而不是仅提供 BKT 的库。
有 npm 包吗? 有,npm install -g masterytrace-cli 已在 npm 注册表上发布。它与 Python 移植版一样提供四个子命令(init、record、score、report),构建自通过 CI 的同一份 TypeScript 源码。
可以在商业产品中使用 MasteryTrace 吗? 可以。TypeScript 和 Python 代码均采用 MIT 许可证(参见 LICENSE 和 python/pyproject.toml 中对应的分类器),允许在注明出处的前提下用于商业用途、修改和再分发,且不提供任何保证。
贡献
欢迎提交问题和拉取请求,无论是针对 TypeScript 代码库(仓库根目录)还是 Python 代码库(python/)。完整指南请参阅
CONTRIBUTING.md。TypeScript
快速入门:
npm install
npm run lint
npm run typecheck
npm run test:coverage
项目保持 100% 的语句、行和函数覆盖率,并确保 eslint/tsc/npm audit 均无问题;如果某项指标有所下降,这类更改很可能无法直接合并。Python 快速入门请参阅 python/README.md。
许可证
MIT,详见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。
