Servidor API

El servidor ADK-Rust proporciona un REST API para ejecutar agentes, gestionar sesiones y acceder a artefactos. Cuando implementas tu agente mediante Launcher en modo servidor, expone estos endpoints junto con una interfaz web.

Descripción general

El servidor está basado en Axum y proporciona:

  • REST API: endpoints HTTP para la ejecución de agentes y la gestión de sesiones
  • Eventos enviados por el servidor (SSE): transmisión en tiempo real de las respuestas del agente
  • Interfaz web: interfaz interactiva basada en el navegador
  • Compatibilidad con CORS: solicitudes de origen cruzado habilitadas
  • Telemetría: observabilidad integrada con tracing

ServerConfig también expone un passthrough a nivel del ejecutor para implementaciones de larga duración:

let config = ServerConfig::new(agent_loader, session_service)
    .with_compaction(compaction_config)
    .with_context_cache(context_cache_config, cache_capable_model);

Iniciar el servidor

Usa Launcher para iniciar el servidor:

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<()> {
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = Arc::new(GeminiModel::new(&api_key, "gemini-3.7-flash")?);
    
    let agent = LlmAgentBuilder::new("my_agent")
        .description("A helpful assistant")
        .instruction("You are a helpful assistant.")
        .model(model)
        .build()?;
    
    Launcher::new(Arc::new(agent)).run().await
}

Inicia desde el scaffold API validado:

cargo adk new my-api --template api
cd my-api
cargo run

Endpoints REST API

Comprobación de estado

Comprueba si el servidor está en ejecución:

GET /api/health

Respuesta:

OK

Ejecutar el agente con transmisión

Ejecuta un agente y transmite las respuestas mediante eventos enviados por el servidor:

POST /api/run_sse

Cuerpo de la solicitud:

{
  "appName": "my_agent",
  "userId": "user123",
  "sessionId": "session456",
  "newMessage": {
    "role": "user",
    "parts": [
      {
        "text": "What is the capital of France?"
      }
    ]
  },
  "streaming": true
}

Respuesta:

  • Content-Type: text/event-stream
  • Transmite eventos como objetos JSON

Formato del evento:

{
  "id": "evt_123",
  "timestamp": 1234567890,
  "author": "my_agent",
  "content": {
    "role": "model",
    "parts": [
      {
        "text": "The capital of France is Paris."
      }
    ]
  },
  "actions": {},
  "llm_response": {
    "content": {
      "role": "model",
      "parts": [
        {
          "text": "The capital of France is Paris."
        }
      ]
    }
  }
}

Ejecutar el agente (sin transmisión)

Ejecuta un agente hasta completarlo y recibe todos los eventos en una única respuesta JSON:

POST /api/run

Cuerpo de la solicitud: misma estructura que POST /api/run_sse (el campo streaming se ignora):

{
  "appName": "my_agent",
  "userId": "user123",
  "sessionId": "session456",
  "newMessage": {
    "role": "user",
    "parts": [
      {
        "text": "What is the capital of France?"
      }
    ]
  }
}

Respuesta:

  • Content-Type: application/json
  • Un array JSON que contiene todos los eventos producidos por la ejecución, en orden, utilizando el mismo formato de evento que /api/run_sse

Este endpoint refleja la ruta /run sin transmisión de api_server de Google ADK.

Gestión de sesiones

Crear sesión

Crear una nueva sesión:

POST /api/sessions

Cuerpo de la solicitud:

{
  "appName": "my_agent",
  "userId": "user123",
  "sessionId": "session456"
}

Respuesta:

{
  "id": "session456",
  "appName": "my_agent",
  "userId": "user123",
  "lastUpdateTime": 1234567890,
  "events": [],
  "state": {}
}

Obtener sesión

Recuperar los detalles de una sesión:

GET /api/sessions/:app_name/:user_id/:session_id

Respuesta:

{
  "id": "session456",
  "appName": "my_agent",
  "userId": "user123",
  "lastUpdateTime": 1234567890,
  "events": [],
  "state": {}
}

Eliminar sesión

Eliminar una sesión:

DELETE /api/sessions/:app_name/:user_id/:session_id

Respuesta:

  • Estado: 204 No Content

Enumerar sesiones

Enumerar todas las sesiones de un usuario:

GET /api/apps/:app_name/users/:user_id/sessions

Respuesta:

[
  {
    "id": "session456",
    "appName": "my_agent",
    "userId": "user123",
    "lastUpdateTime": 1234567890,
    "events": [],
    "state": {}
  }
]

Gestión de artefactos

Enumerar artefactos

Enumerar todos los artefactos de una sesión:

GET /api/sessions/:app_name/:user_id/:session_id/artifacts

Respuesta:

