Fournisseurs de modèles (cloud)

ADK-Rust prend en charge plusieurs fournisseurs LLM cloud via la crate adk-model. Tous les fournisseurs implémentent le trait Llm, ce qui les rend interchangeables dans vos agents.

Vue d’ensemble

┌─────────────────────────────────────────────────────────────────────┐
│                     Cloud Model Providers                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   • Gemini (Google)    ⭐ Default    - Multimodal, large context    │
│   • OpenAI (GPT-5)    🔥 Popular    - Best ecosystem               │
│   • Anthropic (Claude) 🧠 Smart      - Best reasoning               │
│   • DeepSeek           💭 Thinking   - Chain-of-thought, cheap      │
│   • Groq               ⚡ Ultra-Fast  - Fastest inference           │
│                                                                     │
│   For local/offline models, see:                                    │
│   • Ollama     → ollama.md                                          │
│   • mistral.rs → mistralrs.md                                       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Comparaison rapide

FournisseurIdéal pourRapiditéCoûtFonctionnalité clé
GeminiUsage général⚡⚡⚡💰Multimodal, grand contexte, raisonnement
OpenAIFiabilité⚡⚡💰💰Meilleur écosystème
AnthropicRaisonnement complexe⚡⚡💰💰Le plus sûr et le plus réfléchi
DeepSeekRaisonnement en chaîne⚡⚡💰Mode réflexion, économique
GroqVitesse critique⚡⚡⚡⚡💰Inférence la plus rapide

Étape 1 : Installation

Ajoutez les fournisseurs dont vous avez besoin à votre Cargo.toml :

[dependencies]
# Pick one or more providers:
adk-model = { version = "2.1.0", features = ["gemini"] }        # Google Gemini (default)
adk-model = { version = "2.1.0", features = ["openai"] }        # OpenAI GPT-5
adk-model = { version = "2.1.0", features = ["anthropic"] }     # Anthropic Claude
adk-model = { version = "2.1.0", features = ["deepseek"] }      # DeepSeek
adk-model = { version = "2.1.0", features = ["groq"] }          # Groq (ultra-fast)

# Or all cloud providers at once:
adk-model = { version = "2.1.0", features = ["all-providers"] }

Étape 2 : Définir votre clé API

export GOOGLE_API_KEY="your-key"      # Gemini
export OPENAI_API_KEY="your-key"      # OpenAI
export ANTHROPIC_API_KEY="your-key"   # Anthropic
export DEEPSEEK_API_KEY="your-key"    # DeepSeek
export GROQ_API_KEY="your-key"        # Groq

Normalisation des schémas

Chaque fournisseur normalise automatiquement les schémas d’outils MCP au moment de la requête. Vous n’avez rien à faire — cela fonctionne de manière transparente. Mais voici ce qui se passe en coulisses :

FournisseurAdaptateur de schémaComportement
GeminiGeminiSchemaAdapterAgressif : résout $ref, regroupe les combineurs et supprime les mots-clés non pris en charge
OpenAI (strict)OpenAiStrictSchemaAdapterPréserve la structure et ajoute additionalProperties: false
OpenAIOpenAiSchemaAdapterCorrections minimales sans risque
AnthropicAnthropicSchemaAdapterPresque sans modification
DeepSeekGenericSchemaAdapterTransformations prudentes et sûres
OllamaGenericSchemaAdapterTransformations prudentes et sûres

Accédez programmatiquement à l’adaptateur via le trait Llm :

use adk_core::{Llm, SchemaAdapter};

let adapter = model.schema_adapter();
let normalized = adapter.normalize_schema(raw_schema);

Consultez Normalisation du schéma pour obtenir la documentation complète.


Gemini (Google) ⭐ Par défaut

Idéal pour : tâches générales, tâches multimodales, documents volumineux

Points forts :

  • 🖼️ Multimodalité native (images, vidéo, audio, PDF)
  • 📚 Fenêtre de contexte allant jusqu’à 2 millions de tokens
  • 🧠 Mode réflexion : basé sur des niveaux (Gemini 3) et sur un budget (Gemini 2.5), avec des signatures de réflexion
  • 💰 Tarification compétitive
  • ⚡ Inférence rapide

Exemple complet fonctionnel

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = GeminiModel::new(&api_key, "gemini-3.7-flash")?;

    let agent = LlmAgentBuilder::new("gemini_assistant")
        .description("Gemini-powered assistant")
        .instruction("You are a helpful assistant powered by Google Gemini. Be concise.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

Modèles disponibles

ModèleDescriptionContexte
gemini-3.7-flashModèle d’agent équilibré par défaut1M tokens
gemini-3.6-flashGénération équilibrée précédente1M tokens
gemini-3.5-flash-liteRoutage économique et tâches à haut volume1M tokens
gemini-3.1-pro-previewRaisonnement avancé en préversion2M tokens

Mode de réflexion

Les modèles Gemini 3 prennent en charge la réflexion basée sur des niveaux, tandis que Gemini 2.5 utilise une réflexion basée sur un budget. Lors de l’utilisation du mode de réflexion avec l’appel de fonctions, les modèles Gemini 2.5+ et 3.x renvoient des valeurs thoughtSignature qui doivent être répercutées lors des tours suivants afin de préserver le contexte du raisonnement. ADK-Rust gère cela automatiquement — les signatures sont sérialisées lorsqu’elles sont présentes et omises lorsque None.

use adk_gemini::{Gemini, ThinkingLevel};

// Gemini 3: level-based thinking
let response = client.generate_content()
    .with_user_message("Solve this step by step")
    .with_thinking_level(ThinkingLevel::High)
    .with_thoughts_included(true)
    .execute().await?;

// Gemini 2.5: budget-based thinking
let response = client.generate_content()
    .with_user_message("Solve this step by step")
    .with_thinking_budget(2048)
    .with_thoughts_included(true)
    .execute().await?;

Exemple de sortie

👤 User: What's in this image? [uploads photo of a cat]

🤖 Gemini: I can see a fluffy orange tabby cat sitting on a windowsill. 
The cat appears to be looking outside, with sunlight illuminating its fur. 
It has green eyes and distinctive striped markings typical of tabby cats.

Idéal pour : applications en production, performances fiables, capacités étendues

Points forts :

  • 🏆 Standard du secteur
  • 🔧 Excellente prise en charge des appels d’outils et de fonctions
  • 📖 Meilleure documentation et meilleur écosystème
  • 🎯 Sorties cohérentes et prévisibles
  • 📋 Sortie structurée avec validation du schéma JSON
  • 🧠 Contrôle de l’effort de raisonnement pour les modèles de raisonnement GPT-5.6
  • 🆕 Réponses API — client dédié à /v1/responses avec résumés du raisonnement, outils intégrés et état côté serveur

Exemple complet fonctionnel

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("OPENAI_API_KEY")?;
    let model = OpenAIClient::new(OpenAIConfig::new(&api_key, "gpt-5.6-terra"))?;

    let agent = LlmAgentBuilder::new("openai_assistant")
        .description("OpenAI-powered assistant")
        .instruction("You are a helpful assistant powered by OpenAI GPT-5. Be concise.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

Sortie structurée (schéma JSON)

OpenAI prend en charge une sortie JSON garantie via output_schema. ADK-Rust relie automatiquement cette fonctionnalité à OpenAI et à son response_format API :

use adk_rust::prelude::*;
use serde_json::json;
use std::sync::Arc;

let model = OpenAIClient::new(OpenAIConfig::new(&api_key, "gpt-5.6-terra"))?;

let agent = LlmAgentBuilder::new("data_extractor")
    .model(Arc::new(model))
    .instruction("Extract person information from the text.")
    .output_schema(json!({
        "type": "object",
        "properties": {
            "name": { "type": "string" },
            "age": { "type": "number" },
            "email": { "type": "string" }
        },
        "required": ["name", "age"]
    }))
    .build()?;

// Response is guaranteed to be valid JSON matching the schema

Pour le mode strict avec des objets imbriqués, incluez additionalProperties: false à chaque niveau :

.output_schema(json!({
    "type": "object",
    "properties": {
        "title": { "type": "string" },
        "metadata": {
            "type": "object",
            "properties": {
                "author": { "type": "string" },
                "tags": { "type": "array", "items": { "type": "string" } }
            },
            "required": ["author"],
            "additionalProperties": false  // Required for nested objects
        }
    },
    "required": ["title", "metadata"],
    "additionalProperties": false  // Auto-injected at root level
}))

Effort de raisonnement

Pour les modèles de raisonnement OpenAI, contrôlez la quantité d’effort de raisonnement appliquée par le modèle :

use adk_model::openai::{OpenAIClient, OpenAIConfig, OpenAIReasoningEffort};

let config = OpenAIConfig::new(&api_key, "gpt-5.6-terra");
let model = OpenAIClient::new_with_reasoning_effort(
    config,
    OpenAIReasoningEffort::XHigh,
)?;

Le vocabulaire complet est None, Minimal, Low, Medium, High, XHigh, et Max ; la disponibilité dépend du modèle et de API. GPT-5.6 Chat Completions prend en charge jusqu’à XHigh ; utilisez OpenAIResponsesClient pour Max. Le ReasoningEffort original à trois valeurs API reste disponible pour assurer la compatibilité ascendante.

OpenAI-Compatible Local APIs

Utilisez OpenAIConfig::compatible() pour vous connecter à des serveurs locaux (Ollama, vLLM, LM Studio) :

// Ollama exposes OpenAI-compatible API at /v1
let config = OpenAIConfig::compatible(
    "not-needed",                      // API key (ignored by Ollama)
    "http://localhost:11434/v1",       // Base URL
    "llama3.2"                         // Model name
);
let model = OpenAIClient::new(config)?;

Remarque : La sortie structurée (output_schema) nécessite la prise en charge par le backend. Le OpenAI natif la prend entièrement en charge ; les serveurs locaux peuvent offrir une prise en charge limitée.

Gemini via le Endpoint Compatible avec OpenAI

Les modèles Gemini sont accessibles via le format de transmission Chat Completions de OpenAI à https://generativelanguage.googleapis.com/v1beta/openai. Utilisez le préréglage OpenAICompatibleConfig::gemini(...) (dans la fonctionnalité openai) avec un GEMINI_API_KEY pour exécuter Gemini via le même client compatible avec OpenAI que celui que vous utilisez pour tous les autres fournisseurs :

use adk_model::openai_compatible::{OpenAICompatible, OpenAICompatibleConfig};

let api_key = std::env::var("GEMINI_API_KEY")?;
let model = OpenAICompatible::new(
    OpenAICompatibleConfig::gemini(api_key, "gemini-3.5-flash"),
)?;

Cette voie prend en charge le chat, la diffusion en continu, les appels de fonctions, la sortie structurée et l’effort de raisonnement (le reasoning_effort de OpenAI correspond aux niveaux et budgets de réflexion de Gemini). Les options propres à Gemini — par exemple thinking_config avec include_thoughts, ou cached_content — sont transmises via la map extensions["openai"]["extra_body"]["google"] de la requête, que le client fusionne verbatim dans le corps de la requête.

Quand utiliser ceci plutôt que GeminiModel : Pour les fonctionnalités Gemini natives (outils côté serveur, API Interactions, ThinkingConfig natif et ergonomie axée sur le multimodal), préférez GeminiModel. Utilisez le préréglage compatible avec OpenAI lorsque vous souhaitez un client unique et uniforme entre les fournisseurs.

Exemples (nécessitent GEMINI_API_KEY ou GOOGLE_API_KEY) :

# Direct client: chat, reasoning effort, extra_body thinking, streaming,
# function calling, structured output.
cargo run -p adk-model --features openai --example gemini_openai_compat

# The same compat client driving a normal LlmAgent in a Runner.
# (Lives in adk-agent: it exercises the agent layer, which sits above adk-model.)
cargo run -p adk-agent --example gemini_openai_compat_agent

API d’effort de raisonnement héritée

L’ReasoningEffort API original à trois niveaux reste disponible pour assurer la compatibilité :

use adk_model::openai::{OpenAIClient, OpenAIConfig, ReasoningEffort};

let config = OpenAIConfig::new(&api_key, "gpt-5")
    .with_reasoning_effort(ReasoningEffort::High);
let model = OpenAIClient::new(config)?;

Niveaux disponibles : Low (le plus rapide), Medium (équilibré), High (le plus approfondi).

Modèles disponibles

ModèleDescriptionContexte
gpt-5.6-terraValeur par défaut équilibrée pour les agents en production256K jetons
gpt-5.6-solRaisonnement et programmation haut de gamme256K jetons
gpt-5.6-lunaCharges de travail à volume élevé et économiques128K tokens
gpt-5.6Alias phare256K tokens

Exemple de sortie

👤 User: Write a haiku about Rust programming

🤖 GPT-5: Memory so safe,
Ownership guards every byte—
Compiler, my friend.

Anthropic (Claude) 🧠 Intelligent

Idéal pour : raisonnement complexe, applications critiques en matière de sécurité, documents longs

Points forts :

  • 🧠 Capacité de raisonnement exceptionnelle
  • 🛡️ Le plus axé sur la sécurité
  • 📚 Contexte de 200 K tokens
  • ✍️ Excellente qualité rédactionnelle

Exemple complet fonctionnel

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("ANTHROPIC_API_KEY")?;
    let model = AnthropicClient::new(AnthropicConfig::new(&api_key, "claude-sonnet-5"))?;

    let agent = LlmAgentBuilder::new("anthropic_assistant")
        .description("Anthropic-powered assistant")
        .instruction("You are a helpful assistant powered by Anthropic Claude. Be concise and thoughtful.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

Modèles disponibles

ModèleDescriptionContexte
claude-sonnet-5Intelligence et coût équilibrés (par défaut)1M tokens
claude-opus-5Capacité phare1M tokens
claude-fable-5Travail créatif haut de gamme et contenu long format1M tokens
claude-haiku-4-5Génération précédente économique200K tokens

Exemple de sortie

👤 User: Explain quantum entanglement to a 10-year-old

🤖 Claude: Imagine you have two magic coins. When you flip them, they always 
land the same way - both heads or both tails - even if one coin is on Earth 
and the other is on the Moon! Scientists call this "entanglement." The coins 
are connected in a special way that we can't see, like invisible best friends 
who always make the same choice at the exact same time.

DeepSeek 💭 Réflexion

Idéal pour : résolution de problèmes complexes, mathématiques, programmation, tâches de raisonnement

Points forts :

  • 💭 Mode réflexion – affiche le raisonnement étape par étape
  • 💰 Très économique (10 fois moins cher que GPT-4)
  • 🔄 Mise en cache du contexte pour les préfixes répétés
  • 🧮 Très performant en mathématiques et en programmation

Exemple complet fonctionnel

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("DEEPSEEK_API_KEY")?;
    
    // Standard chat model
    let model = DeepSeekClient::chat(&api_key)?;
    
    // OR: Reasoning model with thinking mode
    // let model = DeepSeekClient::reasoner(&api_key)?;

    let agent = LlmAgentBuilder::new("deepseek_assistant")
        .description("DeepSeek-powered assistant")
        .instruction("You are a helpful assistant powered by DeepSeek. Be concise.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

Modèles disponibles

ModèleDescriptionFonctionnalité spéciale
deepseek-v4-flashModèle par défaut actuelAgents polyvalents rapides
deepseek-v4-proRaisonnement avancéTâches agentiques complexes

Exemple de sortie (Raisonneur avec mode de réflexion)

👤 User: What's 17 × 23?

🤖 DeepSeek: <thinking>
Let me break this down:
17 × 23 = 17 × (20 + 3)
       = 17 × 20 + 17 × 3
       = 340 + 51
       = 391
</thinking>

The answer is 391.

Groq ⚡ Ultra-rapide

Idéal pour : applications en temps réel, chatbots, tâches nécessitant une grande rapidité

Points forts :

  • Inférence la plus rapide - 10 fois plus rapide que les concurrents
  • 🔧 Technologie LPU (Language Processing Unit)
  • 💰 Tarification compétitive
  • 🦙 Exécute les modèles LLaMA, Mixtral et Gemma

Exemple complet fonctionnel

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("GROQ_API_KEY")?;
    let model = GroqClient::new(GroqConfig::gpt_oss_120b(&api_key))?;

    let agent = LlmAgentBuilder::new("groq_assistant")
        .description("Groq-powered assistant")
        .instruction("You are a helpful assistant powered by Groq. Be concise and fast.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

Modèles disponibles

ModèleMéthodeDescription
openai/gpt-oss-120bGroqClient::new(GroqConfig::gpt_oss_120b(key))Valeur par défaut actuelle en production
openai/gpt-oss-20bGroqClient::new(GroqConfig::new(key, "openai/gpt-oss-20b"))Modèle GPT-OSS à moindre coût
N’importe quel modèleGroqClient::new(GroqConfig::new(key, "model"))Modèle personnalisé

Exemple de sortie

👤 User: Quick! Name 5 programming languages

🤖 Groq (in 0.2 seconds): 
1. Rust
2. Python
3. JavaScript
4. Go
5. TypeScript

Changer de fournisseur

Tous les fournisseurs implémentent le même trait Llm, le changement est donc simple :

use adk_agent::LlmAgentBuilder;
use std::sync::Arc;

// Just change the model - everything else stays the same!
let model: Arc<dyn adk_core::Llm> = Arc::new(
    // Pick one:
    // GeminiModel::new(&api_key, "gemini-3.7-flash")?
    // OpenAIClient::new(OpenAIConfig::new(&api_key, "gpt-5.6-terra"))?
    // AnthropicClient::new(AnthropicConfig::new(&api_key, "claude-sonnet-5"))?
    // DeepSeekClient::chat(&api_key)?
    // GroqClient::new(GroqConfig::gpt_oss_120b(&api_key))?
);

let agent = LlmAgentBuilder::new("assistant")
    .instruction("You are a helpful assistant.")
    .model(model)
    .build()?;

Exemples

Utilisez cargo-adk pour générer des projets spécifiques à chaque fournisseur avec des dépendances 0.8 validées :

cargo adk new gemini_agent --provider gemini
cargo adk new openai_agent --template openai
cargo adk new anthropic_agent --provider anthropic

Les projets générés sont compilés en CI par scripts/check-cargo-adk-templates.sh. La galerie complète d’exemples est maintenue dans le dépôt adk-playground.



Précédent : ← Agents en temps réel | Suivant : Ollama (local) →

Que devient le contenu qu’un fournisseur ne peut pas transporter ?

Content peut exprimer davantage que ce qu’accepte le transport d’un fournisseur donné, chaque adaptateur doit donc décider quoi faire du reste. Ces décisions sont désormais consignées au lieu d’être appliquées invisiblement. Chaque partie est classifiée :

DispositionSignification
ConvertedTransmis au fournisseur sous une forme native équivalente
DowngradedTransmis sous une forme plus dégradée — une référence de fichier rendue sous forme de texte descriptif que le modèle peut lire, mais pas récupérer
OmittedPas transporté du tout

Les rétrogradations et les omissions émettent un avertissement tracing au moment où elles sont enregistrées, en indiquant le type de partie, le type MIME et la raison, afin qu’aucune ne passe inaperçue.

Pour voir le résultat avant d’envoyer une requête :

use adk_core::{Content, Part};
use adk_model::bedrock::convert::report_for_contents;

let content = Content {
    role: "user".to_string(),
    parts: vec![Part::inline_data("audio/wav", vec![0u8; 16])],
};
let report = report_for_contents(std::slice::from_ref(&content));

for omission in report.omitted_parts() {
    println!("{} was dropped: {}", omission.kind, omission.detail);
}

Pour refuser une requête qui parviendrait au modèle de manière incomplète plutôt que de recevoir une réponse concernant des éléments que le modèle n’a jamais vus :

use adk_core::{Content, Part};
use adk_model::bedrock::convert::report_for_contents;

let content = Content {
    role: "user".to_string(),
    parts: vec![Part::inline_data("video/mp4", vec![0u8; 16])],
};

if let Some(error) = report_for_contents(std::slice::from_ref(&content)).into_error() {
    return Err(error);
}

into_error couvre uniquement les omissions. Une rétrogradation parvient tout de même au modèle, et la rejeter reviendrait à refuser le repli textuel documenté.

Remarque : le registre est complet par construction. Toute partie qui quitte un adaptateur sans état enregistré — y compris une partie ajoutée par une modification future — est enregistrée comme une omission avec une « raison non enregistrée » explicite, et adk-model/tests/part_conversion_matrix_tests.rs échoue dans ce cas.

Couverture de Bedrock Converse

PartieDisposition
Texte, FunctionCall, FunctionResponse, RéflexionConverted
InlineData avec JPEG, PNG, GIF, WebPConverted comme bloc d’image
InlineData avec un type de document pris en charge (PDF et similaires)Converted en tant que bloc de document
InlineData avec de l’audio, de la vidéo ou des données binaires arbitrairesOmitted
FileData pour une image ou un document pris en chargeDowngraded vers du texte — Converse accepte URIs S3, et non des URLs arbitraires
FileData pour tout autre typeOmitted
ServerToolCall, ServerToolResponseOmitted — spécifique à Gemini
texte EmbeddedResource, ou un blob d’un type pris en chargeConverted
blob EmbeddedResource d’un type non pris en chargeOmitted
Fournisseurs de modèles (cloud) - Documentation ADK-Rust | ADK-Rust