API Serveur

Le serveur ADK-Rust fournit une API REST pour exécuter des Agent, gérer des Session, et accéder aux artefacts. Lorsque vous déployez votre Agent en utilisant le Launcher en mode serveur, il expose ces points de terminaison ainsi qu'une interface utilisateur web.

Aperçu

Le serveur est construit sur Axum et fournit :

  • API REST : Points de terminaison HTTP pour l'exĂ©cution d'Agent et la gestion de Session
  • Server-Sent Events (SSE) : Diffusion en temps rĂ©el des rĂ©ponses d'Agent
  • Interface utilisateur web : Interface interactive basĂ©e sur un navigateur
  • Support CORS : RequĂȘtes inter-origines activĂ©es
  • TĂ©lĂ©mĂ©trie : ObservabilitĂ© intĂ©grĂ©e avec traçage

ServerConfig expose également un passthrough au niveau du Runner pour les déploiements à long terme :

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

Démarrage du Serveur

Utilisez le Launcher pour démarrer le serveur :

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-2.5-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
}

Démarrez à partir de l'échafaudage d'API validé :

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

Points de terminaison de l'API REST

Vérification de l'état de santé

Vérifiez si le serveur est en cours d'exécution :

GET /api/health

Réponse :

OK

Exécuter un Agent avec Streaming

Exécutez un Agent et diffusez les réponses à l'aide des Server-Sent Events :

POST /api/run_sse

Corps de la requĂȘte :

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

Réponse :

  • Content-Type: text/event-stream
  • Diffuse les Ă©vĂ©nements sous forme d'objets JSON

Format de l'événement :

{
  "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."
        }
      ]
    }
  }
}

Gestion des Session

Créer une Session

Créez une nouvelle Session :

POST /api/sessions

Corps de la requĂȘte :

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

Réponse :

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

Obtenir une Session

Récupérez les détails de la Session :

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

Réponse :

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

Supprimer une Session

Supprimez une Session :

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

Réponse :

  • Statut : 204 No Content

Lister les Session

Listez toutes les Session pour un utilisateur :

GET /api/apps/:app_name/users/:user_id/sessions
[
  {
    "id": "session456",
    "appName": "my_agent",
    "userId": "user123",
    "lastUpdateTime": 1234567890,
    "events": [],
    "state": {}
  }
]

Gestion des artefacts

Lister les artefacts

Lister tous les artefacts d'une session :

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

Réponse :

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

Obtenir un artefact

Télécharger un artefact :

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

Réponse :

  • Content-Type : DĂ©terminĂ© par l'extension du fichier
  • Corps : Contenu binaire ou textuel

Gestion des applications

Lister les applications

Lister tous les agents disponibles :

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

Réponse :

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

Interface utilisateur web

Le serveur inclut une interface utilisateur web intégrée accessible à l'adresse :

http://localhost:8080/ui/

Fonctionnalités

  • Chat interactif : Envoyez des messages et recevez des rĂ©ponses en streaming
  • Gestion de session : CrĂ©ez, visualisez et basculez entre les sessions
  • Prise en charge multi-agents : Visualisez les transferts et les hiĂ©rarchies d'agents
  • Visionneuse d'artefacts : Visualisez et tĂ©lĂ©chargez les artefacts de session
  • Mises Ă  jour en temps rĂ©el : Streaming basĂ© sur SSE pour des rĂ©ponses instantanĂ©es

