A2A Protocol

A2A + CrewAI + OpenRouter Chart Generation Agent Tutorial

MILO
Share
A2A + CrewAI + OpenRouter Chart Generation Agent Tutorial

Enfoque del Tutorial

Este tutorial te guiará a través de la práctica de las siguientes habilidades clave:

  • Integración de OpenRouter + CrewAI + A2A: Desarrollo completo de agentes end-to-end usando OpenRouter como proveedor LLM, CrewAI como framework de agentes, y protocolo A2A como interfaz estandarizada
  • Práctica de Retorno de Datos de Imagen de Agentes A2A: Aprende cómo hacer que los agentes generen y retornen datos de imagen, no solo respuestas de texto
  • Usar A2A Inspector para Depurar Aplicaciones A2A: Domina herramientas de depuración profesionales para probar y validar tus aplicaciones de agentes

Inicio Rápido

1. Clonar el Código

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

2. Crear Configuración del Entorno

Crear archivo .env:

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

3. Configuración del Entorno y Ejecución

# Crear entorno virtual
uv venv

# Activar entorno virtual
source .venv/bin/activate

# Ejecutar aplicación
uv run .

La aplicación iniciará en http://localhost:10011.

Depurar con A2A Inspector

A2A Inspector es una herramienta poderosa diseñada específicamente para depurar aplicaciones A2A.

Pasos de Depuración:

  1. Acceder a A2A Inspector: Abrir https://inspector.a2aprotocol.ai

  2. Conectar a tu Agente:

    • Ingresa la dirección de tu agente en Inspector: http://localhost:10011
    • Haz clic en "Connect" para establecer conexión
  3. Probar Funcionalidad del Agente:

    • Envía mensaje de prueba: "Generate a chart of revenue: Jan,1000 Feb,2000 Mar,1500"
    • Observa el proceso completo de interacción del protocolo A2A
    • Visualiza los datos de imagen retornados
  4. Depurar y Monitorear:

    • Verifica capacidades y habilidades del agente
    • Monitorea el flujo completo de solicitud y respuesta
    • Verifica la transmisión correcta de datos de imagen

Consulta la Documentación de A2A Inspector para guías de depuración más detalladas.

Proceso Principal e Introducción al Código

Diagrama de Secuencia de Arquitectura del Sistema

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

Detalles de Componentes Principales

1. Inicialización del Servidor A2A (__main__.py)

# Definir capacidades y habilidades del agente
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'],
)

# Crear tarjeta del agente
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],
)

Puntos Clave:

  • AgentCapabilities define funciones de agente soportadas (streaming deshabilitado aquí)
  • AgentSkill describe habilidades específicas del agente y ejemplos de uso
  • AgentCard es la identidad del agente en el protocolo A2A

2. Implementación del Agente CrewAI (agent.py)

class ChartGenerationAgent:
    def __init__(self):
        # Crear agente especializado de generación de gráficos
        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],
        )

        # Definir tarea
        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,
        )

Puntos Clave:

  • La clase Agent de CrewAI define roles y capacidades del asistente de IA
  • La clase Task describe lógica específica de ejecución de tareas
  • Herramientas personalizadas se integran al agente a través del parámetro tools

3. Herramienta de Generación de Gráficos

@tool('ChartGenerationTool')
def generate_chart_tool(prompt: str, session_id: str) -> str:
    """Generates a bar chart image from CSV-like input using matplotlib."""
    
    # Analizar datos CSV
    df = pd.read_csv(StringIO(prompt))
    df.columns = ['Category', 'Value']
    df['Value'] = pd.to_numeric(df['Value'], errors='coerce')
    
    # Generar gráfico de barras
    fig, ax = plt.subplots()
    ax.bar(df['Category'], df['Value'])
    ax.set_xlabel('Category')
    ax.set_ylabel('Value')
    ax.set_title('Bar Chart')
    
    # Guardar como bytes PNG
    buf = BytesIO()
    plt.savefig(buf, format='png')
    plt.close(fig)
    buf.seek(0)
    image_bytes = buf.read()
    
    # Codificar y cachear imagen
    data = Imagedata(
        bytes=base64.b64encode(image_bytes).decode('utf-8'),
        mime_type='image/png',
        name='generated_chart.png',
        id=uuid4().hex,
    )
    
    # Almacenar imagen en caché
    session_data = cache.get(session_id) or {}
    session_data[data.id] = data
    cache.set(session_id, session_data)
    
    return data.id

Puntos Clave:

  • Usar decorador @tool para convertir función en herramienta CrewAI
  • Usar pandas para analizar datos CSV, matplotlib para generar gráficos
  • Imágenes almacenadas como codificación base64 para transmisión de red
  • Usar IDs de sesión para gestionar aislamiento de datos para múltiples usuarios

4. Ejecutor A2A (agent_executor.py)

class ChartGenerationAgentExecutor(AgentExecutor):
    async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
        # Obtener entrada del usuario
        query = context.get_user_input()
        
        # Llamar agente CrewAI
        result = self.agent.invoke(query, context.context_id)
        
        # Obtener datos de imagen generados
        data = self.agent.get_image_data(
            session_id=context.context_id, 
            image_key=result.raw
        )
        
        if data and not data.error:
            # Crear parte de archivo conteniendo bytes de imagen
            parts = [
                Part(
                    root=FilePart(
                        file=FileWithBytes(
                            bytes=data.bytes,
                            mimeType=data.mime_type,
                            name=data.name,
                        )
                    )
                )
            ]
        else:
            # Retornar mensaje de texto en caso de error
            parts = [Part(root=TextPart(text=data.error or 'Failed to generate chart image.'))]
        
        # Agregar tarea completada a cola de eventos
        event_queue.enqueue_event(
            completed_task(
                context.task_id,
                context.context_id,
                [new_artifact(parts, f'chart_{context.task_id}')],
                [context.message],
            )
        )

Puntos Clave:

  • AgentExecutor es la capa de ejecución del protocolo A2A
  • Obtener solicitudes de usuario a través de RequestContext
  • Convertir respuestas CrewAI al formato del protocolo A2A
  • Soportar retorno de datos tipo archivo (imágenes)

5. Sistema de Caché (utils.py)

class InMemoryCache:
    """Caché simple en memoria thread-safe sin expiración."""
    
    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

Puntos Clave:

  • Implementación de caché en memoria thread-safe
  • Usado para almacenar datos de imagen generados
  • Soporta aislamiento de sesión para evitar confusión de datos de usuario

Resumen del Stack Tecnológico

  • Protocolo A2A: Protocolo de comunicación de agentes estandarizado
  • CrewAI: Framework de colaboración multi-agente
  • OpenRouter: Servicio de agregación de API LLM
  • Matplotlib: Biblioteca de generación de gráficos Python
  • Pandas: Biblioteca de procesamiento de datos
  • UV: Gestor de paquetes Python moderno

Sugerencias de Extensión

  1. Soportar Más Tipos de Gráficos: Gráficos de pastel, gráficos de línea, diagramas de dispersión, etc.
  2. Agregar Validación de Datos: Validación más fuerte de datos de entrada y manejo de errores
  3. Caché Persistente: Usar Redis o sistema de archivos para almacenar imágenes
  4. Soporte de Streaming: Soporte de progreso de generación de gráficos en tiempo real
  5. Entrada Multimodal: Soporte para subida de archivos CSV en lugar de solo entrada de texto

A través de este tutorial, has dominado las habilidades clave para construir agentes prácticos usando el stack de tecnología de IA moderna. Este agente de generación de gráficos puede servir como base para aplicaciones de análisis de datos más complejas.

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.