Repository Wiki
LYOfficial/OneDocs

自定义服务商接入

OneDocs 通过自定义供应商配置支持接入未内置的、兼容 OpenAI 格式 API 的第三方服务,包括自建代理、企业内部模型服务和其他模型平台。

Purpose and Scope

本页聚焦“自定义服务商接入”这一叶子能力:配置供应商名称、Base URL 和模型 ID,并将其作为模型设置中的可选服务商使用。页面同时说明代码中的自定义配置对象如何生成,以及设置页如何把模型配置入口挂载到 ModelSelectionPanel。

本页不展开具体模型分析、RAG、数据管理或部署流程;这些能力属于设置页中的其他面板或相关主题。对于模型选择页面的完整交互细节,应结合 ModelSelectionPanel 的实现阅读;当前已检索到的源码只显示其由 Settings 在 model 区域挂载。

Overview

自定义服务商的核心约束是协议兼容性,而不是供应商名称。用户需要提供:

  • 名称:仅用于 OneDocs 界面中的显示。
  • Base URL:第三方 API 的服务根地址;文档示例通常以 /v1 结尾。
  • 模型 ID:必须与远端服务实际支持的模型标识完全一致。
  • API Key:部分服务需要,部分服务可以留空。

仓库中的 createCustomProvider 将这三个必需的业务字段转换为 CustomProviderConfig,并补充唯一性标识和 isCustom: true 标志。内置服务商则通过 MODEL_PROVIDERS 静态配置维护名称、Base URL、endpoint、模型列表和凭证提示;自定义服务商因此适合表达“运行时添加的一条配置”,而不是修改内置供应商注册表。

Architecture

Loading diagram...

Sources: Settings.tsx, providers.ts

图中的设置入口关系来自 Settings:当活动区域为 model 时渲染 ModelSelectionPanel。配置层则由 providers.ts 中的 createCustomProvider 和 MODEL_PROVIDERS 构成。源码没有在已读取范围内展示自定义配置最终保存到哪一个状态或存储,因此不能把持久化实现画成已确认的组件;这里仅表示配置对象被交给模型选择流程后,按其 Base URL 和模型 ID 对接远端兼容 API。

实现机制

1. 运行时配置对象的生成

createCustomProvider 是当前源码中自定义供应商的明确工厂函数。它接收 name、baseUrl 和 model 三个字符串参数,返回 CustomProviderConfig:

