Google NotebookLM 终于有了Python SDK!这个开源项目让AI笔记管理效率提升10倍

Google NotebookLM 终于有了Python SDK!这个开源项目让AI笔记管理效率提升10倍

Google NotebookLM 终于有了Python SDK!这个开源项目让AI笔记管理效率提升10倍

前言

当Google NotebookLM在2023年一经推出,便以其强大的AI辅助笔记功能席卷了整个知识管理圈。它能够理解、上传文档,并基于文档内容回答复杂问题、生成摘要、创建学习指南。然而,尽管NotebookLM的Web界面功能强大,但缺乏官方API和Python SDK一直是开发者们的痛点——无法将它便捷地集成到自己的工作流中。

今天要介绍的这个开源项目notebooklm-py,正是为了解决这一痛点而生。它由开发者teng-lin维护,为NotebookLM提供了一个完整的Python封装,让开发者能够通过代码直接与NotebookLM交互,实现自动化文档处理、智能问答、个性化学习材料生成等功能。

本文将带你从零开始,深入掌握这个强大的工具,让你真正把AI笔记系统融入到自己的开发工作流中。


为什么值得关注 / Why This Project Matters

解决的实际痛点

在日常工作和学习中,你是否遇到过以下场景?

手动复制粘贴文档内容到各种工具中进行处理,效率低下且容易出错。希望能够自动化批量处理大量文档,但NotebookLM没有提供API接口。想要将NotebookLM的强大能力集成到自己的应用或网站中,却无从下手。需要定时对某些文档进行更新和分析,但只能手动操作。

notebooklm-py正是为了解决这些痛点而生的:

痛点                          notebooklm-py解决方案
─────────────────────────────────────────────────────────
缺乏API接口            →      提供完整的Python API封装
手动操作效率低         →      支持批量自动化处理
难以集成到现有系统     →      简洁的函数调用,易于集成
无法定时任务处理       →      可与Python调度库完美配合

核心价值

1. 官方能力的完整映射

这个项目并非简单的爬虫或逆向工程,而是通过模拟浏览器行为的方式,实现了对NotebookLM核心功能的完整调用。你可以通过它完成几乎所有Web端能做的事情。

2. 开源透明,完全可控

代码完全开源,你可以查看每一行实现逻辑,了解数据是如何被处理的。这对于需要将敏感文档交给第三方服务的用户来说尤为重要。

3. 灵活扩展,无限可能

基于Python的天然优势,你可以将它与LangChain、ChromaDB、FastAPI等工具结合,构建更复杂的AI应用。


环境搭建 / Getting Started

前置要求

在开始之前,请确保你的环境满足以下要求:

Python版本:3.8 或更高版本(推荐3.10+)网络环境:能够正常访问Google NotebookLM及其相关服务操作系统:Windows、macOS、Linux均可

安装步骤

方式一:通过pip直接安装(推荐)

打开终端或命令行,执行以下命令:

pip install notebooklm-py

方式二:从源码安装(适合开发者)

如果你想要使用最新功能或参与开发,可以从GitHub拉取源码:

git clone https://github.com/teng-lin/notebooklm-py.git
cd notebooklm-py
pip install -e .

方式三:使用uv安装(更快的包管理)

如果你使用uv作为包管理器:

uv pip install notebooklm-py

验证安装

安装完成后,可以通过以下命令验证是否安装成功:

import notebooklm

print(f"notebooklm-py版本: {notebooklm.__version__}")
# 输出类似:notebooklm-py版本: 0.1.2

核心依赖说明

notebooklm-py的核心依赖包括:

requests        - 用于HTTP请求
beautifulsoup4  - 用于解析HTML
lxml           - XML/HTML解析器
tqdm           - 进度条显示
pydantic       - 数据模型验证

这些依赖会在安装时自动安装。如果你遇到依赖冲突,可以单独安装指定版本。


核心功能详解 / Core Features

功能概览

notebooklm-py提供了以下核心功能模块:

