open-notebook

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Open Notebook

Open Notebook

Overview

概述

Open Notebook is an open-source, self-hosted alternative to Google's NotebookLM that enables researchers to organize materials, generate AI-powered insights, create podcasts, and have context-aware conversations with their documents — all while maintaining complete data privacy.
Unlike Google's Notebook LM, which has no publicly available API outside of the Enterprise version, Open Notebook provides a comprehensive REST API, supports 16+ AI providers, and runs entirely on your own infrastructure.
Key advantages over NotebookLM:
  • Full REST API for programmatic access and automation
  • Choice of 16+ AI providers (not locked to Google models)
  • Multi-speaker podcast generation with 1-4 customizable speakers (vs. 2-speaker limit)
  • Complete data sovereignty through self-hosting
  • Open source and fully extensible (MIT license)
Open Notebook是一款开源、自托管的Google NotebookLM替代工具,研究人员可通过它整理材料、生成AI驱动的洞察、创建播客,并与文档进行上下文感知对话——同时保持完全的数据隐私。
与Google NotebookLM不同(除企业版外无公开API),Open Notebook提供完整的REST API,支持16+ AI提供商,且完全运行在您自己的基础设施上。
相对NotebookLM的核心优势:
  • 完整的REST API,支持程序化访问和自动化
  • 可选择16+ AI提供商(不局限于Google模型)
  • 支持1-4个可自定义主播的多主播播客生成(对比NotebookLM的2主播限制)
  • 通过自托管实现完全的数据主权
  • 开源且可完全扩展(MIT许可证)

Quick Start

快速开始

Prerequisites

前置条件

  • Docker Desktop installed
  • API key for at least one AI provider (or local Ollama for free local inference)
  • 已安装Docker Desktop
  • 至少一个AI提供商的API密钥(或使用本地Ollama进行免费本地推理)

Installation

安装

Deploy Open Notebook using Docker Compose:
bash
undefined
使用Docker Compose部署Open Notebook:
bash
undefined

Download the docker-compose file

Download the docker-compose file

Set the required encryption key

Set the required encryption key

export OPEN_NOTEBOOK_ENCRYPTION_KEY="your-secret-key-here"
export OPEN_NOTEBOOK_ENCRYPTION_KEY="your-secret-key-here"

Launch the services

Launch the services

docker-compose up -d

Access the application:
- **Frontend UI:** http://localhost:8502
- **REST API:** http://localhost:5055
- **API Documentation:** http://localhost:5055/docs
docker-compose up -d

访问应用:
- **前端UI:** http://localhost:8502
- **REST API:** http://localhost:5055
- **API文档:** http://localhost:5055/docs

Configure AI Provider

配置AI提供商

After startup, configure at least one AI provider:
  1. Navigate to Settings > API Keys in the UI
  2. Add credentials for your preferred provider (OpenAI, Anthropic, etc.)
  3. Test the connection and discover available models
  4. Register models for use across the platform
Or configure via the REST API:
python
import requests

BASE_URL = "http://localhost:5055/api"
启动后,至少配置一个AI提供商:
  1. 在UI中导航至设置 > API密钥
  2. 添加您偏好的提供商(OpenAI、Anthropic等)的凭证
  3. 测试连接并发现可用模型
  4. 注册模型以在全平台使用
或通过REST API配置:
python
import requests

BASE_URL = "http://localhost:5055/api"

Add a credential for an AI provider

Add a credential for an AI provider

response = requests.post(f"{BASE_URL}/credentials", json={ "provider": "openai", "name": "My OpenAI Key", "api_key": "sk-..." }) credential = response.json()
response = requests.post(f"{BASE_URL}/credentials", json={ "provider": "openai", "name": "My OpenAI Key", "api_key": "sk-..." }) credential = response.json()

Discover available models

Discover available models

response = requests.post( f"{BASE_URL}/credentials/{credential['id']}/discover" ) discovered = response.json()
response = requests.post( f"{BASE_URL}/credentials/{credential['id']}/discover" ) discovered = response.json()

