使用说明
AI Creative Studio
A distributed multi-agent orchestration system using A2A protocol, Vertex AI Agent Engine, and Cloud Run - demonstrating agent-to-agent communication with remote specialist agents for social media campaign generation.
🎬 Live Demo
Watch the complete system in action: Deploying Distributed Multi-Agent Systems to Google Cloud: Live Demo
Watch a distributed multi-agent system in action: 1 Creative Director orchestrator coordinates 5 specialist agents via A2A protocol to generate complete Instagram campaigns:from market research to Notion timeline (via MCP integration).
📋 Table of Contents
- Overview
- Architecture
- Agents Implementation
- Quick Start
- Deployment
- Testing & Observability
- Technology Stack
- Troubleshooting
🚀 Quick Links
- Complete Deployment Guide - Comprehensive step-by-step deployment instructions
- Revision Workflow Guide - Automatic quality improvement with critic feedback
- Critic Test Prompts - Test scenarios for the revision workflow
- A2A Inspector Guide - Testing individual agents with A2A Inspector
- A2A Logging Guide - Debugging and monitoring A2A interactions
Overview
AI Creative Studio demonstrates distributed multi-agent orchestration for creating complete social media campaigns. It showcases the A2A protocol with an intelligent orchestrator (Creative Director) deployed on Vertex AI Agent Engine that coordinates 5 specialist agents running on Cloud Run to handle everything from market research to project planning with (via Notion MCP integration).
Key Features
- 🌐 Distributed Multi-Agent System: Orchestrator on Vertex AI Agent Engine coordinates 5 remote specialist agents on Cloud Run
- 🔄 A2A Protocol: Standardized agent-to-agent communication over HTTPS
- 🎯 Intelligent Orchestration: Flexible routing - calls 1 agent for simple tasks, all 5 for complete campaigns
- 📊 Planning-First Approach: Orchestrator creates execution plan before delegating
- 🔁 Critic Revision Workflow: Automatic quality improvement loop - critic feedback triggers agent revisions before final delivery
- 🧠 Smart Context Compaction: Lazy summarization prevents token limit failures while preserving quality
- 📝 Notion MCP Integration: Project Manager creates tasks directly in Notion via Model Context Protocol
- 🔍 Built-in Observability: Comprehensive logging and delegation tracking via plugins
- 🔧 AgentTool Pattern: Wraps remote agents as callable tools for flexible delegation
What It Does
Input: Campaign brief
"Create Instagram campaign for EcoFlow smart water bottle targeting health-conscious millennials"
Output: Complete campaign with:
- Market research and competitor analysis
- 5 Instagram posts with captions and hashtags
- AI image generation prompts for each post
- Quality review and feedback
- Project timeline and deliverables
- Notion tasks created for project tracking (optional)
Architecture
System Architecture
graph TB
subgraph "User Interface"
USER[User/Client]
end
subgraph "Orchestration Layer - Vertex AI Agent Engine"
CD[Creative Director<br/>Orchestrator]
end
subgraph "Specialist Agents - Cloud Run"
BS[Brand Strategist<br/>Market Research]
CW[Copywriter<br/>Social Media Copy]
DS[Designer<br/>Visual Concepts]
CR[Critic<br/>Quality Review]
PM[Project Manager<br/>Timeline & Tasks]
end
subgraph "External Tools"
GS[Google Search]
NOTION[Notion API<br/>via MCP]
end
USER -->|Campaign Brief| CD
CD -->|A2A Protocol| BS
CD -->|A2A Protocol| CW
CD -->|A2A Protocol| DS
CD -->|A2A Protocol| CR
CD -->|A2A Protocol| PM
BS -->|Uses| GS
PM -->|Uses| NOTION
CD -->|Complete Campaign| USER
style CD fill:#4285f4,color:#fff
style BS fill:#34a853,color:#fff
style CW fill:#34a853,color:#fff
style DS fill:#34a853,color:#fff
style CR fill:#34a853,color:#fff
style PM fill:#34a853,color:#fff
Agent Workflow (Complete Campaign)
sequenceDiagram
participant User
participant CreativeDirector
participant BrandStrategist
participant Copywriter
participant Designer
participant Critic
participant ProjectManager
User->>CreativeDirector: Campaign Brief
Note over CreativeDirector: PLANNING PHASE<br/>Creates 5-step plan
CreativeDirector->>User: Present Plan:<br/>1. Research<br/>2. Copy<br/>3. Design<br/>4. Review<br/>5. Timeline
Note over CreativeDirector: EXECUTION PHASE
CreativeDirector->>BrandStrategist: Research market & competitors
BrandStrategist->>CreativeDirector: Audience insights, trends
CreativeDirector->>User: ✓ Research complete
CreativeDirector->>Copywriter: Create posts with insights
Copywriter->>CreativeDirector: 5 Instagram posts
CreativeDirector->>User: ✓ Copywriting complete
CreativeDirector->>Designer: Generate image prompts
Designer->>CreativeDirector: Image concepts
CreativeDirector->>User: ✓ Design complete
CreativeDirector->>Critic: Review all creative work
Critic->>CreativeDirector: Quality feedback
CreativeDirector->>User: ✓ Review complete
CreativeDirector->>ProjectManager: Create timeline
ProjectManager->>CreativeDirector: Project plan
CreativeDirector->>User: ✓ Timeline complete
CreativeDirector->>User: Final Campaign<br/>(All 5 sections)
Deployment Architecture
graph TB
subgraph "Google Cloud Platform"
subgraph "Vertex AI Agent Engine"
AE[Creative Director<br/>Orchestrator Agent]
end
subgraph "Cloud Run Services"
CR1[brand-strategist-agent<br/>Port 8000]
CR2[copywriter-agent<br/>Port 8000]
CR3[designer-agent<br/>Port 8000]
CR4[critic-agent<br/>Port 8000]
CR5[project-manager-agent<br/>Port 8000]
end
subgraph "APIs"
GEMINI[Gemini API<br/>2.5 Flash]
end
end
subgraph "Environment Configuration"
ENV[.env file with:<br/>- Agent URLs<br/>- API Keys<br/>- Project ID]
end
ENV -.->|Agent URLs| AE
AE -->|HTTPS + A2A| CR1
AE -->|HTTPS + A2A| CR2
AE -->|HTTPS + A2A| CR3
AE -->|HTTPS + A2A| CR4
AE -->|HTTPS + A2A| CR5
CR1 & CR2 & CR3 & CR4 & CR5 -->|LLM Calls| GEMINI
style AE fill:#4285f4,color:#fff
style CR1 fill:#34a853,color:#fff
style CR2 fill:#34a853,color:#fff
style CR3 fill:#34a853,color:#fff
style CR4 fill:#34a853,color:#fff
style CR5 fill:#34a853,color:#fff
Agent Communication Flow
graph LR
subgraph "Creative Director (Orchestrator)"
LLM1[Gemini 2.5 Flash]
AT1[AgentTool: brand_strategist]
AT2[AgentTool: copywriter]
AT3[AgentTool: designer]
AT4[AgentTool: critic]
AT5[AgentTool: project_manager]
end
subgraph "Remote Agents via A2A"
R1[RemoteA2aAgent<br/>brand_strategist]
R2[RemoteA2aAgent<br/>copywriter]
R3[RemoteA2aAgent<br/>designer]
R4[RemoteA2aAgent<br/>critic]
R5[RemoteA2aAgent<br/>project_manager]
end
LLM1 -->|Function Call| AT1
LLM1 -->|Function Call| AT2
LLM1 -->|Function Call| AT3
LLM1 -->|Function Call| AT4
LLM1 -->|Function Call| AT5
AT1 -->|A2A Protocol<br/>HTTPS| R1
AT2 -->|A2A Protocol<br/>HTTPS| R2
AT3 -->|A2A Protocol<br/>HTTPS| R3
AT4 -->|A2A Protocol<br/>HTTPS| R4
AT5 -->|A2A Protocol<br/>HTTPS| R5
style LLM1 fill:#fbbc04,color:#000
style AT1 fill:#4285f4,color:#fff
style AT2 fill:#4285f4,color:#fff
style AT3 fill:#4285f4,color:#fff
style AT4 fill:#4285f4,color:#fff
style AT5 fill:#4285f4,color:#fff
Agents Implementation
Agent Types
1. Creative Director (Orchestrator)
File: agents/creative_director/agent.py
Type: Agent (not LlmAgent) with AgentTool wrappers
Pattern: AgentTool + Planning-First
Key Implementation:
from google.adk.agents import Agent
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent
from google.adk.tools.agent_tool import AgentTool
from google.adk.apps import App
from google.adk.apps.app import EventsCompactionConfig
from google.adk.apps.llm_event_summarizer import LlmEventSummarizer
from google.adk.models import Gemini
# Create remote agents
strategist_agent = RemoteA2aAgent(
name="brand_strategist",
description="Brand strategist for market research",
agent_card=f"{STRATEGIST_URL}/.well-known/agent.json"
)
# Wrap as AgentTool
strategist_tool = AgentTool(agent=strategist_agent)
# Create orchestrator agent
agent = Agent(
name="creative_director",
model="gemini-2.5-flash",
tools=[strategist_tool, copywriter_tool, designer_tool, critic_tool, pm_tool],
instruction=PLANNING_FIRST_INSTRUCTION,
generate_content_config=GenerateContentConfig(
max_output_tokens=20000, # Support full 5-agent workflows
temperature=0.2
)
)
# Configure lazy context compaction for scalability
summarizer = LlmEventSummarizer(llm=Gemini(model_id="gemini-2.5-flash"))
compaction_config = EventsCompactionConfig(
summarizer=summarizer,
compaction_interval=3, # Summarize after every 3 agents
overlap_size=1 # Keep most recent agent's full output
)
# Wrap in App with compaction
app = App(
name="creative_director",
root_agent=agent,
events_compaction_config=compaction_config
)
Instruction Pattern:
The orchestrator uses a planning-first instruction pattern:
- Understand Request Complexity: Determine if task needs 1 agent or all 5
- Create Plan BEFORE Delegating: Outline complete sequence to user
- Execute Sequentially: Call each agent, wait for response, confirm, continue
- Pass Context: Each agent receives relevant output from previous agents
Context Compaction Strategy:
To prevent token limit failures in long workflows, the orchestrator uses lazy context compaction:
- When: After every 3 agent completions (configurable)
- How: Older agent outputs are summarized using Gemini Flash
- Quality: Most recent agent's full output is preserved (overlap_size=1)
For a 5-agent workflow:
- Agents 1-3 (Strategist → Copywriter → Designer): Full context preserved
- After Agent 3: Context compacted → Agents 1-2 summarized, Agent 3 kept full
- Agents 4-5 (Critic → PM): See full recent context + summarized earlier work
Benefits:
- ✅ Prevents token limit failures in multi-agent workflows
- ✅ Preserves quality (full recent context always available)
- ✅ Scales to 10+ agent workflows
- ✅ Cost efficient (only summarizes when needed)
Simple Request → Calls 1 agent:
User: "Just research the market for eco water bottles"
→ Creative Director calls brand_strategist only
Complex Request → Calls all 5 agents:
User: "Create complete campaign with posts and timeline"
→ Creative Director executes all 5 steps sequentially
Deployment: Vertex AI Agent Engine (handles agent URLs via environment variables at runtime)
2. Brand Strategist
File: agents/brand_strategist/agent.py
Type: LlmAgent
Tools: google_search
Responsibility: Research market trends, competitors, and target audience insights
Output Format:
**Audience Insights:**
[Key behaviors, preferences, pain points]
**Competitive Analysis:**
[2-3 competitors - strengths and weaknesses]
**Trending Topics:**
[3-5 relevant trends]
**Key Strategic Insights:**
[High-level themes and positioning]
Deployment: Cloud Run with A2A server
3. Copywriter
File: agents/copywriter/agent.py
Type: LlmAgent
Tools: None (pure LLM)
Responsibility: Create engaging social media captions and copy
Input: Receives campaign brief + brand strategist insights from conversation history
Output Format:
### 1. Caption Title: [Theme]
**Full Caption Text:**
[Caption with emojis]
**Hashtags:**
#tag1 #tag2 #tag3...
**Suggested CTA:**
[Call to action]
Deployment: Cloud Run with A2A server
4. Designer
File: agents/designer/agent.py
Type: LlmAgent
Tools: None (pure LLM)
Responsibility: Generate AI image concepts and visual design prompts
Input: Receives copywriter's posts from conversation history
Output Format:
**For Caption 1: [Theme]**
**Concept A: [Visual Theme]**
- Prompt: [Detailed Imagen prompt]
- Style: [minimalist, vibrant, cinematic]
- Colors: [Palette]
- Mood: [energetic, calm, inspiring]
Deployment: Cloud Run with A2A server
5. Critic
File: agents/critic/agent.py
Type: LlmAgent
Tools: None (pure LLM)
Responsibility: Review creative work and provide quality feedback
Input: Receives all outputs (strategy, copy, visuals) from conversation history
Output Format:
**Overall Assessment:**
[Quality score and summary]
**Strengths:**
[What works well]
**Areas for Improvement:**
[Specific suggestions]
**Platform Optimization:**
[Instagram-specific recommendations]
Deployment: Cloud Run with A2A server
Revision Workflow: When the Critic identifies issues (Status: NEEDS_REVISION), the orchestrator automatically calls the relevant agent (copywriter or designer) with the critic's feedback to revise the work before proceeding to the Project Manager. See docs/REVISION_WORKFLOW.md for details.
6. Project Manager
File: agents/project_manager/agent.py
Type: Agent (using Agent class with MCP tools)
Tools: Notion MCP (Model Context Protocol) via @notionhq/notion-mcp-server
Responsibility: Create project timelines, tasks, and deliverables with Notion integration
MCP Integration:
- Connects to Notion API via MCP server:
@notionhq/notion-mcp-server - Uses
McpToolsetwithStdioConnectionParamsto spawn MCP server as subprocess - Creates project and task pages in two separate Notion databases
How MCP works here:
The agent connects to @notionhq/notion-mcp-server via stdio. The server returns a list of tools with their descriptions — the LLM reads these and decides which to call based on the task. No tool sequence is hardcoded in the agent.
Tools advertised by @notionhq/notion-mcp-server (the LLM picks from these):
API-post-page: Create new pages in databases (projects or tasks)API-patch-page: Update existing pagesAPI-post-search: Search for existing pagesAPI-post-database-query: Query databases with filtersAPI-retrieve-a-database: Get database schema and details
Notion Database Structure:
TWO DATABASES REQUIRED — the agent discovers their schemas dynamically at runtime using API-retrieve-a-database, so property names can be anything. The default template uses:
-
Projects Database (ID from
NOTION_PROJECT_DATABASE_IDenvironment variable)- One title property (campaign name)
- One status property (e.g., "In progress", "Completed")
- One select property for priority (e.g., "High", "Medium", "Low")
- One date property with start and end (e.g., campaign dates)
- One rich_text property for summary
-
Tasks Database (ID from
NOTION_TASKS_DATABASE_IDenvironment variable)- One title property (task description)
- One status property (e.g., "Not started", "In progress", "Done")
- One select property for priority
- One date property for deadline
- One relation property linking to the Projects database
Dynamic schema discovery: the agent never hardcodes property names. The MCP server exposes
API-retrieve-a-databaseas a tool — the LLM calls it autonomously to read exact property names and valid values before writing. Rename your properties to any language — the agent adapts automatically.
Environment Variables:
NOTION_API_KEY: Notion integration token (passed asNOTION_TOKENto MCP server)NOTION_PROJECT_DATABASE_ID: Database ID for the Projects databaseNOTION_TASKS_DATABASE_ID: Database ID for the Tasks database
Workflow:
- ADK connects the agent to the MCP server at startup — the server advertises its available tools
- The LLM receives the task and decides which MCP tools to call and in what order
- Typically: discovers schemas → creates project page → creates task pages linked to the project
- Generates the text timeline regardless of whether Notion operations succeed
Input: Receives complete campaign details from conversation history
Output Format:
**Project Timeline:**
[Gantt-style timeline]
**Key Milestones:**
[Major checkpoints]
**Tasks & Deliverables:**
[Detailed task list with Notion links]
**Team Responsibilities:**
[Who does what]
Deployment: Cloud Run with A2A server and Notion MCP integration
Agent-to-Agent (A2A) Protocol
All specialist agents expose an A2A server for remote communication:
# agents/[agent_name]/app.py
from google.adk.servers.a2a_server import A2aServer
a2a_server = A2aServer(agent=root_agent)
app = a2a_server.create_app()
if __name__ == "__main__":
a2a_server.run(port=8000)
A2A Features:
- 📡 Agent Card:
/.well-known/agent.json- describes agent capabilities - 🔄 Stateless: Each request is independent
- 🌐 HTTP-based: Standard HTTPS communication
- 📝 JSONRPC: Structured message format
AgentTool Pattern
The orchestrator uses the AgentTool pattern to wrap remote agents as callable tools:
Why AgentTool?
- ✅ Flexible routing (LLM decides which agents to call)
- ✅ Can call same agent multiple times (revisions)
- ✅ Passes context between sequential calls
- ✅ Works with remote A2A agents
How It Works:
graph LR
A[LLM generates<br/>function call] --> B[AgentTool intercepts]
B --> C[Wraps request in<br/>A2A protocol]
C --> D[Sends HTTPS request<br/>to remote agent]
D --> E[Remote agent<br/>processes]
E --> F[Returns response<br/>via A2A]
F --> G[AgentTool unwraps]
G --> H[Returns to<br/>orchestrator LLM]
Quick Start
Prerequisites
- Google Cloud Project with billing enabled
- Python 3.11+
- Google API Key from AI Studio
- gcloud CLI installed and configured
- Node.js and npm (for Notion MCP server via npx)
- Notion Account (optional, for Project Manager integration)
-
Create a Notion integration at Notion Developers
-
Create TWO databases in Notion with the following properties:
Projects Database:
- Project name (Title)
- Status (Status)
- Priority (Select: High, Medium, Low)
- Dates (Date with start and end)
- Summary (Rich text)
Tasks Database:
- Task name (Title)
- Status (Status: Not started, In progress, Done)
- Priority (Select: High, Medium, Low)
- Due (Date)
- Project (Relation to Projects database)
-
Share both databases with your integration
-
Copy the Integration Token and Projects Database ID
-
Copy the Tasks Database ID and update it in
agents/project_manager/agent.py:59
-
1. Clone and Install
# Clone repository
git clone <your-repo-url>
cd ai-creative-studio
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
2. Configure Environment
# Copy environment template
cp .env.example .env
Edit .env with your credentials:
# Google Cloud
PROJECT_ID="your-gcp-project-id"
REGION="us-central1"
# Gemini API
GOOGLE_API_KEY="your-gemini-api-key"
# Notion Integration (for Project Manager)
# IMPORTANT: You need TWO databases:
# 1. Projects Database (ID from NOTION_PROJECT_DATABASE_ID)
# 2. Tasks Database (ID from NOTION_TASKS_DATABASE_ID)
NOTION_API_KEY="your-notion-integration-token"
NOTION_PROJECT_DATABASE_ID="your-projects-database-id"
NOTION_TASKS_DATABASE_ID="your-tasks-database-id"
# Agent URLs (will be filled after deployment)
STRATEGIST_AGENT_URL=""
COPYWRITER_AGENT_URL=""
DESIGNER_AGENT_URL=""
CRITIC_AGENT_URL=""
PM_AGENT_URL=""
3. Test a Single Agent Locally
# Test brand strategist
cd agents/brand_strategist
python agent.py
Expected output:
🎯 Starting Brand Strategist Agent...
Brief:
Research competitors for eco-friendly water bottles targeting millennials
User > Research competitors for eco-friendly water bottles
brand_strategist > **Audience Insights:**
...
4. Deploy Complete System
# Deploy all agents (specialists + orchestrator) with one command
cd deploy
./deploy_complete_system.sh
This will:
- Load environment variables (including Notion credentials)
- Deploy all 5 specialist agents to Cloud Run (in parallel)
- Collect agent URLs automatically
- Deploy Creative Director to Vertex AI Agent Engine
- Output resource name
Or deploy specialists separately:
# Deploy all specialists only
cd deploy
python3 deploy_all_specialists.py
5. Alternative: Deploy Orchestrator Separately
# Deploy orchestrator only (after specialists are deployed)
python3 deploy_orchestrator.py --action deploy
This will:
- Use already-deployed specialist agents (or deploy them if --auto-deploy-specialists flag is used)
- Read agent URLs from environment variables
- Deploy Creative Director to Vertex AI Agent Engine
- Output resource name
Copy the resource name and add to .env:
AGENT_ENGINE_RESOURCE_NAME="projects/123456789/locations/us-central1/reasoningEngines/987654321"
6. Test the Complete System
# Test orchestrator with deployed agents
cd ..
python test_orchestrator.py
Expected output:
================================================================================
Testing Campaign: EcoFlow Water Bottle (B2C)
================================================================================
creative_director > I'll coordinate our team to create your complete social media
campaign. Here's my plan:
1. Brand Strategist will research the market
2. Copywriter will create 5 Instagram posts
3. Designer will generate image concepts
4. Critic will review quality
5. Project Manager will create timeline
Let's begin with the market research!
[... full campaign output ...]
Total Events: 11+
✓ Success!
Deployment
Complete System Deployment (Recommended)
Deploy everything with a single command:
cd deploy
./deploy_complete_system.sh
This script:
- ✅ Deploys all 5 specialist agents to Cloud Run (in parallel)
- ✅ Collects agent URLs automatically
- ✅ Deploys Creative Director to Agent Engine with URLs
- ✅ Outputs complete configuration
Time: ~10-15 minutes for complete deployment
Alternative Deployment Options
Option 1: Python Script with Auto-Deploy
cd deploy
python3 deploy_orchestrator.py --action deploy --auto-deploy-specialists
Same as the shell script above, but gives you more control and detailed output.
Option 2: Manual Deployment
If you prefer manual control over each step:
# Step 1: Deploy all specialist agents (with public agent cards)
cd deploy
python3 deploy_all_specialists.py
# Step 2: Deploy orchestrator with collected URLs
python3 deploy_orchestrator.py --action deploy
Deployment Architecture Details
Specialist Agents → Cloud Run:
- Containerized with A2A server
- Auto-scaling (0-100 instances)
- Public HTTPS endpoints (--allow-unauthenticated for agent cards)
- Uses default Compute Engine service account
- Environment variables:
GOOGLE_GENAI_USE_VERTEXAI=trueGOOGLE_CLOUD_PROJECTandGOOGLE_CLOUD_LOCATIONNOTION_API_KEY(Project Manager only - for Notion MCP integration)NOTION_PROJECT_DATABASE_ID(Project Manager only - Projects database ID)
Creative Director → Vertex AI Agent Engine:
- Managed agent runtime
- Environment: All 5 agent URLs + API key
- No containerization needed
- Integrated with Vertex AI
Environment Variables Setup
The deployment scripts automatically configure:
# For Creative Director (Agent Engine)
GOOGLE_API_KEY="..."
STRATEGIST_AGENT_URL="https://brand-strategist-agent-...-uc.a.run.app"
COPYWRITER_AGENT_URL="https://copywriter-agent-...-uc.a.run.app"
DESIGNER_AGENT_URL="https://designer-agent-...-uc.a.run.app"
CRITIC_AGENT_URL="https://critic-agent-...-uc.a.run.app"
PM_AGENT_URL="https://project-manager-agent-...-uc.a.run.app"
⚠️ Important: Agent URLs are read at runtime using os.getenv(), not at build time!
Testing & Observability
A2A Protocol Logging
The system includes comprehensive logging for all Agent-to-Agent (A2A) interactions:
Features:
- 🔍 Automatic Logging: All A2A calls logged to Cloud Logging
- 📊 Protocol Details: Agent names, timestamps, query/response sizes
- 🎯 Error Detection: Automatic flagging of failed agent calls
- 📈 Performance Tracking: Response times and workflow analysis
Viewing Logs:
# Fetch recent A2A logs
cd deploy
./fetch_orchestrator_logs.sh 1h
# Analyze logs
python3 analyze_agent_logs.py /tmp/orchestrator_logs_*.txt
# Monitor live
gcloud logging tail \
'resource.type="aiplatform.googleapis.com/ReasoningEngine"' \
--project=YOUR_PROJECT_ID
📖 Complete Guide: A2A_LOGGING_GUIDE.md
- How to access A2A logs
- Log analysis and metrics
- Debugging A2A issues
- Performance monitoring
Example Log Output:
======================================================================
🔧 A2A AGENT CALL: brand_strategist
Timestamp: 2025-12-18T22:45:12.123456
Protocol: Agent-to-Agent (A2A)
Query length: 450 chars
======================================================================
======================================================================
📥 A2A AGENT RESPONSE: brand_strategist - ✅ SUCCESS
Timestamp: 2025-12-18T22:45:19.654321
Response length: 2340 chars
======================================================================
A2A Inspector Testing
Test individual agents with the A2A Inspector tool (locally and on Cloud Run):
# Setup inspector (one-time)
cd deploy
./setup_inspector.sh
# Start inspector
cd ~/a2a-inspector
bash scripts/run.sh
# Open http://localhost:5001
# Connect to local agent: http://localhost:8080
# Or Cloud Run agent with auth token
📖 See full guide: A2A_INSPECTOR_GUIDE.md
- How to test agents locally
- How to test Cloud Run deployments
- Troubleshooting common issues
Local Testing with Plugins
For deep debugging and observability:
python test_orchestrator_local_with_plugins.py
Features:
-
🔍 LoggingPlugin: Comprehensive ADK logging
- LLM requests and responses
- Tool calls and results
- Token usage
- Event timeline
-
📊 AgentDelegationTrackerPlugin: Custom delegation tracking
- Which agents were called
- Sequence of calls
- Diagnosis of workflow completion
- Summary report
Output:
================================================================================
🔍 AGENT DELEGATION TRACKER - SUMMARY
================================================================================
📊 AGENT CALLS:
• creative_director: 1 call(s)
• brand_strategist: 1 call(s)
• copywriter: 1 call(s)
• designer: 1 call(s)
• critic: 1 call(s)
• project_manager: 1 call(s)
🎯 EXPECTED SPECIALIST AGENTS:
• brand_strategist: ✅ CALLED
• copywriter: ✅ CALLED
• designer: ✅ CALLED
• critic: ✅ CALLED
• project_manager: ✅ CALLED
🩺 DIAGNOSIS:
✅ SUCCESS: All specialist agents were called!
Testing Remote Deployment
# Test deployed orchestrator
python test_orchestrator.py
Using adk web for Interactive Testing
# Test orchestrator locally with web UI
cd agents/creative_director
adk web --log_level DEBUG
Then open http://localhost:8000 to interact with the agent through a web interface.
Technology Stack
Core Technologies
- Google ADK: Agent Development Kit for building distributed agents
- Gemini 2.5 Flash: Fast, efficient multimodal LLM
- A2A Protocol: Agent-to-Agent communication standard
- Vertex AI Agent Engine: Managed agent runtime for orchestrator
- Cloud Run: Serverless container platform for specialist agents
- Model Context Protocol (MCP): Standard protocol for tool integration
- Notion API: Task management and database integration
Key Patterns
- Distributed Multi-Agent Architecture: Orchestrator and specialist agents deployed separately, communicating via A2A
- AgentTool Pattern: Wrapping remote agents as tools for flexible orchestration
- Planning-First: Orchestrator creates plan before execution
- Sequential Execution: Agents execute in order with context passing
- Lazy Context Compaction: Smart summarization prevents token limits while preserving quality
- MCP Integration: External tool integration via Model Context Protocol (Notion)
- Plugin-Based Observability: Logging and tracking via ADK plugins
Project Structure
ai-creative-studio/
├── agents/
│ ├── creative_director/ # Orchestrator
│ │ ├── agent.py # Agent definition with AgentTool pattern
│ │ └── app.py # Not used (deployed to Agent Engine)
│ ├── brand_strategist/ # Market research agent
│ │ ├── agent.py # Agent definition
│ │ ├── app.py # A2A server
│ │ └── Dockerfile # Cloud Run deployment
│ ├── copywriter/ # Social media copy agent
│ ├── designer/ # Visual design agent
│ ├── critic/ # Quality review agent
│ ├── project_manager/ # Timeline & planning agent (with Notion MCP)
│ └── common/
│ ├── setup.sh # Local development setup
│ └── test_local.sh # Local A2A testing
├── deploy/
│ ├── deploy_all_specialists.py # Deploy all specialists to Cloud Run
│ ├── deploy_complete_system.sh # One-command full deploy
│ ├── deploy_orchestrator.py # Deploy orchestrator to Agent Engine
│ ├── env_utils.py # Environment variable utilities
│ ├── teardown_gcp.sh # Clean up resources
│ ├── test_agents.sh # Test agents
│ └── test_deployed_agents.py # Comprehensive tests
├── tools/
│ └── a2a-inspector/ # A2A debugging and testing tools
│ ├── setup_inspector.sh # Setup A2A Inspector
│ ├── A2A_INSPECTOR_GUIDE.md # Inspector usage guide
│ ├── A2A_LOGGING_GUIDE.md # Logging guide
│ └── README.md
├── requirements.txt
├── .env.example
├── DEPLOYMENT_GUIDE.md
└── README.md
Troubleshooting
Common Issues
1. Orchestrator Stops After 2-3 Agents (Token Limit)
Symptom: Orchestrator stops after calling designer (agent 3), doesn't complete critic and project_manager
Root Cause: The orchestrator hits the token output limit (default 8192) before completing all 5 agents. Each agent produces 1000-3000 token outputs, and the orchestrator presents full results.
Solution: The orchestrator now uses lazy context compaction (implemented in agents/creative_director/agent.py):
# Increased token limit
max_output_tokens=20000 # From 8192
# Lazy context compaction (summarizes after 3 agents)
compaction_config = EventsCompactionConfig(
compaction_interval=3, # Summarize after every 3 agents
overlap_size=1, # Keep most recent agent's full output
summarizer=LlmEventSummarizer(llm=Gemini(model_id="gemini-2.5-flash"))
)
How it works:
- Agents 1-3: Full context preserved
- After Agent 3: Older agents (1-2) are summarized, Agent 3 kept full
- Agents 4-5: Receive full recent context + summarized earlier work
To verify fix:
python deploy/test_deployed_agents.py --test orchestrator
# Should see all 5 agents complete: strategist → copywriter → designer → critic → project_manager
2. Orchestrator Only Calls One Agent
Symptom: Orchestrator stops after calling brand_strategist only
Solution: Ensure you're using the latest agent.py with:
- ✅
Agent(notLlmAgent) withAgentToolwrappers - ✅ Planning-first instruction pattern
- ✅ Step-by-step confirmation pattern
3. Agent URLs Not Found
Symptom: RemoteA2aAgent fails with "Cannot resolve agent card"
Solution:
# Verify URLs are set
echo $STRATEGIST_AGENT_URL
# Test URL directly
curl https://your-agent-url/.well-known/agent.json
# Redeploy with correct URLs
cd deploy
python3 deploy_orchestrator.py --action deploy
4. API Quota Exceeded (429 Error)
Symptom: "You exceeded your current quota" error
Solutions:
- Use Vertex AI deployment (no quota limits)
- Upgrade to paid Gemini API tier
- Add retry logic with exponential backoff (already in code)
5. Cloud Run Agent Not Accessible
Symptom: "Connection refused" or "Service unavailable"
Solution:
# Check Cloud Run service
gcloud run services describe brand-strategist-agent --region us-central1
# Verify agent card is accessible
curl https://brand-strategist-agent-xxxxx-uc.a.run.app/.well-known/agent.json
# Check logs
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=brand-strategist-agent" --limit 50
6. Import Errors
Symptom: ModuleNotFoundError: No module named 'google.adk'
Solution:
# Reinstall dependencies
pip install -r requirements.txt
# Verify ADK installation
python -c "import google.adk; print(google.adk.__version__)"
Getting Help
- Documentation: See DEPLOYMENT_GUIDE.md for detailed setup
- A2A Debugging: See A2A Inspector Guide for debugging agents
- Logging: See A2A Logging Guide for log analysis
- Architecture: See architecture diagrams in this README
Debug Mode
Enable DEBUG logging for detailed output:
# Local testing with DEBUG logs
python test_orchestrator_local_with_plugins.py
# View detailed logs
cat orchestrator_test.log
Advanced Usage
Custom Plugins
Create custom plugins for observability:
from google.adk.plugins.base_plugin import BasePlugin
class CustomMetricsPlugin(BasePlugin):
async def before_agent_callback(self, *, agent, callback_context):
# Your custom logic
print(f"Agent {agent.name} starting...")
Adding New Agents
- Create agent directory:
agents/new_agent/ - Implement
agent.pywithLlmAgent - Create
app.pywith A2A server - Add Dockerfile
- Update orchestrator's tools
- Deploy to Cloud Run
- Add URL to orchestrator environment
MCP Integration
The Project Manager agent integrates with Notion via Model Context Protocol (MCP):
# agents/project_manager/agent.py
from google.adk.tools.mcp_tool import McpToolset, StdioConnectionParams
from mcp import StdioServerParameters
# Configure Notion MCP server
# IMPORTANT: Notion MCP server expects NOTION_TOKEN, not NOTION_API_KEY
mcp_env = {
"NOTION_TOKEN": os.getenv("NOTION_API_KEY"), # Pass as NOTION_TOKEN
"PATH": os.environ.get("PATH", "/usr/local/bin:/usr/bin:/bin")
}
server_params = StdioServerParameters(
command="notion-mcp-server", # Use globally installed version from Dockerfile
args=[],
env=mcp_env
)
# Create MCP toolset
notion_toolset = McpToolset(
connection_params=StdioConnectionParams(
server_params=server_params,
timeout=30.0 # Timeout for MCP server startup
)
)
# Add to agent
agent = Agent(
name="project_manager",
model="gemini-2.5-flash",
tools=[notion_toolset],
instruction=get_system_instruction(database_id=os.getenv("NOTION_PROJECT_DATABASE_ID"))
)
MCP Server: Uses the official @notionhq/notion-mcp-server package version 1.9.1
Important: The Dockerfile pins the MCP server to version 1.9.1 to avoid UUID reformatting bugs in version 2.0.0. The agent uses the globally installed version instead of downloading the latest via npx.
Dockerfile Configuration:
# Install Notion MCP server globally (pinned to 1.9.1)
RUN npm install -g @notionhq/notion-mcp-server@1.9.1
Environment Variables Required:
NOTION_API_KEY: Your Notion integration token (passed asNOTION_TOKENto MCP server)NOTION_PROJECT_DATABASE_ID: The Projects database ID- Tasks Database ID: Hardcoded in
agent.py:59(default:2ceb1b31123181508894ddb3c597dc48)
Available MCP Operations:
API-post-page: Create project/task pages in Notion databasesAPI-patch-page: Update existing page propertiesAPI-post-search: Search for pagesAPI-post-database-query: Query databases with filtersAPI-retrieve-a-database: Get database schema and details
Test the Integration:
cd agents/project_manager
python test_local_notion.py
License
MIT License - See LICENSE file for details
Acknowledgments
Built with:
Questions? Check QUICK_START.md or review the architecture diagrams above.