跳到主要内容

如何扩展 LLM 提供商

本文档提供三个常见扩展场景的分步操作指南:添加新的预设模板、添加新的 API 格式、以及为提供商配置搜索能力。


文件位置

文件路径
Provider 模板packages/desktop/app/shared/llm-config.ts
Provider 预设packages/desktop/app/shared/provider-presets.ts
ProviderManagerpackages/desktop/app/main/services/capabilities/llm/config-service/ProviderManager.ts
URL Builderpackages/desktop/app/main/services/capabilities/llm/completion/url-builder.ts
Header Builderpackages/desktop/app/main/services/capabilities/llm/completion/header-builder.ts
Message Converterpackages/desktop/app/main/services/capabilities/llm/completion/message-converter.ts
DirectApiHandlerpackages/desktop/app/main/services/capabilities/llm/completion/DirectApiHandler.ts
StreamHandlerpackages/desktop/app/main/services/capabilities/llm/completion/StreamHandler.ts
CompletionServicepackages/desktop/app/main/services/capabilities/llm/completion/CompletionService.ts
Typespackages/desktop/app/main/services/capabilities/llm/completion/types.ts
ProviderSearchInjectorpackages/desktop/app/main/services/capabilities/llm/completion/ProviderSearchInjector.ts
NativeSearchInjectorpackages/desktop/app/main/services/capabilities/llm/completion/NativeSearchInjector.ts
IPC Router Schemaspackages/desktop/app/main/services/routers/llm/schemas.ts
前端 i18npackages/renderer/src/locales/{en,zh,ja}/providers/llm.json

架构上下文

graph TB
subgraph 扩展点
direction TB
A["(1) 新预设模板<br/>provider-presets.ts"]
B["(2) 新 API 格式<br/>types + handlers"]
C["(3) 搜索配置<br/>PROVIDER_SEARCH_CONFIGS"]
end

subgraph 影响范围
direction TB
Shared[shared 层<br/>类型 + 预设]
Completion[completion 层<br/>Handlers + URL]
Config[config-service 层<br/>ProviderManager]
Router[router 层<br/>IPC Schemas]
Frontend[renderer 层<br/>UI + i18n]
end

A --> Shared
A --> Config
A --> Frontend

B --> Shared
B --> Completion
B --> Router

C --> Shared
C --> Completion

场景一:添加新的预设模板

当需要支持一个新的 LLM 提供商(如新的中国云厂商或国际提供商),需要创建预设模板,让用户在 UI 中一键添加。

数据结构

// 预设模板的完整接口
interface PresetProviderTemplate {
id: string; // 唯一 ID(小写,如 'minimax')
name: string; // 显示名称
apiFormat: ApiFormat; // API 格式
baseUrl: string; // Base URL
modelsEndpoint?: string; // 模型发现端点
models: string[]; // 支持的模型 ID 列表
modelConfigs: ModelConfig[]; // 模型详细配置
features: string[]; // 特性标签
icon?: string; // 图标
website?: string; // 官网
docsUrl?: string; // API 文档
defaultSettings?: CompletionSettings; // 默认补全参数
}

操作步骤

步骤 1:定义预设模板

packages/desktop/app/shared/provider-presets.tsPROVIDER_PRESETS 数组中添加:

// 伪代码 - 添加新预设
{
id: 'newprovider',
name: 'NewProvider AI',
apiFormat: 'openai', // 多数中国厂商兼容 OpenAI 格式
baseUrl: 'https://api.newprovider.com/v1',
modelsEndpoint: '/models',
models: ['np-large', 'np-lite', 'np-vision'],
modelConfigs: [
{
id: 'np-large',
name: 'NP Large',
enabled: true,
category: 'chat',
contextLength: 128000,
maxTokens: 8192,
vision: false,
functionCall: true,
reasoning: false,
},
{
id: 'np-lite',
name: 'NP Lite',
enabled: true,
category: 'chat',
contextLength: 32000,
maxTokens: 4096,
},
{
id: 'np-vision',
name: 'NP Vision',
enabled: true,
category: 'chat',
contextLength: 64000,
maxTokens: 4096,
vision: true,
},
],
features: ['chat', 'function_call'],
website: 'https://newprovider.com',
docsUrl: 'https://docs.newprovider.com/api',
}