Register discovered models

Register discovered models

requests.post( f"{BASE_URL}/credentials/{credential['id']}/register-models", json={"model_ids": [m["id"] for m in discovered["models"]]} )
undefined
requests.post( f"{BASE_URL}/credentials/{credential['id']}/register-models", json={"model_ids": [m["id"] for m in discovered["models"]]} )
undefined

Core Features

核心功能

Notebooks

笔记本

Organize research into separate notebooks, each containing sources, notes, and chat sessions.
python
import requests

BASE_URL = "http://localhost:5055/api"
将研究内容整理到独立的笔记本中,每个笔记本包含来源、笔记和对话会话。
python
import requests

BASE_URL = "http://localhost:5055/api"

Create a notebook

Create a notebook

response = requests.post(f"{BASE_URL}/notebooks", json={ "name": "Cancer Genomics Research", "description": "Literature review on tumor mutational burden" }) notebook = response.json() notebook_id = notebook["id"]
undefined
response = requests.post(f"{BASE_URL}/notebooks", json={ "name": "Cancer Genomics Research", "description": "Literature review on tumor mutational burden" }) notebook = response.json() notebook_id = notebook["id"]
undefined

Sources

内容来源

Ingest diverse content types including PDFs, videos, audio files, web pages, and Office documents. Sources are processed for full-text and vector search.
python
undefined
导入多样化内容类型,包括PDF、视频、音频文件、网页和Office文档。来源会经过处理以支持全文检索和向量搜索。
python
undefined

Add a web URL source

Add a web URL source

response = requests.post(f"{BASE_URL}/sources", data={ "url": "https://arxiv.org/abs/2301.00001", "notebook_id": notebook_id, "process_async": "true" }) source = response.json()
response = requests.post(f"{BASE_URL}/sources", data={ "url": "https://arxiv.org/abs/2301.00001", "notebook_id": notebook_id, "process_async": "true" }) source = response.json()

Upload a PDF file

Upload a PDF file

with open("paper.pdf", "rb") as f: response = requests.post( f"{BASE_URL}/sources", data={"notebook_id": notebook_id}, files={"file": ("paper.pdf", f, "application/pdf")} )
undefined
with open("paper.pdf", "rb") as f: response = requests.post( f"{BASE_URL}/sources", data={"notebook_id": notebook_id}, files={"file": ("paper.pdf", f, "application/pdf")} )
undefined

Notes

笔记

Create and manage notes (human or AI-generated) associated with notebooks.
python
undefined
创建和管理与笔记本关联的笔记(人工或AI生成)。
python
undefined

Create a human note

Create a human note

response = requests.post(f"{BASE_URL}/notes", json={ "title": "Key Findings", "content": "TMB correlates with immunotherapy response in NSCLC...", "note_type": "human", "notebook_id": notebook_id })
undefined
response = requests.post(f"{BASE_URL}/notes", json={ "title": "Key Findings", "content": "TMB correlates with immunotherapy response in NSCLC...", "note_type": "human", "notebook_id": notebook_id })
undefined

Context-Aware Chat

上下文感知对话

Chat with your research materials using AI that cites sources.
python
undefined
使用可引用来源的AI与您的研究材料对话。
python
undefined

Create a chat session

Create a chat session

session = requests.post(f"{BASE_URL}/chat/sessions", json={ "notebook_id": notebook_id, "title": "TMB Discussion" }).json()
session = requests.post(f"{BASE_URL}/chat/sessions", json={ "notebook_id": notebook_id, "title": "TMB Discussion" }).json()

Send a message with context from sources

Send a message with context from sources

response = requests.post(f"{BASE_URL}/chat/execute", json={ "session_id": session["id"], "message": "What are the key biomarkers for immunotherapy response?", "context": {"include_sources": True, "include_notes": True} })
undefined
response = requests.post(f"{BASE_URL}/chat/execute", json={ "session_id": session["id"], "message": "What are the key biomarkers for immunotherapy response?", "context": {"include_sources": True, "include_notes": True} })
undefined

Search

搜索

