A2A Protocol
Exemple A2A Java

Cloner le Code

git clone https://github.com/google-a2a/a2a-samples
cd a2a-samples/samples/java

Ce projet est un exemple d'implémentation Java du protocole Agent-to-Agent (A2A), fournissant des SDKs client et serveur complets, ainsi qu'une application de démonstration de service de traduction alimentée par l'IA.

Architecture du Projet

Ce projet utilise une architecture Maven multi-modules, contenant les trois modules principaux suivants :

samples/java/
├── model/          # Modèles de Données du Protocole A2A
├── server/         # SDK Serveur A2A & Service de Traduction
├── client/         # SDK Client A2A & Code d'Exemple
└── pom.xml         # Fichier de Configuration Maven Parent

Détails des Modules

🎯 Module Model (model/)

Modèles de données principaux pour le protocole A2A, fournissant des structures de données complètes pour JSON-RPC 2.0 et le protocole A2A :

  • Modèles de Message : Message, Part, TextPart, Artifact
  • Modèles de Tâche : Task, TaskStatus, TaskState
  • Modèles d'Agent : AgentCard, AgentCapabilities, AgentSkill
  • Modèles JSON-RPC : JSONRPCRequest, JSONRPCResponse, JSONRPCError
  • Modèles d'Événement : TaskStatusUpdateEvent, TaskArtifactUpdateEvent

🚀 Module Serveur (server/)

SDK serveur A2A basé sur Spring Boot, intégré avec le framework Spring AI :

  • Composants Principaux :

    • A2AServer : Classe serveur principale gérant le comportement de l'agent
    • A2AController : Contrôleur REST implémentant les endpoints du protocole A2A
    • TaskHandler : Interface de traitement des tâches
    • A2AServerConfiguration : Configuration du bot de traduction IA
  • Fonctionnalités Clés :

    • Support complet de JSON-RPC 2.0
    • Publication de carte d'agent (/.well-known/agent-card)
    • Gestion des tâches (envoi, requête, annulation)
    • Support de réponse en streaming (Server-Sent Events)
    • Intégration Spring AI supportant OpenAI et autres modèles

📱 Module Client (client/)

SDK client A2A Java pur avec des exemples de client de traduction :

  • Composants Principaux :

    • A2AClient : Classe client principale gérant toutes les opérations A2A
    • StreamingEventListener : Interface d'écoute d'événements en streaming
    • A2AClientException : Gestion d'exceptions spécifiques à A2A
    • A2AClientExample : Exemple complet de client de traduction
  • Fonctionnalités Clés :

    • Implémentation client JSON-RPC 2.0
    • Découverte d'agent et requête de capacités
    • Opérations de tâches synchrones/asynchrones
    • Gestion de réponses en streaming
    • Pool de connexions et récupération d'erreurs

Implémentation des Fonctionnalités Principales

🤖 Service de Traduction IA

Le projet implémente un agent de traduction intelligent supportant la traduction multilingue :

Logique de Traduction :

  • Chinois → Anglais
  • Anglais → Chinois
  • Autres langues → Anglais

Fonctionnalités Techniques :

  • Basé sur Spring AI ChatClient
  • Supporte OpenAI, Azure OpenAI et autres modèles
  • Traduction en langage naturel sensible au contexte
  • Réponses en streaming en temps réel

🔄 Implémentation du Protocole A2A

Implémentation complète des spécifications du protocole A2A :

Opérations Principales :

  • tasks/send : Envoyer des messages de tâche
  • tasks/get : Interroger le statut des tâches
  • tasks/cancel : Annuler l'exécution des tâches

Fonctionnalités du Protocole :

  • Communication JSON-RPC 2.0
  • Découverte de capacités d'agent
  • Suivi du statut des tâches
  • Push d'événements en streaming
  • Codes d'erreur standardisés

📡 Mécanismes de Communication

Communication Synchrone :

  • HTTP POST /a2a - Requêtes JSON-RPC standard
  • HTTP GET /.well-known/agent-card - Récupération d'informations d'agent

