Building multi-agent systems with Vertex AI and Claude

Source notebook

Repo path: agents/agent_engine/tutorial_multi_agent_systems_on_vertexai_with_claude.ipynb · Open on GitHub · advanced

Builds a Vertex AI Agent Engine multi-agent market analysis system with Gemini, Claude, ADK, A2A, and MCP.

Summary

The notebook teaches how to build a multi-agent trading analysis platform with a Bear Agent for risk analysis, a Bull Agent for opportunity analysis, and an ADK orchestrator. It demonstrates local testing, MCP tool creation, A2A agent cards and executors, and packaging agents for Vertex AI Agent Engine deployment.

Key code patterns

Vertex AI environment setup

PROJECT_ID = "[your-project-id]"
LOCATION = "us-central1"
BUCKET_URI = f"gs://{PROJECT_ID}-agent"
os.environ["GOOGLE_CLOUD_PROJECT"] = PROJECT_ID
os.environ["GOOGLE_CLOUD_LOCATION"] = LOCATION
os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "TRUE"
client = vertexai.Client(project=PROJECT_ID, location=LOCATION)

Configures project, region, Vertex AI mode, and deployment artifact storage.

MCP tool definition

bear_mcp = FastMCP("bear-agent-tools")
 
@bear_mcp.tool()
async def risk_scanner(symbol: str) -> str:
    prices = market_generator.generate_price_series(symbol, days=30)
    current_price = prices[-1]["close"]
    return f"RISK ANALYSIS FOR {symbol}\nCurrent Price: ${current_price}"

Exposes async market-analysis functions as MCP tools agents can call.

Pydantic AI Bear Agent

provider = GoogleProvider(vertexai=True)
model = GoogleModel("gemini-2.5-flash", provider=provider)
 
bear_agent = Agent(
    model=model,
    system_prompt=bear_system_prompt,
    tools=[risk_scanner, divergence_detector, exit_signal_monitor],
    retries=2,
)

Builds a risk-focused agent using Gemini on Vertex AI with local MCP-backed tools.

ADK Bull Agent with Claude

litellm.vertex_project = os.environ.get("GOOGLE_CLOUD_PROJECT")
litellm.vertex_location = "global"
 
bull_agent = LlmAgent(
    name="bull_agent",
    model=LiteLlm("vertex_ai/claude-sonnet-4-5@20250929"),
    tools=[find_breakout_patterns, momentum_screener, entry_signal_detector],
)

Shows ADK using LiteLLM routing to call Claude Sonnet on Vertex AI.

A2A executor lifecycle

class BearAgentExecutor(AgentExecutor):
    async def execute(self, context, event_queue):
        query = context.get_user_input()
        updater = TaskUpdater(event_queue, context.task_id, context.context_id)
        await updater.submit()
        await updater.start_work()
        result = await self.agent.run(query)
        await updater.add_artifact([TextPart(text=result.output)], name="risk_analysis")
        await updater.complete()

Bridges agent execution into A2A task status updates and artifacts.

Models & APIs used

  • Models: gemini-2.5-flash, vertex_ai/claude-sonnet-4-5@20250929
  • APIs / services: Vertex AI, Vertex AI Agent Engine, Cloud Storage
  • SDKs / libraries: google-cloud-aiplatform, google-adk, google-genai, a2a-sdk, pydantic-ai, fastmcp, litellm, vertexai

When to use this

Use this pattern when deploying specialized agents that collaborate through A2A and use MCP tools on Vertex AI Agent Engine.

Gotchas & caveats

  • Requires a Google Cloud project with the Vertex AI API enabled.
  • Requires permissions to deploy agents to Vertex AI Agent Engine.
  • The notebook sets LOCATION to us-central1 for Vertex AI setup but uses global for LiteLLM Claude routing.
  • Colab authentication is only run when google.colab is present.
  • nest_asyncio is applied for async execution inside Jupyter notebooks.
  • Bear Agent deployment uses lazy initialization to avoid pickling issues.
  • Cancellation is not supported in BearAgentExecutor.
  • The notebook notes an io.UnsupportedOperation issue in Colab and skips a workaround.

Best practices

  • Test Bear and Bull agents locally before deployment.
  • Use environment variables for ADK and Vertex AI project configuration.
  • Define A2A agent cards with skills, descriptions, tags, and examples for discovery.
  • Package MCP tools as importable Python modules with a stdio server entry point.
  • Use lazy initialization for deployed agents to avoid pickling issues.
  • Use TaskUpdater to submit, start, update, complete, or fail A2A tasks.