Search across all materials using full-text or vector (semantic) search.
python
undefined
通过全文检索或向量(语义)搜索跨所有材料进行查找。
python
undefined

Vector search across the knowledge base

Vector search across the knowledge base

results = requests.post(f"{BASE_URL}/search", json={ "query": "tumor mutational burden immunotherapy", "search_type": "vector", "limit": 10 }).json()
results = requests.post(f"{BASE_URL}/search", json={ "query": "tumor mutational burden immunotherapy", "search_type": "vector", "limit": 10 }).json()

Ask a question with AI-powered answer

Ask a question with AI-powered answer

answer = requests.post(f"{BASE_URL}/search/ask/simple", json={ "query": "How does TMB predict checkpoint inhibitor response?" }).json()
undefined
answer = requests.post(f"{BASE_URL}/search/ask/simple", json={ "query": "How does TMB predict checkpoint inhibitor response?" }).json()
undefined

Podcast Generation

播客生成

Generate professional multi-speaker podcasts from research materials with 1-4 customizable speakers.
python
undefined
从研究材料生成专业的多主播播客,支持1-4个可自定义主播。
python
undefined

Generate a podcast episode

Generate a podcast episode

job = requests.post(f"{BASE_URL}/podcasts/generate", json={ "notebook_id": notebook_id, "episode_profile_id": episode_profile_id, "speaker_profile_ids": [speaker1_id, speaker2_id] }).json()
job = requests.post(f"{BASE_URL}/podcasts/generate", json={ "notebook_id": notebook_id, "episode_profile_id": episode_profile_id, "speaker_profile_ids": [speaker1_id, speaker2_id] }).json()

Check generation status

Check generation status

status = requests.get(f"{BASE_URL}/podcasts/jobs/{job['job_id']}").json()
status = requests.get(f"{BASE_URL}/podcasts/jobs/{job['job_id']}").json()

Download audio when ready

Download audio when ready

audio = requests.get( f"{BASE_URL}/podcasts/episodes/{status['episode_id']}/audio" )
undefined
audio = requests.get( f"{BASE_URL}/podcasts/episodes/{status['episode_id']}/audio" )
undefined

Content Transformations

内容转换

Apply custom AI-powered transformations to content for summarization, extraction, and analysis.
python
undefined
应用自定义AI驱动的转换对内容进行摘要、提取和分析。
python
undefined

Create a custom transformation

Create a custom transformation

transform = requests.post(f"{BASE_URL}/transformations", json={ "name": "extract_methods", "title": "Extract Methods", "description": "Extract methodology details from papers", "prompt": "Extract and summarize the methodology section...", "apply_default": False }).json()
transform = requests.post(f"{BASE_URL}/transformations", json={ "name": "extract_methods", "title": "Extract Methods", "description": "Extract methodology details from papers", "prompt": "Extract and summarize the methodology section...", "apply_default": False }).json()

Execute transformation on text

Execute transformation on text

result = requests.post(f"{BASE_URL}/transformations/execute", json={ "transformation_id": transform["id"], "input_text": "...", "model_id": "model_id_here" }).json()
undefined
result = requests.post(f"{BASE_URL}/transformations/execute", json={ "transformation_id": transform["id"], "input_text": "...", "model_id": "model_id_here" }).json()
undefined

Supported AI Providers

支持的AI提供商

Open Notebook supports 16+ AI providers through the Esperanto library:
ProviderLLMEmbeddingSpeech-to-TextText-to-Speech
OpenAIYesYesYesYes
AnthropicYesNoNoNo
Google GenAIYesYesNoYes
Vertex AIYesYesNoYes
OllamaYesYesNoNo
GroqYesNoYesNo
MistralYesYesNoNo
Azure OpenAIYesYesNoNo
DeepSeekYesNoNoNo
xAIYesNoNoNo
OpenRouterYesNoNoNo
ElevenLabsNoNoYesYes
PerplexityYesNoNoNo
VoyageNoYesNoNo
Open Notebook通过Esperanto库支持16+ AI提供商:
提供商LLMEmbeddingSpeech-to-TextText-to-Speech
OpenAI
Anthropic
Google GenAI
Vertex AI
Ollama
Groq
Mistral
Azure OpenAI
DeepSeek
xAI
OpenRouter
ElevenLabs
Perplexity
Voyage

