diff --git a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/challenges/challenge-05.md b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/challenges/challenge-05.md index bfc2bc9a6..cb8174f79 100644 --- a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/challenges/challenge-05.md +++ b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/challenges/challenge-05.md @@ -5,138 +5,174 @@ > [!NOTE] > This is an **optional stretch challenge** for teams that finish early. It builds directly on the three agents you created in Challenges 2–4. Skip it without penalty β€” Challenges 1–4 are the core of the hack. +> [!IMPORTANT] +> This challenge uses the Foundry **visual workflow designer** (preview), which is supported in the portal until **30 November 2026**. Microsoft Foundry retires in-portal workflows on **1 December 2026**. + ## 🎯 Objective -Wire your three agents together in a Foundry **Workflow** so the entire sense β†’ plan β†’ approve β†’ act loop runs from one prompt. You'll use the visual workflow designer to chain the agents in sequence with a human-approval gate, then read the trace to see each node execute β€” the pattern behind real multi-agent systems. +Chain your three agents in a Foundry **Workflow** so the whole sense β†’ plan β†’ approve β†’ act loop runs from **one prompt** and pauses only for your approval. No new agent and no code: you reuse the three agents you already built. ## 🧭 Context -The planning team doesn't want to talk to three separate agents. They want to type one sentence β€” *"A heatwave is hitting the Pacific Northwest, check our outdoor power tool exposure and prepare a replenishment order for approval"* β€” and have the system run the whole loop, pausing only for the human approval gate. +The planning team doesn't want to talk to three separate agents. They want to type one sentence β€” *"A heatwave is hitting the Pacific Northwest, check our outdoor power tool exposure and prepare a replenishment order for approval"* β€” and have the system run the whole loop. + +How it works: a workflow runs its agent nodes **in order** in **one shared conversation**, so each agent automatically sees what the previous agent replied. You don't need to pass data between nodes β€” you only add a **human approval gate** on the last node. + +``` +Start ─▢ demand-sensing-agent ─▢ inventory-optimisation-agent ─▢ replenishment-action-agent ─▢ End + (waits for YES / NO / MODIFY) +``` ## βœ… Tasks -### Part A β€” Create the workflow (15 min) +### Before you start β€” 2-minute pre-flight check -> [!NOTE] -> The visual workflow designer is in preview and is supported in-portal until **1 December 2026**, after which you run the same logic by exporting the workflow **YAML** and deploying it as a hosted agent (see Learning resources). For this hack's timeframe the visual designer is the fastest no-code path. - -1. In the Foundry portal, go to **Agents β†’ Workflows β†’ + New workflow** (or **Create**). -2. Choose the **Blank** workflow β€” it already includes a **Start** node you extend. -3. Open the **Build** canvas (Visualizer view). You'll name it `inventory-planning-workflow` when you **Save** in Part B. - -### Part B β€” Add and wire the three agent nodes (20 min) - -You'll chain the three specialist agents you built in Challenges 2–4. **You do not need a separate orchestrator agent β€” the workflow *is* the orchestrator.** - -1. On the canvas, click **+ New node** (or the **+** on the Start node) and add an **Agent** node. In **Select an agent**, pick **`demand-sensing-agent`**. -2. Add a second Agent node for **`inventory-optimisation-agent`**, connected after the first. -3. Add a third Agent node for **`replenishment-action-agent`**, connected after the second. -4. For each node, open **Node settings** and wire the data flow so each agent receives the previous agent's output: - - Use **Save agent output message as** on each node to name its output (e.g. `demandAssessment`, `reorderTable`). - - Set the next node's **Input message** to that upstream variable. - - Leave **Conversation context** as `System.ConversationId` so the run shares one conversation. -5. On the **`replenishment-action-agent`** node, enable **Allow multi-turn conversation** β€” this lets the workflow pause at the purchase-order proposal and wait for the human's `YES` / `MODIFY` reply (the human-in-the-loop gate). In the **Loop condition** box, paste this PowerFx so the node keeps re-prompting until the agent submits or cancels the order: - - ```powerfx - And( - IsBlank(Find("submitted to ERP", Last(Local.LatestMessage).Text)), - IsBlank(Find("Order cancelled", Last(Local.LatestMessage).Text)) - ) - ``` +- [ ] Your three agents exist with **exactly** these names: `demand-sensing-agent`, `inventory-optimisation-agent`, `replenishment-action-agent`. +- [ ] In Challenge 4, `replenishment-action-agent` answered `YES` with `βœ… Purchase order PO-… submitted to ERP.` and `NO` with `❌ Order cancelled. …`. The approval gate below looks for those exact phrases, so don't reword them. + +If either check fails, finish Challenge 4 first β€” the workflow only reuses your agents. + +> [!WARNING] +> **The workflow designer does not save automatically**, and it only saves a **valid** workflow (every agent node has an agent, and the chain ends in **End**). Select **Save** once the workflow is valid, and again after every later change. + +### Part A β€” Create the workflow from the Sequential template (10 min) + +1. In the [Foundry portal](https://ai.azure.com), select **Build** in the upper-right menu, then **Workflows β†’ Create new workflow** (or **+ New workflow**). +2. Pick the **Sequential** template. It opens a canvas with **Start**, three **agent nodes**, and three yellow **notes** with sample marketing instructions. +3. **Delete the three yellow notes** (they're only sample text for the template). - The loop runs **while the condition is true**: `MODIFY` re-presents the proposal (neither phrase present β†’ keep looping), while `YES` (`βœ… … submitted to ERP.`) or `NO` (`❌ Order cancelled…`) makes it false and ends the node. `Find` is **case-sensitive**, so keep the Challenge 4 confirmation wording exactly. -6. Click **Save**. + ![The Sequential template canvas with three yellow sample notes above the agent nodes](../images/challenge-05-workflow-template.png) - ![Workflow canvas showing Start then demand-sensing-agent then inventory-optimisation-agent then replenishment-action-agent wired in sequence](../images/challenge-04-orchestrator.png) +Don't save yet β€” the template isn't valid until you finish Part B. -> [!TIP] -> Foundry also ships a **Human in the loop** template and a **Group chat** template. The **Sequential** pattern used here matches this hack's deterministic sense β†’ plan β†’ approve β†’ act chain; **Group chat** is for dynamic hand-off scenarios. +### Part B β€” Put your three agents in the nodes (15 min) -### Part C β€” Run the full loop from one prompt (20 min) +1. Select the **first** agent node. Choose **Use an existing agent** (labelled **existing**), search for `demand-sensing-agent`, and select it. +2. Select the **second** agent node and pick `inventory-optimisation-agent` in the same way. +3. If there is no third agent node, select the **+** after the second node β†’ **Invoke agent**. Pick `replenishment-action-agent` for the **third** node. +4. Remove any **extra** template nodes you don't use (select the node's **β‹― β†’ Delete**). +5. If there's no **End** node after `replenishment-action-agent`, select the **+** after it β†’ **Basics β†’ End**. The chain must be exactly: + **Start β†’ `demand-sensing-agent` β†’ `inventory-optimisation-agent` β†’ `replenishment-action-agent` β†’ End**. -1. Click **Preview** to open the workflow playground. -2. Send a single request, e.g.: + ![Adding an End node from the + after replenishment-action-agent, under Basics](../images/challenge-05-workflow-add-end.png) +6. Select the **`replenishment-action-agent`** node, open **Node settings**, and add the **human approval gate**: + 1. Leave **Conversation context** = `System.ConversationId` and **Input message** = `Local.LatestMessage` (the defaults β€” don't change them). + 2. Turn on **Allow multi-turn conversation**. This makes the node wait for your reply instead of ending after its first answer. + 3. In **Loop condition**, paste this formula, then select **Done**: + + ```powerfx + And( + IsBlank(Find("submitted to ERP", Last(Local.LatestMessage).Text)), + IsBlank(Find("Order cancelled", Last(Local.LatestMessage).Text)) + ) + ``` + + In plain words: *keep waiting for the human until the agent says the order was submitted or cancelled.* `MODIFY` re-presents the order and keeps waiting; `YES` or `NO` ends the node. + + ![Node settings of replenishment-action-agent: Input message Local.LatestMessage, multi-turn on, loop condition pasted, Done](../images/challenge-05-workflow-approval-gate.png) +7. Leave every other setting at its default. Select **Save**, and when asked, name the workflow `inventory-planning-workflow`. + + ![Saved inventory-planning-workflow at version 1 with Start, the three agents and End](../images/challenge-05-workflow-saved.png) + +**βœ” Checkpoint:** the name `inventory-planning-workflow` and a **Version** number show at the top, and the canvas shows the three agents in order between Start and End. + +### Part C β€” Run the full loop from one prompt (15 min) + +1. **Refresh the browser page**, then select **Preview** to open the chat pane. (Preview stays disabled while there are unsaved changes, and the chat box may not accept input until the page is refreshed after saving.) +2. Send this request: ```text A prolonged heatwave is hitting the Pacific Northwest. Check our exposure on outdoor power tools and prepare a replenishment order for approval. Include Leaf Blower X2 (P004) at Seattle and Portland. ``` > [!TIP] - > **Name the product, as in Challenge 3.** A prompt that only says "outdoor power tools" sometimes makes the Fabric Data Agent write a query that fails with a *collation conflict*, and then the later agents have no data to work with. Naming the SKU (`P004`) and the locations avoids it. If a run says it cannot verify inventory, send the request again. + > **Keep the product and stores in the prompt, as in Challenge 3.** Naming the SKU (`P004`) and the locations avoids a Fabric query error (*collation conflict*) that would leave the later agents with no data. + +3. Watch the nodes turn green one after another: demand sensing β†’ optimisation β†’ replenishment. Each agent's answer appears in the chat pane. +4. When the purchase-order proposal appears, check that the unit cost for P004 is **$95** (not the **$20** fallback). Then reply `YES`. Optionally try `MODIFY 1 50` first, then `YES`. +5. Confirm the final message is `βœ… Purchase order PO-… submitted to ERP.` and the **End** node turns green. + + ![All nodes green; the replenishment agent confirms the purchase order was submitted after YES](../images/challenge-05-workflow-run-complete.png) +6. Open the **Traces** tab of the workflow (or **Traces** next to a reply) and find your run. Expand it to see each agent node with its **Fabric IQ** tool call, and your approval turn on the replenishment node. -3. Watch the nodes execute in order: demand sensing β†’ optimisation β†’ replenishment. When the replenishment node presents the PO proposal, check that the unit costs are **$95** (P004) and not the **$20** fallback, then reply `YES` (or `MODIFY `). -4. Open **Traces** and find the run. Confirm you can see the **node-by-node execution** β€” each agent node's model call with its **Fabric IQ** tool call underneath, and the human approval turn on the replenishment node. +**βœ” Checkpoint:** one prompt plus one `YES` produced a submitted purchase order, and the trace shows all three agents. ## 🏁 Success criteria -- [ ] `inventory-planning-workflow` exists with the three agents chained Start β†’ demand β†’ optimisation β†’ replenishment. -- [ ] A single prompt drives the full sense β†’ plan β†’ approve β†’ act loop, pausing only at the human approval gate on the replenishment node. -- [ ] The trace shows node-by-node execution (each agent node β†’ its Fabric Data Agent tool call), plus the human approval turn. -- [ ] You can explain the trade-offs of a deterministic workflow vs. three agents a human drives manually β€” and when you'd choose the Group chat pattern instead. +- [ ] `inventory-planning-workflow` chains Start β†’ `demand-sensing-agent` β†’ `inventory-optimisation-agent` β†’ `replenishment-action-agent` β†’ End. +- [ ] A single prompt runs the full sense β†’ plan β†’ approve β†’ act loop and pauses only at the approval gate. +- [ ] Replying `YES` ends the run with `βœ… Purchase order PO-… submitted to ERP.` (and `NO` would end it with `❌ Order cancelled…`). +- [ ] The trace shows node-by-node execution β€” each agent's Fabric IQ tool call, plus your approval turn. +- [ ] You can explain the trade-off between a deterministic workflow and three agents a human drives manually. -## Part D β€” Alternative / bonus: an evaluation pass (optional) +## πŸ› οΈ Troubleshooting + +| Symptom | Fix | +|---------|-----| +| No **Workflows** option, or you can't create one | Make sure you use the new Foundry portal (the **New Foundry** toggle is on) and select **Build**. You need the **Contributor** role or higher on the project β€” ask your facilitator. | +| Your changes are gone | The designer doesn't save automatically. Redo the change and select **Save** after each step. | +| Your agent isn't in the **existing** agent list | Search by the exact name from Challenges 2–4. The agent must be saved in the **same** Foundry project. | +| **Save** does nothing or shows an error | The workflow isn't valid yet: every agent node needs an agent, the yellow template notes should be deleted, and the chain must end in **End** (**+ β†’ Basics β†’ End**). | +| **Preview** is greyed out, or you can't type in the preview chat | Select **Save** first, then refresh the browser page and open **Preview** again. | +| Loop condition error *"Name isn't valid"* | On the replenishment node, keep **Input message** = `Local.LatestMessage` (the default) and re-paste the formula exactly. | +| The run ends right after the proposal, without waiting for you | **Allow multi-turn conversation** is off on the replenishment node. Turn it on, **Save**, and run again in a **new** conversation. | +| The replenishment node never stops asking | The confirmation wording changed. The formula looks for `submitted to ERP` and `Order cancelled` (case-sensitive), exactly as in the Challenge 4 instructions. | +| A later agent says it has no data, or asks you to paste a table | An earlier agent returned no usable result. Start a **new** conversation and send the prompt again with the product and stores named, as in Part C. | +| The purchase order shows **$20** unit costs | That's the fallback: the agent skipped the Fabric cost lookup. Reply `NO` and run again in a **new** conversation. Expect $95 (P004), $140 (P005) and $85 (P006). | +| Something else looks wrong between nodes | Open **Traces** for the run and check which node produced the unexpected answer. Fix that agent's instructions in its own playground first, then re-run the workflow. | + +## ⭐ Optional extras (if you have time) -If you want a second stretch (or the visual designer is unavailable), evaluate one agent's quality instead: +These are **not** needed to complete the challenge. + +### A β€” Evaluate an agent (15 min) 1. Open **Evaluation** in the portal (preview). -2. Create a small evaluation dataset of 3–5 questions with expected answers about the inventory data (e.g. *"Which store has the lowest leaf blower stock?"* β†’ *"Portland"*). +2. Create a small dataset of 3–5 questions with expected answers about the inventory data (e.g. *"Which store has the lowest leaf blower stock?"* β†’ *"Portland"*). 3. Run an evaluation against `inventory-optimisation-agent` and review the **groundedness** and **relevance** scores. 4. Discuss: what would you add to the agent's instructions to improve the weakest score? -## Part E β€” What's next: publish to Teams & Microsoft 365 Copilot (showcase, optional) - -> [!NOTE] -> This part is a **look-ahead showcase**, not a required lab step. You don't need to publish anything to finish the hack β€” it's here to show where a working workflow goes next and what a business rollout looks like. +### B β€” Showcase: chat with an agent in Teams & Microsoft 365 Copilot (15 min) -Everything so far lives in the Foundry portal β€” great for builders, but the **planners who actually place orders live in Teams**. Publishing an agent to **Microsoft 365 Copilot & Teams** lets a non-technical user chat with it right inside a Teams conversation. +The planners who place orders live in Teams. Publishing an agent lets them chat with it there. > [!IMPORTANT] -> **Publish a *prompt agent*, not the workflow.** Teams / Microsoft 365 publishing supports only **prompt and hosted agents** β€” a **workflow** can't be chatted through the published endpoint (you'll get *"Agent kind 'workflow' is not supported"*). For this showcase, publish one of your prompt agents (e.g. **`demand-sensing-agent`**). Org-wide publishing needs a **Microsoft 365 admin** to approve the agent, so use the **Just you** scope β€” available immediately with no approval. +> **Publish a prompt agent, not the workflow.** Teams / Microsoft 365 publishing supports only **prompt and hosted agents**; a workflow fails with *"Agent kind 'workflow' is not supported"*. Use the **Just you** scope β€” it needs no admin approval. -1. Open your **`demand-sensing-agent`** (a prompt agent) and select **Publish β†’ Publish to Teams and Microsoft 365 Copilot**. Foundry provisions an **Azure Bot Service** resource behind the scenes. +1. Open **`demand-sensing-agent`** and select **Publish β†’ Publish to Teams and Microsoft 365 Copilot**. ![A prompt agent with the Publish menu open, showing the Teams & Microsoft 365 Copilot publish target](../images/challenge-04-teams.png) -2. Fill in the metadata: **Name** (e.g. *Inventory Planning Assistant*), **Publish version** `1.0.0`, **Short description** (e.g. *"Senses demand signals and checks inventory exposure over governed data."*), a longer **Description** (e.g. *"Chats over governed Zava inventory data to sense demand and report whether stock is adequate, at risk, or critically exposed."*), and your **Developer** name (your name or team). - > Don't put secrets/keys in any field β€” this metadata is user-visible. -3. Select **Next: Publish options β†’ Direct publish**, choose **Just you** under *Choose who can use this agent*, then **Publish**. (Org-wide = *People in your organization* β†’ M365 admin approval β†’ appears under **Built by your org** in the agent store.) -4. Open **Microsoft 365 Copilot** ([m365.cloud.microsoft](https://m365.cloud.microsoft)) or **Teams** ([teams.microsoft.com](https://teams.microsoft.com)) β€” **sign in with the same lab user** you used in Foundry, not your corporate account β€” then open the **agent store β†’ Your agents**, pick your agent, and chat like a business user: +2. Fill in **Name** (e.g. *Inventory Planning Assistant*), **Publish version** `1.0.0`, a short and a long **Description**, and your **Developer** name. Don't put secrets in any field β€” this metadata is user-visible. +3. Select **Next: Publish options β†’ Direct publish**, choose **Just you**, then **Publish**. +4. Open [Microsoft 365 Copilot](https://m365.cloud.microsoft) or [Teams](https://teams.microsoft.com) **signed in with the same lab user** you used in Foundry, open the **agent store β†’ Your agents**, pick your agent, and ask: ```text A heatwave is hitting the Pacific Northwest β€” check our outdoor power tool exposure and tell me whether we're covered or exposed. ``` -5. The agent responds in the Teams chat, grounded in your Fabric data β€” no portal, no code. *(Running the full sense β†’ plan β†’ approve loop as one Teams conversation needs the **workflow** published, which isn't supported yet β€” see the note above.)* - -**Discuss:** what governance would you add before letting hundreds of planners trigger real purchase orders from Teams? (Think: the approval gate, a spend cap, `BotServiceRbac` vs `BotServiceTenant` calling scope, and audit via the trace.) - -## πŸ› οΈ Troubleshooting - -| Symptom | Fix | -|---------|-----| -| Chatting a published **workflow** in Teams/M365 fails: *"Agent kind 'workflow' is not supported"* | Teams / Microsoft 365 publishing supports only **prompt and hosted agents**. Publish a **prompt agent** (e.g. `demand-sensing-agent`) instead β€” see Part E. | -| The replenishment node never stops looping | The **Loop condition** `Find` is **case-sensitive** β€” keep the Challenge 4 confirmation wording (`submitted to ERP`, `Order cancelled`) exactly. | -| A node doesn't receive the previous agent's output | Set **Save agent output message as** on the upstream node and reference that variable in the next node's **Input message**. | -| The purchase order shows **$20** unit costs | That is the fallback: the replenishment agent skipped the Fabric cost lookup. Reply `NO`, then run the workflow again in a **new** conversation. The costs should be $95 (P004), $140 (P005) and $85 (P006). | -| The replenishment node asks you to paste a table or SKU data instead of presenting a purchase order | An earlier node returned no usable recommendation. Run the workflow again in a **new** conversation, and name the product as in step 2 (*Include Leaf Blower X2 (P004) at Seattle and Portland*). | -| The visual designer isn't available | Do the **Part D** evaluation bonus instead, or export the workflow **YAML** and run it as a hosted agent (see Learning resources). | - -## πŸš€ Go further - -- Do the **Part D** evaluation pass to score `inventory-optimisation-agent` on groundedness and relevance. -- Follow the **Part E** showcase to publish a **prompt agent** to **Teams & Microsoft 365 Copilot** (use the *Just you* scope). -- Swap the **Sequential** template for **Group chat** and observe how dynamic hand-off changes the run. +**Discuss:** what governance would you add before hundreds of planners trigger real purchase orders from Teams? (Think: the approval gate, a spend cap, who may call the bot, and audit via the trace.) ## 🧠 Reflection -- When would you choose a deterministic workflow over three agents a human drives manually β€” and when would **Group chat** fit better? -- What governance would you add before hundreds of planners could trigger real purchase orders from Teams? -- Where does the human-approval gate belong once the loop runs end-to-end from a single prompt? +- When would you choose a deterministic workflow over three agents a human drives manually β€” and when would the **Group chat** pattern (dynamic hand-off) fit better? +- Once the loop runs end-to-end from one prompt, the approval gate is the only human checkpoint. What else would you add before production? + +> [!NOTE] +> **Using this pattern in your own scenarios after 1 December 2026.** The visual designer and in-portal workflow runs retire, but the pattern you built β€” specialist agents in a fixed order with a human approval gate β€” carries over: +> +> - **Keep your design:** before you leave, open your workflow's **YAML** view and copy the YAML. It is the portable definition of what you built today. +> - **Code-first (recommended):** run the same sequence with **Microsoft Agent Framework** β€” reuse the YAML as a *declarative workflow*, or write it in Python/.NET β€” and deploy it to Foundry as a **hosted agent**. Your prompt agents from Challenges 2–4 stay unchanged. +> - **Low-code, visual:** use **Azure Logic Apps** to call your Foundry agents as steps and mix them with business actions (approvals, emails, ERP or database writes). +> - **Simple hand-off:** if one agent only needs to call another, connect them **agent-to-agent (A2A)** instead of building a workflow. +> +> Whichever path you pick, keep the human approval gate in front of any action that changes a real system. See the [migration guide](https://learn.microsoft.com/azure/foundry/agents/concepts/workflow#migration-guide). ## πŸ“š Learning resources - [Build a workflow in Microsoft Foundry (Preview)](https://learn.microsoft.com/azure/foundry/agents/concepts/workflow) +- [Microsoft Agent Framework declarative workflows (the YAML behind the designer)](https://learn.microsoft.com/agent-framework/workflows/declarative) +- [Automate Foundry agents with workflows in Azure Logic Apps](https://learn.microsoft.com/azure/logic-apps/automate-foundry-agents-with-workflows) - [Publish agents to Microsoft 365 Copilot and Microsoft Teams](https://learn.microsoft.com/azure/foundry/agents/how-to/publish-copilot) -- [Microsoft Agent Framework workflows (code-first / YAML)](https://learn.microsoft.com/agent-framework/workflows/orchestrations/sequential) - [Agent tracing β€” Foundry](https://learn.microsoft.com/azure/foundry/observability/concepts/trace-agent-concept) - [Evaluate agents β€” Foundry](https://learn.microsoft.com/azure/foundry/observability/how-to/evaluate-agent) -- [Orchestration patterns for AI agents](https://learn.microsoft.com/azure/architecture/ai-ml/guide/ai-agent-design-patterns) +- [Orchestration patterns for AI agents](https://learn.microsoft.com/azure/architecture/ai-ml/guide/ai-agent-design-patterns) \ No newline at end of file diff --git a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/README.md b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/README.md index c2a1489f8..36f1de83d 100644 --- a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/README.md +++ b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/README.md @@ -31,5 +31,10 @@ This folder holds the screenshots embedded throughout the challenge guides and w | `challenge-02-trace.png` | 2 | The **Traces** tab's trace detail: an **Invoke Agent** span with its **Execute Tool** (Fabric) and **Chat** spans, and **Input + Output**. | | `challenge-03-approval-flow.png` | 3 | The `MODIFY 1 50` β†’ `YES` approval exchange and the simulated submission confirmation. | | `challenge-03-trace.png` | 3 | The conversation trace for the approval run: three **Invoke Agent** spans, with the Fabric unit-cost lookup only in the first. | -| `challenge-04-orchestrator.png` | 4 *(stretch)* | The `inventory-planning-workflow` canvas: Start β†’ demand-sensing β†’ inventory-optimisation β†’ replenishment-action. | +| `challenge-04-orchestrator.png` | 5 *(stretch)* | An earlier capture of the finished `inventory-planning-workflow` canvas. Not embedded now; kept for the archived workflow exercise in the post-1-December update. | +| `challenge-05-workflow-template.png` | 5 *(stretch)* | The **Sequential** template canvas with its three yellow sample notes (to delete). | +| `challenge-05-workflow-add-end.png` | 5 *(stretch)* | Adding an **End** node: **+** after `replenishment-action-agent` β†’ **Basics β†’ End**. | +| `challenge-05-workflow-approval-gate.png` | 5 *(stretch)* | `replenishment-action-agent` **Node settings**: Input message `Local.LatestMessage`, multi-turn on, loop condition, **Done**. | +| `challenge-05-workflow-saved.png` | 5 *(stretch)* | The saved `inventory-planning-workflow` (version 1): Start β†’ three agents β†’ End. | +| `challenge-05-workflow-run-complete.png` | 5 *(stretch)* | A completed run: every node green, and `βœ… Purchase order PO-… submitted to ERP.` after `YES`. | | `challenge-04-teams.png` | 4 *(stretch)* | The workflow's **Publish** menu open on **Teams & Microsoft 365 Copilot** β€” the "what's next" showcase entry point. | diff --git a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-add-end.png b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-add-end.png new file mode 100644 index 000000000..98f032caa Binary files /dev/null and b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-add-end.png differ diff --git a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-approval-gate.png b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-approval-gate.png new file mode 100644 index 000000000..4751bb42c Binary files /dev/null and b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-approval-gate.png differ diff --git a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-run-complete.png b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-run-complete.png new file mode 100644 index 000000000..b371145c8 Binary files /dev/null and b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-run-complete.png differ diff --git a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-saved.png b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-saved.png new file mode 100644 index 000000000..87bb4cf28 Binary files /dev/null and b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-saved.png differ diff --git a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-template.png b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-template.png new file mode 100644 index 000000000..e91245789 Binary files /dev/null and b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-05-workflow-template.png differ diff --git a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/walkthrough/challenge-05/solution-05.md b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/walkthrough/challenge-05/solution-05.md index 4e3187297..8e8411fed 100644 --- a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/walkthrough/challenge-05/solution-05.md +++ b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/walkthrough/challenge-05/solution-05.md @@ -6,49 +6,73 @@ ## Goal -Chain the three agents in a Foundry **Workflow** (Sequential pattern + human-in-the-loop), then read the node-by-node trace. +Chain the three agents in a Foundry **Workflow** (Sequential template) with a human approval gate on the last node, run the loop from one prompt, and read the node-by-node trace. + +> The visual designer is supported in the portal until **30 November 2026**; Foundry retires in-portal workflows on **1 December 2026**. ## Solution walkthrough -### Why a workflow +### Why it is simpler than it looks -Use a Foundry **Workflow** for multi-agent orchestration. A workflow is a *deterministic* graph: each agent is a **node**, and edges pass one node's output to the next. That's a better fit than an LLM-driven orchestrator for this hack's fixed sense β†’ plan β†’ approve β†’ act chain, and it keeps everything no-code. +All nodes run in **one shared conversation** (`System.ConversationId`), so each agent reads the previous agent's reply from the conversation history. **No data wiring between nodes is needed.** The only node that needs configuration is the last one. -Wire the three specialists in order and name each node's output so the next node can consume it: -- `demand-sensing-agent` β†’ output `demandAssessment` -- `inventory-optimisation-agent` β†’ input `demandAssessment`, output `reorderTable` -- `replenishment-action-agent` β†’ input `reorderTable`, **Allow multi-turn conversation** ON for the approval gate +### The finished workflow -> The visual designer is supported in-portal until **1 December 2026**; after that, export the workflow **YAML** and run it via Microsoft Agent Framework / a hosted agent. The orchestration logic carries over unchanged. +| Node | Agent | Settings | +|------|-------|----------| +| 1 | `demand-sensing-agent` | Defaults | +| 2 | `inventory-optimisation-agent` | Defaults | +| 3 | `replenishment-action-agent` | **Input message** = `Local.LatestMessage` (default) Β· **Allow multi-turn conversation** = on Β· **Loop condition** = formula below | -### What a good run looks like +```powerfx +And( + IsBlank(Find("submitted to ERP", Last(Local.LatestMessage).Text)), + IsBlank(Find("Order cancelled", Last(Local.LatestMessage).Text)) +) +``` -The orchestrator should narrate its delegation and stop at the approval gate: +The node keeps waiting for the human **while** the formula is true. `MODIFY` re-presents the proposal (neither phrase present), while `YES` (`βœ… … submitted to ERP.`) or `NO` (`❌ Order cancelled…`) ends the node. `Find` is case-sensitive, so the Challenge 4 confirmation wording must stay exactly as written. + +### What a good run looks like ``` -run (challenge 4 workflow) +workflow run (inventory-planning-workflow) β”œβ”€β”€ node: demand-sensing-agent -β”‚ └── tool_call: Fabric Data Agent (stock + velocity) +β”‚ └── tool_call: Fabric IQ (stock + velocity) β”‚ β†’ "Outdoor power tools critically exposed at Portland/Seattle." β”œβ”€β”€ node: inventory-optimisation-agent -β”‚ └── tool_call: Fabric Data Agent (reorder point + demand) +β”‚ └── tool_call: Fabric IQ (reorder point + demand) β”‚ β†’ recommendation table with CRITICAL items -└── node: replenishment-action-agent - β”œβ”€β”€ model_call (present PO, ask for approval) +└── node: replenishment-action-agent (multi-turn) + β”œβ”€β”€ tool_call: Fabric IQ (unit costs: P004 $95, P005 $140, P006 $85) + β”œβ”€β”€ model_call β†’ PO proposal + "Do you approve…?" β”‚ β†’ user replies: YES - └── model_call (simulated PO confirmation) + └── model_call β†’ "βœ… Purchase order PO--001 submitted to ERP." (loop ends β†’ End) ``` +### Coaching tips + +- **Run the pre-flight check first.** Most failures come from an agent name that doesn't match or a changed confirmation phrase in `replenishment-action-agent`. +- **Remind teams to Save after every change** β€” the designer doesn't save automatically, and only saves a valid workflow (template notes deleted, **End** node added). Refresh the page after saving before using **Preview**. +- **Always retry in a new conversation.** A failed run leaves its messages in the shared conversation, which confuses the next attempt. +- **Use the trace to locate a bad step**, then fix that agent in its own playground before re-running the workflow. + ### Common issues | Symptom | Fix | |---|---| -| A node gets empty input | Wire it: set the node's **Input message** to the upstream node's **Save agent output message as** variable. | -| A specialist node uses the wrong model | Each node runs its underlying agent β€” confirm that agent is on `gpt-5.4-mini` with **tool choice = required** so it always calls the Fabric tool. | -| Approval gate is skipped | Enable **Allow multi-turn conversation** on the `replenishment-action-agent` node, and keep the Challenge 4 instructions that require explicit `YES`. | -| No **Workflows** tab / designer | Preview rollout β€” use the Part D evaluation alternative instead. | +| Loop condition error *"Name isn't valid"* | Keep **Input message** = `Local.LatestMessage` (the default) on the replenishment node and re-paste the formula. | +| **Save** fails | Delete the template's yellow notes and add an **End** node (**+ β†’ Basics β†’ End**). | +| **Preview** disabled or chat won't accept input | **Save**, refresh the page, then open **Preview**. | +| The run ends at the proposal without waiting | **Allow multi-turn conversation** is off on the replenishment node. | +| The node never stops asking | The confirmation wording in the Challenge 4 instructions was changed; restore `submitted to ERP` / `Order cancelled`. | +| A later agent has no data or asks for a table | An earlier node failed (often the collation-conflict query). Start a new conversation and name the SKU and stores in the prompt. | +| `$20` unit costs | The replenishment agent skipped the Fabric cost lookup. Reply `NO` and re-run in a new conversation. | +| A node uses the wrong model or skips its tool | Each node runs its underlying agent β€” confirm the agent is on `gpt-5.4-mini` with Fabric IQ connected. | +| No **Workflows** option | Use the new Foundry portal (**Build**) and check the attendee has **Contributor** on the project. | ### Discussion points - **Deterministic workflow vs. three human-driven agents:** the workflow is faster and hands-free, but the human loses the natural checkpoints between steps. The approval gate becomes the *only* control point β€” so it matters even more. -- **Where would you add guardrails** in a production version? (e.g. a spend cap the orchestrator can't exceed without escalation.) +- **Where would you add guardrails** in a production version? (e.g. a spend cap that requires escalation, and an audit review of the trace.) +- **After 1 December 2026:** point teams to the note at the end of the challenge β€” copy the workflow YAML, then use Microsoft Agent Framework (hosted agent), Azure Logic Apps, or A2A to reuse the same pattern in their own scenarios. \ No newline at end of file