步骤 2(可选):添加为默认提供商

如果希望新提供商出现在所有用户的初始列表中:

ProviderManager.getDefaultProviders()defaultTemplateIds 数组中添加 ID。

同时在 packages/desktop/app/shared/llm-config.tsPROVIDER_TEMPLATES 中添加对应的 ProviderTemplate

步骤 3(可选):添加 Coding Plan 支持

如果提供商支持 Coding Plan 专用 API:

// 在 CODING_PLAN_URL_PRESETS 中添加
CODING_PLAN_URL_PRESETS['newprovider'] = {
baseUrl: 'https://api.newprovider.com/coding/v1',
separateApiKey: false, // 是否需要单独的 API Key
};

步骤 4(可选):添加 Follow-Provider 模型映射

如果希望支持自动选择同一提供商的 background/vision 模型:

// 在 PROVIDER_MODEL_MAPPINGS 中添加
PROVIDER_MODEL_MAPPINGS['newprovider'] = {
primary: 'np-large',
background: 'np-lite',
vision: 'np-vision', // 无视觉模型时设为 null
};

步骤 5:添加前端 i18n

packages/renderer/src/locales/ 下的 en/zh/ja 的 providers/llm.json 中添加提供商名称翻译。


场景二:添加新的 API 格式

当遇到无法兼容现有格式(openai/anthropic/google/azure-openai/openai-response)的提供商 API 时,需要添加新的 API 格式。

步骤总览

flowchart TD
S1["(1) 定义格式标识<br/>types.ts"] --> S2["(2) URL 构建<br/>url-builder.ts"]
S2 --> S3["(3) Header 构建<br/>header-builder.ts"]
S3 --> S4["(4) 消息转换<br/>message-converter.ts"]
S4 --> S5["(5) 非流式 Handler<br/>DirectApiHandler.ts"]
S5 --> S6["(6) 流式 Handler<br/>StreamHandler.ts"]
S6 --> S7["(7) 注册分发<br/>CompletionService.ts"]
S7 --> S8["(8) Schema 更新<br/>schemas.ts"]

步骤 1:定义格式标识

packages/desktop/app/main/services/capabilities/llm/completion/types.tsApiFormat 中添加新值:

// 修改前
type ApiFormat = 'openai' | 'anthropic' | 'google' | 'azure-openai' | 'openai-response';

// 修改后
type ApiFormat = 'openai' | 'anthropic' | 'google' | 'azure-openai' | 'openai-response' | 'newformat';

同步更新 packages/desktop/app/main/services/capabilities/llm/config-service/schemas.tsApiFormatSchema

const ApiFormatSchema = z.enum([
'openai', 'anthropic', 'google', 'azure-openai', 'openai-response', 'newformat'
]);

同步更新 packages/desktop/app/main/services/routers/llm/schemas.tsllmProviderCreateSchema

步骤 2:URL 构建

url-builder.ts 中添加构建函数:

// 伪代码
function buildNewFormatApiUrl(baseUrl: string): string {
// 根据提供商 API 文档构建正确的 endpoint URL
// 处理各种 baseUrl 输入格式
}

resolveApiFormat() 中添加新格式的识别逻辑(如果需要从 apiType 推导)。

buildProviderApiUrl() 中添加新格式的分支。

步骤 3:Header 构建

header-builder.tsgetProviderHeaders() 中处理新格式的认证头:

// 伪代码 - 不同提供商的认证方式
// OpenAI: Authorization: Bearer <key>
// Anthropic: x-api-key: <key>
// 新格式可能使用不同的头部

步骤 4:消息格式转换

message-converter.ts 中添加消息转换函数:

// 伪代码
function convertMessageToNewFormat(message: SimpleChatMessage): NewFormatMessage {
// 将通用消息格式转换为提供商特定格式
// 处理 role 映射、content 结构、images、tool calls 等
}