Communication en Streaming :

  • HTTP POST /a2a/stream - Server-Sent Events
  • Mises à jour de statut de tâche en temps réel
  • Reconnexion automatique et récupération d'erreurs

Comment Exécuter

Prérequis

  • Java : 17 ou supérieur

Étape 1 : Compiler le Projet

Exécuter la compilation dans le répertoire racine du projet :

cd samples/java
./mvnw clean install -DskipTests

Étape 2 : Configurer les Variables d'Environnement

Définir les variables d'environnement liées au modèle IA (requis pour la fonctionnalité de traduction) :

# Configuration OpenAI
export OPENAI_API_KEY="your-openai-api-key"
export OPENAI_BASE_URL="https://api.openai.com"
export OPENAI_CHAT_MODEL="gpt-4o"

# Ou Configuration GCP OpenAI
export OPENAI_API_KEY="your-gcp-api-key"
export OPENAI_BASE_URL="https://{location}-aiplatform.googleapis.com/v1/projects/{project_id}/locations/{location}/endpoints/openapi"
export OPENAI_CHAT_MODEL="gemini-2.5-pro-preview-05-06"

Configuration OpenRouter

export OPENAI_API_KEY="sk-or-v1-"
export OPENAI_BASE_URL="https://openrouter.ai/api"
export OPENAI_CHAT_MODEL="openai/gpt-4o-2024-11-20"

Attention à OPENAI_BASE_URL, il n'y a pas de /v1 dans l'URL.

Étape 3 : Démarrer le Serveur de Traduction

Démarrer le serveur de traduction A2A :

cd server
../mvnw spring-boot:run

Le serveur démarrera à http://localhost:8080, fournissant les endpoints suivants :

  • http://localhost:8080/.well-known/agent-card - Informations d'agent
  • http://localhost:8080/a2a - Endpoint du protocole A2A
  • http://localhost:8080/a2a/stream - Endpoint de streaming

Valider la Carte d'Agent :

Étape 4 : Exécuter le Client de Traduction

Dans une nouvelle fenêtre de terminal, exécuter l'exemple de client :

cd client
../mvnw exec:java -Dexec.mainClass="com.google.a2a.client.A2AClientExample"

Diagramme de Séquence

Le diagramme de séquence suivant illustre le flux d'interaction complet de l'application d'exemple A2A Java, basé sur A2AClientExample.java :

