<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marcos Vinicius</title>
    <description>The latest articles on DEV Community by Marcos Vinicius (@devmaarcosvnl).</description>
    <link>https://dev.to/devmaarcosvnl</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4238023%2Fc777122e-df3b-4f3e-bb24-bc78e9984be2.jpg</url>
      <title>DEV Community: Marcos Vinicius</title>
      <link>https://dev.to/devmaarcosvnl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devmaarcosvnl"/>
    <language>en</language>
    <item>
      <title>Do Zero ao Grafo Multiagente em .NET com Microsoft Agent Framework e DuckDB</title>
      <dc:creator>Marcos Vinicius</dc:creator>
      <pubDate>Wed, 11 Nov 2026 00:55:23 +0000</pubDate>
      <link>https://dev.to/devmaarcosvnl/do-zero-ao-grafo-multiagente-em-net-com-microsoft-agent-framework-e-duckdb-1dl4</link>
      <guid>https://dev.to/devmaarcosvnl/do-zero-ao-grafo-multiagente-em-net-com-microsoft-agent-framework-e-duckdb-1dl4</guid>
      <description>&lt;p&gt;Muito se fala em Python quando o tema é Inteligência Artificial Generativa. No entanto, quando entramos no território de &lt;strong&gt;sistemas corporativos, tipagem estrita, alta performance, governança e microsserviços&lt;/strong&gt;, o ecossistema &lt;strong&gt;.NET (C#)&lt;/strong&gt; oferece uma base arquitetural sólida e madura.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos analisar a engenharia por trás do &lt;strong&gt;&lt;code&gt;DecisionFlow.cs&lt;/code&gt;&lt;/strong&gt;, o núcleo inteligente do projeto &lt;a href="https://github.com/marcosvnl/Workflow-MAF-DOTNET" rel="noopener noreferrer"&gt;Olist.Agents&lt;/a&gt;. Trata-se de um projeto acadêmico desenvolvido para a entrega do Tech Challenge da pós-graduação, modelado para demonstrar maturidade de produção e padrões arquiteturais reais com IA agêntica.&lt;/p&gt;

&lt;p&gt;Você vai aprender:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Como abstrair modelos de linguagem usando &lt;code&gt;Microsoft.Extensions.AI&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;O que é um &lt;code&gt;AIAgent&lt;/code&gt; e por que ele precisa de ferramentas (&lt;em&gt;tools&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Por que usamos &lt;code&gt;Executors&lt;/code&gt;&lt;/strong&gt; se já instanciamos os agentes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Como o agente Cadu implementa RAG Estruturado&lt;/strong&gt; sobre 100 mil registros reais.&lt;/li&gt;
&lt;li&gt;Como orquestrar um fluxo em grafo com bifurcações e supervisão humana (&lt;em&gt;Human-in-the-Loop&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Por que usamos &lt;code&gt;RequestPort&lt;/code&gt;&lt;/strong&gt; para receber decisões humanas sem travar threads.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. O Alicerce: Desacoplamento com &lt;code&gt;Microsoft.Extensions.AI&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Muitos desenvolvedores acoplam suas aplicações diretamente a SDKs proprietários. No .NET moderno, a Microsoft padronizou a interação com modelos através da interface unificada &lt;strong&gt;&lt;code&gt;IChatClient&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No trecho inicial do &lt;code&gt;DecisionFlow.cs&lt;/code&gt;, instanciamos o cliente do Google Gemini, mas o encapsulamos sob essa abstração:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nc"&gt;IChatClient&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;_googleAIConfigs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ApiKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;httpOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HttpOptions&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;RetryOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HttpRetryOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Attempts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;InitialDelay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;MaxDelay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AsIChatClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_googleAIConfigs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Por que isso é importante?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Desacoplamento de Provedor:&lt;/strong&gt; O fluxo de trabalho não se importa se o motor de inferência é o Gemini, Azure OpenAI, Claude ou um modelo local rodando via Ollama.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resiliência Nativa:&lt;/strong&gt; O &lt;code&gt;HttpRetryOptions&lt;/code&gt; trata erros de rede transitórios, códigos &lt;code&gt;503&lt;/code&gt; (sobrecarga) e &lt;code&gt;429&lt;/code&gt; (limites de requisição por minuto) com &lt;em&gt;backoff&lt;/em&gt; exponencial configurado.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Ferramentas e Protocolo Aberto: Model Context Protocol (MCP)
&lt;/h2&gt;

&lt;p&gt;Antes de instanciar os agentes, o código inicializa um cliente &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nc"&gt;McpClient&lt;/span&gt; &lt;span class="n"&gt;learnMcpClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nc"&gt;McpClient&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CreateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HttpClientTransport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HttpClientTransportOptions&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_mcpServerConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;McpServerUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Microsoft Learn MCP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;IList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AITool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;researcherTools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;learnMcpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ListToolsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AITool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O MCP padroniza como modelos de IA descobrem e acionam ferramentas externas via JSON-RPC/HTTP. No .NET, essas ferramentas são convertidas diretamente para instâncias de &lt;code&gt;AITool&lt;/code&gt;, ficando disponíveis para consumo agêntico sem SDKs intermediários.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. O que é um &lt;code&gt;AIAgent&lt;/code&gt; e Como Criá-lo
&lt;/h2&gt;

&lt;p&gt;Um &lt;strong&gt;AIAgent&lt;/strong&gt; no &lt;em&gt;Microsoft Agent Framework&lt;/em&gt; combina três pilares:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identidade / Nome:&lt;/strong&gt; Como ele é identificado no fluxo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instruções (&lt;em&gt;System Prompt&lt;/em&gt;):&lt;/strong&gt; Regras de negócio e limites de atuação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ferramentas (&lt;em&gt;Tools&lt;/em&gt;):&lt;/strong&gt; Métodos que o modelo pode acionar sob demanda via &lt;em&gt;function calling&lt;/em&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nc"&gt;AIAgent&lt;/span&gt; &lt;span class="n"&gt;cadu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AsAIAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Cadu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AgentHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ReadablePromptAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Agents/Prompts/Cadu.md"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;billing&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;_sqlConsultTool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GetCaduTools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Boas Práticas:&lt;/strong&gt; Os prompts não ficam &lt;em&gt;hardcoded&lt;/em&gt; em classes C#. Eles residem em arquivos &lt;code&gt;.md&lt;/code&gt; externos, permitindo versionamento, refinamento e manutenção sem necessidade de recompilar a aplicação.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. Por que Usar &lt;code&gt;Executors&lt;/code&gt; se Já Temos os &lt;code&gt;AIAgent&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Uma dúvida frequente de quem está iniciando no framework é: &lt;em&gt;"Se eu já criei a instância do &lt;code&gt;AIAgent&lt;/code&gt;, por que preciso de classes como &lt;code&gt;SantiExecutor&lt;/code&gt;, &lt;code&gt;LeoExecutor&lt;/code&gt; ou &lt;code&gt;CaduExecutor&lt;/code&gt;?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A resposta está no &lt;strong&gt;Princípio da Responsabilidade Única (SRP)&lt;/strong&gt; e na arquitetura interna de workflows em grafo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;AIAgent&lt;/code&gt; (O Cérebro / Raciocínio):&lt;/strong&gt; Cuida exclusivamente da cognição com a LLM — interpreta o prompt, executa ferramentas e devolve texto ou JSON. Ele &lt;strong&gt;não conhece o grafo&lt;/strong&gt;, não sabe quem o antecedeu e não sabe para onde enviar o resultado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Executor&lt;/code&gt; (O Nó Operacional do Grafo):&lt;/strong&gt; É o nó de infraestrutura que herda do framework (como &lt;code&gt;Executor&amp;lt;TInput, TOutput&amp;gt;&lt;/code&gt;). Suas responsabilidades são:

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Adaptação de Contratos:&lt;/strong&gt; Recebe os dados de entrada do nó anterior e formata o contexto para o agente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chamada e Desserialização:&lt;/strong&gt; Executa o &lt;code&gt;AIAgent&lt;/code&gt; e converte a resposta em texto/JSON para um objeto C# fortemente tipado (&lt;code&gt;SantiTriagem&lt;/code&gt;, &lt;code&gt;LeoTriagem&lt;/code&gt;, &lt;code&gt;CaduTriagem&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regras de Negócio Determinísticas:&lt;/strong&gt; Se o modelo falhar, alucinar ou retornar dados incompletos, o &lt;code&gt;Executor&lt;/code&gt; aplica validações defensivas e &lt;em&gt;fallbacks&lt;/em&gt; antes de propagar o estado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Telemetria:&lt;/strong&gt; Emite o &lt;code&gt;ExecutorInvokedEvent&lt;/code&gt;, permitindo que o painel de controle acompanhe a execução em tempo real.
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nc"&gt;SantiExecutor&lt;/span&gt; &lt;span class="n"&gt;santiExecutor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;santi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;LeoExecutor&lt;/span&gt; &lt;span class="n"&gt;leoExecutor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;CaduExecutor&lt;/span&gt; &lt;span class="n"&gt;caduExecutor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cadu&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. RAG no Mundo Real: Como o Cadu Audita o Catálogo
&lt;/h2&gt;

&lt;p&gt;Muitos tutoriais resumem &lt;strong&gt;RAG (Retrieval-Augmented Generation)&lt;/strong&gt; a dividir arquivos PDF em blocos (&lt;em&gt;chunks&lt;/em&gt;) e buscar similaridade vetorial. No mercado corporativo, &lt;strong&gt;RAG também opera sobre dados estruturados de missão crítica&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  O Cenário do Cadu (&lt;em&gt;Catalog Guard&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;O Cadu audita inconsistências em anúncios de produtos sobre o dataset público da Olist (mais de 100 mil registros de pedidos e produtos).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O Desafio:&lt;/strong&gt; Como um modelo de linguagem pode validar se as dimensões, o peso ou o histórico de um anúncio são coerentes sem estourar o limite de tokens da janela de contexto?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Solução (RAG Estruturado / Text-to-SQL in-process):&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;O nó do Cadu recebe a identificação do anúncio (&lt;code&gt;ProductId&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;O agente decide acionar a sua ferramenta: &lt;code&gt;_sqlConsultTool.GetCaduTools()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A ferramenta executa consultas analíticas via &lt;strong&gt;DuckDB + Dapper&lt;/strong&gt; diretamente sobre os arquivos &lt;code&gt;.csv&lt;/code&gt; locais (tabelas &lt;code&gt;products&lt;/code&gt;, &lt;code&gt;order_items&lt;/code&gt;, &lt;code&gt;sellers&lt;/code&gt;), sem a complexidade de subir um banco de dados relacional dedicado.&lt;/li&gt;
&lt;li&gt;Os dados factuais retornam da base (&lt;em&gt;Retrieval&lt;/em&gt;) e são incorporados ao contexto do Cadu.&lt;/li&gt;
&lt;li&gt;O agente sintetiza a sua avaliação determinando se o anúncio está conforme (&lt;em&gt;Augmented Generation&lt;/em&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essa abordagem garante custo reduzido, zero alucinação com dados numéricos e altíssima velocidade de auditoria.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. O Grafo de Decisão (WorkflowBuilder)
&lt;/h2&gt;

&lt;p&gt;Para conectar todos os nós de forma auditável e paralela, utilizamos o &lt;strong&gt;&lt;code&gt;WorkflowBuilder&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nc"&gt;Workflow&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WorkflowBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orchestrator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WithName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"OlistDecisionFlow"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AddFanOutEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orchestrator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;santiExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leoExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;caduExecutor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AddSwitch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;santiExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AddCase&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SantiTriagem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Gravidade&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Gravidade&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Moderada&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;santiAuto&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WithDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;analistaCX&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AddSwitch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leoExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AddCase&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LeoTriagem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Risco&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;RiscoAtraso&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Baixo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;leoAuto&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WithDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;analistaLogistica&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AddSwitch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;caduExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AddCase&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CaduTriagem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Parecer&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;ParecerCatalogo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Conforme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;caduAuto&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WithDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;analistaCatalogo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AddEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;analistaCX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;humanGate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AddEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;analistaLogistica&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;humanGate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AddEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;analistaCatalogo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;humanGate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WithOutputFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;santiAuto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leoAuto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;caduAuto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;humanGate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Entendendo a Topologia:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;orchestrator&lt;/code&gt;:&lt;/strong&gt; Consulta a base DuckDB e extrai os casos pendentes de triagem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;AddFanOutEdge&lt;/code&gt;:&lt;/strong&gt; Dispara a análise em paralelo para os três agentes especialistas (Santi, Léo e Cadu).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;AddSwitch&lt;/code&gt;:&lt;/strong&gt; Bifurcação condicional com tipagem estrita do C#. Se o parecer do Cadu for &lt;code&gt;Conforme&lt;/code&gt;, ele desvia para &lt;code&gt;caduAuto&lt;/code&gt; (ação automática). Se houver inconformidade, segue para a porta do analista.
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
  Orquestrador --&amp;gt; Santi &amp;amp; Leo[Léo] &amp;amp; Cadu
  Santi -- moderada --&amp;gt; SantiAuto[Ação automática]
  Santi -- grave --&amp;gt; AnalistaCX
  Leo -- risco baixo --&amp;gt; LeoAuto[Ação automática]
  Leo -- risco alto --&amp;gt; AnalistaLogistica
  Cadu -- conforme --&amp;gt; CaduAuto[Ação automática]
  Cadu -- não conforme --&amp;gt; AnalistaCatalogo
  AnalistaCX &amp;amp; AnalistaLogistica &amp;amp; AnalistaCatalogo --&amp;gt; HumanGate[Decisão humana]&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  7. Por que Usar &lt;code&gt;RequestPort&lt;/code&gt; se o Agente Já Devolve um Objeto C#?
&lt;/h2&gt;

&lt;p&gt;Quando o agente conclui a inferência, ele devolve um objeto tipado (como &lt;code&gt;CaduTriagem&lt;/code&gt;). Então, por que declarar um &lt;code&gt;RequestPort&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nc"&gt;RequestPort&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CaduTriagem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;analistaCatalogo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestPort&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Create&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CaduTriagem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"AnalistaCatalogo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se tentássemos recolher o input humano com um simples &lt;code&gt;Console.ReadLine()&lt;/code&gt; dentro da execução de um nó, bloquearíamos a thread do runtime, impedindo o paralelismo do &lt;code&gt;AddFanOutEdge&lt;/code&gt; e travando a fila de streaming de eventos.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;RequestPort&amp;lt;TRequest, TResponse&amp;gt;&lt;/code&gt; implementa o padrão &lt;strong&gt;Human-in-the-Loop assíncrono&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pausa Controlada de Estado:&lt;/strong&gt; Ao receber o caso não conforme, o ramo específico do workflow é suspenso.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Emissão de Evento Desacoplada:&lt;/strong&gt; O workflow emite um &lt;code&gt;RequestInfoEvent&lt;/code&gt; contendo o payload &lt;code&gt;CaduTriagem&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recolha Não Bloqueante:&lt;/strong&gt; A interface de apresentação (neste projeto, um terminal visual com Spectre.Console) exibe os detalhes para o operador humano.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retomada com &lt;code&gt;SendResponseAsync&lt;/code&gt;:&lt;/strong&gt; Assim que o analista confirma a sua decisão (&lt;code&gt;true&lt;/code&gt; ou &lt;code&gt;false&lt;/code&gt;), o valor é enviado de volta e o workflow retoma a sua execução imediatamente:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;RequestInfoEvent&lt;/span&gt; &lt;span class="n"&gt;requestEvt&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;requestEvt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;TryGetDataAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="nc"&gt;CaduTriagem&lt;/span&gt; &lt;span class="n"&gt;caduTriagem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;decisao&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dashboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AskAnalyst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;caduTriagem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SendResponseAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestEvt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CreateResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decisao&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  8. Execução Orientada a Eventos
&lt;/h2&gt;

&lt;p&gt;A inicialização e o consumo do grafo acontecem em modo streaming através do método &lt;code&gt;InProcessExecution.RunStreamingAsync&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nc"&gt;StreamingRun&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nc"&gt;InProcessExecution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RunStreamingAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scanRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;WorkflowEvent&lt;/span&gt; &lt;span class="n"&gt;evt&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WatchStreamAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;ExecutorInvokedEvent&lt;/span&gt; &lt;span class="n"&gt;invokedEvt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;// Notifica o início de processamento no dashboard&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;WorkflowOutputEvent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;CaduTriagem&lt;/span&gt; &lt;span class="n"&gt;caduAutomatico&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;dashboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AutoResolved&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Cadu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;caduAutomatico&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ProductId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"o anúncio foi publicado na loja"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;ExecutorFailedEvent&lt;/span&gt; &lt;span class="n"&gt;failedEvt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;dashboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;$&lt;span class="s2"&gt;"Falha no executor '{failedEvt.ExecutorId}': {failedEvt.Data}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;dashboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa estrutura transforma a aplicação num sistema reativo, auditável e resiliente, onde a interface de usuário permanece desacoplada da mecânica do grafo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Projetos de conclusão de curso e provas de conceito ganham muito em relevância quando combinam fundamentação teórica com padrões de engenharia de software corporativa. O ecossistema .NET entrega tipagem rigorosa, ciclo de vida com injeção de dependência e arquitetura agêntica estruturada com o Microsoft Agent Framework.&lt;/p&gt;

&lt;p&gt;Para conferir a implementação completa, incluindo prompts, diagramas e configuração de ambiente, acesse o repositório:&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Repositório no GitHub:&lt;/strong&gt; &lt;a href="https://github.com/marcosvnl/Workflow-MAF-DOTNET" rel="noopener noreferrer"&gt;https://github.com/marcosvnl/Workflow-MAF-DOTNET&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como você tem estruturado sistemas de IA agêntica em .NET? Compartilhe suas experiências e dúvidas nos comentários!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
