Skip to content

Onyx(原 Danswer)技术实现原理深度分析 #182

Description

@Pines-Cheng

分析时间:2026年7月
仓库:onyx-dot-app/onyx(⭐ ~31K+,190+ 贡献者,MIT License CE)
参考来源:DeepWiki官方文档、源码分析
技术栈:Python (FastAPI) + TypeScript (Next.js) + PostgreSQL + Vespa + Redis + MinIO + Celery


一、整体架构概览

Onyx 是一个开源企业级 AI 知识管理与对话平台,核心定位为 LLM 的应用层,提供从数据摄入到 AI 对话的完整闭环。

核心服务组成

服务 技术 职责
Web Frontend Next.js(standalone build) Chat UI、Admin Dashboard、Connector 管理、Agent 编辑器
Backend API FastAPI REST API、WebSocket/SSE 流式、LLM 编排、鉴权
Background Workers Celery(6 类 Worker Pool) 文档抓取、解析、嵌入、索引同步、权限同步、定时调度
Task Scheduler Celery Beat + DynamicTenantScheduler 多租户定时任务调度
Document Index Vespa 8 / OpenSearch 3.4 混合检索(Dense Vector + BM25)、ACL 过滤
Metadata Store PostgreSQL 15 连接器配置、凭证、文档元数据、用户/租户管理
Coordination Redis 分布式锁(OnyxRedisLocks)、Fence 模式、任务状态管理
Object Storage MinIO(S3 兼容) 原始文件持久化

架构特点

┌─────────────────────────────────────────────────────────────┐
│                      Next.js Web UI                         │
│         (Chat / Admin / Agent Editor / Projects)            │
└──────────────────────┬──────────────────────────────────────┘
                       │ REST / SSE / WebSocket
┌──────────────────────▼──────────────────────────────────────┐
│                   FastAPI Backend                            │
│  ┌─────────┐  ┌──────────┐  ┌──────────┐  ┌─────────────┐  │
│  │  Auth    │  │ Chat/LLM │  │ Search   │  │ Connector   │  │
│  │(OIDC/   │  │ Loop     │  │ Pipeline │  │ CRUD API    │  │
│  │ SAML/   │  │          │  │          │  │             │  │
│  │ OAuth)  │  │          │  │          │  │             │  │
│  └─────────┘  └──────────┘  └──────────┘  └─────────────┘  │
└──────────┬───────────┬───────────┬───────────┬──────────────┘
           │           │           │           │
     ┌─────▼────┐ ┌────▼────┐ ┌───▼───┐ ┌────▼─────┐
     │PostgreSQL│ │  Vespa  │ │ Redis │ │  MinIO   │
     │ (元数据) │ │(索引+   │ │(协调) │ │(文件存储)│
     │          │ │ 检索)   │ │       │ │          │
     └──────────┘ └─────────┘ └───┬───┘ └──────────┘
                                  │
                    ┌─────────────▼──────────────┐
                    │      Celery Workers         │
                    │  (6 类专用 Worker Pool)      │
                    │  DocFetching / DocProcessing │
                    │  Primary / Light / Heavy     │
                    │  UserFileProcessing          │
                    └─────────────────────────────┘

二、Connector 架构(数据源连接器)

2.1 三层抽象体系

Onyx 的 Connector 框架基于三个核心实体四种摄入模式构建:

核心实体

实体 说明 源码
Connector 数据源类型定义 + 配置参数(如哪些仓库要索引) backend/onyx/db/models.py
Credential 认证信息(API Key / OAuth Token / SAML) web/src/lib/connectors/credentials.ts
CCPair (ConnectorCredentialPair) Connector + Credential 的绑定,构成一个独立的索引单元 backend/onyx/db/models.py:94

四种摄入模式

InputType 对应接口 说明 适用场景
load_state LoadConnector 全量加载 + 状态管理,connector 自行追踪增量状态 Web 爬虫、Airtable、File Upload
poll PollConnector / CheckpointedConnector 定时轮询,框架传入 start/end 时间窗口进行增量拉取 Slack、GitHub、Confluence、Google Drive 等大部分 SaaS
event EventConnector 事件驱动,外部系统推送变更通知 Webhook 触发场景
slim_retrieval SlimConnector / SlimConnectorWithPermSync 轻量检索,仅获取文档 ID 列表(用于权限同步/剪枝) 权限同步、增量剪枝

2.2 工厂模式与注册机制

# backend/onyx/connectors/factory.py — 核心工厂函数

