文档/开放格式
tasks 格式说明
任务是一个 JSON 文件,描述「要做哪些练习、做到什么程度」。进度不另存,每次由你的练习记录算出来,删了记录进度跟着回退。App 里「任务 → 导入任务」选文件即可。
最小的任务#
累计完成三次、都要 90 分以上的朗读:
three-reads.json
{
"id": "three-reads-90",
"name": "三次 90 分",
"description": "朗读三篇,每篇 90 分以上。",
"steps": [
{"type": "readAloud", "times": 3, "minScore": 90}
]
}id、name 和 steps(或 stages)是必填的。同 id 再次导入是替换,开始状态保留。Schema:task.schema.json。
步骤 step#
一个步骤就是一条要满足的条件,用来匹配你产生的练习记录。
| 字段 | 说明 |
|---|---|
type | 必填:readAloud 朗诵 / retell 复述 / speak 口述(旧名 diary 也认) |
mode | 模式,不写 = 该模块任意模式;可写数组,任一即可。取值见下表 |
style | 仅口述的自我介绍 / 汇报:introNormal introInterview reportWork reportReview;与 mode 矛盾会报错 |
times | 需要达标几次,默认 1。在 daily 阶段里是每天几次 |
minScore | 总分下限,0–100 |
minChars | 转写字数下限(复述、口述):写数字,或按年龄段写对象,没写的年龄段不限 |
minDurationSeconds | 时长下限(秒) |
minAccuracy / maxSeconds | 仅打字、默写:正确率下限 0–100 / 用时上限 |
sameArticle | true:times 次必须是同一篇。「每天同一篇读 3 次」就是 A 读 3 次才算,A、B、A 只算 2 次。需要 minAppVersion ≥ 0.5.18 |
target | 限定内容:bank + title 指定某一篇;只写 bank 是该题库任意一篇;bankSet 引用题库集合(见下) |
mode 的取值#
| 模块 | mode |
|---|---|
| readAloud | read 朗读 · recite 背诵 · typing 打字 · dictation 默写。不写 mode 时只含 read 和 recite,要打字、默写必须明确写 |
| retell | normal 正常 · brief 极简总结 · structured 总分总 · guided 指导 |
| speak | diary 日记 · topic 命题说话 · intro 自我介绍 · report 工作汇报 · review 读后感 |
写错模式会被拒绝
不认识的模式不会被悄悄当成「不限」,导入时报「可能需要升级 App」。
阶段与「每天」#
一个扁平的步骤列表表达不了「三周 × 每天」。用 stages 代替 steps:
- 每个阶段有自己的
steps,按order顺序(或任意顺序)完成。只有steps的任务等价于一个阶段。 daily: true+days: N:阶段里全部步骤每天都要达标,累计 N 个达标日阶段才完成,不要求连续,漏一天不用重来。一天按本地时间的自然日算。daily默认 false,此时步骤在整个阶段内累计。days只能和daily一起用。- 同一个阶段(
daily按天)里,一条练习记录只算给一个步骤:先分给指定了具体mode的,剩下的再分给更宽的。所以「复述 3 篇,其中 1 篇极简总结、1 篇总分总」写成三个步骤:brief ×1、structured ×1、不限模式 ×1。
memory-14-day.json(官方任务,说明略有精简)
{
"id": "memory-14-day",
"name": "练记忆 14 天",
"description": "累计 14 个达标日,每天朗诵 6 次、背诵 2 次,题库不限。",
"order": "sequence",
"badge": {"id": "memory-14", "name": "记忆达人", "icon": "brain.head.profile", "description": "14 天坚持朗诵与背诵"},
"stages": [
{"id": "daily", "name": "每日朗诵与背诵", "days": 14, "daily": true,
"steps": [
{"type": "readAloud", "mode": "recite", "times": 2},
{"type": "readAloud", "mode": "read", "times": 6}
]}
]
}按年龄段指定题库 bankSets#
顶层 bankSets 定义题库集合,步骤的 target 用 {"bankSet": "名字"} 引用,表示「集合里任意题库的任意一篇」。键是年龄段:kindergarten primary middle high adult。集合也可以是普通数组(所有人相同)。
"bankSets": {
"byAge": {
"kindergarten": ["hsk-1", "hsk-2"],
"primary": ["zh-grade-1", "zh-grade-2", "zh-grade-3"],
"adult": ["putonghua-50"]
}
},
"steps": [
{"type": "readAloud", "times": 3, "target": {"bankSet": "byAge"}},
{"type": "speak", "mode": "review", "target": {"bankSet": "byAge"},
"minChars": {"kindergarten": 50, "primary": 100, "adult": 300}}
]- 当前用户的年龄段在集合里没有对应项时,任务不能开始,并提示原因。
- 这里的题库 id 是题库文件里写的
id(见 稳定标识),本机没有该题库时,任务卡片会提示缺哪些,并可跳到题库商店。
顶层字段#
| 字段 | 说明 |
|---|---|
id name | 必填。id 只用字母、数字和 ._-;别以 custom- 开头,那是 App 里新建的自定义任务专用 |
description | 任务卡片上的说明,用 \n 换行 |
order | sequence(默认)按顺序解锁;any 任意顺序。顺序任务里,上一阶段完成之后的记录才算数下一阶段 |
ageGroups | 只对这些年龄段显示;不写 = 所有人 |
badge | 完成整个任务得一枚徽章:id name icon(SF Symbol 名,不存在时用默认图标)description。授予后不撤销 |
minAppVersion | 最低 App 版本,如 "0.5.18"。版本更低的 App 会标「需要升级 App」,不能开始。用到较新的能力(如 sameArticle)要写 |
计算规则要点#
- 只统计任务开始之后产生的记录,历史记录不会直接把任务刷完。
- 打字、默写不加每日积分、不进日历分数,但任务里可以明确用
typing/dictation来要求。 - 任务本身不加积分;任务里的练习照常计入每日积分。
校验#
导入时 App 会校验,不通过会说明原因:缺 id / 名称、steps 和 stages 同时写、没有步骤、daily 阶段缺 days、minScore 越界、找不到题库集合、写了 title 没写 bank 等。也可以先用 task.schema.json 在本地检查:
shell
pip install jsonschema
python3 - <<'EOF'
import json
from jsonschema import Draft202012Validator as V
schema = json.load(open("task.schema.json"))
print(list(V(schema).iter_errors(json.load(open("three-reads.json")))))
EOF在线任务的样子
现有的官方任务见题库商店 · 任务。想让 AI 帮你写,见 用 AI 制作 tasks。