┌─────────────────────────────────────────────────────────┐
│                  notebooklm-py 功能架构                   │
├─────────────────────────────────────────────────────────┤
│  📁 文档管理                                              │
│     ├── 上传本地文件(PDF、TXT、DOCX等)                    │
│     ├── 添加网页内容                                      │
│     ├── 管理Notebook中的文档                              │
│     └── 删除文档                                          │
├─────────────────────────────────────────────────────────┤
│  💬 AI对话                                               │
│     ├── 基于文档的智能问答                                │
│     ├── 多轮对话支持                                      │
│     └── 上下文管理                                        │
├─────────────────────────────────────────────────────────┤
│  📝 内容生成                                             │
│     ├── 生成摘要                                         │
│     ├── 创建FAQ                                          │
│     ├── 生成学习指南                                      │
│     └── 制作时间线                                       │
├─────────────────────────────────────────────────────────┤
│  🎙️ 播客功能                                             │
│     ├── 生成Audio Overview                               │
│     └── 管理音频内容                                     │
└─────────────────────────────────────────────────────────┘

初始化配置

使用notebooklm-py的第一步是创建NotebookLM客户端实例:

from notebooklm import NotebookLMClient

# 方式一:使用OAuth认证(推荐)
client = NotebookLMClient()

# 方式二:使用API密钥(如果项目支持)
client = NotebookLMClient(api_key="your_api_key")

# 方式三:使用代理(如果网络需要)
client = NotebookLMClient(proxy="http://127.0.0.1:7890")

认证机制详解

OAuth认证流程

OAuth是目前推荐的认证方式,它安全且易于使用:

from notebooklm import NotebookLMClient
from notebooklm.auth import GoogleAuthenticator

# 初始化认证器
auth = GoogleAuthenticator()

# 启动本地认证服务器
# 这会自动打开浏览器让你登录Google账号
credentials = auth.authenticate()

# 使用credentials创建客户端
client = NotebookLMClient(credentials=credentials)

# 建议:将credentials保存以便后续使用
import json
with open('credentials.json', 'w') as f:
    json.dump(credentials, f)

加载已保存的credentials

import json
from notebooklm import NotebookLMClient

with open('credentials.json', 'r') as f:
    credentials = json.load(f)

client = NotebookLMClient(credentials=credentials)

实战教程 / Step-by-Step Tutorial

实战一:创建Notebook并上传文档

这是最基础也是最常用的功能。下面的例子展示了如何创建一个新的Notebook并上传多个文档:

from notebooklm import NotebookLMClient
import json

# 初始化客户端
client = NotebookLMClient()

# 创建新的Notebook
notebook = client.create_notebook(
    title="技术文档分析",
    description="用于分析项目技术文档的Notebook"
)

print(f"创建成功!Notebook ID: {notebook.id}")
print(f"Notebook 标题: {notebook.title}")

上传文档有多种方式:

# 上传本地文件
doc1 = client.upload_document(
    notebook_id=notebook.id,
    file_path="path/to/document.pdf"
)

# 上传多个文件(批量操作)
file_paths = [
    "path/to/file1.txt",
    "path/to/file2.pdf",
    "path/to/doc.docx",
    "path/to/notes.md"
]

uploaded_docs = client.upload_documents(
    notebook_id=notebook.id,
    file_paths=file_paths,
    show_progress=True  # 显示上传进度
)

print(f"成功上传 {len(uploaded_docs)} 个文档")

# 查看上传结果
for doc in uploaded_docs:
    print(f"文档名: {doc.name}, 大小: {doc.size}, 状态: {doc.status}")

支持的文档格式

格式类型          扩展名                    说明
───────────────────────────────────────────────────────
文本文件          .txt, .md, .csv           纯文本格式
PDF文档          .pdf                      扫描版需OCR支持
Word文档         .docx, .doc               微软文档格式
Google文档       -                         支持Google Drive导入
网页内容          URL                       直接抓取网页内容
音频文件          .mp3, .wav, .m4a          未来可能支持
视频文件          .mp4, .webm               未来可能支持

实战二:智能问答

基于上传的文档进行智能问答是NotebookLM的核心能力之一:

# 基础问答
question = "这份文档的核心主题是什么?"
response = client.ask_question(
    notebook_id=notebook.id,
    question=question
)