步骤 5:非流式 Handler

DirectApiHandler.ts 中添加:

// 伪代码
async function callNewFormatCompletion(
provider: LLMProvider,
apiKey: string,
options: CompletionOptions,
logger: LoggerService
): Promise<CompletionResult> {
// 构建请求体
// 发送请求
// 解析响应为 CompletionResult
}

步骤 6:流式 Handler

StreamHandler.ts 中添加:

// 伪代码
async function streamNewFormatCompletion(
provider: LLMProvider,
apiKey: string,
options: CompletionOptions,
messageId: string,
callbacks: StreamCallbacks,
logger: LoggerService
): Promise<void> {
// 构建流式请求体
// 使用 streamSSEResponse() 或自定义流解析
// 调用 callbacks 传递增量内容
}

步骤 7:注册分发

CompletionService 中注册新格式:

// 在 callDirectHandler 的 switch 中
case 'newformat':
return callNewFormatCompletion(provider, apiKey, options, this.logger);

// 在 callStreamHandler 的 switch 中
case 'newformat':
await streamNewFormatCompletion(provider, apiKey, options, messageId, callbacks, this.logger);
return;

步骤 8:Schema 更新

确保所有涉及 ApiFormat 枚举的 Zod Schema 都已更新:

  • capabilities/llm/config-service/schemas.tsApiFormatSchema
  • routers/llm/schemas.tsllmProviderCreateSchema.apiFormat

场景三:为提供商添加搜索配置

当提供商支持网页搜索功能时,需要配置搜索注入方式。

搜索类型决策

flowchart TD
Start[提供商支持搜索?] --> Type{搜索实现方式}
Type -->|请求参数启用| ModelParam["model-param<br/>修改请求 body"]
Type -->|内置工具定义| BuiltinTool["builtin-tool<br/>注入 tools 数组"]
Type -->|MCP 服务器| MCP["mcp<br/>外部处理"]
Type -->|SDK 原生| SDKNative["sdk-native<br/>NativeSearchInjector"]
Type -->|不支持| None["none<br/>无需配置"]

步骤

步骤 1:确定搜索类型

