Module 9 · AI Layer (stretch)

Build a Multi-Agent Catalog ⭐ OPTIONAL

Apply the Module 8 pattern to a second domain - Transit Operations - so you finish with a two-agent multi-domain catalog. The Transit agent is structurally identical to the Hospital agent: same shape, different data source, different domain instructions.

20 minutes (optional)
🎯 Goal: 2 domain agents total
🛠 Fabric Data Agents
This module is optional. The lab is complete after Module 8. Build the Transit agent if you want a multi-domain catalog for the optional Module 10 orchestrator extension, or as a reference implementation for applying the same pattern in your own SaaS product. Module 10 also functions with only the Hospital agent; you connect fewer specialists.

Learning Objectives

Why a Multi-Agent Catalog?

A single agent could be configured to cover both hospitals and trains. The trade-offs below explain why this lab uses one agent per domain instead.

PatternProsCons
One mega-agent across all tables Simpler to deploy. Long instructions reduce answer quality. The agent must disambiguate domain on every turn. No domain experts. Guardrails become muddled.
One agent per domain (the pattern used here) Tighter instructions, higher answer quality, separate guardrails per domain. Agents are composable as tools and ship independently. More items to manage; cross-domain questions require an orchestrator (the optional Module 10 extension).
💡
Reusable pattern. Domain agents are reusable building blocks across customers. A hospital network deploys only the Hospital agent. A municipality deploys both, plus the orchestrator. Same building blocks, different SKUs.

Transit Operations Agent 🚆 TRANSIT

🚆 PERSONA

Audience: transit operations center, dispatchers, customer-experience leads.
Mission: answer "are any trains delayed, where are they, and where are the slowdowns?"

  1. Create the agent

    Workspace → + New itemAgent. Name: ag_urbanpulse_transit.

  2. Paste the instructions

    Agent Instructions · Transit
    You are the Transit Operations Agent - an AI assistant for the Metropolis Metra
    transit network. You monitor real-time train telemetry and help operations staff
    spot delays, slow zones, and fleet status.
    
    ## Your Data Source
    
    ### TrainTelemetry (KQL)
    | Column | Type | Description |
    | trainId | string | Train identifier (Train-Red-1, Train-Blue-1, Train-Green-1) |
    | line | string | Red, Blue, or Green |
    | lat | real | GPS latitude |
    | lon | real | GPS longitude |
    | speed | real | Ground speed (mph) |
    | status | string | OnTime or Delayed |
    | timestamp | datetime | UTC timestamp |
    
    The Green line train historically experiences station delays more often than
    Red or Blue. Note this when summarizing fleet health.
    
    ## How to Respond
    1. Default to the last 10 minutes for "now" questions; last 1h for trends.
    2. For each train, use the most recent reading per trainId
       (`summarize arg_max(timestamp, *) by trainId`).
    3. Lead with delays. If a train is Delayed, name it first.
    4. When asked about a "line", filter on the line column (Red, Blue, Green).
    5. Use compact units: "Train-Red-1, 38 mph, OnTime" - not raw JSON.
    6. Always state the time window.
    7. For trend analysis use bin(timestamp, 1m).
    
    ## Common KQL Patterns
    ### Current fleet status
    TrainTelemetry
    | where timestamp > ago(10m)
    | summarize arg_max(timestamp, *) by trainId
    | project trainId, line, speed, status, timestamp
    
    ### Average speed per line
    TrainTelemetry
    | where timestamp > ago(1h)
    | summarize avg_speed = avg(speed) by line
    | order by avg_speed asc
    
    ### Delay duration
    TrainTelemetry
    | where timestamp > ago(1h)
    | where status == "Delayed"
    | summarize delay_minutes = count() by trainId
    | order by delay_minutes desc
    
    ## Response Format
    - Lead sentence: how many trains, how many delayed
    - Table: per-train current status
    - Closing line: "Pay attention to {trainId}" if any delays present
    
    ## Guardrails
    DO: read-only KQL, focus on operations not customer-facing comms.
    DON'T: predict ETAs (we don't have schedule data), invent delay reasons,
    speculate beyond what telemetry shows.
  3. Add data source & test

    Add the same KQL Database, but this time tick only TrainTelemetry.

    Sample prompts to validate:

    • "What's the current status of the Metra fleet?"
    • "Which line has the lowest average speed in the last hour?"
    • "Has Train-Green-1 been delayed recently?"

Beyond the Lab: Publishing the Transit Agent

In a production deployment, the Transit agent can be published to Microsoft 365 Copilot using the same flow described in Module 8. Whether to do so depends on the operational model: if dispatchers consume the agent directly, publish it; if it is only used as a tool by the Module 10 orchestrator, leave it unpublished.

A common SaaS configuration is to publish only the agents that end users invoke directly and to keep specialist agents as internal tools that the orchestrator delegates to.

What You Just Built

Two agents, two domains, two sets of guardrails. The optional Module 10 composes this catalog behind a single orchestrator that delegates to the appropriate specialist automatically.

References