Skip to lesson

MicrosoftMicrosoft Certified: Multi-Agent AI Solutions Expert2026-104.2 Design and implement guardrails for multi-agent solutions

Turn domain rules into enforced verdicts

Completed by the knowledge check

Learning objective

Build custom guardrails for domain rules, escalation thresholds, and exception handling.

Core idea

A custom guardrail translates a domain rule into an executable decision at the point where it matters. “Follow the refund policy” is an instruction. Checking the proposed refund against an authoritative balance and returning a blocking verdict is enforcement. The model can propose a result; trusted application code decides whether that proposal is permitted.

Separate the rule from its integration. A rule takes a candidate and trusted facts and returns an explicit outcome. The integration applies that outcome before the guarded operation proceeds. This separation lets you test the same policy against specialist outputs, final responses, and tool proposals without embedding different policy interpretations in each agent’s prompt.

In Foundry, a custom guardrail is a configured risk/action policy assigned to an agent; see 4.2.1. Here, a custom guardrail means application code enforcing a domain rule.

See 4.2.5 for output acceptance and 4.2.3 for tool authorization. This lesson focuses on custom decisions, escalation, and exception handling. Failure-mode selection belongs to 4.2.7.

How it works

Define the rule’s inputs and outcomes

Begin with authoritative inputs: the acting principal, tenant, resource, candidate identifier, policy version, and relevant business state. Distinguish a model-proposed amount from a balance read from the account system. Missing required facts should produce an explicit unresolved result, not a permissive default such as a zero balance or an unrestricted limit.

Define decision cases that the application can implement. For example, a company policy might permit refunds up to the unused balance, require supervisor approval above a company-selected amount, and prohibit refunds for an ineligible purchase. These thresholds are organization policy, not Microsoft product limits. Include the comparison operator, currency, rounding rule, and policy version so a threshold has the same meaning in every agent.

A useful application decision record contains the rule identifier, verdict, reason, candidate identifier, and trusted state version. Those are application-defined fields. Do not present them as reserved Microsoft API fields. They give the caller enough information to route a denial or escalation without returning the sensitive source record.

Attach the decision to an enforcement surface

Use agent and function middleware for custom rules outside the Python Agent Hooks contract; see 2.4.15 for the layers. Python middleware can set context.result and raise MiddlewareTermination to stop the normal execution path. In .NET function middleware, FunctionInvocationContext.Terminate = true stops the function-calling loop from sending results back to inference after invocation; it does not undo the invoked function. Enforce a pre-action rule before calling that function. Go provides the run-level agent.Middleware interface, registered through agent.Config.Middlewares. Ordinary middleware requires you to implement the enforcement behavior; it does not inherit Agent Hooks’ coordinated streaming and persistence guarantees.

Python Agent Framework supports Agent Hooks through create_agent_hooks_middleware(). The capability is experimental and the factory emits ExperimentalWarning; .NET and Go do not implement it. An interceptor receives agent_hooks.AgentContext and returns a verdict. This context differs from agent_framework.AgentContext, which is used by ordinary agent middleware.

Choose the interception point by the guarded operation. input covers incoming requests; pre_model_call covers messages sent to the model; post_model_call covers completed model responses; pre_tool_call covers framework-executed tool arguments; post_tool_call covers tool results; output covers the final response. Use the narrowest point that receives the required facts before the consequence occurs.

Agent Hooks does not intercept provider-hosted tools at the framework’s function-invocation seam. Their calls and outputs appear at post_model_call, but pre_tool_call cannot prevent their server-side execution. If a domain rule must authorize a write before it happens, enforce it in a controllable execution path or the downstream service; an after-the-fact result check is insufficient.

Install one intact bundle on each guarded Agent, first in its middleware list. Microsoft rejects stacked bundles and documents that middleware placed before the bundle sits outside its enforcement coverage. Give nested agents their own bundle when their internal model and tool activity also requires interception.

Return a precise verdict

Agent Hooks exposes ALLOW, Verdict.deny(...), Verdict.warn(...), and Verdict.escalate(...). A warning permits execution and adds a record; it is not a denial. A transform uses Decision.TRANSFORM and Transform(...) to rewrite the guarded value, and the framework writes that value back into execution.