identify_connector_class(source, input_type)
  → _load_connector_class()       # 懒加载模块,缓存到 _connector_cache_validate_connector_supports_input_type()  # 校验接口实现

instantiate_connector(...)         # 主入口identify_connector_class()
  → connector.load_credentials()   # 初始化 API 客户端(如 MSAL for Teams)connector.validate_connector_settings()  # 校验 API 可达性绑定回调: raw_file_callback文件持久化)、indexing_heartbeat心跳

ValidSources 枚举web/src/lib/types.ts)定义了所有支持的数据源,作为单一真相来源。前端和后端共享同一枚举,涵盖 60+ 数据源:

类别 代表 Connector
Wiki/文档 Confluence、Notion、BookStack、Outline、Coda、Slab、Guru、Google Sites
云存储 Google Drive、Dropbox、S3、R2、Google Cloud Storage、Egnyte、OCI Storage
代码 GitHub、GitLab、Bitbucket
消息 Slack、Teams、Gmail、Discord、Zulip
工单/项目 Jira、Zendesk、Linear、Asana、ClickUp、Freshdesk、TestRail
数据 Airtable、Salesforce、HubSpot
通用 Web Crawler、File Upload、Ingestion API

2.3 新建 Connector 的开发模式

TeamsConnector 为例的标准模板:

class TeamsConnector(PollConnector, SlimConnector):
    """每个 Connector 实现 1-3 个接口"""
    
    def __init__(self, teams: list[str] = [], ...):
        # 配置参数由前端表单传入
        self.teams = teams
    
    def load_credentials(self, credentials: dict) -> None:
        # 初始化 API 客户端(如 MSAL Token)
        self.client = MSALClient(credentials["client_id"], ...)
    
    def validate_connector_settings(self) -> None:
        # 校验 API 可达性
        self.client.test_connection()
    
    def poll_source(self, start: SecondsSinceUnixEpoch, end: ...) -> GenerateDocumentsOutput:
        # 增量拉取:框架传入时间窗口
        for message in self.client.get_messages(after=start, before=end):
            yield Document(
                id=message.id,
                sections=[Section(text=message.body, link=message.url)],
                source=DocumentSource.TEAMS,
                metadata={"channel": message.channel},
            )
    
    def retrieve_all_slim_documents(self) -> GenerateSlimDocumentOutput:
        # 权限同步时仅返回 ID 列表
        for doc_id in self.client.list_all_doc_ids():
            yield SlimDocument(id=doc_id, perm_sync_data={...})

前端配置系统ConnectionConfigurationweb/src/lib/connectors/connectors.tsx)支持动态表单生成,字段类型包括 textselectcheckboxtab,如 GitHub 用 tab 切换"特定仓库"与"全部仓库"。

2.4 权限同步机制

三种访问控制模式:

模式 说明
Public 组织内所有人可见
Private 限定用户/用户组
Sync 从源系统同步权限(SlimConnectorWithPermSync),每个文档的 ACL 写入 Vespa,查询时强制过滤

Indexed vs Federated

  • Indexed:文档被抓取、嵌入、存入 Vespa,支持全功能语义搜索
  • Federated:实时从源 API 查询(如 Slack),延迟更高,搜索质量较低

三、触发机制(定时 / 事件 / 手动)

3.1 Celery Beat 定时调度

Onyx 基于 Celery Beat + 自定义 DynamicTenantScheduler 实现多租户定时任务调度。

beat_task_templatesbackend/onyx/background/celery/tasks/beat_schedule.py)定义了所有周期性任务:

任务 默认周期 Worker Pool 说明
check_for_indexing 15 秒 primary 检查是否有 CCPair 需要索引
check_for_vespa_sync 5 秒 primary 检查 PG ↔ Vespa 元数据同步
check_for_pruning 1 小时 heavy 删除源系统中已不存在的文档
check_for_connector_deletion 20 秒 primary 处理 CCPair 删除清理
check_for_doc_permissions_sync 30 秒 heavy 权限同步
monitor_* 各异 primary 监控任务健康(僵尸任务清理、Fence 回收)

DynamicTenantSchedulerbackend/onyx/background/celery/apps/beat.py):

  • 继承 Celery PersistentScheduler
  • 周期性重新加载任务调度表
  • 多租户环境下为每个 tenant 动态生成任务实例
  • CLOUD_BEAT_MULTIPLIER_DEFAULT = 8.0 用于云环境缩放任务频率

3.2 事件驱动触发

  • EventConnector 接口:支持外部系统通过 Webhook 推送变更事件
  • Ingestion APIPOST /api/ingestion 允许外部程序直接推送文档到索引流水线
  • MCP Server:Onyx 可作为 MCP Server 暴露搜索能力,也可连接外部 MCP Server 作为 Tool

