Back to flin
flin

Passerelle IA : 8 fournisseurs, une seule API

Comment la passerelle IA de FLIN fournit une interface unifiée vers OpenAI, Anthropic, DeepInfra, Google, Mistral, Cohere, Groq et les modèles locaux -- changez de fournisseur en modifiant une ligne de configuration.

Juste A. Gnimavo (Thales) & Claude | March 26, 2026 6 min flin
EN/ FR/ ES
flinaigatewayprovidersapi

Le paysage de l'IA en 2026 est fragmenté. OpenAI a GPT-4o. Anthropic a Claude. Google a Gemini. Mistral a ses modèles open-weight. Cohere se spécialise dans les embeddings. Groq offre l'inférence à une vitesse extraordinaire. DeepInfra héberge des dizaines de modèles open source. Chaque fournisseur a son propre format d'API, son propre schéma d'authentification, son propre modèle de tarification et son propre SDK.

Une application FLIN qui utilise l'IA ne devrait pas être verrouillée sur un seul fournisseur. Si OpenAI augmente ses prix, vous devriez pouvoir basculer vers DeepInfra. Si Anthropic ajoute une fonctionnalité dont vous avez besoin, vous devriez pouvoir l'essayer sans réécrire votre code. Si vous voulez exécuter localement pour la confidentialité, vous devriez pouvoir utiliser un modèle local.

La passerelle IA de FLIN fournit une interface unifiée vers huit fournisseurs. Votre code FLIN appelle ai_complete(), ai_embed() et ai_chat(). La passerelle route la requête vers le fournisseur configuré, traduit le format d'API et retourne une réponse normalisée. Changer de fournisseur se fait en une ligne dans flin.config.

L'API unifiée

Trois fonctions couvrent les opérations IA les plus courantes :

flin// Complétion de texte
response = ai_complete("Summarize this article: " + article.content, {
    max_tokens: 200,
    temperature: 0.3
})

// Complétion de chat
response = ai_chat([
    { role: "system", content: "You are a helpful assistant." },
    { role: "user", content: user_message }
])

// Embeddings
vector = ai_embed("comfortable office chair for long work sessions")

Ces fonctions marchent quel que soit le fournisseur configuré. L'API est la même que vous utilisiez GPT-4o, Claude, Gemini ou un modèle Llama local.

Configuration du fournisseur

Le fournisseur IA est configuré dans flin.config :

flin// flin.config
ai {
    provider = "openai"
    model = "gpt-4o-mini"
    embedding_model = "text-embedding-3-small"
    api_key = env("OPENAI_API_KEY")
}

Basculer vers un autre fournisseur :

flin// Anthropic
ai {
    provider = "anthropic"
    model = "claude-3-haiku"
    api_key = env("ANTHROPIC_API_KEY")
}

// DeepInfra
ai {
    provider = "deepinfra"
    model = "meta-llama/Meta-Llama-3-8B-Instruct"
    api_key = env("DEEPINFRA_API_KEY")
}

// Groq (pour la vitesse)
ai {
    provider = "groq"
    model = "llama3-70b-8192"
    api_key = env("GROQ_API_KEY")
}

// Local (pas de clé API nécessaire)
ai {
    provider = "local"
    model = "llama3"
    endpoint = "http://localhost:11434"
}

Le code de l'application ne change pas. Le même appel ai_complete() fonctionne avec chaque fournisseur.

Les huit fournisseurs pris en charge

FournisseurModèlesIdéal pour
OpenAIGPT-4o, GPT-4o MiniUsage général, vision
AnthropicClaude 3 Opus, Sonnet, HaikuContexte long, raisonnement
GoogleGemini Pro, Gemini FlashMultimodal, vitesse
MistralMistral Large, Medium, SmallRésidence des données européenne
CohereCommand R+, Embed v3Embeddings, RAG
GroqLlama 3, MixtralUltra-faible latence
DeepInfra50+ modèles openOptimisation des coûts
LocalOllama, llama.cppConfidentialité, hors ligne

