notebook-builder

分段式 Jupyter Notebook 生成与修改工具。当用户需要创建、分段追加、修改、合并 Jupyter Notebook (.ipynb) 时使用此技能。支持的高级功能包括:(1) 分段多次生成 Notebook 内容,避免一次性生成过大导致超时或内容截断;(2) 本地图片 base64 嵌入到 Markdown cell;(3) 内置哈希判题系统(不显示明文答案);(4) 灵活的 cell 级增删改查;(5) 合并多个 notebook 为一个;(6) 导出为纯 Python 脚本;(7) 自动生成目录;(8) Cell 标签分组与重排序。适用场景包括教学课件、编程练习、技术教程、学习笔记等 notebook 的创建与维护。

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "notebook-builder" with this command: npx skills add aigamatrix/notebook-builder

Notebook Builder

分段式创建和修改 Jupyter Notebook,支持图片嵌入与判题系统。

⚠️ 执行规则(必须遵守)

所有 Python 代码必须由 agent 自己通过 terminal 工具执行,严禁让用户手动在命令行执行。

原因:agent 通过工具执行命令时,stdout/stderr 会被自动捕获并返回,agent 可以依据输出判断操作是否成功。如果让用户手动执行,agent 无法感知执行结果,会导致工作流中断或状态不一致。

具体要求:

  1. 每一段 Python 代码都必须通过 terminal 工具直接执行,不要输出代码让用户自己运行
  2. 执行后必须检查 stdout 输出,确认操作成功(如看到 前缀的确认信息)
  3. 分段生成时,每段执行完毕后应通过 terminal 工具执行 nb_info()get_cell_summary() 检查当前 notebook 状态,再继续下一段
  4. 如遇执行错误,agent 应自行分析错误信息并修正代码后重试,无需用户介入

核心工作流程

用户请求
  │
  ├─ 创建新 notebook      → "创建流程"
  ├─ 修改现有 notebook    → "修改流程"
  ├─ 添加判题系统         → "判题流程"
  └─ 嵌入图片             → "图片流程"

❗ 关于 <技能脚本目录> 占位符

示例代码中的 <技能脚本目录> 需要替换为此技能实际的 scripts/ 目录绝对路径。agent 应通过以下方式确定该路径:

  1. 此 SKILL.md 文件所在目录的同级 scripts/ 子目录
  2. 即 SKILL.md 的父目录 + /scripts

例如如果此 SKILL.md 位于 /home/user/.codebuddy/skills/notebook-builder/SKILL.md,则 <技能脚本目录> 应替换为 /home/user/.codebuddy/skills/notebook-builder/scripts

辅助脚本

此技能包含核心辅助脚本 scripts/nb_helpers.py,提供以下能力:

函数作用
new_notebook()创建空 notebook 字典
load_notebook(path)从文件加载 notebook
save_notebook(nb, path)保存 notebook 到文件
make_markdown_cell(src)构造 Markdown cell
make_code_cell(src)构造 Code cell
append_cells(nb, cells)向末尾追加 cell
insert_cells(nb, idx, cells)在指定位置插入 cell
delete_cells(nb, start, count)删除 cell
replace_cell(nb, idx, cell)替换 cell
find_cells_by_keyword(nb, kw)按关键词搜索 cell
find_cells_by_id(nb, id)按 id 查找 cell
embed_image_in_markdown(path)图片转 base64 嵌入
make_image_output(path)为 code cell 创建图片输出
make_quiz_code_cell(...)生成哈希判题 cell
make_quiz_summary_cell(ids, total, scores)生成判题汇总 cell
merge_notebooks(paths, output)合并多个 notebook
export_to_script(nb, path)导出为 Python 脚本
make_toc_cell(nb, max_level)自动生成目录 cell
reorder_cells(nb, new_order)按索引重排 cell
tag_cell(cell, tags)为 cell 添加标签
find_cells_by_tag(nb, tag)按标签查找 cell
make_section(title, ...)快速生成章节
clear_all_outputs(nb)清除所有输出
set_kernel(nb, name, display)修改 kernel
nb_info(nb)notebook 统计信息
get_cell_summary(nb)每个 cell 的摘要

创建流程(分段生成)

分段生成的核心思路:不要试图一次性生成整个 notebook。将内容拆分为多个"段",每段包含若干 cell,逐段追加。

步骤

  1. 初始化:用 new_notebook() 创建空 notebook,根据用户需求设置 kernel
  2. 规划章节:将内容大纲拆分为 3-5 段,每段对应一个逻辑章节
  3. 逐段生成
    • 使用 make_section()make_markdown_cell() + make_code_cell() 构造当前段的 cell
    • 使用 append_cells() 追加到 notebook
    • 调用 save_notebook() 保存当前进度(支持中途预览)
  4. 收尾:添加总结章节,最终保存

分段生成示例

重要:以下每一段代码都应由 agent 通过 terminal 工具分段执行,不要一次性全部执行,也不要让用户手动执行。