3.3 手动触发

  • Admin Dashboard:一键触发"Re-index"重新索引特定 CCPair
  • REST APIPOST /api/manage/admin/connector/run-once 手动触发单次索引

3.4 增量状态管理

IndexAttemptSnapshot {
  new_docs_indexed: number     // 本次新增文档数
  total_docs_indexed: number   // 累计文档数
  error_msg: string | null     // 错误信息
  status: "not_started" | "in_progress" | "success" | "failed" | "canceled"
  time_started: string
}
  • PollConnector:框架传入 (start, end) 时间窗口,connector 只拉取该区间变更
  • CheckpointedConnector:更先进的增量方式,connector 自行管理 checkpoint 状态(支持断点续传)
  • LoadConnector:connector 自行管理 load_state,框架不干预

四、Pipeline(文档处理流水线)

4.1 全链路数据流

┌─────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ Celery  │    │ Connector│    │ 文档解析 │    │ Chunking │    │ Embedding│
│ Beat    │───▶│ 拉取文档 │───▶│ + 清洗   │───▶│ 分块     │───▶│ 向量化   │
│ (调度)  │    │ (DocFetch│    │ (DocProc │    │          │    │          │
│         │    │  Worker) │    │  Worker) │    │          │    │          │
└─────────┘    └──────────┘    └──────────┘    └──────────┘    └────┬─────┘
                                                                    │
                                                              ┌─────▼─────┐
                                                              │  Vespa    │
                                                              │  写入 +   │
                                                              │  ACL 同步 │
                                                              └───────────┘

4.2 六阶段处理流水线

阶段 Worker Pool 核心处理
① 调度触发 Beat (primary) check_for_indexing 检查所有 CCPair 是否到达轮询间隔
② 文档抓取 docfetching instantiate_connector()poll_source() / load_from_state() 生成 Document 对象
③ 文档解析 docprocessing 多格式解析(PDF/DOCX/PPTX/HTML/Markdown)、OCR(图片/表格)、格式归一化
④ 分块 docprocessing 基于 Section 边界的 Chunking,生成带 chunk_id 的子文档
⑤ 向量嵌入 docprocessing 调用嵌入模型(OpenAI / Cohere / 本地模型)生成 dense vector
⑥ 索引写入 light (Vespa sync) 写入 Vespa(向量 + BM25 + 元数据 + ACL),PG 更新文档状态

4.3 Celery Worker Pool 分工

Worker Pool 队列 职责 设计目标
celery_worker_primary celery 监控 + 调度检查 + 僵尸任务清理 轻量快速,不阻塞
celery_worker_light vespa_metadata_sync / connector_deletion / doc_permissions_upsert Vespa 元数据同步、权限单条写入、connector 删除 高频短任务
celery_worker_heavy connector_pruning / connector_doc_permissions_sync 文档剪枝、批量权限同步 低频长任务
celery_worker_docfetching connector_doc_fetching 从外部源抓取文档 I/O 密集
celery_worker_docprocessing docprocessing 解析、分块、嵌入 CPU/GPU 密集
celery_worker_user_file_processing user_file_processing 用户上传文件处理 隔离用户负载

4.4 分布式协调:Fence 模式

Onyx 使用自研的 Fence 模式 管理分布式任务生命周期:

# Redis Fence 模式
DOCUMENT_SYNC_FENCE_KEY    # 文档同步 fence
ACTIVE_FENCES             # 全局 fence 集合(OnyxRedisConstants)

# 流程:
# 1. 任务启动前设置 fence key
# 2. 生成 taskset(多个子任务)
# 3. 子任务完成后 decrement fence counter
# 4. counter 归零 → fence 释放
# 5. Beat 监控 → 清理过期 fence

Redis 锁注册表OnyxRedisLocks):

  • CHECK_VESPA_SYNC_BEAT_LOCK — Vespa 同步互斥
  • CELERY_INDEXING_LOCK — 索引任务互斥
  • CELERY_PRUNING_LOCK — 剪枝任务互斥
  • CHECK_CONNECTOR_DELETION_BEAT_LOCK — 删除任务互斥

4.5 Pipeline 的局限性

Onyx 的 Pipeline 不可自定义(L1 级):

  • 解析→分块→嵌入→写入的流程是固定的
  • 无法插入自定义处理步骤(如自定义 NER、自定义摘要生成)
  • Chunking 策略不可配置(固定基于 Section 边界)
  • 嵌入模型可切换,但嵌入逻辑不可修改

五、存储架构

5.1 多层存储体系

存储层 引擎 存储内容 特点
元数据层 PostgreSQL 15 Connector/Credential/CCPair 配置、用户/租户/权限、文档状态、索引记录 Alembic 管理 schema migration
索引检索层 Vespa 8 文档向量 + BM25 倒排 + 元数据 + ACL 原生混合检索,支持 YQL
索引检索层(备选) OpenSearch 3.4 同上 标准化 pipeline 归一化分数
文件存储层 MinIO (S3 兼容) 原始文件(PDF/DOCX/图片等) Postgres fallback 可选
协调层 Redis 分布式锁、Fence 状态、任务队列 Celery broker + 自研协调

5.2 数据模型

ConnectorCredentialPair (CCPair)
├── connector_id → Connector(数据源类型 + 配置)
├── credential_id → Credential(认证信息,加密存储)
├── last_successful_index_time
├── indexing_status: "not_started" | "in_progress" | "success" | "failed"
├── access_type: "public" | "private" | "sync"
└── documents → [Document]
       ├── document_id (全局唯一)
       ├── semantic_identifier (人可读标题)
       ├── source_type (来源系统)
       ├── sections → [Section]
       │     ├── text (原始文本)
       │     └── link (来源链接)
       ├── metadata (自定义 KV)
       └── doc_updated_at (源系统时间戳)

5.3 多租户数据隔离

  • Schema 级隔离:每个 tenant 独立 PostgreSQL schema(MULTI_TENANT 模式)
  • Alembic migration:每个 schema 独立执行迁移脚本
  • TenantAwareTask:Celery Task 基类,自动设置 CURRENT_TENANT_ID_CONTEXTVAR
  • TenantRedisClient:Redis 客户端自动添加 tenant 前缀,实现键空间隔离
  • Vespa:文档级 ACL 字段,查询时通过 YQL 强制过滤

5.4 数据持久化与迁移

方面 实现
Schema 迁移 Alembic(PG schema 级别)
数据导出 pg_dump + Vespa snapshot + MinIO bucket 分别导出
数据卷 Docker Compose 持久化卷 / K8s PVC
索引重建 删除 Vespa 索引 → 重新触发全量索引

六、开放扩展能力

6.1 Agent / Persona 扩展

Onyx 通过 Persona(AI Assistant)系统提供高度可配置的 Agent:

配置维度 说明
System Prompt 自定义系统提示词(角色定义、行为约束)
Knowledge Scoping 限定可搜索的 Document Sets / Hierarchy Nodes / 特定文档
Tool Selection 选择可用工具(Search / Web Search / Code Execution / MCP / Custom)
LLM Model 选择特定 LLM 模型(支持 OpenAI / Anthropic / Azure / 本地模型)
Visibility public / private / user-specific

6.2 Tool 扩展机制

Tool 类型 说明
SearchTool 内置内部文档搜索(Vespa)
WebSearchTool 内置 Web 搜索
PythonTool (Craft) 内置 Code Execution(沙箱环境)
Custom OpenAPI Tool 用户通过 OpenAPI spec 定义自定义工具
MCP Server Tool 连接外部 MCP Server,自动发现并注册工具
ImageGenerationTool 内置图片生成

6.3 Connector 扩展

新增数据源只需:

  1. ValidSources 枚举中添加新值
  2. 实现 PollConnector / LoadConnector 接口(Python 类)
  3. connectorConfigs 中添加前端表单配置
  4. SOURCE_METADATA_MAP 中添加 UI 元数据(图标、分类、文档链接)

6.4 不可扩展的部分

  • 索引 Pipeline:解析→分块→嵌入→Vespa 写入的流程不可插拔自定义步骤
  • Chunking 策略:不可自定义分块大小或分块算法
  • 存储后端:Vespa / OpenSearch 二选一,不可替换为其他向量数据库
  • 检索排序:RRF 融合权重可配但排序逻辑不可自定义

七、检索能力

7.1 混合检索架构

Onyx 支持 Dense Vector + BM25 原生混合检索,由 Vespa 引擎直接支持:

用户查询
    │
    ▼
