Tools, Flows, and Adaptive Cards

Choose the right tool for calculations, transformations, external actions, and structured output. Report success only when the responsible system confirms it.


What you'll learn

  • Choose the smallest tool that fits an operation
  • Write custom prompts and calculations that refuse to invent
  • Build an agent flow that reports only confirmed results
  • Diagnose an Adaptive Card failure from the layer that holds the wrong value
On this page

An agent can discuss equipment requests all day. When someone asks it to submit one, the job changes. An answer is text. A submission is a record that either exists in the target system or doesn't.

Prompts, calculations, connectors, flows, and cards let an agent move beyond conversation. They don't all prove the same thing. In this lesson, you'll choose each tool by the operation it performs and reserve success language for results the responsible system has confirmed.

Which tool does this job?

An agent that only chats has one move. Give it tools and it can retrieve, calculate, transform, and act. Each capability has a job, and reaching for the wrong one is how agents end up claiming work they never did.

Component What it is for Example
Knowledge Supply information for an answer Find a rule in an approved policy
Topic Control a scripted conversation path Ask for a missing request number
Connector Invoke one operation on a service Create or read a record
Custom prompt Interpret or transform supplied content Normalize a messy request
Code interpreter Calculate or analyze values with Python Total and average a column
Agent flow Coordinate validation, actions, and results Submit a validated request

Use the smallest tool that fits the operation. Choose a prompt to reshape text, a connector for one service operation, and a flow when several steps must be coordinated. Generated text does not establish that an external action occurred. If an agent must create, update, send, or delete something, it may report success only after the responsible connector or flow confirms the result.

A realistic request often combines several tools. A custom prompt normalizes messy input, a topic collects missing values, and a flow validates the completed request before calling the service. The topic should display only the result that the flow confirms. Everything before that confirmation is preparation.

A sentence is not a receipt

The most common agent failure is an answer that says "Done, I've submitted it" when nothing was submitted. Require the tool's confirmed result and identifier before you show success. Without that confirmation, the agent has not earned the word "done."

Custom prompts need hard source boundaries

A custom prompt is a reusable instruction that takes supplied content and returns a constrained response. Build it from four elements you already know from prompting fundamentals: goal, context, source, and expectations. Make the expectations strict. Fixed headings, a hard word limit, an explicit source boundary, and a rule for missing information turn a vague "summarize this ticket" into something you can verify. The rule that pays for itself is the missing-value policy: tell the prompt to write "Not provided" under any heading the source doesn't fill, so a gap shows up as a gap instead of a plausible invention.

Some jobs aren't text at all. They're arithmetic. When a prompt must total, average, or compare numbers, use its code interpreter, which runs Python instead of estimating. But calculation has its own footgun: bad input. Define the invalid-value policy before you calculate. A missing or nonnumeric value should produce a validation error that names the offending line and performs no calculations. Never a total that treated a blank as zero. Code interpreter proves the math. It doesn't prove a business record exists.

A custom prompt that refuses to invent· copilot-studio
Bad example

Summarize this support ticket for the supervisor.

Good example

Goal: Summarize the support ticket for an internal support supervisor. Context: The supervisor needs a neutral summary before assigning the ticket. Source: Use only ticketText. Do not invent a customer name, deadline, severity, diagnosis, owner, or resolution. Expectations: Return exactly these headings: Issue, Customer impact, Requested action, Missing information. Use no more than 80 words. If information for a heading is absent, write "Not provided." Do not claim the issue is resolved.

Why this works: A four-heading summary under 80 words where every line traces to the ticket and any gap reads "Not provided" rather than an invented cause or owner.

Validate before you calculate· copilot-studio
Bad example

Calculate the total, average, highest, and lowest monthly service volumes.

Good example

Goal: Validate and calculate service-volume statistics from monthlyValues. Source: Use only the lines in monthlyValues, each formatted "Month: number." Expectations: Validate every line first. If any value is missing or nonnumeric, do not calculate anything: return the heading "Validation error," list each invalid month and its value, and state "No calculations were performed." Only when every value is valid, use Python to return total volume, average (two decimals), and the highest and lowest months. Do not estimate missing values or treat invalid values as zero.

Why this works: Clean numbers produce a small stats table. A single bad line produces only a validation error naming it, never a total built on guessed or zeroed data.

Trustworthy flows report real outcomes

An agent flow is a workflow the agent calls as a tool. Treat its interface as a contract: named inputs, validation and other actions, named outputs, and clear failure behavior. The outputs should distinguish the terminal paths, such as submitted, invalid input, and not submitted. The topic that calls the flow shouldn't have to infer which path occurred.

When required values are missing, return the names of all empty inputs together. The topic can then ask for those values and call the flow again. Return success only when the operation's documented result confirms it and includes an identifier. If the destination supplies no identifier, report "not submitted." An example identifier is never a substitute for the value returned by the system.

Test each terminal path while the flow still stands alone: one missing input, several missing inputs, a simulated success, and a simulated failure. Once the flow sits behind a polished topic, basic faults are harder to see.