typescript
1export const createCustomProvider = ( 2 name: string, 3 baseUrl: string, 4 model: string, 5): CustomProviderConfig => ({ 6 id: `custom_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, 7 name, 8 baseUrl, 9 model, 10 isCustom: true, 11});

Source: providers.ts

实现有两个重要设计意图:

  1. isCustom: true 为后续 UI 或模型选择逻辑提供来源标记,使运行时添加项可以与内置 MODEL_PROVIDERS 区分。
  2. id 由当前时间戳和随机字符串组成,不依赖名称、URL 或模型 ID,因此同一服务可以用不同配置创建多个条目。源码没有展示 ID 冲突检测或持久化逻辑,不能推断该 ID 在跨设备或重启后保持不变。

2. 内置供应商与自定义供应商的边界

MODEL_PROVIDERS 是内置供应商注册表。以 OpenAI 配置为例,每个条目包含统一的 name、baseUrl、endpoint、models、defaultModel、凭证提示和图标等字段:

typescript
1 openai: { 2 name: "OpenAI", 3 baseUrl: "https://api.openai.com/v1", 4 endpoint: "/chat/completions", 5 models: [ 6 { value: "openai/gpt-5.5", name: "GPT-5.5", tags: [MODEL_TAGS.flagship] }, 7 { value: "openai/gpt-5.4", name: "GPT-5.4", tags: [MODEL_TAGS.flagship] }, 8 { value: "openai/gpt-5.4-mini", name: "GPT-5.4 mini", tags: [MODEL_TAGS.flagship] }, 9 ], 10 defaultModel: "openai/gpt-5.5", 11 keyLabel: "OpenAI API Key", 12 keyHint: "需要填入有效的OpenAI API密钥方可使用", 13 baseUrlHint: "API服务器地址,默认为OpenAI官方地址", 14 icon: PROVIDER_LOGOS.openai, 15 },

Source: providers.ts

这说明两条配置路径的职责不同:内置供应商拥有预置模型列表和展示元数据;自定义供应商工厂只负责生成最小配置对象。若用户添加的模型不在供应商列表中,产品文档要求输入真实的模型 ID,而不是显示名称。

3. Base URL 的规范化边界

源码对 OneDocs 自有服务的环境变量进行 trim,并在缺少 /v1 时补齐;这段逻辑只作用于 VITE_ONEDOCS_API_URL,不能直接推断它会自动修正用户输入的自定义 Base URL:

typescript
1const sanitizeEnvValue = (value: unknown) => 2 typeof value === "string" ? value.trim() : ""; 3 4let ONEDOCS_BASE_URL = sanitizeEnvValue(import.meta.env.VITE_ONEDOCS_API_URL); 5if (ONEDOCS_BASE_URL && !ONEDOCS_BASE_URL.endsWith("/v1")) { 6 ONEDOCS_BASE_URL = `${ONEDOCS_BASE_URL.replace(/\/$/, "")}/v1`; 7}

Source: providers.ts

因此,接入第三方服务时应在界面中直接填写服务要求的 Base URL,并特别检查路径和尾部斜杠。仓库文档明确建议兼容 OpenAI 的服务通常使用以 /v1 结尾的地址。

Core Flow

Loading diagram...

Sources: Settings.tsx, Settings.tsx, providers.ts, Custom-Provider.md

流程中前两步是源码直接确认的:Settings 将模型区域渲染为 ModelSelectionPanel。工厂调用和远端请求的具体调用点不在已读取的源码片段中;图中后半段是产品文档定义的接入流程,表示契约边界而非已确认的 HTTP 实现细节。

配置选项与接入步骤

选项类型必填说明
名称 namestring是自定义供应商的显示名称;工厂函数原样写入配置。
Base URL baseUrlstring是API 服务地址;应填写第三方服务要求的兼容接口根地址。
模型 modelstring是远端服务支持的模型 ID,必须与服务商定义完全一致。
API Keystring否由具体服务的认证要求决定;产品文档明确说明部分服务不需要。
idstring自动生成由时间戳和随机字符串组合生成,调用方不传入。
isCustomboolean自动生成工厂函数固定设为 true。

界面操作路径为“设置 → 模型 → 自定义供应商”。创建时至少填写名称、Base URL 和模型;完成后点击添加。仓库文档还说明可以添加多个自定义供应商,没有数量限制,每条配置可以使用独立的 URL、模型和 API Key。

可验证的配置示例

下面示例取自仓库文档,展示的是实际支持的填写形式,而不是 TypeScript API 调用:

text
1名称: 302.AI 2Base URL: https://api.302.ai/v1 3模型: 平台支持的模型 ID 4API Key: 302.AI 提供的 API Key

Source: Custom-Provider.md

若使用 SiliconFlow,文档给出的 Base URL 是 https://api.siliconflow.cn/v1,模型字段示例是 Qwen/Qwen2.5-7B-Instruct。模型字段不要填写产品展示名称;它必须是远端 API 接受的模型标识。

API Reference

createCustomProvider(name: string, baseUrl: string, model: string): CustomProviderConfig

创建一个标记为自定义的供应商配置对象。

参数:

  • name (string):供应商显示名称。
  • baseUrl (string):供应商 API Base URL。
  • model (string):供应商支持的模型 ID。

返回值:

返回 CustomProviderConfig 对象,包含自动生成的 id、原样传递的 name、baseUrl、model,以及固定的 isCustom: true。

异常:

源码未声明异常,也未在函数内部对空字符串、URL 格式或模型 ID 做校验。因此输入校验、重复配置处理和远端可用性检查应由调用层或后续请求流程承担;具体实现细节在已读取源码中未找到。

失败模式、边界条件与并发

配置错误

  • Base URL 错误:产品文档建议检查 URL 是否正确,通常包括 /v1 路径,并确认 API 服务正在运行。
  • API Key 无效:应确认密钥复制无误、供应商选择正确且账户额度充足;自定义服务不要求密钥时可以留空。
  • 模型 ID 不存在:自定义模型名称必须与服务商支持的 ID 完全一致,否则模型列表即使显示成功,也可能在请求阶段失败。
  • 协议不兼容:本能力的兼容目标是 OpenAI 格式 API。对于仅提供完全不同请求/响应协议的服务,当前源码没有显示适配器或转换层。

删除与当前选择

产品文档规定,删除当前正在使用的自定义供应商后会自动切换到 OpenAI。这是文档层面的产品行为;当前已读取源码未包含删除处理函数,因此无法进一步确认切换动作发生在何处,或 OpenAI 不可用时的替代策略。

并发与一致性

id 使用 Date.now() 加随机字符串生成,能够降低同一运行时内的重复概率,但工厂函数没有锁、事务或集中式 ID 分配器。源码也未显示并发添加、跨标签页同步、持久化写入或冲突合并策略。若调用层同时提交多个配置,应由调用层保证状态更新的一致性。

性能与运维注意事项

  • createCustomProvider 只创建一个普通对象,没有网络访问,函数本身没有可见的 I/O 或重计算开销。
  • 真正的延迟和失败率来自用户配置的远端 API;仓库已检索内容没有自定义服务专用的超时、重试、熔断或健康检查实现。
  • 使用企业内部服务或自建代理时,应从客户端网络环境验证 Base URL 可达性,并确认远端暴露的是兼容接口路径。
  • API Key 属于敏感配置。当前已读取的工厂函数将配置对象返回给调用方,但没有展示脱敏、加密或日志过滤实现;运维上不应把密钥写入调试日志或公开配置文件。

Extension Points

当前最明确的扩展点是 CustomProviderConfig 契约和 createCustomProvider 工厂:需要增加自定义供应商元数据时,应先检查 CustomProviderConfig 类型定义以及 ModelSelectionPanel 的消费方式,再决定是否扩展字段。若目标服务不是 OpenAI 兼容协议,则仅增加字段不足以完成接入,还需要在请求层增加经过源码验证的协议适配逻辑;在本页已读取范围内尚未发现该适配器。