One codebase, any AI provider: why we build on Neuron AI
4 min read
Our three open-source projects (CVolve, CVolve Template Maker and Plate Plan) all use AI. None of them is tied to one AI company. You choose the provider: Anthropic Claude, OpenAI, Google Gemini, Mistral, DeepSeek, xAI Grok, a local Ollama model, or any OpenAI-compatible server such as OpenRouter, Groq or LM Studio.
We did not write eight integrations to get there. All three projects are built on Neuron AI, an open-source PHP framework for building AI agents.
Why not just call one API?
Calling a single provider's API directly is the quickest way to start. It also creates problems later:
- Lock-in. Every provider has its own request format, message types and tool-calling rules. Switching means rewriting code.
- Privacy. Some people cannot send their data to a cloud service. A CV or a family's meal plan is personal data, and for some users a model on their own computer is the only acceptable option.
- Cost and choice. Prices and model quality change every few months. Users should be able to follow the best option without waiting for us.
Neuron AI gives us one interface for all of these providers: messages, tools and agents work the same way whichever model is behind them.
The pattern: a small provider factory
Each project has a ProviderFactory that reads a few environment variables and returns a Neuron AI provider. This is a shortened version of the one in CVolve:
return match ($provider) { 'gemini' => new Gemini(key: $key, model: $model), 'openai' => new OpenAI(key: $key, model: $model), 'anthropic' => new Anthropic(key: $key, model: $model), 'ollama' => new Ollama(url: $baseUrl, model: $model), 'mistral' => new Mistral(key: $key, model: $model), 'deepseek' => new Deepseek(key: $key, model: $model), 'grok' => new Grok(key: $key, model: $model), 'openai_like' => new OpenAILike(baseUri: $baseUrl, key: $key, model: $model), };
CVolve and Plate Plan use the same variables, so one .env.local works for both:
AI_PROVIDER=anthropic AI_MODEL=claude-sonnet-5-5 AI_API_KEY=...
Change AI_PROVIDER to ollama and nothing leaves your machine. No other code changes.
Agents with tools
Picking a provider is only half the job. The interesting part is letting the model do things: add a meal to Wednesday, rewrite the bullets of one job, translate a CV into Arabic.
Neuron AI handles this with agents and tools. We describe each action as a tool with a name, a description and typed parameters. The agent decides which tools to call, Neuron AI runs them, and the model sees the results:
$agent = Agent::make() ->setAiProvider($this->providers->make()) ->setInstructions($systemPrompt) ->setTools($tools); $reply = $agent->chat($messages)->getMessage()?->getContent();
In Plate Plan, "Plan meals for this week" becomes a series of tool calls that fill the board while you watch. In CVolve, the same mechanism powers the editor's AI assistant. Every tool that changes a CV creates a proposal instead of writing directly, so you review a diff and choose Apply or Discard.
Bring your own key, safely
CVolve Template Maker goes one step further. It is a multi-user studio, so each designer connects their own AI accounts in the app instead of in a config file. The keys are encrypted at rest with libsodium (sodium_crypto_secretbox), are never shown again after saving, and are only sent to the provider the designer picked.
Testable, and optional
Two details matter a lot in practice:
- Tests do not call real models. Neuron AI includes a fake provider, so our test suites can script the model's answers and check what the app does with them. This keeps the tests fast, free and repeatable.
- AI is never required. Without a configured provider, Plate Plan falls back to local planning and evaluation rules, and CVolve still works as a complete CV builder. AI is an assistant, not a dependency.
Takeaway
If you are adding AI to a PHP application, keep the choice of model out of your business logic. A thin factory over a framework like Neuron AI costs very little, and it gives your users freedom of choice, a private local option and an easy path to the next better model.
All three projects are MIT licensed. Read the code, try them, and contribute on GitHub.