mcpField
A
alterlab-open-notebook

alterlab-open-notebook

github.com/alterlab-ieu生产力7866 次安装5 周前更新
代码仓库

关于 alterlab-open-notebook

alterlab-open-notebook 是部署和自动化 Open Notebook 自托管研究工作区的技能,用于整理资料并处理其内容。它涵盖基于来源的对话、搜索、播客生成、内容转换,以及对接可配置 AI 提供方的 REST API 工作流。

主要功能

  1. 01整理笔记本、来源和笔记
  2. 02导入文档、媒体、网址和文本
  3. 03基于来源上下文进行对话
  4. 04全文或语义搜索
  5. 05生成多说话人播客
  6. 06通过 REST API 自动化工作流

适用场景

  1. 01搭建私有研究工作区
  2. 02搜索并讨论个人研究资料集
  3. 03根据笔记本资料生成播客
  4. 04自动管理来源和笔记

MCP 相关

运行中的 Open Notebook 实例可通过社区维护的 `open-notebook-mcp` 软件包供 MCP 客户端(如 Claude Desktop 和 VS Code)访问。README 提供 `uvx open-notebook-mcp` 及 `OPEN_NOTEBOOK_URL` / `OPEN_NOTEBOOK_PASSWORD` 设置方式。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/alterlab-ieu/alterlab-academic-skills --skill alterlab-open-notebook

安装后在 Claude Code 中输入/alterlab-open-notebook确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

evals/
evals.json
references/
api_reference.md
architecture.md
configuration.md
examples.md
scripts/
chat_interaction.py
notebook_management.py
source_ingestion.py
test_open_notebook_skill.py

详细介绍

Open Notebook

概述

Open Notebook 是一个开源(MIT)、可自托管的 Google NotebookLM 替代方案,可帮助研究人员整理资料、生成 AI 洞见、创建播客,并围绕文档进行上下文感知对话。它提供完整的 REST API,通过 Esperanto 库支持 18+ 个 AI 提供商,并完全运行在你自己的基础设施上。本技能面向 1.x 系列(截至 2026-09 的 v1.14;Docker 镜像为 lfnovo/open_notebook:v1-latest)。

相比 NotebookLM 的主要优势:

  • 完整的 REST API,支持编程访问和自动化
  • 可选择 18+ 个 AI 提供商(不局限于 Google 模型),包括完全本地运行的 Ollama / LM Studio
  • 支持生成多说话人播客,可自定义 1-4 位说话人
  • 数据存储在你自己的机器或服务上
  • 开源且可扩展(MIT 许可证)

**数据隐私:**自托管可将笔记本和文件保留在本地,但源文本仍会发送给你配置的云模型提供商。对于敏感或受 IRB 限制的材料,请使用本地提供商(Ollama、LM Studio)或符合你数据协议要求的提供商。

**代码仓库:**https://github.com/lfnovo/open-notebook

何时使用此技能

当用户想要:

  • 搭建私有、可自托管的 NotebookLM 风格研究工作区
  • 将 PDF、URL、音频/视频或文本导入笔记本,并结合来源上下文进行对话
  • 使用全文或向量搜索检索个人研究资料库
  • 根据来源生成多说话人播客或自定义转换结果(摘要、方法提取)
  • 通过 REST API 自动执行上述任一操作
不适用场景
场景改用
将单个文件一次性转换为 Markdown(无需笔记本、对话或搜索)alterlab-markitdown
在单个 PDF 中定位并进行跨章节问答alterlab-pdf-explore
为多份 PDF 制作每篇论文占一行的证据表alterlab-pdf-extract
在 Zotero 文献库中管理参考文献、DOI 或 BibTeXalterlab-pyzotero
系统性地搜索和筛选新文献alterlab-literature-review

快速开始

前置条件
  • Docker 和 Docker Compose v2(OrbStack 和 Docker Desktop 均可;必须能使用 docker compose)
  • 至少一个 AI 提供商的 API 密钥(也可使用本地 Ollama / LM Studio 免费进行本地推理)