Routes de l'interface utilisateur

  • / - Redirige vers /ui/
  • /ui/ - Interface de chat principale
  • /ui/assets/* - Actifs statiques (CSS, JS, images)
  • /ui/assets/config/runtime-config.json - Configuration d'exĂ©cution

Exemples de clients

JavaScript/TypeScript

Utilisation de l'API Fetch avec 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

Utilisation de la bibliothĂšque 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
  }'

Configuration du serveur

Port personnalisé

Pour un port personnalisé, définissez PORT avant de démarrer le serveur généré :

PORT=3000 cargo run

Service d'artefacts personnalisé

Fournissez votre propre service d'artefacts :

use adk_artifact::InMemoryArtifactService;

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

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

Service de session personnalisé

Pour les déploiements en production, utilisez un service de session persistant :

use adk_session::SqliteSessionService;

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

Gestion des erreurs

L'API utilise des réponses d'erreur structurées avec des codes d'état HTTP dérivés de la catégorie d'erreur :

Code d'étatCatégorieSignification
200—Succùs
204—Succùs (Pas de contenu)
400invalid_inputMauvaise requĂȘte — paramĂštres ou configuration invalides
401unauthorizedIdentifiants manquants ou invalides
403forbiddenIdentifiants valides, permissions insuffisantes
404not_foundRessource introuvable
408timeoutOpération expirée
429rate_limitedLimite de débit en amont dépassée
500internalErreur interne du serveur
501unsupportedFonctionnalité non supportée
503unavailableService en amont indisponible

Format de la réponse d'erreur (Problem JSON) :

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

Les champs requestId, retryAfter et upstreamStatusCode sont inclus s'ils sont disponibles (null autrement).

Configuration CORS

Le serveur active le CORS permissif par dĂ©faut, autorisant les requĂȘtes de n'importe quelle origine. Ceci convient au dĂ©veloppement mais devrait ĂȘtre restreint en production.

Télémétrie

Le serveur initialise automatiquement la télémétrie au démarrage. Les logs sont émis vers la sortie standard (stdout) avec un formatage structuré.

Niveaux de journalisation :

  • ERROR : Erreurs critiques
  • WARN : Avertissements
  • INFO : Informations gĂ©nĂ©rales (par dĂ©faut)
  • DEBUG : DĂ©bogage dĂ©taillĂ©
  • TRACE : Traçage trĂšs dĂ©taillĂ©

Définissez le niveau de journalisation avec la variable d'environnement RUST_LOG :

RUST_LOG=debug cargo run

Bonnes pratiques

  1. Gestion de Session: Toujours créer une Session avant d'exécuter un Agent
  2. Gestion des erreurs: Vérifier les codes d'état HTTP et gérer les erreurs de maniÚre appropriée
  3. Streaming: Utiliser SSE pour les réponses en temps réel ; analyser les événements ligne par ligne
  4. Sécurité: En production, implémenter l'authentification et restreindre CORS
  5. Persistance: Utiliser SqliteSessionService ou PostgresSessionService pour les déploiements en production
  6. Surveillance: Activer la télémétrie et surveiller les journaux pour les problÚmes

Exemple Full-Stack

Pour un échafaudage de serveur fonctionnel complet, utilisez le modÚle d'API cargo-adk validé. Cela démontre :

  • Frontend: Client HTML/JavaScript avec streaming en temps rĂ©el
  • Backend: Agent ADK avec des outils de recherche personnalisĂ©s et de gĂ©nĂ©ration de PDF
  • IntĂ©gration: Utilisation complĂšte de l'API REST avec streaming SSE
  • Artefacts: GĂ©nĂ©ration et tĂ©lĂ©chargement de PDF
  • Gestion de Session: CrĂ©ation et gestion automatiques des Sessions

L'exemple montre un modĂšle prĂȘt pour la production pour la crĂ©ation d'applications web basĂ©es sur l'IA avec ADK-Rust.

Démarrage rapide :

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

Fichiers :

  • Backend: adk-rust-guide/examples/deployment/full_stack_research.rs
  • Frontend: examples/research_paper/frontend.html
  • Documentation: examples/research_paper/README.md
  • Architecture: examples/research_paper/architecture.md

PrĂ©cĂ©dent: ← Lanceur | Suivant: A2A Protocol →

API Serveur - Documentation ADK-Rust | ADK-Rust