agentic_huge_data_base / wiki
页面 Open WebUI · 10.1 频道架构·DeepWiki 中文全文译文

10.1 · 频道架构(Channel Architecture)

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

项目Open WebUI 章节10.1 状态全文译文 模块界面与交互、频道、笔记与协作、系统架构、工具、记忆与模型调用
源码线索
  • backend/open_webui/models/channels.py
  • backend/open_webui/models/messages.py
  • backend/open_webui/routers/channels.py
  • src/lib/apis/channels/index.ts
  • src/lib/components/channel/Channel.svelte
  • src/lib/components/channel/ChannelInfoModal.svelte
  • src/lib/components/channel/ChannelInfoModal/AddMembersModal.svelte
  • src/lib/components/channel/ChannelInfoModal/UserList.svelte
  • src/lib/components/channel/MessageInput.svelte
  • src/lib/components/channel/MessageInput/InputMenu.svelte
模块标签
  • 界面与交互
  • 频道、笔记与协作
  • 系统架构
  • 工具、记忆与模型调用
  • 接口与服务契约

中文译文

频道架构(中文译文)

原始 DeepWiki 页面:https://deepwiki.com/open-webui/open-webui/10.1-channel-architecture
翻译时间:2026-06-09T16:10:19.033Z
翻译模型:deepseek-chat
原文字符数:16769
项目:Open WebUI (open-webui)

---

频道架构

相关源文件

本 Wiki 页面基于以下源文件生成:

  • backend/open_webui/models/channels.py
  • backend/open_webui/models/messages.py
  • backend/open_webui/routers/channels.py
  • src/lib/apis/channels/index.ts
  • src/lib/components/channel/Channel.svelte
  • src/lib/components/channel/ChannelInfoModal.svelte
  • src/lib/components/channel/ChannelInfoModal/AddMembersModal.svelte
  • src/lib/components/channel/ChannelInfoModal/UserList.svelte
  • src/lib/components/channel/MessageInput.svelte
  • src/lib/components/channel/MessageInput/InputMenu.svelte
  • src/lib/components/channel/Messages.svelte
  • src/lib/components/channel/Messages/Message.svelte
  • src/lib/components/channel/Thread.svelte
  • src/lib/components/layout/Sidebar/ChannelItem.svelte
  • src/lib/components/layout/Sidebar/ChannelModal.svelte
  • src/lib/components/workspace/common/AddAccessModal.svelte
  • src/lib/components/workspace/common/MemberSelector.svelte

目的与范围

本文档描述 Open WebUI 中的频道系统,该系统提供群组消息和直接消息功能。频道支持用户间的实时通信,并具备线程、反应、文件附件和 AI 模型交互能力。

关于实时 Socket.IO 事件处理的信息,请参见实时通信架构 (2.5)。关于消息渲染和显示的详细信息,请参见消息渲染 (5)

---

频道类型与数据模型

频道系统支持三种不同的频道类型,每种类型具有不同的访问控制模型和用例:

