Guide Complet du SDK A2A JS : Guide de Démarrage Rapide
Table des Matières
- Qu'est-ce que le SDK A2A JS ?
- Installation et Configuration d'A2A JS
- Concepts Fondamentaux d'A2A JS
- Création de Votre Premier Agent A2A JS
- Développement Serveur A2A JS
- Utilisation du Client A2A JS
- Fonctionnalités Avancées d'A2A JS
- Meilleures Pratiques A2A JS
- Dépannage A2A JS
Qu'est-ce que le SDK A2A JS ?
Le SDK A2A JS est une bibliothèque puissante conçue spécifiquement pour les développeurs JavaScript/TypeScript qui souhaitent créer des applications d'agents intelligents conformes au Protocole Agent2Agent (A2A). Grâce à ce framework A2A JS, les développeurs peuvent facilement créer des systèmes d'agents intelligents capables de communiquer et de collaborer entre eux.
Avantages Clés d'A2A JS
- 🚀 Facilité d'utilisation : A2A JS fournit une API intuitive pour un démarrage rapide
- 🔄 Communication en Temps Réel : Support du traitement en streaming et des Server-Sent Events (SSE)
- 🛡️ Sécurité des Types : Basé sur TypeScript, offre un support complet des types
- 🌐 Multiplateforme : A2A JS peut fonctionner dans les environnements Node.js et navigateur
- 📡 Protocole Standard : Implémentation complète de la spécification du Protocole A2A
Installation et Configuration d'A2A JS
Installation du SDK A2A JS
Installez le SDK A2A JS en utilisant npm :
npm install @a2a-js/sdk
Ou utilisez yarn :
yarn add @a2a-js/sdk
Vérification de l'Installation d'A2A JS
Créez un fichier de test simple pour vérifier l'installation correcte d'A2A JS :
import { A2AClient, AgentCard } from "@a2a-js/sdk";
console.log("SDK A2A JS installé avec succès !");
Concepts Fondamentaux d'A2A JS
Avant de commencer à utiliser A2A JS, il est important de comprendre les concepts fondamentaux suivants :
1. Carte d'Agent
Chaque agent A2A JS nécessite une carte d'agent qui décrit ses capacités et son interface :
import { AgentCard } from "@a2a-js/sdk";
const agentCard: AgentCard = {
name: 'Mon Agent A2A JS',
description: 'Agent intelligent construit avec le SDK A2A JS',
url: 'http://localhost:3000/',
provider: {
organization: 'Développeur A2A JS',
url: 'https://example.com'
},
version: '1.0.0',
capabilities: {
streaming: true,
pushNotifications: false,
stateTransitionHistory: true,
},
skills: [{
id: 'general_chat',
name: 'Chat Général',
description: 'Conversation générale utilisant A2A JS',
tags: ['chat', 'a2a-js'],
examples: ['Bonjour', 'Aide à répondre aux questions']
}]
};
2. Exécuteur d'Agent
La logique d'exécution principale d'A2A JS est implémentée via l'AgentExecutor :
import { AgentExecutor, RequestContext, IExecutionEventBus } from "@a2a-js/sdk";
class MyA2AJSExecutor implements AgentExecutor {
async execute(
requestContext: RequestContext,
eventBus: IExecutionEventBus
): Promise<void> {
// Logique de l'agent A2A JS
console.log("Traitement de la requête de l'agent A2A JS...");
}
async cancelTask(taskId: string, eventBus: IExecutionEventBus): Promise<void> {
console.log(`Annulation de la tâche A2A JS : ${taskId}`);
}
}
Création de Votre Premier Agent A2A JS
Créons un exemple complet d'agent utilisant le SDK A2A JS :
Étape 1 : Définir la Carte d'Agent A2A JS
import { AgentCard } from "@a2a-js/sdk";
const myAgentCard: AgentCard = {
name: 'Agent Hello World A2A JS',
description: 'Mon premier agent A2A JS pour apprendre le SDK',
url: 'http://localhost:3000/',
provider: {
organization: 'Tutoriel A2A JS',
url: 'https://example.com'
},
version: '1.0.0',
capabilities: {
streaming: true,
pushNotifications: false,
stateTransitionHistory: true,
},
defaultInputModes: ['text/plain'],
defaultOutputModes: ['text/plain'],
skills: [{
id: 'hello_world',
name: 'Hello World',
description: 'Compétence exemple A2A JS : répondre aux salutations',
tags: ['hello', 'greeting', 'a2a-js'],
examples: [
'Bonjour',
'Bienvenue',
'Parle-moi d\'A2A JS'
],
inputModes: ['text/plain'],
outputModes: ['text/plain']
}],
supportsAuthenticatedExtendedCard: false,
};
Étape 2 : Implémentation de l'Exécuteur A2A JS
import {
AgentExecutor,
RequestContext,
IExecutionEventBus,
Task,
TaskState,
TaskStatusUpdateEvent
} from "@a2a-js/sdk";
import { v4 as uuidv4 } from "uuid";
class HelloWorldA2AJSExecutor implements AgentExecutor {
private cancelledTasks = new Set<string>();
async cancelTask(taskId: string, eventBus: IExecutionEventBus): Promise<void> {
this.cancelledTasks.add(taskId);
console.log(`Annulation de la tâche par l'exécuteur A2A JS : ${taskId}`);
}
async execute(
requestContext: RequestContext,
eventBus: IExecutionEventBus
): Promise<void> {
const userMessage = requestContext.userMessage;
const existingTask = requestContext.task;
const taskId = existingTask?.id || uuidv4();
const contextId = userMessage.contextId || existingTask?.contextId || uuidv4();
console.log(`Traitement du message par l'agent A2A JS : ${userMessage.parts[0]?.text}`);
// Créer une nouvelle tâche
if (!existingTask) {
const initialTask: Task = {
kind: 'task',
id: taskId,
contextId: contextId,
status: {
state: TaskState.Submitted,
timestamp: new Date().toISOString(),
},
history: [userMessage],
metadata: userMessage.metadata,
artifacts: [],
};
eventBus.publish(initialTask);
}
// Publier la mise à jour du statut
const workingUpdate: TaskStatusUpdateEvent = {
kind: 'status-update',
taskId: taskId,
contextId: contextId,
status: {
state: TaskState.Working,
message: {
kind: 'message',
role: 'agent',
messageId: uuidv4(),
parts: [{ kind: 'text', text: 'L\'agent A2A JS réfléchit...' }],
taskId: taskId,
contextId: contextId,
},
timestamp: new Date().toISOString(),
},
final: false,
};
eventBus.publish(workingUpdate);
// Simuler le temps de traitement
await new Promise(resolve => setTimeout(resolve, 1000));
// Vérifier l'état d'annulation
if (this.cancelledTasks.has(taskId)) {
const cancelledUpdate: TaskStatusUpdateEvent = {
kind: 'status-update',
taskId: taskId,
contextId: contextId,
status: {
state: TaskState.Canceled,
timestamp: new Date().toISOString(),
},
final: true,
};
eventBus.publish(cancelledUpdate);
return;
}
// Générer la réponse
const userText = userMessage.parts[0]?.text || '';
let responseText = '';
if (userText.toLowerCase().includes('hello') || userText.toLowerCase().includes('hi')) {
responseText = `Bonjour ! Bienvenue dans le SDK A2A JS ! Je suis un agent intelligent construit avec A2A JS.`;
} else if (userText.toLowerCase().includes('a2a js')) {
responseText = `Le SDK A2A JS est une puissante bibliothèque JavaScript pour créer des applications d'agents intelligents !`;
} else {
responseText = `Je suis un agent A2A JS et j'ai reçu votre message : "${userText}". Merci d'utiliser le SDK A2A JS !`;
}
// Publier le résultat final
const finalUpdate: TaskStatusUpdateEvent = {
kind: 'status-update',
taskId: taskId,
contextId: contextId,
status: {
state: TaskState.Completed,
message: {
kind: 'message',
role: 'agent',
messageId: uuidv4(),
parts: [{ kind: 'text', text: responseText }],
taskId: taskId,
contextId: contextId,
},
timestamp: new Date().toISOString(),
},
final: true,
};
eventBus.publish(finalUpdate);
}
}
Étape 3 : Démarrer le Serveur A2A JS
import express from 'express';
import {
A2AExpressApp,
DefaultRequestHandler,
InMemoryTaskStore
} from "@a2a-js/sdk";
const taskStore = new InMemoryTaskStore();
const agentExecutor = new HelloWorldA2AJSExecutor();
const requestHandler = new DefaultRequestHandler(
myAgentCard,
taskStore,
agentExecutor
);
const appBuilder = new A2AExpressApp(requestHandler);
const expressApp = appBuilder.setupRoutes(express(), '');
const PORT = process.env.PORT || 3000;
expressApp.listen(PORT, () => {
console.log(`Serveur agent A2A JS démarré sur http://localhost:${PORT}`);
console.log(`Carte d'agent A2A JS : http://localhost:${PORT}/.well-known/agent.json`);
console.log('Appuyez sur Ctrl+C pour arrêter le serveur A2A JS');
});
Développement Serveur A2A JS
Stockage des Tâches
A2A JS fournit un stockage de tâches en mémoire et permet également l'implémentation de stockages personnalisés :
import { TaskStore, Task } from "@a2a-js/sdk";
class CustomA2AJSTaskStore implements TaskStore {
private tasks = new Map<string, Task>();
async getTask(taskId: string): Promise<Task | undefined> {
console.log(`Récupération de la tâche A2A JS : ${taskId}`);
return this.tasks.get(taskId);
}
async setTask(task: Task): Promise<void> {
console.log(`Sauvegarde de la tâche A2A JS : ${task.id}`);
this.tasks.set(task.id, task);
}
async deleteTask(taskId: string): Promise<void> {
console.log(`Suppression de la tâche A2A JS : ${taskId}`);
this.tasks.delete(taskId);
}
}
Support des Middlewares
A2A JS est basé sur Express.js et prend en charge tous les middlewares standard :
import cors from 'cors';
import express from 'express';
const app = express();
// Configuration des middlewares du serveur A2A JS
app.use(cors());
app.use(express.json());
// Middleware de journalisation personnalisé A2A JS
app.use((req, res, next) => {
console.log(`Requête A2A JS : ${req.method} ${req.path}`);
next();
});
Utilisation du Client A2A JS
Opérations Client de Base
import { A2AClient, MessageSendParams } from "@a2a-js/sdk";
import { v4 as uuidv4 } from "uuid";
const client = new A2AClient("http://localhost:3000");
async function testA2AJSClient() {
console.log("Test du client A2A JS...");
const messageParams: MessageSendParams = {
message: {
messageId: uuidv4(),
role: "user",
parts: [{ kind: "text", text: "Bonjour, A2A JS !" }],
kind: "message"
},
configuration: {
blocking: true,
acceptedOutputModes: ['text/plain']
}
};
try {
const response = await client.sendMessage(messageParams);
if (response.error) {
console.error("Erreur du client A2A JS :", response.error);
return;
}
console.log("Réponse A2A JS :", response.result);
} catch (error) {
console.error("Erreur de communication A2A JS :", error);
}
}
testA2AJSClient();
Streaming A2A JS
A2A JS prend en charge la communication en streaming en temps réel :
import { A2AClient, TaskStatusUpdateEvent } from "@a2a-js/sdk";
async function streamA2AJSResponse() {
const client = new A2AClient("http://localhost:3000");
console.log("Démarrage du streaming A2A JS...");
const streamParams = {
message: {
messageId: uuidv4(),
role: "user",
parts: [{ kind: "text", text: "Conversation en streaming avec A2A JS" }],
kind: "message"
}
};
try {
const stream = client.sendMessageStream(streamParams);
for await (const event of stream) {
if (event.kind === 'task') {
console.log(`Tâche A2A JS créée : ${event.id}`);
} else if (event.kind === 'status-update') {
const statusEvent = event as TaskStatusUpdateEvent;
console.log(`Mise à jour du statut A2A JS : ${statusEvent.status.state}`);
if (statusEvent.status.message?.parts[0]?.text) {
console.log(`Message A2A JS : ${statusEvent.status.message.parts[0].text}`);
}
if (statusEvent.final) {
console.log("Streaming A2A JS terminé");
break;
}
}
}
} catch (error) {
console.error("Erreur de streaming A2A JS :", error);
}
}
Fonctionnalités Avancées d'A2A JS
Traitement des Artéfacts
A2A JS prend en charge la génération et la gestion des artéfacts :
import { TaskArtifactUpdateEvent } from "@a2a-js/sdk";
// Publier un artéfact depuis l'AgentExecutor
const artifactUpdate: TaskArtifactUpdateEvent = {
kind: 'artifact-update',
taskId: taskId,
contextId: contextId,
artifact: {
artifactId: "a2a-js-example",
name: "Fichier exemple A2A JS",
parts: [{
text: `# Contenu généré par A2A JS\n\nCeci est un fichier exemple généré en utilisant le SDK A2A JS.`
}],
},
append: false,
lastChunk: true,
};
eventBus.publish(artifactUpdate);
Configuration de la Sécurité
Configuration des options de sécurité pour l'agent A2A JS :
const secureAgentCard: AgentCard = {
name: 'Agent A2A JS Sécurisé',
description: 'Agent A2A JS avec sécurité',
// ... autres configurations
securitySchemes: {
apiKey: {
type: 'apiKey',
name: 'X-API-Key',
in: 'header'
}
},
security: [{
apiKey: []
}]
};
Meilleures Pratiques A2A JS
1. Gestion des Erreurs
Implémentation d'une gestion complète des erreurs dans les applications A2A JS :
class RobustA2AJSExecutor implements AgentExecutor {
async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) {
try {
// Logique d'exécution A2A JS
await this.processRequest(requestContext, eventBus);
} catch (error) {
console.error("Erreur d'exécution A2A JS :", error);
// Publier l'état d'erreur
const errorUpdate: TaskStatusUpdateEvent = {
kind: 'status-update',
taskId: requestContext.task?.id || uuidv4(),
contextId: requestContext.userMessage.contextId || uuidv4(),
status: {
state: TaskState.Failed,
message: {
kind: 'message',
role: 'agent',
messageId: uuidv4(),
parts: [{ kind: 'text', text: 'Une erreur s\'est produite lors du traitement A2A JS. Veuillez réessayer plus tard.' }],
},
timestamp: new Date().toISOString(),
},
final: true,
};
eventBus.publish(errorUpdate);
}
}
}
2. Optimisation des Performances
Optimisation des performances des applications A2A JS :
// Optimisation du client A2A JS avec mise en pool des connexions
const client = new A2AClient("http://localhost:3000", {
keepAlive: true,
timeout: 30000
});
// Mise en cache des réponses de l'agent A2A JS
class CachedA2AJSExecutor implements AgentExecutor {
private cache = new Map<string, string>();
async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) {
const userText = requestContext.userMessage.parts[0]?.text || '';
const cacheKey = `a2a-js-${userText}`;
// Vérifier le cache A2A JS
if (this.cache.has(cacheKey)) {
console.log("Utilisation de la réponse mise en cache A2A JS");
// Retourner la réponse mise en cache
}
// Traiter la nouvelle requête et mettre en cache le résultat
}
}
3. Journalisation
Ajout d'une journalisation détaillée dans les applications A2A JS :
import { createLogger, format, transports } from 'winston';
const a2aJSLogger = createLogger({
level: 'info',
format: format.combine(
format.timestamp(),
format.printf(({ timestamp, level, message }) => {
return `[A2A JS] ${timestamp} ${level}: ${message}`;
})
),
transports: [
new transports.Console(),
new transports.File({ filename: 'a2a-js.log' })
]
});
// Utilisation dans le code A2A JS
a2aJSLogger.info('Agent A2A JS démarré avec succès');
a2aJSLogger.error('Erreur de traitement A2A JS', { error: errorDetails });
Dépannage A2A JS
Résolution des Problèmes Courants
1. Problèmes de Connexion A2A JS
// Vérifier la connexion au serveur A2A JS
async function checkA2AJSConnection() {
try {
const client = new A2AClient("http://localhost:3000");
const response = await fetch("http://localhost:3000/.well-known/agent.json");
if (response.ok) {
console.log("Connexion au serveur A2A JS normale");
} else {
console.error("Réponse anormale du serveur A2A JS :", response.status);
}
} catch (error) {
console.error("Échec de la connexion A2A JS :", error);
}
}
Essayez également ces méthodes :
2. Erreurs de Type A2A JS
Assurez-vous d'importer correctement les types A2A JS :
// Importer correctement les types A2A JS
import {
AgentCard,
AgentExecutor,
A2AClient,
Task,
TaskState,
Message,
MessageSendParams
} from "@a2a-js/sdk";
3. Débogage des Performances A2A JS
// Surveillance des performances A2A JS
class PerformanceA2AJSExecutor implements AgentExecutor {
async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) {
const startTime = Date.now();
console.log(`Début du traitement A2A JS : ${startTime}`);
try {
// Logique A2A JS
await this.processRequest(requestContext, eventBus);
} finally {
const endTime = Date.now();
console.log(`Traitement A2A JS terminé, temps écoulé : ${endTime - startTime}ms`);
}
}
}
Résumé
Le SDK A2A JS est un outil puissant pour créer des applications d'agents intelligents. À travers ce tutoriel, nous avons appris :
- Les concepts fondamentaux et l'architecture d'A2A JS
- Comment créer et configurer des agents A2A JS
- Le développement serveur et client A2A JS
- Les fonctionnalités avancées et les meilleures pratiques d'A2A JS
- Comment résoudre les problèmes courants des applications A2A JS
Vous pouvez maintenant créer votre propre application A2A JS ! Le SDK A2A JS fournit des fonctionnalités riches pour vous aider à créer des systèmes d'agents intelligents puissants et extensibles.
Pour plus de ressources et d'exemples A2A JS, visitez :
Commencez votre voyage de développement A2A JS ! 🚀