┌─────────────────┐
│  Query 扩展      │  LLM 生成多个查询变体:
│  (Multi-Query)   │  - semantic_query_rephrase(语义重写)
│                  │  - keyword_query_expansion(关键词扩展)
└────────┬────────┘
         │ N 个加权查询
    ┌────▼────┐
    │ Vespa   │  每个查询执行:
    │ Hybrid  │  - Dense Vector(embedding 余弦相似度)
    │ Search  │  - BM25(倒排索引关键词匹配)
    │         │  - ACL Filter(权限过滤)
    │         │  - DocumentSet Filter(知识域过滤)
    └────┬────┘
         │ 多路结果
    ┌────▼────────────┐
    │ Weighted RRF    │  加权倒数排序融合
    │ (reciprocal     │  deduplicate_queries 去重 + 权重求和
    │  rank fusion)   │
    └────┬────────────┘
         │
    ┌────▼────────────┐
    │ Chunk Merge     │  merge_individual_chunks
    │ (相邻块合并)     │  → InferenceSection 对象
    └────┬────────────┘
         │
    ┌────▼────────────┐
    │ LLM Selection   │  select_chunks_for_relevance
    │ (相关性过滤)     │  LLM 判断最相关的 sections
    └────┬────────────┘
         │
    ┌────▼────────────┐
    │ Context Expand  │  expand_section_with_context
    │ (上下文扩展)     │  拉取周围 chunk 补全上下文
    └────┬────────────┘
         │
    ┌────▼────────────┐
    │ Prompt Build    │  JSON → LLM / Rich Object → UI
    └─────────────────┘

7.2 Vespa 查询细节

  • YQL(Vespa Query Language)支持复杂过滤:ACL、Document Set、时间范围、Source 类型
  • Normalization Pipeline:OpenSearch 备选方案使用归一化 pipeline 统一不同查询类型的分数
  • InferenceChunk:检索结果的核心对象,包含 document_idsource_typematch_highlightscontentchunk_id
  • InferenceSection:一个或多个相邻 InferenceChunk 合并后的结果

7.3 SearchTool 五阶段 Pipeline

SearchToolbackend/onyx/tools/tool_implementations/search/search_tool.py)是 Onyx 检索的核心实现:

阶段 处理 关键函数/常量
Multi-Query LLM 生成多个查询变体(语义重写 + 关键词扩展) semantic_query_rephrase, keyword_query_expansion
Parallel Search 对每个查询并行执行 Vespa 混合检索 Vespa YQL / OpenSearch DSL
RRF Fusion 加权倒数排序融合 + 去重 weighted_reciprocal_rank_fusion, deduplicate_queries
LLM Selection LLM 判断最相关的文档块 select_chunks_for_relevance
Context Expansion 拉取选中块的上下文邻居 expand_section_with_context

八、上下文注入与对话系统

8.1 Chat 处理流程

POST /chat/send-chat-message
         │
         ▼
  handle_send_chat_message()
         │
         ├── check_token_rate_limits()   // 速率限制
         ├── verify LLM cost limits      // 成本控制
         │
         ▼
  stream_chat_message()
         │
         ├── construct_message_history() // 构建对话历史
         │     └── compress_chat_history()  // Token 溢出时压缩
         │
         ▼
  run_llm_loop()                        // 多轮 LLM 循环
         │
         ├── 决定 tool_choice: AUTO / REQUIRED / NONE
         ├── 调用 LLM → 判断是否需要 tool call
         │     ├── SearchTool → 内部文档搜索
         │     ├── WebSearchTool → Web 搜索
         │     ├── PythonTool → 代码执行(沙箱)
         │     ├── Custom/MCP Tool → 自定义工具
         │     └── _try_fallback_tool_extraction() // XML/JSON fallback
         ├── Tool 结果 → 注入上下文 → 再次调用 LLM
         └── 循环直到 LLM 生成最终回答
         │
         ▼
  DynamicCitationProcessor             // 引用追踪
         │
         └── 监听 LLM 流式输出 → 提取引用标记 → 映射到 SearchDoc → 生成 CitationInfo

8.2 两条上下文注入路径

路径 条件 实现
In-Context Loading 附件文件尺寸在 LLM 上下文窗口内 build_file_context() 直接注入 prompt
Tool-Mediated Retrieval 大文件或通用查询 SearchTool 语义搜索 → 合并相邻 chunk → 注入 prompt

8.3 对话历史压缩

  • Token 预算:上下文窗口的 75% 作为触发阈值
  • 压缩策略compress_chat_history() 保留 system_prompt + 最新消息,截断/摘要中间历史
  • additional_context:支持临时附加上下文(不进入持久化历史)

8.4 Deep Research 模式

用户复杂问题
    │
    ▼
Clarification Stage(可选)
    │  LLM 通过 clarification_tool 向用户确认细节
    ▼