第 1 次执行(通过 terminal 工具):初始化 + 标题段

import sys
sys.path.insert(0, "<技能脚本目录>")
from nb_helpers import *

nb = new_notebook(kernel_name="python3")
append_cells(nb, [
    make_markdown_cell("# 🔥 我的教程\n---\n**目标**:xxx"),
    make_code_cell("import torch\nprint(torch.__version__)"),
])
save_notebook(nb, "my_tutorial.ipynb")
print(nb_info(nb))  # 验证状态

第 2 次执行(通过 terminal 工具):追加第一章

import sys
sys.path.insert(0, "<技能脚本目录>")
from nb_helpers import *

nb = load_notebook("my_tutorial.ipynb")
append_cells(nb, make_section(
    "1.1 基础概念",
    "这里是 Markdown 正文...",
    ["# 实验代码\nprint('hello')"],
))
save_notebook(nb, "my_tutorial.ipynb")
print(nb_info(nb))  # 验证状态

第 N 次执行(通过 terminal 工具):追加考核 + 总结

import sys
sys.path.insert(0, "<技能脚本目录>")
from nb_helpers import *

nb = load_notebook("my_tutorial.ipynb")
quiz = make_quiz_code_cell("q1", "1+1=?", 2, score=10)
append_cells(nb, [make_divider_cell(), make_markdown_cell("## 📝 考核时间"), quiz])
save_notebook(nb, "my_tutorial.ipynb")
print(nb_info(nb))  # 验证状态

关键约束

  • 所有代码必须由 agent 通过 terminal 工具执行,不要输出代码让用户手动运行
  • 每次追加的 cell 数量建议不超过 10 个,避免单次操作过大
  • 每次追加后都 save_notebook(),确保进度不丢失
  • 每次执行后检查 stdout 输出,确认看到 成功信息
  • 使用 nb_info()get_cell_summary() 检查当前状态
  • 分段执行时,每次都需要重新 importload_notebook(),因为每次 terminal 调用是独立的 Python 进程

修改流程

步骤

  1. 加载load_notebook(path) 加载现有 notebook
  2. 定位
    • get_cell_summary() 查看所有 cell 概览
    • find_cells_by_keyword() 按关键词搜索目标 cell
    • find_cells_by_id() 按 id 精确定位
  3. 修改
    • replace_cell() 替换整个 cell
    • insert_cells() 在指定位置插入新 cell
    • delete_cells() 删除不需要的 cell
  4. 保存save_notebook(nb, path)

修改示例

以下代码由 agent 通过 terminal 工具执行:

import sys
sys.path.insert(0, "<技能脚本目录>")
from nb_helpers import *

nb = load_notebook("existing.ipynb")

# 查看结构
for line in get_cell_summary(nb):
    print(line)

# 在第 5 个 cell 后插入新内容
insert_cells(nb, 5, [
    make_markdown_cell("### 补充说明\n新增的内容..."),
    make_code_cell("# 新的实验代码"),
])

# 替换第 3 个 cell
replace_cell(nb, 3, make_markdown_cell("## 更新后的标题"))

save_notebook(nb, "existing.ipynb")
print(nb_info(nb))  # 验证修改结果

图片流程

两种嵌入方式:

方式 1:嵌入到 Markdown cell(推荐)

# 基础用法
img_md = embed_image_in_markdown("diagram.png", alt_text="架构图")
cell = make_markdown_cell(f"## 系统架构\n\n{img_md}\n\n上图展示了...")

# 指定宽度
img_md = embed_image_in_markdown("photo.jpg", alt_text="示例", width=500)

方式 2:嵌入到 Code cell 输出

output = make_image_output("result.png")
cell = make_code_cell("# 运行结果如下", outputs=[output])

注意事项

  • 图片会被 base64 编码嵌入,无需外部依赖
  • 大图片会显著增大 .ipynb 文件体积,建议压缩后再嵌入
  • 支持 PNG、JPG、GIF、SVG 格式

判题流程

判题系统通过 SHA256 哈希存储答案,学生无法看到明文。

生成判题 cell

# 单选/填空题
quiz1 = make_quiz_code_cell(
    question_id="q1",
    question_prompt="torch.randn(3,4,5) 的 stride 是什么?",
    answer=(20, 5, 1),      # 正确答案(不会以明文出现在 notebook 中)
    answer_type="tuple",
    hints=["stride[i] = 后面所有维度 size 的乘积"],
    score=10,
)

支持的答案类型

类型示例说明
int42整数
float3.14浮点数
str"hello"字符串(不区分大小写,去首尾空格)
boolTrue布尔值
tuple(20, 5, 1)元组
list[1, 2, 3]列表(会被转为 tuple 比较)

汇总评分

summary = make_quiz_summary_cell(
    question_ids=["q1", "q2", "q3"],
    total_score=30,
    scores={"q1": 10, "q2": 10, "q3": 10},  # 可选,未指定时平均分配
)
append_cells(nb, [summary])

