@polymorphism-tech/morph-spec 6.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +367 -366
- package/docs/CHEATSHEET.md +3 -3
- package/docs/QUICKSTART.md +4 -4
- package/framework/CLAUDE.md +13 -0
- package/framework/MORPH.md +57 -36
- package/framework/agents.json +132 -127
- package/framework/commands/morph-apply.md +4 -21
- package/framework/commands/morph-archive.md +1 -1
- package/framework/commands/morph-proposal.md +2 -0
- package/framework/hooks/claude-code/core/enforce-phase-writes.js +1 -1
- package/framework/hooks/claude-code/core/protect-spec-files.js +1 -1
- package/framework/hooks/claude-code/core/state-sync.js +212 -0
- package/framework/hooks/shared/phase-utils.js +5 -4
- package/framework/hooks/shared/state-reader.js +1 -1
- package/framework/phases.json +1 -1
- package/framework/rubrics/backend.json +41 -36
- package/framework/rules/ai-agents-standards.md +45 -15
- package/framework/rules/morph-workflow.md +15 -34
- package/framework/rules/neon-standards.md +25 -26
- package/framework/schemas/tasks.schema.json +35 -0
- package/framework/skills/core/morph-apply/SKILL.md +154 -0
- package/framework/skills/core/morph-brainstorming/SKILL.md +53 -30
- package/framework/skills/core/morph-implement/SKILL.md +25 -14
- package/framework/skills/core/morph-plan/SKILL.md +91 -23
- package/framework/skills/core/morph-proposal/SKILL.md +137 -0
- package/framework/skills/core/morph-review/SKILL.md +43 -7
- package/framework/skills/core/morph-stack-scan/SKILL.md +40 -1
- package/framework/standards/STANDARDS.json +1729 -1134
- package/framework/standards/ai-agents/agent-session.md +160 -0
- package/framework/standards/ai-agents/batching.md +193 -0
- package/framework/standards/ai-agents/context-providers.md +188 -0
- package/framework/standards/ai-agents/mcp-server.md +250 -0
- package/framework/standards/ai-agents/mcp-tools.md +197 -0
- package/framework/standards/ai-agents/middleware-patterns.md +207 -0
- package/framework/standards/ai-agents/modalities-image-gen.md +173 -0
- package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -0
- package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -0
- package/framework/standards/ai-agents/modalities-vision.md +201 -0
- package/framework/standards/ai-agents/multi-agent-patterns.md +155 -0
- package/framework/standards/ai-agents/production.md +114 -258
- package/framework/standards/ai-agents/prompts-in-db.md +214 -0
- package/framework/standards/ai-agents/providers/model-registry.md +158 -0
- package/framework/standards/ai-agents/rag-custom-pgvector.md +243 -0
- package/framework/standards/ai-agents/service-tier-flex.md +135 -0
- package/framework/standards/ai-agents/setup.md +142 -316
- package/framework/standards/ai-agents/structured-output.md +249 -0
- package/framework/standards/ai-agents/sweet-spot.md +109 -0
- package/framework/standards/ai-agents/workflows.md +114 -284
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +433 -429
- package/framework/standards/backend/api/validation.md +92 -88
- package/framework/standards/backend/database/postgresql/database.md +336 -332
- package/framework/standards/backend/database/vector-search-rag.md +599 -541
- package/framework/standards/backend/dotnet/fluent-validation-vsa.md +4 -0
- package/framework/standards/backend/dotnet/result-pattern.md +4 -0
- package/framework/standards/backend/dotnet/scalar-ui.md +176 -172
- package/framework/standards/backend/dotnet/scrutor.md +4 -0
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +278 -274
- package/framework/standards/backend/integrations/asaas/asaas-api.md +260 -216
- package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +354 -350
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +30 -19
- package/framework/standards/backend/integrations/resend/resend-email.md +400 -385
- package/framework/standards/data/nosql/cache/redis.md +106 -97
- package/framework/standards/data/nosql/cosmos-db.md +127 -118
- package/framework/standards/data/vector-search/rag-chunking.md +113 -104
- package/framework/standards/frontend/design-system/ai-image-generation.md +4 -0
- package/framework/standards/frontend/design-system/animations.md +164 -160
- package/framework/standards/frontend/design-system/naming.md +68 -64
- package/framework/standards/frontend/gsap/gsap-core.md +14 -8
- package/framework/standards/frontend/gsap/gsap-plugins.md +26 -21
- package/framework/standards/frontend/gsap/gsap-scrolltrigger.md +9 -7
- package/framework/standards/frontend/nextjs/app-router.md +127 -123
- package/framework/standards/frontend/nextjs/components.md +136 -132
- package/framework/standards/frontend/nextjs/data-fetching.md +130 -126
- package/framework/standards/frontend/nextjs/forms.md +134 -128
- package/framework/standards/frontend/nextjs/motion-patterns.md +328 -322
- package/framework/standards/frontend/nextjs/naming-conventions.md +71 -67
- package/framework/standards/frontend/nextjs/nextjs-patterns.md +229 -225
- package/framework/standards/frontend/nextjs/project-structure.md +106 -102
- package/framework/standards/frontend/nextjs/state-management.md +76 -72
- package/framework/standards/frontend/nextjs/testing.md +115 -111
- package/framework/standards/infrastructure/docker/easypanel-deploy.md +196 -192
- package/framework/standards/infrastructure/neon/neon-pgrag.md +6 -2
- package/framework/standards/infrastructure/neon/neon-pgvector.md +4 -0
- package/framework/standards/infrastructure/neon/neon-setup.md +5 -1
- package/framework/standards/integration/mcp/mcp-tools.md +471 -462
- package/framework/templates/REGISTRY.json +1745 -1239
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -0
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -0
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -0
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -0
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -0
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -0
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -0
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -0
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -0
- package/framework/templates/docs/onboarding.md +4 -4
- package/framework/templates/tasks.template.json +17 -0
- package/package.json +89 -83
- package/src/commands/project/init.js +16 -0
- package/src/commands/validation/validate-feature.js +1 -1
- package/src/core/paths/output-schema.js +6 -6
- package/src/core/state/state-manager.js +1 -1
- package/src/core/templates/template-registry.js +289 -256
- package/src/lib/detectors/design-system-detector.js +1 -1
- package/src/lib/generators/context-generator.js +516 -518
- package/src/lib/generators/scaffold-generator.js +23 -26
- package/src/lib/installers/memory-installer.js +138 -0
- package/src/lib/phase-chain/phase-validator.js +4 -4
- package/src/lib/risk-detector.js +80 -0
- package/src/lib/tasks/tasks-json-parser.js +185 -0
- package/src/scripts/setup-infra.js +25 -0
- package/src/utils/hooks-installer.js +59 -10
- package/framework/standards/infrastructure/neon/neon-semantic-kernel.md +0 -310
- package/framework/templates/integrations/semantic-kernel-neon.cs +0 -125
|
@@ -1,357 +1,187 @@
|
|
|
1
|
-
# Microsoft Agent Framework
|
|
1
|
+
# Microsoft Agent Framework — Workflow Orchestration
|
|
2
2
|
|
|
3
|
-
> **Scope:**
|
|
4
|
-
> **Layer:**
|
|
5
|
-
> **Keywords:** workflow, orchestration,
|
|
6
|
-
> **
|
|
3
|
+
> **Scope:** stacks=["dotnet"]
|
|
4
|
+
> **Layer:** 1 (on-keyword)
|
|
5
|
+
> **Keywords:** workflow, orchestration, fan-in, fan-out, multi-agent workflow, sequential workflow
|
|
6
|
+
> **Read by Claude in:** plan (only when a genuine fan-in/out or long-running need appears)
|
|
7
7
|
|
|
8
|
-
**
|
|
9
|
-
|
|
10
|
-
Workflows compose multiple agents and executors into coordinated pipelines using `AgentWorkflowBuilder`.
|
|
8
|
+
**Verified against:** MAF 1.0 GA. Last-verified: 2026-05-19.
|
|
11
9
|
|
|
12
10
|
---
|
|
13
11
|
|
|
14
|
-
##
|
|
15
|
-
|
|
16
|
-
| Concept | Description |
|
|
17
|
-
|---------|-------------|
|
|
18
|
-
| **Executor** | Base processing unit. Implements `IMessageHandler<T>`. Agents are executors. |
|
|
19
|
-
| **Edge** | Typed connection between executors defining message flow |
|
|
20
|
-
| **Workflow** | Composition of executors + edges forming a processing graph |
|
|
21
|
-
| **AIAgent** | Chat-based executor (most common type) |
|
|
22
|
-
|
|
23
|
-
### Packages
|
|
12
|
+
## Quando NÃO usar um Workflow
|
|
24
13
|
|
|
25
|
-
|
|
26
|
-
<!-- Microsoft.Extensions.AI — core abstractions -->
|
|
27
|
-
<PackageReference Include="Microsoft.Extensions.AI" Version="9.5.0" />
|
|
28
|
-
```
|
|
14
|
+
Leia `ai-agents-sweet-spot` antes de continuar. A regra:
|
|
29
15
|
|
|
30
|
-
>
|
|
31
|
-
>
|
|
32
|
-
> the expected GA surface. Until MAF ships, implement sequential/parallel workflows manually using `IChatClient`.
|
|
16
|
+
> "Tudo que Workflows fazem, código C# normal faz com menos complexidade."
|
|
17
|
+
> — pesquisa sweet-spot (2026-05-18)
|
|
33
18
|
|
|
34
|
-
|
|
19
|
+
Checklist de desqualificação — se qualquer item for verdadeiro, **não use Workflow**:
|
|
35
20
|
|
|
36
|
-
|
|
21
|
+
- [ ] A feature tem **um tópico + uma decisão** → single agent com tools resolve
|
|
22
|
+
- [ ] O fan-in pode ser escrito como `foreach` + `LINQ Aggregate` sobre os resultados → escreva o `foreach`
|
|
23
|
+
- [ ] Você quer "dividir responsabilidade" entre 2 agents → use **Agent-as-Tool** (ver `ai-agents-multi-agent-patterns` — Onda 2)
|
|
24
|
+
- [ ] O workflow seria Sequential de 2 etapas → é só `await agent.RunAsync(await step1.RunAsync(input))`
|
|
37
25
|
|
|
38
|
-
|
|
39
|
-
|---------|----------|----------|--------------|
|
|
40
|
-
| **Sequential** | Linear chain | Pipelines, multi-stage processing | Ordered, dependent |
|
|
41
|
-
| **Concurrent** | Broadcast | Parallel analysis, ensemble | Independent, aggregated |
|
|
42
|
-
| **GroupChat** | Star (manager hub) | Iterative refinement, review | Manager-controlled |
|
|
43
|
-
| **Handoff** | Mesh | Dynamic routing, escalation | Agent-decided |
|
|
44
|
-
| **Magentic** | Star (planner) | Complex generalist collaboration | Planner-based |
|
|
26
|
+
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.
|
|
45
27
|
|
|
46
28
|
---
|
|
47
29
|
|
|
48
|
-
##
|
|
49
|
-
|
|
50
|
-
Agents execute in order — each agent receives the output of the previous one.
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
[Writer] → [Editor] → [Output]
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
```csharp
|
|
57
|
-
using Microsoft.Extensions.AI;
|
|
58
|
-
|
|
59
|
-
AIAgent writer = new ChatClientAgent(chatClient, new ChatClientAgentOptions
|
|
60
|
-
{
|
|
61
|
-
Name = "Writer",
|
|
62
|
-
Instructions = "Write stories that are engaging and creative."
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
AIAgent editor = new ChatClientAgent(chatClient, new ChatClientAgentOptions
|
|
66
|
-
{
|
|
67
|
-
Name = "Editor",
|
|
68
|
-
Instructions = "Make the story more engaging, fix grammar, and enhance plot."
|
|
69
|
-
});
|
|
30
|
+
## Quando um Workflow É justificado
|
|
70
31
|
|
|
71
|
-
|
|
32
|
+
| Critério | Exemplo realista |
|
|
33
|
+
|----------|------------------|
|
|
34
|
+
| **Fan-in genuíno sobre N inputs** | Relatório mensal que agrega análises de N documentos em paralelo |
|
|
35
|
+
| **Fan-out para > 2 agents especializados independentes** | Code review: security + perf + readability ao mesmo tempo |
|
|
36
|
+
| **Long-running com human-in-the-loop (HITL)** | Fluxo de aprovação onde um humano intervém entre etapas |
|
|
72
37
|
|
|
73
|
-
|
|
74
|
-
AgentRunResponse response = await workflowAgent.RunAsync(
|
|
75
|
-
"Write a short story about a haunted house.");
|
|
76
|
-
|
|
77
|
-
Console.WriteLine(response.Text);
|
|
78
|
-
```
|
|
38
|
+
Se sua feature não se encaixa nesses critérios, volte ao single agent.
|
|
79
39
|
|
|
80
40
|
---
|
|
81
41
|
|
|
82
|
-
##
|
|
42
|
+
## Packages
|
|
83
43
|
|
|
84
|
-
|
|
44
|
+
Workflow APIs (`AgentWorkflowBuilder`, `WorkflowBuilder`, `InProcessExecution`) estão no pacote GA principal:
|
|
85
45
|
|
|
46
|
+
```xml
|
|
47
|
+
<PackageReference Include="Microsoft.Agents.AI" Version="1.0.*" />
|
|
86
48
|
```
|
|
87
|
-
┌→ [Agent B1] →┐
|
|
88
|
-
[Input] → Fan-Out → [Agent B2] → Fan-In → [Aggregator]
|
|
89
|
-
└→ [Agent B3] →┘
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
```csharp
|
|
93
|
-
// Create specialized analysis agents
|
|
94
|
-
AIAgent securityAnalyst = chatClient.AsAIAgent(
|
|
95
|
-
instructions: "Analyze code for security vulnerabilities.",
|
|
96
|
-
name: "SecurityAnalyst");
|
|
97
49
|
|
|
98
|
-
|
|
99
|
-
instructions: "Analyze code for performance issues.",
|
|
100
|
-
name: "PerformanceAnalyst");
|
|
50
|
+
Para DI helpers (`AddAIAgent`):
|
|
101
51
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
name: "ReadabilityAnalyst");
|
|
105
|
-
|
|
106
|
-
// Fan-out to all analysts, fan-in results
|
|
107
|
-
// Use AddFanOutEdge / AddFanInEdge for custom executors
|
|
52
|
+
```xml
|
|
53
|
+
<PackageReference Include="Microsoft.Agents.AI.Hosting" Version="1.0.*" />
|
|
108
54
|
```
|
|
109
55
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## 3. GroupChat Workflow
|
|
115
|
-
|
|
116
|
-
Manager-controlled round-robin conversation between agents.
|
|
117
|
-
|
|
118
|
-
```csharp
|
|
119
|
-
Workflow workflow = AgentWorkflowBuilder
|
|
120
|
-
.CreateGroupChatBuilderWith(agents =>
|
|
121
|
-
new AgentWorkflowBuilder.RoundRobinGroupChatManager(agents)
|
|
122
|
-
{
|
|
123
|
-
MaximumIterationCount = 2 // Max rounds
|
|
124
|
-
})
|
|
125
|
-
.AddParticipants(writer, editor)
|
|
126
|
-
.Build();
|
|
127
|
-
|
|
128
|
-
AIAgent workflowAgent = await workflow.AsAgentAsync();
|
|
129
|
-
AgentRunResponse response = await workflowAgent.RunAsync(prompt);
|
|
130
|
-
```
|
|
56
|
+
> Sem pacotes "preview" separados. Sem `Microsoft.Extensions.AI 9.x`. As APIs de Workflow são parte do `Microsoft.Agents.AI` 1.0 GA.
|
|
131
57
|
|
|
132
58
|
---
|
|
133
59
|
|
|
134
|
-
##
|
|
60
|
+
## Exemplo canônico — Fan-In Concurrent
|
|
135
61
|
|
|
136
|
-
|
|
62
|
+
Caso realista: analisar o mesmo documento com 3 agents especializados em paralelo, depois agregar.
|
|
137
63
|
|
|
138
64
|
```
|
|
139
|
-
[
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
```csharp
|
|
144
|
-
// Define specialized agents
|
|
145
|
-
ChatClientAgent historyTutor = new(chatClient,
|
|
146
|
-
"You provide help with historical queries. Only respond about history.",
|
|
147
|
-
"history_tutor",
|
|
148
|
-
"Specialist agent for historical questions");
|
|
149
|
-
|
|
150
|
-
ChatClientAgent mathTutor = new(chatClient,
|
|
151
|
-
"You provide help with math problems. Only respond about math.",
|
|
152
|
-
"math_tutor",
|
|
153
|
-
"Specialist agent for math questions");
|
|
154
|
-
|
|
155
|
-
ChatClientAgent triageAgent = new(chatClient,
|
|
156
|
-
"You determine which agent to use. ALWAYS handoff to another agent.",
|
|
157
|
-
"triage_agent",
|
|
158
|
-
"Routes messages to the appropriate specialist");
|
|
159
|
-
|
|
160
|
-
// Build handoff workflow
|
|
161
|
-
var workflow = AgentWorkflowBuilder.StartHandoffWith(triageAgent)
|
|
162
|
-
.WithHandoffs(triageAgent, [mathTutor, historyTutor])
|
|
163
|
-
.WithHandoff(mathTutor, triageAgent)
|
|
164
|
-
.WithHandoff(historyTutor, triageAgent)
|
|
165
|
-
.Build();
|
|
65
|
+
[Input] ──┬→ [SecurityAnalyst] ──┐
|
|
66
|
+
├→ [PerfAnalyst] ──┤→ [Aggregator]
|
|
67
|
+
└→ [QualityAnalyst] ──┘
|
|
166
68
|
```
|
|
167
69
|
|
|
168
|
-
### Running Handoff with Streaming Events
|
|
169
|
-
|
|
170
70
|
```csharp
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
StreamingRun run = await InProcessExecution.StreamAsync(workflow, messages);
|
|
175
|
-
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
|
|
176
|
-
|
|
177
|
-
await foreach (WorkflowEvent evt in run.WatchStreamAsync())
|
|
178
|
-
{
|
|
179
|
-
if (evt is AgentResponseUpdateEvent e)
|
|
180
|
-
Console.WriteLine($"{e.ExecutorId}: {e.Data}");
|
|
181
|
-
else if (evt is WorkflowOutputEvent outputEvt)
|
|
182
|
-
{
|
|
183
|
-
messages.AddRange(((List<ChatMessage>)outputEvt.Data!).Skip(messages.Count));
|
|
184
|
-
break;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**Handoff characteristics:**
|
|
190
|
-
- Receiving agent takes full task ownership
|
|
191
|
-
- Full conversation history passed to receiving agent
|
|
192
|
-
- Only supports `ChatAgent` with local tool execution
|
|
193
|
-
|
|
194
|
-
---
|
|
195
|
-
|
|
196
|
-
## 5. Magentic Workflow
|
|
197
|
-
|
|
198
|
-
Planner-based variant of GroupChat. A manager agent dynamically selects which agent acts next based on planning.
|
|
199
|
-
|
|
200
|
-
| Aspect | GroupChat | Magentic |
|
|
201
|
-
|--------|-----------|----------|
|
|
202
|
-
| Turn order | Fixed (round-robin) | Dynamic (planner decides) |
|
|
203
|
-
| Manager | Simple rotation | LLM-based planner |
|
|
204
|
-
| Best for | Predictable workflows | Complex, adaptive tasks |
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
## Workflow-as-Agent
|
|
71
|
+
using Microsoft.Agents.AI;
|
|
72
|
+
using Microsoft.Agents.AI.Workflows;
|
|
73
|
+
using Microsoft.Extensions.AI;
|
|
209
74
|
|
|
210
|
-
|
|
75
|
+
// --- 1. Agents (via Model Registry — nunca hardcode o modelo) ---
|
|
76
|
+
IChatClient chatClient = _modelRegistry.GetChatClient("text-default");
|
|
211
77
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
78
|
+
AIAgent securityAnalyst = chatClient.AsAIAgent(
|
|
79
|
+
instructions: "Analyze code for security vulnerabilities. Be concise.",
|
|
80
|
+
name: "SecurityAnalyst");
|
|
215
81
|
|
|
216
|
-
|
|
217
|
-
|
|
82
|
+
AIAgent perfAnalyst = chatClient.AsAIAgent(
|
|
83
|
+
instructions: "Analyze code for performance bottlenecks. Be concise.",
|
|
84
|
+
name: "PerfAnalyst");
|
|
218
85
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
86
|
+
AIAgent qualityAnalyst = chatClient.AsAIAgent(
|
|
87
|
+
instructions: "Analyze code for readability and maintainability. Be concise.",
|
|
88
|
+
name: "QualityAnalyst");
|
|
222
89
|
|
|
223
|
-
|
|
90
|
+
AIAgent aggregator = chatClient.AsAIAgent(
|
|
91
|
+
instructions: "You receive multiple analysis reports. Produce a unified summary with key findings.",
|
|
92
|
+
name: "Aggregator");
|
|
224
93
|
|
|
225
|
-
|
|
94
|
+
// --- 2. Build fan-out / fan-in workflow ---
|
|
95
|
+
WorkflowBuilder builder = new(securityAnalyst);
|
|
96
|
+
builder.AddEdge(securityAnalyst, aggregator);
|
|
226
97
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
builder.AddAIAgent("Writer", (sp, key) =>
|
|
230
|
-
{
|
|
231
|
-
var chatClient = sp.GetRequiredService<IChatClient>();
|
|
232
|
-
return new ChatClientAgent(chatClient, name: key,
|
|
233
|
-
instructions: "You are a creative writing assistant.");
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
builder.AddAIAgent("Editor",
|
|
237
|
-
instructions: "You improve a writer's draft.");
|
|
238
|
-
|
|
239
|
-
app.MapGet("/agent/chat", async (
|
|
240
|
-
[FromKeyedServices("Writer")] AIAgent writer,
|
|
241
|
-
[FromKeyedServices("Editor")] AIAgent editor,
|
|
242
|
-
string prompt) =>
|
|
243
|
-
{
|
|
244
|
-
Workflow workflow = AgentWorkflowBuilder.BuildSequential(writer, editor);
|
|
245
|
-
AIAgent workflowAgent = await workflow.AsAgentAsync();
|
|
246
|
-
var response = await workflowAgent.RunAsync(prompt);
|
|
247
|
-
return Results.Ok(response.Text);
|
|
248
|
-
});
|
|
249
|
-
```
|
|
98
|
+
builder.AddInputEdge(perfAnalyst); // also receives the original input
|
|
99
|
+
builder.AddEdge(perfAnalyst, aggregator);
|
|
250
100
|
|
|
251
|
-
|
|
101
|
+
builder.AddInputEdge(qualityAnalyst);
|
|
102
|
+
builder.AddEdge(qualityAnalyst, aggregator);
|
|
252
103
|
|
|
253
|
-
|
|
104
|
+
builder.WithOutputFrom(aggregator);
|
|
105
|
+
Workflow workflow = builder.Build();
|
|
254
106
|
|
|
255
|
-
|
|
107
|
+
// --- 3. Run with streaming events ---
|
|
108
|
+
string codeSnippet = /* input from request */;
|
|
109
|
+
await using StreamingRun run =
|
|
110
|
+
await InProcessExecution.RunStreamingAsync(workflow, codeSnippet);
|
|
256
111
|
|
|
257
|
-
|
|
258
|
-
public class PhotoCritiqueExecutor : BaseExecutor, IMessageHandler<WorkflowMessage>
|
|
112
|
+
await foreach (WorkflowEvent evt in run.WatchStreamAsync())
|
|
259
113
|
{
|
|
260
|
-
|
|
261
|
-
WorkflowMessage message,
|
|
262
|
-
WorkflowContext context,
|
|
263
|
-
CancellationToken cancellationToken)
|
|
114
|
+
switch (evt)
|
|
264
115
|
{
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
var fullPrompt = new PromptBuilder()
|
|
273
|
-
.AddText(prompt)
|
|
274
|
-
.AddImage(dataContent)
|
|
275
|
-
.Build();
|
|
276
|
-
|
|
277
|
-
var response = await client.GetResponseAsync(fullPrompt);
|
|
278
|
-
await context.SendAsync(new CritiqueResult(response));
|
|
116
|
+
case AgentResponseUpdateEvent update:
|
|
117
|
+
Console.WriteLine($"[{update.Update.AuthorName}] {update.Update.Text}");
|
|
118
|
+
break;
|
|
119
|
+
case WorkflowErrorEvent error:
|
|
120
|
+
Console.Error.WriteLine($"Workflow error: {error.Exception?.Message}");
|
|
121
|
+
break;
|
|
279
122
|
}
|
|
280
123
|
}
|
|
281
124
|
```
|
|
282
125
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
| Conversational | `GetConversationalClient()` | Text → Text | Chat, analysis, generation |
|
|
290
|
-
| Vision | `GetVisionClient()` | Image → Text | Image analysis, OCR |
|
|
291
|
-
| Image Generation | `GetImageClient()` | Text → Image | Mockups, visualizations |
|
|
126
|
+
**Key points:**
|
|
127
|
+
- `AddInputEdge(agent)` — agent recebe o input original (fan-out)
|
|
128
|
+
- `AddEdge(from, to)` — conecta um executor ao próximo
|
|
129
|
+
- `WithOutputFrom(aggregator)` — define quem produz o output final
|
|
130
|
+
- O Aggregator só executa após todos os analysts completarem (superstep boundary)
|
|
131
|
+
- Agents criados via Model Registry alias — não hardcode modelo ou provider
|
|
292
132
|
|
|
293
133
|
---
|
|
294
134
|
|
|
295
|
-
##
|
|
296
|
-
|
|
297
|
-
Store prompts in external markdown files for:
|
|
298
|
-
- Versioning without recompilation
|
|
299
|
-
- Independent iteration and testing
|
|
300
|
-
- Reuse across agents
|
|
135
|
+
## Outros padrões — tabela de referência rápida
|
|
301
136
|
|
|
302
|
-
|
|
303
|
-
var prompt = await File.ReadAllTextAsync("prompts/analysis.md");
|
|
304
|
-
var agent = chatClient.AsAIAgent(instructions: prompt, name: "Analyst");
|
|
305
|
-
```
|
|
137
|
+
Use esta tabela para decidir qual padrão pesquisar. Não escreva código de todos aqui.
|
|
306
138
|
|
|
307
|
-
|
|
139
|
+
| Padrão | Topologia | Quando usar |
|
|
140
|
+
|--------|-----------|-------------|
|
|
141
|
+
| **Sequential** | Cadeia linear | Pipeline simples onde cada etapa depende da anterior. Muitas vezes substituível por chamadas encadeadas. |
|
|
142
|
+
| **Handoff** | Mesh dinâmico | Roteamento dinâmico — agents passam controle conforme o contexto. Ver `ai-agents-multi-agent-patterns` (Onda 2). |
|
|
143
|
+
| **GroupChat** | Estrela (manager) | Refinamento iterativo entre agents com rodadas fixas. `AgentWorkflowBuilder.CreateGroupChatBuilderWith(...)`. |
|
|
144
|
+
| **Magentic** | Estrela (planner LLM) | Variante de GroupChat onde o manager é um LLM que decide dinamicamente quem age. |
|
|
145
|
+
| **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). |
|
|
308
146
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
| Scenario | Pattern | Why |
|
|
312
|
-
|----------|---------|-----|
|
|
313
|
-
| ETL / data pipeline | Sequential | Each step depends on previous |
|
|
314
|
-
| Code review (security + perf + style) | Concurrent | Independent analyses |
|
|
315
|
-
| Content creation + editing | GroupChat | Iterative refinement |
|
|
316
|
-
| Customer support routing | Handoff | Dynamic expert selection |
|
|
317
|
-
| Complex research tasks | Magentic | Adaptive planning |
|
|
318
|
-
| Composing sub-workflows | Workflow-as-Agent | Abstraction |
|
|
147
|
+
Para Sequential simples, `AgentWorkflowBuilder.BuildSequential(agent1, agent2)` é suficiente.
|
|
148
|
+
Para Handoff, `AgentWorkflowBuilder.CreateHandoffBuilderWith(entryAgent)` + `.WithHandoffs(...)`.
|
|
319
149
|
|
|
320
150
|
---
|
|
321
151
|
|
|
322
|
-
##
|
|
152
|
+
## Executando um Workflow (resumo da API)
|
|
153
|
+
|
|
154
|
+
| Método | Retorno | Quando usar |
|
|
155
|
+
|--------|---------|-------------|
|
|
156
|
+
| `InProcessExecution.RunStreamingAsync(workflow, input)` | `StreamingRun` | Input conhecido de antemão, streama eventos |
|
|
157
|
+
| `InProcessExecution.OpenStreamingAsync(workflow)` | `StreamingRun` | Input enviado depois via `TrySendMessageAsync` (ex: chat interativo) |
|
|
158
|
+
| `InProcessExecution.RunAsync(workflow, input)` | `Run` | Sem streaming, acumula todos os eventos |
|
|
323
159
|
|
|
324
|
-
|
|
325
|
-
|------|---------|
|
|
326
|
-
| Mermaid diagrams | Auto-generated workflow visualization |
|
|
327
|
-
| Aspire Dashboard | Trace inter-agent calls and performance |
|
|
328
|
-
| `dotnet new webapi-ai` | Template: Web API with Agent Framework |
|
|
329
|
-
| `dotnet new mcp-server` | Template: MCP Server |
|
|
160
|
+
Sempre use `await using` no `StreamingRun` / `Run` — é `IAsyncDisposable`.
|
|
330
161
|
|
|
331
162
|
---
|
|
332
163
|
|
|
333
|
-
## Checklist
|
|
164
|
+
## Checklist (verifiable by morph-eval)
|
|
334
165
|
|
|
335
|
-
- [ ] `
|
|
336
|
-
- [ ]
|
|
337
|
-
- [ ] Agents
|
|
338
|
-
- [ ]
|
|
339
|
-
- [ ]
|
|
340
|
-
- [ ]
|
|
341
|
-
- [ ]
|
|
342
|
-
- [ ] Error handling defined per executor
|
|
166
|
+
- [ ] Foi verificado que um `foreach` ou single agent não resolve o problema?
|
|
167
|
+
- [ ] O critério de fan-in/out genuíno ou HITL está documentado em `decisions.md`?
|
|
168
|
+
- [ ] `Microsoft.Agents.AI` 1.0.* presente no `.csproj` (sem pacotes preview separados)?
|
|
169
|
+
- [ ] Agents referenciando alias do Model Registry (não model strings hardcoded)?
|
|
170
|
+
- [ ] `await using` no `StreamingRun` / `Run`?
|
|
171
|
+
- [ ] `WorkflowErrorEvent` tratado no loop de eventos?
|
|
172
|
+
- [ ] OpenTelemetry habilitado para rastrear chamadas inter-agent?
|
|
343
173
|
|
|
344
174
|
---
|
|
345
175
|
|
|
346
176
|
## References
|
|
347
177
|
|
|
348
|
-
-
|
|
349
|
-
-
|
|
350
|
-
-
|
|
351
|
-
-
|
|
352
|
-
-
|
|
353
|
-
-
|
|
178
|
+
- `ai-agents-setup` — pacotes, `ChatClientAgent`, tools
|
|
179
|
+
- `ai-agents-sweet-spot` — decisão single agent vs workflow
|
|
180
|
+
- `ai-agents-multi-agent-patterns` (Onda 2) — Agent-as-Tool, Handoff patterns
|
|
181
|
+
- `ai-agents-providers-model-registry` — Model Registry para alias de provider
|
|
182
|
+
- MAF Workflows docs: https://learn.microsoft.com/agent-framework/
|
|
183
|
+
- MAF Workflow samples: https://github.com/microsoft/agent-framework/tree/main/dotnet/samples/03-workflows
|
|
354
184
|
|
|
355
185
|
---
|
|
356
186
|
|
|
357
|
-
*MORPH-SPEC by Polymorphism Tech*
|
|
187
|
+
*MORPH-SPEC by Polymorphism Tech — ai-agents/workflows.md v2.0 (2026-05-19)*
|