Orchestrator Agent(ORCHESTRATOR_PROMPT)
    │  分解问题为多个子任务
    │
    ├── Research Agent 1 ──► SearchTool + WebSearchTool + OpenURLTool
    │                           └── generate_intermediate_report()
    ├── Research Agent 2 ──► ...
    │                           └── generate_intermediate_report()
    └── Research Agent N ──► ...
                                └── generate_intermediate_report()
    │
    ▼
generate_final_report()
    │  合并所有中间报告 → 生成带引用的长文档
    ▼
最终回答(Long-form cited document)

8.5 知识域限定

Persona 可通过以下方式限定知识范围:

方式 说明
Document Sets 绑定特定 Connector 的文档集合
Hierarchy Nodes 指定特定文件夹/空间/频道
Individual Documents 固定特定文档 ID
User Files 用户上传文件(通过 FileReaderTool 处理)
Project Files 项目级别共享文件(project_id_filter

九、鉴权与多租户

9.1 认证方式

方式 说明
basic 用户名/密码
google_oauth Google OAuth 2.0
oidc OpenID Connect(通用 SSO)
saml SAML 2.0(企业 SSO)

9.2 企业级多租户

  • MULTI_TENANT 模式:每个 tenant 独立 PG schema
  • DynamicTenantScheduler:为每个 tenant 动态生成 Beat 任务
  • TenantAwareTask:Celery 任务自动绑定 tenant 上下文
  • 文档级 ACL:每个文档在 Vespa 中存储 access_control_list 字段

十、部署架构

10.1 部署方式

方式 说明
Docker Compose 标准部署,docker-compose.yml 包含所有服务
Kubernetes (Helm) 生产级部署,支持 HPA、PVC、Ingress
Cloud Providers AWS / GCP / Azure 一键部署模板

10.2 服务依赖

# Docker Compose 服务列表
services:
  api_server:        # FastAPI 后端
  web_server:        # Next.js 前端
  background:        # Celery Worker(多 pool)
  celery_beat:       # 定时调度器
  postgres:          # 元数据存储
  vespa:             # 文档索引 + 检索
  redis:             # 任务队列 + 分布式协调
  minio:             # 文件存储(可选 Postgres fallback)
  model_server:      # 嵌入模型服务(可选)

十一、Admin Dashboard(管理后台)

Onyx Admin 是 完全开源 的(MIT License CE),与 Chat UI 共属同一个 Next.js 工程,源码位于 web/src/app/admin/ 目录。

11.1 功能模块总览

模块 路由 核心功能
Connector 管理 /admin/connectors/[connector] 新增/编辑/删除数据源连接器,动态表单配置
索引状态 /admin/indexing/status 所有 CCPair 的索引进度、文档数、错误监控
CCPair 详情 /admin/connector/[ccPairId] 单个连接器的详细管理:手动触发 Re-index、调整频率、查看错误
Agent/Persona 编辑 /admin/agents (AgentEditorPage) 创建/编辑 AI 助手:Prompt、知识域、工具选择、LLM 模型
Document Sets /admin/documents/sets 创建/管理文档集合(绑定 CCPair 的知识域)
LLM 配置 /admin/models 配置 LLM Provider(OpenAI/Anthropic/Azure/本地模型)
Embedding 配置 /admin/embeddings 配置嵌入模型
用户管理 /admin/users 用户列表、角色分配、邀请
Chat 偏好 /admin/chat-preferences (ChatPreferencesPage) 全局对话偏好设置
Tool 管理 /admin/tools Custom OpenAPI Tool + MCP Server 管理
性能/使用统计 /admin/performance 查询量、响应时间、Token 消耗等指标

11.2 Connector 管理 — 动态表单生成系统

Admin 中最核心的设计是 声明式配置驱动的动态表单,新增一个 Connector 无需写任何前端代码。

三层配置体系

┌────────────────────────────┐
│  SOURCE_METADATA_MAP       │  UI 元数据层
│  (图标、分类、文档链接、    │  web/src/lib/sources.ts
│   是否支持 OAuth/Federated) │
└────────────┬───────────────┘
             │
┌────────────▼───────────────┐
│  connectorConfigs          │  表单配置层
│  (ConnectionConfiguration) │  web/src/lib/connectors/connectors.tsx
│  字段类型: text/select/    │
│  checkbox/tab/list         │
└────────────┬───────────────┘
             │
┌────────────▼───────────────┐
│  credentialTemplates       │  凭证模板层
│  (API Key / OAuth Token /  │  web/src/lib/connectors/credentials.ts
│   Service Account JSON)    │
└────────────────────────────┘

ConnectionConfiguration Schemaweb/src/lib/connectors/connectors.tsx:114-143):