判题原理

  1. 答案经过标准化处理(去空格/小写/统一类型表示)
  2. 加盐后 SHA256 哈希,截取前 16 位存储
  3. 学生运行 cell 时,对其输入做同样处理并比对哈希
  4. 哈希不可逆,学生无法从中推导答案

完整教程生成模板

当用户要求生成完整教学 notebook 时,推荐结构:

1. 标题 + 目标描述 (markdown)
2. 环境准备 (code: import + version check)
3. --- 分隔线 ---
4. 章节 1: 概念讲解 (markdown) + 实验代码 (code) × N
5. --- 分隔线 ---
6. 章节 2: ...
7. --- 分隔线 ---
8. 📝 考核时间 (markdown)
9. 题目 1 (quiz code cell)
10. 题目 2 (quiz code cell)
11. ...
12. 📊 汇总评分 (quiz summary code cell)
13. --- 分隔线 ---
14. 完成总结 (markdown)

常见问题

Q: 为什么代码必须由 agent 自己执行?

A: agent 只能通过工具调用的返回值感知执行结果。如果让用户在终端手动执行,即使输出了结果,agent 也无法检测到,会导致状态不一致。因此所有 Python 代码都必须通过 terminal 工具执行。

Q: 分段执行时变量会丢失吗?

A: 会。每次 terminal 工具调用是一个独立的 Python 进程,上次定义的变量不会保留。因此每次执行都需要重新 import 并用 load_notebook() 加载之前保存的 notebook。

Q: 分段生成时如何避免内容重复?

A: 每次追加前用 get_cell_summary() 检查当前状态,确认上一段已正确追加后再继续。

Q: 如何修改已有 notebook 中的某个 cell?

A: 用 find_cells_by_keyword() 定位目标 cell 的 index,然后用 replace_cell() 替换。

Q: 判题 cell 能否防止学生查看哈希?

A: 哈希值虽然可见,但不可逆。学生无法从 16 位哈希推导出原始答案。如需更高安全性,可将判题逻辑放到外部服务。

Q: 图片嵌入后文件太大怎么办?

A: 建议在嵌入前压缩图片(如 PNG → 降低分辨率、JPG → 降低质量),或只嵌入关键图片。

合并 Notebook

将多个 notebook 合并为一个,适合把分散的章节/讲义合并。

# 合并多个 notebook
merged = merge_notebooks(
    paths=["chapter1.ipynb", "chapter2.ipynb", "chapter3.ipynb"],
    output_path="full_course.ipynb",
    add_dividers=True,   # 在每个 notebook 之间添加分隔线
    add_titles=False,    # 不添加来源标注
)

导出为 Python 脚本

将 notebook 的 Code cell 导出为 .py 文件,Markdown cell 可选地转为注释。

nb = load_notebook("tutorial.ipynb")
export_to_script(
    nb,
    output_path="tutorial.py",
    include_markdown=True,  # Markdown cell 作为注释写入
)

自动生成目录

扫描 notebook 中所有 Markdown 标题,生成可点击跳转的目录 cell。

nb = load_notebook("long_tutorial.ipynb")
toc = make_toc_cell(nb, max_level=3, title="📑 目录")
insert_cells(nb, 0, [toc])  # 插入到 notebook 开头
save_notebook(nb, "long_tutorial.ipynb")

Cell 重排序

按指定索引顺序重排 cell,可用于调整结构。

nb = load_notebook("messy.ipynb")
for line in get_cell_summary(nb):
    print(line)
# 按新顺序重排
reorder_cells(nb, [0, 3, 1, 2, 4])
save_notebook(nb, "messy.ipynb")

Cell 标签系统

为 cell 打标签,然后按标签筛选。标签存储在 metadata.tags 中,JupyterLab 可直接识别。

# 打标签
cell = make_code_cell("x = 1")
tag_cell(cell, ["exercise", "easy"])

# 按标签查找
exercises = find_cells_by_tag(nb, "exercise")
for idx, cell in exercises:
    print(f"Cell {idx}: {cell['cell_type']}")

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Subtitle To Video

add subtitle files, video into captioned videos with this skill. Works with MP4, MOV, AVI, WebM files up to 500MB. YouTubers, content creators use it for add...

Registry SourceRecently Updated
General

Api Changelog Generator

Generate and maintain API changelogs from OpenAPI/Swagger specs — track endpoints added, removed, deprecated, or modified between versions. Detect breaking c...

Registry SourceRecently Updated
General

Free Music

Skip the learning curve of professional editing software. Describe what you want — add upbeat background music to my video for free — and get music-backed vi...

Registry SourceRecently Updated
General

Indie Maker News

独行者 Daily - 变现雷达。读对一条新闻,少走一年弯路。每天5分钟,给创业者装上商业雷达。聚焦一人公司、副业、创业变现资讯,智能分类,行动导向。用户下载即能用,无需本地部署!

Registry SourceRecently Updated