agentic_huge_data_base / wiki
页面 Open WebUI · 9.2 内容格式转换·DeepWiki 中文全文译文

9.2 · 内容格式转换(Content Format Conversion)

多模型对话工作台与知识应用入口 · 本章是 Open WebUI DeepWiki 中文译文的独立章节页,保留原始链接、源码锚点、模块标签和章节层级。

项目Open WebUI 章节9.2 状态全文译文 模块界面与交互、频道、笔记与协作、工具、记忆与模型调用、接口与服务契约
源码线索
  • src/lib/components/icons/AdjustmentsHorizontalOutline.svelte
  • src/lib/components/icons/ArrowUpLeft.svelte
  • src/lib/components/icons/PagePlus.svelte
  • src/lib/components/notes/NoteEditor.svelte
  • src/lib/components/notes/NoteEditor/Chat.svelte
  • src/lib/components/notes/NoteEditor/Chat/Message.svelte
  • src/lib/components/notes/NoteEditor/Chat/Messages.svelte
  • src/lib/components/notes/NoteEditor/Controls.svelte
  • src/lib/components/notes/NotePanel.svelte
  • src/lib/components/notes/utils.ts
模块标签
  • 界面与交互
  • 频道、笔记与协作
  • 工具、记忆与模型调用
  • 接口与服务契约
  • 系统架构

中文译文

内容格式转换(中文译文)

原始 DeepWiki 页面:https://deepwiki.com/open-webui/open-webui/9.2-content-format-conversion
翻译时间:2026-06-09T16:09:52.142Z
翻译模型:deepseek-chat
原文字符数:10432
项目:Open WebUI (open-webui)

---

内容格式转换

相关源文件

以下文件为本 wiki 页面的生成提供了上下文:

  • src/lib/components/icons/AdjustmentsHorizontalOutline.svelte
  • src/lib/components/icons/ArrowUpLeft.svelte
  • src/lib/components/icons/PagePlus.svelte
  • src/lib/components/notes/NoteEditor.svelte
  • src/lib/components/notes/NoteEditor/Chat.svelte
  • src/lib/components/notes/NoteEditor/Chat/Message.svelte
  • src/lib/components/notes/NoteEditor/Chat/Messages.svelte
  • src/lib/components/notes/NoteEditor/Controls.svelte
  • src/lib/components/notes/NotePanel.svelte
  • src/lib/components/notes/utils.ts
  • src/routes/(app)/admin/+layout.svelte/admin/+layout.svelte)
  • src/routes/(app)/admin/+page.svelte/admin/+page.svelte)
  • src/routes/(app)/home/+layout.svelte/home/+layout.svelte)
  • src/routes/(app)/notes/+page.svelte/notes/+page.svelte)
  • [src/routes/(app)/notes/[id]/+page.svelte](src/routes/(app)/notes/[id]/+page.svelte)
  • src/routes/(app)/notes/new/+page.svelte/notes/new/+page.svelte)
  • src/routes/(app)/playground/+layout.svelte/playground/+layout.svelte)
  • src/routes/(app)/workspace/+layout.svelte/workspace/+layout.svelte)

本文档阐述了双向内容格式转换系统,该系统在 MarkdownHTMLTiptap JSON 格式之间维护同步表示。转换管道允许用户使用 Markdown 语法,而 Tiptap 编辑器在内部操作 HTML/ProseMirror 结构,同时所有格式都会被存储,用于版本控制、AI 处理和导出。

有关 Tiptap 编辑器整体架构和扩展的信息,请参阅 9.1 TipTap 编辑器架构。有关使用 Yjs CRDT 的协作编辑功能,请参阅 9.3 协作编辑

目的与范围