搜索实现方式判断标准示例
model-paramAPI 通过请求参数启用搜索(如 enable_search: trueDashScope, Baidu
builtin-toolAPI 需要在 tools 数组中注入特定工具定义Kimi, Volcengine
mcp搜索通过外部 MCP 服务器提供自定义部署
sdk-nativeSDK 原生处理(如 Anthropic server-side tools)Anthropic
none不支持搜索Ollama

步骤 2:添加搜索配置

packages/desktop/app/shared/provider-presets.tsPROVIDER_SEARCH_CONFIGS 中添加:

model-param 类型(请求参数):

// 伪代码
PROVIDER_SEARCH_CONFIGS['newprovider'] = {
type: 'model-param',
paramName: 'enable_search', // 参数名
paramValue: true, // 参数值
extraParams: { // 额外参数(可选)
search_mode: 'auto',
},
applicableModels: null, // null 表示所有模型
};

builtin-tool 类型(内置工具):

// 伪代码
PROVIDER_SEARCH_CONFIGS['newprovider'] = {
type: 'builtin-tool',
toolDefinition: {
type: 'function',
function: {
name: 'web_search',
description: 'Search the web for information',
parameters: {
type: 'object',
properties: {
query: { type: 'string', description: 'Search query' },
},
required: ['query'],
},
},
},
conflictsWithFC: false, // 是否与函数调用冲突
applicableModels: ['np-large'], // 仅特定模型支持(null = 全部)
};

步骤 3:验证注入

ProviderSearchInjector 会自动通过 getSearchConfig() 检测提供商的搜索配置,并在 buildSearchAugmentation() 中构建注入内容。无需额外代码修改。


修改文件清单

场景一:新增预设模板

文件修改内容必需
shared/provider-presets.ts添加 PROVIDER_PRESETS 条目
shared/llm-config.ts添加 PROVIDER_TEMPLATES 条目(如需默认)可选
capabilities/llm/config-service/ProviderManager.ts添加到 defaultTemplateIds(如需默认)可选
shared/provider-presets.tsCODING_PLAN_URL_PRESETS(如需)可选
shared/provider-presets.tsPROVIDER_MODEL_MAPPINGS(如需)可选
shared/provider-presets.tsPROVIDER_SEARCH_CONFIGS(如需搜索)可选
i18n JSON 文件 (en/zh/ja)提供商名称翻译建议

场景二:新增 API 格式

文件修改内容必需
capabilities/llm/completion/types.tsApiFormat 类型
capabilities/llm/completion/url-builder.tsURL 构建函数 + resolveApiFormat + buildProviderApiUrl
capabilities/llm/completion/header-builder.ts认证头部
capabilities/llm/completion/message-converter.ts消息格式转换
capabilities/llm/completion/DirectApiHandler.ts非流式 Handler
capabilities/llm/completion/StreamHandler.ts流式 Handler
capabilities/llm/completion/CompletionService.tsswitch 分支注册
capabilities/llm/config-service/schemas.tsApiFormatSchema
routers/llm/schemas.tsllmProviderCreateSchema

场景三:添加搜索配置

文件修改内容必需
shared/provider-presets.tsPROVIDER_SEARCH_CONFIGS 条目

测试指南

预设模板测试

  1. 单元测试:验证模板数据完整性

    • 所有必填字段存在且有效
    • modelConfigs 中每个模型 ID 在 models 数组中
    • apiFormat 值在 ApiFormat 枚举范围内
  2. 集成测试

    • 从预设创建提供商 → 验证 Provider 数据正确
    • 启用提供商 → 配置有效 API Key → 发送测试消息
    • 模型发现 → 验证返回的模型列表
  3. UI 测试

    • 在设置页面的预设列表中能看到新预设
    • 点击添加后正确创建提供商
    • 提供商配置页面显示正确的字段

API 格式测试

  1. URL 构建测试

    • 各种 baseUrl 输入格式 → 正确的 API endpoint
    • 带路径前缀的 URL → 不丢失前缀
  2. 消息转换测试

    • 纯文本消息 → 正确格式
    • 带图片的消息 → 正确处理
    • 带工具调用的消息 → 正确格式
  3. Handler 测试

    • 非流式:发送请求 → 解析响应 → CompletionResult
    • 流式:SSE 事件 → 正确触发 callbacks
    • 错误处理:网络错误、API 错误、格式错误
  4. 端到端测试

    • 使用 testModel() 验证完整管线
    • 流式对话 → 验证 onDelta/onDone 回调

搜索配置测试

  1. 注入测试

    • getSearchConfig() 能正确识别新提供商
    • buildSearchAugmentation() 生成正确的注入内容
    • model-param 类型:请求 body 包含正确参数
    • builtin-tool 类型:tools 数组包含正确的工具定义
  2. 冲突测试

    • conflictsWithFC 为 true 时:搜索工具和函数调用不同时存在
    • applicableModels 限制:非适用模型不注入搜索

关联文件表

文件关联方式
shared/llm-config.tsPROVIDER_TEMPLATES、ApiFormat、核心类型
shared/provider-presets.ts预设模板、搜索配置、Coding Plan URL、模型映射
capabilities/llm/config-service/ProviderManager.ts默认提供商列表、模板创建逻辑
capabilities/llm/config-service/schemas.tsApiFormatSchema、验证 Schema
capabilities/llm/completion/types.tsApiFormat 类型定义
capabilities/llm/completion/url-builder.tsresolveApiFormat、URL 构建
capabilities/llm/completion/header-builder.ts认证头部
capabilities/llm/completion/message-converter.ts消息格式转换
capabilities/llm/completion/DirectApiHandler.ts非流式 API Handler
capabilities/llm/completion/StreamHandler.ts流式 API Handler
capabilities/llm/completion/CompletionService.tsHandler 分发注册
capabilities/llm/completion/ProviderSearchInjector.ts搜索注入逻辑
routers/llm/schemas.tsIPC 参数验证 Schema
i18n JSON 文件前端翻译