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

ProveedorIdeal paraVelocidadCosteCaracterística principal
GeminiUso general⚡⚡⚡💰Multimodal, contexto amplio, razonamiento
OpenAIFiabilidad⚡⚡💰💰Mejor ecosistema
AnthropicRazonamiento complejo⚡⚡💰💰El más seguro y reflexivo
DeepSeekCadena de pensamiento⚡⚡💰Modo de razonamiento, económico
GroqVelocidad 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:

ProveedorAdaptador de esquemaComportamiento
GeminiGeminiSchemaAdapterAgresivo: resuelve $ref, colapsa los combinadores y elimina las palabras clave no compatibles
OpenAI (estricto)OpenAiStrictSchemaAdapterConserva la estructura y añade additionalProperties: false
OpenAIOpenAiSchemaAdapterCorrecciones mínimas seguras
AnthropicAnthropicSchemaAdapterCasi sin modificaciones
DeepSeekGenericSchemaAdapterTransformaciones seguras conservadoras
OllamaGenericSchemaAdapterTransformaciones 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

ModeloDescripciónContexto
gemini-3.7-flashModelo de agente equilibrado predeterminado1M tokens
gemini-3.6-flashGeneración equilibrada anterior1M tokens
gemini-3.5-flash-liteEnrutamiento rentable y tareas de gran volumen1M tokens
gemini-3.1-pro-previewRazonamiento avanzado en vista previa2M 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.

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/responses con 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, ThinkingConfig nativo y una ergonomía centrada en lo multimodal), se recomienda GeminiModel. 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

ModeloDescripciónContexto
gpt-5.6-terraOpción predeterminada equilibrada para agentes de producción256K tokens
gpt-5.6-solRazonamiento y programación de vanguardia256K tokens
gpt-5.6-lunaCargas de trabajo de gran volumen y rentables128K tokens
gpt-5.6Alias insignia256K 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

ModeloDescripciónContexto
claude-sonnet-5Inteligencia y coste equilibrados (predeterminado)1M tokens
claude-opus-5Capacidad insignia1M tokens
claude-fable-5Trabajo creativo premium y de formato largo1M tokens
claude-haiku-4-5Generación anterior rentable200K 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

ModeloDescripciónCaracterística especial
deepseek-v4-flashPredeterminado actualAgentes rápidos de propósito general
deepseek-v4-proRazonamiento avanzadoTrabajo 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

ModeloMétodoDescripción
openai/gpt-oss-120bGroqClient::new(GroqConfig::gpt_oss_120b(key))Predeterminado actual de producción
openai/gpt-oss-20bGroqClient::new(GroqConfig::new(key, "openai/gpt-oss-20b"))Modelo GPT-OSS de menor coste
Cualquier modeloGroqClient::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.



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ónSignificado
ConvertedTransferido al proveedor en una forma nativa equivalente
DowngradedTransferido en una forma con pérdida: una referencia de archivo representada como texto descriptivo que el modelo puede leer, pero no recuperar
OmittedNo 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.rs falla en ese caso.

Cobertura de Bedrock Converse

ParteDisposición
Texto, FunctionCall, FunctionResponse, RazonamientoConverted
InlineData con JPEG, PNG, GIF, WebPConverted 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 arbitrariosOmitted
FileData para una imagen o un documento compatibleDowngraded a texto — Converse acepta URIs de S3, no URLs arbitrarios
FileData para cualquier otro tipoOmitted
ServerToolCall, ServerToolResponseOmitted — específico de Gemini
EmbeddedResource texto, o un blob de un tipo compatibleConverted
EmbeddedResource blob de un tipo no compatibleOmitted
Proveedores de modelos (nube) - Documentación ADK-Rust | ADK-Rust