メインコンテンツまでスキップ

LLM プロバイダーモジュール概要

このドキュメントでは、Elftia における LLM プロバイダーサブシステムの全体アーキテクチャを説明します。このサブシステムは、マルチプロバイダー設定の管理、API キープール、モデルディスカバリー、リクエストルーティング、Completion 呼び出しパイプラインを担当します。


ファイルの場所

モジュールパス
CompletionServicepackages/desktop/app/main/services/capabilities/llm/completion/CompletionService.ts
ApiKeyPoolServicepackages/desktop/app/main/services/capabilities/llm/completion/ApiKeyPoolService.ts
LLMConfigServicepackages/desktop/app/main/services/capabilities/llm/config-service/LLMConfigService.ts
ProviderManagerpackages/desktop/app/main/services/capabilities/llm/config-service/ProviderManager.ts
ModelDiscoveryManagerpackages/desktop/app/main/services/capabilities/llm/config-service/ModelDiscoveryManager.ts
ConfigIOManagerpackages/desktop/app/main/services/capabilities/llm/config-service/ConfigIOManager.ts
AgentModelsManagerpackages/desktop/app/main/services/capabilities/llm/config-service/AgentModelsManager.ts
ThinkingResolverpackages/desktop/app/main/services/capabilities/llm/completion/ThinkingResolver.ts
StreamHandlerpackages/desktop/app/main/services/capabilities/llm/completion/StreamHandler.ts
DirectApiHandlerpackages/desktop/app/main/services/capabilities/llm/completion/DirectApiHandler.ts
ToolHandlerpackages/desktop/app/main/services/capabilities/llm/completion/ToolHandler.ts
TransformerHandlerpackages/desktop/app/main/services/capabilities/llm/completion/TransformerHandler.ts
ProviderSearchInjectorpackages/desktop/app/main/services/capabilities/llm/completion/ProviderSearchInjector.ts
NativeSearchInjectorpackages/desktop/app/main/services/capabilities/llm/completion/NativeSearchInjector.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
Provider Presetspackages/desktop/app/shared/provider-presets.ts
IPC Routerspackages/desktop/app/main/services/routers/llm/

アーキテクチャの全体像

graph TB
subgraph Frontend ["Frontend (Renderer)"]
UI[Provider Settings UI]
ChatUI[Chat Interface]
end

subgraph IPCLayer ["IPC Layer"]
PR[ProviderRouter]
AKR[ApiKeyRouter]
CR[CompletionRouter]
RCR[RouterConfigRouter]
TR[TransformerRouter]
MPR[ModelParametersRouter]
end

subgraph LLMConfigService ["LLMConfigService (Delegate Pattern)"]
PM[ProviderManager]
MDM[ModelDiscoveryManager]
CIOM[ConfigIOManager]
AMM[AgentModelsManager]
end

subgraph CompletionService ["CompletionService (Facade Pattern)"]
DAH[DirectApiHandler]
SH[StreamHandler]
TH[ToolHandler]
THR[TransformerHandler]
TR2[ThinkingResolver]
end

AKPS[ApiKeyPoolService]

subgraph ExternalAPIs ["External APIs"]
OpenAI[OpenAI API]
Anthropic[Anthropic API]
Gemini[Gemini API]
Azure[Azure OpenAI API]
Others[Other Providers...]
end

subgraph Storage ["Storage"]
SQLite[(SQLite)]
JSON[(llms-config.json)]
end

UI --> PR
UI --> AKR
ChatUI --> CR

PR --> PM
AKR --> AKPS
CR --> CompletionService

PM --> SQLite
PM --> JSON
MDM --> SQLite
MDM --> JSON

CompletionService --> AKPS
CompletionService --> LLMConfigService
DAH --> OpenAI
DAH --> Anthropic
DAH --> Gemini
DAH --> Azure
SH --> OpenAI
SH --> Anthropic
SH --> Gemini
SH --> Azure

データ構造

コアの型定義

// API format enum
type ApiFormat = 'openai' | 'anthropic' | 'google' | 'azure-openai' | 'openai-response';

// LLM provider
interface LLMProvider {
id: string; // Unique identifier
name: string; // Display name
apiFormat?: ApiFormat; // API format (preferred field)
chatApiFormat?: ApiFormat; // Legacy API format field
apiType?: string; // Legacy type field
api_base_url?: string; // API base URL
api_key: string; // Single key (legacy)
models: string[]; // Model ID list
modelConfigs?: ModelConfig[]; // Per-model detailed config
modelGroups?: ModelGroup[]; // Model groups
modelsEndpoint?: string; // Model discovery endpoint
enabled: boolean; // Whether enabled
transformer?: TransformerConfig; // Transformer chain config
icon?: string; // Icon
website?: string; // Official website
docsUrl?: string; // Documentation link
defaultSettings?: CompletionSettings; // Default completion parameters
codingPlan?: CodingPlanConfig; // Coding Plan config
isSystem?: boolean; // System built-in provider
presetId?: string; // Preset template ID
createdAt: string;
updatedAt: string;
}

// Completion request options
interface CompletionOptions {
providerId: string; // Provider ID
model: string; // Model ID
messages: SimpleChatMessage[]; // Message list
maxTokens?: number; // Max token count
temperature?: number; // Temperature
stream?: boolean; // Whether streaming
thinkLevel?: ThinkLevel; // Thinking level
nativeSearchAugmentation?: NativeSearchAugmentation; // Native search augmentation
sessionId?: string; // Session ID (for API Key Pool affinity)
}

// API key pool entry
interface ApiKeyEntry {
id: string; // Unique ID
providerId: string; // Owning provider
label?: string; // Display label
apiKey: string; // Key value
enabled: boolean; // Whether enabled
weight: number; // Weight (1-100)
}

