# How SymbolicAI Handles Multiple LLM Providers: OpenAI, Anthropic, and Google

> SymbolicAI seamlessly integrates OpenAI, Anthropic, and Google LLMs. Discover how its mix-in and engine architecture routes calls without altering your application code.

- Repository: [ExtensityAI/symbolicai](https://github.com/extensityai/symbolicai)
- Tags: how-to-guide
- Published: 2026-03-01

---

**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`](https://github.com/extensityai/symbolicai/blob/main/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`](https://github.com/extensityai/symbolicai/blob/main/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`](https://github.com/extensityai/symbolicai/blob/main/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.py`](https://github.com/extensityai/symbolicai/blob/main/engine_openai_gptX_chat.py) implements `GPTXChatEngine`, handling OpenAI chat completions, vision image patterns (`<<vision:...>>`), and token limit enforcement.
- [`engine_anthropic_claudeX_chat.py`](https://github.com/extensityai/symbolicai/blob/main/engine_anthropic_claudeX_chat.py) implements `ClaudeXChatEngine`, using `anthropic.Anthropic` client, token counting via `client.messages.count_tokens()`, and Claude-specific streaming event formatting.
- [`engine_google_geminiX_reasoning.py`](https://github.com/extensityai/symbolicai/blob/main/engine_google_geminiX_reasoning.py) implements `GeminiXReasoningEngine`, interfacing with `google.generativeai` (`genai`), uploading multimodal media, and constructing `genai.types.Part` objects for content generation.

## Configuration and Runtime Selection

The active provider is determined at runtime through the configuration system in [`symai/backend/settings.py`](https://github.com/extensityai/symbolicai/blob/main/symai/backend/settings.py). The `SYMAI_CONFIG` singleton loads [`symai.config.json`](https://github.com/extensityai/symbolicai/blob/main/symai.config.json) and reads the `NEUROSYMBOLIC_ENGINE_MODEL` value.

The `EngineRepository` class in [`symai/functional.py`](https://github.com/extensityai/symbolicai/blob/main/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 to `GPTXChatEngine`
- `claude...` routes to `ClaudeXChatEngine`
- `gemini-...` routes to `GeminiXReasoningEngine`

When `EngineRepository.get_active()` is called, it returns the concrete engine instance matching the current configuration, allowing the decorators in [`symai/core.py`](https://github.com/extensityai/symbolicai/blob/main/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`](https://github.com/extensityai/symbolicai/blob/main/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`](https://github.com/extensityai/symbolicai/blob/main/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`](https://github.com/extensityai/symbolicai/blob/main/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

```python
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`](https://github.com/extensityai/symbolicai/blob/main/symai.config.json).

### Inspecting the active engine at runtime

```python
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

```python
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`](https://github.com/extensityai/symbolicai/blob/main/symai/backend/mixin/openai.py), [`anthropic.py`](https://github.com/extensityai/symbolicai/blob/main/anthropic.py), [`google.py`](https://github.com/extensityai/symbolicai/blob/main/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 `EngineRepository` in [`symai/functional.py`](https://github.com/extensityai/symbolicai/blob/main/symai/functional.py), which matches the `NEUROSYMBOLIC_ENGINE_MODEL` configuration value to the appropriate engine's `id()` method.
- This design enables **provider-agnostic code**—decorators like `@zero_shot` work 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`](https://github.com/extensityai/symbolicai/blob/main/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`](https://github.com/extensityai/symbolicai/blob/main/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`](https://github.com/extensityai/symbolicai/blob/main/symai.config.json) configuration file, loaded by [`symai/backend/settings.py`](https://github.com/extensityai/symbolicai/blob/main/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.