alterlab-open-notebook について
alterlab-open-notebookは、セルフホスト型の研究ワークスペースOpen Notebookの導入と自動化を支援するスキルです。資料の整理、資料に基づくチャットや検索、ポッドキャスト生成、コンテンツ変換、設定可能なAIプロバイダーを使ったREST API連携を扱います。
主な機能
- 01ノートブック、資料、ノートの整理
- 02文書、メディア、URL、テキストの取り込み
- 03資料のコンテキストに基づくチャット
- 04全文検索とセマンティック検索
- 05複数話者のポッドキャスト生成
- 06REST APIによるワークフロー自動化
活用シーン
- 01プライベートな研究ワークスペースの構築
- 02個人の研究資料の検索と対話
- 03ノートブック資料からのポッドキャスト生成
- 04資料とノートの管理自動化
MCP 対応
稼働中のOpen Notebookインスタンスは、コミュニティ製の`open-notebook-mcp`パッケージを介して、Claude DesktopやVS CodeなどのMCPクライアントから利用できます。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.jsonreferences/api_reference.mdarchitecture.mdconfiguration.mdexamples.mdscripts/chat_interaction.pynotebook_management.pysource_ingestion.pytest_open_notebook_skill.py詳細
Open Notebook
概要
Open Notebook は、Google の NotebookLM に代わるオープンソース(MIT ライセンス)でセルフホスト可能なツールです。研究者が資料を整理し、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 |
| 1 つの PDF 内の特定箇所や複数セクションにまたがる質疑応答 | alterlab-pdf-explore |
| 多数の PDF にわたる、論文ごとに 1 行のエビデンステーブル | alterlab-pdf-extract |
| Zotero ライブラリで参考文献、DOI、BibTeX を管理する | alterlab-pyzotero |
| 新しい文献を体系的に検索・スクリーニングする | alterlab-literature-review |
クイックスタート
前提条件
- Docker Compose v2 を含む Docker(OrbStack と Docker Desktop のどちらでも動作します。
docker composeが利用可能である必要があります) - 少なくとも 1 つの 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 秒かかります)。
- フロントエンド UI: http://localhost:8502
- REST API: http://localhost:5055
- API ドキュメント: http://localhost:5055/docs(正式なスキーマ)
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、動画、音声、Web ページ、Office ドキュメント、またはプレーンテキストを取り込みます。POST /api/sources はマルチパートフォームフィールドを受け取り、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}, ...]
検索
notebook_id / notebook_ids で対象を絞り、全文検索("text"、デフォルト)またはセマンティック検索("vector"、埋め込みモデルが必要)を使って、すべての資料を検索します。
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 プロバイダーに対応しています。代表的なものを以下に示します。
| プロバイダー | LLM | 埋め込み | 音声テキスト変換 | テキスト音声変換 |
|---|---|---|---|---|
| OpenAI | はい | はい | はい | はい |
| Anthropic | はい | いいえ | いいえ | いいえ |
| Google GenAI | はい | はい | はい | はい |
| Vertex AI | はい | はい | いいえ | はい |
| Ollama | はい | はい | いいえ | いいえ |
| Groq | はい | いいえ | はい | いいえ |
| Mistral | はい | はい | はい | はい |
| Azure OpenAI | はい | はい | はい | はい |
| DeepSeek | はい | いいえ | いいえ | いいえ |
| xAI | はい | いいえ | いいえ | はい |
| OpenRouter | はい | はい | はい | はい |
| ElevenLabs | いいえ | いいえ | はい | はい |
| Voyage | いいえ | はい | いいえ | いいえ |
| OpenAI 互換(LM Studio、vLLM、...) | はい | はい | はい | はい |
oMLX、Perplexity、Deepgram、Cohere、DashScope、MiniMax、Novita を含む最新の全対応状況については、上流の README を参照してください。
環境変数
Docker デプロイメントで使用する主要な設定変数:
| 変数 | 説明 | デフォルト |
|---|---|---|
OPEN_NOTEBOOK_ENCRYPTION_KEY | 必須。 保存されたプロバイダー認証情報を暗号化します。安定した値を維持してください(変更または紛失すると、保存済みの認証情報を読み取れなくなります) | なし |
OPEN_NOTEBOOK_PASSWORD | 任意のパスワードです。設定すると、API 呼び出しに Authorization: Bearer <password> が必要です | なし |
SURREAL_URL | SurrealDB 接続 URL | ws://surrealdb:8000/rpc |
SURREAL_USER / SURREAL_PASSWORD | SurrealDB の認証情報(インスタンスを公開する前に .env で上書きしてください) | root / root |
SURREAL_NAMESPACE | データベースのネームスペース | open_notebook |
SURREAL_DATABASE | データベース名 | open_notebook |
OPEN_NOTEBOOK_WORKER_MAX_TASKS | バックグラウンドジョブの同時実行数です。ローカル GPU を 1 台だけ使う場合は 1 に設定してください | 5 |
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 は、最新の技術スタックを使用しています。
- バックエンド: Python と FastAPI
- データベース: SurrealDB(ドキュメント型+リレーショナル型)
- AI 統合: LangChain/LangGraph と Esperanto マルチプロバイダーライブラリ
- フロントエンド: React を使用した Next.js
- デプロイ: 永続ボリューム(
./notebook_data、./surreal_data)を使用する Docker Compose
重要事項
- Open Notebook は Docker でデプロイされます(開発用にソースからセットアップする方法もあります)。
- AI 機能を使用するには、少なくとも 1 つの 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 スイートの一部です。