sequenceDiagram
    participant Example as A2AClientExample
    participant Client as A2AClient
    participant Server as A2A Server<br/>(localhost:8080)
    
    Note over Example,Server: Diagramme de Séquence Exemple A2A Java
    
    %% 1. Initialize Client
    Example->>Client: new A2AClient("http://localhost:8080")
    activate Client
    
    %% 2. Get Agent Card
    Example->>Client: getAgentCard()
    Client->>Server: GET /.well-known/agent-card
    Server-->>Client: AgentCard (name, description, version, skills)
    Client-->>Example: AgentCard
    Note over Example: Afficher les informations d'agent
    
    %% 3. French to Chinese Translation
    Example->>Client: sendTask(frenchToChineseParams)
    Note right of Example: TextPart: "Bonjour le monde!<br/>Comment allez-vous?"
    Client->>Server: POST /a2a<br/>JSON-RPC: tasks/send
    Server-->>Client: Task (id, status, history)
    Client-->>Example: JSONRPCResponse<Task>
    Note over Example: Afficher le résultat de traduction
    
    %% 4. Chinese to English Translation
    Example->>Client: sendTask(chineseParams)
    Note right of Example: TextPart: "你好,世界!<br/>欢迎使用AI翻译机器人。"
    Client->>Server: POST /a2a<br/>JSON-RPC: tasks/send
    Server-->>Client: Task (id, status, history)
    Client-->>Example: JSONRPCResponse<Task>
    Note over Example: Afficher le résultat de traduction
    
    %% 5. Streaming Translation
    Example->>Client: sendTaskStreaming(frenchParams, StreamingEventListener)
    Note right of Example: TextPart: "Bonjour le monde!<br/>Comment allez-vous?"
    Client->>Server: POST /a2a/stream<br/>Server-Sent Events
    activate Server
    
    loop Réponse en Streaming
        Server-->>Client: SSE Event (progression de traduction)
        Client-->>Example: onEvent(event)
        Note over Example: Afficher les événements de traduction en temps réel
    end
    
    Server-->>Client: SSE Complete
    deactivate Server
    Client-->>Example: onComplete()
    Note over Example: Traduction en streaming terminée
    
    %% 6. Query Task Status
    Example->>Client: getTask(queryParams)
    Note right of Example: Interroger le statut de la tâche de traduction française
    Client->>Server: POST /a2a<br/>JSON-RPC: tasks/get
    Server-->>Client: Task (statut mis à jour)
    Client-->>Example: JSONRPCResponse<Task>
    Note over Example: Afficher le statut de la tâche
    
    %% 7. Send Task to be Canceled
    Example->>Client: sendTask(cancelParams)
    Note right of Example: TextPart: "Diese Übersetzung<br/>wird abgebrochen." (Allemand)
    Client->>Server: POST /a2a<br/>JSON-RPC: tasks/send
    Server-->>Client: Task (id, status)
    Client-->>Example: JSONRPCResponse<Task>
    
    %% 8. Cancel Task
    Example->>Client: cancelTask(cancelTaskParams)
    Client->>Server: POST /a2a<br/>JSON-RPC: tasks/cancel
    Server-->>Client: Task (statut annulé)
    Client-->>Example: JSONRPCResponse<Task>
    Note over Example: Afficher le résultat d'annulation
    
    deactivate Client
    Note over Example,Server: Exécution du programme d'exemple terminée

Modèles d'Interaction Clés

Le diagramme de séquence démontre les modèles d'interaction principaux suivants :

  1. Initialisation du Client : Création d'une instance A2AClient connectée au serveur local
  2. Découverte d'Agent : Récupération d'informations d'agent via l'endpoint /.well-known/agent-card
  3. Exemples de Traduction Multilingue :
    • Traduction Français → Chinois
    • Traduction Chinois → Anglais
    • Traduction en streaming Allemand → Anglais
  4. Gestion des Tâches :
    • Interrogation du statut des tâches
    • Annulation de l'exécution des tâches

Mécanismes de Communication

  • Traduction Synchrone : Utilisation de l'endpoint POST /a2a avec des requêtes JSON-RPC
  • Traduction en Streaming : Utilisation de l'endpoint POST /a2a/stream avec Server-Sent Events (SSE)
  • Requêtes de Statut : Utilisation de la méthode tasks/get pour vérifier le statut d'exécution des tâches
  • Annulation de Tâche : Utilisation de la méthode tasks/cancel pour annuler les tâches en cours

Exemples d'Utilisation de l'API

Obtenir les Informations d'Agent

curl -X GET http://localhost:8080/.well-known/agent-card \
  -H "Accept: application/json"

Envoyer une Tâche de Traduction

curl -X POST http://localhost:8080/a2a \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": "request-1",
    "method": "tasks/send",
    "params": {
      "id": "translation-task-1",
      "message": {
        "messageId": "msg-1",
        "kind": "message",
        "role": "user",
        "parts": [
          {
            "kind": "text",
            "text": "Hello, world!"
          }
        ]
      }
    }
  }'

Traduction en Streaming

curl -X POST http://localhost:8080/a2a/stream \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": "stream-request-1",
    "method": "tasks/send",
    "params": {
      "id": "streaming-translation-task",
      "message": {
        "messageId": "stream-msg-1",
        "kind": "message",
        "role": "user",
        "parts": [
          {
            "kind": "text",
            "text": "Hello world!"
          }
        ]
      }
    }
  }'