Provedores de modelos (nuvem)

ADK-Rust oferece suporte a vários provedores de LLM na 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, contexto amplo, raciocínio
OpenAIConfiabilidade⚡⚡💰💰Melhor ecossistema
AnthropicRaciocínio complexo⚡⚡💰💰Mais seguro e ponderado
DeepSeekRaciocínio em cadeia⚡⚡💰Modo de pensamento, econômico
GroqCrítico para velocidade⚡⚡⚡⚡💰Inferência mais rápida

Etapa 1: Instalação

Adicione os provedores necessários ao seu 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"] }

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 esquema

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

ProvedorAdaptador de esquemaComportamento
GeminiGeminiSchemaAdapterAgressivo: resolve $ref, simplifica combinadores e remove palavras-chave não compatíveis
OpenAI (estrito)OpenAiStrictSchemaAdapterPreserva a estrutura e adiciona additionalProperties: false
OpenAIOpenAiSchemaAdapterCorreções mínimas e seguras
AnthropicAnthropicSchemaAdapterQuase sem alterações
DeepSeekGenericSchemaAdapterTransformações conservadoras e seguras
OllamaGenericSchemaAdapterTransformações conservadoras e seguras

Acesse o adaptador programaticamente por meio da trait Llm:

use adk_core::{Llm, SchemaAdapter};

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

Consulte Normalização de esquema para obter a documentação completa.


Gemini (Google) ⭐ Padrão

Ideal para: Tarefas de uso geral e multimodais, documentos grandes

Principais destaques:

  • 🖼️ Multimodalidade nativa (imagens, vídeo, áudio, PDF)
  • 📚 Janela de contexto de até 2 milhões de tokens
  • 🧠 Modo de raciocínio: baseado em níveis (Gemini 3) e baseado 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-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(())
}

Modelos disponíveis

ModeloDescriçãoContexto
gemini-3.7-flashModelo de agente equilibrado padrão1M tokens
gemini-3.6-flashGeração equilibrada anterior1M tokens
gemini-3.5-flash-liteRoteamento econômico e tarefas de alto volume1M tokens
gemini-3.1-pro-previewRaciocínio avançado em prévia2M tokens

Modo de raciocínio

Os modelos Gemini 3 são compatíveis com raciocínio baseado em níveis, enquanto o Gemini 2.5 usa raciocínio baseado em orçamento. Ao usar o modo de raciocínio com chamadas de função, os modelos Gemini 2.5+ e 3.x retornam valores thoughtSignature que devem ser repetidos nas interações 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?;

Exemplo de saída

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

Mais adequado para: aplicativos em produção, desempenho confiável e recursos abrangentes

Principais destaques:

  • 🏆 Padrão do setor
  • 🔧 Excelente suporte a chamadas de ferramentas/funções
  • 📖 Melhor documentação e ecossistema
  • 🎯 Saídas consistentes e previsíveis
  • 📋 Saída estruturada com aplicação de esquema JSON
  • 🧠 Controle do esforço de raciocínio para modelos de raciocínio GPT-5.6
  • 🆕 Respostas API — cliente dedicado para /v1/responses com resumos de raciocínio, ferramentas integradas e estado no lado do servidor

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

Saída estruturada (esquema JSON)

OpenAI oferece saída JSON garantida por meio de output_schema. ADK-Rust conecta isso automaticamente ao response_format API de OpenAI:

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

Para o modo estrito 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

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

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

O vocabulário completo é None, Minimal, Low, Medium, High, XHigh, e Max; a disponibilidade depende do modelo e de API. GPT-5.6 Chat Completions é compatível com até XHigh; use OpenAIResponsesClient para Max. O ReasoningEffort original de três valores API continua disponível para compatibilidade retroativa.

OpenAI-Compatible Local APIs

Use OpenAIConfig::compatible() para se 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)?;

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

Gemini via o Endpoint Compatível com OpenAI

Os modelos Gemini podem ser acessados por meio do formato de comunicação Chat Completions compatível com OpenAI em https://generativelanguage.googleapis.com/v1beta/openai. Use a predefinição OpenAICompatibleConfig::gemini(...) (na funcionalidade openai) com um 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 oferece suporte a chat, streaming, chamadas de função, saída estruturada e esforço de raciocínio (reasoning_effort de OpenAI é mapeado para os níveis/orçamentos de raciocínio do Gemini). Opções específicas do Gemini — por exemplo, thinking_config com include_thoughts ou cached_content — são transmitidas pelo mapa extensions["openai"]["extra_body"]["google"] da solicitação, que o cliente mescla literalmente ao corpo da solicitação.