内容格式转换系统提供以下功能:

  • Markdown → HTML 转换:在初始化编辑器内容时使用 markedsrc/lib/components/notes/NoteEditor.svelte:168-170
  • HTML → Markdown 转换:在提取用户输入用于 AI 上下文或存储时使用 TurndownService
  • JSON → HTML 转换:通过 ProseMirror schema 恢复编辑器状态 src/lib/components/notes/NoteEditor.svelte:248-251
  • 自定义渲染规则:针对任务列表、表格和代码块,确保 AI 的 Markdown 响应与编辑器视觉状态之间的一致性 src/lib/components/notes/NoteEditor/Chat.svelte:7-31
  • 多格式存储:支持版本控制、导出和跨平台兼容性 src/lib/components/notes/NoteEditor.svelte:108-122

该系统在编辑器事务期间透明运行,同时维护三种格式的表示。笔记将所有格式持久化到数据库结构中:note.data.content.jsonnote.data.content.htmlnote.data.content.md src/lib/components/notes/NoteEditor.svelte:108-115

来源: src/lib/components/notes/NoteEditor.svelte:108-122src/lib/components/notes/NoteEditor/Chat.svelte:7-31

转换管道架构

三向格式转换流程
graph TB
    subgraph "外部接口"
        MDInput["Markdown 输入<br/>(AI 响应 / 初始加载)"]
        MDOutput["Markdown 输出<br/>(AI 上下文 / 导出)"]
    end

    subgraph "存储层"
        NoteStorage["note.data.content<br/>{json, html, md}"]
    end

    subgraph "转换层"
        MarkedParser["marked.use()<br/>Markdown -> HTML"]
        TurndownService["TurndownService<br/>HTML -> Markdown"]
    end

    subgraph "编辑器核心"
        TiptapEditor["Tiptap 编辑器<br/>(ProseMirror)"]
        HTMLState["editor.getHTML()"]
        JSONState["editor.getJSON()"]
    end

    MDInput --> MarkedParser
    MarkedParser --> TiptapEditor
    TiptapEditor --> HTMLState
    TiptapEditor --> JSONState
    HTMLState --> TurndownService
    TurndownService --> MDOutput

    HTMLState --> NoteStorage
    JSONState --> NoteStorage
    MDOutput --> NoteStorage

    NoteStorage -.->|恢复版本| TiptapEditor

来源: src/lib/components/notes/NoteEditor.svelte:108-115src/lib/components/notes/NoteEditor.svelte:168-170src/lib/components/notes/NoteEditor.svelte:233-246

转换发生在关键事务节点:

  1. 初始化:加载笔记时,系统检查是否存在 HTML。如果缺失,则回退到通过 marked.parse() 解析 Markdown 来填充编辑器 src/lib/components/notes/NoteEditor.svelte:168-170
  2. AI 集成:当 AI 模型生成内容时,通常提供 Markdown。Chat.svelte 组件处理此流并触发编辑器更新 src/lib/components/notes/NoteEditor/Chat.svelte:204-241
  3. 版本存储NoteEditor.svelte 中的 insertNoteVersion() 函数为版本历史数组存储所有三种格式(JSON、HTML、MD)的快照 src/lib/components/notes/NoteEditor.svelte:233-246
  4. 手动编辑:当编辑器内容发生变化时,状态会更新并在各格式之间同步,以确保 md 表示可用于标题生成 src/lib/components/notes/NoteEditor.svelte:253-255

来源: src/lib/components/notes/NoteEditor.svelte:168-170src/lib/components/notes/NoteEditor.svelte:233-246src/lib/components/notes/NoteEditor/Chat.svelte:204-241

Markdown 到 HTML 转换(marked.js)

marked 库被广泛用于将 AI 生成的 Markdown 转换为与 Tiptap 编辑器 schema 兼容的 HTML。自定义渲染器处理特定的 GFM(GitHub Flavored Markdown)扩展。

自定义列表和任务渲染