Implémentation de la passerelle

La passerelle traduit entre le format unifié de FLIN et l'API spécifique de chaque fournisseur :

rustpub struct AiGateway {
    provider: Box<dyn AiProvider>,
    config: AiConfig,
}

pub trait AiProvider: Send + Sync {
    async fn complete(&self, prompt: &str, opts: &CompletionOptions) -> Result<String, AiError>;
    async fn chat(&self, messages: &[Message], opts: &ChatOptions) -> Result<String, AiError>;
    async fn embed(&self, text: &str) -> Result<Vec<f32>, AiError>;
}

impl AiGateway {
    pub fn new(config: &AiConfig) -> Result<Self, AiError> {
        let provider: Box<dyn AiProvider> = match config.provider.as_str() {
            "openai" => Box::new(OpenAiProvider::new(&config)?),
            "anthropic" => Box::new(AnthropicProvider::new(&config)?),
            "google" => Box::new(GoogleProvider::new(&config)?),
            "mistral" => Box::new(MistralProvider::new(&config)?),
            "cohere" => Box::new(CohereProvider::new(&config)?),
            "groq" => Box::new(GroqProvider::new(&config)?),
            "deepinfra" => Box::new(DeepInfraProvider::new(&config)?),
            "local" => Box::new(LocalProvider::new(&config)?),
            other => return Err(AiError::UnknownProvider(other.into())),
        };

        Ok(Self { provider, config })
    }
}

Le fournisseur Anthropic traduit vers le format d'Anthropic (qui utilise system comme paramètre séparé, pas comme message) :

rustimpl AiProvider for AnthropicProvider {
    async fn chat(&self, messages: &[Message], opts: &ChatOptions) -> Result<String, AiError> {
        let system = messages.iter()
            .find(|m| m.role == "system")
            .map(|m| m.content.clone());

        let user_messages: Vec<_> = messages.iter()
            .filter(|m| m.role != "system")
            .map(|m| json!({ "role": m.role, "content": m.content }))
            .collect();

        let mut body = json!({
            "model": self.model,
            "messages": user_messages,
            "max_tokens": opts.max_tokens.unwrap_or(1024),
        });

        if let Some(sys) = system {
            body["system"] = json!(sys);
        }

        // ... envoyer la requête à l'API Anthropic
    }
}

Chaînes de repli

FLIN prend en charge la configuration de repli pour la haute disponibilité :

flinai {
    provider = "openai"
    model = "gpt-4o-mini"
    api_key = env("OPENAI_API_KEY")

    fallback {
        provider = "deepinfra"
        model = "meta-llama/Meta-Llama-3-8B-Instruct"
        api_key = env("DEEPINFRA_API_KEY")
    }
}

Si le fournisseur principal échoue (limite de débit, erreur API, timeout), la passerelle réessaie automatiquement avec le fournisseur de repli. Le code de l'application n'est pas au courant du basculement.

Optimisation des coûts

Les différents fournisseurs ont des tarifications radicalement différentes :

FournisseurModèleCoût par 1M tokens
OpenAIGPT-4o Mini0,15 $ entrée / 0,60 $ sortie
AnthropicClaude 3 Haiku0,25 $ entrée / 1,25 $ sortie
DeepInfraLlama 3 8B0,06 $ entrée / 0,06 $ sortie
GroqLlama 3 70B0,59 $ entrée / 0,79 $ sortie

Pour la traduction de requêtes du moteur d'intentions, où la tâche est relativement simple, un modèle plus petit comme Llama 3 8B sur DeepInfra peut être 10 fois moins cher que GPT-4o avec une précision comparable. La passerelle de FLIN rend ce changement trivial.

Pourquoi une passerelle, pas une bibliothèque