[
  "image1.png",
  "document.pdf",
  "data.json"
]

Obtener artefacto

Descargar un artefacto:

GET /api/sessions/:app_name/:user_id/:session_id/artifacts/:artifact_name

Respuesta:

  • Tipo de contenido: Determinado por la extensión del archivo
  • Cuerpo: Contenido binario o de texto

Gestión de aplicaciones

Enumerar aplicaciones

Enumerar todos los agentes disponibles:

GET /api/apps
GET /api/list-apps  (legacy compatibility)

Respuesta:

{
  "apps": [
    {
      "name": "my_agent",
      "description": "A helpful assistant"
    }
  ]
}

Interfaz web

El servidor incluye una interfaz web integrada disponible en:

http://localhost:8080/ui/

Solicitar a un agente, seguir una transferencia animada entre equipos e inspeccionar la telemetría en la interfaz de usuario del entorno de ejecución integrado

La guía rápida de cinco minutos crea la estructura de un servidor respaldado por OpenAI y abre esta interfaz con cuatro comandos. La grabación utiliza un equipo para hacer visible el borde de la topología activa; los agentes hoja, las herramientas, los grafos, los flujos de trabajo, los agentes en tiempo real y los agentes remotos utilizan la misma interfaz.

Funciones

  • Ejecuciones interactivas: Envía mensajes y archivos adjuntos, e inspecciona Markdown renderizado de forma segura, texto transmitido, llamadas a herramientas, fallos y transferencias
  • Gestión de sesiones: Crea, visualiza y cambia entre sesiones
  • Topología de equipo portable: Distingue las conexiones exactas de delegación y retorno de las transferencias de control, con animación al estilo de Studio Next para el miembro activo y la conexión entrante
  • Inspector del tiempo de ejecución: Inspecciona eventos ordenados, spans de telemetría dedicados, el estado compartido y de la sesión, los servicios configurados del tiempo de ejecución, el descubrimiento de A2A y la compatibilidad con el protocolo de Apps de UI/MCP
  • Reproducción en tiempo real: Reconoce agentes en tiempo real, combina los deltas de la transcripción y reproduce la salida PCM completada como audio WAV
  • Visor de artefactos: Visualiza y descarga artefactos de sesión
  • Temas adaptables: Diseños del sistema, claros y oscuros accesibles mediante teclado, sin recursos externos

