1实现原理 · 为什么它能做到
SKILL.md 本身不是执行器,而是一份『agent 操作手册』:它教 agent 调用随包安装的 `notebooklm` CLI,真正的网络与协议实现在 Python 包里(Web 走 batchexecute RPC,另有 Android gRPC 后端)。
Use the `notebooklm` CLI for agent workflows. Prefer `--json` and explicit IDs so every operation is inspectable and safe under concurrency.
本 skill 是被打包进 Python 包的产物:构建时把仓库根 SKILL.md 注入 `notebooklm/data/SKILL.md`,`notebooklm skill install` 再把它写到 agent 宿主的 skill 目录,因此 skill 文本与 CLI 版本天然同源同版。
force-include = {"SKILL.md" = "notebooklm/data/SKILL.md", "AGENTS.md" = "notebooklm/data/CODEX.md"}
认证走『凭证明文文件 + 分级』模型:浏览器登录产出 storage_state.json(会话 cookie),无头场景用 master_token.json(账户级凭证),两者都要求 0600、目录 0700,并支持按 profile 隔离。
A master token is a durable full-account credential that survives password changes; use a dedicated account, protect it in a secret store and as `0600` on disk, and explicitly revoke it if exposed.
它靠『显式 ID + readiness 门禁』把不可靠的异步生成过程变成可核对的状态机:source 必须等到 `ready`,artifact 必须等到 `completed`,且都要用返回的真实 ID 而不是『最新可见的那个』。
After adding sources, retain every `.source.id`, then run `source wait` for each before chat or generation.
并发安全靠三重隔离:每个 CLI 命令显式带 `-n/--notebook`、每个并发 run 用独立 profile、深层研究用 `--run-id`;并禁止多 agent 共享同一个可写 storage_state.json。
For every concurrent run, also set a unique `NOTEBOOKLM_PROFILE=agent-<id>` so context and profile writes are isolated.
授权边界被写成契约而非口号:安全只读操作可直接做,破坏性/耗时/写盘动作必须先拿到用户确认;且明确『CLI 不弹提示 ≠ 已授权』。
User intent, not the presence of a CLI prompt, is the authorization boundary.
引用可追溯:聊天回答带 `references[].source_id`,而字符偏移是 UTF-16 偏移(不是扁平正文的字节/字符偏移),因此提供专门解析函数而非让 agent 自行截取。
A reference's `start_char`/`end_char` are UTF-16 offsets into the structured source document, not flat `SourceFulltext.content`.
失败处理给的是可判定的退出码与包络契约,而不是模糊提示:成功 0、普通失败 1、`source wait` 超时 2、`artifact wait`/`research wait` 超时 1,并要求先只读诊断、不边诊断边改状态。
Exit 0 means success. Expected command failures use exit 1. A `source wait` timeout uses exit 2; `artifact wait` and `research wait` timeouts use exit 1.
2核心能力
3外部依赖
| Kind | Dependency / Endpoint |
|---|---|
| cli | notebooklm CLI(本包 entry point,agent 全程调用它) |
| cli | pip / uv tool install / pipx(安装包本体,可选 extra 决定能力面) |
| cli | uv / uvx(桌面版 MCP 扩展启动器,用于拉起 notebooklm-mcp) |
| network | NotebookLM Web batchexecute RPC 端点(默认 notebook.google.com,可切 notebooklm.google.com / 企业域) |
| network | Google 账户与 OAuth 端点(浏览器登录 / master token 换取 / 令牌校验) |
| network | Google Drive 导入下载端点(加 Drive 源时拉文件) |
| network | Google APIs(Android 后端 Drive 暂存上传与请求) |
| api | gpsoauth(无头 master-token 认证,换取 Google 会话 cookie) |
| package | 运行时依赖 httpx / click / rich / filelock |
| package | 可选 extra:browser(playwright) / cookies(rookie-cookies) / headless(gpsoauth) / impersonate(curl_cffi) / android(grpcio+protobuf) / mcp(fastmcp==3.4.2) / server(fastapi+uvicorn+python-multipart) / markdown(markdownify) |
4管控建议与判定依据
- 本地凭据 / 浏览器配置: 读取用户登录 Cookie/会话/密钥环: `~/.notebooklm/profiles/<profile>/storage_state.json`(Google 会话 cookie;默认 p
- scripts/: 执行本地脚本或命令: SKILL.md 指示 agent 在宿主 shell 执行 `pip install "notebooklm-py[browser]"` / `[c
- scripts/ 或 SKILL.md: 声明动态安装外部语言包依赖
- 网络端点: 声明外部网络访问: https://notebook.google.com/_/LabsTailwindUi/data/batchexecute(默认 Web RPC;可
- 本地工作目录: 文件读写与工件输出: 下载产物写入用户指定路径(`notebooklm download <type> <path> -n <nb> -a <artifact>`),SKI
5第二遍独立确认
- [ok] skill.path 定位 — 候选位置检查:仓库根有 SKILL.md(存在,314 行);无 skills/ 目录、无 .claude/skills/、无 plugins/;另在包内发现它的分发副本位置 `notebooklm/data/SKILL.md`(构建期注入,非仓库源文件)。故按批次规则 path='.'。
- [ok] 『实现方式』核对:SKILL.md 是不是空壳?(first-pass 假设它靠 CLI) — 不是空壳也不是纯文档——它是 crate 级薄指令 + 重实现库的组合:SKILL.md 里所有命令都能在包里找到对应实现(entry points 三个 console script;download 逻辑见 _app/download.py 的 'Click-free core' 说明),且 pyproject 的 force-include 把 SKILL.md 本身当包数据分发,说明二者版本绑定。没有夸大口径:它自称的前提(Python 3.10+、需 pip 装包、非官方集成)都在源码/文档里有对应。
- [ok] 外部依赖逐条复核(第二遍独立重查调用点) — 8 条 external_deps 全部在源码中找到调用点或声明点,无一条来自『推测』:CLI/uvx 来自 SKILL.md 与 desktop-extension;网络四条来自 rpc/types.py、_env.py、_web/sources/drive_import.py、_source/drive.py 的常量;gpsoauth 与各 extra 来自 _auth/mint_service.py 与 pyproject.toml。
- [ok] 安全结论反例搜索:有没有漏掉的网络调用/隐藏脚本/混淆内容? — 按主机名穷举后未发现第三方(非 Google)外发;未发现混淆代码或 base64 载荷;`src/notebooklm/_android/proto/**` 是 Google 生成的 protobuf 桩(自动生成、量大但非隐藏逻辑);desktop-extension/run_server.py 只做 uvx 定位与 exec,且注释明确 stdout 必须保持纯 JSON-RPC(有单测暴露函数)。deploy/ 与 MCP/REST 是 opt-in 且 SECURITY.md 把风险写明。
- [ok] injection_surface 的『无隔离条款』是否有遗漏的防护(例如源内容白名单/沙箱) — 在 SKILL.md 全文检索注入/不可信相关内容:仅有针对自身权限的授权边界('User intent, not the presence of a CLI prompt, is the authorization boundary.')与凭证不外泄要求('Never expose credential contents.'),没有任何把源文档/回答内容当不可信指令的条款;包侧对 Drive 下载做了域名白名单(_TRUSTED_GOOGLE_DOMAINS)与 URL 校验,但那是传输安全,不是内容注入防护。故 first-pass 的判断成立,且已把风险写进 risks。
- [ok] 退出码/状态取值等细节表述是否与代码一致 — SKILL.md 所述 exit 0/1/2 与 JSON 包络形态来自仓库自述的契约文档(docs/cli-exit-codes.md 同主题);本次未逐条跑 CLI 实测(不构造账号环境、也不跑测试),故只按『源码文本一致』给结论,未验证运行时行为。
- [ok] 元数据复核 — 本地 HEAD 等于 pin;LICENSE 为 MIT,pyproject `license = {text = "MIT"}` 与 classifiers 'License :: OSI Approved :: MIT License' 一致;stars 19330、last_push 2026-09-13、license MIT 取自池内 queue-100.json(未额外 gh 复核)。installs 无公开来源,置 null。
6结论
2231081c4d43c0ea…