How SymbolicAI Handles Multiple LLM Providers: OpenAI, Anthropic, and Google
SymbolicAI abstracts LLM provider differences through a mix-in and engine architecture that routes calls to OpenAI, Anthropic, or Google Gemini based on configuration, without changing application code.
SymbolicAI (extensityai/symbolicai) implements a provider-agnostic neurosymbolic programming framework that seamlessly integrates multiple LLM backends. By decoupling provider-specific logic from core application code through mix-ins and engine classes, SymbolicAI LLM provider support allows developers to switch between OpenAI, Anthropic, and Google models by changing a single configuration value.
The Mix-in and Engine Architecture
SymbolicAI uses a two-layer abstraction to isolate provider specifics from user code. This design keeps provider constants in lightweight mix-ins while implementing heavy API logic in dedicated engine classes.
Provider Mix-ins
The framework uses mix-in classes located in symai/backend/mixin/ to encapsulate provider-specific metadata. Each mix-in declares supported models and exposes token limit helpers.
In symai/backend/mixin/openai.py, the mix-in defines api_max_context_tokens() and api_max_response_tokens() methods that return model-specific limits for GPT-4o, GPT-4, and other OpenAI models.
Similarly, symai/backend/mixin/anthropic.py provides supports_adaptive_thinking() and supports_long_context_1m() helpers for Claude model capabilities, while symai/backend/mixin/google.py defines the 1,048,576 token limit for Gemini-2.5 family models.
Engine Implementations
Concrete API interactions reside in engine subclasses within symai/backend/engines/neurosymbolic/. Each engine inherits from the base Engine class and its respective provider mix-in.
engine_openai_gptX_chat.pyimplementsGPTXChatEngine, handling OpenAI chat completions, vision image patterns (<<vision:...>>), and token limit enforcement.engine_anthropic_claudeX_chat.pyimplementsClaudeXChatEngine, usinganthropic.Anthropicclient, token counting viaclient.messages.count_tokens(), and Claude-specific streaming event formatting.engine_google_geminiX_reasoning.pyimplementsGeminiXReasoningEngine, interfacing withgoogle.generativeai(genai), uploading multimodal media, and constructinggenai.types.Partobjects for content generation.
Configuration and Runtime Selection
The active provider is determined at runtime through the configuration system in symai/backend/settings.py. The SYMAI_CONFIG singleton loads symai.config.json and reads the NEUROSYMBOLIC_ENGINE_MODEL value.
The EngineRepository class in symai/functional.py maintains a registry of available engines. Each engine implements an id() method that checks if the configured model identifier matches its supported prefix:
gpt-...routes toGPTXChatEngineclaude...routes toClaudeXChatEnginegemini-...routes toGeminiXReasoningEngine
When EngineRepository.get_active() is called, it returns the concrete engine instance matching the current configuration, allowing the decorators in symai/core.py (such as @zero_shot and @few_shot) to invoke LLM capabilities without provider-specific logic.
Provider-Specific Implementation Details
Each engine handles provider quirks internally while presenting a uniform interface.
OpenAI Integration
The GPTXChatEngine in engine_openai_gptX_chat.py constructs JSON payloads compatible with the OpenAI Chat Completions API. It processes vision tokens using the <<vision:url>> syntax, converting these into OpenAI's image_url message format. Token limits are enforced through the inherited api_max_context_tokens() method from the OpenAI mix-in, which returns 128,000 for GPT-4o models.
Anthropic Integration
ClaudeXChatEngine in engine_anthropic_claudeX_chat.py utilizes the native anthropic Python client. It implements token counting using client.messages.count_tokens() to validate context window usage before sending requests. The engine handles Claude's unique streaming response format, extracting content blocks from message_stop events. The mix-in provides capability flags like supports_adaptive_thinking() to conditionally enable extended reasoning modes.
Google Gemini Integration
GeminiXReasoningEngine in engine_google_geminiX_reasoning.py interfaces with Google's google.generativeai library. It handles complex multimodal workflows by uploading media files (images, PDFs, video, audio) via genai.upload_file(), then constructing genai.types.Part objects to include these in the generation request. The engine supports Gemini's 1 million token context window (1,048,576 tokens) as defined in the Google mix-in, making it suitable for long-document analysis.
Practical Usage Examples
The following examples demonstrate how SymbolicAI LLM provider abstraction enables provider-agnostic code.
Zero-shot decorator with automatic provider routing
from symai import symai
from symai.core import zero_shot
@zero_shot(prompt="Summarize the following text:\n{{input}}")
def summarize(input: str) -> str:
...
text = "Symbolic AI blends classical Python with LLM reasoning."
print(summarize(text))
This function executes via GPTXChatEngine, ClaudeXChatEngine, or GeminiXReasoningEngine depending solely on the NEUROSYMBOLIC_ENGINE_MODEL value in symai.config.json.
Inspecting the active engine at runtime
from symai.functional import EngineRepository
engine = EngineRepository.get_active()
print(f"Active engine: {engine.__class__.__name__}")
print(f"Context window: {engine.api_max_context_tokens()}")
This returns the concrete engine instance (e.g., ClaudeXChatEngine) and its specific token limits as defined in the corresponding mix-in.
Multimodal input across providers
from symai.core import zero_shot
@zero_shot(prompt="Describe the image and answer: {{question}}")
def analyze_image(image_prompt: str, question: str) -> str:
...
# Vision token syntax works across all engines
prompt = "<<vision:https://example.com/cat.jpg:>> What breed is the cat?"
print(analyze_image(prompt, ""))
The <<vision:...>> token is parsed differently by each engine—OpenAI uses image_url fields, Anthropic converts images to base64, and Gemini uses genai.upload_file() and genai.types.Part objects—yet the user interface remains identical.
Summary
- SymbolicAI uses a mix-in and engine architecture to abstract OpenAI, Anthropic, and Google Gemini implementations.
- Mix-ins (
symai/backend/mixin/openai.py,anthropic.py,google.py) store provider-specific constants like token limits and model lists. - Engines (
GPTXChatEngine,ClaudeXChatEngine,GeminiXReasoningEngine) inherit from mix-ins and implement concrete API logic, payload construction, and response parsing. - Runtime selection occurs via
EngineRepositoryinsymai/functional.py, which matches theNEUROSYMBOLIC_ENGINE_MODELconfiguration value to the appropriate engine'sid()method. - This design enables provider-agnostic code—decorators like
@zero_shotwork identically regardless of whether the backend is OpenAI, Anthropic, or Google.
Frequently Asked Questions
How do I switch between OpenAI and Anthropic models in SymbolicAI?
Change the NEUROSYMBOLIC_ENGINE_MODEL value in your symai.config.json file. Set it to an OpenAI model ID (e.g., gpt-4o) to use GPTXChatEngine, or a Claude model ID (e.g., claude-3-5-sonnet-latest) to use ClaudeXChatEngine. The EngineRepository automatically instantiates the correct engine on the next call.
What is the maximum context window when using Google Gemini with SymbolicAI?
The GeminiXReasoningEngine supports a context window of 1,048,576 tokens (1 million tokens) for Gemini 2.5 models, as defined in symai/backend/mixin/google.py. This is significantly larger than the default OpenAI context windows and enables processing of very long documents or extensive codebases in a single prompt.
Does SymbolicAI support multimodal inputs across all providers?
Yes. SymbolicAI provides a unified vision syntax (<<vision:url>>) that works across OpenAI, Anthropic, and Google Gemini engines. Each engine implements provider-specific handling: OpenAI uses image_url fields, Anthropic converts images to base64, and Gemini uses genai.upload_file() and genai.types.Part objects. The user interface remains identical regardless of the backend.
Where are the API keys configured for different LLM providers?
API keys are stored in the symai.config.json configuration file, loaded by symai/backend/settings.py into the SYMAI_CONFIG singleton. Each provider uses a specific key field: OpenAI uses NEUROSYMBOLIC_ENGINE_API_KEY, while Anthropic and Google similarly read from their respective configuration entries within the same file. The EngineRepository passes these credentials when instantiating the concrete engine classes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →