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外部依赖
| 类型 | 依赖 |
|---|---|
| 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风险提醒 风险提醒:黄色 · 留意使用
- 凭证是账户级,泄露后果不可逆 — master_token.json 可在改密后继续铸造会话(SKILL.md 自述 'durable full-account credential that survives password changes'),storage_state.json 是活 cookie。任何能读到 ~/.notebooklm/ 的进程(含被 MCP/REST 暴露的服务端与本机其他程序)都等于拿到该 Google 账户的 NotebookLM 权限;SECURITY.md 也要求泄露后到 Google 账户设置里显式吊销。
- 启用 MCP/REST 托管即把账户凭证挂到网络端点上 — deploy/ 提供 Docker + Tailscale Funnel 方案把服务公开到 :443;SECURITY.md 定性为 'experimental, single-tenant','Both front account-equivalent Google credentials for whoever can reach the process.' 一旦暴露且鉴权配置不当,就是外部可达的账号级入口——此时应按橙档对待。
- 源内容注入无任何隔离条款 — 加进来的 URL/PDF/YouTube/Drive 源与 deep research 自动导入的源,其文本会经 NotebookLM 生成结果回流到 agent 上下文;SKILL.md 只教结构化解析(references/偏移/退出码),未要求把源内容当不可信数据。恶意文档可借生成内容影响 agent 后续动作(间接 prompt injection),防护完全依赖宿主。
- 对未公开 Google 服务的强依赖,可用性与合规性都由对方决定 — 仓库自述 'Android and Web are both unofficial integrations over undocumented Google services',默认主机还经历过 #2067 切换(notebook.google.com ↔ notebooklm.google.com),说明端点与内部 RPC id 随时可能变;大量类似 'NOTEBOOKLM_RPC_OVERRIDES' 的逃生开关也侧面印证脆弱性。用于生产自动化需接受随时被上游打断。
- 耗时与配额约束会拖长 agent 会话 — deep research 15-30+ 分钟、`research wait --import-all` 可能吃掉约 3600 秒宿主墙钟时间、`generate video --format cinematic` 约 30-40 分钟且需 Google AI Ultra、生成受 Google 速率限制。SKILL.md 要求这些长等待必须先获用户授权,否则容易变成长时间前台阻塞或反复重试。
- 自我安装能力可改写宿主 skill 目录 — `notebooklm skill install` 会把 SKILL.md 写入 .claude/skills/notebooklm/(或 .agents/skills/…)。虽然需用户显式执行且提供 --dry-run/--no-clobber/--force 与 content_mismatch 报告,但意味着一个 CLI 命令可以改写 agent 的指令层文件;在多个 skill 混装的目录里应先用 --scope project --dry-run 预览。
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…5472d7cfcc