print(f"问题: {question}")
print(f"回答: {response.answer}")
print(f"引用来源: {response.citations}")

多轮对话示例

# 开始一个新对话
conversation = client.start_conversation(notebook_id=notebook.id)

# 第一轮对话
response1 = conversation.ask("项目的技术架构是怎样的?")
print(f"回答1: {response1.answer}")

# 第二轮对话(基于上下文)
response2 = conversation.ask("能否详细解释一下数据库设计?")
print(f"回答2: {response2.answer}")

# 第三轮对话
response3 = conversation.ask("有没有什么性能优化的建议?")
print(f"回答3: {response3.answer}")

# 查看对话历史
for msg in conversation.history:
    print(f"{msg.role}: {msg.content}")

带参数的问答

# 自定义回答风格
response = client.ask_question(
    notebook_id=notebook.id,
    question="总结一下主要观点",
    style="简洁",  # 可选:简洁/详细/专业
    language="中文"  # 回答语言
)

# 限制回答长度
response = client.ask_question(
    notebook_id=notebook.id,
    question="详细解释这个概念",
    max_length=500,  # 最大字数
    include_sources=True  # 包含来源引用
)

实战三:生成学习材料

NotebookLM强大的内容生成功能可以通过代码调用:

# 生成摘要
summary = client.generate_summary(
    notebook_id=notebook.id,
    style="详细"  # 或 "简洁"
)

print("=" * 50)
print("文档摘要")
print("=" * 50)
print(summary.content)

# 生成FAQ
faq = client.generate_faq(
    notebook_id=notebook.id,
    count=10  # 生成的问题数量
)

print("\n" + "=" * 50)
print("常见问题 (FAQ)")
print("=" * 50)

for i, item in enumerate(faq.items, 1):
    print(f"\nQ{i}: {item.question}")
    print(f"A{i}: {item.answer}")

生成学习指南

# 创建学习指南
study_guide = client.generate_study_guide(
    notebook_id=notebook.id,
    format="markdown"  # markdown 或 html
)

# 保存到文件
with open("study_guide.md", "w", encoding="utf-8") as f:
    f.write(study_guide.content)

print("学习指南已生成!")

生成时间线

# 提取文档中的时间信息,生成时间线
timeline = client.generate_timeline(
    notebook_id=notebook.id
)

for event in timeline.events:
    print(f"[{event.date}] {event.title}")
    print(f"    描述: {event.description}")

实战四:批量处理多个Notebook

如果你有大量的文档需要处理,可以批量操作:

from notebooklm import NotebookLMClient
from concurrent.futures import ThreadPoolExecutor, as_completed

client = NotebookLMClient()

# 准备要处理的文件列表
documents = [
    {"title": "项目需求文档", "path": "docs/requirements.pdf"},
    {"title": "技术设计文档", "path": "docs/design.pdf"},
    {"title": "API接口文档", "path": "docs/api.pdf"},
    {"title": "测试报告", "path": "docs/testing.pdf"},
    {"title": "用户手册", "path": "docs/manual.pdf"},
]

def process_document(doc_info):
    """处理单个文档的函数"""
    try:
        # 创建Notebook
        notebook = client.create_notebook(
            title=doc_info["title"]
        )

        # 上传文档
        client.upload_document(
            notebook_id=notebook.id,
            file_path=doc_info["path"]
        )

        # 生成摘要
        summary = client.generate_summary(notebook_id=notebook.id)

        return {
            "title": doc_info["title"],
            "status": "success",
            "notebook_id": notebook.id,
            "summary": summary.content[:200]  # 截取前200字
        }
    except Exception as e:
        return {
            "title": doc_info["title"],
            "status": "failed",
            "error": str(e)
        }

# 使用多线程加速处理
with ThreadPoolExecutor(max_workers=3) as executor:
    futures = {
        executor.submit(process_document, doc): doc 
        for doc in documents
    }

    results = []
    for future in as_completed(futures):
        result = future.result()
        results.append(result)
        status = "✓" if result["status"] == "success" else "✗"
        print(f"{status} {result['title']}")

