Tutorial Completo do A2A JS SDK: Guia de Início Rápido
Índice
- O que é o A2A JS SDK?
- Instalação e Configuração do A2A JS
- Conceitos Básicos do A2A JS
- Criando Seu Primeiro Agente A2A JS
- Desenvolvimento do Servidor A2A JS
- Uso do Cliente A2A JS
- Recursos Avançados do A2A JS
- Melhores Práticas do A2A JS
- Solução de Problemas do A2A JS
O que é o A2A JS SDK?
A2A JS SDK é uma biblioteca poderosa projetada especificamente para desenvolvedores JavaScript/TypeScript construírem aplicações de agentes inteligentes que estejam em conformidade com o Protocolo Agent2Agent (A2A). Este framework A2A JS permite que os desenvolvedores criem facilmente sistemas de agentes inteligentes que podem se comunicar e colaborar entre si.
Vantagens Principais do A2A JS
- 🚀 Fácil de Usar: A2A JS fornece APIs intuitivas que permitem que os desenvolvedores comecem rapidamente
- 🔄 Comunicação em Tempo Real: Suporta processamento de streaming e Server-Sent Events (SSE)
- 🛡️ Segurança de Tipos: Construído em TypeScript, fornecendo suporte completo a tipos
- 🌐 Multiplataforma: A2A JS pode ser executado tanto em ambientes Node.js quanto em navegadores
- 📡 Protocolo Padrão: Implementa completamente as especificações do protocolo A2A
Instalação e Configuração do A2A JS
Instalando o A2A JS SDK
Instale o A2A JS SDK usando npm:
npm install @a2a-js/sdk
Ou usando yarn:
yarn add @a2a-js/sdk
Verificando a Instalação do A2A JS
Crie um arquivo de teste simples para verificar se o A2A JS está instalado corretamente:
import { A2AClient, AgentCard } from "@a2a-js/sdk";
console.log("A2A JS SDK instalado com sucesso!");
Conceitos Básicos do A2A JS
Antes de começar a usar o A2A JS, é importante entender os seguintes conceitos básicos:
1. Cartão do Agente
Cada agente no A2A JS requer um Cartão do Agente que descreve as capacidades e interfaces do agente:
import { AgentCard } from "@a2a-js/sdk";
const agentCard: AgentCard = {
name: 'Meu Agente A2A JS',
description: 'Agente inteligente construído com A2A JS SDK',
url: 'http://localhost:3000/',
provider: {
organization: 'Desenvolvedores A2A JS',
url: 'https://example.com'
},
version: '1.0.0',
capabilities: {
streaming: true,
pushNotifications: false,
stateTransitionHistory: true,
},
skills: [{
id: 'general_chat',
name: 'Chat Geral',
description: 'Conversa geral usando A2A JS',
tags: ['chat', 'a2a-js'],
examples: ['Olá', 'Me ajude a responder perguntas']
}]
};
2. Executor do Agente
A lógica principal de execução do A2A JS é implementada através do AgentExecutor:
import { AgentExecutor, RequestContext, IExecutionEventBus } from "@a2a-js/sdk";
class MyA2AJSExecutor implements AgentExecutor {
async execute(
requestContext: RequestContext,
eventBus: IExecutionEventBus
): Promise<void> {
// Sua lógica do agente A2A JS
console.log("Agente A2A JS está processando a requisição...");
}
async cancelTask(taskId: string, eventBus: IExecutionEventBus): Promise<void> {
console.log(`A2A JS cancelando tarefa: ${taskId}`);
}
}
Criando Seu Primeiro Agente A2A JS
Vamos criar um exemplo completo de agente usando o A2A JS SDK:
Passo 1: Definindo o Cartão do Agente A2A JS
import { AgentCard } from "@a2a-js/sdk";
const myAgentCard: AgentCard = {
name: 'Agente Hello World A2A JS',
description: 'Meu primeiro agente A2A JS para aprender o A2A JS SDK',
url: 'http://localhost:3000/',
provider: {
organization: 'Tutorial 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: 'Exemplo de habilidade A2A JS: responder a saudações',
tags: ['hello', 'greeting', 'a2a-js'],
examples: [
'Olá',
'Oi',
'Me fale sobre A2A JS'
],
inputModes: ['text/plain'],
outputModes: ['text/plain']
}],
supportsAuthenticatedExtendedCard: false,
};
Passo 2: Implementando o Executor 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(`Executor A2A JS cancelando tarefa: ${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(`Agente A2A JS processando mensagem: ${userMessage.parts[0]?.text}`);
// Criando nova tarefa
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);
}
// Publicando status de trabalho
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: 'Agente A2A JS está pensando...' }],
taskId: taskId,
contextId: contextId,
},
timestamp: new Date().toISOString(),
},
final: false,
};
eventBus.publish(workingUpdate);
// Simulando tempo de processamento
await new Promise(resolve => setTimeout(resolve, 1000));
// Verificando status de cancelamento
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;
}
// Gerando resposta
const userText = userMessage.parts[0]?.text || '';
let responseText = '';
if (userText.toLowerCase().includes('hello') || userText.toLowerCase().includes('hi')) {
responseText = `Olá! Bem-vindo ao A2A JS SDK! Sou um agente inteligente construído com A2A JS.`;
} else if (userText.toLowerCase().includes('a2a js')) {
responseText = `A2A JS SDK é uma poderosa biblioteca JavaScript para construir aplicações de agentes inteligentes!`;
} else {
responseText = `Sou um agente A2A JS e recebi sua mensagem: "${userText}". Obrigado por usar o A2A JS SDK!`;
}
// Publicando resultado 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);
}
}
Passo 3: Iniciando o Servidor 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(`Servidor do agente A2A JS iniciado em http://localhost:${PORT}`);
console.log(`Cartão do agente A2A JS: http://localhost:${PORT}/.well-known/agent.json`);
console.log('Pressione Ctrl+C para parar o servidor A2A JS');
});
Desenvolvimento do Servidor A2A JS
Armazenamento de Tarefas
A2A JS fornece armazenamento de tarefas em memória, e você também pode implementar armazenamento personalizado:
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(`A2A JS obtendo tarefa: ${taskId}`);
return this.tasks.get(taskId);
}
async setTask(task: Task): Promise<void> {
console.log(`A2A JS salvando tarefa: ${task.id}`);
this.tasks.set(task.id, task);
}
async deleteTask(taskId: string): Promise<void> {
console.log(`A2A JS deletando tarefa: ${taskId}`);
this.tasks.delete(taskId);
}
}
Suporte a Middleware
A2A JS é baseado em Express.js e suporta todos os middlewares padrão:
import cors from 'cors';
import express from 'express';
const app = express();
// Configuração de middleware do servidor A2A JS
app.use(cors());
app.use(express.json());
// Middleware de logging personalizado A2A JS
app.use((req, res, next) => {
console.log(`Requisição A2A JS: ${req.method} ${req.path}`);
next();
});
Uso do Cliente A2A JS
Operações Básicas do Cliente
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("Testando cliente A2A JS...");
const messageParams: MessageSendParams = {
message: {
messageId: uuidv4(),
role: "user",
parts: [{ kind: "text", text: "Olá, A2A JS!" }],
kind: "message"
},
configuration: {
blocking: true,
acceptedOutputModes: ['text/plain']
}
};
try {
const response = await client.sendMessage(messageParams);
if (response.error) {
console.error("Erro do cliente A2A JS:", response.error);
return;
}
console.log("Resposta A2A JS:", response.result);
} catch (error) {
console.error("Erro de comunicação A2A JS:", error);
}
}
testA2AJSClient();
Streaming A2A JS
A2A JS suporta comunicação em tempo real via streaming:
import { A2AClient, TaskStatusUpdateEvent } from "@a2a-js/sdk";
async function streamA2AJSResponse() {
const client = new A2AClient("http://localhost:3000");
console.log("Iniciando streaming A2A JS...");
const streamParams = {
message: {
messageId: uuidv4(),
role: "user",
parts: [{ kind: "text", text: "Conversa em streaming usando A2A JS" }],
kind: "message"
}
};
try {
const stream = client.sendMessageStream(streamParams);
for await (const event of stream) {
if (event.kind === 'task') {
console.log(`Tarefa A2A JS criada: ${event.id}`);
} else if (event.kind === 'status-update') {
const statusEvent = event as TaskStatusUpdateEvent;
console.log(`Atualização de status A2A JS: ${statusEvent.status.state}`);
if (statusEvent.status.message?.parts[0]?.text) {
console.log(`Mensagem A2A JS: ${statusEvent.status.message.parts[0].text}`);
}
if (statusEvent.final) {
console.log("Streaming A2A JS concluído");
break;
}
}
}
} catch (error) {
console.error("Erro de streaming A2A JS:", error);
}
}
Recursos Avançados do A2A JS
Manipulação de Artefatos
A2A JS suporta criação e gerenciamento de artefatos:
import { TaskArtifactUpdateEvent } from "@a2a-js/sdk";
// Publicando artefatos no AgentExecutor
const artifactUpdate: TaskArtifactUpdateEvent = {
kind: 'artifact-update',
taskId: taskId,
contextId: contextId,
artifact: {
artifactId: "a2a-js-example",
name: "Arquivo de Exemplo A2A JS",
parts: [{
text: `# Conteúdo Gerado pelo A2A JS\n\nEste é um arquivo de exemplo gerado usando A2A JS SDK.`
}],
},
append: false,
lastChunk: true,
};
eventBus.publish(artifactUpdate);
Configuração de Segurança
Configure opções de segurança para agentes A2A JS:
const secureAgentCard: AgentCard = {
name: 'Agente Seguro A2A JS',
description: 'Agente seguro A2A JS',
// ... outras configurações
securitySchemes: {
apiKey: {
type: 'apiKey',
name: 'X-API-Key',
in: 'header'
}
},
security: [{
apiKey: []
}]
};
Melhores Práticas do A2A JS
1. Tratamento de Erros
Implemente tratamento de erros abrangente em aplicações A2A JS:
class RobustA2AJSExecutor implements AgentExecutor {
async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) {
try {
// Lógica de execução A2A JS
await this.processRequest(requestContext, eventBus);
} catch (error) {
console.error("Erro de execução A2A JS:", error);
// Publicando status de erro
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: 'Ocorreu um erro durante o processamento A2A JS, por favor tente novamente mais tarde.' }],
},
timestamp: new Date().toISOString(),
},
final: true,
};
eventBus.publish(errorUpdate);
}
}
}
2. Otimização de Performance
Otimize a performance da sua aplicação A2A JS:
// Otimizando cliente A2A JS com pool de conexões
const client = new A2AClient("http://localhost:3000", {
keepAlive: true,
timeout: 30000
});
// Cache de respostas do agente 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}`;
// Verificando cache A2A JS
if (this.cache.has(cacheKey)) {
console.log("A2A JS usando resposta em cache");
// Retornando resposta em cache
}
// Processando nova requisição e cacheando resultado
}
}
3. Logging
Adicione logging detalhado às aplicações 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' })
]
});
// Usando no código A2A JS
a2aJSLogger.info('Agente A2A JS iniciado com sucesso');
a2aJSLogger.error('Erro de processamento A2A JS', { error: errorDetails });
Solução de Problemas do A2A JS
Resolução de Problemas Comuns
1. Problemas de Conexão A2A JS
// Verificando conexão com servidor 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("Conexão com servidor A2A JS normal");
} else {
console.error("Resposta anormal do servidor A2A JS:", response.status);
}
} catch (error) {
console.error("Falha na conexão A2A JS:", error);
}
}
Você também pode tentar os seguintes métodos:
2. Erros de Tipo A2A JS
Certifique-se de importar corretamente os tipos A2A JS:
// Importações corretas de tipos A2A JS
import {
AgentCard,
AgentExecutor,
A2AClient,
Task,
TaskState,
Message,
MessageSendParams
} from "@a2a-js/sdk";
3. Depuração de Performance A2A JS
// Monitoramento de performance A2A JS
class PerformanceA2AJSExecutor implements AgentExecutor {
async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) {
const startTime = Date.now();
console.log(`A2A JS iniciando processamento: ${startTime}`);
try {
// Sua lógica A2A JS
await this.processRequest(requestContext, eventBus);
} finally {
const endTime = Date.now();
console.log(`Processamento A2A JS concluído, duração: ${endTime - startTime}ms`);
}
}
}
Resumo
A2A JS SDK é uma ferramenta poderosa para construir aplicações de agentes inteligentes. Através deste tutorial, você aprendeu:
- Conceitos básicos e arquitetura do A2A JS
- Como criar e configurar agentes A2A JS
- Desenvolvimento de servidor e cliente A2A JS
- Recursos avançados e melhores práticas do A2A JS
- Métodos de solução de problemas para aplicações A2A JS
Agora você pode começar a construir suas próprias aplicações A2A JS! Lembre-se, o A2A JS SDK fornece funcionalidades ricas para ajudar você a criar sistemas de agentes inteligentes poderosos e escaláveis.
Para mais recursos e exemplos do A2A JS, visite:
Comece sua jornada de desenvolvimento com A2A JS! 🚀