データフロー概要

Completion リクエストパイプライン

sequenceDiagram
participant Frontend as フロントエンド
participant CS as CompletionService
participant LLC as LLMConfigService
participant AKP as ApiKeyPoolService
participant Handler as API Handler
participant API as Provider API

Frontend->>CS: complete() / completeStream()
CS->>LLC: resolveRoutedModel(providerId, model)
LLC-->>CS: actualProviderId + actualModel
CS->>LLC: getProvider(actualProviderId)
LLC-->>CS: provider config
CS->>CS: resolveApiKeyForRequest()
Note right of CS: Priority: codingPlan > pool > legacy
CS->>AKP: getKeyForSession(providerId, sessionId)
AKP-->>CS: resolved API key
CS->>CS: resolveApiFormat(provider)
CS->>Handler: callDirectHandler / callStreamHandler
Handler->>API: HTTP request
API-->>Handler: response / SSE stream
Handler-->>CS: CompletionResult
alt 429/529 error
CS->>AKP: reportError(providerId, sessionId, status)
AKP-->>CS: new key
CS->>Handler: retry with new key
end
CS->>AKP: reportSuccess(sessionId)
CS-->>Frontend: result

モジュール境界と責務

モジュール責務担当外
CompletionServiceリクエストパイプラインのオーケストレーション、フォーマットのディスパッチ、リトライ、Vision フォールバックプロバイダー CRUD、キーの保存
ApiKeyPoolServiceマルチキーの負荷分散、セッションアフィニティ、クールダウンバックオフキーの永続化(DB に委譲)
LLMConfigServiceプロバイダー設定管理、モデルディスカバリー、ルーティング、Transformer チェーンAPI 呼び出し
ProviderManagerプロバイダー CRUD、テンプレート/プリセットシステム、SQLite 永続化モデルディスカバリー、ルーティング設定
ModelDiscoveryManagerモデルリストのディスカバリー、キャッシュ(SQLite + ファイル)プロバイダー CRUD
ConfigIOManager設定のインポート/エクスポート、JSON ファイル I/Oデータベース操作
AgentModelsManagerルーティング設定、Transformer 管理、グローバルパラメータプロバイダー CRUD
ThinkingResolvermax_tokens の解決、思考バジェットの計算リクエストの送信
StreamHandlerSSE ストリーム処理(OpenAI/Anthropic/Gemini)非ストリーミングリクエスト
DirectApiHandler非ストリーミング API 呼び出しストリーミングリクエスト
ToolHandlerAgent ツール呼び出しループ通常の Completion
TransformerHandlerTransformer チェーン Completion直接 API 呼び出し

IPC 統合テーブル

IPC チャンネル方向Router説明
llmConfig:getProvidersRenderer -> MainProviderRouterすべてのプロバイダーを取得
llmConfig:getProviderRenderer -> MainProviderRouter単一プロバイダーを取得
llmConfig:addProviderRenderer -> MainProviderRouterプロバイダーを追加
llmConfig:updateProviderRenderer -> MainProviderRouterプロバイダーを更新
llmConfig:deleteProviderRenderer -> MainProviderRouterプロバイダーを削除
llmConfig:toggleProviderRenderer -> MainProviderRouterプロバイダーを有効/無効化
llmConfig:discoverModelsRenderer -> MainProviderRouterモデル一覧をディスカバリー
llmConfig:getProviderPresetsRenderer -> MainProviderRouterプリセットテンプレートを取得
llmConfig:addFromPresetRenderer -> MainProviderRouterプリセットからプロバイダーを追加
llmConfig:exportConfigRenderer -> MainProviderRouter設定をエクスポート
llmConfig:importConfigRenderer -> MainProviderRouter設定をインポート
llmConfig:getApiKeysRenderer -> MainApiKeyRouterキー一覧を取得
llmConfig:addApiKeyRenderer -> MainApiKeyRouterキーを追加
llmConfig:updateApiKeyRenderer -> MainApiKeyRouterキーを更新
llmConfig:deleteApiKeyRenderer -> MainApiKeyRouterキーを削除
llmConfig:toggleApiKeyRenderer -> MainApiKeyRouterキーを有効/無効化

拡張ポイント

  • 新しい API フォーマットの追加: url-builder.ts に URL ビルダー関数を追加し、DirectApiHandler.ts / StreamHandler.ts にハンドラー関数を追加して、CompletionService の switch に登録する
  • 新しいプロバイダープリセットの追加: provider-presets.tsPROVIDER_PRESETS 配列にテンプレートを追加する
  • 新しい検索設定の追加: provider-presets.tsPROVIDER_SEARCH_CONFIGS にエントリを追加する
  • カスタム Transformer: AgentModelsManager 経由で新しい Transformer チェーンを登録する

関連ファイル

ファイル目的
packages/desktop/app/shared/llm-config.tsLLM 設定の共有型定義
packages/desktop/app/shared/completion-types.tsCompletion の型定義
packages/desktop/app/shared/thinking-config.ts思考設定とバジェット計算
packages/desktop/app/shared/provider-presets.tsプロバイダープリセットテンプレートと検索設定
packages/desktop/app/main/services/routers/llm/schemas.tsIPC リクエストの Zod バリデーションスキーマ
packages/desktop/app/main/services/capabilities/llm/config-service/schemas.ts設定サービス内部の Zod スキーマ
packages/desktop/app/main/services/infra/utils/sse-parser.tsSSE ストリーム解析ユーティリティ
packages/desktop/app/main/workers/db/apiKeys.tsAPI キーのデータベース操作
packages/desktop/app/main/workers/DbClient.tsデータベースクライアント
packages/desktop/app/preload/index.tsPreload API の公開