# 汇总报告
success_count = sum(1 for r in results if r["status"] == "success")
print(f"\n处理完成:{success_count}/{len(results)} 成功")

实战五:构建知识库问答系统

将notebooklm-py与向量数据库结合,可以构建更强大的知识库系统:

from notebooklm import NotebookLMClient
from notebooklm import Notebook
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
import os

# 初始化
client = NotebookLMClient()
embeddings = OpenAIEmbeddings(openai_api_key=os.getenv("OPENAI_API_KEY"))

# 获取Notebook中的所有文档
notebook = client.get_notebook(notebook_id="your_notebook_id")
documents = notebook.get_documents()

# 准备文本数据
texts = []
metadatas = []

for doc in documents:
    # 文档内容
    content = doc.get_content()

    # 分块处理
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=1000,
        chunk_overlap=200,
        length_function=len
    )

    chunks = text_splitter.split_text(content)

    for i, chunk in enumerate(chunks):
        texts.append(chunk)
        metadatas.append({
            "document_id": doc.id,
            "document_name": doc.name,
            "chunk_index": i,
            "source": "notebooklm"
        })

# 创建向量存储
print("正在创建向量索引...")
vectorstore = Chroma.from_texts(
    texts=texts,
    embedding=embeddings,
    metadatas=metadatas,
    persist_directory="./vectorstore_db"
)

print("向量数据库构建完成!")

# 查询示例
query = "这个项目的部署流程是什么?"
docs = vectorstore.similarity_search(query, k=3)

print(f"\n查询: {query}")
print("=" * 50)

for i, doc in enumerate(docs, 1):
    print(f"\n结果 {i}:")
    print(f"来源: {doc.metadata['document_name']}")
    print(f"内容: {doc.page_content[:300]}...")

实战六:自动化定时任务

结合Python的调度库,可以实现文档的自动更新和分析:

import schedule
import time
from notebooklm import NotebookLMClient

client = NotebookLMClient()

def daily_report_task():
    """每日报告任务"""
    print("开始执行每日报告生成任务...")

    # 获取目标Notebook
    notebook = client.get_notebook("daily_summary_notebook_id")

    # 检查是否有新文档
    new_docs = notebook.check_updates(since="last_check")

    if new_docs:
        print(f"发现 {len(new_docs)} 个新文档")

        # 上传新文档
        for doc in new_docs:
            client.upload_document(
                notebook_id=notebook.id,
                file_path=doc.path
            )

        # 生成当日摘要
        summary = client.generate_summary(notebook_id=notebook.id)

        # 发送通知(可以是邮件、Slack等)
        send_notification(
            title="📊 每日文档摘要",
            content=summary.content
        )

        print("任务完成!")
    else:
        print("今日无新文档")

def send_notification(title, content):
    """发送通知的示例函数"""
    # 这里可以接入钉钉、飞书、邮件等通知服务
    print(f"\n通知标题: {title}")
    print(f"通知内容:\n{content}")

# 设置定时任务
schedule.every().day.at("09:00").do(daily_report_task)        # 每天早上9点
schedule.every().monday.at("10:00").do(daily_report_task)     # 每周一早上10点

print("定时任务已启动...")
print("按 Ctrl+C 停止")

# 运行调度器
while True:
    schedule.run_pending()
    time.sleep(60)

常见使用场景 / Common Use Cases

场景一:学术研究辅助

如果你是一名研究人员,可以使用notebooklm-py来管理大量的论文和文献:

from notebooklm import NotebookLMClient

client = NotebookLMClient()

# 为每个研究主题创建Notebook
topics = [
    "machine_learning",
    "natural_language_processing",
    "computer_vision"
]

notebooks = {}
for topic in topics:
    notebooks[topic] = client.create_notebook(
        title=f"{topic} 论文汇总"
    )

# 上传论文到对应的Notebook
paper_topics = {
    "papers/attention_is_all_you_need.pdf": "natural_language_processing",
    "papers/bert_pre-training.pdf": "natural_language_processing",
    "papers/resnet.pdf": "computer_vision",
    "papers/gan.pdf": "computer_vision",
}