Test the flow before the topic

Exercise every terminal path: missing input, multiple missing inputs, success, failure, while the flow stands alone. Attaching an untested flow to a topic hides its bugs behind a nicer conversation.

A prompt that normalizes without inventing· copilot-studio
Bad example

Turn requestText into a clean equipment request.

Good example

Use only requestText. Return exactly this format: Requested item: <value or Not provided> Quantity: <whole number or Not provided> Business reason: <value or Not provided> Missing information: <comma-separated fields or Not provided> Do not invent a requester, quantity, priority, delivery date, item, or reason. For "Missing information," consider only Requested item, Quantity, and Business reason, and list whichever are absent.

Why this works: A clean four-line record where absent fields say "Not provided" and "Missing information" names exactly the missing ones, ready for a topic to collect what is missing and re-run.

Adaptive Cards need an honest data path

An Adaptive Card presents related values under stable labels, which is easier to scan than a paragraph. The way to build one you can trust is to keep three layers separate. Data supplies source values and transforms them into display-ready ones. Presentation decides the title, labels, order, and which variable each field binds to. Behavior handles interaction after rendering, like a submit action. Build and verify them in that order, and keep display rules from rewriting source values: preserve the original record and create separate display variables for transformed values.

That separation is what makes failures diagnosable. Suppose your transform correctly turns a status of "Resolved" into "Closed," but the card still shows "Resolved." Because the correct value reached the presentation boundary but failed to render, the evidence points to presentation. The visible field probably still uses the raw status variable. Point it at the display variable while leaving the correct data unchanged. If the display variable itself contained "Resolved," the evidence would point to the data layer. Inspect which layer holds the wrong value before you change anything.

One more honesty rule: a card previews a planned route or a current state. It cannot prove that an action behind it occurred. And the text you sketch on paper is an assessable representation of the card's content. You cannot paste it into a message and expect it to render as a card.

Try it yourself

Build a card, then break it on purpose

Turn three source records into display values, render the cards, then plant a binding fault and diagnose the layer. Ten minutes on paper.

  1. 01

    Take three equipment-request records: E1 status "Pending approval," no approver. E2 status "Approved," approver Taylor Kim. E3 status "In review," approver Taylor Kim.

  2. 02

    Apply the transform: replace "Pending approval" with "Awaiting approval" and keep other statuses. Replace a missing approver with "Not assigned" and keep a present one.

  3. 03

    Fill a transformation sheet, then render each card by copying the display values under fixed labels: Employee, Equipment, Status, Needed by, Approver.

  4. 04

    Now bind the visible status field to the raw source status for E1 and re-render. You should see "Pending approval" instead of "Awaiting approval."

    Hint: The transform is still correct. Only the render changed.

  5. 05

    Diagnose: because the transformed value is right but the render is wrong, the failure is in the presentation binding. Restore the display-variable binding and re-render.

Three correct cards, one deliberately faulted card traced to the presentation layer, and the fix verified: the habit of diagnosing from evidence before changing a rule.

Before moving to Autonomous Agents, Testing, and Publishing, take one flow you've built and locate the status and identifier returned by its final action. If either is missing, record the action as unconfirmed and fix the output contract before the agent runs unattended.

Key takeaways

  • Match the tool to the job: prompts interpret and transform, code interpreter calculates, connectors call one service, agent flows coordinate and return explicit results.
  • Generated text is never proof of an external action. Report success only when a connector or flow confirms it with an identifier.
  • A trustworthy custom prompt fixes its output format, bans invented facts, and prints "Not provided" for anything missing.
  • A trustworthy flow validates first, returns the names of every missing input, and has a failure status distinct from success.
  • Separate an Adaptive Card's data, presentation, and behavior layers, and diagnose a wrong field from the layer that holds the wrong value.

Check your understanding

  1. 1. An assistant must first turn free text into a fixed four-line summary, then validate required fields, call an approved service, and return an explicit success or failure. Which component does which job?

  2. 2. A transform correctly produces a display status of "Closed," but the rendered card shows "Resolved." Which layer failed, and what do you inspect first?

  3. 3. Your agent replies "Done, I've submitted your request." What does that sentence prove about the record?

  4. 4. A calculation prompt receives one nonnumeric value among the monthly figures. What is the correct behavior?

  5. 5. A flow is missing two required inputs. What should it return so the topic can recover cleanly?

Frequently asked questions

Terms used in this lesson

tool
A callable capability (connector, custom prompt, code interpreter, or agent flow) that lets an agent do more than compose a reply.
custom prompt
A reusable instruction that receives supplied content and returns a constrained, formatted response.
code interpreter
A Python capability inside a prompt for calculating or analyzing supplied values instead of estimating them.
agent flow
A workflow an agent or topic calls, with named inputs, actions, outputs, and explicit failure behavior.
Adaptive Card
A structured response that presents related values under stable labels and positions, built from data, presentation, and behavior layers.

Further reading