
1. 为什么我要把 Open Notebook 接上统一模型通道Open Notebook 是一个开源、可自托管的 AI 笔记与研究平台简单说就是 Google NotebookLM 的开源替代品你把 PDF、网页、YouTube 视频、音频、Office 文档丢进一个 Notebook它自动做内容提取、分块、向量化然后你可以基于这些材料做带引用溯源的问答、生成摘要、甚至把研究内容转成多人播客。它适合研究人员、学生、知识工作者以及任何不想把私人笔记锁在别人云端的开发者。我最初被它吸引是因为「数据主权」这四个字。所有内容存在自己机器的 SurrealDB 里用哪个模型自己定谁能访问自己控。但真正部署完第一个卡点就来了模型接入。Open Notebook 通过内部的 Esperanto 适配层支持 18 家提供商可当你手上有五六个不同厂商的 Key、每个 Key 的额度、限速、计费方式都不一样时逐个在 Settings 里添加、测试、注册模型是一件很碎的事。更麻烦的是一旦某个厂商临时不可用你得回到界面里手动切换研究思路被打断。所以这篇的路线很明确先把 Open Notebook 用 Docker Compose 跑起来再用 TaoToken 的统一 Key 和 API 通道把对话模型、Embedding 模型收敛到一个入口最后用一段脚本验证连通性跑通「导入材料 → 向量检索 → 带引用问答」的端到端链路。全程可复制配置和报错我都会给全。需要先说明一点TaoToken 在这里扮演的是「OpenAI 兼容端点」的角色。Open Notebook 的提供商矩阵里明确支持 OpenAI 兼容接口这意味着任何遵循 OpenAI API 格式的服务都能接进来不需要改它的源码也不需要写适配器。这是整条链路能走通的关键前提。下面按部署、接入、验证、排障的顺序展开。如果你已经跑起了 Open Notebook可以直接跳到第 3 节看配置片段。2. 部署 Open Notebook 与 TaoToken 前置准备2.1 环境要求与目录规划先确认机器条件。Open Notebook 双服务部署需要 Docker 和 Docker Compose内存建议 4GB 起步SurrealDB 加应用进程磁盘看你导入多少 PDF。我用的是 Ubuntu 22.04Docker 24.xCompose v2。创建工作目录把数据卷和编排文件放一起方便备份mkdir -p ~/open-notebook cd ~/open-notebook mkdir -p surreal_data notebook_data目录结构最后长这样open-notebook/ ├── docker-compose.yml ├── .env ├── surreal_data/ └── notebook_data/2.2 获取 TaoToken API Key打开 TaoToken 官网注册后在控制台的 API Keys 页面创建一个 Key。地址是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。创建时给它起个能认出来的名字比如open-notebook方便以后按项目撤销。拿到 Key 之后你需要记住两个东西Base URLhttps://taotoken.net/api注意这个地址不加 UTM 参数直接用于程序请求API Key形如sk-...的字符串TaoToken 的模型列表可以在模型对话页面查看地址是 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。我建议至少准备两类模型一个对话模型用于问答和摘要一个 Embedding 模型用于向量检索。Open Notebook 的语义搜索依赖 Embedding如果只配对话模型全文搜索能用但向量检索会缺一块。2.3 编写 docker-compose.yml这是核心编排文件直接复制services: surrealdb: image: surrealdb/surrealdb:v2 command: start --log info --user root --pass root rocksdb:/mydata/mydatabase.db ports: - 8000:8000 volumes: - ./surreal_data:/mydata restart: always open_notebook: image: lfnovo/open_notebook:v1-latest ports: - 8502:8502 # 前端 UI - 5055:5055 # REST API env_file: - .env volumes: - ./notebook_data:/app/data depends_on: - surrealdb restart: always注意我把环境变量抽到了.env这样密钥不会硬编码进编排文件也方便版本管理时排除。2.4 环境变量模板创建.env# 数据库连接 SURREAL_URLws://surrealdb:8000/rpc SURREAL_USERroot SURREAL_PASSWORDroot SURREAL_NAMESPACEopen_notebook SURREAL_DATABASEopen_notebook # 应用加密密钥自己生成一串随机字符串 OPEN_NOTEBOOK_ENCRYPTION_KEYchange-me-to-a-random-string # TaoToken 统一通道OpenAI 兼容 OPENAI_API_KEYsk-你的TaoToken密钥 OPENAI_BASE_URLhttps://taotoken.net/apiOPEN_NOTEBOOK_ENCRYPTION_KEY用来加密存在数据库里的凭据务必改掉默认值且不要提交到 Git。生成方式openssl rand -hex 322.5 启动与首次访问docker compose up -d docker compose ps等 15 到 20 秒两个容器都应该是running。浏览器打开http://localhost:8502能看到 Open Notebook 界面就说明部署成功。REST API 在http://localhost:5055Swagger 文档在http://localhost:5055/docs。如果open_notebook容器反复重启先看日志docker compose logs -f open_notebook常见原因是 SurrealDB 还没就绪应用连不上就退出。等数据库起来后docker compose restart open_notebook即可。3. 在 Open Notebook 里配置 TaoToken 统一接入3.1 界面配置路径进入 Open Notebook 后走这条路径Settings → API Keys → Add Credential。在提供商下拉里选择OpenAI或OpenAI Compatible不同版本措辞略有差异本质都是走 OpenAI 格式。填入API Key你的 TaoToken KeyBase URLhttps://taotoken.net/api保存后点Test Connection。成功的话会提示连接正常然后点Discover Models拉取可用模型列表再Register Models把你要用的模型注册进 Open Notebook。这里有个细节Open Notebook 把 LLM、Embedding、STT、TTS 分开注册。你至少要注册一个对话模型和一个 Embedding 模型。注册时给模型起个可读的名字比如taotoken-chat、taotoken-embed后面在 Notebook 设置里选默认模型时好认。3.2 用 settings 片段固化配置如果你不想每次重装都手点界面可以把模型配置写成 JSON通过 REST API 导入。Open Notebook 的凭据和模型注册接口在/api/credentials和/api/models下。下面是一个可复制的凭据 JSON 结构字段名以你实际版本的 Swagger 为准{ name: taotoken, provider: openai, api_key: sk-你的TaoToken密钥, base_url: https://taotoken.net/api }用 curl 提交curl -X POST http://localhost:5055/api/credentials \ -H Content-Type: application/json \ -d credential.json模型注册片段{ name: taotoken-chat, provider: openai, model_type: language, model_id: gpt-4o-mini }{ name: taotoken-embed, provider: openai, model_type: embedding, model_id: text-embedding-3-small }model_id填 TaoToken 模型列表里实际存在的 ID。如果你不确定某个 ID 是否可用先在模型对话页面手动发一条消息验证再写进配置。3.3 三件套对照表无论你用界面还是 API接入任何 OpenAI 兼容服务都离不开这三样缺一不可配置项值说明Base URLhttps://taotoken.net/api请求入口不要带 UTMAPI Keysk-...控制台创建按项目命名Model ID如gpt-4o-mini必须是通道支持的模型这三件套在 Open Notebook、Cline、Codex 的auth.json、Claude Code 的配置里逻辑是一致的只是字段名不同。记住这个心智模型换工具时不会慌。3.4 设置默认模型注册完模型后回到 Notebook 的设置页把默认对话模型设为taotoken-chat默认 Embedding 模型设为taotoken-embed。新建 Notebook 导入材料时系统会用 Embedding 模型做向量化。如果这一步没设导入的文档不会进向量索引语义搜索会返回空。4. 验证请求与端到端成功结果4.1 先用 curl 验证通道在碰 Open Notebook 之前先确认 TaoToken 通道本身是通的curl https://taotoken.net/api/chat/completions \ -H Authorization: Bearer sk-你的TaoToken密钥 \ -H Content-Type: application/json \ -d { model: gpt-4o-mini, messages: [{role: user, content: 用一句话解释向量检索}] }返回里如果有choices[0].message.content说明 Key、Base URL、模型 ID 三件套都对。这一步能排除掉大部分「到底是通道问题还是应用问题」的扯皮。4.2 验证 Open Notebook 的 API 连通性Open Notebook 的 REST API 在 5055 端口。先看健康状态curl http://localhost:5055/api/health然后列出已注册的模型确认 TaoToken 的模型在里面curl http://localhost:5055/api/models | jq如果返回的 JSON 里有你注册的taotoken-chat和taotoken-embed说明应用层已经认到了通道。4.3 端到端验证脚本下面这段 Python 脚本做三件事创建一个 Notebook、导入一段文本、发起一次带引用的问答。把它存成verify_open_notebook.pyimport requests BASE http://localhost:5055/api HEADERS {Content-Type: application/json} # 1. 创建 Notebook nb requests.post(f{BASE}/notebooks, headersHEADERS, json{ name: TaoToken 验证, description: 端到端连通性测试 }).json() nb_id nb[id] print(Notebook:, nb_id) # 2. 导入一段文本作为来源 src requests.post(f{BASE}/notebooks/{nb_id}/sources, headersHEADERS, json{ type: text, title: 测试材料, content: Open Notebook 使用 SurrealDB 同时支持全文搜索和向量搜索。 }).json() print(Source:, src.get(id)) # 3. 发起问答 ans requests.post(f{BASE}/notebooks/{nb_id}/chat, headersHEADERS, json{ message: Open Notebook 用什么数据库它支持哪两种搜索 }).json() print(Answer:, ans.get(content))运行pip install requests python verify_open_notebook.py成功的话最后一行会打印出基于你导入材料的回答并且带上来源引用。如果回答里提到了 SurrealDB 和两种搜索说明「导入 → 向量化 → 检索 → 生成」整条链路是通的。4.4 成功结果的判断标准我一般看三个信号一是Test Connection返回成功二是Discover Models能列出模型三是问答结果带引用来源。三个都满足才算真正接好。只满足前两个可能 Embedding 没配语义搜索是瘸的。5. 本篇常见报错排查5.1 401 Unauthorized最常见。原因通常是 Key 复制时带了空格、Key 被撤销、或者 Base URL 写成了带 UTM 的地址。检查.env里的OPENAI_API_KEY和界面里填的 Key 是否一致。注意 TaoToken 的 API 地址是https://taotoken.net/api不要在后面拼/v1也不要带查询参数。5.2 local proxy failed / connection refused这个报错一般出现在容器内请求外部通道时。先确认容器能出网docker compose exec open_notebook curl -I https://taotoken.net/api如果这里就失败是容器网络问题不是 Key 问题。检查宿主机 DNS 和防火墙。如果宿主机能通、容器不通多半是 Docker 的 DNS 配置给open_notebook服务加dns: 8.8.8.8试试。5.3 reading choices of undefined这个报错说明请求发出去了但返回体结构不是预期的 OpenAI 格式。常见原因是 Base URL 指错了端点或者模型 ID 不存在导致返回了错误对象。先用 4.1 的 curl 确认返回结构再回头检查 Open Notebook 里注册的model_id是否和通道支持的完全一致。大小写、连字符都要对上。5.4 OAuth / 认证相关报错如果你在配置里误选了需要 OAuth 的提供商比如某些云厂商的托管端点会走到 OAuth 流程然后失败。Open Notebook 接 TaoToken 应该选 OpenAI 或 OpenAI Compatible不要选需要额外 OAuth 的选项。回到Settings → API Keys删掉错误凭据重新添加。5.5 导入文档后语义搜索为空界面能问答但语义搜索没结果八成是 Embedding 模型没注册或没设为默认。检查Settings里 Embedding 那一栏是否指向taotoken-embed。另外已经导入的文档如果是在配置 Embedding 之前导入的需要重新触发一次内容处理否则不会补做向量化。5.6 容器启动后 8502 打不开先docker compose ps看容器状态。如果是restarting看日志。如果是running但打不开检查端口是否被占用ss -tlnp | grep 8502被占用就改docker-compose.yml里的端口映射比如18502:8502。6. 把统一通道用进日常研究流跑通之后我实际用下来的感受是把模型通道收敛到一个入口最大的收益不是省钱而是「切换成本趋近于零」。以前换个模型要改配置、重启、重新测现在在 TaoToken 控制台调整Open Notebook 侧几乎无感。如果你打算长期用 Open Notebook 做研究建议把 Coding Plan 也了解一下地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。它适合需要长期跑 Agent、批量处理材料的场景配合 Open Notebook 的 REST API 可以做自动化流水线比如定时把新论文导入 Notebook 并生成摘要。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各语言 SDK 的调用示例。控制台在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 可以看用量和额度。最后给一个我踩过的坑Open Notebook 的OPEN_NOTEBOOK_ENCRYPTION_KEY一旦设定不要随意更改否则数据库里已加密的凭据会解不开表现为模型突然全部失效。换 Key 之前先备份surreal_data目录。这个坑不写在官方文档显眼处但会让你排查半天。