A2A Protocol

A2A JS SDK Полное Руководство: Краткое Руководство по Началу Работы

MILO
Share
A2A JS SDK Полное Руководство: Краткое Руководство по Началу Работы

Содержание

  1. Что такое A2A JS SDK?
  2. Установка и настройка A2A JS
  3. Основные концепции A2A JS
  4. Создание первого агента A2A JS
  5. Разработка сервера A2A JS
  6. Использование клиента A2A JS
  7. Расширенные возможности A2A JS
  8. Лучшие практики A2A JS
  9. Устранение неполадок A2A JS

Что такое A2A JS SDK?

A2A JS SDK - это мощная библиотека, специально разработанная для разработчиков JavaScript/TypeScript для создания приложений интеллектуальных агентов, соответствующих протоколу Agent2Agent (A2A). Этот фреймворк A2A JS позволяет разработчикам легко создавать системы интеллектуальных агентов, которые могут общаться и сотрудничать друг с другом.

Основные преимущества A2A JS

  • 🚀 Простота использования: A2A JS предоставляет интуитивные API, которые позволяют разработчикам быстро начать работу
  • 🔄 Связь в реальном времени: Поддерживает потоковую обработку и Server-Sent Events (SSE)
  • 🛡️ Типобезопасность: Построен на TypeScript, обеспечивает полную поддержку типов
  • 🌐 Кроссплатформенность: A2A JS может работать как в среде Node.js, так и в браузере
  • 📡 Стандартный протокол: Полностью реализует спецификации протокола A2A

Установка и настройка A2A JS

Установка A2A JS SDK

Установите A2A JS SDK используя npm:

npm install @a2a-js/sdk

Или используя yarn:

yarn add @a2a-js/sdk

Проверка установки A2A JS

Создайте простой тестовый файл для проверки правильности установки A2A JS:

import { A2AClient, AgentCard } from "@a2a-js/sdk";

console.log("A2A JS SDK успешно установлен!");

Основные концепции A2A JS

Перед началом использования A2A JS важно понимать следующие основные концепции:

1. Карточка агента

Каждый агент в A2A JS требует карточку агента, которая описывает возможности и интерфейсы агента:

import { AgentCard } from "@a2a-js/sdk";

const agentCard: AgentCard = {
  name: 'Мой агент A2A JS',
  description: 'Интеллектуальный агент, построенный с помощью A2A JS SDK',
  url: 'http://localhost:3000/',
  provider: {
    organization: 'Разработчики A2A JS',
    url: 'https://example.com'
  },
  version: '1.0.0',
  capabilities: {
    streaming: true,
    pushNotifications: false,
    stateTransitionHistory: true,
  },
  skills: [{
    id: 'general_chat',
    name: 'Общий чат',
    description: 'Общий разговор с использованием A2A JS',
    tags: ['chat', 'a2a-js'],
    examples: ['Привет', 'Помоги мне ответить на вопросы']
  }]
};

2. Исполнитель агента

Основная логика выполнения A2A JS реализуется через AgentExecutor:

import { AgentExecutor, RequestContext, IExecutionEventBus } from "@a2a-js/sdk";

class MyA2AJSExecutor implements AgentExecutor {
  async execute(
    requestContext: RequestContext,
    eventBus: IExecutionEventBus
  ): Promise<void> {
    // Логика вашего агента A2A JS
    console.log("Агент A2A JS обрабатывает запрос...");
  }

  async cancelTask(taskId: string, eventBus: IExecutionEventBus): Promise<void> {
    console.log(`A2A JS отменяет задачу: ${taskId}`);
  }
}

Создание первого агента A2A JS

Давайте создадим полный пример агента с использованием A2A JS SDK:

Шаг 1: Определение карточки агента A2A JS

import { AgentCard } from "@a2a-js/sdk";

const myAgentCard: AgentCard = {
  name: 'Hello World агент A2A JS',
  description: 'Мой первый агент A2A JS для изучения A2A JS SDK',
  url: 'http://localhost:3000/',
  provider: {
    organization: 'Обучение 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: 'Пример навыка A2A JS: отвечать на приветствия',
    tags: ['hello', 'greeting', 'a2a-js'],
    examples: [
      'Привет',
      'Здравствуйте',
      'Расскажите мне о A2A JS'
    ],
    inputModes: ['text/plain'],
    outputModes: ['text/plain']
  }],
  supportsAuthenticatedExtendedCard: false,
};

Шаг 2: Реализация исполнителя 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(`Исполнитель 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(`Агент A2A JS обрабатывает сообщение: ${userMessage.parts[0]?.text}`);

    // Создание новой задачи
    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);
    }

    // Публикация статуса работы
    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: 'Агент A2A JS думает...' }],
          taskId: taskId,
          contextId: contextId,
        },
        timestamp: new Date().toISOString(),
      },
      final: false,
    };
    eventBus.publish(workingUpdate);

    // Имитация времени обработки
    await new Promise(resolve => setTimeout(resolve, 1000));

    // Проверка статуса отмены
    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;
    }

    // Генерация ответа
    const userText = userMessage.parts[0]?.text || '';
    let responseText = '';
    
    if (userText.toLowerCase().includes('hello') || userText.toLowerCase().includes('hi')) {
      responseText = `Привет! Добро пожаловать в A2A JS SDK! Я интеллектуальный агент, созданный с помощью A2A JS.`;
    } else if (userText.toLowerCase().includes('a2a js')) {
      responseText = `A2A JS SDK - это мощная JavaScript библиотека для создания приложений интеллектуальных агентов!`;
    } else {
      responseText = `Я агент A2A JS, и я получил ваше сообщение: "${userText}". Спасибо за использование A2A JS SDK!`;
    }

    // Публикация окончательного результата
    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);
  }
}

Шаг 3: Запуск сервера 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(`Сервер агента A2A JS запущен по адресу http://localhost:${PORT}`);
  console.log(`Карточка агента A2A JS: http://localhost:${PORT}/.well-known/agent.json`);
  console.log('Нажмите Ctrl+C для остановки сервера A2A JS');
});

Разработка сервера A2A JS

Хранилище задач

A2A JS предоставляет хранилище задач в памяти, и вы также можете реализовать собственное хранилище:

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 получает задачу: ${taskId}`);
    return this.tasks.get(taskId);
  }

  async setTask(task: Task): Promise<void> {
    console.log(`A2A JS сохраняет задачу: ${task.id}`);
    this.tasks.set(task.id, task);
  }

  async deleteTask(taskId: string): Promise<void> {
    console.log(`A2A JS удаляет задачу: ${taskId}`);
    this.tasks.delete(taskId);
  }
}

Поддержка промежуточного ПО

A2A JS основан на Express.js и поддерживает все стандартные промежуточные ПО:

import cors from 'cors';
import express from 'express';

const app = express();

// Конфигурация промежуточного ПО сервера A2A JS
app.use(cors());
app.use(express.json());

// Пользовательское промежуточное ПО логирования A2A JS
app.use((req, res, next) => {
  console.log(`Запрос A2A JS: ${req.method} ${req.path}`);
  next();
});

Использование клиента A2A JS

Основные операции клиента

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("Тестирование клиента A2A JS...");
  
  const messageParams: MessageSendParams = {
    message: {
      messageId: uuidv4(),
      role: "user",
      parts: [{ kind: "text", text: "Привет, A2A JS!" }],
      kind: "message"
    },
    configuration: {
      blocking: true,
      acceptedOutputModes: ['text/plain']
    }
  };

  try {
    const response = await client.sendMessage(messageParams);
    
    if (response.error) {
      console.error("Ошибка клиента A2A JS:", response.error);
      return;
    }

    console.log("Ответ A2A JS:", response.result);
  } catch (error) {
    console.error("Ошибка связи A2A JS:", error);
  }
}

testA2AJSClient();

Потоковая передача A2A JS

A2A JS поддерживает связь в реальном времени через потоковую передачу:

import { A2AClient, TaskStatusUpdateEvent } from "@a2a-js/sdk";

async function streamA2AJSResponse() {
  const client = new A2AClient("http://localhost:3000");
  
  console.log("Запуск потоковой передачи A2A JS...");
  
  const streamParams = {
    message: {
      messageId: uuidv4(),
      role: "user",
      parts: [{ kind: "text", text: "Потоковый разговор с использованием A2A JS" }],
      kind: "message"
    }
  };

  try {
    const stream = client.sendMessageStream(streamParams);
    
    for await (const event of stream) {
      if (event.kind === 'task') {
        console.log(`Создана задача A2A JS: ${event.id}`);
      } else if (event.kind === 'status-update') {
        const statusEvent = event as TaskStatusUpdateEvent;
        console.log(`Обновление статуса A2A JS: ${statusEvent.status.state}`);
        
        if (statusEvent.status.message?.parts[0]?.text) {
          console.log(`Сообщение A2A JS: ${statusEvent.status.message.parts[0].text}`);
        }
        
        if (statusEvent.final) {
          console.log("Потоковая передача A2A JS завершена");
          break;
        }
      }
    }
  } catch (error) {
    console.error("Ошибка потоковой передачи A2A JS:", error);
  }
}

Расширенные возможности A2A JS

Обработка артефактов

A2A JS поддерживает создание и управление артефактами:

import { TaskArtifactUpdateEvent } from "@a2a-js/sdk";

// Публикация артефактов в AgentExecutor
const artifactUpdate: TaskArtifactUpdateEvent = {
  kind: 'artifact-update',
  taskId: taskId,
  contextId: contextId,
  artifact: {
    artifactId: "a2a-js-example",
    name: "Пример файла A2A JS",
    parts: [{ 
      text: `# Содержимое, сгенерированное A2A JS\n\nЭто пример файла, сгенерированного с помощью A2A JS SDK.`
    }],
  },
  append: false,
  lastChunk: true,
};
eventBus.publish(artifactUpdate);

Конфигурация безопасности

Настройка параметров безопасности для агентов A2A JS:

const secureAgentCard: AgentCard = {
  name: 'Безопасный агент A2A JS',
  description: 'Безопасный агент A2A JS',
  // ... другие конфигурации
  securitySchemes: {
    apiKey: {
      type: 'apiKey',
      name: 'X-API-Key',
      in: 'header'
    }
  },
  security: [{
    apiKey: []
  }]
};

Лучшие практики A2A JS

1. Обработка ошибок

Реализуйте комплексную обработку ошибок в приложениях A2A JS:

class RobustA2AJSExecutor implements AgentExecutor {
  async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) {
    try {
      // Логика выполнения A2A JS
      await this.processRequest(requestContext, eventBus);
    } catch (error) {
      console.error("Ошибка выполнения A2A JS:", error);
      
      // Публикация статуса ошибки
      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: 'Произошла ошибка во время обработки A2A JS, пожалуйста, попробуйте позже.' }],
          },
          timestamp: new Date().toISOString(),
        },
        final: true,
      };
      eventBus.publish(errorUpdate);
    }
  }
}

2. Оптимизация производительности

Оптимизируйте производительность вашего приложения A2A JS:

// Оптимизация клиента A2A JS с пулом соединений
const client = new A2AClient("http://localhost:3000", {
  keepAlive: true,
  timeout: 30000
});

// Кэширование ответов агента 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}`;
    
    // Проверка кэша A2A JS
    if (this.cache.has(cacheKey)) {
      console.log("A2A JS использует кэшированный ответ");
      // Возврат кэшированного ответа
    }
    
    // Обработка нового запроса и кэширование результата
  }
}

3. Логирование

Добавьте подробное логирование в приложения 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' })
  ]
});

// Использование в коде A2A JS
a2aJSLogger.info('Агент A2A JS успешно запущен');
a2aJSLogger.error('Ошибка обработки A2A JS', { error: errorDetails });

Устранение неполадок A2A JS

Решение распространенных проблем

1. Проблемы с подключением A2A JS

// Проверка подключения к серверу 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("Подключение к серверу A2A JS в норме");
    } else {
      console.error("Ненормальный ответ сервера A2A JS:", response.status);
    }
  } catch (error) {
    console.error("Ошибка подключения к A2A JS:", error);
  }
}

Вы также можете попробовать следующие методы:

2. Ошибки типов A2A JS

Убедитесь в правильности импорта типов A2A JS:

// Правильный импорт типов A2A JS
import {
  AgentCard,
  AgentExecutor,
  A2AClient,
  Task,
  TaskState,
  Message,
  MessageSendParams
} from "@a2a-js/sdk";

3. Отладка производительности A2A JS

// Мониторинг производительности A2A JS
class PerformanceA2AJSExecutor implements AgentExecutor {
  async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) {
    const startTime = Date.now();
    console.log(`A2A JS начал обработку: ${startTime}`);
    
    try {
      // Ваша логика A2A JS
      await this.processRequest(requestContext, eventBus);
    } finally {
      const endTime = Date.now();
      console.log(`Обработка A2A JS завершена, продолжительность: ${endTime - startTime}мс`);
    }
  }
}

Итоги

A2A JS SDK - это мощный инструмент для создания приложений интеллектуальных агентов. В этом руководстве вы узнали:

  • Основные концепции и архитектуру A2A JS
  • Как создавать и настраивать агентов A2A JS
  • Разработку сервера и клиента A2A JS
  • Расширенные возможности и лучшие практики A2A JS
  • Методы устранения неполадок в приложениях A2A JS

Теперь вы можете начать создавать свои собственные приложения A2A JS! Помните, что A2A JS SDK предоставляет богатый функционал для создания мощных, масштабируемых систем интеллектуальных агентов.

Для получения дополнительных ресурсов и примеров A2A JS, посетите:

Начните свой путь разработки с A2A JS! 🚀