安装
# 1. Download the official compose file (SurrealDB v2 + lfnovo/open_notebook:v1-latest)
curl -o docker-compose.yml https://raw.githubusercontent.com/lfnovo/open-notebook/main/docker-compose.yml

# 2. Set the encryption key: the compose file hard-codes
#    OPEN_NOTEBOOK_ENCRYPTION_KEY=change-me-to-a-secret-string, so edit that line
#    (exporting a shell variable has no effect on this file)
sed -i.bak "s/change-me-to-a-secret-string/$(openssl rand -hex 32)/" docker-compose.yml

# 3. Launch the services
docker compose up -d

访问应用(启动需等待 15-20 秒):

SurrealDB 默认使用 root:root,且仅绑定到 127.0.0.1。在将实例暴露到本机以外之前,请在 compose 文件旁的 .env 文件中设置 SURREAL_USER / SURREAL_PASSWORD,设置 OPEN_NOTEBOOK_PASSWORD,并让 UI/API 通过 HTTPS 访问。

配置 AI 提供商

在 UI 中打开 Models,选择一个提供商,点击 + Add Configuration,粘贴密钥,点击 Test 测试连接,再点击 Sync Models,然后在 Default Model Assignments 下使用 Auto-Assign Defaults。

或者通过 REST API 配置:

import os
import requests

BASE_URL = "http://localhost:5055/api"
# Only needed when OPEN_NOTEBOOK_PASSWORD is set on the server
HEADERS = {"Authorization": f"Bearer {os.environ['OPEN_NOTEBOOK_PASSWORD']}"} if os.environ.get("OPEN_NOTEBOOK_PASSWORD") else {}

# Add a credential for an AI provider (stored encrypted with OPEN_NOTEBOOK_ENCRYPTION_KEY)
credential = requests.post(f"{BASE_URL}/credentials", headers=HEADERS, json={
    "provider": "openai",
    "name": "My OpenAI Key",
    "api_key": os.environ["OPENAI_API_KEY"],
}).json()

# Discover the provider's models: {"credential_id", "provider", "discovered": [{name, provider, model_type}, ...]}
discovered = requests.post(
    f"{BASE_URL}/credentials/{credential['id']}/discover", headers=HEADERS
).json()["discovered"]

# Register them (model_type: language, embedding, text_to_speech, speech_to_text)
requests.post(
    f"{BASE_URL}/credentials/{credential['id']}/register-models",
    headers=HEADERS,
    json={"models": [
        {"name": m["name"], "provider": m["provider"], "model_type": m["model_type"]}
        for m in discovered if m.get("model_type")
    ]},
).raise_for_status()

# Fill empty default slots (chat, transformation, large-context, embedding, TTS, STT, tools)
requests.post(f"{BASE_URL}/models/auto-assign", headers=HEADERS)

核心功能

以下代码片段会重复使用上文中的 BASE_URL 和 HEADERS。

笔记本

将研究资料整理到不同的笔记本中,每个笔记本都包含来源、笔记和对话会话。

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

导入 PDF、视频、音频、网页、Office 文档或原始文本。POST /api/sources 接受 multipart 表单字段;必须提供 type(link、upload 或 text),设置 embed="true" 后,该来源即可用于向量搜索。

# Add a web URL source (processed in the background)
source = requests.post(f"{BASE_URL}/sources", headers=HEADERS, data={
    "type": "link",
    "url": "https://arxiv.org/abs/2301.00001",
    "notebook_id": notebook_id,
    "embed": "true",
    "async_processing": "true",
}).json()

# Upload a PDF file
with open("paper.pdf", "rb") as f:
    upload = requests.post(
        f"{BASE_URL}/sources",
        headers=HEADERS,
        data={"type": "upload", "notebook_id": notebook_id, "embed": "true"},
        files={"file": ("paper.pdf", f, "application/pdf")},
    ).json()