L'alternative à une passerelle est des bibliothèques spécifiques aux fournisseurs : openai-sdk, anthropic-sdk, google-ai-sdk. Chacune avec sa propre API, sa propre gestion d'erreurs, ses propres types. Changer de fournisseur signifie réécrire chaque appel IA dans votre application.

La passerelle de FLIN fait de la sélection du fournisseur une décision de configuration, pas une décision de code. Votre logique applicative exprime ce qu'elle veut (« résumer ce texte », « classifier ce ticket », « embedder cette requête »), et la passerelle gère comment l'obtenir du fournisseur configuré.

Cette séparation des préoccupations est particulièrement importante pour le moteur d'intentions et la recherche sémantique, qui sont des fonctionnalités centrales du langage. Elles ne devraient pas cesser de fonctionner parce que vous avez basculé d'OpenAI à Anthropic.

Dans le prochain article, nous plongeons dans l'intégration FastEmbed -- comment FLIN génère des embeddings localement sans aucun appel API, permettant la recherche sémantique hors ligne et les applications privacy-first.


Ceci est la partie 118 de la série « Comment nous avons construit FLIN », documentant comment un CEO à Abidjan et un CTO IA ont conçu et construit un langage de programmation à partir de zéro.

Navigation de la série : - [117] Recherche sémantique et stockage vectoriel - [118] Passerelle IA : 8 fournisseurs, une seule API (vous êtes ici) - [119] Intégration FastEmbed pour les embeddings - [120] RAG : récupération, reclassement et attribution des sources

Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles

Thales & Claude thales

Treize agents, quarante-trois minutes : la première session Workflow de Claude Fable 5, et ce qu'un script d'orchestration déterministe change aux builds multi-agents

Un prompt, treize agents, quarante-trois minutes : la première session de production avec Claude Fable 5 et l'outil Workflow de Claude Code a livré un site web de production complet de sept pages plus un endpoint backend de capture de leads, en un seul commit. Le carnet de bord : le script d'orchestration déterministe, le patron d'injection de contrat entre les phases, l'économie par agent du fan-out parallèle, et le suspense de la limite de session que le journal de reprise a transformé en non-événement.

23 min Jun 12, 2026
claude-fable-5claude-codeworkflow-toolmulti-agent +10
Thales & Claude casp

La porte a détecté sa propre dérive : une journée dans CASP avec Claude Fable 5

Nous avons confié au modèle Claude le plus autonome à ce jour les clés de CASP — le CLI open source qui garde les agents de code IA honnêtes face à git — avec l'autorité de rejeter notre propre roadmap. Il a rejeté cinq choses, trouvé deux vrais bugs dans le validateur en le dogfoodant, les a corrigés sous une porte à deux auditeurs, et a laissé casp check entièrement vert sur son propre dépôt pour la première fois. CASP 0.3.0 en est le résultat.

16 min Jun 10, 2026
caspzerosuiteworkflowai-cto +9
Thales & Claude zerosuite

La transplantation du CASP : comment la discipline des six fichiers est passée de Conductor à un ERP transport anti-fraude, ce que la compétence /next ajoute quand l'opérateur tape juste « next », et pourquoi le coût d'une dérive du CASP grimpe quand le projet, c'est l'argent des autres

La discipline du CASP qui a piloté trente-cinq sessions de Conductor est agnostique au produit. Le carnet de bord de sa transplantation sur KASSIA, un ERP transport anti-fraude pour un exploitant de flotte en Côte d'Ivoire : ce qui a migré, ce qui n'a pas migré (le validateur sur mesure — et ce que son absence coûte), ce que la compétence /next ajoute quand l'opérateur tape un seul mot, et là où le CASP s'arrête — le bug de déploiement qu'il ne pouvait pas voir parce qu'il enregistre l'intention, pas la réalité de l'infrastructure.

23 min Jun 8, 2026
kassiaerp-kassia-transport-logistiquezerosuiteCASP +15