第 3 课
出题、JSON 事件流与会话续聊
用 run deep_question --config num_questions 按知识库出题并看清小模型的局限,用 --format json 输出 NDJSON 并用 jq 取 result、sources 和 session_id,用 --session 跨进程续聊,用 session list、session show 回看记录,最后照官方文档了解用 SKILL.md 交给 Claude Code、Code
课程目录第 3 / 3 课
学习位置仅保存在当前浏览器,有效期 180 天。
图文教材
本课对照的官方页面:命令参考、代理交接、故障排查。第 1~4 步为实测(DeepTutor 1.7.0,本地 gemma-4-e2b),第 5 步照官方文档整理、未实测。
前两课用的都是 chat。这一课先试 DeepTutor 的出题能力 deep_question,再学 --format json 事件流和 --session 续聊。掌握这两样,就能把 DeepTutor 写进脚本,或者交给 Claude Code、Codex 这类代理来调用。
第 1 步:根据知识库出题
deeptutor run 的第一个参数是能力名(capability)。deep_question 用来出题,题量、难度等参数通过 --config key=value 传入:
deeptutor run deep_question "根据笔记出 2 道导数选择题" \
--kb calculus -l zh --config num_questions=2
实测(约 4 分钟,节选,公式两侧的 $ 已省略):
▶ exploring
模型违反了动作标签协议;本轮重试。 (共出现 8 次)
已达迭代上限。基于当前已有内容产出输出。
▶ planning
▶ quizzing
题目 1
函数 f(x) = x^2 在 x=1 处的导数值是多少?
• A. 2 • B. 1 • C. 0 • D. 4
答案: A
解析: f'(x) = 2x,因此 f'(1) = 2。
题目 2
……下列哪一项最准确地描述了导数的几何意义?
答案: true
这次实测的结果并不理想,这里如实记录。deep_question 会先进入 exploring 阶段,让模型按智能体协议调用工具去查资料。2B 小模型反复违反协议,8 轮后触顶,最后只能凭模型自己的知识出题。第 1 题正确;第 2 题是选择题却没有选项,答案写成了 true。
结论:chat 和 kb 用小模型就够了,但 deep_question、deep_solve、deep_research 这类多阶段能力,应该在 setup.json 里换成更强的模型,具体写法见第 1 课第 4 步。官方的代理交接示例还演示了 --config difficulty=easy|medium|hard,可以分难度出题。
第 2 步:用 --format json 拿到结构化事件
加上 --format json 后,stdout 每行输出一个 JSON 事件(NDJSON)。日志走 stderr,可以用 2>/dev/null 屏蔽:
deeptutor run chat "用一句话说明 (x^3)' 等于多少" \
--kb calculus -l zh --format json 2>/dev/null > turn1.ndjson
统计一下各类事件的数量:
jq -r '.type' turn1.ndjson | sort | uniq -c
实测对照结果:
37 content
1 done
22 progress
1 result
1 session
1 session_meta
1 sources
1 stage_end
1 stage_start
498 thinking
thinking 是模型的推理流,content 是逐段输出的正文。脚本最常用的是三类事件:result 里有完整回答,sources 是引用的资料,done 带着会话 ID。
jq -r 'select(.type=="result") | .metadata.response' turn1.ndjson
jq -r 'select(.type=="done") | .session_id' turn1.ndjson
对照结果:
$(x^3)'$ 等于 $3x^2$,这是根据幂法则 $(x^n)' = n x^{n-1}$ 推导得出的结果。
unified_1793290582368_cd7cb797
第 3 步:用 --session 接着上一轮聊
把会话 ID 存进变量,下一轮通过 --session 传回去,模型就能记得上下文:
SID=$(jq -r 'select(.type=="done") | .session_id' turn1.ndjson)
deeptutor run chat "那 (x^4)' 呢?只写结果" --session "$SID" \
-l zh --format json 2>/dev/null \
| jq -r 'select(.type=="result") | .metadata.response'
对照结果:
$(x^4)' = 4x^3$
第二轮只问了「那 (x^4)' 呢」,模型能接上,说明上下文确实续上了。这就是官方代理交接示例的做法:第一轮从 done 事件取出 session_id,后面每一轮都带上它。
第 4 步:回看会话记录
deeptutor session list
deeptutor session show "$SID"
对照结果:session list 列出所有会话,包括 ID、自动生成的标题、能力和消息数。这次实测的标题有「导数幂法则」「速度加速度辨析」「无法生成题目」等。session show 的节选(公式两侧的 $ 已省略):
导数幂法则 (unified_1793290582368_cd7cb797)
capability=chat status=completed messages=4
USER 用一句话说明 (x^3)' 等于多少
ASSISTANT (x^3)' 等于 3x^2……
USER 那 (x^4)' 呢?只写结果
ASSISTANT (x^4)' = 4x^3
会话数据都保存在运行目录的 data/ 下,换一个终端、换一个进程都能用 --session 续上。
第 5 步:交给 Claude Code / Codex 调用(照官方文档)
DeepTutor 仓库根目录附带一份 SKILL.md,按官方说明,内容包括使用场景、前置条件、全部命令、REPL 斜杠命令和典型工作流。官方给出的接入方式是把它链接到你的项目根目录:
cd /your-project
ln -s /path/to/DeepTutor/SKILL.md ./SKILL.md
之后就可以直接用自然语言下任务,例如官方示例:
Read SKILL.md before doing anything else. Then build study plans,
generate quizzes, ...
代理会把任务翻译成 kb create、run deep_question --format json、--session 这些前面练过的命令。这一步本课没有实测,具体以代理交接页面为准。
小结
deeptutor run <能力> "<消息>"是统一入口,能力参数用--config key=value传入。--format json输出 NDJSON:result取回答,sources取引用,done取session_id。--session可以跨进程续聊,session list和session show用来回看记录。- 多阶段能力(出题、解题、研究)对模型要求高,小模型实测会出现协议错误和题目格式错误。
本课资料
适用环境
- 网页
- Linux
- macOS
- Windows