# Poll background processing: status is queued / running / completed / failed
status = requests.get(f"{BASE_URL}/sources/{source['id']}/status", headers=HEADERS).json()
笔记

创建和管理与笔记本关联的笔记(由人工或 AI 生成)。

requests.post(f"{BASE_URL}/notes", headers=HEADERS, json={
    "title": "Key Findings",
    "content": "TMB correlates with immunotherapy response in NSCLC...",
    "note_type": "human",
    "notebook_id": notebook_id,
})
上下文感知聊天

聊天回答以你传入的上下文为依据。使用 /api/chat/context 构建上下文(空的 context_config 会将笔记本中的所有来源和笔记作为简短上下文;每项可设为 "full content"、"insights" 或 "not in context",以进一步细化),然后随消息一并发送。

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

ctx = requests.post(f"{BASE_URL}/chat/context", headers=HEADERS, json={
    "notebook_id": notebook_id,
    "context_config": {},   # or {"sources": {source_id: "full content"}, "notes": {...}}
}).json()

reply = requests.post(f"{BASE_URL}/chat/execute", headers=HEADERS, json={
    "session_id": session["id"],
    "message": "What are the key biomarkers for immunotherapy response?",
    "context": ctx["context"],
}).json()
print(reply["messages"][-1]["content"])   # messages: [{id, type: human|ai, content}, ...]
搜索

使用全文搜索("text",默认)或语义搜索("vector",需要嵌入模型)检索所有材料,也可以选择按 notebook_id / notebook_ids 限定范围。

results = requests.post(f"{BASE_URL}/search", headers=HEADERS, json={
    "query": "tumor mutational burden immunotherapy",
    "type": "vector",
    "limit": 10,
    "notebook_id": notebook_id,
}).json()   # {"results": [...], "total_count": n, "search_type": "vector"}

# Ask a question: the three model IDs are required (see GET /api/models or /api/models/defaults)
defaults = requests.get(f"{BASE_URL}/models/defaults", headers=HEADERS).json()
chat_model = defaults["default_chat_model"]
answer = requests.post(f"{BASE_URL}/search/ask/simple", headers=HEADERS, json={
    "question": "How does TMB predict checkpoint inhibitor response?",
    "strategy_model": chat_model,
    "answer_model": chat_model,
    "final_answer_model": chat_model,
    "notebook_id": notebook_id,
}).json()["answer"]

POST /api/search/ask 接受相同的请求体,并以 Server-Sent Events 流式传输。

播客生成

根据笔记本生成多位说话人的播客(1-4 位说话人)。配置通过名称引用:单集配置(格式、模型、时长)和说话人配置(语音和人物设定)。

episode_profile = requests.get(f"{BASE_URL}/episode-profiles", headers=HEADERS).json()[0]

job = requests.post(f"{BASE_URL}/podcasts/generate", headers=HEADERS, json={
    "episode_profile": episode_profile["name"],
    "speaker_profile": episode_profile["speaker_config_name"],   # or any name from /api/speaker-profiles
    "episode_name": "TMB and immunotherapy",
    "notebook_id": notebook_id,
}).json()

# Poll until the job reports "completed" (or "failed")
status = requests.get(f"{BASE_URL}/podcasts/jobs/{job['job_id']}", headers=HEADERS).json()["status"]

# Then locate the episode and download its audio
episodes = requests.get(f"{BASE_URL}/podcasts/episodes", headers=HEADERS).json()
episode = next(e for e in episodes if e["name"] == "TMB and immunotherapy")
audio = requests.get(f"{BASE_URL}/podcasts/episodes/{episode['id']}/audio", headers=HEADERS)
内容转换

对内容应用自定义的 AI 驱动转换,用于摘要、提取和分析。

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

result = requests.post(f"{BASE_URL}/transformations/execute", headers=HEADERS, json={
    "transformation_id": transform["id"],
    "input_text": "...",
    # "model_id": "model:...",   # optional; defaults to the transformation model
}).json()["output"]

