Open Notebook REST API 完全指南:调用方法、端点全解与源码级实践
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
Open Notebook 是一个开源的、可自托管的 Google NotebookLM 替代方案,专为科研场景下的文献整理、多模态资料摄取、AI 笔记生成、多播客语音合成与上下文问答而设计。本文以仓库中的 API 参考文档 为骨架,结合 SKILL.md、架构文档、配置文档 与 示例脚本 等源码级材料,系统讲解 Open Notebook REST API 的全部端点、请求/响应格式、认证方式与错误处理,并给出可复制运行的完整实战代码。
服务概览:Base URL、端口与交互式文档
Open Notebook 采用前后端分离架构,REST API 由 FastAPI 提供。部署后(通过 Docker Compose 拉起)主要端口如下:
| 服务 | 地址 |
|---|---|
| 前端 UI(Next.js) | http://localhost:8502 |
| REST API | http://localhost:5055/api |
| Swagger UI 交互式文档 | http://localhost:5055/docs |
| ReDoc 文档 | http://localhost:5055/redoc |
从仓库的 架构文档 可以看到,后端 FastAPI 服务组织为约 20 个路由模块,覆盖 notebooks、sources、notes、chat、search、podcasts、transformations、models、credentials、embeddings、settings 等全部业务域;全程使用 async/await 非阻塞 I/O,并以 Pydantic 模型做请求/响应校验,自定义异常处理器将领域错误映射为 HTTP 状态码。数据由 SurrealDB 存储(文档型 + 关系型能力,RocksDB 持久化),AI 能力由 LangChain + Esperanto 多提供商库驱动。测试文件 test_open_notebook_skill.py 中明确校验了 API 参考必须覆盖 notebooks、sources、notes、chat、search 等端点组以及 GET/POST/PUT/DELETE 四类 HTTP 方法,可作为端点完整性的验收依据。
认证机制
若设置了环境变量OPEN_NOTEBOOK_PASSWORD,所有请求都需要携带密码完成认证。以下路由豁免认证,可直接访问:
//health/docs/openapi.json/redoc/api/auth/status/api/config
配置方式见 configuration.md:通过export OPEN_NOTEBOOK_PASSWORD="your-ui-password"开启 UI 密码保护;同时推荐使用 Nginx 反向代理将 HTTPS 流量分别转发到8502(前端)与5055/api(REST API),并将 WebSocket 升级头一并透传。
认证之外的全局约定:错误响应
API 遵循标准 HTTP 状态码,错误时返回统一 JSON 结构{"detail": "Description of the error"}。各状态码含义如下:
| 状态码 | 含义 |
|---|---|
| 400 | 输入无效 |
| 401 | 需要认证 |
| 404 | 资源不存在 |
| 422 | 配置错误 |
| 429 | 请求被限流 |
| 500 | 内部服务器错误 |
| 502 | 外部服务(如 AI 提供商)错误 |
端点详解:Notebooks(研究笔记本管理)
Notebook 是组织研究的顶层容器,每个笔记本包含若干 sources(资料源)、notes(笔记)和 chat sessions(对话会话)。
列出笔记本
GET /api/notebooks查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
archived | boolean | 按归档状态过滤 |
order_by | string | 排序字段(默认updated_at) |
返回笔记本对象数组,每个对象附带source_count和note_count统计字段。仓库示例脚本 notebook_management.py 中即通过该端点打印每个笔记本的资料来源数与笔记数。
创建笔记本
POST /api/notebooks请求体:
{ "name": "My Research", "description": "Optional description" }获取 / 更新 / 删除笔记本
GET /api/notebooks/{notebook_id} PUT /api/notebooks/{notebook_id} DELETE /api/notebooks/{notebook_id}更新请求体:
{ "name": "Updated Name", "description": "Updated description", "archived": false }删除笔记本时可通过查询参数delete_sources(boolean,默认false)决定是否同时删除该笔记本独占的 sources。
删除预览
GET /api/notebooks/{notebook_id}/delete-preview返回删除将影响的 notes 与 sources 数量统计,用于在真正删除前确认影响范围。示例脚本 notebook_management.py 中先调用 delete-preview 打印note_count与source_count,再执行删除,是一种安全删除的推荐做法。
关联 / 解除关联 Source
POST /api/notebooks/{notebook_id}/sources/{source_id} DELETE /api/notebooks/{notebook_id}/sources/{source_id}将已有 source 关联到笔记本是幂等操作(重复关联不会报错),适合把一份资料挂到多个研究主题下复用。
端点详解:Sources(资料摄取与处理)
Sources 支持 PDF、DOCX、音频、视频等文件上传,也支持 Web URL 与纯文本摄取,处理后进入全文检索与向量检索索引。
列出 Sources
GET /api/sources查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
notebook_id | string | 按笔记本过滤 |
limit | integer | 返回条数 |
offset | integer | 分页偏移 |
order_by | string | 排序字段 |
创建 Source(表单 / multipart)
POST /api/sources接受 multipart 表单数据(文件上传)或 JSON(URL / 文本)两种形式。表单参数:
| 参数 | 类型 | 说明 |
|---|---|---|
file | file | 上传文件(PDF、DOCX、音频、视频) |
url | string | 待摄取的网页 URL |
text | string | 原始文本内容 |
notebook_id | string | 关联的笔记本 |
process_async | boolean | 是否异步处理(默认true) |
三点实践要点:
- URL / 文本来源使用
data=表单字段提交,文件上传使用files=multipart 字段。参见 source_ingestion.py 中的add_url_source、add_text_source、upload_file_source三个函数; - 异步处理是默认行为(
process_async=true),创建后需要轮询/api/sources/{source_id}/status直到状态变为completed或failed,轮询间隔建议 5 秒、可设超时上限(示例脚本默认 300 秒); - 同端点还提供
/api/sources/json(旧版 JSON 创建端点,标注为 legacy,新代码应优先使用表单端点)。
状态轮询、重试与洞察
GET /api/sources/{source_id}/status # 轮询异步处理状态 POST /api/sources/{source_id}/retry # 重新入队处理失败 source GET /api/sources/{source_id}/insights # 获取 AI 生成的资料洞察配合架构文档中描述的摄取数据流(Upload/URL → Source Record → Processing Queue → 文本抽取 / 向量生成 / 元数据抽取 → Source 可检索),status、retry、insights三端点恰好对应处理链路的关键控制点。
获取 / 更新 / 删除 / 下载
GET /api/sources/{source_id} PUT /api/sources/{source_id} DELETE /api/sources/{source_id} GET /api/sources/{source_id}/download # 返回原始上传文件 HEAD /api/sources/{source_id}/download # 仅检查文件是否存在更新请求体示例:
{ "title": "Updated Title", "topic": "Updated topic" }端点详解:Notes(笔记管理)
列出 / 创建笔记
GET /api/notes POST /api/notes列表支持查询参数notebook_id按笔记本过滤。创建请求体:
{ "title": "My Note", "content": "Note content...", "note_type": "human", "notebook_id": "notebook:abc123" }关键约束:note_type必须为"human"或"ai";AI 生成的笔记如果未提供标题,系统会自动生成标题。SKILL.md 中展示了创建人工笔记(如记录 TMB 与免疫治疗响应的关键发现)的完整示例。
获取 / 更新 / 删除笔记
GET /api/notes/{note_id} PUT /api/notes/{note_id} DELETE /api/notes/{note_id}更新请求体:
{ "title": "Updated Title", "content": "Updated content", "note_type": "human" }端点详解:Chat(上下文感知对话)
Chat 模块让用户与自己的研究资料对话,AI 回答可引用资料源。
会话管理
GET /api/chat/sessions # 列表,支持 notebook_id 过滤 POST /api/chat/sessions # 创建会话 GET /api/chat/sessions/{session_id} # 返回会话详情含消息历史 PUT /api/chat/sessions/{session_id} DELETE /api/chat/sessions/{session_id}创建会话请求体:
{ "notebook_id": "notebook:abc123", "title": "Discussion Topic", "model_override": "optional_model_id" }model_override可在会话级临时覆盖默认对话模型,无需修改全局配置。
执行对话
POST /api/chat/execute请求体:
{ "session_id": "chat_session:abc123", "message": "Your question here", "context": { "include_sources": true, "include_notes": true }, "model_override": "optional_model_id" }context.include_sources与context.include_notes决定是否将笔记本内资料源与笔记注入上下文,这是实现"引用来源的对话"的关键开关。
构建上下文
POST /api/chat/context从 sources 与 notes 为会话构建上下文数据。示例脚本 chat_interaction.py 中的build_context函数展示其用途:提交notebook_id(可选source_ids、note_ids)后返回token_count与char_count,可据此评估上下文规模。
从架构文档可以进一步理解其底层机制:对话由 LangGraph 状态机驱动,流程为"用户消息 → 构建上下文(sources + notes)→ 检索相关上下文 → 带引用格式化提示词 → 流式返回 LLM 响应",最终响应附带来源引用。
端点详解:Search(全文检索与向量检索)
知识库搜索
POST /api/search请求体:
{ "query": "search terms", "search_type": "vector", "limit": 10, "source_ids": [], "note_ids": [], "min_similarity": 0.7 }search_type可选"vector"(语义检索,需要已配置 embedding 模型)或"text"(关键词全文匹配)。source_ids与note_ids用于把检索范围限定在指定资料与笔记内,min_similarity设置向量相似度阈值——这是做"限定在某笔记本内检索"的关键参数,示例脚本 examples.md 中的advanced_search函数即先取笔记本全部 source_ids 再带阈值检索。
AI 问答(流式与非流式)
POST /api/search/ask # 返回 Server-Sent Events(SSE)流式 AI 回答 POST /api/search/ask/simple # 非流式,返回完整回答/api/search/ask基于知识库内容生成回答并以 SSE 推送,适合 Web 实时展示;/api/search/ask/simple返回完整 JSON 响应,适合脚本与 Agent 调用。两者均在 chat_interaction.py 与 examples.md 中有调用示例(后者取answer['response']字段)。
端点详解:Podcasts(多播客生成)
Open Notebook 支持从研究资料生成 1–4 位可定制主播的多播客节目(相比 NotebookLM 的 2 主播限制更具灵活性)。
生成播客(异步任务)
POST /api/podcasts/generate请求体:
{ "notebook_id": "notebook:abc123", "episode_profile_id": "episode_profile:xyz", "speaker_profile_ids": ["speaker:a", "speaker:b"] }返回job_id用于跟踪生成进度。生成流水线(见 架构文档)为:笔记本内容 → 节目画像 → LLM 脚本生成 → 主播分配 → 分段文本转语音(TTS)→ 音频组装 → 生成节目记录与音频文件。
任务状态与节目管理
GET /api/podcasts/jobs/{job_id} # 查询生成进度 GET /api/podcasts/episodes # 节目列表 GET /api/podcasts/episodes/{episode_id} # 节目详情 GET /api/podcasts/episodes/{episode_id}/audio # 流式获取音频文件 POST /api/podcasts/episodes/{episode_id}/retry # 重试失败的节目生成 DELETE /api/podcasts/episodes/{episode_id} # 删除节目轮询模式与 Sources 一致:提交 job → 轮询jobs/{job_id}直到completed/failed→ 用返回的episode_id下载音频。完整实现见 examples.md 的generate_research_podcast函数(将音频写入research_podcast.mp3)。
端点详解:Transformations(自定义内容变换管道)
Transformations 允许用自定义提示词对文本做 AI 变换,典型场景包括摘要、信息抽取、结构化分析。
创建 / 列表
GET /api/transformations POST /api/transformations创建请求体:
{ "name": "summarize", "title": "Summarize Content", "description": "Generate a concise summary", "prompt": "Summarize the following text...", "apply_default": false }apply_default控制该变换是否默认应用到新资料。
执行变换
POST /api/transformations/execute请求体:
{ "transformation_id": "transformation:abc", "input_text": "Text to transform...", "model_id": "model:xyz" }examples.md 展示了一个论文方法学抽取案例:先创建extract_methods变换(提示词要求按 Study Design、Sample Size、Statistical Methods、Key Variables 结构化输出),再从GET /api/models?model_type=llm取一个 LLM 模型,最后执行变换并读取result['output']。
默认提示词与 CRUD
GET /api/transformations/default-prompt PUT /api/transformations/default-prompt GET /api/transformations/{transformation_id} PUT /api/transformations/{transformation_id} DELETE /api/transformations/{transformation_id}端点详解:Models(AI 模型管理)
列出与默认模型槽位
GET /api/models支持查询参数model_type(llm、embedding、stt、tts)按能力类型过滤。
GET /api/models/defaults返回7 个服务槽位的默认模型分配:chat(对话)、transformation(变换)、embedding(向量化)、speech-to-text(语音转文本)、text-to-speech(文本转语音)、podcast(播客)、summary(摘要)。用PUT /api/models/defaults可更新这些分配。
提供商发现与同步
GET /api/models/providers # 可用提供商列表 GET /api/models/discover/{provider} # 发现某提供商可用模型 POST /api/models/sync/{provider} # 同步单提供商模型 POST /api/models/sync # 同步全部模型 POST /api/models/auto-assign # 按提供商优先级自动填充空默认槽位 GET /api/models/count/{provider} # 提供商模型计数 GET /api/models/by-provider/{provider} # 按提供商列出模型 POST /api/models/{model_id}/test # 测试模型可用性 DELETE /api/models/{model_id} # 删除模型其中auto-assign可在注册模型后一键根据提供商优先级排名自动填充 7 个默认槽位,极大简化初始化流程。
端点详解:Credentials(提供商凭据管理)
Credential 管理是接入多 AI 提供商的门户。凭据的api_key会被加密存储(由OPEN_NOTEBOOK_ENCRYPTION_KEY加密,详见 configuration.md),且API 永远不回传 api_key 值。
状态与列表
GET /api/credentials/status # 认证与配置状态总览 GET /api/credentials/env-status # 环境变量凭据状态 GET /api/credentials # 列表,支持 provider 过滤 GET /api/credentials/by-provider/{provider}创建凭据
POST /api/credentials请求体:
{ "provider": "openai", "name": "My OpenAI Key", "api_key": "sk-...", "base_url": null }base_url留空使用官方端点,非空可指向代理或本地兼容服务(如 Ollama)。
凭据驱动的模型接入闭环
GET /api/credentials/{credential_id} PUT /api/credentials/{credential_id} DELETE /api/credentials/{credential_id} POST /api/credentials/{credential_id}/test # 测试连接 POST /api/credentials/{credential_id}/discover # 通过凭据发现模型 POST /api/credentials/{credential_id}/register-models # 注册发现到的模型SKILL.md 与 configuration.md 给出了标准接入四步曲,这一闭环也解释了 Models 端点多处"发现/同步"能力的来源:
import requests BASE_URL = "http://localhost:5055/api" # 1. 创建凭据 cred = requests.post(f"{BASE_URL}/credentials", json={ "provider": "anthropic", "name": "Anthropic Production", "api_key": "sk-ant-..." }).json() # 2. 测试连接 test = requests.post(f"{BASE_URL}/credentials/{cred['id']}/test").json() assert test["success"] # 3. 发现并注册模型 discovered = requests.post( f"{BASE_URL}/credentials/{cred['id']}/discover" ).json() requests.post( f"{BASE_URL}/credentials/{cred['id']}/register-models", json={"model_ids": [m["id"] for m in discovered["models"]]} ) # 4. 自动分配默认模型槽位 requests.post(f"{BASE_URL}/models/auto-assign")实战:一次完整的科研工作流
下面整合 examples.md 与仓库三个脚本(notebook_management.py、source_ingestion.py、chat_interaction.py),给出从建库到检索问答的端到端流程(运行前提:已按 SKILL.md 的 Quick Start 部署服务并配置至少一个 AI 提供商):
import requests import time BASE_URL = "http://localhost:5055/api" # 1. 创建笔记本 notebook = requests.post(f"{BASE_URL}/notebooks", json={ "name": "Drug Resistance in Cancer", "description": "Review of mechanisms of drug resistance in solid tumors" }).json() notebook_id = notebook["id"] # 2. 摄取 URL 资料(异步) source = requests.post(f"{BASE_URL}/sources", data={ "url": "https://www.nature.com/articles/s41568-020-0281-y", "notebook_id": notebook_id, "process_async": "true" }).json() # 3. 轮询处理状态 while True: status = requests.get( f"{BASE_URL}/sources/{source['id']}/status" ).json() if status.get("status") in ("completed", "failed"): break time.sleep(5) # 4. 上下文感知对话(引用资料与笔记) session = requests.post(f"{BASE_URL}/chat/sessions", json={ "notebook_id": notebook_id, "title": "Resistance Mechanisms" }).json() answer = requests.post(f"{BASE_URL}/chat/execute", json={ "session_id": session["id"], "message": "What are the primary mechanisms of drug resistance in solid tumors?", "context": {"include_sources": True, "include_notes": True} }).json() # 5. 向量检索(限定笔记本资料,设置相似度阈值) sources = requests.get(f"{BASE_URL}/sources", params={"notebook_id": notebook_id}).json() results = requests.post(f"{BASE_URL}/search", json={ "query": "efflux pump resistance mechanism", "search_type": "vector", "limit": 10, "source_ids": [s["id"] for s in sources], "min_similarity": 0.75 }).json() # 6. 非流式 AI 问答 answer = requests.post(f"{BASE_URL}/search/ask/simple", json={ "query": "How does TMB predict checkpoint inhibitor response?" }).json() print(answer["response"])环境变量约定:三个示例脚本均通过OPEN_NOTEBOOK_URL(默认http://localhost:5055)读取服务地址,SKILL.md 的 frontmatter 中还将OPEN_NOTEBOOK_URL、OPEN_NOTEBOOK_PASSWORD、OPEN_NOTEBOOK_ENCRYPTION_KEY声明为 Agent 调用时的环境配置项,便于将本 API 能力封装为可复用的 Agent Skill。
端点到源码的证据链小结
| API 端点组 | 对应源码 / 文档证据 |
|---|---|
| Notebooks CRUD + 关联 | notebook_management.py(创建/列表/更新/归档/删除预览/关联) |
| Sources 摄取 + 轮询 | source_ingestion.py(URL/文本/文件三类摄取与wait_for_processing) |
| Chat 会话与执行 | chat_interaction.py(会话、消息、上下文构建) |
| Search / Ask | examples.md(advanced_search、AI 问答) |
| Podcasts 生成 | examples.md(generate_research_podcast,含轮询与音频落盘) |
| Transformations | examples.md(create_and_run_transformations) |
| Models / Credentials 闭环 | configuration.md(四步接入流程)、SKILL.md |
| 架构与数据流 | architecture.md(路由组织、摄取/对话/播客数据流) |
| 端点完整性验收 | test_open_notebook_skill.py(校验端点组与 HTTP 方法覆盖) |
最佳实践与注意事项
- 先配凭据再谈功能:AI 相关功能(洞察、问答、笔记生成、播客、变换)均依赖已配置且注册的模型;仅做资料管理与检索时也需配置 embedding 模型才能使用向量检索。免费场景可直接接入本地 Ollama(base URL 设为
http://ollama:11434,见 configuration.md)。 - 默认异步 + 状态轮询:source 摄取默认
process_async=true,播客生成为异步任务,务必轮询对应 status/job 端点而非直接取结果。 - API Key 只写不回:凭据创建后无法通过 API 读取密钥值,妥善保管创建时的凭据 ID;存储加密依赖
OPEN_NOTEBOOK_ENCRYPTION_KEY,该密钥需在首次启动前设置并保持跨重启一致。 - 删除前先预览:删除笔记本前调用 delete-preview 确认影响范围,再决定是否携带
delete_sources=true。 - 限定检索范围:使用
source_ids/note_ids/min_similarity组合做精准检索,避免全局模糊命中。
通过以上对 api_reference.md 的完整拆解与仓库源码佐证,你已经可以完全脱离 UI,用 REST API 驱动 Open Notebook 完成"建库 → 多源摄取 → AI 洞察 → 上下文问答 → 语义检索 → 播客生成"的全链路科研自动化。
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考