频道类型概览
类型代码值访问控制用例
标准频道None""access_grants(基于组/用户的权限)组织范围的讨论,具有细粒度权限
群组频道"group"成员列表 + is_private 标志团队协作,支持成员加入
直接消息"dm"仅成员列表私密的一对一或小群组对话
核心数据模型
erDiagram
    "Channel (Base)" ||--o{ "ChannelMember (Base)" : "拥有成员"
    "Channel (Base)" ||--o{ "Message (Base)" : "包含"
    "Channel (Base)" ||--o{ "AccessGrant (Base)" : "拥有授权"
    "Channel (Base)" ||--o{ "ChannelWebhook (Base)" : "拥有 Webhook"
    "Channel (Base)" ||--o{ "ChannelFile (Base)" : "拥有文件"
    "Message (Base)" ||--o{ "MessageReaction (Base)" : "拥有反应"
    "Message (Base)" ||--o{ "Message (Base)" : "父/回复(线程)"

    "Channel (Base)" {
        text id PK
        text user_id
        text type
        text name
        text description
        boolean is_private
        json data
        json meta
        bigint created_at
        bigint updated_at
    }

    "ChannelMember (Base)" {
        text id PK
        text channel_id FK
        text user_id FK
        text role
        text status
        boolean is_active
        boolean is_channel_muted
        boolean is_channel_pinned
        bigint joined_at
        bigint last_read_at
    }

    "Message (Base)" {
        text id PK
        text user_id
        text channel_id FK
        text reply_to_id FK
        text parent_id FK
        boolean is_pinned
        text content
        json data
        json meta
        bigint created_at
    }

    "AccessGrant (Base)" {
        text principal_type
        text principal_id
        text permission
    }

来源:

  • backend/open_webui/models/channels.py:36-62
  • backend/open_webui/models/channels.py:93-121
  • backend/open_webui/models/messages.py:24-30
  • backend/open_webui/models/messages.py:43-63
频道模型实现

ChannelModel Pydantic 类表示一个频道实例,包括用于权限检查的访问授权。

class ChannelModel(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: str
    user_id: str
    type: Optional[str] = None
    name: str
    description: Optional[str] = None
    is_private: Optional[bool] = None
    data: Optional[dict] = None
    meta: Optional[dict] = None
    access_grants: list[AccessGrantModel] = Field(default_factory=list)
    created_at: int
    updated_at: int
    # ... 归档和删除字段

来源:

  • backend/open_webui/models/channels.py:64-91

---

访问控制架构

频道系统实现了一种复杂的访问控制机制,该机制因频道类型而异,依赖于显式成员关系和基于权限的访问授权。

按频道类型的访问控制流程
graph TD
    UserRequest["用户请求"] --> CheckChannelType{"检查 channel.type?"}

    CheckChannelType -->|"type='dm' 或 'group'"| CheckMembership["检查 ChannelMember 表"]
    CheckChannelType -->|"type=None/empty"| CheckAccessGrants["检查 AccessGrants"]

    CheckMembership --> IsMember{"用户是否在<br/>ChannelMember 中?"}
    IsMember -->|"是"| AllowAccess["✓ 允许访问"]
    IsMember -->|"否"| DenyAccess["✗ 拒绝访问"]

    CheckAccessGrants --> HasPermission{"AccessGrants.has_access()?"}
    HasPermission -->|"是"| AllowAccess
    HasPermission -->|"否"| IsAdmin{"User.role == 'admin'?"}
    IsAdmin -->|"是"| AllowAccess
    IsAdmin -->|"否"| DenyAccess

来源:

  • backend/open_webui/routers/channels.py:75-94
  • backend/open_webui/models/channels.py:373-381
访问授权结构

对于标准频道(type=None/""),access_grants 数组控制权限:

# 示例 access_grants 结构
access_grants = [
    {
        "principal_type": "user",    # 或 "group"
        "principal_id": "user-uuid", # 或 "*" 表示所有用户
        "permission": "read"         # 或 "write"
    }
]

公开频道检测:如果频道具有 principal_id="*" 的访问授权,则视为公开频道。前端使用 hasPublicReadGrant 来判断频道是否公开。src/lib/components/layout/Sidebar/ChannelItem.svelte:29-46

来源:

  • backend/open_webui/routers/channels.py:108-128
  • src/lib/components/layout/Sidebar/ChannelItem.svelte:29-46
权限检查函数
graph LR
    channel_has_access["channel_has_access()<br/>backend/open_webui/routers/channels.py"] --> AccessGrants_has_access["AccessGrants.has_access()<br/>backend/open_webui/models/access_grants.py"]
    get_channel_users_with_access["get_channel_users_with_access()<br/>backend/open_webui/routers/channels.py"] --> AccessGrants_get_users["AccessGrants.get_users_with_access()<br/>backend/open_webui/models/access_grants.py"]
    get_channel_permitted_group_and_user_ids["get_channel_permitted_group_and_user_ids()<br/>backend/open_webui/routers/channels.py"] --> ParseAccessGrants["解析 channel.access_grants 数组"]

关键函数:

  • channel_has_access(user_id, channel, permission, strict):检查用户是否对频道具有特定权限。backend/open_webui/routers/channels.py:75-94
  • get_channel_users_with_access(channel, permission):通过 AccessGrants 检索对频道具有特定权限的用户列表。backend/open_webui/routers/channels.py:97-105
  • get_channel_permitted_group_and_user_ids(channel, permission):返回对频道具有特定权限的用户和组 ID 字典。backend/open_webui/routers/channels.py:108-129

来源:

  • backend/open_webui/routers/channels.py:75-129

---

消息架构

消息支持 Markdown 内容、层级线程、反应和置顶。

消息结构与线程模型
graph TD
    RootMessage["根消息<br/>(parent_id=null)"] --> Thread1["线程回复 1<br/>(parent_id=root_id,<br/>reply_to_id=root_id)"]
    RootMessage --> Thread2["线程回复 2<br/>(parent_id=root_id,<br/>reply_to_id=root_id)"]
    Thread1 --> Thread1Reply["线程回复 1.1<br/>(parent_id=root_id,<br/>reply_to_id=thread1_id)"]

    AnotherRoot["另一条根消息"] --> DirectReply["直接回复<br/>(parent_id=null,<br/>reply_to_id=another_root_id)"]

消息字段:

  • parent_id:线程根消息 ID(非线程消息为 null)。backend/open_webui/models/messages.py:51
  • reply_to_id:直接回复目标消息 ID(创建引用链接)。backend/open_webui/models/messages.py:50
  • is_pinned:布尔标志,表示消息是否置顶。backend/open_webui/models/messages.py:54
  • content:Markdown 文本内容。backend/open_webui/models/messages.py:58
  • data:包含文件附件和结构化数据。backend/open_webui/models/messages.py:59
  • meta:元数据,如 AI 消息的 model_idwebhook 信息。backend/open_webui/models/messages.py:60

来源:

  • backend/open_webui/models/messages.py:43-63
消息响应模型

后端返回带有额外计算字段的丰富消息对象:

模型用途额外字段
MessageModel基础消息仅核心数据库字段
MessageUserSlimResponse优化响应data: bool(如果存在非空数据则为 true)
MessageResponse完整响应reply_count, latest_reply_at, reactions[]

来源:

  • backend/open_webui/models/messages.py:113-138
消息反应系统
graph LR
    MessageReaction["MessageReaction 表<br/>backend/open_webui/models/messages.py"] --> MessageReactionId["id: 唯一实例"]
    MessageReaction --> UserId["user_id: 谁做出的反应"]
    MessageReaction --> MessageId["message_id: 目标消息"]
    MessageReaction --> Name["name: 表情符号短代码"]

    GetReactions["get_reactions_by_message_id()<br/>backend/open_webui/models/messages.py"] --> GroupByName["按名称分组"]
    GroupByName --> ReactionsArray["reactions: [{name, users[], count}]"]

反应 API 端点:

  • POST /channels/{id}/messages/{message_id}/reactions/add:向消息添加反应。backend/open_webui/routers/channels.py:1277-1326
  • POST /channels/{id}/messages/{message_id}/reactions/remove:从消息移除反应。backend/open_webui/routers/channels.py:1329-1377

来源:

  • backend/open_webui/models/messages.py:24-30
  • backend/open_webui/models/messages.py:481-518
  • backend/open_webui/routers/channels.py:1277-1377

---

频道成员管理

对于群组和 DM 频道,ChannelMember 表跟踪用户参与情况和未读计数。

成员操作

ChannelTable 类提供了管理成员关系的方法:

# 添加成员(创建 ChannelMember 记录)
add_members_to_channel(channel_id, invited_by, user_ids, group_ids) # [backend/open_webui/models/channels.py:457-480]()

# 移除成员(删除 ChannelMember 记录)
remove_members_from_channel(channel_id, user_ids) # [backend/open_webui/models/channels.py:483-500]()

# 软隐藏/取消隐藏(用于 DM 频道)
update_member_active_status(channel_id, user_id, is_active) # [backend/open_webui/models/channels.py:503-524]()

来源:

  • backend/open_webui/models/channels.py:457-524
未读消息跟踪

每个 ChannelMember 记录维护一个 last_read_at 时间戳。

# 计算未读计数
unread_count = Messages.get_unread_message_count(channel_id, user_id, last_read_at) # [backend/open_webui/models/messages.py:520-539]()

# 更新最后读取时间戳(通过 Socket.IO 事件)
socket.emit('events:channel', { # [src/lib/components/channel/Channel.svelte:58-64]()
    channel_id: id,
    data: { type: 'last_read_at' }
})

来源:

  • backend/open_webui/models/messages.py:520-539
  • src/lib/components/channel/Channel.svelte:57-77

---

实时通信事件

频道使用 Socket.IO 进行实时更新,事件类型为 events:channel

事件类型与负载
事件类型用途负载数据
message新消息发布{type: 'message', data: MessageModel}
message:update消息编辑{type: 'message:update', data: MessageModel}
typing用户输入指示器{type: 'typing', data: {typing: bool}}
last_read_at已读回执更新{type: 'last_read_at'}

来源:

  • backend/open_webui/routers/channels.py:1146-1200
  • src/lib/components/channel/Channel.svelte:115-188
  • src/lib/components/channel/Thread.svelte:62-129

---

频道中的 AI 模型集成

频道支持通过提及和回复与 AI 模型直接交互。

模型响应机制
graph TD
    UserMessage["用户发送包含 @model 的消息"] --> ExtractMentions["extract_mentions()<br/>backend/open_webui/utils/channels.py"]
    ExtractMentions --> CheckReply{"回复模型消息?"}

    CheckReply -->|是| AddParentModel["添加父消息 model_id"]
    CheckReply -->|否| CheckMentions{"提及了模型?"}

    CheckMentions -->|是| CollectModels["收集模型提及"]
    CheckMentions -->|否| Done["无 AI 响应"]

    ProcessModels["model_response_handler()<br/>backend/open_webui/routers/channels.py"] --> BuildHistory["构建线程历史"]
    BuildHistory --> CallAPI["generate_chat_completion()<br/>backend/open_webui/utils/chat.py"]
    CallAPI --> PostResponse["作为新消息发布,附带 meta.model_id"]

来源:

  • backend/open_webui/routers/channels.py:976-1139
  • backend/open_webui/utils/channels.py:66-66

---

前端组件架构

频道 UI 使用 Svelte 组件构建,采用层级结构。

组件层级
graph TD
    ChannelSvelte["Channel.svelte<br/>src/lib/components/channel/Channel.svelte"] --> NavbarSvelte["Navbar.svelte<br/>src/lib/components/channel/Navbar.svelte"]
    ChannelSvelte --> MessagesSvelte["Messages.svelte<br/>src/lib/components/channel/Messages.svelte"]
    ChannelSvelte --> MessageInputSvelte["MessageInput.svelte<br/>src/lib/components/channel/MessageInput.svelte"]
    ChannelSvelte --> ThreadSvelte["Thread.svelte<br/>src/lib/components/channel/Thread.svelte"]

    MessagesSvelte --> MessageSvelte["Message.svelte<br/>src/lib/components/channel/Messages/Message.svelte"]

    ThreadSvelte --> ThreadMessages["Messages.svelte"]
    ThreadSvelte --> ThreadInput["MessageInput.svelte"]

来源:

  • src/lib/components/channel/Channel.svelte:19-24
  • src/lib/components/channel/Messages.svelte:16
  • src/lib/components/channel/Thread.svelte:9-10
变量替换与文件

MessageInput.svelte 组件处理富文本输入、变量替换(例如 {{USER_NAME}}{{CLIPBOARD}})和文件附件。src/lib/components/channel/MessageInput.svelte:86-223 文件通过 uploadFile 上传,并通过 inputFilesHandler 处理。src/lib/components/channel/MessageInput.svelte:355-505

来源:

  • src/lib/components/channel/MessageInput.svelte:86-223
  • src/lib/components/channel/MessageInput.svelte:355-505

---

数据库模式总结

主要表
用途关键列
channel频道定义id, user_id, type, name, is_private
channel_member频道成员关系channel_id, user_id, is_active, last_read_at
message频道消息id, channel_id, user_id, parent_id, reply_to_id, content
message_reaction消息反应message_id, user_id, name(表情符号)

来源:

  • backend/open_webui/models/channels.py:36-62
  • backend/open_webui/models/channels.py:93-121
  • backend/open_webui/models/messages.py:24-30
  • backend/open_webui/models/messages.py:43-63