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
| Provedor | Melhor para | Velocidade | Custo | Recurso principal |
|---|---|---|---|---|
| Gemini | Uso geral | ⚡⚡⚡ | 💰 | Multimodal, contexto amplo, raciocínio |
| OpenAI | Confiabilidade | ⚡⚡ | 💰💰 | Melhor ecossistema |
| Anthropic | Raciocínio complexo | ⚡⚡ | 💰💰 | Mais seguro e ponderado |
| DeepSeek | Raciocínio em cadeia | ⚡⚡ | 💰 | Modo de pensamento, econômico |
| Groq | Crí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:
| Provedor | Adaptador de esquema | Comportamento |
|---|---|---|
| Gemini | GeminiSchemaAdapter | Agressivo: resolve $ref, simplifica combinadores e remove palavras-chave não compatíveis |
| OpenAI (estrito) | OpenAiStrictSchemaAdapter | Preserva a estrutura e adiciona additionalProperties: false |
| OpenAI | OpenAiSchemaAdapter | Correções mínimas e seguras |
| Anthropic | AnthropicSchemaAdapter | Quase sem alterações |
| DeepSeek | GenericSchemaAdapter | Transformações conservadoras e seguras |
| Ollama | GenericSchemaAdapter | Transformaçõ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
| Modelo | Descrição | Contexto |
|---|---|---|
gemini-3.7-flash | Modelo de agente equilibrado padrão | 1M tokens |
gemini-3.6-flash | Geração equilibrada anterior | 1M tokens |
gemini-3.5-flash-lite | Roteamento econômico e tarefas de alto volume | 1M tokens |
gemini-3.1-pro-preview | Raciocínio avançado em prévia | 2M 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.
OpenAI (GPT-5) 🔥 Popular
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/responsescom 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,ThinkingConfignativo e ergonomia priorizando multimodalidade), prefiraGeminiModel. 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
| Modelo | Descrição | Contexto |
|---|---|---|
gpt-5.6-terra | Padrão equilibrado para agentes de produção | 256K tokens |
gpt-5.6-sol | Raciocínio e programação de ponta | 256K tokens |
gpt-5.6-luna | Cargas de trabalho de alto volume e econômicas | 128K tokens |
gpt-5.6 | Alias principal | 256K 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
| Modelo | Descrição | Contexto |
|---|---|---|
claude-sonnet-5 | Inteligência e custo equilibrados (padrão) | 1 milhão de tokens |
claude-opus-5 | Capacidade de ponta | 1 milhão de tokens |
claude-fable-5 | Trabalho criativo premium e de formato longo | 1M tokens |
claude-haiku-4-5 | Geração anterior com custo eficiente | 200K 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
| Modelo | Descrição | Recurso especial |
|---|---|---|
deepseek-v4-flash | Padrão atual | Agentes rápidos de uso geral |
deepseek-v4-pro | Raciocínio avançado | Trabalho 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
| Modelo | Método | Descrição |
|---|---|---|
openai/gpt-oss-120b | GroqClient::new(GroqConfig::gpt_oss_120b(key)) | Padrão atual de produção |
openai/gpt-oss-20b | GroqClient::new(GroqConfig::new(key, "openai/gpt-oss-20b")) | Modelo GPT-OSS de menor custo |
| Qualquer modelo | GroqClient::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.
Relacionados
- Ollama (local) - Execute modelos localmente com Ollama
- Modelos locais (mistral.rs) - Inferência nativa em Rust
- LlmAgent - Usando modelos com agentes
- Ferramentas de função - Adicionando ferramentas aos agentes
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ção | Significado |
|---|---|
Converted | Transmitido ao provedor em um formato nativo equivalente |
Downgraded | Transmitido em um formato com maior perda — uma referência de arquivo renderizada como texto descritivo que o modelo pode ler, mas não buscar |
Omitted | Nã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.rsfalha nesse caso.
Cobertura do Bedrock Converse
| Parte | Disposição |
|---|---|
| Texto, FunctionCall, FunctionResponse, Raciocínio | Converted |
InlineData com JPEG, PNG, GIF, WebP | Converted 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ário | Omitted |
FileData para uma imagem ou documento compatível | Downgraded para texto — Converse aceita URIs do S3, não URLs arbitrário |
FileData para qualquer outro tipo | Omitted |
ServerToolCall, ServerToolResponse | Omitted — específico do Gemini |
texto EmbeddedResource ou um blob de um tipo compatível | Converted |
blob EmbeddedResource de um tipo incompatível | Omitted |