# Microsoft Agent Framework — Workflow Orchestration

> **Scope:** stacks=["dotnet"]
> **Layer:** 1 (on-keyword)
> **Keywords:** workflow, orchestration, fan-in, fan-out, multi-agent workflow, sequential workflow
> **Read by Claude in:** plan (only when a genuine fan-in/out or long-running need appears)

**Verified against:** Microsoft.Agents.AI 1.20.0 (ai-pin 2026-09-08) + Microsoft.Agents.AI.Workflows 1.20.0, Microsoft.Agents.AI.Workflows.Declarative 1.20.0 e Microsoft.Agents.AI.Declarative `1.20.0-rc1` (**os três fora do pin**; versões apuradas no nuget.org em 2026-09-08). **Verificação documental**, sem cláusula `provado por` — o ai-kit não monta workflows. **A localização dos tipos de workflow foi medida por reflexão em 2026-09-08 e CORRIGE este standard**: eles não estão no pacote base. Last-verified: 2026-09-08.

---

## Quando NÃO usar um Workflow

Leia `ai-agents-sweet-spot` antes de continuar. A regra:

> "Tudo que Workflows fazem, código C# normal faz com menos complexidade."
> — pesquisa sweet-spot (2026-05-18)

Checklist de desqualificação — se qualquer item for verdadeiro, **não use Workflow**:

- [ ] A feature tem **um tópico + uma decisão** → single agent com tools resolve
- [ ] O fan-in pode ser escrito como `foreach` + `LINQ Aggregate` sobre os resultados → escreva o `foreach`
- [ ] Você quer "dividir responsabilidade" entre 2 agents → use **Agent-as-Tool** (ver `ai-agents-multi-agent-patterns` — Onda 2)
- [ ] O workflow seria Sequential de 2 etapas → é só `await agent.RunAsync(await step1.RunAsync(input))`

Workflows adicionam: classes extras, configuração de edges, streaming de eventos, coordenação de supersteps. Adicione esse custo somente quando os critérios abaixo se aplicarem.

---

## Quando um Workflow É justificado

| Critério | Exemplo realista |
|----------|------------------|
| **Fan-in genuíno sobre N inputs** | Relatório mensal que agrega análises de N documentos em paralelo |
| **Fan-out para > 2 agents especializados independentes** | Code review: security + perf + readability ao mesmo tempo |
| **Long-running com human-in-the-loop (HITL)** | Fluxo de aprovação onde um humano intervém entre etapas |

Se sua feature não se encaixa nesses critérios, volte ao single agent.

Para o critério de HITL/long-running acima, a implementação (`RequestPort`, `CheckpointManager`, resume após restart) está em `ai-agents-durable-workflows-hitl` — leia esse standard antes de escrever o código de aprovação humana ou de checkpoint.

---

## Packages

> **Correção de 2026-09-08, medida.** A versão anterior deste standard dizia que `AgentWorkflowBuilder`, `WorkflowBuilder` e `InProcessExecution` estavam no pacote base `Microsoft.Agents.AI`. **Não estão.** Varredura dos tipos exportados de `Microsoft.Agents.AI` 1.20.0: **zero** tipos de workflow. Todos os 132 tipos de workflow — `AgentWorkflowBuilder`, `WorkflowBuilder`, `InProcessExecution`, `HandoffWorkflowBuilder`, `GroupChatWorkflowBuilder`, `MagenticWorkflowBuilder`, `CheckpointManager` — vivem em **`Microsoft.Agents.AI.Workflows`**, um pacote **separado**. Seguir o texto antigo dá erro de compilação, não aviso.

```xml
<!-- Base MAF — no ai-pin.json -->
<PackageReference Include="Microsoft.Agents.AI" Version="1.20.0" />

<!-- Workflows: PACOTE SEPARADO. Estável. Fora do pin; apurado no nuget.org em 2026-09-08. -->
<PackageReference Include="Microsoft.Agents.AI.Workflows" Version="1.20.0" />
```

Para DI helpers (`AddAIAgent`, `AddSequentialWorkflow`):

```xml
<!-- PRERELEASE: não há versão estável. Fora do pin; apurado em 2026-09-08. -->
<PackageReference Include="Microsoft.Agents.AI.Hosting" Version="1.20.0-preview.260831.1" />
```

### Declarativo: workflow é estável, agente ainda não

Os dois costumam ser citados juntos e têm maturidade **diferente**. Apurado no nuget.org em 2026-09-08:

| Pacote | Última versão | Estável? |
|---|---|---|
| `Microsoft.Agents.AI.Workflows.Declarative` (workflows em YAML) | **1.20.0** | **Sim** — estáveis desde a 1.9 |
| `Microsoft.Agents.AI.Declarative` (agentes declarativos) | `1.20.0-rc1` | **Não** — ainda exige `--prerelease` |

Ou seja: descrever o **grafo** em YAML é caminho estável; descrever o **agente** em YAML ainda não.

### Mudança de comportamento na 1.17

A partir da **1.17**, um workflow **falha quando um agente participante retorna erro** — antes o erro podia ser absorvido e o grafo seguia com um resultado parcial. Consequência: um workflow que "sempre funcionou" pode passar a falhar depois do upgrade, e isso é o comportamento **correto**. Trate erro de agente explicitamente (branch de erro no grafo, ou tratamento dentro do executor) em vez de contar com a absorção antiga.

> Sem `Microsoft.Extensions.AI 9.x`. Nenhuma faixa flutuante — SDK de cadência semanal com `1.0.*` é o defeito que `ai-agents-setup` §1 proíbe.

---

## Exemplo canônico — Fan-In Concurrent

Caso realista: analisar o mesmo documento com 3 agents especializados em paralelo, depois agregar.

```
[Input] ──┬→ [SecurityAnalyst]  ──┐
          ├→ [PerfAnalyst]       ──┤→ [Aggregator]
          └→ [QualityAnalyst]   ──┘
```

```csharp
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Extensions.AI;

// --- 1. Agents (via Model Registry — nunca hardcode o modelo) ---
IChatClient chatClient = _modelRegistry.GetChatClient("text-default");

AIAgent securityAnalyst = chatClient.AsAIAgent(
    instructions: "Analyze code for security vulnerabilities. Be concise.",
    name: "SecurityAnalyst");

AIAgent perfAnalyst = chatClient.AsAIAgent(
    instructions: "Analyze code for performance bottlenecks. Be concise.",
    name: "PerfAnalyst");

AIAgent qualityAnalyst = chatClient.AsAIAgent(
    instructions: "Analyze code for readability and maintainability. Be concise.",
    name: "QualityAnalyst");

AIAgent aggregator = chatClient.AsAIAgent(
    instructions: "You receive multiple analysis reports. Produce a unified summary with key findings.",
    name: "Aggregator");

// --- 2. Build fan-out / fan-in workflow ---
WorkflowBuilder builder = new(securityAnalyst);
builder.AddEdge(securityAnalyst, aggregator);

builder.AddInputEdge(perfAnalyst);          // also receives the original input
builder.AddEdge(perfAnalyst, aggregator);

builder.AddInputEdge(qualityAnalyst);
builder.AddEdge(qualityAnalyst, aggregator);

builder.WithOutputFrom(aggregator);
Workflow workflow = builder.Build();

// --- 3. Run with streaming events ---
string codeSnippet = /* input from request */;
await using StreamingRun run =
    await InProcessExecution.RunStreamingAsync(workflow, codeSnippet);

await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
    switch (evt)
    {
        case AgentResponseUpdateEvent update:
            Console.WriteLine($"[{update.Update.AuthorName}] {update.Update.Text}");
            break;
        case WorkflowErrorEvent error:
            Console.Error.WriteLine($"Workflow error: {error.Exception?.Message}");
            break;
    }
}
```

**Key points:**
- `AddInputEdge(agent)` — agent recebe o input original (fan-out)
- `AddEdge(from, to)` — conecta um executor ao próximo
- `WithOutputFrom(aggregator)` — define quem produz o output final
- O Aggregator só executa após todos os analysts completarem (superstep boundary)
- Agents criados via Model Registry alias — não hardcode modelo ou provider

---

## Outros padrões — tabela de referência rápida

Use esta tabela para decidir qual padrão pesquisar. Não escreva código de todos aqui.

| Padrão | Topologia | Quando usar |
|--------|-----------|-------------|
| **Sequential** | Cadeia linear | Pipeline simples onde cada etapa depende da anterior. Muitas vezes substituível por chamadas encadeadas. |
| **Handoff** | Mesh dinâmico | Roteamento dinâmico — agents passam controle conforme o contexto. Ver `ai-agents-multi-agent-patterns` (Onda 2). |
| **GroupChat** | Estrela (manager) | Refinamento iterativo entre agents com rodadas fixas. `AgentWorkflowBuilder.CreateGroupChatBuilderWith(...)`. |
| **Magentic** | Estrela (planner LLM) | Variante de GroupChat onde o manager é um LLM que decide dinamicamente quem age. |
| **Agent-as-Tool** | Ferramental | **Não é um Workflow** — o agent chama outro como tool via `AIFunctionFactory`. Opção mais simples; cobre 80% dos casos multi-agent. Ver `ai-agents-multi-agent-patterns` (Onda 2). |

Para Sequential simples, `AgentWorkflowBuilder.BuildSequential(agent1, agent2)` é suficiente.
Para Handoff, `AgentWorkflowBuilder.CreateHandoffBuilderWith(entryAgent)` + `.WithHandoffs(...)`.

---

## Executando um Workflow (resumo da API)

| Método | Retorno | Quando usar |
|--------|---------|-------------|
| `InProcessExecution.RunStreamingAsync(workflow, input)` | `StreamingRun` | Input conhecido de antemão, streama eventos |
| `InProcessExecution.OpenStreamingAsync(workflow)` | `StreamingRun` | Input enviado depois via `TrySendMessageAsync` (ex: chat interativo) |
| `InProcessExecution.RunAsync(workflow, input)` | `Run` | Sem streaming, acumula todos os eventos |

Sempre use `await using` no `StreamingRun` / `Run` — é `IAsyncDisposable`.

---

## Checklist (verifiable by morph-eval)

- [ ] Foi verificado que um `foreach` ou single agent não resolve o problema?
- [ ] O critério de fan-in/out genuíno ou HITL está documentado em `decisions.md`?
- [ ] `Microsoft.Agents.AI` 1.0.* presente no `.csproj` (sem pacotes preview separados)?
- [ ] Agents referenciando alias do Model Registry (não model strings hardcoded)?
- [ ] `await using` no `StreamingRun` / `Run`?
- [ ] `WorkflowErrorEvent` tratado no loop de eventos?
- [ ] OpenTelemetry habilitado para rastrear chamadas inter-agent?

---

## References

- `ai-agents-setup` — pacotes, `ChatClientAgent`, tools
- `ai-agents-sweet-spot` — decisão single agent vs workflow
- `ai-agents-multi-agent-patterns` (Onda 2) — Agent-as-Tool, Handoff patterns
- `ai-agents-providers-model-registry` — Model Registry para alias de provider
- `ai-agents-durable-workflows-hitl` — `RequestPort`, `CheckpointManager`, resume após restart
- MAF Workflows docs: https://learn.microsoft.com/agent-framework/
- MAF Workflow samples: https://github.com/microsoft/agent-framework/tree/main/dotnet/samples/03-workflows

---

*MORPH-SPEC by Polymorphism Tech — ai-agents/workflows.md v2.0 (2026-09-08)*