for paper_path, topic in paper_topics.items():
    client.upload_document(
        notebook_id=notebooks[topic].id,
        file_path=paper_path
    )

# 跨主题对比分析
question = "这三个领域中,深度学习的主要应用有什么异同?"
response = client.ask_cross_notebook(
    source_ids=[n.id for n in notebooks.values()],
    question=question
)

print(response.answer)

场景二:企业知识库建设

企业可以利用notebooklm-py构建内部知识库系统:

from notebooklm import NotebookLMClient
from notebooklm.models import KnowledgeBase

client = NotebookLMClient()

# 创建企业知识库
kb = client.create_knowledge_base(
    name="公司产品知识库",
    description="包含所有产品的技术文档、用户手册和常见问题"
)

# 添加不同类型的文档
document_sources = {
    "产品技术文档": "docs/products/tech_specs/",
    "用户手册": "docs/products/user_guides/",
    "常见问题": "docs/products/faqs/",
    "培训材料": "docs/training/",
    "服务政策": "docs/policies/"
}

for category, path in document_sources.items():
    # 扫描目录下的所有文件
    import os
    for filename in os.listdir(path):
        if filename.endswith(('.pdf', '.docx', '.txt')):
            client.upload_document(
                notebook_id=kb.id,
                file_path=os.path.join(path, filename),
                category=category
            )

# 创建员工问答机器人
print("知识库已准备就绪!")
print(f"Notebook ID: {kb.id}")

# 员工可以这样查询
answer = client.ask_question(
    notebook_id=kb.id,
    question="产品的退换货政策是什么?"
)

场景三:法律文档分析

from notebooklm import NotebookLMClient

client = NotebookLMClient()

# 创建合同分析Notebook
contract_notebook = client.create_notebook(
    title="合同审查 - 2024年合同包"
)

# 上传待审查的合同
contracts = [
    "contracts/contract_A.pdf",
    "contracts/contract_B.pdf",
    "contracts/contract_C.pdf"
]

for contract in contracts:
    client.upload_document(
        notebook_id=contract_notebook.id,
        file_path=contract
    )

# 生成风险点分析
risks = client.analyze_risks(
    notebook_id=contract_notebook.id,
    risk_categories=["payment", "liability", "termination", "confidentiality"]
)

print("合同风险分析报告")
print("=" * 50)

for category, items in risks.items():
    print(f"\n{category}】")
    for item in items:
        print(f"  ⚠️ {item.description}")
        print(f"     风险等级: {item.severity}")
        print(f"     建议: {item.recommendation}")

技巧与最佳实践 / Tips and Best Practices

性能优化技巧

1. 批量处理减少API调用

# 不推荐:逐个上传
for file_path in file_list:
    client.upload_document(notebook_id=notebook_id, file_path=file_path)

# 推荐:批量上传
client.upload_documents(
    notebook_id=notebook_id,
    file_paths=file_list,
    show_progress=True
)

2. 合理使用缓存

from notebooklm import NotebookLMClient
from notebooklm.cache import FileCache

# 初始化带缓存的客户端
cache = FileCache(cache_dir="./cache")
client = NotebookLMClient(cache=cache)

# 相同内容的文档会被缓存,不会重复上传
for doc in document_list:
    client.upload_document(
        notebook_id=notebook_id,
        file_path=doc,
        use_cache=True  # 启用缓存
    )

3. 并发控制

from notebooklm import NotebookLMClient
from notebooklm.rate_limiter import RateLimiter

# 设置请求速率限制
rate_limiter = RateLimiter(max_calls=10, period=60)  # 60秒内最多10次请求
client = NotebookLMClient(rate_limiter=rate_limiter)

错误处理最佳实践

from notebooklm import NotebookLMClient
from notebooklm.exceptions import (
    AuthenticationError,
    UploadError,
    QuotaExceededError,
    NetworkError
)

client = NotebookLMClient()