Use mode="enforce" when decisions must change behavior. In mode="evaluate_only", every action continues and transforms are not applied. That mode can measure how a proposed rule behaves, but cannot satisfy an enforcing policy requirement.

A denial at a run or model point raises InterceptionBlocked. At a tool point, a policy denial blocks the tool action or discards its result and returns a control error with the reason, without the denied payload, to the model. The loop can continue. This distinction matters when a denied action should lead to a harmless alternative rather than be confused with an infrastructure failure.

Escalate only an eligible exception

Verdict.escalate(...) represents a liftable denial. The resolver configured on create_agent_hooks_middleware() connects it to an approval channel; without a resolver, the denial remains effective. Reserve escalation for rules that explicitly allow an authorized reviewer to permit the request. Do not make an absolute prohibition overridable merely because an approval service exists.

Bind the approval request to the actual candidate and trusted facts. If the amount, destination, or policy changes while approval is pending, require a fresh decision. An approver’s permit for one proposal does not authorize every proposal in the session. See 2.4.6 for durable workflow approval and resumption.

Agent Hooks’ default composition is sequential first_deny, with approval configured to stop the fold. Put controls that must always run before controls that can request approval. Otherwise, an early escalation can prevent a later mandatory check from executing. Decide how several rule results combine instead of assuming every registered rule always runs.

Keep operational exceptions visible

A rule denial means the policy was evaluated and rejected the operation. An interceptor exception means it could not complete that evaluation. Agent Hooks fails closed on interceptor and enforcement failures. See 4.2.7 for the timeout setting and the availability consequences of failed evaluation.

Function middleware normally converts an ordinary exception into a tool-error result so the model loop can continue. If safe continuation is impossible, raise MiddlewareFailure from agent_framework and preserve it through outer middleware. Catching it and continuing changes the intended failure behavior; see 2.4.15.

Use record_sink for InterceptionRecord audit evidence. The records contain verdict, reason, mode, identity, and sequence without copying the intercepted payload. Interceptors still receive the content needed to decide, so register trusted code and minimize what your own diagnostics retain.

Key distinctions and trade-offs

Custom rules and built-in safety controls solve different problems. A general content classifier does not know a customer’s refund eligibility. A deterministic business check does not classify every harmful phrase. Compose them, and keep their reasons distinguishable.

Deterministic comparisons are suitable for exact domain limits. Semantic judgments need calibration and explicit uncertainty handling. A model’s self-reported confidence is not an authoritative eligibility value. Additional remote policy calls also add dependencies; decide what happens when trusted facts cannot be retrieved rather than letting a timeout choose policy accidentally.

Architecture / decision scenario

An expense agent proposes reimbursement. Company policy permits an eligible receipt up to its verified amount, requires manager approval above a company-defined threshold, and prohibits a duplicate reimbursement. A rule evaluator checks the receipt identifier against authoritative payment records before returning a verdict.

A duplicate receives Verdict.deny(...); a permitted high-value proposal receives Verdict.escalate(...) through the configured resolver. If the payment-records lookup fails or times out, the evaluator reports an operational exception rather than inferring that the receipt was not paid. Mandatory duplicate and eligibility checks run before the escalation rule under first_deny composition.

The tool-stage check prevents an unauthorized payment proposal from executing through the framework. The output-stage check prevents the final writer from falsely claiming that an unapproved reimbursement completed. The audit record distinguishes rejection, pending approval, approval, and failed evaluation so support can explain the outcome without exposing the receipt content.

Common exam traps

  • Treating a domain instruction as an executable policy check.
  • Using Verdict.warn(...) when the action must stop.
  • Treating evaluate_only as enforced governance.
  • Assuming a resolver can override every denial.
  • Catching MiddlewareFailure and continuing the model loop.
  • Expecting framework hooks to block provider-hosted tool execution.

What to remember

Build custom guardrails from authoritative inputs, exact rule comparisons, and explicit verdicts. Place mandatory checks before escalation, bind approval to the actual proposal, and distinguish policy denials from evaluation failures. The enforcement surface must run before the consequence it is intended to control.

Knowledge check

References