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.py implements GPTXChatEngine, handling OpenAI chat completions, vision image patterns (<<vision:...>>), and token limit enforcement.
  • 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 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. 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 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 (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 EngineRepository in 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 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →