Provedores de Modelo (Nuvem)

ADK-Rust oferece suporte a múltiplos provedores de LLM em nuvem por meio do crate adk-model. Todos os provedores implementam o trait Llm, tornando-os intercambiáveis em seus agentes.

Visão geral

┌─────────────────────────────────────────────────────────────────────┐
│                     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                                       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Comparação rápida

ProvedorMelhor paraVelocidadeCustoRecurso principal
GeminiUso geral⚡⚡⚡💰Multimodal, grande contexto, raciocínio
OpenAIConfiabilidade⚡⚡💰💰Melhor ecossistema
Anthropicraciocínio complexo⚡⚡💰💰Mais seguro, mais cuidadoso
DeepSeekcadeia de pensamento⚡⚡💰Modo de pensamento, barato
Groqcrítico para velocidade⚡⚡⚡⚡💰inferência mais rápida

Etapa 1: Instalação

Adicione os provedores de que você precisa ao seu Cargo.toml:

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

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

Etapa 2: Defina sua chave 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

Normalização do Schema

Cada provedor normaliza automaticamente os schemas de ferramentas MCP no momento da requisição. Você não precisa fazer nada — isso funciona de forma transparente. Mas veja o que acontece nos bastidores:

ProvedorAdaptador de SchemaComportamento
GeminiGeminiSchemaAdapterAgressivo: resolve $ref, reduz combinadores, remove palavras-chave sem suporte
OpenAI (rigoroso)OpenAiStrictSchemaAdapterPreserva a estrutura, adiciona additionalProperties: false
OpenAIOpenAiSchemaAdapterCorreções seguras mínimas
AnthropicAnthropicSchemaAdapterPassagem quase direta
DeepSeekGenericSchemaAdapterTransformações seguras conservadoras
OllamaGenericSchemaAdapterTransformações seguras conservadoras

Acesse o adapter programaticamente via o trait Llm:

use adk_core::{Llm, SchemaAdapter};

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

Veja Schema Normalization para a documentação completa.


Gemini (Google) ⭐ Padrão

Melhor para: tarefas multimodais de propósito geral, documentos grandes

Principais destaques:

  • 🖼️ Multimodal nativo (imagens, vídeo, áudio, PDF)
  • 📚 Janela de contexto de até 2M tokens
  • 🧠 Modo de pensamento: baseado em níveis (Gemini 3) e em orçamento (Gemini 2.5) com assinaturas de pensamento
  • 💰 Preços competitivos
  • ⚡ Inferência rápida

Exemplo Completo em Funcionamento

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-2.5-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(())
}

Modelos Disponíveis

ModeloDescriçãoContexto
gemini-3.1-pro-previewRaciocínio mais forte para fluxos de trabalho agentic complexos2M tokens
gemini-3-flash-previewRápido e eficiente para código e agentes1M tokens
gemini-3.1-flash-lite-previewRoteamento mais barato e rápido e tarefas de alto volume1M tokens
gemini-2.5-proRaciocínio avançado e multimodal1M tokens
gemini-2.5-flashVelocidade e capacidade equilibradas (recomendado)1M tokens

Modo de Pensamento

Os modelos Gemini 3 suportam pensamento baseado em nível, enquanto o Gemini 2.5 usa pensamento baseado em orçamento. Ao usar o modo de pensamento com chamada de função, os modelos Gemini 2.5+ e 3.x retornam valores de thoughtSignature que devem ser ecoados de volta em turnos subsequentes para preservar o contexto do raciocínio. ADK-Rust lida com isso automaticamente — as assinaturas são serializadas quando presentes e omitidas quando 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?;

Saída de Exemplo

👤 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.

Melhor para: aplicativos de produção, desempenho confiável, amplas capacidades

Destaques principais:

  • 🏆 Padrão da indústria
  • 🔧 Excelente chamada de ferramenta/função
  • 📖 Melhor documentação e ecossistema
  • 🎯 Saídas consistentes e previsíveis
  • 📋 Saída estruturada com aplicação de esquema JSON
  • 🧠 controle de esforço de raciocínio para modelos de raciocínio o1/o3
  • 🆕 Responses API — cliente dedicado para /v1/responses com resumos de raciocínio, ferramentas integradas e estado no lado do servidor

Exemplo Completo em Funcionamento

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-mini"))?;

    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(())
}

Saída Estruturada (Esquema JSON)

OpenAI suporta saída JSON garantida via output_schema. ADK-Rust conecta isso automaticamente ao OpenAI do response_format do API:

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

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

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

