概要
プライバシーと柔軟性を重視した、オープンソースのセルフホスト型 Notebook LM 代替ツール。18種類以上の AI プロバイダー、マルチモーダルコンテンツ、カスタマイズ可能なポッドキャスト生成機能をサポート。
README プレビュー
\n\n\n[![Forks][forks-shield]][forks-url]\n[![Stargazers][stars-shield]][stars-url]\n[![Issues][issues-shield]][issues-url]\n[![MIT License][license-shield]][license-url]\n\n\n\n\n\n\n \n \n \n\n Open Notebook\n\n \n An open source, privacy-focused alternative to Google's Notebook LM!\n Join our Discord server for help, to share workflow ideas, and suggest features!\n \n Checkout our website »\n \n \n 📚 Get Started\n ·\n 📖 User Guide\n ·\n ✨ Features\n ·\n 🚀 Deploy\n \n\n\n\n\n\n\n\n \n Deutsch | \n Español | \n français | \n 日本語 | \n 한국어 | \n Português | \n Русский | \n 中文\n\n\n## A private, multi-model, 100% local, full-featured alternative to Notebook LM\n\n\n\nIn a world dominated by Artificial Intelligence, having the ability to think 🧠 and acquire new knowledge 💡, is a skill that should not be a privilege for a few, nor restricted to a single provider.\n\n**Open Notebook empowers you to:**\n- 🔒 **Control your data** - Keep your research private and secure\n- 🤖 **Choose your AI models** - Support for 18+ providers including OpenAI, Anthropic, Ollama, LM Studio, and more\n- 📚 **Organize multi-modal content** - PDFs, videos, audio, web pages, and more\n- 🎙️ **Generate professional podcasts** - Advanced multi-speaker podcast generation\n- 🔍 **Search intelligently** - Full-text and vector search across all your content\n- 💬 **Chat with context** - AI conversations powered by your research\n- 🌐 **Multi-language UI** - English, Portuguese, Chinese (Simplified & Traditional), Japanese, Russian, and Bengali support\n\nLearn more about our project at [https://www.open-notebook.ai](https://www.open-notebook.ai)\n\n---\n\n## 🆚 Open Notebook vs Google Notebook LM\n\n| Feature | Open Notebook | Google Notebook LM | Advantage |\n|---------|---------------|--------------------|-----------|\n| **Privacy & Control** | Self-hosted, your data | Google cloud only | Complete data sovereignty |\n| **AI Provider Cho
FAQ (5)
トラブル対応ソースチャットのストリーミングが以前の回答をすべて繰り返してしまう問題と、リフレッシュ後にコンテキストバッジが消えてしまう問題を修正するにはどうすればよいですか?
ソースチャットのストリーミングおよびセッション読み込みの経路にある両方の問題を修正してください。
1. ストリーミング中にチェックポイントに保存された全メッセージ履歴を送信しないようにしてください。api/routers/source_chat.py の376〜384行目付近で、result["messages"] のすべてのエントリをループ処理しないでください。最新のAIメッセージのみを発行してください:
last_message = result["messages"][-1]
# Emit the ai_message event for last_message only
2. 既存のセッションが読み込まれた際にコンテキストインジケーターを復元してください。frontend/src/lib/hooks/use-source-chat.ts の41〜45行目付近にあるセッション読み込みのエフェクトを更新してください:
setContextIndicators(currentSession.context_indicators ?? null);
バックエンドはすでに api/routers/source_chat.py の GET セッションから context_indicators を返していますが、このフックはSSEイベントからのみ設定していました。これらの変更により、後続のストリーミング回答には新しい回答のみが含まれるようになり、ページ更新後もソース数が表示され続けます。main ブランチのコミット 3959eb0 に対して検証済みです。
トラブル対応バッチ挿入が失敗した後、ソースが埋め込み済みとして表示されるのに、ベクトル検索でドキュメントの一部しか返されないのはなぜですか?
バッチ化された repo_insert 呼び出しはアトミックではありません:最初のバッチ以降が失敗した場合、それ以前の source_embedding 行が残ってしまいます。埋め込み済みチェックは1行しか参照しない(LIMIT 1)ため、そのソースは完全に埋め込み済みとして誤ってマークされます。commands/embedding_commands.py の embed_source を修正し、挿入処理を try/except でラップして、失敗時にそのソースの埋め込みを削除し、元の例外を再送出してください:
try:
await repo_insert(...)
except Exception:
await db.execute(
"DELETE FROM source_embedding WHERE source = $source_id",
{"source_id": source_id},
)
raise
後続のバッチを強制的に失敗させるテストを追加し、そのソースに対する source_embedding の行が0件であること、および元の例外が変更されずに伝播することをアサートしてください。
トラブル対応空のノートブックや transformation の説明がリフレッシュ後に保持されない問題を修正するにはどうすればよいですか?
空文字列がPATCHリクエストの前に削除されています。frontend/src/app/(dashboard)/notebooks/components/NotebookHeader.tsx で description: description || undefined を description: description に置き換えてください。frontend/src/app/(dashboard)/transformations/components/TransformationEditorDialog.tsx の title フィールドと description フィールドにも同じ変更を適用してください。バックエンドでは、api/routers/notebooks.py と api/routers/transformations.py を更新して、省略されたフィールドと明示的に "" に設定されたフィールドを区別できるようにしてください。is not None のチェックのみではなく、Pydantic の model_fields_set または model_dump(exclude_unset=True) を使用してください。description: "" を含む PATCH で検証し、その場合はフィールドがクリアされること、一方で description を省略した場合は既存の値が変更されずに残ることを確認してください。
トラブル対応IPがフラグ付けされたネットワークでブロックされたYouTubeのトランスクリプトリクエストを修正するにはどうすればよいですか?
content-core 2.2 以降を使用し、YouTube の Cookie とレジデンシャルプロキシを設定してください。YouTube の Cookie を Netscape cookies.txt 形式でエクスポートし、そのファイルをコンテナにマウントして、次のように設定します。
-e CCORE_YOUTUBE_COOKIES_FILE=/run/secrets/cookies.txt \
-e CCORE_YOUTUBE_PROXY=http://user:password@residential-proxy:port \
-v /path/to/cookies.txt:/run/secrets/cookies.txt:ro
プロキシは、トランスクリプトの取得、pytubefix フォールバック、およびタイトル検索に使用されます。レジデンシャルプロキシを使用してください。データセンタープロキシはブロックされます。Cookie ファイルが存在しない、または読み取れない場合は ConfigurationError が発生するため、マウントされたパスとファイルのパーミッションを確認してから、ワーカー/コンテナを再起動してください。
トラブル対応Open NotebookでLLM呼び出しが60秒でタイムアウトする問題を解決するにはどうすればよいですか?特にOllamaや推論モデルを使用している場合。
esperanto 2.28以降では、to_langchain()はすべてのプロバイダーに対してESPERANTO_LLM_TIMEOUTを強制します。未設定の場合、実質的なフォールバックは60秒となるため、長いレスポンスや低速なローカルモデルは失敗する可能性があります。この値のデフォルトが180秒に設定されたOpen Notebookリリースにアップグレードするか、APIとワーカーを起動する前に明示的に設定してください:
export ESPERANTO_LLM_TIMEOUT=180
低速なローカルモデルの場合は、より大きな値を使用し、API_CLIENT_TIMEOUTも増やして、LLMタイムアウトにバッファを加えた値より大きくなるようにしてください:
export ESPERANTO_LLM_TIMEOUT=600
export API_CLIENT_TIMEOUT=720
コードでは、モデルが作成される前に次のようにしてデフォルトを適用できます:
os.environ.setdefault("ESPERANTO_LLM_TIMEOUT", "180")
明示的に設定されたESPERANTO_LLM_TIMEOUTは常に優先されます。STT/TTSのタイムアウト変数は別途存在し、esperantoのデフォルトの300秒のままです。