消息渲染(中文译文)
原始 DeepWiki 页面:https://deepwiki.com/open-webui/open-webui/5-message-rendering
翻译时间:2026-06-09T16:08:24.987Z
翻译模型:deepseek-chat
原文字符数:10708
项目:Open WebUI (open-webui)
---
消息渲染
相关源文件
以下文件为本 wiki 页面的生成提供了上下文:
src/lib/components/chat/Chat.sveltesrc/lib/components/chat/ContentRenderer/FloatingButtons.sveltesrc/lib/components/chat/MessageInput.sveltesrc/lib/components/chat/Messages.sveltesrc/lib/components/chat/Messages/CodeBlock.sveltesrc/lib/components/chat/Messages/ContentRenderer.sveltesrc/lib/components/chat/Messages/Markdown.sveltesrc/lib/components/chat/Messages/Markdown/AlertRenderer.sveltesrc/lib/components/chat/Messages/Markdown/ConsecutiveDetailsGroup.sveltesrc/lib/components/chat/Messages/Markdown/MarkdownTokens.sveltesrc/lib/components/chat/Messages/Message.sveltesrc/lib/components/chat/Messages/MultiResponseMessages.sveltesrc/lib/components/chat/Messages/ResponseMessage.sveltesrc/lib/components/chat/Messages/UserMessage.sveltesrc/lib/components/chat/PyodideFileNav.sveltesrc/lib/components/common/ToolCallDisplay.sveltesrc/lib/utils/index.tssrc/lib/utils/marked/extension.tssrc/lib/workers/pyodide.worker.ts
目的与范围
本文档描述了 Open WebUI 中的消息渲染系统,该系统负责在用户界面中显示聊天消息。内容涵盖组件架构、数据流、内容处理管道,以及不同类型消息(用户消息、助手消息、多模型消息)如何通过丰富的格式(包括 Markdown、代码块、图片、引用和交互元素)进行渲染。
有关特定子系统的详细技术规范,请参阅以下子页面:
- 响应消息组件 — 详细说明
ResponseMessage.svelte组件如何渲染带有引用、代码执行和反馈机制的 AI 响应。 - 内容渲染管道 — 解释消息内容如何通过 Markdown 解析、语法高亮和特殊元素处理进行加工。
- Markdown 处理 — 记录 Markdown 处理系统,包括 GitHub 风格 Markdown、LaTeX 数学公式渲染和代码块处理。
- 代码块执行 — 解释代码块执行系统,该系统允许通过 Pyodide 和 Jupyter 直接从聊天消息中运行 Python 代码。
- 多模型响应展示 — 记录
MultiResponseMessages.svelte组件如何并排显示来自多个 AI 模型的响应。 - 交互式文本操作 — 解释交互式文本功能,如文本转语音、复制到剪贴板、消息编辑和评分/反馈。
---
消息渲染架构
消息渲染系统遵循层级组件结构,消息从容器组件出发,经过路由逻辑,根据消息类型和内容分发到专门的渲染器。
组件层级图
graph TB
Messages["Messages.svelte<br/>容器组件"]
Message["Message.svelte<br/>路由组件"]
UserMessage["UserMessage.svelte<br/>用户消息渲染器"]
ResponseMessage["ResponseMessage.svelte<br/>单条助手响应"]
MultiResponse["MultiResponseMessages.svelte<br/>多模型响应"]
ContentRenderer["ContentRenderer.svelte<br/>Markdown 与富文本内容"]
Citations["Citations.svelte<br/>来源引用"]
CodeExecutions["CodeExecutions.svelte<br/>代码执行结果"]
StatusHistory["StatusHistory.svelte<br/>状态更新"]
Markdown["Markdown.svelte<br/>Markdown 解析器"]
Messages -->|"遍历每条消息"| Message
Message -->|"role === 'user'"| UserMessage
Message -->|"单模型"| ResponseMessage
Message -->|"多模型"| MultiResponse
UserMessage --> Markdown
ResponseMessage --> StatusHistory
ResponseMessage --> ContentRenderer
ResponseMessage --> Citations
ResponseMessage --> CodeExecutions
MultiResponse --> ResponseMessage
ContentRenderer --> Markdown
来源: src/lib/components/chat/Messages.svelte:19-23、src/lib/components/chat/Messages/ResponseMessage.svelte:53-64、src/lib/components/chat/Messages/ContentRenderer.svelte:5-15
---
消息数据流
消息以树形结构存储在 history 对象中,并根据当前导航位置进行渲染。Messages.svelte 组件从 history.currentId 开始遍历这棵树,并通过 parentId 引用向后回溯,以构建要显示的消息列表。
代码实体关联图
graph TD
subgraph "前端状态空间"
H["history Store 对象"]
CI["currentId"]
ML["messages Map"]
end
subgraph "组件空间"
MS["Messages.svelte"]
BM["buildMessages()"]
HHC["handleHistoryChange()"]
end
H --> CI
H --> ML
MS --> BM
MS --> HHC
BM -->|"通过 parentId 遍历"| ML
HHC -->|"节流更新"| BM
| 步骤 | 操作 | 代码位置 |
|---|---|---|
| 1 | 从 history.currentId 开始 | src/lib/components/chat/Messages.svelte:88 |
| 2 | 通过 parentId 向后回溯 | src/lib/components/chat/Messages.svelte:99 |
| 3 | 流式传输期间节流重建 | src/lib/components/chat/Messages.svelte:121-130 |
| 4 | 使用 Message.svelte 渲染每条消息 | src/lib/components/chat/Messages.svelte:19 |
来源: src/lib/components/chat/Messages.svelte:85-103、src/lib/components/chat/Messages.svelte:107-132
---
内容处理管道
消息内容在渲染之前会经历多个转换阶段,以确保格式正确、安全性和显示效果。详情请参阅内容渲染管道。
文本转换管道
graph LR
raw["原始内容"]
sanitize["sanitizeResponseContent()"]
process["processResponseContent()"]
replace["replaceTokens()"]
markdown["marked.lexer()"]
render["MarkdownTokens.svelte"]
raw --> sanitize
sanitize --> process
process --> replace
replace --> markdown
markdown --> render
内容处理函数
| 函数 | 用途 | 位置 |
|---|---|---|
sanitizeResponseContent | 移除不完整的 token,转义 HTML 标签 | src/lib/utils/index.ts:85-94 |
processResponseContent | 修复中文字符的 Markdown/LaTeX 格式 | src/lib/utils/index.ts:96-99 |
replaceTokens | 替换 {{char}}、{{user}} 以及文件/视频 token | src/lib/utils/index.ts:55-83 |
removeAllDetails | 移除 <details> 标签以获取干净的文本副本 | src/lib/utils/index.ts:37 |
来源: src/lib/utils/index.ts:55-99、src/lib/components/chat/Messages/Markdown.svelte:62-71
---
组件概览
用户消息渲染
用户消息由 UserMessage.svelte 渲染。它支持两种布局模式:带有个人头像的传统布局,以及用于现代消息外观的“聊天气泡”模式 src/lib/components/chat/Messages/UserMessage.svelte:136-145。它处理文件附件,包括图片(通过 Image.svelte)和文档(通过 FileItem.svelte)src/lib/components/chat/Messages/UserMessage.svelte:204-228。 来源: src/lib/components/chat/Messages/UserMessage.svelte:130-228
助手响应渲染
ResponseMessage.svelte 是 AI 输出的主要组件。它管理复杂的 UI 状态,包括工具执行状态(通过 StatusHistory.svelte)、引用和代码执行结果 src/lib/components/chat/Messages/ResponseMessage.svelte:53-64。它提供交互式操作,如文本转语音和重新生成 src/lib/components/chat/Messages/ResponseMessage.svelte:226-233。详情请参阅响应消息组件。 来源: src/lib/components/chat/Messages/ResponseMessage.svelte:123-154
Markdown 与代码处理
Markdown.svelte 组件使用 marked 库及其自定义扩展来处理 LaTeX(markedKatexExtension)、引用和提及 src/lib/components/chat/Messages/Markdown.svelte:48-60。代码块由 CodeBlock.svelte 渲染,它通过 highlight.js 提供语法高亮,并通过 Pyodide 或 Jupyter 提供执行能力 src/lib/components/chat/Messages/CodeBlock.svelte:142-221。详情请参阅Markdown 处理和代码块执行。 来源: src/lib/components/chat/Messages/Markdown.svelte:48-60、src/lib/components/chat/Messages/CodeBlock.svelte:142-221
多模型对比
当用户查询多个模型时,MultiResponseMessages.svelte 负责编排并排显示 src/lib/components/chat/Messages/MultiResponseMessages.svelte:12-22。它通过 gotoMessage 管理每个模型响应分支的独立导航 src/lib/components/chat/Messages/MultiResponseMessages.svelte:76-103。详情请参阅多模型响应展示。 来源: src/lib/components/chat/Messages/MultiResponseMessages.svelte:148-203
交互式文本操作
当选中文本时,FloatingButtons.svelte 组件会显示,允许用户“提问”或“解释”响应的特定片段 src/lib/components/chat/Messages/ContentRenderer.svelte:217-226。全局操作如“复制到剪贴板”使用 copyToClipboard 工具函数,该函数处理格式化的 HTML 复制 src/lib/components/chat/Messages/ResponseMessage.svelte:192-203。详情请参阅交互式文本操作。 来源: src/lib/components/chat/Messages/ContentRenderer.svelte:217-226、src/lib/components/chat/ContentRenderer/FloatingButtons.svelte:41-76