Quando usar isto em vez de GeminiModel: para recursos nativos do Gemini (ferramentas no lado do servidor, a API Interactions, ThinkingConfig nativo e ergonomia priorizando multimodalidade), prefira GeminiModel. Use a predefinição compatível com OpenAI quando quiser um único cliente uniforme entre provedores.

Exemplos (requerem 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 legado de esforço de raciocínio

O original de três níveis ReasoningEffort API continua disponível para compatibilidade:

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

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

Modelos disponíveis

ModeloDescriçãoContexto
gpt-5.6-terraPadrão equilibrado para agentes de produção256K tokens
gpt-5.6-solRaciocínio e programação de ponta256K tokens
gpt-5.6-lunaCargas de trabalho de alto volume e econômicas128K tokens
gpt-5.6Alias principal256K 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

Ideal para: Raciocínio complexo, aplicativos essenciais para a segurança, documentos longos

Principais destaques:

  • 🧠 Capacidade excepcional de raciocínio
  • 🛡️ Maior foco em segurança
  • 📚 Contexto de 200 mil tokens
  • ✍️ Excelente qualidade de escrita

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

Modelos disponíveis

ModeloDescriçãoContexto
claude-sonnet-5Inteligência e custo equilibrados (padrão)1 milhão de tokens
claude-opus-5Capacidade de ponta1 milhão de tokens
claude-fable-5Trabalho criativo premium e de formato longo1M tokens
claude-haiku-4-5Geração anterior com custo eficiente200K 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 💭 Raciocínio

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

Principais destaques:

  • 💭 Modo de raciocínio - mostra o raciocínio passo a passo
  • 💰 Muito econômico (10x mais barato que GPT-4)
  • 🔄 Armazenamento em cache do contexto para prefixos repetidos
  • 🧮 Excelente 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-v4-flashPadrão atualAgentes rápidos de uso geral
deepseek-v4-proRaciocínio avançadoTrabalho agentivo complexo

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 que exigem alta velocidade

Principais destaques:

  • ⚡ Inferência mais rápida - 10 vezes mais rápido que os concorrentes
  • 🔧 Tecnologia LPU (Unidade de Processamento de Linguagem)
  • 💰 Preços competitivos
  • 🦙 Executa os modelos LLaMA, Mixtral e 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::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(())
}

Modelos disponíveis

ModeloMétodoDescrição
openai/gpt-oss-120bGroqClient::new(GroqConfig::gpt_oss_120b(key))Padrão atual de produção
openai/gpt-oss-20bGroqClient::new(GroqConfig::new(key, "openai/gpt-oss-20b"))Modelo GPT-OSS de menor custo
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 entre provedores

Todos os provedores implementam a mesma trait Llm, portanto 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-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()?;

Exemplos

Use cargo-adk para gerar projetos específicos do provedor 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 na CI por scripts/check-cargo-adk-templates.sh. A galeria completa de exemplos é mantida no repositório adk-playground.



Anterior: ← Agentes em tempo real | Próximo: Ollama (local) →

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

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

DisposiçãoSignificado
ConvertedTransmitido ao provedor em um formato nativo equivalente
DowngradedTransmitido em um formato com maior perda — uma referência de arquivo renderizada como texto descritivo que o modelo pode ler, mas não buscar
OmittedNão transportado de forma alguma

Downgrades e omissões emitem um aviso tracing à medida que são registradas, identificando o tipo de parte, o tipo MIME e o motivo, para que nenhuma delas passe despercebida.

Para ver o resultado antes de enviar 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 incompleta ao modelo, em vez de receber uma resposta sobre um 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 abrange apenas omissões. Um downgrade ainda chega ao modelo, e rejeitá-lo recusaria o fallback textual documentado.

Observação: o registro é completo por construção. Qualquer parte que saia de um adaptador sem um destino registrado — incluindo uma adicionada por uma alteração futura — é registrada como uma omissão com um "motivo não registrado" explícito, e adk-model/tests/part_conversion_matrix_tests.rs falha nesse caso.

Cobertura do Bedrock Converse

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