Para o modo rígido com objetos aninhados, inclua additionalProperties: false em cada nível:

.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
}))

Esforço de Raciocínio (Modelos o1, o3)

Para modelos de raciocínio OpenAI, controle quanto esforço de raciocínio o modelo aplica:

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

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

Níveis disponíveis: Low, Medium, High. Um esforço maior produz raciocínio mais completo, ao custo de latência e tokens.

Local OpenAI-Compatível APIs

Use OpenAIConfig::compatible() para conectar a servidores locais (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)?;

Nota: A saída estruturada (output_schema) requer suporte do backend. O OpenAI nativo oferece suporte completo; servidores locais podem ter suporte limitado.

Gemini via o Endpoint Compatível com OpenAI

Os modelos Gemini são acessíveis através do formato de wire Chat Completions OpenAI em https://generativelanguage.googleapis.com/v1beta/openai. Use o preset OpenAICompatibleConfig::gemini(...) (sob o recurso openai) com uma GEMINI_API_KEY para executar o Gemini pelo mesmo cliente compatível com OpenAI que você usa para todos os outros provedores:

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"),
)?;

Esse caminho suporta chat, streaming, chamada de função, saída estruturada e esforço de raciocínio (OpenAI's reasoning_effort mapeia para os níveis/orçamentos de pensamento do Gemini). Opções específicas do Gemini — por exemplo, thinking_config com include_thoughts, ou cached_content — são repassadas pelo mapa extensions["openai"]["extra_body"]["google"] da requisição, que o cliente mescla verbatim no corpo da requisição.

Quando usar isso em vez de GeminiModel: Para recursos nativos do Gemini (ferramentas no lado do servidor, as Interactions API, ThinkingConfig nativo, ergonomia multimodal-first), prefira GeminiModel. Use o preset compatível com OpenAI quando você quiser um único cliente uniforme entre provedores.

Exemplos (requer 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

Esforço de Raciocínio (Modelos o1, o3)

Controle quanto esforço de raciocínio o modelo aplica com ReasoningEffort:

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

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

Níveis disponíveis: Low (mais rápido), Medium (equilibrado), High (mais completo).

Modelos Disponíveis

ModeloDescriçãoContexto
gpt-5Modelo unificado de última geração com raciocínio adaptativo256K tokens
gpt-5-miniVersão eficiente para a maioria das tarefas (recomendada)128K tokens
gpt-5-nanoRoteamento e classificação de menor custo128K tokens
gpt-4.1Modelo estável de produção para implantações legadas de GPT-4.11M tokens

Exemplo de Saída

👤 User: Write a haiku about Rust programming

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

Anthropic (Claude) 🧠 Inteligente

Melhor para: Raciocínio complexo, aplicativos críticos de segurança, documentos longos

Destaques principais:

  • 🧠 Capacidade excepcional de raciocínio
  • 🛡️ Mais focado em segurança
  • 📚 Contexto de 200K tokens
  • ✍️ Excelente qualidade de escrita

Exemplo Completo em Funcionamento

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-4-6"))?;

    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(())
}

Modelos Disponíveis

ModeloDescriçãoContexto
claude-opus-4-7Modelo GA mais capaz, apenas pensamento adaptativo1M tokens
claude-opus-4-6Versão principal anterior para tarefas autônomas complexas1M tokens
claude-sonnet-4-6Inteligência e custo equilibrados (recomendado)1M tokens
claude-haiku-4-5-20251001Ultraeficiente para cargas de trabalho de alto volume200K tokens
claude-opus-4-20250514Modelo híbrido com raciocínio estendido200K tokens
claude-sonnet-4-20250514Modelo equilibrado com raciocínio estendido1M tokens

Exemplo de saída

👤 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 💭 Pensamento

Melhor para: resolução de problemas complexos, matemática, programação, tarefas de raciocínio

Destaques principais:

  • 💭 Modo de raciocínio - mostra raciocínio em cadeia
  • 💰 Muito econômico (10x mais barato que GPT-4)
  • 🔄 Cache de contexto para prefixos repetidos
  • 🧮 Forte em matemática e programação

Exemplo Completo em Funcionamento

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(())
}

Modelos Disponíveis

ModeloDescriçãoRecurso Especial
deepseek-r1-0528Modelo de raciocínio mais recenteProfundidade de raciocínio aprimorada
deepseek-r1Raciocínio avançadoComparável ao o1
deepseek-v3.1Modelo mais recente 671B MoETarefas gerais
deepseek-chatModelo 671B MoE (V3)Propósito geral, barato
deepseek-vl2Modelo de visão e linguagemMultimodal

