OpenAI-compatible only: why we didn’t pick a direct Anthropic SDK
One interface, many providers — vLLM, OpenRouter, Together — and a deliberate non-dependency.

DEINO calls LLMs through one interface: the OpenAI-compatible chat completions API. That interface covers OpenAI, vLLM, OpenRouter, and Together — and it is a deliberate non-dependency on a direct Anthropic SDK. The choice is not about which model is best. It is about which contract keeps the platform provider-agnostic.
The sisters produce forecasts. The forecasts are only as defensible as the substrate is portable. If the platform is welded to one provider’s SDK, the manifest survives a model swap but the codebase does not — and a regulated buyer reading the architecture sees a vendor lock-in that a compliance posture cannot absorb. The OpenAI-compatible interface is the narrowest contract that covers the most providers, and that is the one we picked.
One interface, many providers
async-openai is the crate. It speaks the OpenAI chat completions wire format, which vLLM, OpenRouter, and Together all implement. One client, configured by environment variables — OPENAI_API_KEY, OPENROUTER_API_KEY, VLLM_BASE_URL, ANTHROPIC_API_KEY — routes to whichever provider the deployment prefers. There is no per-provider crate, no per-provider branch in the call path. The provider is a configuration; the code does not know which one it is talking to.
Why no direct Anthropic SDK
A direct Anthropic SDK would be a second interface, a second dependency, a second place where the call path branches. Every branch is a place where the manifest has to record which interface in addition to which model, and every branch is a place where a model swap becomes a code change, not a config change. The OpenAI-compatible interface already covers the providers we care about — including Anthropic via OpenRouter — without a second contract. The non-dependency is the point: one interface, zero branches, the provider is env.

Every branch in the call path is a place where a model swap becomes a code change. One interface, zero branches — the provider is env, not code.
Provider-agnostic as an audit posture
Provider-agnostic is not just an engineering convenience; it is an audit posture. A regulated buyer asks: can I swap the live model and keep my history? The manifest pins the model by hash, and the code routes through one interface — so swapping the provider is an env change, the historical manifest still verifies, and the chain does not break. Vendor lock-in is a compliance risk because it makes the history hostage to the vendor. One interface dissolves that. We are pre-revenue, building the POC; the interface runs, and the calibration that would make any provider’s output trustworthy is gated (Gate 1b) regardless of which provider is behind it.
- One interface (OpenAI-compatible chat completions) covers OpenAI, vLLM, OpenRouter, Together — and Anthropic via OpenRouter.
- No per-provider SDK, no per-provider branch — the provider is an environment variable.
- Provider-agnostic is an audit posture — swap the live model, the manifest and the codebase both survive.
- Vendor lock-in is a compliance risk; one interface is how the architecture refuses it.
The deliberate non-dependency
Calling the absence of a direct Anthropic SDK a non-dependency is precise. It is not that we could not add one; it is that we chose not to, because the cost of the second interface is higher than the cost of routing Anthropic through OpenRouter. The cost is a branch in the call path, a second contract to maintain, a second place where the manifest has to explain itself. The benefit — direct access to a vendor’s native API — does not outweigh it, because the OpenAI-compatible interface already reaches the models. The non-dependency is the discipline.
Provider-agnostic is a property of the substrate, not a feature of the product. You write it into the architecture by refusing the second interface, not by promising to swap someday.
— architecture note