将内容导入 Open Notebook:添加 Source 的完整实战指南
【免费下载链接】open-notebookAn Open Source implementation of Notebook LM with more flexibility and features项目地址: https://gitcode.com/GitHub_Trending/op/open-notebook
把文档、网页、音视频等外部材料转化为可供 AI 检索与对话的「研究原材料」,是 Open Notebook 一切工作流(Chat、Search、Transformations、Podcasts)的起点。本文基于官方用户指南 adding-sources.md,系统讲解在 Open Notebook 中如何通过上传文件、粘贴链接、粘贴文本三种方式添加 Source,覆盖支持的格式清单、后台处理管线(抽取→分块→向量化→入库)、各类内容的处理时长预期、来源状态与上下文管理,并结合仓库源码说明每次添加时实际发生了什么。读完本文,你将能够根据材料类型选择正确的添加路径、预判处理耗时、排解常见错误,并控制 AI 对来源内容的访问级别。
快速开始:添加你的第一个 Source
在笔记本(Notebook)页面中点击Add Source即可开始。系统提供三种入口,适用于不同形态的原始材料:
方式一:上传文件(PDF、Word 等)
1. 在笔记本中点击 "Add Source" 2. 选择 "Upload File" 3. 从本地电脑选择文件 4. 点击 "Upload" 5. 等待 30-60 秒处理 6. 完成!Source 出现在你的笔记本中方式二:添加网页链接
1. 点击 "Add Source" 2. 选择 "Web Link" 3. 粘贴 URL:https://example.com/article 4. 点击 "Add" 5. 等待处理(通常比文件更快) 6. 完成!方式三:直接粘贴文本
1. 点击 "Add Source" 2. 选择 "Text" 3. 粘贴或输入内容 4. 点击 "Save" 5. 完成!立即可用从 API 角度看,这三种类型在底层分别对应create_source路由中的type字段取值:upload、link、text。接口以 multipart/form-data 接收表单参数(类型、目标笔记本、URL、正文、标题、是否嵌入等),随后根据提交的async_processing标志决定走异步后台队列还是同步执行路径,可参考 api/routers/sources.py 中parse_source_form_data与_build_content_state的实现。
支持的格式
文档类
| 类别 | 格式 | 说明 |
|---|---|---|
.pdf | 支持最完善,含扫描件 OCR | |
| Word | .docx,.doc | 完整支持 |
| PowerPoint | .pptx | 幻灯片转为文本 |
| Excel | .xlsx,.xls | 表格数据 |
| EPUB | .epub | 电子书文件 |
| Markdown / 纯文本 | .md,.txt | 纯文本格式 |
| HTML | .html,.htm | 网页文件 |
| 图片 | .png,.jpg,.jpeg,.tiff,.bmp | 通过 OCR 读取文字,需要启用 Docling(见下文) |
文件大小上限:约 100MB(因系统而异)。API 侧由MaxBodyMiddleware兜底,默认上限 100MB,可通过环境变量OPEN_NOTEBOOK_MAX_UPLOAD_SIZE_MB调整(见 api/middleware.py);若部署了反向代理,还需同步放开代理的上传体积限制(参考 docs/5-CONFIGURATION/reverse-proxy.md)。
处理时长:10 秒到 2 分钟(取决于长度与文件类型)。
OCR(扫描版 PDF 与图片):扫描版 PDF 和图片文件中的文字依赖 OCR 读取。OCR 走Docling引擎,该引擎是可选组件:当你在环境变量中设置OPEN_NOTEBOOK_ENABLE_DOCLING=true时,容器会在首次启动时自动安装。启用后 OCR 默认开启,如需关闭或强制使用更精确的抽取引擎,可前往Settings → Content Processing调整,详细说明见 内容处理引擎指南。
音频与视频
- 音频:MP3、WAV、M4A、OGG、FLAC(处理速度约为每小时音频 30 秒 - 3 分钟)
- 视频:MP4、AVI、MOV、MKV、WebM(处理速度约为每小时视频 3-10 分钟)
- YouTube:支持直接粘贴 URL
- 播客:支持 RSS feed 地址
自动转写:音频/视频会由系统自动转写为文本。该功能需要在设置中启用语音转文本(speech-to-text)。在源码中,转写模型来自系统默认配置:当配置了默认语音转写模型时,content_process会把其 provider/model 写入 content-core 的抽取配置,可参考 open_notebook/graphs/source.py 中读取default_speech_to_text_model的逻辑。
网页内容
- 文章:博客、新闻、Medium
- YouTube:完整视频、播放列表,以及
/live/、/shorts/链接 - Reddit:公开帖子 URL(通过 Reddit 公开 JSON 获取)
- 在线 PDF:直接的 PDF 链接
- 新闻:新闻网站文章
直接粘贴 URL 到 "Web Link" 即可。
JS 重度网站:URL 能抽取到什么程度取决于 URL 处理引擎。默认的auto引擎会依次尝试多个引擎;启用 Crawl4AI 后可在本地渲染 JavaScript 页面。如果链接抽取结果为空,参见内容处理引擎指南。此外,YouTube 的字幕语言偏好由源码中的YOUTUBE_PREFERRED_LANGUAGES列表决定(见 open_notebook/graphs/source.py),包含 en、pt、es、de、nl、en-GB、fr、hi、ja 等语言。
不支持的输入
- 付费墙内容(如 WSJ、FT 等)——无法抽取
- 带密码保护的 PDF——无法打开
- 不支持的格式——立即被拒绝并给出清晰的 "unsupported file type" 提示,不会让你长时间等待
- 超大文件(>100MB)——超时
后端对「不支持格式」做了上传前置检查(pre-flight check):上传接口会先调用 content-core 的check_file_support按文件头判断类型,一旦判定不支持就直接抛出UnsupportedTypeException(映射为 HTTP 415),而不会把注定失败的任务投进后台队列空耗重试预算,可参考 api/routers/sources.py 中_assert_file_supported的实现与 tests/test_upload_type_mitigations.py 的测试用例。
添加 Source 后会发生什么
系统会自动完成四件事:
1. 抽取文本 (EXTRACT TEXT) 文件/URL → 可读文本 (PDF 若为扫描件则走 OCR) (视频若启用转写则转写) 2. 切分块 (BREAK INTO CHUNKS) 长文本 → 约 500 词的片段 (这样搜索命中的是具体片段,而不是整篇文档) 3. 生成向量 (CREATE EMBEDDINGS) 每个块 → 向量表示 (支撑语义/概念搜索) 4. 索引入库 (INDEX & STORE) 全部 → 数据库 (随时可检索、可召回)何时可用:进度条走完后,Source 立即可用。向量化(embedding)在后台异步进行。
源码视角的完整管线
这四个阶段在仓库中由一条 LangGraph 工作流实现(source_graph,见 open_notebook/graphs/source.py),状态流转为:START → content_process → save_source → (条件触发) transform_content → END。
content_process:根据内容类型调用 content-core 的extract_content。对于 URL,支持url_engine(auto/simple/firecrawl/jina/crawl4ai);对文件支持document_engine(auto/docling/simple),并可透传docling_ocr、docling_formulas、docling_vision开关。如果某个被配置的引擎是可选的且其运行时未安装,_usable_engine会自动回退到auto并打印告警日志。抽取结果为空时(含 YouTube 无字幕),系统会抛出明确错误使任务标记为 failed 并可重试。save_source:把抽取出的文本写入source.full_text,仅当标题为占位符时才用抽取出的标题覆盖(保留用户自定义标题),随后保存数据库记录。- 切块:文本切块由 open_notebook/utils/chunking.py 完成。核心逻辑:若全文 token 数不超过块上限则直接作为单块;否则按内容类型(HTML/Markdown/纯文本)选择对应 splitter,再对超长块做二次切分、丢弃低于
MIN_CHUNK_SIZE的碎片块。可通过环境变量OPEN_NOTEBOOK_CHUNK_SIZE(默认 400 token,最小 100)、OPEN_NOTEBOOK_CHUNK_OVERLAP(默认块大小的 15%)、OPEN_NOTEBOOK_MIN_CHUNK_SIZE(默认 5)调优。内容类型优先按文件扩展名判定(.html/.md/.txt等),无扩展名或不确定时由文本内容启发式打分兜底。 - 向量化:
save_source在embed=True时调用source.vectorize()。该方法是 fire-and-forget 的:向队列提交embed_source命令,由 commands/embedding_commands.py 中的embed_source_command在后台执行「删除旧向量 → 检测内容类型 → 切块 → 批量生成向量 → 批量写入source_embedding表」。这也是为什么进度条完成后 Source 即可对话使用——检索所需的文本已就绪,向量在后台补齐。
以process_source命令为入口的后台任务还带有健壮的重试策略:最多 15 次、指数抖动退避(1-120 秒),但对ValueError/ConfigurationError这类确定性错误不重试(见 commands/source_commands.py)。
分类型实操步骤
最佳实践:
纯文字 PDF: 1. 上传 → 完成 2. 处理时间:约 30-60 秒 扫描版 / 图片型 PDF: 1. 同样方式上传 2. 系统自动识别并启用 OCR 3. 处理时间:约 2-3 分钟 4. (OCR 带来额外开销,耗时更高) 大型 PDF(50 页以上): 1. 考虑拆分为多个小文件 2. 或按原样上传(系统能处理) 3. 处理时间随体量线性增长常见问题:
- 报错 "Can't extract text" → PDF 损坏或带复制保护
- 对策:先用 Adobe 打开试试。如果连 Adobe 都打不开,该 PDF 很可能受保护。
网页链接 / 文章
最佳实践:
1. 从浏览器复制完整 URL:https://example.com/article-title 2. 粘贴到 "Web Link" 3. 点击 Add 4. 等待抽取 处理时间:通常 5-15 秒可以成功:标准网页文章、博客、新闻、Wikipedia 页面、Medium、Substack 文章。
无法成功:
- Twitter 帖子串(不可靠)
- 付费墙文章(无法访问)
- JavaScript 重度站点(内容无法抽取)
专业建议:如果链接抽取失败,把文章正文复制后改用 "Text" 方式粘贴即可。前端添加对话框同时支持给链接打标签、关联多个笔记本以及附带变换(transformations),可参考 frontend/src/components/sources/AddSourceDialog.tsx。
音频文件
最佳实践:
1. 确保在 Settings 中启用语音转文本 2. 上传 MP3、WAV 或 M4A 文件 3. 系统自动转写为文本 4. 处理时间:每 5 分钟音频约 1 分钟 示例: - 1 小时播客 → 约 12 分钟处理 - 10 分钟录音 → 约 2 分钟处理音质至关重要:
- 清晰音频:转写快
- 模糊/嘈杂音频:转写慢且准确率下降
- 背景噪音:上传前尽量消除
提示:若音质差,AI 可能误解内容。必要时可手动修正转写稿。
YouTube 视频
两种添加方式:
方式一:直接 URL 1. 复制 YouTube 链接:https://www.youtube.com/watch?v=... (普通 watch、/live/、/shorts/ 链接均可用) 2. 粘贴到 "Web Link" 3. 点击 Add 4. 系统抽取字幕(若有)+ 转写 方式二:播放列表 1. 粘贴播放列表 URL 2. 系统将每个视频作为独立 Source 添加 3. 每个视频分别处理 4. 耗时更长(视频较多)抽取内容:字幕/副标题(若可用)、转写文本(若无字幕)、基础元数据(标题、频道、时长)。
处理时长:
- 10 分钟视频:约 2-3 分钟
- 1 小时视频:约 10-15 分钟
文本 / 粘贴内容
最佳实践:
1. 添加 Source 时选择 "Text" 2. 粘贴或输入内容 3. 系统立即处理 4. 无需等待 适合: - 想引用的笔记 - 书中摘录 - 手头现成的文稿 - 快速研究片段管理你的 Sources
查看来源详情
点击 Source → 可查看: - 原始文件名/标题 - 添加时间 - 大小与格式 - 处理状态 - 分块数量详情接口还会返回该来源是否已嵌入(embedded)、已嵌入块数(embedded_chunks)、关联的命令 ID 与处理进度元数据,以及原始文件是否仍可在服务器上访问(file_available),见 api/routers/sources.py 的get_source。列表接口支持按type、title、created、updated、insights_count、embedded排序并带分页(limit1-100、offset)。每当打开某个来源详情,系统还会在后台更新last_viewed_at时间戳以支撑「最近查看」功能。
用元数据组织来源
每个 Source 都可以补充:
- 标题(Title):比原始文件名更友好的命名
- 标签(Tags):分类标签,例如 "primary research"、"background"、"competitor analysis"
- 描述(Description):几句内容说明
为什么重要:
- 让来源更易检索
- 辅助 Chat 场景下的上下文构建
- 便于组织大型笔记本
在领域模型中,Source 的标题与标签分别对应title与topics字段,可通过PUT /sources/{id}接口(update_source,只更新传入的字段)或界面直接修改,见 open_notebook/domain/notebook.py 与 api/routers/sources.py。删除来源时,Source.delete()会一并清理上传文件、source_embedding与source_insight记录,避免产生孤儿数据。
在来源内搜索
来源添加完成后,你可以: 文本搜索:找确切词组 向量搜索:找概念相近内容 两种搜索都覆盖笔记本内全部来源。 结果会显示: - 来自哪个来源 - 命中的段落 - 相关度得分两者在代码中的入口分别是 open_notebook/domain/notebook.py 的text_search(调用 SurrealDB 的全文检索函数)与vector_search(先调用generate_embedding生成查询向量再执行向量检索)。文本检索在高亮出现字节位置溢出时会自动回退到向量搜索以保证可用性。
上下文管理:Sources 如何被使用
你可以控制 AI 访问来源的方式。对 Chat 而言共有三个层级:
完整内容(Full Content)
AI 看到:完整来源文本 成本:100% token 适用:需要精读分析、精确引用时 示例:"仔细分析这篇方法学论文"仅摘要(Summary Only)
AI 看到:AI 生成的摘要(而非全文) 成本:约 10-20% token 适用:背景材料、参考上下文 示例:"把它当作背景,但聚焦主来源"不在上下文中(Not in Context)
AI 看到:无(被排除) 成本:0 token 适用:机密、不相关或已归档 示例:"保留在笔记本里,但本次对话不要使用"如何在 Chat 中设置上下文:
1. 进入 Chat 2. 点击 "Select Context Sources" 3. 对每个来源: - 开关 ON/OFF(包含/排除) - 选择层级(Full/Summary/Excluded) 4. 点击 "Save" 5. Chat 随即使用这些设置从源码看,来源之所以能按「全文 / 摘要 / 排除」灵活注入,是因为领域层提供了细粒度的上下文读取方法:Source.get_context()支持short/long两种规格,long会携带完整正文与洞察(insights),short仅返回标题与洞察;Notebook.get_context()则把这些片段组装为带## Source:/## Note:标题的结构化长文,供 Chat、播客等下游使用(见 open_notebook/domain/notebook.py)。界面侧的上下文选择器与切换控件见 frontend/src/components/common/ContextIndicator.tsx 与 frontend/src/components/common/ContextToggle.tsx。
常见错误
| 错误 | 后果 | 对策 |
|---|---|---|
| 一次性上传 200 个来源 | 系统变慢、处理停滞 | 一次添加 10-20 个,等处理完成 |
| 所有来源都用完整内容 | token 消耗飙升、成本高 | 背景材料用 "Summary" 或 "Excluded" |
| 上传超大 PDF 而不拆分 | 处理慢、搜索结果不精确 | 考虑把大 PDF 拆成章节 |
| 忘记给来源命名 | 相似来源难以区分 | 上传后立即用描述性标题重命名 |
| 不添加标签 | 日后难查找、难组织 | 立即加标签:"primary"、"background" 等 |
| 一个来源混用多种语言 | 转写/向量质量下降 | 每种语言单独成来源 |
| 重复使用同一来源多次 | 占用空间、造成混淆 | 只添加一次;在多个 Chat/笔记本中复用 |
处理状态与故障排查
状态指示的含义
🟡 处理中 (Processing) → 来源正在抽取与向量化 → 等待 30 秒 - 3 分钟(取决于大小) → 暂时不要用于 Chat 🟢 就绪 (Ready) → 来源已处理完成且可搜索 → 可立即用于 Chat → 可应用 Transformations 🔴 错误 (Error) → 出了某些问题 → 常见原因: - 不支持的格式 - 文件过大或损坏 - 网络超时 ⚪ 不在上下文中 (Not in Context) → 来源已添加但被排除出 Chat → 仍可搜索,但不会发给 AI这些状态标签直接来自后台命令的实时状态。每个 Source 关联一个command记录(指向 surreal-commands 的处理任务),Source.get_status()返回 queued/running/completed/failed 等状态,get_processing_progress()返回起止时间与错误信息。异步创建路径会把状态初始化为new并标记queued,同步路径则直接等待最多 5 分钟的执行结果(见 api/routers/sources.py 的_create_source_async_path/_create_source_sync_path)。处理失败或卡住的来源可以在界面一键重试,重试接口POST /sources/{id}/retry会重新提交process_source命令并总是启用向量化。
常见错误及解决
"Unsupported file type"(不支持的文件类型)
- 你上传了格式清单之外的文件(如
.webp图片) - 上传会立即被拒绝并提示检测到的类型——不会长时间卡在 "Processing" 状态
- 注意:图片格式(PNG/JPEG/TIFF/BMP)仅在启用 Docling时受支持(
OPEN_NOTEBOOK_ENABLE_DOCLING=true) - 对策:转换成支持格式(文档用 PDF、音频用 MP3),或启用 Docling 以支持图片
"Processing timeout"(处理超时)
- 文件过大(>100MB)或音频过长
- 对策:拆分成更小的片段或重新上传
"Transcription failed"(转写失败)
- 音频质量太差或未能识别语言
- 对策:用更好的质量重新录制,或手动粘贴文本转写稿
"Web link won't extract"(网页链接抽取失败)
- 网站阻止自动化访问或内容依赖 JavaScript 渲染
- 对策:尝试不同的 URL 处理引擎(见内容处理引擎指南)——启用 Crawl4AI 可渲染 JavaScript 页面——或者复制文章正文后以 "Text" 方式粘贴
最佳效果建议
对 PDF
- 干净的数字版 PDF 效果最好
- 如有复制保护请先解除(须合法)
- 扫描版 PDF 可用但耗时更长
对网页文章
- 使用包含域名的完整 URL
- 避开满是 Cookie/弹窗的站点
- 若抽取失败,改用复制粘贴正文
对音频
- 清晰、录音良好的音频转写效果更好
- 尽量去除背景噪音
- YouTube 视频通常自带良好转写
对大文档
- 考虑拆分成更小的来源
- 搜索结果更精确
- 小片段处理更快
对组织管理
- 给来源清晰命名(不要叫 "document_2.pdf")
- 上传后立即添加标签
- 复杂文档用描述说明内容
添加之后:使用你的 Sources
一旦添加完成,来源即可驱动多种下游能力:
- Chat→ 提问对话(见 有效使用 Chat)
- Search→ 检索具体内容(见 搜索指南)
- Transformations→ 抽取结构化洞察(见 笔记使用)
- Ask→ 获取综合答案(见 搜索指南)
- Podcasts→ 转为音频(见 创建播客)
值得注意的是,你在添加来源时还可以顺带挂载变换(transformations):表单中的transformations字段支持传入一组预定义变换 ID,后台处理完来源后会自动对全文运行这些变换并生成 insights(见 api/routers/sources.py 与 open_notebook/graphs/source.py 中trigger_transformations的条件分支)。
行动清单
添加来源之前,逐项确认:
- 文件是支持的格式
- 文件小于 100MB(或对大型文件做了拆分)
- 网页链接是完整 URL(而非短链)
- 音频文件发音清晰(若依赖转写)
- 已给来源清晰命名
- 已添加标签便于组织
- 已理解上下文层级(Full/Summary/Excluded)
完成以上确认后,来源即可用于 Chat、Search、Transformations 及其他一切后续流程——这正是 Open Notebook 从「收集」走向「研究产出」的关键一步。
【免费下载链接】open-notebookAn Open Source implementation of Notebook LM with more flexibility and features项目地址: https://gitcode.com/GitHub_Trending/op/open-notebook
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考