Rutas de la interfaz de usuario

  • / - Redirige a /ui/
  • /ui/ - Interfaz principal de chat
  • /ui/assets/* - Recursos estáticos (CSS, JS, imágenes)
  • /ui/assets/config/runtime-config.json - Configuración del tiempo de ejecución
  • /api/ui/agents/{name} - Capacidades, jerarquía y metadatos de topología portable del agente

La interfaz se mantiene en adk-server/webui y su compilación de producción está integrada en el crate del servidor, por lo que los proyectos generados y las implementaciones utilizan la misma interfaz de usuario del tiempo de ejecución sin un servicio de frontend independiente.

La interfaz de usuario de tiempo de ejecución ejecutable incluye recorridos guiados y capturas de pantalla independientes basados en OpenAI para un agente que realiza llamadas a herramientas, un flujo de trabajo de grafo determinista y un equipo de delegación portátil. La galería avanzada de agentes añade un programador ambiental, reproducción de voz en tiempo real de OpenAI, descubrimiento de A2A, descubrimiento de MCP 2026-07-28 con tareas SEP-2663, y servicios configurados de telemetría, artefactos y memoria en un solo servidor. La marca ADK Runtime enlaza a adk-rust.com en una pestaña nueva.

Ejemplos de cliente

JavaScript/TypeScript

Uso de Fetch API con SSE:

async function runAgent(message) {
  const response = await fetch('http://localhost:8080/api/run_sse', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      appName: 'my_agent',
      userId: 'user123',
      sessionId: 'session456',
      newMessage: {
        role: 'user',
        parts: [{ text: message }]
      },
      streaming: true
    })
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    
    const chunk = decoder.decode(value);
    const lines = chunk.split('\n');
    
    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const event = JSON.parse(line.slice(6));
        console.log('Event:', event);
      }
    }
  }
}

Python

Uso de la biblioteca requests:

import requests
import json

def run_agent(message):
    url = 'http://localhost:8080/api/run_sse'
    payload = {
        'appName': 'my_agent',
        'userId': 'user123',
        'sessionId': 'session456',
        'newMessage': {
            'role': 'user',
            'parts': [{'text': message}]
        },
        'streaming': True
    }
    
    response = requests.post(url, json=payload, stream=True)
    
    for line in response.iter_lines():
        if line:
            line_str = line.decode('utf-8')
            if line_str.startswith('data: '):
                event = json.loads(line_str[6:])
                print('Event:', event)

run_agent('What is the capital of France?')

cURL

# Create session
curl -X POST http://localhost:8080/api/sessions \
  -H "Content-Type: application/json" \
  -d '{
    "appName": "my_agent",
    "userId": "user123",
    "sessionId": "session456"
  }'

# Run agent with streaming
curl -X POST http://localhost:8080/api/run_sse \
  -H "Content-Type: application/json" \
  -d '{
    "appName": "my_agent",
    "userId": "user123",
    "sessionId": "session456",
    "newMessage": {
      "role": "user",
      "parts": [{"text": "What is the capital of France?"}]
    },
    "streaming": true
  }'

Configuración del servidor

Puerto personalizado

Para usar un puerto personalizado, establece PORT antes de iniciar el servidor generado:

PORT=3000 cargo run

Servicio de artefactos personalizado

Proporciona tu propio servicio de artefactos:

use adk_artifact::InMemoryArtifactService;

let artifact_service = Arc::new(InMemoryArtifactService::new());

Launcher::new(Arc::new(agent))
    .with_artifact_service(artifact_service)
    .run()
    .await

Servicio de sesiones personalizado

Para implementaciones en producción, utiliza un servicio de sesiones persistente:

use adk_session::SqliteSessionService;

// Note: This requires implementing a custom server setup
// The Launcher uses InMemorySessionService by default

Gestión de errores

API utiliza respuestas de error estructuradas con códigos de estado HTTP derivados de la categoría del error:

Código de estadoCategoríaSignificado
200—Éxito
204—Éxito (sin contenido)
400invalid_inputSolicitud incorrecta — parámetros o configuración no válidos
401unauthorizedCredenciales faltantes o no válidas
403forbiddenCredenciales válidas, permisos insuficientes
404not_foundRecurso no encontrado
408timeoutLa operación agotó el tiempo de espera
429rate_limitedSe superó el límite de velocidad ascendente
500internalError interno del servidor
501unsupportedFuncionalidad no compatible
503unavailableServicio ascendente no disponible

Formato de respuesta de error (Problema JSON):

{
  "error": {
    "code": "model.openai.rate_limited",
    "message": "OpenAI rate limit exceeded",
    "component": "model",
    "category": "rate_limited",
    "requestId": "req-abc123",
    "retryAfter": 5000,
    "upstreamStatusCode": 429
  }
}

Los campos requestId, retryAfter y upstreamStatusCode se incluyen cuando están disponibles (de lo contrario, null).

Configuración de CORS

El servidor habilita CORS permisivo de forma predeterminada, lo que permite solicitudes desde cualquier origen. Esto es adecuado para el desarrollo, pero debe restringirse en producción.

Telemetría

El servidor inicializa automáticamente la telemetría al iniciarse. Los registros se envían a stdout con formato estructurado.

Niveles de registro:

  • ERROR: Errores críticos
  • WARN: Advertencias
  • INFO: Información general (predeterminado)
  • DEBUG: Depuración detallada
  • TRACE: Seguimiento muy detallado

Establece el nivel de registro con la variable de entorno RUST_LOG:

RUST_LOG=debug cargo run

Prácticas recomendadas

  1. Gestión de sesiones: Crea siempre una sesión antes de ejecutar un agente
  2. Gestión de errores: Comprueba los códigos de estado de HTTP y gestiona los errores adecuadamente
  3. Streaming: Usa SSE para obtener respuestas en tiempo real; analiza los eventos línea por línea
  4. Seguridad: En producción, implementa autenticación y restringe CORS
  5. Persistencia: Usa SqliteSessionService o PostgresSessionService para implementaciones en producción
  6. Supervisión: Habilita la telemetría y supervisa los registros para detectar problemas

Ejemplo de pila completa

Para obtener un andamiaje de servidor completo y funcional, usa la plantilla validada de cargo-adk API. Esto demuestra:

  • Frontend: Cliente HTML/JavaScript con streaming en tiempo real
  • Backend: Agente ADK con herramientas personalizadas de investigación y generación de PDF
  • Integración: Uso completo de REST API con streaming de SSE
  • Artefactos: Generación y descarga de PDF
  • Gestión de sesiones: Creación y gestión automáticas de sesiones

El ejemplo muestra un patrón listo para producción para crear aplicaciones web impulsadas por IA con ADK-Rust.

Inicio rápido:

cargo adk new my-api --template api
cd my-api
cargo run

Archivos:

  • Backend: adk-rust-guide/examples/deployment/full_stack_research.rs
  • Frontend: examples/research_paper/frontend.html
  • Documentación: examples/research_paper/README.md
  • Arquitectura: examples/research_paper/architecture.md

Anterior: ← Lanzador | Siguiente: A2A Protocolo →