在笔记系统中,列表需要特定的 HTML 属性才能被 Tiptap 的 TaskListTaskItem 扩展识别 src/lib/components/notes/NoteEditor/Chat.svelte:10-30

  • 列表渲染器:检测列表是否包含任务项(已勾选/未勾选)。如果是,则将内容包裹在 <ul data-type="taskList"> 中,而不是标准的 <ul> src/lib/components/notes/NoteEditor/Chat.svelte:11-21
  • 列表项渲染器:将 Markdown 任务语法(- [ ]- [x])转换为带有 data-type="taskItem" 和布尔属性 data-checked 的列表项 src/lib/components/notes/NoteEditor/Chat.svelte:23-29
graph LR
    subgraph "Marked 自定义渲染器"
        MD["Markdown: - [x] 任务"] --> List["list() 函数"]
        List --> Detect["检查 'data-checked='"]
        Detect --> HTML["HTML: &lt;li data-type='taskItem' data-checked='true'&gt;"]
    end

来源: src/lib/components/notes/NoteEditor/Chat.svelte:7-31

与 AI 工作流的集成

转换系统对于笔记中的 AI 集成至关重要。AI 充当“专家文档编辑器”,接收当前内容的 Markdown 格式,并返回增强后的相同格式版本。

AI 上下文准备

在向 LLM 发送请求之前,系统将数据聚合到基于 Markdown 的提示中 src/lib/components/notes/NoteEditor/Chat.svelte:160-171

  1. 现有笔记:使用 note.data.content.md 包裹在 <notes> XML 标签中 src/lib/components/notes/NoteEditor/Chat.svelte:166
  2. 文件上下文:附加文件中提取的内容被追加 src/lib/components/notes/NoteEditor/Chat.svelte:167-169
  3. 选中内容:如果用户高亮了文本,则将其包裹在 <selection> 标签中 src/lib/components/notes/NoteEditor/Chat.svelte:170
AI 响应处理

当 AI 流式输出 Markdown 时,Chat.svelte 组件管理状态。AI 完成后,生成的 Markdown 用于更新编辑器内容 src/lib/components/notes/NoteEditor/Chat.svelte:219-224

来源: src/lib/components/notes/NoteEditor/Chat.svelte:160-171src/lib/components/notes/NoteEditor/Chat.svelte:219-241

笔记存储结构

笔记在 data.content 对象中以三种同步格式持久化内容 src/lib/components/notes/NoteEditor.svelte:108-115

格式属性用途
JSONjson主要的 Tiptap/ProseMirror 状态;用于精确的文档结构保存 src/lib/components/notes/NoteEditor.svelte:112
HTMLhtml用于编辑器中的即时渲染和基于 Web 的预览 src/lib/components/notes/NoteEditor.svelte:113
Markdownmd用于 AI 上下文、标题生成和导出到外部工具 src/lib/components/notes/NoteEditor.svelte:114
版本控制集成

insertNoteVersion() 函数捕获所有三种格式的快照 src/lib/components/notes/NoteEditor.svelte:233-246。在保存新版本之前,它使用 areContentsEqual()(通过 fast-deep-equal)验证内容是否实际发生变化,以防止重复的历史记录 src/lib/components/notes/NoteEditor.svelte:229-231

来源: src/lib/components/notes/NoteEditor.svelte:108-115src/lib/components/notes/NoteEditor.svelte:229-246

格式支持矩阵

Markdown 结构HTML 表示Tiptap 节点/属性
- [ ] 任务项<li data-type="taskItem" data-checked="false">taskItem 扩展 src/lib/components/notes/NoteEditor/Chat.svelte:26
- [x] 已勾选任务<li data-type="taskItem" data-checked="true">taskItem 扩展 src/lib/components/notes/NoteEditor/Chat.svelte:26
GFM 表格<table>...</table>Table 扩展
硬换行<br />HardBreak 扩展 src/lib/components/notes/NoteEditor/Chat.svelte:8

来源: src/lib/components/notes/NoteEditor/Chat.svelte:7-31