支持的 AI 提供商

Open Notebook 通过 Esperanto 库支持 18+ 个 AI 提供商。以下是部分代表性提供商:

提供商大模型嵌入语音转文本文本转语音
OpenAI是是是是
Anthropic是否否否
Google GenAI是是是是
Vertex AI是是否是
Ollama是是否否
Groq是否是否
Mistral是是是是
Azure OpenAI是是是是
DeepSeek是否否否
xAI是否否是
OpenRouter是是是是
ElevenLabs否否是是
Voyage否是否否
OpenAI-compatible (LM Studio, vLLM, ...)是是是是

如需查看完整的最新支持矩阵(包括 oMLX、Perplexity、Deepgram、Cohere、DashScope、MiniMax、Novita),请参阅上游 README。

环境变量

Docker 部署的关键配置变量:

变量说明默认值
OPEN_NOTEBOOK_ENCRYPTION_KEY**必需。**用于加密已存储的提供商凭据;请保持其稳定(更改或丢失密钥会导致已保存的凭据无法读取)无
OPEN_NOTEBOOK_PASSWORD可选密码;设置后,API 调用需要 Authorization: Bearer <password>无
SURREAL_URLSurrealDB 连接 URLws://surrealdb:8000/rpc
SURREAL_USER / SURREAL_PASSWORDSurrealDB 凭据(在向外部开放实例前,可通过 .env 覆盖)root / root
SURREAL_NAMESPACE数据库命名空间open_notebook
SURREAL_DATABASE数据库名称open_notebook
OPEN_NOTEBOOK_WORKER_MAX_TASKS并发后台任务数;使用单块本地 GPU 时设为 15

API 参考

REST API 位于 http://localhost:5055/api,交互式文档位于 /docs。

核心端点组:

  • /api/notebooks - 笔记本 CRUD、删除预览和来源关联
  • /api/sources - 来源导入、状态、重试、见解和下载
  • /api/notes - 笔记管理
  • /api/chat/sessions、/api/chat/context、/api/chat/execute - 聊天会话、上下文构建和消息
  • /api/search、/api/search/ask、/api/search/ask/simple - 全文/向量搜索和问答
  • /api/podcasts、/api/episode-profiles、/api/speaker-profiles - 播客生成和配置
  • /api/transformations - 内容转换工作流
  • /api/models - 模型注册、默认设置、同步和自动分配
  • /api/credentials - 提供商凭据管理、发现和注册

请求/响应详情请参阅 references/api_reference.md;可运行示例位于 scripts/ 和 references/examples.md。

架构

Open Notebook 使用现代技术栈:

  • 后端: 使用 FastAPI 的 Python
  • 数据库: SurrealDB(文档型 + 关系型)
  • AI 集成: LangChain / LangGraph 和 Esperanto 多提供商库
  • 前端: 使用 React 的 Next.js
  • 部署: 使用 Docker Compose 和持久卷(./notebook_data、./surreal_data)

重要说明

  • Open Notebook 使用 Docker 部署(也提供供开发使用的源码部署方式)
  • 必须配置至少一个 AI 提供商才能使用 AI 功能;向量搜索和 Ask 还需要嵌入模型
  • 如需免费本地推理且无需 API 费用,请使用 Ollama 或 LM Studio
  • 必须在首次启动前设置 OPEN_NOTEBOOK_ENCRYPTION_KEY,并确保每次重启时保持一致
  • 数据存储在绑定挂载的 notebook_data/ 和 surreal_data/ 文件夹中;请备份这些文件夹
  • MCP 客户端(Claude Desktop、VS Code)可通过上游文档提到的社区 open-notebook-mcp 包访问运行中的实例(使用 OPEN_NOTEBOOK_URL / OPEN_NOTEBOOK_PASSWORD 的 uvx open-notebook-mcp)

AlterLab Academic Skills 套件的一部分。

评论

支持 Markdown