Exemplo de saída (Reasoner com modo de raciocínio)

👤 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 ⚡ Ultrarrápido

Ideal para: aplicações em tempo real, chatbots, tarefas críticas de velocidade

Destaques principais:

  • Inferência mais rápida - 10x mais rápido que os concorrentes
  • 🔧 Tecnologia LPU (Language Processing Unit)
  • 💰 Preços competitivos
  • 🦙 Executa modelos LLaMA, Mixtral, Gemma

Exemplo completo funcional

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::llama70b(&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(())
}

Modelos disponíveis

ModeloMétodoDescrição
llama-4-scoutGroqClient::new(GroqConfig::new(key, "llama-4-scout"))Llama 4 Scout (17Bx16E)
llama-3.2-90b-text-previewGroqClient::new(GroqConfig::new(key, "llama-3.2-90b-text-preview"))Grande modelo de texto
llama-3.1-70b-versatileGroqClient::llama70b()Modelo grande versátil
llama-3.1-8b-instantGroqClient::llama8b()Mais rápido
mixtral-8x7b-32768GroqClient::mixtral()Bom equilíbrio
Qualquer modeloGroqClient::new(GroqConfig::new(key, "model"))Modelo personalizado

Exemplo de saída

👤 User: Quick! Name 5 programming languages

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

Alternando provedores

Todos os provedores implementam o mesmo trait Llm, então alternar é fácil:

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-2.5-flash")?
    // OpenAIClient::new(OpenAIConfig::new(&api_key, "gpt-5-mini"))?
    // AnthropicClient::new(AnthropicConfig::new(&api_key, "claude-sonnet-4-6"))?
    // DeepSeekClient::chat(&api_key)?
    // GroqClient::llama70b(&api_key)?
);

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

Exemplos

Use cargo-adk para gerar projetos específicos de provedores com dependências 0.8 validadas:

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

Os projetos gerados são compilados no CI por scripts/check-cargo-adk-templates.sh. Você pode explorar e executar a galeria completa de exemplos no ADK-Rust Playground incorporado a este site.



Anterior: ← Realtime Agents | Próximo: Ollama (Local) →

O que acontece com conteúdo que um provedor não consegue transportar

Content pode expressar mais do que qualquer transporte de um único provedor aceita, então cada adaptador precisa decidir o que fazer com o restante. Essas decisões agora são registradas em vez de aplicadas de forma invisível. Cada parte é classificada:

DisposiçãoSignificado
ConvertedTransportado ao provedor em uma forma nativa equivalente
DowngradedTransportado em uma forma mais perdedora de informação — uma referência a arquivo renderizada como texto descritivo que o modelo pode ler, mas não buscar
OmittedNão é carregado de forma alguma

Downgrades e omissões emitem um aviso tracing conforme são registrados, nomeando o tipo de parte, o tipo MIME e o motivo, para que nenhum deles passe despercebido.

Para ver o resultado antes de despachar uma solicitação:

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);
}

Para recusar uma solicitação que chegaria ao modelo incompleta, em vez de receber uma resposta sobre material que o modelo nunca viu:

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 cobre apenas omissões. Uma degradação ainda chega ao modelo, e rejeitá-la recusaria o fallback textual documentado.

Nota: o ledger é completo por construção. Qualquer parte que saia de um adaptador sem um destino registrado — incluindo uma adicionada por uma mudança futura — é registrada como uma omissão com um "sem motivo registrado" explícito, e adk-model/tests/part_conversion_matrix_tests.rs falha nisso.

Cobertura do Bedrock Converse

ParteDisposição
Texto, FunctionCall, FunctionResponse, PensamentoConverted
InlineData com JPEG, PNG, GIF, WebPConverted como um bloco de imagem
InlineData com um tipo de documento compatível (PDF e semelhantes)Converted como um bloco de documento
InlineData com áudio, vídeo ou binário arbitrárioOmitted
FileData para uma imagem ou documento compatívelDowngraded em texto — Converse aceita S3 URIs, não URLs arbitrário
FileData para qualquer outro tipoOmitted
ServerToolCall, ServerToolResponseOmitted — específico do Gemini
Texto de EmbeddedResource ou blob de um tipo compatívelConverted
EmbeddedResource blob of an unsupported typeOmitted
Provedores de Modelo (Nuvem) - Documentação ADK-Rust | ADK-Rust