A2A Protocol

A2A ADK Expense Reimbursement Agent

MILO
Share
A2A ADK Expense Reimbursement Agent

This is an intelligent expense reimbursement agent developed based on Google Agent Development Kit (ADK), running as an Agent2Agent (A2A) server. The core feature of this agent is intelligent form generation: when a user's reimbursement request lacks necessary information, the agent automatically generates a form for the user to fill out, ensuring complete reimbursement information is collected before processing.

Source Code

A2A ADK Sample

🎯 Project Features

  • Intelligent Form Interaction: Automatically detects missing information and generates dynamic forms
  • A2A Protocol Support: Standardized inter-agent communication protocol
  • Streaming Processing: Supports real-time responses and status updates
  • Google ADK Integration: Based on Google's latest Agent Development Kit

📋 System Requirements

  • Python 3.12 or higher
  • UV package management tool
  • Google API Key (Gemini model access)

🚀 Quick Start

1. Get Google API Key

  1. Visit Google AI Studio
  2. Log in to your Google account
  3. Click "Get API key"
  4. Create a new API key or use an existing one
  5. Copy the API key for later use

2. Environment Configuration

# Clone the project locally (if needed)
git clone https://github.com/sing1ee/a2a-adk-expense-reimbursement.git
cd a2a-adk-expense-reimbursement

# Create environment variable file
echo "GOOGLE_API_KEY=your_api_key_here" > .env

# Replace your_api_key_here with your actual API key

3. Install Dependencies and Run

# Activate virtual environment
source .venv/bin/activate

# Run the project using uv
uv run .

The server will start at http://localhost:10002.

4. Test with CLI Client

Open a new terminal window:

git clone https://github.com/a2aproject/a2a-samples.git
# Navigate to CLI client directory (assuming in samples/python/hosts/cli)
cd a2a-samples/samples/python/hosts/cli

# Connect to the reimbursement agent
uv run . --agent http://localhost:10002

5. Test Interaction Examples

Enter the following test commands in the CLI client:

# Example 1: Request with missing information (will trigger form)
I need to reimburse $20 for lunch

# Example 2: Request with complete information
I need to reimburse $50 for client lunch on January 15, 2024

# Example 3: Request with partial information
Please help me reimburse yesterday's transportation cost of $25

🏗️ Project Architecture

Core File Structure

a2a-adk-expense-reimbursement/
├── __main__.py          # Server startup entry
├── agent.py             # Core agent logic
├── agent_executor.py    # A2A request executor
├── pyproject.toml       # Project configuration and dependencies
└── README.md           # Project documentation

Main Component Description

1. __main__.py - Server Entry

  • Configure A2A server and agent information
  • Set agent skills and capability descriptions
  • Start HTTP server to listen for requests

2. agent.py - Core Agent Logic

Contains three key tool functions:

  • create_request_form(): Create reimbursement form template
  • return_form(): Wrap form in A2A protocol format and return
  • reimburse(): Execute actual reimbursement approval operation

3. agent_executor.py - Request Executor

  • Handle A2A protocol requests and responses
  • Manage task states (working, needs input, completed, etc.)
  • Coordinate communication between agent and A2A server

🔄 Core Workflow

The following sequence diagram shows the complete interaction flow of the reimbursement agent:

sequenceDiagram
    participant User as User/CLI Client
    participant Server as A2A Server
    participant Agent as Reimbursement Agent
    participant LLM as Gemini 2.0 Flash

    User->>Server: Send reimbursement request<br/>"I need to reimburse $20 for lunch"
    Server->>Agent: Forward user request
    Agent->>LLM: Analyze request content
    LLM->>Agent: Identify missing date and other info
    Agent->>Agent: Call create_request_form()
    Agent->>Agent: Call return_form()
    Agent->>Server: Return form structure
    Server->>User: Return JSON form<br/>containing date, amount, purpose fields
    
    User->>User: User fills out form<br/>date, amount, purpose
    User->>Server: Submit completed form
    Server->>Agent: Forward form data
    Agent->>LLM: Validate form completeness
    LLM->>Agent: Confirm information is complete
    Agent->>Agent: Call reimburse(request_id)
    Agent->>Server: Return approval result
    Server->>User: Return final result<br/>"Reimbursement approved"

Workflow Details

  1. Request Reception: User sends reimbursement request through CLI client
  2. Intelligent Analysis: Gemini model analyzes request and identifies missing necessary information
  3. Form Generation: If information is incomplete, automatically generate form with required fields
  4. User Interaction: User fills out form to supplement missing information
  5. Information Validation: Validate completeness and validity of form data
  6. Reimbursement Processing: Execute reimbursement approval and return result

🛠️ Advanced Configuration

Environment Variables

# Google API configuration
GOOGLE_API_KEY=your_api_key_here

# Use Vertex AI (optional)
GOOGLE_GENAI_USE_VERTEXAI=TRUE

# Server configuration
HOST=localhost
PORT=10002

Run with Custom Port

uv run . --host 0.0.0.0 --port 8080

🧪 Development and Debugging

Enable Verbose Logging

The agent enables INFO level logging by default. View detailed request processing:

# View server logs
uv run . 2>&1 | tee agent.log

Form Structure Example

The agent generates forms following JSON Schema format:

{
  "type": "form",
  "form": {
    "type": "object",
    "properties": {
      "date": {
        "type": "string",
        "format": "date",
        "title": "Date",
        "description": "Date of expense"
      },
      "amount": {
        "type": "string",
        "format": "number", 
        "title": "Amount",
        "description": "Amount of expense"
      },
      "purpose": {
        "type": "string",
        "title": "Purpose",
        "description": "Purpose of expense"
      }
    },
    "required": ["date", "amount", "purpose"]
  }
}

⚠️ Security Considerations

Important Notice: This sample code is for demonstration purposes only to show how the Agent2Agent (A2A) protocol works. When building production applications, any external agent must be treated as a potentially untrusted entity.

Security Measures

  • Input Validation: Strictly validate and sanitize all external inputs
  • Data Processing: Handle agent cards, messages, artifacts and other data with caution
  • Credential Management: Implement appropriate credential protection measures
  • Permission Control: Limit agent access permissions and operation scope