interface ConnectionConfiguration {
  description: string;                    // 连接器描述
  subtext?: string;                       // 辅助说明
  values: ConnectionConfigurationValue[]; // 表单字段列表
  advanced_values?: ConnectionConfigurationValue[];  // 高级选项
  overrideDefaultFreq?: number;           // 覆盖默认轮询频率
}

// 字段类型
interface ConnectionConfigurationValue {
  type: "text" | "select" | "checkbox" | "tab" | "list" | "file" | "zip";
  query: string;          // 字段标签
  label: string;          // 表单 name
  optional?: boolean;
  description?: string;
  default?: any;
  options?: SelectOption[];  // select 类型的选项
  tabs?: TabOption[];        // tab 类型的切换页
}

GitHub Connector 配置示例

connectorConfigs["github"] = {
  description: "Configure GitHub connector",
  values: [],  // 基础字段为空
  advanced_values: [
    {
      type: "tab",
      query: "Choose indexing scope",
      label: "indexing_scope",
      tabs: [
        { label: "Specific Repository", fields: [
          { type: "text", query: "Repository Owner", label: "repo_owner" },
          { type: "text", query: "Repository Name", label: "repo_name" },
        ]},
        { label: "Everything", fields: [] },  // 索引所有仓库
      ]
    }
  ]
};

11.3 索引状态监控

Indexing Status Dashboardweb/src/app/admin/indexing/status/):

组件 功能
CCPairIndexingStatusTable 所有 CCPair 的汇总表格
SummaryRow 单行摘要:Connector 名称、状态、文档数
ConnectorRow 可点击跳转到详情页
CCPairStatus 状态标签(Running / Success / Failed / Paused)

每行展示的信息

  • 状态:当前索引状态(颜色编码)
  • Last Success Time:上次成功索引时间
  • Access Type:Public / Private / Sync(继承源系统权限)
  • Document Count:已索引文档总数
  • Error Count:错误数量(可点击查看详情)

CCPair 详情页/admin/connector/[ccPairId]):

操作 说明
Trigger Re-index 手动触发重新索引
Edit Frequency 调整 refresh_freq(轮询频率)和 prune_freq(剪枝频率),Yup 校验
View Errors IndexAttemptErrorsModal 弹窗展示具体错误信息
Delete 删除 CCPair(触发后台 check_for_connector_deletion_task 清理)

11.4 Agent/Persona 编辑器

AgentEditorPageweb/src/refresh-pages/AgentEditorPage.tsx):

配置项 说明
Name & Description Agent 名称和描述
System Prompt 自定义系统提示词
LLM Model 选择特定模型或使用默认
Tools 勾选可用工具:SEARCH_TOOL_ID(内部搜索)、WEB_SEARCH_TOOL_ID(Web 搜索)、PYTHON_TOOL_ID(代码执行/Craft)、Custom OpenAPI、MCP Server
Knowledge Sources Document Sets(文档集)、Hierarchy Nodes(特定目录/频道)、Individual Documents(固定文档)
Visibility Public / Private / 指定用户组

11.5 RBAC 角色体系

UserRole 枚举(backend/onyx/auth/schemas.py:11):

角色 权限范围
ADMIN 全权管理:Connector/Agent/用户/LLM 配置/系统设置
GLOBAL_CURATOR 跨组管理:管理所有 Document Sets 和 Connector
CURATOR 组内管理:管理所属 User Group 的 Document Sets
BASIC 普通用户:使用 Chat/Search,管理个人 Agent
LIMITED 受限用户:仅基础对话
SLACK_USER Slack 集成用户
EXT_PERM_USER 外部权限同步用户(源系统 ACL)

权限检查机制

  • backend/onyx/server/auth_check.py 定义了公开端点白名单(PUBLIC_ENDPOINT_SPECS
  • Admin API 路由通过 current_admin_user 依赖注入强制校验 ADMIN 角色
  • Curator API 通过 validate_ccpair_for_user() 校验用户对特定 CCPair 的操作权限
  • IsPublicGroupSelectorweb/src/components/IsPublicGroupSelector.tsx)组件处理 Connector 的 Public/Private/User Group 分配

11.6 CE vs EE 功能对比

功能 CE(MIT 开源) EE(商业许可)
Connector CRUD
索引状态监控
Agent/Persona 编辑
Document Sets 管理
LLM/Embedding 配置
基础用户管理
Custom Tool/MCP 管理
SAML/SSO
User Groups 精细权限
审计日志
高级分析
多租户管理
白标/定制品牌

