
Onyx 企业 AI 平台技术全景与实战一、Onyx 是什么不只做“企业知识库问答”1.1 连接器不是“导入一次”而是持续知识入口1.2 Lite 与 Standard 的区别应先弄清二、系统架构在线问答与离线索引两条链路2.1 技术分层与源码目录三、RAG 核心实现文档怎样切 Chunk怎样完成混合检索3.1 从文档到 Chunk 的真实链路3.2 Multipass小块召回与大块上下文并存3.3 Contextual RAG给孤立片段补充文档语境3.4 召回不是只做向量相似度四、Agent 怎样设计工具、MCP 与记忆如何进入 LLM4.1 先做规则过滤再把当前工具集整体暴露给模型4.2 MCP 在内部仍然被适配成统一 Tool 接口4.3 记忆不是把整段历史永久塞进 Prompt4.4 长上下文管理体现了产品取舍4.5 CraftOpenCode 怎样在隔离工作区中完成端到端交付Docker 与 Kubernetes 使用同一 Sandbox 抽象Sandbox Proxy 同时承担凭据边界和写操作审批Craft 与普通 Code Interpreter 不是同一类能力五、权限、版本边界与并发架构5.1 权限不是一个简单的 is_admin5.2 高并发能力来自可拆分组件不是一个开关六、部署与使用从单机体验到 Kubernetes6.1 官方引导脚本最快启动 Standard6.2 直接使用 Docker Compose6.3 跑通知识接入、检索与权限闭环6.4 Kubernetes Helm6.5 使用 --include-craft 部署 Craft并正视 Docker Socket 边界七、从 Onyx 学习 Agent RAG 系统设计参考资料把大模型接入企业内部并不等于完成了“企业 AI”。真正困难的部分通常在模型之外资料分散在 Slack、Google Drive、Confluence、GitHub 等系统中文档会不断更新且带有访问边界用户既需要有引用的知识问答又希望 Agent能搜索网页、运行代码、生成文件或调用外部业务接口系统还要处理后台同步、索引重建、流式响应和扩缩容。Onyx 的价值正是把这些问题组织成一套可以自行部署的应用层。Onyx 是一套面向团队知识与业务执行的开源 AI 平台将连接器同步、混合检索、可配置 Agent、MCP/自定义工具与 Craft组合在统一应用中。本文依据官方文档和固定源码分析 RAG 数据链、工具循环、记忆与权限并重点拆解 Craft/OpenCode持久工作区、Sandbox Proxy 审批、代码执行边界及 Docker Compose、Helm 部署方法。GitHub仓库https://github.com/cmyk-labs/onyx.git如果这个仓库对你有帮助欢迎在 GitHub 上点一个 Star ⭐ 支持一下。官方GitHub仓库https://github.com/onyx-dot-app/onyx官方文档https://docs.onyx.app/一、Onyx 是什么不只做“企业知识库问答”Onyx曾用名 Danswer把自己定位为开源 AI 平台而不是一个只有聊天框的 RAG Demo。它的核心能力可以分成四层层次解决的问题代表能力数据接入企业资料在哪里、怎样持续同步连接器、文件上传、元数据与增量同步知识检索怎样把资料加工成可搜索的上下文文档解析、句子级分块、Embedding、关键词/向量混合检索、加权 RRF 与 LLM 相关性筛选Agent 执行模型怎样从“回答”走向“做事”内部搜索、Web 搜索、打开网页、Python、图片生成、MCP、自定义 OpenAPI 工具应用与运维怎样让团队稳定使用Projects、Custom Agents、多模型、权限、流式输出、Docker Compose、Helm/Terraform官方 README 展示的产品形态已经覆盖检索、Agent、文件和工具协作。下面这段演示图来自官方 GitHub Release可直观看到它不是传统的“输入问题—输出一段文本”而是在一个会话中组织搜索结果、推理与最终答案。图片来源Onyx 官方 GitHub README 固定提交。1.1 连接器不是“导入一次”而是持续知识入口Onyx 官方将连接器定义为知识系统和 Onyx 之间的同步层它不仅抓取正文还会处理标题、时间、来源链接等元数据并按连接器能力持续发现新增、修改与删除。源码中backend/onyx/connectors按数据源拆分实现后台任务则把抓取、处理和索引解耦。下面列出仓库内的一组典型连接器图标。它们不是“全部支持清单”而是帮助理解 Onyx 所面对的数据源跨度协作消息、网盘、知识库、代码平台、项目管理和邮件都可能成为 Agent 的知识入口。SlackGoogle DriveConfluenceNotionGitHubJiraSharePointGmail图片来源本项目仓库web/public/slackbot-source-icons目录。1.2 Lite 与 Standard 的区别应先弄清Onyx 官方部署文档将运行形态分成 Lite 和 Standard。Lite 重点提供 LLM 对话、工具、文件上传和 Projects不启动完整的向量索引、后台连接器任务及本地模型推理服务Standard 才加入持续连接器同步、关键词与向量索引、后台 Worker、模型服务、Redis 和对象存储等组件。这一区别直接影响选型只想搭建一个支持文件和工具的团队聊天入口可以先体验 Lite需要持续同步企业数据并提供完整内部搜索时应选择 Standard。不要在 Lite 部署后再把“没有完整连接器索引能力”误判为配置故障。二、系统架构在线问答与离线索引两条链路从源码目录和部署编排看Onyx 并不是把所有工作塞进一个 Web 进程。前端使用 Next.js、React 和 TypeScript后端是 Python、FastAPI、SQLAlchemy/AlembicPostgreSQL 保存用户、会话、Agent 配置和关系数据Redis 用于缓存、队列与停止信号等运行状态OpenSearch 承担当前关键词和向量索引Celery Worker 处理连接器抓取、文档加工及其他后台任务模型调用层适配多个 LLM 与 Embedding 提供方。可以把整个系统拆成两条主链路离线/准实时知识链路 数据源 → Connector → 文档解析与标准化 → 分块 → 可选 Contextual RAG → Embedding → OpenSearch 关键词/向量索引 → 持续更新与删除 在线 Agent 链路 用户消息 → 会话/文件/记忆/Agent 配置装配 → 构造可用工具 → LLM 推理 → 工具调用 → 结果回填上下文 → 再推理 → 引用处理与流式输出 → PostgreSQL 持久化这里最重要的设计不是组件名称而是资源隔离数据同步和 Embedding 属于高延迟、易波动的后台负载不应阻塞聊天 API在线工具调用又可能包含搜索、网页抓取和代码执行必须通过循环次数、上下文预算、工具权限和独立执行环境控制风险。2.1 技术分层与源码目录Onyx 官方的系统组件说明展示了 Next.js、FastAPI、后台 Worker、索引/查询模型服务、PostgreSQL、OpenSearch、Redis、MinIO 和 Nginx 等运行组件。这是容器与服务级视图没有完整展开 Craft、Sandbox Proxy也不能替代社区核心与企业扩展的源码边界。层次主要实现关键职责交互层Next.js、React、web/src聊天、搜索、Agent 配置、连接器和平台管理API 与 Agent 层FastAPI、backend/onyx/server、chat、tools会话装配、LLM 循环、工具执行、引用和流式响应索引与后台层connectors、background、indexing、Celery持续抓取、文档加工、Embedding、重建和清理任务搜索与模型层OpenSearch、model_server关键词/向量检索以及索引和查询模型推理数据层PostgreSQL、Redis、MinIO关系状态、运行协同、缓存和对象存储Craft 隔离层coding_agent、sandbox_proxy、Docker/Kubernetes Sandbox持久工作区、代码执行、出网代理、凭据与审批企业扩展层backend/ee外部 ACL 同步等企业能力与社区核心分开维护交付层Docker Compose、Helm、CLI单机体验、服务编排、Kubernetes 部署与运维入口onyx/ ├── backend/ │ ├── onyx/ │ │ ├── connectors/ # 数据源抓取与标准化 │ │ ├── background/ # Celery 任务与后台调度 │ │ ├── indexing/ # Chunk、上下文增强与 Embedding │ │ ├── document_index/ │ │ │ ├── opensearch/ # 当前主要关键词/向量索引实现 │ │ │ └── vespa/ # 历史与迁移兼容实现 │ │ ├── chat/ # 上下文、LLM 循环与流式事件 │ │ ├── tools/ # 内置、OpenAPI 与 MCP 工具 │ │ ├── coding_agent/ # Craft/OpenCode 运行链 │ │ ├── sandbox_proxy/ # 出网、凭据与审批代理 │ │ ├── auth/ # 社区核心认证 │ │ └── server/ # FastAPI 服务入口 │ ├── ee/onyx/ │ │ └── external_permissions/ # 企业版外部 ACL 同步 │ └── model_server/ # 索引与查询模型服务 ├── web/src/ # Next.js/React 前端 ├── deployment/ │ ├── docker_compose/ # Lite、Standard 与 Craft 编排 │ └── helm/ # Kubernetes Chart ├── cli/ # 部署管理 CLI ├── pyproject.toml # Python 工程与依赖 └── LICENSE # 核心许可证及企业目录边界连接器、索引与后台 Worker 独立于在线问答使批量同步和 Embedding 不必占住聊天请求Agent 工具循环与 Craft 又分开运行让普通搜索问答不必默认承担代码执行风险。仓库中仍保留 Vespa 相关实现及迁移保护代码但当前 Compose 和 Helm 已以 OpenSearch 为主要索引不能只看到vespa目录就把它写成当前默认后端。三、RAG 核心实现文档怎样切 Chunk怎样完成混合检索Onyx 的知识处理不是简单的“固定字符数截断”。当前实现同时考虑文档结构、句子边界、元数据、图片/表格、上下文增强、多粒度召回和失败恢复。3.1 从文档到 Chunk 的真实链路backend/onyx/indexing/indexing_pipeline.py负责组织批量索引。简化后一批文档会经历文档过滤与数据库状态准备 → 图片等 Section 处理 → DocumentChunker 按 Section 类型分派 → SentenceChunker 按 Token 与句子边界切分 → 生成正文、标题前缀、语义/关键词元数据后缀 → 可选文档摘要与 Chunk Context → 批量 Embedding失败时按文档降级重试 → 批量写入 OpenSearch → 校验完整性并更新索引状态backend/onyx/indexing/chunker.py使用 Chonkie 的SentenceChunker分块预算由 Embedding 上下文大小控制当前显式设置CHUNK_OVERLAP 0。这说明项目选择的是可干净组合、便于多粒度处理的无重叠 Chunk而不是默认套用常见的滑动窗口重叠。标题和元数据会分别加工语义检索侧使用带键名的自然语言元数据关键词侧更关注元数据值避免同一份表示同时迁就两种检索。DocumentChunker会继续按文档 Section 类型选择文本、图片或表格分块器。表格拥有专门的分析和描述逻辑图片 Section 也有独立处理入口因此“所有内容都先转成一长串纯文本再切”并不准确。3.2 Multipass小块召回与大块上下文并存开启 Multipass 后系统可以为一个普通 Chunk 再生成 mini-chunk 表示在模型条件允许时还会按LARGE_CHUNK_RATIO将相邻 Chunk 合并成 large chunk并记录它所引用的原始 Chunk ID。这种多粒度索引解决的是 RAG 中常见的冲突小 Chunk 更容易精确命中一个术语或事实但给 LLM 的上下文可能不完整大 Chunk 保留更多语义连续性却可能稀释用于召回的关键特征多粒度方案让系统用更细表示发现相关位置再返回足够连贯的正文而不是被迫全局选择一个固定粒度。在backend/onyx/indexing/embedder.py中一个 Chunk 可以同时拥有正文 Embedding、mini-chunk Embedding 和独立的标题 Embedding。标题还做了缓存避免同一文档的标题反复计算。这些细节说明 Multipass 不是简单地“检索两遍”而是索引阶段就保存了多种粒度的向量表示。3.3 Contextual RAG给孤立片段补充文档语境当启用 Contextual RAG 时Chunker 会预留上下文 Token 预算索引流水线随后可生成文档摘要和每个 Chunk 的局部语境并把它们加入 Embedding 内容。若整篇文档本来就能放进单个 Chunk或者预留上下文后剩余的真实正文过少代码会跳过这一步避免“摘要比原文还长”。这项能力提高的是片段的自描述性。例如某个 Chunk 只有“该方案第二阶段将在华东区域上线”孤立检索时并不知道“该方案”是什么补入文档摘要和局部上下文后Embedding 更容易把它与真实主题对应起来。代价也很明确索引时会增加 LLM 调用、时间和费用因此它是可配置增强项而不是所有部署都应无条件开启的默认答案。3.4 召回不是只做向量相似度当前document_index/opensearch查询实现提供关键词、语义和 Hybrid 路径。Hybrid 查询并行组织向量子查询与关键词子查询再使用搜索 Pipeline 做分数归一化和加权融合源码支持 min-max 与 z-score 等归一化配置。访问控制列表、来源类型、标签、文档集、Project、Persona、时间范围和指定文档等条件先被构造成hybrid_search_filters再作为 Hybrid 查询的公共filter作用于每个子查询因而会在候选结果聚合与分数融合之前约束关键词和向量召回而不是先返回全部结果再在应用层裁剪。固定提交中的主检索链不再调用独立 Reranker。OpenSearch 先在公共过滤约束下完成每条查询的关键词/向量混合召回和归一化融合多条查询的结果随后通过weighted_reciprocal_rank_fusion做加权 RRF 合并再合并相邻 Chunk并由 LLM 选择最值得扩展阅读的 Section。于是完整的在线搜索更接近原始问题 → 可选查询扩展/时间与来源判断 → 构造 ACL、来源、标签、文档集、Project/Persona 与时间等过滤约束 → 在这些约束下执行关键词子查询 向量子查询 → OpenSearch Pipeline 对子查询分数归一化并加权融合 → 多条查询结果通过加权 RRF 合并并合并相邻 Chunk → LLM 选择最相关的 Section并按需扩展上下文 → 文档结果压缩成 LLM 友好的 JSON → 进入回答上下文并建立引用编号映射backend/onyx/chat/README.md还揭示了一个实用细节给 LLM 的搜索结果会简化成带document数字、标题、元数据与正文的 JSON而 UI 需要的完整链接和富信息保留在服务端映射中。模型只需引用短数字能够降低上下文噪声也比让模型复制复杂文档 ID 更稳定。四、Agent 怎样设计工具、MCP 与记忆如何进入 LLM很多 Agent 项目介绍会停留在“支持 MCP、支持工具调用”但真正影响行为的是工具何时被选中、是否全量暴露、调用结果如何进入下一轮、上下文超限怎样处理。Onyx 的实现可以从process_message.py、tool_constructor.py、llm_loop.py和各工具类串起来看。4.1 先做规则过滤再把当前工具集整体暴露给模型Onyx 当前并没有在每轮对话前再调用一个“工具路由 LLM”从所有系统工具中语义挑选少数候选。真实流程是读取当前 Persona/Custom Agent 关联的工具应用本次请求的allowed_tool_ids跳过未被允许的工具检查工具依赖是否可用例如 Web 搜索提供方、图片模型或连接配置为内部搜索注入文档集、Project/Persona、文件溢出等范围配置为自定义 OpenAPI 工具装配请求头和 OAuth为 MCP 工具解析当前用户凭据若用户启用记忆功能额外注入 Memory Tool将最终工具对象转换为 Function Calling Schema一起传给本轮 LLM。也就是说它是“配置与权限先过滤保留下来的工具定义全量进入本轮模型”不是“先由 LLM 路由再暴露工具”。这带来两个工程结果一方面路径简单、行为可解释管理员对 Agent 的工具配置就是主要能力边界另一方面工具定义本身会占用上下文因此代码先计算全部 Tool Schema 的 Token再从会话历史预算中扣除。在 Agent 循环中普通轮次使用AUTO如果前端强制某个工具代码只留下这个工具并使用REQUIRED达到最大循环次数或图片生成已经完成后则设置为NONE并清空工具让模型必须收束为最终回答。工具结果写回上下文后LLM 可以继续调用下一项工具形成LLM Step ├─ 直接回答 ───────────────→ 结束 └─ 返回 Tool Calls → 并行执行允许的工具 → 结果转为 Tool Response → 更新引用、文件与循环状态 → 下一次 LLM Step → 最后一轮禁用工具并生成答案run_tool_calls支持一次处理多个工具调用而 Chat 层通过 Emitter 持续发送推理、工具状态和回答 Packet。前端不必等整轮结束才能看到结果中止信号则放在 Redis 中用户停止生成时可以保存部分状态并尽快结束 Worker。4.2 MCP 在内部仍然被适配成统一 Tool 接口MCP Server 的工具定义会先保存到数据库。构造 Agent 工具集时系统读取所选 Server 的工具、输入 Schema 和当前用户凭据为每项能力创建MCPTool。它对 LLM 暴露的仍是标准函数定义名称、说明、JSON 参数执行时才通过 MCP Client 调用远端 Server。源码还处理了几个容易被忽视的问题不同 MCP Server 出现同名工具时会生成带 Server 信息的消歧名称缺少properties的零参数 Schema 会被标准化兼容部分模型提供方的严格校验请求头会过滤禁止透传的字段API Key、OAuth 和按用户凭据在调用前解析OAuth 失效时返回明确的重新连接提示远端结果同时生成适合 UI 展示的富响应和供 LLM 继续推理的 JSON 文本。因此MCP 在 Onyx 中不是另一套孤立 Agent 引擎而是被收敛到统一Tool抽象与内部搜索、Web 搜索、Python、自定义 OpenAPI 工具共用同一个调用循环。4.3 记忆不是把整段历史永久塞进 Prompt当用户启用记忆后系统将add_memory工具注入 Agent。LLM 认为某项稳定信息值得长期保存时会调用该工具并提交一条简洁记忆。随后memory_update.py用一次独立 LLM 判断这条内容应该新增还是替换已有记忆它只截取最近最多 3 条用户消息每条最多 500 字符并要求返回结构化操作结果。调用失败或结果不可解析时代码采取“保留新记忆并按新增处理”的降级策略。记忆读取与记忆写入也是两件事已保存记忆可作为用户上下文进入系统 Prompt隐身/不持久化场景则会限制内容写入。这样的设计比无限拼接历史更可控但仍需认识到记忆合并由 LLM 判断可能出现误归纳或信息过期生产环境应允许用户查看、修改和关闭记忆。4.4 长上下文管理体现了产品取舍Onyx 区分即时上传文件与 Project 文件即时文件被视为某一时间点的上下文随着会话增长可以逐渐远离最新消息Project 文件被认为对整个项目持续重要会尽量放在更靠近当前问题的位置。若 Project 文件无法完整放进模型上下文就转为向量索引并通过内部搜索召回。工具结果也不会永远原样保留。搜索一次可能返回数千 Token后续历史会保留有信息量的工具名称、查询和参数但旧的超长响应可被替换避免工具结果不断挤压用户消息。系统还会在搜索后把引用提醒放到上下文末尾利用模型对最近指令更敏感的特点提高引用稳定性。4.5 CraftOpenCode 怎样在隔离工作区中完成端到端交付普通 Onyx 对话擅长检索、问答和调用单个工具Craft 则是独立的 AI coworker 工作台可以利用企业已索引知识在隔离环境中创建 Web 应用、文档、演示稿等可下载成果。它的核心不是多加一个bash函数而是把持久工作区、OpenCode Agent、实时事件流、产物预览、快照恢复和受控外部访问组合成一条完整执行链。图片来源Onyx Craft 官方文档生成结果与 Output 面板Agent 执行过程与实时工作区固定提交中的交互主链路如下访问 /craft/v1 → POST /api/build/sessions 预创建或修复 BuildSession → 为用户创建或唤醒 Sandbox并建立 /workspace/sessions/{session_id} → 写入 AGENTS.md、opencode.json、Skills、附件与 outputs 模板 → 预热 opencode serve持久化 opencode_session_id → POST /api/build/sessions/{session_id}/send-message → 先持久化用户消息再在 Redis 创建 InteractiveTurn → Runner 竞争 Turn 所有权并检查 Sandbox/Workspace → 取得按 BuildSession 加锁的 prompt_slot提示执行槽位 → 调用 Sandbox 内的 opencode serve /prompt_async → /event 转换为文本、推理、Tool Call、错误和终止事件 → 后端写入消息前端通过 SSE 展示过程 → outputs 成果进入预览、下载和快照流程这里有两个容易误解的边界。第一BuildSession与 OpenCode Session 不是同一个 ID前者是 Onyx 的业务会话后者是 Sandbox 内 OpenCode 的对话状态后端会保存两者映射避免每轮创建新的 OpenCode Session 而丢失上下文。第二当前隔离粒度是一个用户一个 Sandbox用户的多个 Craft Session 放在同一 Sandbox 的不同/workspace/sessions/{session_id}目录不是每条对话各占一个容器或 Pod。因此同一用户的 Session 依靠目录和应用逻辑隔离跨用户才由不同 Docker Container 或 Kubernetes Pod 隔离。Docker 与 Kubernetes 使用同一 Sandbox 抽象SandboxManager为上层提供统一的 provision、workspace、文件、快照、OpenCode 和终止接口当前生产路径实现了 Docker 与 Kubernetes 两种后端后端运行单元工作区与恢复主要隔离措施Docker每个用户一个动态 Container每个 Sandbox 使用独立 Named Volume 挂载/workspace/sessions专用onyx_craft_sandboxBridge、CPU/内存限制、cap_dropALL、no-new-privileges防火墙初始化后以 UID 1000 运行 AgentKubernetes每个用户一个 Pod主 Sandbox Container 配合 Sidecar每个 Session 独立目录快照通过 FileStore/Sidecar 流式保存和恢复独立 Namespace、ServiceAccount/RBAC、ClusterIP Service、SecurityContext、资源限制和 NetworkPolicyDocker 启动时有一个短暂的特权初始化窗口firewall-init.sh需要 Root 与NET_ADMIN写入 iptables并安装 Sandbox Proxy CA完成后通过setpriv切换到 UID 1000 并清空 capability bounding set。Kubernetes 则将网络初始化放进 Init ContainerAgent 主容器保持普通用户运行。两种路径都要求SANDBOX_PROXY_HOST缺少代理配置时 Sandbox Manager 会拒绝启动而不是静默退化为不受控出网。Sandbox Proxy 同时承担凭据边界和写操作审批Sandbox 内只得到占位凭据、会话级配置和代理地址。HTTP_PROXY、HTTPS_PROXY与受信 CA 将 HTTP/S 请求送到sandbox-proxyfirewall-init.sh再通过 iptables 阻止绕过代理的直接出网。Proxy 根据来源 IP 解析 Sandbox、Tenant 和用户身份然后把请求匹配到 External App 或 MCP ActionSandbox 请求 → 来源身份解析 → URL / Method / GraphQL / MCP Tool 匹配 → 读取动作策略 ALWAYS / ASK / DENY → ASK写入 ActionApproval通过 Redis 通知前端等待决定 → 允许后由 Credential Resolver 在服务端注入 PAT、OAuth 或 MCP 凭据 → 转发上游拒绝、超时或凭据解析失败则阻断内置外部应用通常把只读 Action 默认设为ALWAYS写入、发送或删除 Action 保持默认ASK管理员还可以改成DENY。无法归类的已连接应用请求会进入整域ASK无法解析的 MCP Tool 请求则按DENY失败关闭。对于ASK路径批准记录保存在数据库Proxy 只有在获得批准或命中受控 Session Grant/定时任务预批准后才继续ALWAYS路径则可直接进入凭据注入。原始 Token 不进入 Agent 工作区。Prompt 中的“请先询问”与 OpenCode Permission 仍只是行为约束真正的外部写操作边界在 Onyx 后端与 Proxy。Craft 与普通 Code Interpreter 不是同一类能力对比项普通 Code InterpreterCraft入口普通 Agent 循环中的 Python/代码执行 Tool独立/craft/v1工作台与/api/build会话体系执行模型后端请求CODE_INTERPRETER_BASE_URL执行一段代码或在受限 Session 中运行 BashOpenCode 在持久 Sandbox 内多轮规划、读写文件、运行命令并调用 Skills/MCP/外部应用状态以一次执行、暂存文件和执行 Session 为中心BuildSession、OpenCode Session、Workspace、附件、输出、预览和快照共同持久化网络普通执行 Session 明确禁用网络可访问 Onyx Search 与外部系统但必须经过 Sandbox Proxy、凭据注入和审批典型产物计算结果、图表或单次生成文件可迭代的 Next.js 应用、报告、演示稿及其他目录化成果因此Code Interpreter 解决的是“安全地执行一段代码”Craft 解决的是“让 Agent 在可恢复工程环境中持续完成一项交付”。两者都需要隔离但生命周期、网络模型和权限边界并不相同。五、权限、版本边界与并发架构5.1 权限不是一个简单的is_adminOnyx 后端包含会话认证、JWT、API Key、PAT、OIDC/OAuth 等模块工具层还分别处理用户 OAuth、透传认证和 MCP 凭据。检索请求支持把访问控制列表和资源范围直接带入 OpenSearch Filter这比“检索后再删掉无权限文档”更有利于减少越权内容进入候选集。但这里必须区分社区核心能力与企业版能力。官方文档把外部数据源权限同步、细粒度权限感知检索等部分能力标为 Enterprise Edition源码也将 Google Drive、Slack、Confluence、GitHub 等外部权限同步实现放在backend/ee/onyx/external_permissions。仓库根许可证进一步明确ee目录适用 Onyx Enterprise License其余未受额外限制的核心代码采用 MIT Expat License。因此可以确认“系统有权限同步架构”不能据此承诺 MIT 社区核心在所有连接器上都具备同等的外部 ACL 同步能力。选型时应逐项核对登录方式属于哪一版本、数据源能否同步用户/组权限、公开 Agent 是否允许匿名、MCP 凭据是全局还是按用户、代码执行是否隔离以及升级后权限映射是否需要重建。RAG 系统最严重的问题往往不是答错而是检索到了用户本不该看到的内容。5.2 高并发能力来自可拆分组件不是一个开关仓库提供 Docker Compose、Helm 和 Terraform不代表任意默认配置都天然适合高并发。它真正具备的是可横向拆分的基础API Server 可设置多个副本并通过 HPA/KEDA 扩缩文档抓取、文档处理、轻/重任务、用户文件处理等 Celery Worker 拆成不同队列和 Deployment索引模型与推理模型服务可独立扩副本PostgreSQL、Redis、对象存储和 OpenSearch 可以替换为托管服务Helm Chart 提供 API、多个 Worker 和模型服务的资源限制、HPA/ScaledObject 模板仓库包含索引流水线、OpenSearch 延迟和 Redis 队列等 Grafana Dashboard。官方 Chart 的SIZING.md给出了按用户数和文档量划分的经验配置但这些数字是部署起点不是性能承诺。实际容量取决于连接器增量规模、文档大小、Embedding 吞吐、OpenSearch Shard 与磁盘、LLM 供应商限流、Agent 每轮工具次数以及代码执行负载。压测也应把“在线聊天延迟”和“批量重建索引吞吐”分开避免后台 Re-index 抢占模型服务后误判 API 性能。六、部署与使用从单机体验到 Kubernetes6.1 官方引导脚本最快启动 Standard官方文档提供会持续更新的便捷安装地址。为了与本文源码基线一致下面改用仓库固定提交中的等价脚本并先下载审阅再执行curl-fsSLhttps://raw.githubusercontent.com/onyx-dot-app/onyx/6376385614d6c5d69b7460a11a86b656cdd88a7b/deployment/docker_compose/install.sh-oinstall.shlessinstall.shchmodx install.sh ./install.sh官网便利脚本和发布标签可能继续变化生产环境还应记录安装器哈希、最终镜像标签与摘要不要把滚动脚本直接通过管道交给 Shell。安装完成后可以用 CLI 管理生命周期onyx-cli deploy status onyx-cli deploy logs onyx-cli deploy stop onyx-cli deploy upgrade生产环境不建议长期追踪不可预测的latest而不做验证应通过版本标签固定镜像先备份 PostgreSQL、OpenSearch 与对象存储数据再在测试环境验证迁移和连接器同步。6.2 直接使用 Docker Compose希望审阅配置并自行控制环境变量时可以克隆仓库后启动gitclone https://github.com/cmyk-labs/onyx.gitcdonyx/deployment/docker_composecpenv.template .envdockercompose up-d使用官方原仓库时只需替换克隆地址gitclone https://github.com/onyx-dot-app/onyx.git.env中至少应检查镜像版本、Web 地址、LLM/Embedding 配置、PostgreSQL、Redis、OpenSearch、对象存储和认证相关变量。Compose 文件里的minioadmin等值是本地默认值不应原样暴露到公网。反向代理之后还要配置 TLS、可信域名、Cookie/回调地址并限制数据库、Redis、OpenSearch 和 MinIO 端口只在内部网络访问。Lite 组合使用额外 Compose 文件cdonyx/deployment/docker_composedockercompose-fdocker-compose.yml-fdocker-compose.onyx-lite.yml up-d若随后需要完整企业知识索引不要只给 Lite 容器增加内存应切换到 Standard 所需的 OpenSearch、后台 Worker、模型服务和缓存/对象存储组合并完成索引初始化。6.3 跑通知识接入、检索与权限闭环容器启动后建议先用少量可人工核对的资料验证主链路而不是立即回填整个企业数据源配置可用的 LLM 与 Embedding分别验证生成和向量请求在 Standard 中接入一个小型 Connector或上传几份内容已知的测试文件等待后台索引完成创建一个 Agent先问包含原词/编号的问题再问语义改写和资料中不存在的问题检查答案引用是否指向正确文档和片段记录召回遗漏与错误引用使用普通用户重新测试受限资料确认 ACL 在检索前生效而不是只在界面隐藏入口知识和权限闭环稳定后再为 Agent 启用 MCP、自定义工具或 Craft。成功判据至少包括连接器同步状态正常、文档可被检索、语义改写能命中、无答案问题不伪造引用、普通用户无法召回无权内容。Lite 不包含完整的持续连接器索引链不能照搬这套 Standard 验收流程。6.4 Kubernetes Helm对于需要多副本、滚动升级和独立 Worker 扩缩的环境仓库提供 Helm Charthelm repoaddonyx https://onyx-dot-app.github.io/onyx helm repo update helminstallonyx onyx/onyx-nonyx --create-namespace正式部署前应建立自己的values.yaml重点调整API、Web、各 Celery Worker 与模型服务副本和资源外部 PostgreSQL、Redis、S3 与 OpenSearch 的地址、TLS 和凭据Secret/ExternalSecret而不是把密码直接写进 ConfigMapIngress、证书、回调域名与 NetworkPolicyOpenSearch PVC、快照、Shard 规划和恢复演练HPA/KEDA 指标尤其是 API CPU、任务队列积压和索引吞吐日志、Tracing、指标告警与 LLM 调用成本。一个可靠的上线顺序通常是先用少量内部资料验证解析和权限再做知识命中评测然后验证 Agent 工具和凭据隔离最后才进行连接器全量回填与并发压测。这样能把“内容质量问题”“工具权限问题”和“基础设施容量问题”分开定位。6.5 使用--include-craft部署 Craft并正视 Docker Socket 边界当前安装器不会在普通 Standard 部署中默认打开 Craft需要显式传入--include-craftcurl-fsSLhttps://raw.githubusercontent.com/onyx-dot-app/onyx/6376385614d6c5d69b7460a11a86b656cdd88a7b/deployment/docker_compose/install.sh-oinstall.shlessinstall.shchmodx install.sh ./install.sh --include-craft该选项意味着 Standard 模式不能与--lite同时使用。使用当前发布标签时它会设置ENABLE_CRAFTtrue和SANDBOX_BACKENDdocker加入docker-compose.craft.ymlOverlay并准备onyx_craft_sandbox外部网络与sandbox_proxy_caVolumeCLI 对早于v4.0.6的旧标签会回退到 Kubernetes 沙箱后端。不能只在已有.env中手工写一个ENABLE_CRAFTtrue就认为部署完整因为 API Server 还需要 Docker Socket、Sandbox 网络、Proxy 和 CA Volume 才能真正创建受控 Sandbox。已有部署同样应重新执行安装器并带上--include-craft再检查状态和日志onyx-cli deploy status onyx-cli deploy logs api_server background sandbox-proxy如果安装器已经创建好外部 Network 与 CA Volume也可以显式叠加固定提交中的 Compose 文件cddeployment/docker_composedockercompose-fdocker-compose.yml-fdocker-compose.craft.yml up-d这里必须明确一个高风险运维事实Craft 的 Docker Overlay 将/var/run/docker.sock以读写方式挂载给api_server和background因为它们需要动态创建、检查和删除 Sandbox Container在 Linux 上控制 Docker Socket 基本等价于取得宿主机 Root 权限。sandbox-proxy虽然只读挂载 Socket仍可读取 Container Event、Label 和部分运行元数据。Sandbox Container 本身没有获得 Docker Socket但一旦 API Server、Background Worker 或其依赖被攻破影响可能越过应用容器到达整台宿主机。因此启用 Craft 的 Compose 主机应当是专用、受控节点限制管理端口和 Docker Socket 接触面不与无关高价值工作负载混部固定镜像版本并扫描依赖保护.env、数据库和 Proxy CA监控异常 Container 创建在云主机上还应强制 IMDSv2避免 Sandbox 或受损组件读取实例元数据凭据。需要更强租户隔离与独立调度时应优先评估 Helm 中的 Kubernetes Sandbox、独立 Namespace、RBAC、NetworkPolicy 和节点池而不是把普通 Compose 直接解释为多租户安全边界。七、从 Onyx 学习 Agent RAG 系统设计Onyx 更适合需要持续同步企业知识、权限感知搜索、可配置 Agent或者希望用 Craft 在受控工作区生成完整产物的团队。如果需求只是轻量文件聊天组织无法维护 PostgreSQL、Redis、OpenSearch、对象存储和多类 Worker或者不能接受 Compose 启用 Craft 后的 Docker Socket 风险更轻的单体工具可能更合适。跨地域高可用和严格多租户隔离也不是一次安装命令自动获得的能力需要额外基础设施与验证。Onyx 最值得借鉴的并不是它支持多少模型或连接器而是它把 AI 应用里的不确定性放进了清晰边界数据进入系统前先经过连接器与后台索引链路不让同步任务阻塞在线问答Chunk 同时考虑句子、Section、元数据和多粒度表示而不是机械截断检索把过滤约束、关键词/向量混合召回、归一化融合、加权 RRF 与 LLM 相关性选择串联起来不把所有希望押在单一 Embedding 上Agent 工具先按配置、权限和可用性过滤再统一暴露与执行边界可追踪MCP、OpenAPI 和内置工具都收敛到同一个 Tool 接口降低执行循环复杂度上下文、工具 Schema 和文件都进入 Token 预算搜索结果与引用采用 LLM 友好表示社区核心与企业权限能力明确分层部署侧再通过 Worker、索引和模型服务拆分支持扩容。如果要基于 Onyx 建设内部 AI最先确定的也不应是“选哪个大模型”而应是四个问题哪些数据允许被索引、访问权限怎样同步、检索质量如何评测、Agent 可以调用哪些有副作用的工具。只有这四项有了可验证规则模型升级才会成为收益而不是把已有风险放大。参考资料Onyx GitHub 仓库https://github.com/cmyk-labs/onyxOnyx 官方 GitHub 仓库https://github.com/onyx-dot-app/onyxOnyx 官方文档https://docs.onyx.app/