ADR 001 · Accepted
Provider Abstraction Layer
Status
Accepted (2024-01)
Context
We needed to support multiple LLM providers (OpenAI, Anthropic Claude, Google Gemini) while maintaining a consistent API for consumers. Each provider has different:
API endpoints and authentication methods
Request/response formats
Model naming conventions
Capability sets (vision, embeddings, streaming, tools)
Decision
Implement a provider abstraction layer with:
ProviderInterface as the core contract.
Capability interfaces for optional features (embeddings are a core ProviderInterface method, not an opt-in capability):
VisionCapableInterface.
StreamingCapableInterface.
ToolCapableInterface.
DocumentCapableInterface.
AbstractProvider base class with shared functionality.
LlmServiceManager as the unified entry point.
Consequences
Positive:
●● Consumers use single API regardless of provider.
●● Easy to add new providers.
● Capability checking via interface detection.
●● Provider switching requires no code changes.
Negative:
✕ Lowest common denominator for shared features.
◑ Provider-specific features require direct provider access.
◑ Additional abstraction layer complexity.
Net Score: +5.5 (Strong positive impact - abstraction enables flexibility and maintainability)
Alternatives considered
Single monolithic class: Rejected due to maintenance complexity.
Strategy pattern only: Insufficient for capability detection.
Factory pattern: Used in combination with interfaces.