def robust_upload(file_path, notebook_id, max_retries=3):
    """带重试机制的上传函数"""
    for attempt in range(max_retries):
        try:
            result = client.upload_document(
                notebook_id=notebook_id,
                file_path=file_path
            )
            return result

        except AuthenticationError:
            print("认证失败,请检查登录状态")
            raise

        except QuotaExceededError:
            print(f"配额已用完,等待重试... (尝试 {attempt + 1}/{max_retries})")
            import time
            time.sleep(60)  # 等待1分钟后重试

        except NetworkError as e:
            print(f"网络错误: {e}")
            if attempt < max_retries - 1:
                import time
                time.sleep(5 ** attempt)  # 指数退避
            else:
                raise

        except UploadError as e:
            print(f"上传失败: {e}")
            raise

    return None

# 使用示例
result = robust_upload("test.pdf", notebook_id)

安全性建议

# 1. 不要在代码中硬编码凭证
import os

# 正确做法:使用环境变量
client = NotebookLMClient(
    credentials_path=os.environ.get("NOTEBOOKLM_CREDENTIALS")
)

# 2. 定期刷新令牌
def refresh_credentials_if_needed(credentials):
    import time

    # 检查token是否即将过期
    if credentials.is_expiring_soon(threshold_seconds=3600):
        print("Token即将过期,正在刷新...")
        new_credentials = credentials.refresh()
        # 保存新凭证
        credentials.save("credentials.json")
        return new_credentials

    return credentials

# 3. 处理敏感文档时的额外注意
def upload_with_encryption(file_path, notebook_id):
    """上传前加密敏感内容"""
    # 仅在必要时使用
    encrypted_path = encrypt_file(file_path)

    try:
        result = client.upload_document(
            notebook_id=notebook_id,
            file_path=encrypted_path
        )
        return result
    finally:
        # 清理临时文件
        cleanup_temp_files()

代码组织建议

"""
项目结构推荐示例
"""
# project/
# ├── config.py              # 配置文件
# ├── client.py              # NotebookLM客户端初始化
# ├── notebooks/              # Notebook管理
# │   ├── __init__.py
# │   ├── manager.py         # Notebook管理器
# │   └── templates.py      # 常用模板
# ├── processors/            # 文档处理器
# │   ├── __init__.py
# │   ├── pdf_processor.py
# │   └── text_processor.py
# ├── tasks/                # 定时任务
# │   ├── __init__.py
# │   └── scheduler.py
# ├── utils/                # 工具函数
# │   ├── __init__.py
# │   └── helpers.py
# ├── main.py               # 主入口
# └── requirements.txt

# config.py
import os

class Config:
    """配置类"""
    NOTEBOOKLM_CREDENTIALS = os.environ.get("NOTEBOOKLM_CREDENTIALS")
    DEFAULT_NOTEBOOK_TITLE = "自动创建的Notebook"
    MAX_UPLOAD_SIZE = 50 * 1024 * 1024  # 50MB
    SUPPORTED_FORMATS = [".pdf", ".txt", ".docx", ".md", ".csv"]
    RATE_LIMIT = {"calls": 10, "period": 60}

    # 代理设置
    PROXY = os.environ.get("HTTPS_PROXY") or os.environ.get("HTTP_PROXY")

    # 缓存设置
    CACHE_ENABLED = True
    CACHE_DIR = "./cache"

# client.py
from notebooklm import NotebookLMClient
from config import Config

def get_client():
    """获取配置好的客户端实例"""
    return NotebookLMClient(
        credentials_path=Config.NOTEBOOKLM_CREDENTIALS,
        proxy=Config.PROXY,
        cache_enabled=Config.CACHE_ENABLED,
        cache_dir=Config.CACHE_DIR
    )

# 全局客户端实例
client = get_client()

项目扩展与生态 / Extending the Project

与LangChain集成

notebooklm-py可以与LangChain的无缝集成,构建更复杂的AI应用:

from notebooklm import NotebookLMClient
from langchain.agents import initialize_agent, Tool
from langchain.llms import OpenAI

# 初始化NotebookLM客户端
client = NotebookLMClient()

# 定义工具
def search_notebook(query: str) -> str:
    """在Notebook中搜索相关内容"""
    response = client.ask_question(
        notebook_id="default_notebook_id",
        question=query
    )
    return response.answer

