Proveedores de modelos (nube)
ADK-Rust admite múltiples proveedores de LLM en la nube mediante el crate adk-model. Todos los proveedores implementan el trait Llm, lo que permite intercambiarlos en tus agentes.
Descripción general
┌─────────────────────────────────────────────────────────────────────┐
│ 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 │
│ │
└─────────────────────────────────────────────────────────────────────┘
Comparación rápida
| Proveedor | Ideal para | Velocidad | Coste | Característica principal |
|---|---|---|---|---|
| Gemini | Uso general | ⚡⚡⚡ | 💰 | Multimodal, contexto amplio, razonamiento |
| OpenAI | Fiabilidad | ⚡⚡ | 💰💰 | Mejor ecosistema |
| Anthropic | Razonamiento complejo | ⚡⚡ | 💰💰 | El más seguro y reflexivo |
| DeepSeek | Cadena de pensamiento | ⚡⚡ | 💰 | Modo de razonamiento, económico |
| Groq | Velocidad crítica | ⚡⚡⚡⚡ | 💰 | Inferencia más rápida |
Paso 1: Instalación
Añade los proveedores que necesitas a tu 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"] }
Paso 2: Configura tu clave de 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
Normalización del esquema
Cada proveedor normaliza automáticamente los esquemas de herramientas de MCP en el momento de la solicitud. No necesitas hacer nada; funciona de forma transparente. Pero esto es lo que ocurre internamente:
| Proveedor | Adaptador de esquema | Comportamiento |
|---|---|---|
| Gemini | GeminiSchemaAdapter | Agresivo: resuelve $ref, colapsa los combinadores y elimina las palabras clave no compatibles |
| OpenAI (estricto) | OpenAiStrictSchemaAdapter | Conserva la estructura y añade additionalProperties: false |
| OpenAI | OpenAiSchemaAdapter | Correcciones mínimas seguras |
| Anthropic | AnthropicSchemaAdapter | Casi sin modificaciones |
| DeepSeek | GenericSchemaAdapter | Transformaciones seguras conservadoras |
| Ollama | GenericSchemaAdapter | Transformaciones seguras conservadoras |
Accede al adaptador mediante el trait Llm:
use adk_core::{Llm, SchemaAdapter};
let adapter = model.schema_adapter();
let normalized = adapter.normalize_schema(raw_schema);
Consulta Normalización del esquema para obtener la documentación completa.
Gemini (Google) ⭐ Predeterminado
Ideal para: Tareas generales y multimodales, documentos extensos
Aspectos destacados:
- 🖼️ Multimodalidad nativa (imágenes, vídeo, audio, PDF)
- 📚 Ventana de contexto de hasta 2 millones de tokens
- 🧠 Modo de razonamiento: basado en niveles (Gemini 3) y basado en presupuesto (Gemini 2.5), con firmas de pensamiento
- 💰 Precios competitivos
- ⚡ Inferencia rápida
Ejemplo 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("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 disponibles
| Modelo | Descripción | Contexto |
|---|---|---|
gemini-3.7-flash | Modelo de agente equilibrado predeterminado | 1M tokens |
gemini-3.6-flash | Generación equilibrada anterior | 1M tokens |
gemini-3.5-flash-lite | Enrutamiento rentable y tareas de gran volumen | 1M tokens |
gemini-3.1-pro-preview | Razonamiento avanzado en vista previa | 2M tokens |
Modo de razonamiento
Los modelos Gemini 3 admiten el razonamiento basado en niveles, mientras que Gemini 2.5 utiliza un razonamiento basado en presupuesto. Al usar el modo de razonamiento con llamadas a funciones, los modelos Gemini 2.5+ y 3.x devuelven valores thoughtSignature que deben repetirse en los turnos posteriores para conservar el contexto del razonamiento. ADK-Rust gestiona esto automáticamente: las firmas se serializan cuando están presentes y se omiten cuando 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?;
Ejemplo de salida
👤 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
Ideal para: Aplicaciones de producción, rendimiento confiable y amplias capacidades
Aspectos destacados:
- 🏆 Estándar del sector
- 🔧 Excelente compatibilidad con llamadas a herramientas y funciones
- 📖 La mejor documentación y ecosistema
- 🎯 Salidas coherentes y predecibles
- 📋 Salida estructurada con aplicación del esquema JSON
- 🧠 Control del esfuerzo de razonamiento para los modelos de razonamiento GPT-5.6
- 🆕 Respuestas API: cliente dedicado para
/v1/responsescon resúmenes del razonamiento, herramientas integradas y estado en el servidor
Ejemplo 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(())
}
Salida estructurada (esquema JSON)
OpenAI admite salidas JSON garantizadas mediante output_schema. ADK-Rust conecta automáticamente esto con 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 el modo estricto con objetos anidados, incluye additionalProperties: false en cada nivel:
.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
}))
Esfuerzo de razonamiento
Para los modelos de razonamiento OpenAI, controla cuánto esfuerzo de razonamiento aplica el modelo:
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,
)?;
El vocabulario completo es None, Minimal, Low, Medium, High, XHigh,
y Max; la disponibilidad depende del modelo y de API. GPT-5.6 Chat Completions
admite hasta XHigh; usa OpenAIResponsesClient para Max. El ReasoningEffort original de tres valores API
sigue disponible por compatibilidad con versiones anteriores.
OpenAI-Compatible Local APIs
Usa OpenAIConfig::compatible() para conectarte a servidores locales (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: La salida estructurada (
output_schema) requiere compatibilidad del backend. Native OpenAI la admite completamente; los servidores locales pueden tener compatibilidad limitada.
Gemini mediante el endpoint compatible con OpenAI
Los modelos Gemini están disponibles mediante el formato de comunicación Chat Completions de OpenAI en
https://generativelanguage.googleapis.com/v1beta/openai. Usa el ajuste preestablecido
OpenAICompatibleConfig::gemini(...) (en la funcionalidad openai) con un
GEMINI_API_KEY para ejecutar Gemini mediante el mismo cliente compatible con OpenAI que usas
para cualquier otro proveedor:
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"),
)?;
Esta ruta admite chat, transmisión, llamadas a funciones, salida estructurada y
el esfuerzo de razonamiento (reasoning_effort de OpenAI se asigna a los
niveles/presupuestos de pensamiento de Gemini). Las opciones específicas de Gemini —por ejemplo, thinking_config con
include_thoughts, o cached_content— se pasan mediante el mapa
extensions["openai"]["extra_body"]["google"] de la solicitud, que el cliente combina
literalmente con el cuerpo de la solicitud.
Cuándo usar esto en lugar de
GeminiModel: Para las funciones nativas de Gemini (herramientas del servidor, las API de Interactions,ThinkingConfignativo y una ergonomía centrada en lo multimodal), se recomiendaGeminiModel. Usa el ajuste preestablecido compatible con OpenAI cuando quieras un único cliente uniforme entre proveedores.
Ejemplos (requieren GEMINI_API_KEY o 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 de esfuerzo de razonamiento heredado
El ReasoningEffort API original de tres niveles sigue disponible por compatibilidad:
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)?;
Niveles disponibles: Low (más rápido), Medium (equilibrado), High (más exhaustivo).
Modelos disponibles
| Modelo | Descripción | Contexto |
|---|---|---|
gpt-5.6-terra | Opción predeterminada equilibrada para agentes de producción | 256K tokens |
gpt-5.6-sol | Razonamiento y programación de vanguardia | 256K tokens |
gpt-5.6-luna | Cargas de trabajo de gran volumen y rentables | 128K tokens |
gpt-5.6 | Alias insignia | 256K tokens |
Ejemplo de salida
👤 User: Write a haiku about Rust programming
🤖 GPT-5: Memory so safe,
Ownership guards every byte—
Compiler, my friend.
Anthropic (Claude) 🧠 Inteligente
Ideal para: Razonamiento complejo, aplicaciones críticas para la seguridad, documentos extensos
Aspectos destacados:
- 🧠 Capacidad de razonamiento excepcional
- 🛡️ Mayor enfoque en la seguridad
- 📚 Contexto de 200K tokens
- ✍️ Excelente calidad de escritura
Ejemplo 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 disponibles
| Modelo | Descripción | Contexto |
|---|---|---|
claude-sonnet-5 | Inteligencia y coste equilibrados (predeterminado) | 1M tokens |
claude-opus-5 | Capacidad insignia | 1M tokens |
claude-fable-5 | Trabajo creativo premium y de formato largo | 1M tokens |
claude-haiku-4-5 | Generación anterior rentable | 200K tokens |
Ejemplo de salida
👤 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 💭 Pensamiento
Ideal para: Resolución de problemas complejos, matemáticas, programación y tareas de razonamiento
Aspectos destacados:
- 💭 Modo de pensamiento: muestra el razonamiento paso a paso
- 💰 Muy rentable (10 veces más barato que GPT-4)
- 🔄 Almacenamiento en caché del contexto para prefijos repetidos
- 🧮 Excelente en matemáticas y programación
Ejemplo 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("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 disponibles
| Modelo | Descripción | Característica especial |
|---|---|---|
deepseek-v4-flash | Predeterminado actual | Agentes rápidos de propósito general |
deepseek-v4-pro | Razonamiento avanzado | Trabajo complejo con agentes |
Ejemplo de salida (razonador con modo de pensamiento)
👤 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 rápido
Ideal para: aplicaciones en tiempo real, chatbots, tareas críticas en cuanto a velocidad
Aspectos destacados:
- ⚡ Inferencia más rápida: 10 veces más rápida que la de la competencia
- 🔧 Tecnología LPU (Language Processing Unit)
- 💰 Precios competitivos
- 🦙 Ejecuta modelos LLaMA, Mixtral y Gemma
Ejemplo 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 disponibles
| Modelo | Método | Descripción |
|---|---|---|
openai/gpt-oss-120b | GroqClient::new(GroqConfig::gpt_oss_120b(key)) | Predeterminado actual de producción |
openai/gpt-oss-20b | GroqClient::new(GroqConfig::new(key, "openai/gpt-oss-20b")) | Modelo GPT-OSS de menor coste |
| Cualquier modelo | GroqClient::new(GroqConfig::new(key, "model")) | Modelo personalizado |
Ejemplo de salida
👤 User: Quick! Name 5 programming languages
🤖 Groq (in 0.2 seconds):
1. Rust
2. Python
3. JavaScript
4. Go
5. TypeScript
Cambio de proveedores
Todos los proveedores implementan el mismo trait Llm, por lo que cambiar es 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()?;
Ejemplos
Usa cargo-adk para generar proyectos específicos del proveedor con dependencias 0.8 validadas:
cargo adk new gemini_agent --provider gemini
cargo adk new openai_agent --template openai
cargo adk new anthropic_agent --provider anthropic
Los proyectos generados se compilan en CI mediante scripts/check-cargo-adk-templates.sh. La galería completa de ejemplos se mantiene en el repositorio adk-playground.
Relacionado
- Ollama (local) - Ejecuta modelos localmente con Ollama
- Modelos locales (mistral.rs) - Inferencia nativa en Rust
- LlmAgent - Uso de modelos con agentes
- Herramientas de función - Añadir herramientas a los agentes
Anterior: ← Agentes en tiempo real | Siguiente: Ollama (local) →
Qué ocurre con el contenido que un proveedor no puede transportar
Content puede expresar más de lo que acepta cualquier transporte de proveedor individual, por lo que cada adaptador debe decidir qué hacer con el contenido restante. Ahora esas decisiones se registran en lugar de aplicarse de forma invisible. Cada parte se clasifica:
| Disposición | Significado |
|---|---|
Converted | Transferido al proveedor en una forma nativa equivalente |
Downgraded | Transferido en una forma con pérdida: una referencia de archivo representada como texto descriptivo que el modelo puede leer, pero no recuperar |
Omitted | No se transporta en absoluto |
Las degradaciones y omisiones emiten una advertencia tracing al registrarse, indicando el tipo de parte, el tipo MIME y el motivo, para que ninguna pase inadvertida.
Para ver el resultado antes de enviar una solicitud:
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 rechazar una solicitud que llegaría al modelo incompleta, en lugar de recibir una respuesta sobre material que el modelo nunca vio:
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 solo abarca las omisiones. Una degradación aún llega al modelo, y rechazarla impediría la alternativa textual documentada.
Nota: el registro está completo por construcción. Cualquier parte que salga de un adaptador sin un destino registrado —incluida una añadida por un cambio futuro— se registra como una omisión con un "motivo no registrado" explícito, y
adk-model/tests/part_conversion_matrix_tests.rsfalla en ese caso.
Cobertura de Bedrock Converse
| Parte | Disposición |
|---|---|
| Texto, FunctionCall, FunctionResponse, Razonamiento | Converted |
InlineData con JPEG, PNG, GIF, WebP | Converted como bloque de imagen |
InlineData con un tipo de documento compatible (PDF y similares) | Converted como bloque de documento |
InlineData con audio, vídeo o datos binarios arbitrarios | Omitted |
FileData para una imagen o un documento compatible | Downgraded a texto — Converse acepta URIs de S3, no URLs arbitrarios |
FileData para cualquier otro tipo | Omitted |
ServerToolCall, ServerToolResponse | Omitted — específico de Gemini |
EmbeddedResource texto, o un blob de un tipo compatible | Converted |
EmbeddedResource blob de un tipo no compatible | Omitted |