Environment Variables

环境变量

Key configuration variables for Docker deployment:
VariableDescriptionDefault
OPEN_NOTEBOOK_ENCRYPTION_KEY
Required. Secret key for encrypting stored credentialsNone
SURREAL_URL
SurrealDB connection URL
ws://surrealdb:8000/rpc
SURREAL_NAMESPACE
Database namespace
open_notebook
SURREAL_DATABASE
Database name
open_notebook
OPEN_NOTEBOOK_PASSWORD
Optional password protection for the UINone
Docker部署的关键配置变量:
变量描述默认值
OPEN_NOTEBOOK_ENCRYPTION_KEY
必填项。用于加密存储凭证的密钥None
SURREAL_URL
SurrealDB连接URL
ws://surrealdb:8000/rpc
SURREAL_NAMESPACE
数据库命名空间
open_notebook
SURREAL_DATABASE
数据库名称
open_notebook
OPEN_NOTEBOOK_PASSWORD
UI可选密码保护None

API Reference

API参考

The REST API is available at
http://localhost:5055/api
with interactive documentation at
/docs
.
Core endpoint groups:
  • /api/notebooks
    - Notebook CRUD and source association
  • /api/sources
    - Source ingestion, processing, and retrieval
  • /api/notes
    - Note management
  • /api/chat/sessions
    - Chat session management
  • /api/chat/execute
    - Chat message execution
  • /api/search
    - Full-text and vector search
  • /api/podcasts
    - Podcast generation and management
  • /api/transformations
    - Content transformation pipelines
  • /api/models
    - AI model configuration and discovery
  • /api/credentials
    - Provider credential management
For complete API reference with all endpoints and request/response formats, see
references/api_reference.md
.
REST API可通过
http://localhost:5055/api
访问,交互式文档位于
/docs
核心端点组:
  • /api/notebooks
    - 笔记本CRUD操作及来源关联
  • /api/sources
    - 来源导入、处理和检索
  • /api/notes
    - 笔记管理
  • /api/chat/sessions
    - 对话会话管理
  • /api/chat/execute
    - 对话消息执行
  • /api/search
    - 全文检索和向量搜索
  • /api/podcasts
    - 播客生成和管理
  • /api/transformations
    - 内容转换流水线
  • /api/models
    - AI模型配置和发现
  • /api/credentials
    - 提供商凭证管理
如需包含所有端点及请求/响应格式的完整API参考,请查看
references/api_reference.md

Architecture

架构

Open Notebook uses a modern stack:
  • Backend: Python with FastAPI
  • Database: SurrealDB (document + relational)
  • AI Integration: LangChain with the Esperanto multi-provider library
  • Frontend: Next.js with React
  • Deployment: Docker Compose with persistent volumes
Open Notebook采用现代技术栈:
  • 后端: Python + FastAPI
  • 数据库: SurrealDB(文档+关系型)
  • AI集成: LangChain + Esperanto多提供商库
  • 前端: Next.js + React
  • 部署: Docker Compose + 持久化卷

Important Notes

重要说明

  • Open Notebook requires Docker for deployment
  • At least one AI provider must be configured for AI features to work
  • For free local inference without API costs, use Ollama
  • The
    OPEN_NOTEBOOK_ENCRYPTION_KEY
    must be set before first launch and kept consistent across restarts
  • All data is stored locally in Docker volumes for complete data sovereignty
  • Open Notebook需要Docker进行部署
  • 必须至少配置一个AI提供商才能使用AI功能
  • 如需无API成本的免费本地推理,请使用Ollama
  • OPEN_NOTEBOOK_ENCRYPTION_KEY
    必须在首次启动前设置,且重启时需保持一致
  • 所有数据存储在本地Docker卷中,实现完全的数据主权