
{"id":57,"date":"2026-09-10T15:06:11","date_gmt":"2026-09-10T15:06:11","guid":{"rendered":"https:\/\/roboticsmaestro.com\/ai\/?p=57"},"modified":"2026-09-10T15:06:52","modified_gmt":"2026-09-10T15:06:52","slug":"setup-the-agent-to-agent-a2a-tool-and-model-router","status":"publish","type":"post","link":"https:\/\/roboticsmaestro.com\/ai\/blog\/2026\/09\/10\/setup-the-agent-to-agent-a2a-tool-and-model-router\/","title":{"rendered":"Setup the Agent-to-Agent (A2A) tool and model router"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To orchestrate multi-agent workflows efficiently, you can <mark>combine <strong>Agent-to-Agent (A2A)<\/strong> routing and a <strong>Model Router<\/strong> within Azure AI Foundry<\/mark>. This allows a primary <strong>Orchestrator Agent<\/strong> to delegate complex data operations to a specialized <strong>Data Extraction Agent<\/strong> (which calls your Azure Function MCP Server), while dynamically shifting traffic between <code>gpt-4o<\/code> (for reasoning) and <code>gpt-4o-mini<\/code> (for lower-cost data processing).<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Step 1: Deploy and Define the Models in the Project<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Before configuring the Model Router, you must ensure both target models are deployed in your Azure AI Foundry hub.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to the <strong>Azure AI Foundry Portal<\/strong> (azure.com).<\/li>\n\n\n\n<li>Under <strong>Shared Resources<\/strong>, navigate to <strong>Models + Endpoints<\/strong>.<\/li>\n\n\n\n<li>Deploy two models if you haven&#8217;t already:\n<ul class=\"wp-block-list\">\n<li><strong><code>gpt-4o<\/code><\/strong> (Name the deployment: <code>gpt-4o-heavy<\/code>)<\/li>\n\n\n\n<li><strong><code>gpt-4o-mini<\/code><\/strong> (Name the deployment: <code>gpt-4o-light<\/code>)<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Step 2: Create the Sub-Agent (Data Extraction Agent)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The downstream Sub-Agent will explicitly handle interacting with your custom Azure Function MCP server to fetch file paths.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We initialize this agent using the cheaper model (<code>gpt-4o-mini<\/code>) because structured tool execution does not require deep reasoning.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\nfrom azure.identity import DefaultAzureCredential\nfrom azure.ai.projects import AIProjectClient\nfrom azure.ai.projects.models import Agent, AgentToolbox\n\n# 1. Initialize Project Client\nproject_connection_string = os.environ&#91;\"AZURE_AI_PROJECT_CONNECTION_STRING\"]\nclient = AIProjectClient.from_connection_string(\n    credential=DefaultAzureCredential(),\n    conn_str=project_connection_string\n)\n\n# 2. Reference your existing Function App MCP Tool\n# (Assuming it's already cataloged in your Foundry workspace)\nmcp_tool_id = \"your-azure-function-mcp-tool-id\" \n\n# 3. Create the Specialized Downstream Agent\ndata_extraction_agent = client.agents.create_agent(\n    model=\"gpt-4o-mini\",  # Using the low-cost deployment for data fetching tasks\n    name=\"Data-Extraction-SubAgent\",\n    instructions=(\n        \"You are a specialized file path extraction agent. Your only job is to use the \"\n        \"provided Azure Function MCP tool to fetch structured JSON file paths from Blob and SharePoint. \"\n        \"Always return the clean JSON output back to the Orchestrator.\"\n    ),\n    tools=&#91;{\"type\": \"mcp\", \"id\": mcp_tool_id}]\n)\n\nprint(f\"Sub-Agent Created Successfully. ID: {data_extraction_agent.id}\")\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Step 3: Bundle the Sub-Agent into a Toolbox (A2A Setup)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To allow a primary Orchestrator Agent to call this sub-agent, the sub-agent must be wrapped into an <strong>Agent-to-Agent (A2A)<\/strong> tool and bundled inside a <strong>Foundry Toolbox<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># 4. Wrap the Sub-Agent as an A2A Tool definition\na2a_tool = {\n    \"type\": \"agent_to_agent\",\n    \"settings\": {\n        \"agent_id\": data_extraction_agent.id,\n        \"description\": (\n            \"Use this tool when the user requests file paths, file listings, \"\n            \"or data ingestion tasks from Azure Blob Storage or Microsoft SharePoint.\"\n        )\n    }\n}\n\n# 5. Create or Update a versioned Foundry Toolbox with this A2A Tool\ntoolbox = client.agents.create_toolbox(\n    name=\"EnterpriseRoutingToolbox\",\n    description=\"Toolbox containing data extraction sub-agents and routing policies.\",\n    tools=&#91;a2a_tool]\n)\n\nprint(f\"Toolbox published with A2A capabilities. URI: {toolbox.mcp_endpoint_uri}\")\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Step 4: Implement the Model Router and Orchestrator Agent<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A <strong>Model Router<\/strong> evaluates incoming requests and forwards them to the appropriate model based on complexity. For multi-agent orchestration, we will set up the primary agent to use a dynamic routing profile: it boots on <code>gpt-4o<\/code> for high-level semantic planning but routes sub-tasks out to the toolbox efficiently.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from azure.ai.projects.models import ModelRouterConfig, ModelRouterRule\n\n# 6. Define Model Routing Rules (JSON-schema style routing)\n# If a prompt contains phrases explicitly asking for simple status checks or raw lists,\n# the platform can automatically downgrade the primary LLM to save token costs.\nrouting_config = ModelRouterConfig(\n    default_deployment=\"gpt-4o-heavy\",\n    rules=&#91;\n        ModelRouterRule(\n            condition=\"prompt.contains('status check') or prompt.contains('just list')\",\n            target_deployment=\"gpt-4o-light\"\n        )\n    ]\n)\n\n# 7. Create the Orchestrator Agent utilizing the Model Router and A2A Toolbox\norchestrator_agent = client.agents.create_agent(\n    model_router=routing_config, # Dynamic cost optimization\n    name=\"Primary-Orchestrator\",\n    instructions=(\n        \"You are the main coordinator. Analyze user prompts. If a user asks to scan, \"\n        \"retrieve, or process files from storage systems, delegate the task completely to the \"\n        \"Data-Extraction-SubAgent tool. Synthesize its output back to the user.\"\n    ),\n    toolbox_id=toolbox.id # Injecting the Toolbox containing the A2A sub-agent connection\n)\n\nprint(f\"Orchestrator configured with Model Router and A2A Toolbox. Ready for ingestion.\")\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Step 5: Execute the Multi-Agent Flow<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When a user asks a complex question, the primary orchestrator processes the reasoning via <code>gpt-4o<\/code>, identifies that it needs storage paths, routes execution natively via <strong>A2A<\/strong> to the sub-agent, which subsequently runs the python codebase on your <strong>Azure Function App MCP Server<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Create a user thread\nthread = client.agents.create_thread()\n\n# Submit a complex multi-layered request\nclient.agents.create_message(\n    thread_id=thread.id,\n    role=\"user\",\n    content=\"Find all CSV sales reports modified yesterday in SharePoint and give me a summary report.\"\n)\n\n# Run the Orchestrator\nrun = client.agents.create_run(thread_id=thread.id, agent_id=orchestrator_agent.id)\n\n# Process the stream\nwhile run.status in &#91;\"queued\", \"in_progress\"]:\n    run = client.agents.get_run(thread_id=thread.id, run_id=run.id)\n\n# Print execution transcript\nmessages = client.agents.list_messages(thread_id=thread.id)\nfor msg in reversed(messages.data):\n    print(f\"&#91;{msg.role.upper()}]: {msg.content&#91;0].text.value}\")\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use code with caution.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Step 6: Verify Telemetry in Application Insights<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because both agents are bound to the Azure AI Project client workspace, your <strong>Application Insights<\/strong> dashboard will capture a cascading hierarchy trace:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Top-Level Span:<\/strong> <code>Primary-Orchestrator<\/code> execution via <code>gpt-4o-heavy<\/code>.<\/li>\n\n\n\n<li><strong>Child Span (A2A Route):<\/strong> Event showing delegation to <code>Data-Extraction-SubAgent<\/code>.<\/li>\n\n\n\n<li><strong>HTTP Webhook Dependency:<\/strong> Post request flowing straight into your <code>MyFoundryMcpApp<\/code> Azure Function endpoint.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">To monitor this routing overhead and cost tracking in App Insights Logs, run this query:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">kusto<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>customEvents\n| where name in (\"AgentExecution\", \"ToolCall\", \"ModelRouting\")\n| extend ModelUsed = tostring(customDimensions.model_deployment)\n| project timestamp, name, ModelUsed, duration\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">NEXT: enforce custom <strong>Input\/Output Guardrails<\/strong> at the Orchestrator level to block sensitive system paths from being sent down to the sub-agent, or we can configure a <strong>Shared Thread Memory<\/strong> pattern so both agents can access a history of files pulled previously.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>To orchestrate multi-agent workflows efficiently, you can combine Agent-to-Agent (A2A) routing and a Model Router within Azure AI Foundry. This allows a primary Orchestrator Agent to delegate complex data operations to a specialized Data Extraction Agent (which calls your Azure Function MCP Server), while dynamically shifting traffic between gpt-4o (for reasoning) and gpt-4o-mini (for lower-cost [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_regular_price":[],"currency_symbol":[],"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-57","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"post_slider_layout_featured_media_urls":{"thumbnail":"","post_slider_layout_landscape_large":"","post_slider_layout_portrait_large":"","post_slider_layout_square_large":"","post_slider_layout_landscape":"","post_slider_layout_portrait":"","post_slider_layout_square":"","full":""},"_links":{"self":[{"href":"https:\/\/roboticsmaestro.com\/ai\/wp-json\/wp\/v2\/posts\/57","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/roboticsmaestro.com\/ai\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/roboticsmaestro.com\/ai\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/roboticsmaestro.com\/ai\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/roboticsmaestro.com\/ai\/wp-json\/wp\/v2\/comments?post=57"}],"version-history":[{"count":2,"href":"https:\/\/roboticsmaestro.com\/ai\/wp-json\/wp\/v2\/posts\/57\/revisions"}],"predecessor-version":[{"id":59,"href":"https:\/\/roboticsmaestro.com\/ai\/wp-json\/wp\/v2\/posts\/57\/revisions\/59"}],"wp:attachment":[{"href":"https:\/\/roboticsmaestro.com\/ai\/wp-json\/wp\/v2\/media?parent=57"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/roboticsmaestro.com\/ai\/wp-json\/wp\/v2\/categories?post=57"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/roboticsmaestro.com\/ai\/wp-json\/wp\/v2\/tags?post=57"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}