
notebooklm-py Android 后端深度解析gRPC 传输、位置化 Wire 契约与协议证据管理【免费下载链接】notebooklm-pyUnofficial Python API and agentic skill for Google Gemini Notebook. Full programmatic access to NotebookLMs features—including capabilities the web UI doesnt expose—via Python, CLI, and AI agents like Claude Code, Codex, and OpenClaw.项目地址: https://gitcode.com/GitHub_Trending/no/notebooklm-pynotebooklm-py除了默认的 Webbatchexecute后端还支持一条显式的 Android 后端复用同一产品的 bearer 鉴权 gRPC 服务并借助移动端的 protobuf schema 作为 Web 位置化负载的预言机。本文围绕docs/android目录的 Android 用户入口与协议证据体系展开先讲清楚如何安装、登录并切换到 Android 后端再解释 Android protobuf 表面为何能校正 Web 端硬编码的数组索引最后完整覆盖契约清单、可再生工件、一致性conformance门禁与协议恢复的复现路径帮助你在动手维护或扩展任一传输层之前建立对整条证据链的完整认知。同一后端两道前门Web 与 Android 传输对比notebooklm-py的默认后端是 Web 的batchexecute协议而 Android 后端走的是同一产品 bearer 鉴权 gRPC 服务。两者驱动的是同一个 Tailwind 服务族只是传输不同。从docs/android/endpoints.md的交叉引用表可以完整继承这一对比AndroidWebnotebooklm-py/ 浏览器传输原生gRPCHTTP/2batchexecuteHTTP POST端点notebooklm-pa.googleapis.com/Service/Method/_/LabsTailwindUi/data/batchexecute方法标识明文Method名称6 字符混淆rpcid如CCqFvf负载protobuf字段带编号JSON 数组位置化字段鉴权OAuth bearercookies / SAPISID聊天GenerateFreeFormStreamedgRPC 流独立的QUERY_URL端点传输属性方面同见 endpoints.md主机为notebooklm-pa.googleapis.com:443服务为google.internal.labs.tailwind.orchestration.v1.LabsTailwindOrchestrationService路径形如/service/Method采用 HTTP/2 POST、content-type: application/grpc请求体按 5 字节 gRPC 信封逐条长度前缀封装成功标志是 HTTP 200 加 trailergrpc-status: 0。多数方法是 unaryGenerateFreeFormStreamed与StreamLiveSession为服务端流式。方法面上1.46.7二进制快照枚举出49 个方法、4 个 gRPC 服务而 2026-08-29 的 Google 签名构建1.55.10.971450265审计为53 个方法47 个LabsTailwindOrchestrationService、3 个LabsTailwindSharingService、2 个google.internal.labs.tailwind.api.v1.DiscoveryService、1 个LiveSessionService相对旧版新增了CancelGeneration、ListArtifactScheduledNotificationConfigs、UpdateArtifactScheduledNotificationConfig、DiscoveryService/BatchSearchNotebooks、DiscoveryService/SearchNotebooks并移除了旧PrototypeNotebookSearch调用点。这些版本作用域的清单在仓库中都有对应证据文件下文清单章节逐一列出。启用 Android 后端安装、登录与三种选择方式按 docs/android/README.md 的入口说明启用 Android 后端需要安装 Android 运行时如需一次性交互式 master-token 引导另装 browser extra然后在所选 profile 中建立持久凭据pip install notebooklm-py[android] pip install notebooklm-py[browser] # 仅用于一次性交互式引导 notebooklm login --master-token --account youexample.com选择 Android 后端有三种粒度1. 按次 CLI 调用选择--backend android全局 flagnotebooklm --backend android list --json notebooklm --backend android usage --json--backend参数在 CLI 与 MCP 入口都有注册例如 mcp/main.py 中定义了该 flag帮助文案即 Preferred API backend (default: NOTEBOOKLM_BACKEND, else web)。2. 进程级环境变量选择NOTEBOOKLM_BACKENDandroid notebooklm list --json从源码看环境变量的读取集中在两处client.py 中explicit_backend为None时回落到os.environ.get(NOTEBOOKLM_BACKEND)client_config.py 同样以backend if backend is not None else os.environ.get(NOTEBOOKLM_BACKEND, web)完成选择。未选择时 Web 始终是默认值_request_policy.py也把NOTEBOOKLM_BACKEND的默认值登记为web。3. Python API 中选择from notebooklm import NotebookLMClient async with NotebookLMClient.from_storage(backendandroid) as client: notebooks await client.notebooks.list()客户端组装层如何分流可以直接在 client_assembly.py 中看到当preference.preferred android时组装流程要求所选后端必须是AndroidBackendConfig随后调用assemble_android_backend(...)并把 Web 侧的decode_response/sleep/is_auth_error通过WebSeamOverrides传入——即 Android 主图不依赖 Web 传输实现只在兼容边界上复用少量纯函数。Android 分支自身的组合逻辑集中在 assembly.py它按shared共享运行时、configAndroidAssemblyConfig、credentialsprofile 路径、depsmaster token 读取器、OAuth 铸币器、HTTP 客户端工厂等依赖注入四个入参构建完整的 Android 协作图返回的 AndroidRuntime 数据类持有BearerProvider、AndroidSession、AndroidUploadPipeline、AndroidAssetDownloadService与PhenotypeTokenProvider五个 Android 专属协作者。显式选择 Android 之后的行为边界文档明确了几条重要边界读者必须理解覆盖全部 11 个类型化命名空间且不回落到 Web显式 Android 选择会为全部 11 个类型化命名空间安装 Android 实现任何类型化操作都不会回退到 Web 后端原始调用的正确入口高级 Android 调用应使用按后端选择的client.raw.unary(...)或client.raw.unary_stream(...)已废弃的client.rpc_call(...)仍是 Web 语义它接收的是 WebRPCMethod标识符首次 Android 使用会打开一个独立的 Web 兼容 sidecarv0.x 期间保留v0.x 默认策略下的构建期引导保留的默认 v0.x 策略下Android 的from_storage(...)在存储包装器构建客户端、Android open 之前仍会发送一次 homepage GET因此 Web cookie、网络或 homepage token 的失败会在该构建步骤就暴露出来。该引导对 cookie 是只读的不做 PSIDTS poke/恢复也不做 profile cookie 合并homepage cookie 观测值留在内存中直到如果该已废弃 sidecar 接管为止两条独立的凭据路径类型化命名空间与 Android raw unary 调用使用 profile 的 master token已废弃rpc_call(...)使用引导时加载的 Web cookies。因此仅含 master token 的 profile 可以使用 Android 类型化/raw API但无法使用那个 Web 兼容包装器。文档建议优先使用类型化命名空间必要时再用 Androidraw.unary(...)/raw.unary_stream(...)client.backends的含义它描述已安装的命名空间适配器所以每项都是android它不会重新参数化已废弃的client.rpc_call(...)包装器其RPCMethod标识仍是 Web batchexecute 专属也不意味着每个 Android 工作流只是单次 gRPC 调用。该包装器的兼容 sidecar 从不启动 Web keepalive并随包装器在 v1.0 一起移除。master token 的安全约束master_token.json是一个持久的整账户凭据可以为多个 Google 服务铸造 OAuth token并且能跨密码修改存活。文档给出四条操作约束优先使用专用账户保护所选 profile绝不在日志或提交中暴露 token若可能已泄露到 Google Account 安全设置中吊销对应设备/会话。完整说明见 安装与认证指南 的 Headless server or CI 一节。为什么 Android 协议对 Web 端如此重要这是整个docs/android目录存在的核心理由值得完整展开Webbatchexecute的响应是位置化 JSON 数组。线路上没有任何东西说明下标3意味着什么因此错误的索引是静默的——它会产出一个貌似合理但张冠李戴的值。移动端应用的 protobuf schema 为每个字段都命名了而两者精确对齐JSON index i protobuf tag (i 1)这个等价关系使得 tests/_guardrails/test_wire_contract.py 能够把硬编码的位置常量对着真实 schema而不是对着自身做校验。该守卫测试的模块文档记录了它的由来2026-08 一次针对 Android 应用恢复出的 schema 的审计发现了反转的所有权标志、对调的生成选项、颠倒的状态枚举以及两个指向从未存在过的字段的常量——最后一个甚至配有通过的单元测试。该守卫的三类检查可以完整继承其文档注释A. 声明的映射成立_wire_contract.MAPPINGS中每条记录满足constant proto_tag - 1标记known_bad的条目以xfail承载 issue 引用修复 PR 必须移除该标记B. 常量不逃逸审查src/notebooklm/_web/rows/中每个_*_POS式常量都出现在MAPPINGS或UNMAPPED中——新的位置化读取无法在无人登记指向何物的情况下落地被扫描的范围包括src/notebooklm/_web/rows/全目录以及_web/settings.py、_web/mind_maps.pyC. 枚举值一致客户端枚举成员与恢复出的后端枚举匹配已知的缺口必须显式声明。参考数据就是 docs/android/schema.proto 与 docs/android/enums.txt索引↔tag 等价性的加载逻辑在 tests/_guardrails/_wire_schema.py。文档与证据清单契约、报告与工具docs/android目录的组织原则是先看持久契约再按正在修改的功能去查主题性证据报告验证日期和旧日期报告的哈希保留在各合并文档内部而不是编码进文件名。以下三张表完整继承自 README。契约与清单文件角色endpoints.mdgRPC 方法面与 mobile ⇄ Web 交叉引用proto-evidence-ledger.md精确/本地编译闭包、重放策略、哈希与准入决定schema.proto由 CI 解析的、326 消息 / 879 字段 Dart-AOT 恢复产物enums.txt由 CI 解析的 104 块94 个枚举名整数值清单grpc-service-signature-inferences.json17 个 Web 推导签名外加经过实机验证的配额跨服务别名grpc-service-signature-exceptions.jsonschema-v2 仅路径异常含可导入编解码器与重放策略grpc-runtime-parser-overrides.json有意通过本地 live-field 覆盖层解码的精确路径合并证据报告文件范围artifact-contracts-and-live-validation.md生成家族、表示形式、数据表、重试、思维导图、传输与 Drive 导出grpc-capability-and-signature-evidence.md签名 APK 清单、Web 推导签名、后端路由与语义探针resource-lifecycle-and-public-qualification.mdnotebook 复制/元数据、笔记/导图、标签、集合与公开选择边界public-api-audit.md2026-08-29 拒绝审计快照其三个兼容缝隙此后已闭合web-compat-seam-closure.md当前零 Web 操作协作者边界及闭合最后缝隙的证据file-transfer-evidence.mdScotty 上传与 artifact 下载协议含拦截细节deep-research-evidence.mdDeep Research 线契约、生命周期、复现器与拦截copy-append-suggestion-evidence.md#2283 系列的实机 Android gRPC 证据AddSourcesAsync、AppendSource、CopySourcesAsync、CopyArtifactsAsync、NextStepSuggestions、GetArtifactCustomizationChoicessource-search-evidence.mdRetrieveRelevantChunks/sources.search的 Web 与 Android 实机证据auth-research.mdAndroid OAuth 身份、scope 与 bearer 验证blutter-grpc-signature-evidence.md曾经无法解析的响应 FQN 的精确生成客户端绑定chat-session-control-evidence.md#2303 的 Web/Android 会话状态与取消语义usage-quota-evidence.md实机 compute-meter 计费外加 #2283 / ADR-0037 的 Android 配额消息与路由恢复捕获与工具文件角色capture.md主 HTTP/2 gRPC 拦截操作手册android-traffic-capture.md旧版 root 模拟器 Cronet/Frida 流程blutter-dart3.13.patch用于反编译应用快照的 Dart 3.13 移植补丁可再生工件schema.proto 与 enums.txt 的生成机制schema.proto与enums.txt是可再生工件不是手写文档。之所以提交进仓库是因为 CI 要解析它们正确姿势是重新生成而非手工编辑。生成器是 scripts/parse_pbschema.py 与 scripts/parse_pbenums.pyuv run python scripts/parse_pbschema.py /path/to/blutter/out/build/asm \ docs/android/schema.proto uv run python scripts/parse_pbenums.py /path/to/blutter/out/build \ docs/android/enums.txt默认包目录选择器保留完整的历史证据范围当前 dump 为 67 个文件。schema 生成器报告326 messages, 879 fields并通过同目录的objs.txt解析包标识无法解析的包保持显式而不是从目录名推断。一个具体例子FunctionCall、FunctionResponse、TailwindStruct、TailwindValue位于orchestration.v1.agency目录下的 Dart 库中但注册在google.internal.labs.tailwind.orchestration.v1的PackageName对象下——两个 dump 中都不存在…agency包对象schema 记录的是注册包。嵌套消息保留其// Protobuf FQN:行中传给BuilderInfo的点分名如…TailwindStruct.TailwindStructEntry而message标识符保持 Dart 类名。枚举生成器合并对象池object pool与对象存储object store按(Dart 库, 枚举类)每对输出一块有 10 个类名ArtifactType、DiscoveryMode、OriginalSourceContentType、UserAction等被两个库以不同整数值声明仅按类名合并会让一方静默遮蔽另一方。每个块头标注其[library …][objs adds …]列出仅由对象存储证明的整数值[objs-ONLY]标记完全没有池对象的枚举[aliases …]会标记同一枚举内一个整数携带两个名字当前不存在。守卫加载器对共享名只保留 wire 库的块若其中两块不一致则直接抛错。当前再生身份两个工件都从下述构建重新生成从二进制验证而非假设项值应用Gemini Notebook (NotebookLM)1.55.10.971450265versionCode153888发布于 2026-08-29AOT 库lib/arm64-v8a/libNotebookLM_prod_android_library_flutter_artifacts.soAOT 库 SHA-25677bff7507e393c092b78ff1756bb3d726881050b22728dcc8c46cf0fecd7cda7Dart SDK3.14.0-166.0.devdev 渠道快照哈希8c325a9e3a1c32ffd39325f735c49133重新生成日期2026-09-041.46.7快照082d75e3…Dart3.13.0-256.0.dev仍是日期化捕获报告、版本作用域方法清单以及 blutter-grpc-signature-evidence.md 的基础。签入的 blutter-dart3.13.patch 面向 Dart 3.13本次再生使用的 Dart 3.14 构建尚未固化为补丁。内部适配器的精简编译输入与生成管线内部 Android 适配器使用的精简编译输入位于src/notebooklm/_android/proto_src/。用以下命令重新生成签入的 Python 模块与完整描述符 fixturepython scripts/regenerate_android_protos.py --write # 本地再生 python scripts/regenerate_android_protos.py --check # CI 中校验从源码结构看src/notebooklm/_android/目录共包含近 50 个适配模块如 notebooks.py、notes.py、sources.py、sharing.py、drive_staging.py以及proto/、proto_src/、codecs/三个子树。生成管线的闭包约束是双向钉死的累积的orchestration_service.proto拥有 58 方法的 orchestration 服务sharing.proto拥有单独证明的两方法精确 sharing 服务单个 orchestration 消息覆盖层保持 service-free17 个 orchestration 签名被显式标记为Web 推导的约定名推断ListQuotaSummary单独标记为从实机 orchestration 别名推断的精确消息、跨服务绑定60 个生成方法 单个仅路径的GetAccount异常恰好穷尽 61 条已实现适配器路径。生成描述符、适配器路径、推断来源与哈希钉死的外部方法清单在两个方向上都被签入核对因此任何本地重复声明都无法引入归一化或未解析的响应类型。包与生成 proto 仍是私有实现细节。显式backendandroid选择会为全部 11 个公开命名空间安装 Android 适配器且该 Android 命名空间图中没有任何 Web 操作协作者原生 Android gRPC/Scotty、bearer 鉴权资产、Drive 暂存与本地组合共同覆盖类型化公开契约——recent-removal 走原生 shared-project 路由并把 owned-project 的INTERNAL结果视作 Web 暴露的同义已不存在 no-opCSV/DOCX/PPTX 上传在移动 Scotty 前端无法解析该格式时经 Drive 暂存sharing 查看级别走原生MutateProject的 tag-9 分支。证据与有界分歧记录在 web-compat-seam-closure.md。在 Android 选择下artifact 思维导图生成、source 刷新与 Drive 下载/上传、账户设置、协作者共享和自动标签现已全部保持原生。设置探针曾临时修改一个既有输出语言在finally中验证变更后恢复原值并二次验证。协作者写入均经过 bundle 与字节契约限定没有向受控的第二身份之外发出任何实机邀请。一致性Conformance门禁Collections 与 Notes文档给出两组可选开启opt-in且面向隔离 profile的实机一致性门禁它们各自应对同一账户运行两次以证明清理与重跑安全。Public Collections 一致性Collections 仅对显式backendandroid生效。其永久实机门禁会遍历全部 9 个公开方法并清理一个唯一命名的 notebook 与 collection。对一个同时包含 Web cookies 与兄弟 master token 的隔离 profile运行两次同一门禁export NOTEBOOKLM_PROFILEandroid-collections-e2e export NOTEBOOKLM_ANDROID_COLLECTIONS_CONFORMANCE1 uv run pytest tests/e2e/test_android_collections_conformance.py -m e2e -vv uv run pytest tests/e2e/test_android_collections_conformance.py -m e2e -vvAndroid Notes 一致性鉴权一致性探针遍历完整的 8 方法 Notes 清单包括普通笔记 CRUD 与 note 支撑的思维导图 list/delete。使用一个专用 profile其中同时包含有效 Web cookies 与兄弟 Androidmaster_token.json且账户允许创建和删除一次性 notebook。测试会为其资源加前缀并登记做最终前缀扫描并应连续两次通过export NOTEBOOKLM_PROFILEandroid-notes-e2e export NOTEBOOKLM_ANDROID_NOTES_CONFORMANCE1 uv run pytest tests/e2e/test_android_notes_conformance.py -m e2e -vv uv run pytest tests/e2e/test_android_notes_conformance.py -m e2e -vv该测试只对它创建的、带唯一前缀的资源具有破坏性。保持 profile 隔离遵循仓库 agent 指引并检查最终清理结果。Android 投影只保留有证据支撑的语义未知创建时间为None原始思维导图行包含公开契约支持的[id, content]前缀删除后的精确缺席返回None。Web 软删除 tombstone 属于存储泄漏而非文档化的get_or_none保证因此 Android 端不伪造它。分类后的公开差异清单见 Web vs Android 公开行为清单。会咬人的注意事项Caveats文档专门列出了五条在维护协议证据时必须理解的陷阱全部保留schema.proto中的fieldType是解析失败占位符不是字段名。抽取器在无法恢复真实名字时输出该占位符——879 个字段中有 11 个如此。不要把它当作真实字段。若干消息以不同 tag出现两次。一份是 wire schema…orchestration.v1、…tailwind.v1另一份是应用本地持久化 schema…mobile.app.protos.persistence。查询必须限定到正确的包守卫遇到歧义匹配会拒绝而非猜测。使用合并后的枚举 dump而不仅是对象池。快照对象池只为 104 个 (库, 类) 块中的 102 个内联对象且只覆盖其中一部分成员与对象存储合并后才能得到完整的 104 块 / 94 类名 / 2180 个值。只对着池审计会制造出我们发明了该值的假阳性并掩盖真实成员——ARTIFACT_PENDING_REVIEW正是被这样漏掉的。addUnused()的含义是客户端忽略某字段而不是后端不发送它。该客户端触及的消息中大约一半的addUnused()槽位在线路上是有值的。移动端没有建模它不构成缺席证据。addUnused()保留的是字段槽位不是 tag编号。保留槽位占据的是下一个真实 tag且这些 tag 并不连续——ProjectMetadata的排布是userRole1、五个 unused、createTime9。计数只能告诉你空缺里有多少个tag而不能告诉你是哪些。复现协议恢复APK 本身没有签入仓库约 39 MB 专有二进制已 gitignore。复现流程为自行获取一份 APK按 capture.md 完成流量捕获再应用 blutter-dart3.13.patch 完成快照反编译。两份文档各自记录了验证所对应的精确应用构建版本。docs/android/endpoints.md中还保留了方法面枚举命令与解码命令可作为恢复工作的直接入口# 从 Flutter AOT 库枚举方法路径 strings -a libNotebookLM_...flutter_artifacts.so \ | grep -oE /[a-z][a-z0-9_.]\.[A-Z][A-Za-z0-9]/[A-Z][A-Za-z0-9] | sort -u # 重新生成原始 wire 形状解码器会脱敏字符串/字节值只打印长度 python scripts/decode_mobile_grpc.py /tmp/notebooklm-mobile-grpc MethodSubstring需要强调的是脱敏纪律protobuf 请求体携带 notebook ID、source 文本与聊天历史不要把真实捕获输出粘贴进仓库仓库中的文档继承了解码器的脱敏只打印值长度。小结证据链如何闭环docs/android目录的价值在于它把从二进制恢复出的协议知识管理成了一条可验证、可再生的证据链schema.proto/enums.txt作为 CI 可解析的参考数据支撑 test_wire_contract.py 对 Web 端位置常量的独立校验版本作用域的方法清单与签名 JSON 钉死 gRPC 方法面各合并证据报告按功能主题记录实机验证结论而--write/--check双模的 proto 再生脚本与哈希钉死的再生身份表保证任何人拿到同版本 APK 都能重放整条恢复过程。对维护者而言这套结构意味着修改任一传输层之前先查对应证据报告提交任何位置常量或枚举值之前先让它通过 wire 契约守卫换版本时重新生成而不是手改工件。【免费下载链接】notebooklm-pyUnofficial Python API and agentic skill for Google Gemini Notebook. Full programmatic access to NotebookLMs features—including capabilities the web UI doesnt expose—via Python, CLI, and AI agents like Claude Code, Codex, and OpenClaw.项目地址: https://gitcode.com/GitHub_Trending/no/notebooklm-py创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考