Orchestrating AI Workflows with Microsoft Agent Framework 1.0

AI agents are often introduced as conversational features: provide a prompt, call a model, invoke a tool, and return an answer. That framing is useful for a demo, but it is too small for a production system.

Real business processes have boundaries. A support agent may need to identify a customer, retrieve orders, classify urgency, propose a resolution, request approval for a refund, and record an auditable outcome. A document-processing agent may need to extract data, validate it against internal rules, route exceptions to a person, and retry only the failed stage.

Microsoft Agent Framework 1.0 is compelling in .NET because it treats agents as part of an application architecture rather than as a single intelligent function. The model call still matters, but the durable value comes from composition: agents, tools, workflow steps, state, observability, and human decision points working together.

This post explores how to think about the framework as an orchestration layer for practical .NET systems.

Start with a workflow, not a persona

The first design mistake in agent projects is creating a broadly capable assistant before defining the work it is allowed to perform. A prompt such as “You are a helpful operations expert” creates an impressive surface area and an alarming amount of ambiguity.

Instead, begin with a workflow map:

  1. What event starts the process?
  2. What data is trusted input versus model-generated interpretation?
  3. Which actions can change external state?
  4. Which decisions need deterministic validation?
  5. When must a person approve, correct, or stop execution?
  6. What information must be retained for audit and replay?

For example, consider an internal invoice exception process. The workflow may be:

  • Receive an invoice and its extraction result.
  • Ask an analysis agent to explain mismatches.
  • Query approved purchase orders through a constrained tool.
  • Apply deterministic finance rules.
  • Route high-value or low-confidence cases to an approver.
  • Persist the final decision and notify the accounts-payable system.

Only one of those stages requires generative reasoning. The remaining stages are conventional software engineering concerns. Agent Framework becomes useful because it gives the generative stage a disciplined place in the larger process.

Agents should own reasoning; tools should own effects

An effective boundary is simple: an agent can reason about what should happen, but a tool is responsible for what actually happens.

A tool should have a narrow contract, validate its input, enforce authorization, and produce a structured result. It should not accept an unconstrained instruction such as RunDatabaseQuery("find suspicious invoices"). That asks the model to construct a potentially dangerous implementation detail.

Prefer business-level operations:

csharp

The agent can decide whether a purchase-order lookup is relevant. The application decides how the lookup is performed, which tenant is accessible, how timeouts work, and which fields can be exposed.

This distinction is especially important when tools call REST APIs, SQL databases, queues, or payment systems. Tool descriptions are not a security boundary. They help the model choose capabilities, but the implementation must independently enforce identity, authorization, validation, rate limits, and idempotency.

For side-effecting operations, add an explicit command model:

csharp

A refund tool should reject amounts above its delegated limit, reject unknown orders, and require a valid workflow or approval context. The model should never be the final authority for a financial action.

Use structured outputs as the handoff contract

Natural-language output is excellent for explanations and poor for system integration. If a downstream workflow branch depends on an agent’s conclusion, request a typed result rather than parsing prose with regular expressions.

A useful analysis result might look like this:

csharp

The important detail is that this schema is not merely a convenience for deserialization. It is the contract between probabilistic reasoning and deterministic orchestration.

After receiving the assessment, validate it as if it came from an untrusted API client:

  • Require Classification to be one of a known set of values.
  • Ensure confidence is within 0 and 1.
  • Limit evidence length and text size.
  • Check that the selected action is valid for the current workflow state.
  • Ignore any fields the model was not supposed to produce.

Then make routing decisions in code. A workflow should not depend on the model writing the phrase “please escalate this case.” It should branch on a validated RequiresHumanReview flag, a confidence threshold, or a policy outcome.

Compose specialist agents instead of building one super-agent

A single agent with every tool available is tempting because it reduces initial configuration. It also increases prompt complexity, tool-selection errors, and security exposure.

Specialist agents create clearer operational boundaries. In an invoice workflow, those roles could include:

  • Triage agent: classifies the exception and identifies missing evidence.
  • Research agent: retrieves purchase-order and vendor context through read-only tools.
  • Resolution agent: proposes a next action from approved resolution options.
  • Communication agent: drafts an internal explanation or supplier message.

These agents do not need separate personalities. They need separate responsibilities, instructions, and tool sets.

Agent Framework workflows are a natural place to connect them. The triage agent produces a typed assessment; a deterministic step chooses whether research is necessary; the resolution agent receives only the verified context it needs. This is less theatrical than agents “debating” each other, but it is easier to test and considerably easier to operate.

A good rule is to introduce another agent only when it changes one of three things: the available tools, the context boundary, or the evaluation criteria. Otherwise, a regular C# method or workflow step is probably the better abstraction.

Treat state as a product requirement

A production agent process rarely completes in one request. It may wait for an approver, survive a deployment, retry after a dependency failure, or resume when a message arrives from another system.

That means state must be intentional. Separate it into at least three categories:

  1. Workflow state: current step, branch decisions, retry counts, correlation IDs, and approval status.
  2. Business state: invoices, customers, orders, and decisions stored in the system of record.
  3. Conversation or reasoning context: the selected messages, documents, summaries, and tool outputs provided to a model.

Do not confuse the third category with durable business truth. Model context is curated working memory, not a database.

When an execution is long-running, persist enough workflow state to resume safely. Include idempotency keys around external writes, particularly when a retry may occur after a timeout. A timeout does not prove that an external API did not complete the operation.

For example, a workflow can persist RefundRequested before calling a payment API, attach an idempotency key, and later reconcile the result. This design is more valuable than asking an agent to “remember whether it already issued the refund.”

Build observability into every execution

Agent systems need the telemetry discipline of distributed systems plus the evaluation discipline of machine-learning systems.

At minimum, capture:

  • Workflow execution ID and business correlation ID.
  • Agent and workflow step names.
  • Model provider, deployment, and model version.
  • Latency for model calls and tool calls.
  • Token usage and estimated cost.
  • Tool inputs and outputs, with secrets and personal data redacted.
  • Routing decisions, retries, failures, and approval outcomes.
  • Prompt and schema version identifiers.

Use .NET logging, metrics, and tracing conventions so an agent execution can be correlated with the API request, queue message, database activity, and downstream service calls that surrounded it. OpenTelemetry traces are especially useful when a workflow crosses multiple services.

However, observability should not become indiscriminate transcript storage. Prompts and tool results can contain customer data, credentials, contracts, or sensitive internal material. Define retention policies, redact aggressively, and control who can inspect traces.

Evaluation is the release gate

Traditional unit tests remain essential: tool validation, authorization, state transitions, retry behavior, and branch logic should all be tested deterministically.

Agent behavior needs another layer. Build a versioned evaluation set from representative cases:

  • Routine cases with clear expected outcomes.
  • Ambiguous cases that should request clarification.
  • Prompt-injection attempts embedded in documents or tool results.
  • Cases requiring escalation.
  • Invalid or incomplete upstream data.
  • High-impact cases where the agent must not take action.

Evaluate more than answer quality. Measure valid structured output, correct routing, tool-call accuracy, grounded evidence, latency, cost, and unsafe-action rate. Run this suite whenever prompts, models, tools, schemas, or workflow logic change.

The central lesson of Microsoft Agent Framework 1.0 is that an agent is not the application. It is a bounded reasoning component inside an application. When agents are paired with typed contracts, narrow tools, persistent workflow state, deterministic policy checks, and strong telemetry, they become much more than chat interfaces. They become reliable participants in real .NET business processes.

Comments (0)

No comments yet. Be the first to share your thoughts!

Orchestrating AI Workflows with Microsoft Agent Framework 1.0