EE 代码位于 backend/ee/web/src/ee/ 路径下,虽代码可见但受商业许可约束。

11.7 Admin API 架构

Admin 后台由 FastAPI 路由模块提供 API 支持:

Router 路径前缀 职责
connector_router /api/manage/connector Connector CRUD
cc_pair_router /api/manage/admin/cc-pair CCPair 管理
persona_router /api/admin/persona Agent/Persona CRUD
document_set_router /api/manage/admin/document-set Document Set 管理
llm_router /api/admin/llm LLM Provider 配置
user_router /api/manage/users 用户管理
tool_router /api/admin/tool 工具管理

关键实现细节

  • 所有 Admin 路由挂载在 APP_API_PREFIX 下(backend/onyx/main.py:75-135
  • 认证通过 fastapi_users 库实现,支持 Session + Bearer Token(移动端)
  • 前端使用 SWR 进行数据获取和缓存,保持 Dashboard 状态实时更新
  • Admin 组件库使用内部 Opal Libraryweb/lib/opal

十二、总结:优势与局限

优势

维度 评价
Connector 广度 60+ 内置 Connector,开源项目第一
企业就绪 多租户、RBAC/SSO/SAML、文档级 ACL、审计日志
混合检索 Vespa 原生 Dense Vector + BM25,无需外部向量库
完整平台 Chat UI + Agent + Search + Admin + Projects + Deep Research
Connector 开发体验 标准化接口(4 种 InputType)+ 工厂模式 + 前端配置自动生成
触发机制 Celery Beat 定时 + Event Webhook + API 手动 + 多租户动态调度
运维成熟 Docker Compose / K8s Helm / Alembic migration / 健康检查

局限

维度 评价
Pipeline 不可编程 解析→分块→嵌入→写入流程固定,不可插入自定义步骤(L1 级)
存储不可插拔 只支持 Vespa / OpenSearch,不可替换为 Qdrant / Milvus / PGVector 等
无长期记忆演化 无 Agent 记忆层(不跨 session 学习/进化)
多服务依赖 必须部署 PG + Vespa + Redis + MinIO(最少 4 个外部服务)
非中间件定位 是完整应用平台而非可嵌入的 SDK/库

对我们的借鉴价值

借鉴方向 具体参考
Connector 三层抽象 LoadConnector / PollConnector / EventConnector + 工厂模式 + ValidSources 枚举
增量同步机制 CheckpointedConnector 断点续传 + SlimConnector 轻量权限同步
触发调度 DynamicTenantScheduler 多租户定时 + Fence 模式分布式协调
混合检索 Pipeline Multi-Query → RRF Fusion → LLM Selection → Context Expansion
权限同步 SlimConnectorWithPermSync 从源系统同步 ACL → 文档级过滤
前端配置自动化 ConnectionConfiguration schema → 动态表单生成
Admin 管理后台 声明式三层配置体系(元数据 + 表单 + 凭证)、RBAC 7 级角色、CCPair 索引状态监控

📎 核心源码路径索引

模块 路径
Connector 接口 backend/onyx/connectors/interfaces.py
Connector 工厂 backend/onyx/connectors/factory.py
Beat 调度表 backend/onyx/background/celery/tasks/beat_schedule.py
动态调度器 backend/onyx/background/celery/apps/beat.py
SearchTool backend/onyx/tools/tool_implementations/search/search_tool.py
Chat LLM Loop backend/onyx/chat/llm_loop.py
Deep Research backend/onyx/deep_research/dr_loop.py
引用处理 backend/onyx/chat/citation_processor.py
Redis 协调 backend/onyx/configs/constants.py (OnyxRedisLocks)
数据模型 backend/onyx/db/models.py
前端 Source 定义 web/src/lib/sources.ts
前端 Connector 配置 web/src/lib/connectors/connectors.tsx
Vespa 查询 backend/onyx/context/search/pipeline.py
对话压缩 backend/onyx/chat/compression.py
Admin Connector 页 web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx
CCPair 状态表 web/src/app/admin/indexing/status/CCPairIndexingStatusTable.tsx
CCPair 详情页 web/src/app/admin/connector/[ccPairId]/page.tsx
Agent 编辑器 web/src/refresh-pages/AgentEditorPage.tsx
权限检查 backend/onyx/server/auth_check.py
角色定义 backend/onyx/auth/schemas.py
Credential 模板 web/src/lib/connectors/credentials.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions