A2A Protocol

A2A + CrewAI + OpenRouter Chart Generation Agent Tutorial

MILO
Share
A2A + CrewAI + OpenRouter Chart Generation Agent Tutorial

Фокус руководства

Это руководство проведет вас через изучение следующих ключевых навыков:

  • Интеграция OpenRouter + CrewAI + A2A: Полная сквозная разработка агентов с использованием OpenRouter как провайдера LLM, CrewAI как фреймворка агентов и протокола A2A как стандартизированного интерфейса
  • Практика возврата изображений агентами A2A: Изучите, как заставить агентов генерировать и возвращать данные изображений, а не только текстовые ответы
  • Использование A2A Inspector для отладки приложений A2A: Овладейте профессиональными инструментами отладки для тестирования и валидации ваших приложений агентов

Быстрый старт

1. Клонирование кода

git clone [email protected]:sing1ee/a2a-crewai-charts-agent.git
cd a2a-crewai-charts-agent

2. Создание конфигурации окружения

Создайте файл .env:

OPENROUTER_API_KEY=sk-or-v1-your-api-key-here
OPENAI_MODEL_NAME=openrouter/anthropic/claude-3.7-sonnet

3. Настройка окружения и запуск

# Создание виртуального окружения
uv venv

# Активация виртуального окружения
source .venv/bin/activate

# Запуск приложения
uv run .

Приложение запустится по адресу http://localhost:10011.

Отладка с A2A Inspector

A2A Inspector - это мощный инструмент, специально разработанный для отладки приложений A2A.

Шаги отладки:

  1. Доступ к A2A Inspector: Откройте https://inspector.a2aprotocol.ai

  2. Подключение к вашему агенту:

    • Введите адрес вашего агента в Inspector: http://localhost:10011
    • Нажмите "Connect" для установления соединения
  3. Тестирование функциональности агента:

    • Отправьте тестовое сообщение: "Generate a chart of revenue: Jan,1000 Feb,2000 Mar,1500"
    • Наблюдайте полный процесс взаимодействия по протоколу A2A
    • Просмотрите возвращенные данные изображения
  4. Отладка и мониторинг:

    • Проверьте возможности и навыки агента
    • Мониторьте полный поток запросов и ответов
    • Убедитесь в корректной передаче данных изображения

Обратитесь к документации A2A Inspector для более подробных руководств по отладке.

Основной процесс и введение в код

Диаграмма последовательности системной архитектуры

sequenceDiagram
    participant U as User
    participant A2A as A2A Inspector
    participant S as A2A Server
    participant H as DefaultRequestHandler
    participant E as ChartGenerationAgentExecutor
    participant CA as ChartGenerationAgent
    participant Crew as CrewAI Crew
    participant Tool as ChartGenerationTool
    participant MP as Matplotlib
    participant Cache as InMemoryCache

    U->>A2A: Send prompt "Generate chart: A,100 B,200"
    A2A->>S: HTTP POST /tasks with A2A message
    S->>H: Handle request with RequestContext
    H->>E: execute(context, event_queue)
    E->>CA: invoke(query, session_id)
    CA->>Crew: kickoff with inputs
    Crew->>Tool: generate_chart_tool(prompt, session_id)
    Tool->>Tool: Parse CSV data
    Tool->>MP: Create bar chart with matplotlib
    MP-->>Tool: Return PNG bytes
    Tool->>Cache: Store image with ID
    Cache-->>Tool: Confirm storage
    Tool-->>Crew: Return image ID
    Crew-->>CA: Return image ID
    CA-->>E: Return image ID
    E->>CA: get_image_data(session_id, image_key)
    CA->>Cache: Retrieve image data
    Cache-->>CA: Return Imagedata
    CA-->>E: Return Imagedata
    E->>H: Create FilePart with image bytes
    H->>S: enqueue completed_task event
    S-->>A2A: Return A2A response with image
    A2A-->>U: Display generated chart

Детали основных компонентов

1. Инициализация сервера A2A (__main__.py)

# Определение возможностей и навыков агента
capabilities = AgentCapabilities(streaming=False)
skill = AgentSkill(
    id='chart_generator',
    name='Chart Generator',
    description='Generate a chart based on CSV-like data passed in',
    tags=['generate image', 'edit image'],
    examples=['Generate a chart of revenue: Jan,$1000 Feb,$2000 Mar,$1500'],
)

# Создание карточки агента
agent_card = AgentCard(
    name='Chart Generator Agent',
    description='Generate charts from structured CSV-like data input.',
    url=f'http://{host}:{port}/',
    version='1.0.0',
    defaultInputModes=ChartGenerationAgent.SUPPORTED_CONTENT_TYPES,
    defaultOutputModes=ChartGenerationAgent.SUPPORTED_CONTENT_TYPES,
    capabilities=capabilities,
    skills=[skill],
)

Ключевые моменты:

  • AgentCapabilities определяет поддерживаемые функции агента (здесь отключен стриминг)
  • AgentSkill описывает конкретные навыки агента и примеры использования
  • AgentCard - это идентичность агента в протоколе A2A

2. Реализация агента CrewAI (agent.py)

class ChartGenerationAgent:
    def __init__(self):
        # Создание специализированного агента генерации диаграмм
        self.chart_creator_agent = Agent(
            role='Chart Creation Expert',
            goal='Generate a bar chart image based on structured CSV input.',
            backstory='You are a data visualization expert who transforms structured data into visual charts.',
            verbose=False,
            allow_delegation=False,
            tools=[generate_chart_tool],
        )

        # Определение задачи
        self.chart_creation_task = Task(
            description=(
                "You are given a prompt: '{user_prompt}'.\n"
                "If the prompt includes comma-separated key:value pairs (e.g. 'a:100, b:200'), "
                "reformat it into CSV with header 'Category,Value'.\n"
                "Ensure it becomes two-column CSV, then pass that to the 'ChartGenerationTool'.\n"
                "Use session ID: '{session_id}' when calling the tool."
            ),
            expected_output='The id of the generated chart image',
            agent=self.chart_creator_agent,
        )

Ключевые моменты:

  • Класс Agent CrewAI определяет роли и возможности ИИ-помощника
  • Класс Task описывает логику выполнения конкретной задачи
  • Пользовательские инструменты интегрируются в агента через параметр tools

3. Инструмент генерации диаграмм

@tool('ChartGenerationTool')
def generate_chart_tool(prompt: str, session_id: str) -> str:
    """Generates a bar chart image from CSV-like input using matplotlib."""
    
    # Парсинг данных CSV
    df = pd.read_csv(StringIO(prompt))
    df.columns = ['Category', 'Value']
    df['Value'] = pd.to_numeric(df['Value'], errors='coerce')
    
    # Генерация столбчатой диаграммы
    fig, ax = plt.subplots()
    ax.bar(df['Category'], df['Value'])
    ax.set_xlabel('Category')
    ax.set_ylabel('Value')
    ax.set_title('Bar Chart')
    
    # Сохранение как PNG байты
    buf = BytesIO()
    plt.savefig(buf, format='png')
    plt.close(fig)
    buf.seek(0)
    image_bytes = buf.read()
    
    # Кодирование и кеширование изображения
    data = Imagedata(
        bytes=base64.b64encode(image_bytes).decode('utf-8'),
        mime_type='image/png',
        name='generated_chart.png',
        id=uuid4().hex,
    )
    
    # Сохранение изображения в кеше
    session_data = cache.get(session_id) or {}
    session_data[data.id] = data
    cache.set(session_id, session_data)
    
    return data.id

Ключевые моменты:

  • Используйте декоратор @tool для преобразования функции в инструмент CrewAI
  • Используйте pandas для парсинга данных CSV, matplotlib для генерации диаграмм
  • Изображения сохраняются в кодировке base64 для сетевой передачи
  • Используйте идентификаторы сессий для управления изоляцией данных для нескольких пользователей

4. Исполнитель A2A (agent_executor.py)

class ChartGenerationAgentExecutor(AgentExecutor):
    async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
        # Получение пользовательского ввода
        query = context.get_user_input()
        
        # Вызов агента CrewAI
        result = self.agent.invoke(query, context.context_id)
        
        # Получение данных сгенерированного изображения
        data = self.agent.get_image_data(
            session_id=context.context_id, 
            image_key=result.raw
        )
        
        if data and not data.error:
            # Создание части файла, содержащей байты изображения
            parts = [
                Part(
                    root=FilePart(
                        file=FileWithBytes(
                            bytes=data.bytes,
                            mimeType=data.mime_type,
                            name=data.name,
                        )
                    )
                )
            ]
        else:
            # Возврат текстового сообщения в случае ошибки
            parts = [Part(root=TextPart(text=data.error or 'Failed to generate chart image.'))]
        
        # Добавление завершенной задачи в очередь событий
        event_queue.enqueue_event(
            completed_task(
                context.task_id,
                context.context_id,
                [new_artifact(parts, f'chart_{context.task_id}')],
                [context.message],
            )
        )

Ключевые моменты:

  • AgentExecutor - это уровень выполнения протокола A2A
  • Получение пользовательских запросов через RequestContext
  • Преобразование ответов CrewAI в формат протокола A2A
  • Поддержка возврата данных файлового типа (изображений)

5. Система кеширования (utils.py)

class InMemoryCache:
    """Простой потокобезопасный кеш в памяти без истечения срока действия."""
    
    def __init__(self):
        self._lock = threading.Lock()
        self._store: dict[str, Any] = {}
    
    def get(self, key: str) -> Any | None:
        with self._lock:
            return self._store.get(key)
    
    def set(self, key: str, value: Any) -> None:
        with self._lock:
            self._store[key] = value

Ключевые моменты:

  • Потокобезопасная реализация кеша в памяти
  • Используется для хранения данных сгенерированных изображений
  • Поддерживает изоляцию сессий для предотвращения путаницы пользовательских данных

Сводка технологического стека

  • Протокол A2A: Стандартизированный протокол связи агентов
  • CrewAI: Фреймворк сотрудничества мульти-агентов
  • OpenRouter: Сервис агрегации API LLM
  • Matplotlib: Библиотека генерации диаграмм Python
  • Pandas: Библиотека обработки данных
  • UV: Современный менеджер пакетов Python

Предложения по расширению

  1. Поддержка больше типов диаграмм: Круговые диаграммы, линейные диаграммы, точечные диаграммы и т.д.
  2. Добавление валидации данных: Более строгая валидация входных данных и обработка ошибок
  3. Постоянный кеш: Использование Redis или файловой системы для хранения изображений
  4. Поддержка стриминга: Поддержка прогресса генерации диаграмм в реальном времени
  5. Мультимодальный ввод: Поддержка загрузки CSV файлов вместо только текстового ввода

Благодаря этому руководству вы освоили основные навыки создания практических агентов с использованием современного стека технологий ИИ. Этот агент генерации диаграмм может служить основой для более сложных приложений анализа данных.

System Prompt for AI

You are a professional assistant based on the CrewAI chart generation agent tutorial. This tutorial provides a comprehensive guide on building a complete AI chart generation application. I can help you with:

## What I Can Help You With:
- **Quick Start**: Guide you from scratch to build an agent application using OpenRouter + CrewAI + A2A protocol
- **Solve Technical Issues**: Answer specific questions about environment setup, code implementation, and debugging
- **Understand Core Concepts**: Explain how A2A protocol, CrewAI framework, and agent architecture work
- **Practical Guidance**: Provide best practices for image data handling, tool integration, and cache design
- **Debug Support**: Teach you to use A2A Inspector for professional debugging and troubleshooting

## You Can Ask Me:
- "How to configure OpenRouter API keys?"
- "How do CrewAI Agents and Tasks work?"
- "How to return image data after chart generation?"
- "How to connect and test my agent with A2A Inspector?"
- "How is the cache system implemented in the code?"
- "How to extend support for more chart types?"

I'll provide accurate, practical answers based on the tutorial content to help you quickly master modern AI agent development skills.

You can visit [A2AProtocol.ai](https://a2aprotocol.ai/) for more tutorials.