tools = [
    Tool(
        name="Notebook搜索",
        func=search_notebook,
        description="用于在NotebookLM中搜索文档内容。输入应该是具体的搜索问题。"
    )
]

# 初始化代理
llm = OpenAI(temperature=0)
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent="zero-shot-react-description",
    verbose=True
)

# 使用代理
result = agent.run(
    "请帮我查找关于Python异步编程的资料,并总结要点"
)

与FastAPI构建Web服务

from fastapi import FastAPI, UploadFile, File, HTTPException
from notebooklm import NotebookLMClient
from pydantic import BaseModel
import os

app = FastAPI(title="NotebookLM API服务")
client = NotebookLMClient()

class QuestionRequest(BaseModel):
    notebook_id: str
    question: str

class QuestionResponse(BaseModel):
    answer: str
    sources: list

@app.post("/upload", response_model=dict)
async def upload_document(file: UploadFile = File(...)):
    """上传文档"""
    # 保存上传的文件
    temp_path = f"/tmp/{file.filename}"
    with open(temp_path, "wb") as f:
        content = await file.read()
        f.write(content)

    try:
        # 创建Notebook并上传
        notebook = client.create_notebook(title=file.filename)
        doc = client.upload_document(
            notebook_id=notebook.id,
            file_path=temp_path
        )

        return {
            "notebook_id": notebook.id,
            "document_id": doc.id,
            "status": "success"
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
    finally:
        # 清理临时文件
        if os.path.exists(temp_path):
            os.remove(temp_path)

@app.post("/ask", response_model=QuestionResponse)
async def ask_question(request: QuestionRequest):
    """提问"""
    response = client.ask_question(
        notebook_id=request.notebook_id,
        question=request.question
    )

    return QuestionResponse(
        answer=response.answer,
        sources=response.citations or []
    )

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

与Streamlit构建可视化界面

import streamlit as st
from notebooklm import NotebookLMClient

st.set_page_config(page_title="NotebookLM助手", page_icon="📚")

# 初始化客户端
if "client" not in st.session_state:
    st.session_state.client = NotebookLMClient()

client = st.session_state.client

st.title("📚 NotebookLM 智能助手")

# 侧边栏 - 文档管理
with st.sidebar:
    st.header("文档管理")

    uploaded_file = st.file_uploader(
        "上传文档",
        type=["pdf", "txt", "docx", "md"]
    )

    if uploaded_file:
        if st.button("上传到Notebook"):
            with st.spinner("上传中..."):
                # 保存并上传文件
                save_path = f"/tmp/{uploaded_file.name}"
                with open(save_path, "wb") as f:
                    f.write(uploaded_file.getbuffer())

                notebook = client.create_notebook(title=uploaded_file.name)
                client.upload_document(notebook_id=notebook.id, file_path=save_path)

                st.success(f"上传成功!Notebook ID: {notebook.id}")

# 主界面 - 问答功能
st.header("💬 智能问答")

notebook_id = st.text_input("Notebook ID", placeholder="输入Notebook ID")
question = st.text_area("输入你的问题", placeholder="在这里输入问题...")

if st.button("获取答案"):
    if notebook_id and question:
        with st.spinner("思考中..."):
            response = client.ask_question(
                notebook_id=notebook_id,
                question=question
            )

            st.markdown("### 回答")
            st.write(response.answer)

            if response.citations:
                st.markdown("### 来源")
                for citation in response.citations:
                    st.write(f"- {citation}")
    else:
        st.warning("请输入Notebook ID和问题")

# 生成内容功能
st.header("📝 内容生成")

col1, col2 = st.columns(2)

with col1:
    if st.button("生成摘要"):
        if notebook_id:
            with st.spinner("生成中..."):
                summary = client.generate_summary(notebook_id=notebook_id)
                st.markdown("### 摘要")
                st.write(summary.content)

with col2:
    if st.button("生成FAQ"):
        if notebook_id:
            with st.spinner("生成中..."):
                faq = client.generate_faq(notebook_id=notebook_id, count=5)
                st.markdown("### 常见问题")
                for i, item in enumerate(faq.items, 1):
                    st.write(f"**Q{i}: {item.question}**")
                    st.write(f"A{i}: {item.answer}")
                    st.write("")

常见问题解答 / FAQ

Q1: 遇到”Quota Exceeded”错误怎么办?

这是因为NotebookLM对API调用有限制。解决方案:

# 方案一:使用缓存避免重复请求
client = NotebookLMClient(cache_enabled=True)

# 方案二:添加延时
import time
time.sleep(5)  # 在请求之间添加5秒延时

# 方案三:联系Google提高配额(针对企业用户)

Q2: 如何处理大文件上传?

# 分块上传大文件
def upload_large_file(client, notebook_id, file_path, chunk_size=10*1024*1024):
    """分块上传大文件"""
    import os

    file_size = os.path.getsize(file_path)

    if file_size > 50 * 1024 * 1024:  # 超过50MB
        print(f"文件较大 ({file_size / 1024 / 1024:.1f}MB),建议压缩或拆分")

    # 使用进度条显示上传进度
    from tqdm import tqdm

    with open(file_path, 'rb') as f:
        with tqdm(total=file_size, unit='B', unit_scale=True) as pbar:
            while chunk := f.read(chunk_size):
                # 这里可以实现分块上传逻辑
                pbar.update(len(chunk))

Q3: 如何获取Notebook的历史记录?

# 获取对话历史
notebook = client.get_notebook(notebook_id="your_notebook_id")

# 列出所有对话
conversations = notebook.list_conversations()

for conv in conversations:
    print(f"对话ID: {conv.id}")
    print(f"创建时间: {conv.created_at}")
    print(f"消息数: {len(conv.messages)}")

    # 获取对话详情
    messages = conv.get_messages()
    for msg in messages:
        print(f"  [{msg.role}]: {msg.content[:100]}...")

Q4: 出现认证失败如何解决?

# 重新进行OAuth认证
from notebooklm.auth import GoogleAuthenticator

def reauthenticate():
    """清除旧凭证并重新认证"""
    import os

    # 删除旧凭证
    credentials_file = "credentials.json"
    if os.path.exists(credentials_file):
        os.remove(credentials_file)

    # 重新认证
    auth = GoogleAuthenticator()
    credentials = auth.authenticate()

    # 保存新凭证
    with open(credentials_file, 'w') as f:
        import json
        json.dump(credentials, f)

    return credentials

# 调用重新认证
credentials = reauthenticate()

结语 / Conclusion

notebooklm-py为开发者打开了一扇通往NotebookLM强大能力的大门。通过这个开源项目,你不再局限于Web界面,而是可以将AI辅助笔记功能自由地融入到任何工作流程中。

无论你是:

研究人员,可以用它来管理海量的论文文献,进行跨领域对比分析学生,可以用它来整理学习资料,生成个性化的复习指南开发者,可以用它来构建知识库系统,实现智能客服或文档问答企业,可以用它来自动化处理内部文档,提高团队协作效率

notebooklm-py都能成为你的得力助手。

相关资源链接

GitHub仓库:https://github.com/teng-lin/notebooklm-py

官方文档:https://notebooklm-py.readthedocs.io

问题反馈:https://github.com/teng-lin/notebooklm-py/issues

推荐阅读

如果你对AI和知识管理感兴趣,以下资源也值得一看:

LangChain文档 – 构建LLM应用的强大框架Chroma文档 – 开源向量数据库FAISS – Facebook开源的向量检索库Streamlit文档 – 快速构建数据应用的框架

行动起来

现在你已经掌握了这个强大的工具,是时候开始实践了!建议从以下几个小项目开始:

搭建一个本地文档问答系统自动化你的周报生成流程构建一个基于NotebookLM的个人知识管理系统

记住,最好的学习方式就是动手实践。祝你玩得开心!


本文会持续更新以跟进项目最新功能。如有任何问题或建议,欢迎在GitHub仓库中提Issue。

如果内容对您有帮助,欢迎打赏

您的支持是我继续创作的动力

前往打赏页面

评论区

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注