Categoria: IA & Cloud

Inteligência artificial generativa, Azure e arquitetura de soluções em nuvem.

  • Capacitação Microsoft AI — Aula 7: agentes avançados, ferramentas e aprovação humana

    Playlist completa no YouTube · Código .NET da aula 7 · Código Python da aula 7 · Slides da aula 7 (PDF)

    O que a aula cobriu

    A aula 7 pega o agente simples da aula 6 e dá a ele mais responsabilidade: ferramentas reais, um passo de aprovação humana antes de ações irreversíveis, acesso à documentação oficial via MCP hospedado, e um fluxo com três agentes trabalhando em sequência.

    São quatro demos na mesma base de configuração das aulas anteriores (endpoint, identidade e AIProjectClient não mudam):

    • Function calling: quatro ferramentas (consulta a uma base de conhecimento, previsão do tempo, calculadora e um envio de e-mail simulado) criadas com AIFunctionFactory.Create, cada uma documentada com atributos de descrição que o modelo lê para decidir quando chamar.
    • Human-in-the-loop: a ferramenta de envio de e-mail é envolvida num wrapper de aprovação. O agente pausa, devolve um pedido de aprovação, e só continua a execução depois que uma pessoa confirma.
    • MCP hospedado: o agente ganha acesso a um servidor MCP público de documentação da Microsoft, sem precisar de nenhuma integração customizada — é só mais uma ferramenta na lista.
    • Workflow sequencial: três agentes (pesquisador, validador e redator) encadeados, cada um processando a saída do anterior e transmitindo seu resultado em streaming.

    Três ideias para levar

    1. O modelo nunca executa nada — a sua aplicação executa. Toda ferramenta que você expõe a um agente é só um método comum que a sua aplicação roda quando o modelo pede. Isso significa que validar os parâmetros, nunca devolver segredos e tratar erros com mensagens legíveis (em vez de deixar uma exceção estourar) é responsabilidade sua, não do modelo.

    2. Aprovação é uma decisão de wrapper, não da ferramenta. A mesma função de envio de e-mail funciona com ou sem aprovação humana — o que muda é só a camada que envolve ela. Isso separa bem a lógica de negócio da política de segurança: você decide onde exigir aprovação sem tocar no código da ferramenta em si.

    // A ferramenta de envio de e-mail só é executada depois de aprovação explícita
    var emailTool = new ApprovalRequiredAIFunction(
        AIFunctionFactory.Create(EnviarEmailSimulado)
    );
    
    // O agente pausa e devolve um ToolApprovalRequestContent
    // em vez de executar direto — a aplicação decide o que fazer com isso
    

    3. Nem todo problema precisa de vários agentes conversando. O workflow sequencial da aula mostra o caso em que faz sentido ter mais de um agente — quando cada etapa precisa de um papel e um contexto diferentes. Mas vale sempre perguntar primeiro se um único agente, num loop simples, não resolveria o mesmo problema por um custo menor.

    Antes de rodar

    • Confirme que sua conta tem o papel Foundry User no recurso — sem ele, as chamadas à API retornam 403.
    • Copie o launchSettings.template.json da aula 6 e ajuste só o nome do perfil.
    • Configure as variáveis de ambiente FOUNDRY_ENDPOINT e FOUNDRY_MODEL — o modelo escolhido precisa suportar function calling (use algo da família GPT-5.x caso o agente nunca chame as ferramentas).
    • Rode az login --tenant <id> antes do dotnet run, e defina AZURE_TENANT_ID e AZURE_TOKEN_CREDENTIALS=AzureCliCredential para autenticação mais previsível.
    • Se o restore reclamar de versões conflitantes entre os pacotes de Workflows e de Foundry (erros NU1608/NU1605), pin as duas na mesma versão.
    • A demo 3 precisa de saída de internet do serviço para alcançar o MCP hospedado — confirme que sua rede permite isso.

    Se você está na trilha Python

    O equivalente em Python está em Python/aula07-agentes-avancados, com main.py e um módulo próprio de ferramentas (ferramentas.py) espelhando as mesmas quatro demos. A lógica de validação de entrada e de não devolver segredos nas respostas das ferramentas vale igual nos dois ecossistemas — é decisão de arquitetura, não de linguagem.

    Próximo passo

    Na aula 8 fechamos a série com avaliação de agentes: como medir se o que construímos até aqui está realmente funcionando antes de colocar em produção.

  • Capacitação Microsoft AI — Aula 6: seu primeiro agente com o Microsoft Agent Framework

    Este é o sexto de oito artigos que acompanham as aulas da Capacitação Microsoft AI 2026, que Otávio Lourenço da Silva e eu ministramos ao vivo entre agosto e setembro. As gravações continuam no ar; os artigos existem para quem prefere ler, revisar ou copiar o código com calma.

    O que a aula cobriu

    As aulas 1 a 3 já tinham montado a base: mesmo modelo, mesmo recurso Foundry, mesma identidade e o AIProjectClient de sempre. A sexta aula não troca nada disso — ela envolve esse cliente com AsAIAgent(modelo, nome, instruções) e, de repente, você tem um agente. Com nome, com instruções fixas e, a partir daí, com memória de conversa. O agente roda no seu processo; nada é criado do lado do serviço. Não é um recurso novo para provisionar, é uma camada em cima do que já existia.

    Três ideias para levar

    1. Um agente é o cliente de sempre, só que com nome e instruções

    Não existe um serviço de “agentes” separado para criar e gerenciar. AsAIAgent é um método de extensão sobre o client que você já usava desde a aula 3 — ele recebe o nome do deployment, um nome para o agente e as instruções (o equivalente ao system prompt) e devolve um objeto com os mesmos dois jeitos de responder que você já conhecia.

    var agente = client.AsAIAgent(
        model: deploymentName,
        name: "Assistente de Férias",
        instructions: "Responda com base na política de férias da empresa.");
    
    var sessao = agente.GetNewSession();
    var resposta = await agente.RunAsync("Quantos dias de férias eu tenho por ano?", sessao);

    2. RunAsync e RunStreamingAsync continuam sendo a escolha de sempre

    RunAsync devolve a resposta completa de uma vez — cada chamada, isolada, começa do zero se você não passar uma sessão. RunStreamingAsync entrega token a token, do mesmo jeito que o streaming de chat das aulas anteriores. A novidade não está no transporte da resposta, está no que vem entre uma chamada e outra.

    3. AgentSession tira de você a lista de mensagens

    Até a aula 2, manter contexto significava você mesmo acumular uma lista de mensagens e reenviá-la inteira a cada chamada. Com AgentSession, essa lista passa a viver dentro da sessão: você guarda o objeto da sessão, não o histórico, e o framework decide o que mandar de volta ao modelo. Trocar de assunto no meio da conversa, pedir para o agente “lembrar” algo dito três perguntas atrás — isso deixa de ser código seu para ser comportamento do framework.

    Antes de rodar

    • Pré-requisitos de sempre: .NET SDK 10, az login no tenant certo e um recurso Foundry com um modelo já implantado — mas agora com a função Foundry User atribuída à sua identidade. Ser Owner da subscription não é suficiente; sem esse papel específico, as chamadas do agente voltam com 403.
    • A configuração sai de variáveis de ambiente — FOUNDRY_ENDPOINT (o endpoint do projeto) e FOUNDRY_MODEL (o nome do deployment), opcionalmente AZURE_TENANT_ID e AZURE_TOKEN_CREDENTIALS — definidas num launchSettings.json local e fora do controle de versão.
    • O único pacote novo é o Microsoft.Agents.AI.Foundry (ainda em prerelease), mais o Azure.Identity de sempre. Ele já traz consigo os pacotes Azure AI e Microsoft.Extensions.AI de que precisa. Adicionar esses pacotes de novo, manualmente, numa versão diferente da que o framework espera, costuma travar em runtime com MissingMethodException — e os erros do NuGet (NU1608/NU1605) no build já avisam antes disso.
    • 404 geralmente é endpoint no formato errado; o aviso OPENAI001 aparece quando falta o NoWarn para a API ainda experimental.

    Se você está na trilha Python

    A mesma aula existe em Python 3.12+, na pasta aula06-agent-framework, com o mesmo AIProjectClient e o mesmo endpoint de projeto que você já vinha usando desde a aula 3. A ideia de sessão e a separação entre resposta completa e streaming se repete; o que muda é só a sintaxe. Fixar versões no requirements.txt continua valendo, pelo mesmo motivo da aula 5: evitar que uma atualização silenciosa do pacote mude o comportamento do agente entre uma aula e a próxima.

    Próximo passo

    Rode o exemplo sem passar uma sessão entre duas perguntas que dependem uma da outra — deixe ele “esquecer” de propósito — e depois rode de novo passando a mesma AgentSession nas duas chamadas. A diferença entre as duas execuções é a aula inteira resumida em uma demonstração. Na aula 7 esse agente ganha ferramentas, memória de longo prazo e aprende a trabalhar junto com outros agentes.

    Dúvidas ou algo que não funcionou? Deixe nos comentários ou abra uma issue no repositório.

  • Capacitação Microsoft AI — Aula 5: RAG end-to-end com avaliação

    Este é o quinto de oito artigos que acompanham as aulas da Capacitação Microsoft AI 2026, que Otávio Lourenço da Silva e eu ministramos ao vivo entre agosto e setembro. As gravações continuam no ar; os artigos existem para quem prefere ler, revisar ou copiar o código com calma.

    O que a aula cobriu

    A quinta aula pega o RAG da aula 4, que já funcionava, e faz a pergunta que a aula 4 não conseguia responder: funcionava bem? O corpus e o índice são os mesmos. O que entra é medição: um pipeline que devolve objeto em vez de texto, quatro métricas de qualidade calculadas por um modelo juiz, um conjunto de seis perguntas com gabarito e dois experimentos — a varredura de top-k e a comparação com e sem ranqueamento semântico — que terminam num relatório em Markdown. A ideia que sustenta a aula: RAG não termina quando a resposta aparece na tela; termina quando você consegue dizer, com número, se ela ficou melhor ou pior que ontem, e qual etapa mudou.

    Três ideias para levar

    1. Um pipeline que só imprime texto não pode ser avaliado

    A mudança de arquitetura da aula cabe num tipo de retorno. PipelineRag.ResponderAsync devolve a resposta junto com os trechos recuperados, o contexto exato que foi para o modelo, o modo de busca, o top-k e a latência. Sem esses dados, não há o que comparar — e qualquer “acho que melhorou” vira opinião.

    public sealed record RespostaRag(
        string Pergunta,
        string Texto,
        ChatResponse Bruta,
        IReadOnlyList<TrechoCitado> Trechos,
        string Contexto,
        IndiceRag.Modo Modo,
        int TopK,
        TimeSpan Latencia);

    2. Groundedness e retrieval são separadas de propósito

    As quatro métricas do Microsoft.Extensions.AI.Evaluation.Quality parecem medir a mesma coisa com nomes diferentes, mas cada uma compara um par distinto. Groundedness compara a resposta com o contexto recuperado; relevance, a resposta com a pergunta; retrieval, os trechos com a pergunta; correctness, a resposta com o gabarito. As três primeiras olham para a resposta, e retrieval olha para o que veio antes dela. Se a resposta piorou e o retrieval continua bom, o problema está no prompt ou na geração; se os dois caíram, está no chunking, no embedding ou no índice. O caso perigoso é relevance alta com groundedness baixa: a resposta parece ótima e é inventada.

    Ao lado do juiz rodam duas conferências determinísticas, que não custam chamada de modelo: recuperou os documentos esperados? Recusou exatamente quando devia? Quando discordam do juiz, costumam estar certas. Metade de um diagnóstico de queda é um Contains.

    3. Meça antes de acreditar — inclusive no slide

    Na varredura de top-k (3, 5 e 10), quase todo mundo aposta que 10 é melhor. Com o corpus da aula, a curva sai plana: cinco documentos viram doze chunks, então top-k 10 traz quase tudo e só o custo em tokens sobe. Esse é o resultado certo, e ensina a ler a tabela — retrieval igual com mais tokens quer dizer que você está pagando por nada. Para ver a curva aparecer, basta reindexar com chunks menores. O mesmo vale para o ranqueador semântico: o ganho prometido nos slides vem de corpora grandes e heterogêneos, e num corpus de cinco documentos ele é pequeno, às vezes nulo. O juiz, por sua vez, também é um LLM — erra, é sensível ao próprio prompt e responde em inglês. Não é a verdade; é um instrumento barato o bastante para rodar a cada mudança.

    Antes de rodar

    • Os mesmos pré-requisitos da aula 4: .NET SDK 10, Azure CLI com az login no tenant certo, um recurso Foundry com deployments de chat e de embeddings e um Azure AI Search no SKU basic ou superior. Se a aula 4 já indexou, o índice desta aula já existe.
    • O modelo juiz é, por padrão, o mesmo deployment de chat. A variável FOUNDRY_JUDGE_MODEL existe para usar outro modelo e reduzir o viés de um modelo se avaliar bem.
    • O endpoint continua sendo o /openai/v1, como na aula 4, e as versões dos pacotes não devem ser alteradas. Os dois pacotes de avaliação entram sem mudar o pivô OpenAI 2.12.0, porque falam com o modelo por IChatClient — o argumento mais prático a favor da abstração.
    • As opções que avaliam o conjunto inteiro fazem dezenas de chamadas ao juiz. Se aparecer 429, é cota do deployment: o código já limita a três perguntas simultâneas, e dá para baixar para uma.

    Se você está na trilha Python

    A mesma aula existe em Python 3.12+, na pasta aula05-rag-avancado, com o pacote azure-ai-evaluation fazendo o papel de juiz — groundedness, relevance, retrieval e similarity com o gabarito — e a mesma varredura de top-k e o mesmo relatório. Em Python não existe o problema de pivô: a versão Python usa o mesmo AIProjectClient e o mesmo endpoint de projeto das aulas anteriores. Fixar versões no requirements.txt continua valendo.

    Próximo passo

    Comece avaliando uma única pergunta: a sexta do conjunto, cujo assunto está no corpus mas cuja resposta não está. O sistema recusa, groundedness e correctness tiram nota máxima e retrieval tira nota baixa — porque os trechos, de fato, não respondem à pergunta. Métrica não é nota de prova; é instrumento, e quem interpreta é você. Depois rode a varredura de top-k, anote seu palpite antes e grave o relatório: é ele que você compara na semana seguinte. Na aula 6 saímos do RAG e construímos o primeiro agente com o Microsoft Agent Framework.

    Dúvidas ou algo que não funcionou? Deixe nos comentários ou abra uma issue no repositório.

  • Capacitação Microsoft AI — Aula 4: RAG com Azure AI Search

    Este é o quarto de oito artigos que acompanham as aulas da Capacitação Microsoft AI 2026, que Otávio Lourenço da Silva e eu ministramos ao vivo entre agosto e setembro. As gravações continuam no ar; os artigos existem para quem prefere ler, revisar ou copiar o código com calma.

    O que a aula cobriu

    A quarta aula junta as três anteriores — o modelo do Foundry e a abstração do Microsoft.Extensions.AI — com um índice vetorial no Azure AI Search. O corpus é um conjunto de políticas internas de uma empresa fictícia, escrito de propósito para que algumas perguntas só ele responda, e para que uma pergunta pareça estar nele e não esteja. É essa segunda situação que sustenta toda a discussão sobre groundedness: o modelo tem que saber admitir quando não sabe, mesmo com os documentos na mão.

    Três ideias para levar

    1. Chunking é um parâmetro, não um detalhe escondido

    O projeto quebra o texto por parágrafo e junta vizinhos até ~800 caracteres — deliberadamente simples, e deliberadamente exposto como parâmetro. Mudar esse número e reindexar, ao vivo, é o experimento mais barato da aula: chunks pequenos demais perdem contexto, chunks grandes demais diluem o sinal na média.

    // Chunking por parágrafo, até ~800 caracteres
    var chunks = IndiceRag.Fatiar(\n texto,\n tamanhoAlvo: 800);

    2. Keyword, vetorial e híbrida acertam coisas diferentes

    A busca por palavra-chave (BM25) acerta códigos, siglas e nomes próprios, mas erra sinônimos. A busca vetorial acerta sentido e paráfrase, mas erra identificadores literais. A híbrida soma os dois com reranking semântico — acerta ambos os casos, ao custo de mais latência. Ver os três modos lado a lado, com os scores visíveis, é o que desfaz a ideia de que RAG é uma caixa-preta única.

    3. RAG não é sempre a resposta certa

    O roteiro de sala faz a mesma pergunta com e sem RAG, três vezes. A primeira mostra o modelo inventando um valor plausível sem os documentos, e citando a fonte certa com eles — o caso óbvio. A segunda mostra RAG atrapalhando: uma pergunta que o modelo já respondia bem ganha uma citação desnecessária, gastando tokens e latência à toa. A terceira é a que vale a aula: um assunto que está no corpus mas cuja resposta específica não está — e o comportamento certo é admitir a ausência, não inventar uma política inteira.

    Antes de rodar

    • .NET SDK 10 e Azure CLI instalados, com az login feito no tenant certo.
    • Um recurso Foundry com dois deployments — um de chat e um de embeddings (text-embedding-3-small) — e um serviço Azure AI Search no SKU basic ou superior (o free não tem ranqueamento semântico).
    • Os papéis Search Service Contributor e Search Index Data Contributor no Search, concedidos tanto à sua conta quanto à identidade gerenciada do recurso Foundry — são identidades diferentes, e esquecer a segunda é a causa mais comum de 403 no playground.
    • Não altere as versões dos pacotes. O projeto converge para OpenAI 2.12.0; adicionar Azure.AI.Projects recria o conflito de pivô das aulas anteriores.

    Se você está na trilha Python

    A mesma aula existe em Python 3.12+, na pasta aula04-rag: chunking, embeddings e os três modos de busca — keyword, vetorial e híbrida com reranking — com o mesmo corpus e o mesmo roteiro de sala. A regra de fixar versões no requirements.txt continua valendo.

    Próximo passo

    Rode o console, indexe o corpus e compare os três modos de busca com uma pergunta que usa sinônimos — a diferença entre keyword e vetorial fica evidente em uma tela. Depois rode o roteiro de sala completo e observe a terceira pergunta: é o slide de groundedness. Na aula 5 entramos em RAG end-to-end com avaliação — groundedness, relevância e uma varredura de top-k.

    Dúvidas ou algo que não funcionou? Deixe nos comentários ou abra uma issue no repositório.

  • Capacitação Microsoft AI — Aula 3: Microsoft Foundry, do recurso ao SDK com streaming

    Este é o terceiro de oito artigos que acompanham as aulas da Capacitação Microsoft AI 2026, que Otávio Lourenço da Silva e eu ministramos ao vivo entre agosto e setembro. As gravações continuam no ar; os artigos existem para quem prefere ler, revisar ou copiar o código com calma.

    O que a aula cobriu

    A terceira aula é a aula da plataforma. Passamos pela arquitetura do Microsoft Foundry — a diferença entre recurso e projeto, os papéis de acesso (RBAC), as conexões com AI Search, Storage e Key Vault, o deploy de um modelo pelo portal e a escolha entre Standard e PTU — e depois voltamos ao código para fechar um ciclo que começou na aula 1. O programa desta aula usa o mesmo modelo, a mesma identidade, o mesmo SDK e o mesmo IChatClient da aula de Fundamentos, com uma única diferença: a resposta chega token a token, em vez de inteira, de uma vez só.

    Três ideias para levar

    1. Recurso, projeto e papel: a plataforma antes do código

    No Foundry, o recurso é a unidade de infraestrutura — é nele que os modelos são implantados e que as conexões com outros serviços do Azure são registradas. O projeto é a unidade de trabalho, com endpoint próprio, e é a ele que a aplicação se conecta: o FOUNDRY_ENDPOINT de todas as aulas termina em /api/projects/<projeto>. E o papel que a sua identidade precisa ter é o Foundry User, atribuído no recurso: ser Owner da subscription concede Actions (criar e apagar), mas chamar o modelo exige DataActions. Quem aprende essa separação uma vez para de esbarrar em 403 Forbidden.

    2. Streaming é uma troca de método, não de arquitetura

    O setup é idêntico ao da aula 1 — AIProjectClient autenticado por DefaultAzureCredential, cliente de Responses para o deployment e conversão em IChatClient. A diferença cabe no laço final: GetResponseAsync vira GetStreamingResponseAsync, que devolve um IAsyncEnumerable<ChatResponseUpdate>. Cada atualização já traz o texto em .Text, sem testar tipo nenhum, e o mesmo laço funcionaria contra qualquer outro provedor.

    ChatOptions options = new();
    
    await foreach (ChatResponseUpdate update
        in chatClient.GetStreamingResponseAsync(prompt, options))
    {
        Console.Write(update.Text);              // pedaço de texto
    
        if (update.ConversationId is not null)
        {
            options.ConversationId = update.ConversationId;   // elo da próxima pergunta
        }
    }

    Vale rodar esta demo e a de Fundamentos lado a lado, com a mesma pergunta: a percepção de latência muda sem que nada além do método chamado tenha mudado.

    3. O contexto continua no serviço — e chega junto com o fluxo

    Como na aula 1, o programa não guarda histórico: guarda apenas o ConversationId e o serviço cuida do resto. A sutileza do streaming é que esse id chega junto com as atualizações e só é definitivo no fim, por isso o código guarda o último valor não nulo em vez de assumir que ele veio na primeira. Comparado com a aula 2, onde o histórico vive numa lista no cliente, fica claro que a decisão de quem guarda o contexto é independente da decisão de como a resposta é consumida.

    Antes de rodar

    • .NET SDK 10 e Azure CLI instalados, com az login --tenant <tenant-id> feito no tenant certo.
    • Um recurso Foundry com um modelo implantado e o papel Foundry User atribuído à sua conta — ser Owner da subscription não basta.
    • As variáveis FOUNDRY_ENDPOINT (endpoint do projeto, terminando em /api/projects/<projeto>) e FOUNDRY_MODEL (nome do deployment) no seu launchSettings.json. Um único arquivo serve as três primeiras aulas — basta trocar o nome do perfil.
    • Não altere as versões dos pacotes. O projeto converge para o pivô OpenAI 2.9.1; dotnet add package OpenAI, o Azure.AI.Extensions.OpenAI em prerelease ou o Microsoft.Extensions.AI.OpenAI sem versão compilam sem aviso e quebram em tempo de execução com MissingMethodException. O NoWarn de OPENAI001 no .csproj também não é opcional.

    Se você está na trilha Python

    A mesma aula existe em Python 3.12+: AIProjectClient com DefaultAzureCredential, cliente OpenAI obtido do projeto, stream=True para a resposta token a token e contexto no serviço via previous_response_id. A versão Python vai um pouco além: retry exponencial em erros transientes (429 e 5xx) com tenacity, contagem local de tokens com tiktoken para estimar custo antes de rodar em lote, e saída formatada com rich. As versões ficam fixadas no requirements.txt.

    Próximo passo

    Faça um diff entre o Program.cs desta aula e o da aula 1: as seções de setup são idênticas e a diferença cabe no laço final. Depois, se quiser ver o problema de versões ao vivo, rode dotnet add package OpenAI, compile com sucesso, veja o erro em tempo de execução e desfaça — ensina mais sobre grafo de dependências do que qualquer slide. Na aula 4 entramos em RAG, embeddings e Azure AI Search: como dar ao modelo o contexto da sua empresa sem treinar nada.

    Dúvidas ou algo que não funcionou? Deixe nos comentários ou abra uma issue no repositório.

  • Capacitação Microsoft AI — Aula 2: LLMs e engenharia de prompts

    Segundo artigo da série que acompanha as aulas da Capacitação Microsoft AI 2026. Na aula 1 chegamos ao modelo com a montagem mínima; nesta aula a montagem é exatamente a mesma — o que muda é o que colocamos no contexto.

    O que a aula cobriu

    Como um modelo grande de linguagem funciona por dentro — tokens, probabilidade, janela de contexto — e o que isso significa para quem escreve o prompt. Depois, três técnicas na prática, todas sobre os mesmos três chamados de suporte, para que a comparação seja honesta: chat com histórico no cliente, few-shot e saída estruturada.

    Três ideias para levar

    1. Quem guarda o histórico: o serviço ou o cliente?

    Na aula 1 o programa guardava só um ConversationId e o serviço lembrava a conversa. Aqui fazemos o oposto: uma List<ChatMessage> que cresce a cada turno e é enviada inteira. Mesmo IChatClient, mesmo endpoint, mesma identidade. A escolha não é de tecnologia, é de arquitetura: histórico no cliente dá controle total sobre o que entra no contexto (e sobre o custo em tokens); histórico no serviço simplifica o código e facilita retomar conversas.

    2. Few-shot não é um recurso da API, é uma conversa fictícia

    Em vez de descrever o formato de resposta que você quer, você mostra: monta uma conversa em que o assistente “já respondeu” daquele jeito e entrega como se tivesse acontecido. O modelo continua o padrão. Na demo, zero-shot devolve markdown livre; few-shot devolve Acesso | Alta | ... em uma linha.

    List<ChatMessage> exemplos =
    [
        new(ChatRole.System, "Você classifica chamados de suporte. Responda SEMPRE em uma única linha, no formato: Categoria | Urgência | Resumo."),
        new(ChatRole.User, "O sistema fechou sozinho quando cliquei em salvar."),
        new(ChatRole.Assistant, "Erro | Alta | Aplicação encerra ao salvar."),
        // ... mais dois pares
    ];
    
    List<ChatMessage> mensagens = [.. exemplos, new ChatMessage(ChatRole.User, chamado)];
    var resposta = await chatClient.GetResponseAsync(mensagens);

    3. Saída estruturada: um record em vez de texto solto

    Quando a resposta vai alimentar código — e não uma pessoa — pedir “com jeitinho” não basta. GetResponseAsync<T>() gera um JSON Schema a partir do seu record, envia junto com o prompt e desserializa a resposta. O modelo fica obrigado pelo serviço a produzir JSON válido naquele formato.

    record TriagemChamado(string Categoria, string Urgencia, string Resumo, bool RequerAtencaoImediata);
    
    var resposta = await chatClient.GetResponseAsync<TriagemChamado>(mensagens);
    TriagemChamado triagem = resposta.Result;

    Antes de rodar

    • Tudo o que valia na aula 1: .NET 10, Azure CLI com az login, papel Foundry User, FOUNDRY_ENDPOINT (do projeto) e FOUNDRY_MODEL (nome do deployment).
    • Os pacotes são os mesmos e nas mesmas versões. Microsoft.Extensions.AI e Microsoft.Extensions.AI.OpenAI ficam em 10.4.1 — é a única versão compatível com o OpenAI 2.9.1 que os pacotes Azure exigem. Subir sem --version compila e quebra em runtime.
    • O <NoWarn>OPENAI001</NoWarn> no .csproj não é opcional: AsIChatClient() ainda é experimental e o SDK promove o aviso a erro.

    Se você está na trilha Python

    As três demos existem em Python: histórico numa lista de mensagens, few-shot do mesmo jeito, e saída estruturada com Pydantic no lugar do record. Mesmo AIProjectClient e mesmo endpoint da aula 1.

    Próximo passo

    Rode a demo 2 duas vezes com o mesmo chamado — uma zero-shot, outra few-shot — e compare as respostas. Depois troque um dos exemplos do few-shot e veja como o modelo segue o novo padrão. Na aula 3 entramos no Microsoft Foundry de verdade: recurso, projeto, deploy de modelos e o SDK com resposta em streaming.

    Dúvidas ou algo que não funcionou? Deixe nos comentários ou abra uma issue no repositório.

  • Capacitação Microsoft AI — Aula 1: Fundamentos de IA e o ecossistema Microsoft

    Este é o primeiro de oito artigos que acompanham as aulas da Capacitação Microsoft AI 2026, que Otávio Lourenço da Silva e eu ministramos ao vivo entre agosto e setembro. As gravações continuam no ar; os artigos existem para quem prefere ler, revisar ou copiar o código com calma.

    O que a aula cobriu

    A primeira aula constrói a base que todas as outras usam: o que é IA generativa e onde ela se encaixa no ecossistema Microsoft (Copilot, Microsoft Foundry, Azure), e o caminho mínimo — e correto — entre uma aplicação e um modelo hospedado no Foundry. Saímos da aula com um chat de console funcionando, e com três decisões de arquitetura que se repetem em todo o curso.

    Três ideias para levar

    1. Autenticação sem segredo

    Não existe chave de API no código. O Foundry SDK autentica sempre por Entra ID: DefaultAzureCredential descobre quem você é a partir do ambiente (az login na sua máquina, identidade gerenciada em produção) e o mesmo código roda nos dois lugares sem alteração. Não há segredo para vazar em log, repositório ou print de tela.

    O tropeço clássico vem logo depois: ser Owner da subscription não basta. O Azure separa permissões de gerenciamento (criar e apagar recursos) de permissões de dados (conversar com o modelo). Owner tem as primeiras e nenhuma das segundas — você autentica com sucesso e recebe 403 Forbidden. O papel que resolve é o Foundry User, atribuído no recurso Foundry.

    2. Uma abstração entre você e o fornecedor

    Entramos pelo AIProjectClient (o Foundry SDK), pegamos um cliente de Responses para o deployment do modelo e o convertemos em um IChatClient de Microsoft.Extensions.AI. Daí para cima, o código não menciona mais nem Azure nem OpenAI. Trocar o modelo por um Ollama local é mexer nestas três linhas — e em nada mais.

    AIProjectClient projectClient = new(
    endpoint: new Uri(endpoint),
    tokenProvider: new DefaultAzureCredential());
    ProjectResponsesClient responseClient = projectClient.ProjectOpenAIClient
    .GetProjectResponsesClientForModel(model);
    IChatClient chatClient = responseClient.AsIChatClient(model);

    3. Contexto mantido pelo serviço

    O chat lembra o que foi dito antes, mas o programa não guarda histórico nenhum: ele guarda apenas um ChatOptions.ConversationId e o serviço cuida do resto. Na aula 2 fazemos o oposto — o histórico numa lista que cresce no cliente — com o mesmo IChatClient, justamente para comparar as duas estratégias.

    Antes de rodar

    • .NET SDK 10 e Azure CLI instalados, com az login feito no tenant certo.
    • Um recurso Foundry com um modelo implantado e o papel Foundry User atribuído à sua conta.
    • As variáveis FOUNDRY_ENDPOINT (endpoint do projeto) e FOUNDRY_MODEL (nome do deployment, não o nome comercial do modelo) no seu launchSettings.json.
    • Não altere as versões dos pacotes. O projeto converge para um pivô único (OpenAI 2.9.1); subir qualquer pacote compila e quebra em tempo de execução. O README da aula explica a matriz de versões.

    Se você está na trilha Python

    A mesma aula existe em Python 3.12+: AIProjectClient, cliente OpenAI e contexto no serviço via previous_response_id. Em Python não existe o problema do pivô de versões do .NET, e um único endpoint do projeto serve todas as aulas — mas a regra de fixar versões no requirements.txt continua valendo.

    Próximo passo

    Rode o chat, faça duas perguntas encadeadas e confirme que o modelo lembra a primeira. Depois abra o Program.cs e leia os comentários — eles foram escritos para serem lidos, não só para explicar o código. Na aula 2 entramos em LLMs e engenharia de prompts: contexto no cliente, few-shot e saída estruturada.

    Dúvidas ou algo que não funcionou? Deixe nos comentários ou abra uma issue no repositório.

  • A revolução dos dados

    Este artigo foi publicado em 2019. Ferramentas e versões citadas podem ter mudado desde então; a reflexão permanece.

    Fala galera! Como citei no artigo sobre DDD comecei a programar em Clipper no inicio dos anos 90. Lá eu guardava os dados dos meus sistemas em tabelas dBase, um arquivo por tabela, e seus respectivos índices, um arquivo por índice. Havia uma quantidade mínima de tipo de dados, e principalmente uma limitação no tamanho dos discos. Existia uma forma peculiar de relacionamento, que auxiliava apenas nas buscas de dados relacionados por um índice, mas nada de integridade referencial. E cometiamos um erro, que muitos sistemas cometem até hoje, de destuir a informação anterior em detrimento de mante-la atualizada. O que quero dizer com isto? No meu sistema de vendas o produto de código A00931 foi cadastrado inicialmente com a descrição de Pão de Forma sem casca. A tabela de vendas tinha apenas uma referencia a partir do código, o valor unitário, a quantidade. Um belo dia o produto deixava de ser vendido, e para reaproveitar o código ele era substituído por Suco de maracujá. O que acontecia se eu pedisse um relatório de vendas? Pareceria que eu havia vendido inúmeros sucos, sendo que o produto acabou de chegar. Muitossistemas fazem iso até hoje. Colocam que em segurança dos dados por guardar um log de auditoria com a data e hora do que foi alterado. Mas como eu consulto a informação dentro da linha do tempo? Como ei qual o produto mais vendido, independnete das atualizações que este cadastro sofreu? Justifiquei meu erro da época pela tecnologia e limite limitações da época, aliadas a minha pouca experiencia. Mas o que nos faz continuar errando até hoje? As pessoas não aprenderam nem a importancia dos dados, e levam as formas normais ao extremo. Bancos de dados ‘relacionais muito úteis, e que terão uma longa vida pela frente, é usado como um paradigma mais seguro. Mas como sempre não existe bala de prata. Quando comecie a ver bancos de dados NoSQL em um primeiro momento todas as preocupações e questionamentos me vieram a cabeça. Mas como? Mas e a chave estrangeira? Mas e a consistencia? Fui estudando cada vez mais e me apaixonando pelo que cada tipo de banco de dados faz de melhor, e como o ermo pesistencia poliglota faz sentido e que quem não entendeu isto ainda esta fadado a não só tr um produto de menor qualidade, mas de estar desperdiçando dados importantes para o negócio do seu cliente. E a persistencia poliglota eu extendo não só ao fato de usar diferentes tecnologias d bancos. Cada vez mais precisamos que nossos micro servi;ços, eles aqui novamente, tenham independencia, seus próprios dados, e mecanismos robustos de sincronização, mas com total entendimento e tolerancia a ocasionais inconsistencia. O resultado? Um mar de dados para ser navegado pelos analistas e cientistas, um emaranhado de bits e bytes que ‘Machine Learning transformam em decisões conscientes e negócios sendo mais acertivos e reduzino drasticamente seus custos. Se isto não é uma revolução, preciso de mais dados para descobrir oque é! Até amanhã!
  • Vídeo: Falando sobre Chatbots

    Este artigo foi publicado em 2017. Ferramentas e versões citadas podem ter mudado desde então; a reflexão permanece.

    Fala galera!

    Percebi que não havia publicado este vídeos aqui no blog e para começarmos bem o ano aqui estão eles.

    Como voces vão notar já haviamos dito que os bots eram uma tendencia e no fim do ano várias iniciativas foram divulgadas pelas empresas neste sentido.

    Acredito que este ano de 2017 veremos ainda mais evoluções nesta área e a forma como interagimos com as máquinas passará por uma grande revolução muito em breve.

    Aproveitem os vídeos:

    Até a próxima!

  • The Twelve-factor App na plataforma Microsoft – Code Base

    Este artigo foi publicado em 2016. Ferramentas e versões citadas podem ter mudado desde então; a reflexão permanece.

    Fala galera!

    Conforme falei no primeiro artigo da série vou falar como implementamos The Twelve-factor App na plataforma Microsoft.

    Se não se lembra apresentamos os fatores neste vídeo e neste vídeo então assiste lá para não ficar perdido.

    A importancia de se ter um repositório de código

    Acho que exploramos bem o tema nos vídeos mas em resumo ter uma baseline é indispensável para que possamos ter todo rastreamento de alterações em nosso produto de forma a saber por que, quando, como e por quem algo foi feito.

    Isto não é caça bruxas mas entender o porque de algo ter sido feito é importante para a melhoria contínua do processo.

    Além disto uma base de código confiável permite que o produto volte rapidamente a um determinado momento no tempo o que é indispensável para se recuperar de catástrofes bem como fazer depurações mais precisas já que a versão do código acaba sendo identica a que estava em produção no momento da. falha.

    Por último mas não menos importante dependendo do segmento de negócio regulamentações e processos de auditoria impedem que o software seja desenvolvido sem estas características.

    Dentro da plataforma Microsoft

    Originados do extinto Microsoft Source Safe a Microsoft oferece toda uma completa solução de ALM (Ciclo de Vida de Aplicação) em dois sabores:

    • VSTS ou Visual Studio Team Services uma solução em núvem oferecida como SAAS (Software como Serviço);

    • TFS ou Team Foundation Services uma solução para instalação on premise; Como é de se esperar o modelo em nuvem recebe atualizações cnstantes mais rapidamente, mas ambos oferecem praticamente os mesmos recursos quando em versões parelhas.

    • Gestão total de código-fonte das aplicações; Gestão de projetos de desenvolvimento de software utilizando-se de SCRUM, Agile ou CMMI com total possibilidade de personalização do processo; Processos automatizados de build e deploy; Gestão total de testes; E muito mais …;

    E quando falamos de gestão de códigos fontes também temos a disposição duas opções:

    • TFVC solução proprietária desenvolvida pela Microsoft e que se baseia no modelo centralizado;
    • git: sistema de controle de versão desenvolvido por Linus Torvalds criador do sistema operacional Linux e amplamente utilizado pelo mundo open source;

    Ambas as opções oferecem vantagens e desvantagens e não é objetivo deste artigo discutí-las mas deixo a seguir boas referencias de como trabalhar com cada um deles:

    Já em relação a separação dos projetos, módulos ou componentes seja lá como a tecnologia adotada e/ou sua empresa nomeie a componentização da aplicação a plataforma da Microsoft oferece um grande nível de personalização sendo o mais comum a utilização de Team Collections e Team Projects. Mais informações podem ser obtidas neste guia.

    Conclusão

    A plataforma Microsoft está totalmente preparada para atender ao primeiro fator sem o menor esforço e com amplas possibilidades de personalização dos fluxos de trabalho e alta conectividade com as mais diversas ferramentas de desenvolvimento não se limitando apenas aquelas desenvolvidas pela empresa.

    Existe conteúdo abundante na internet sobre como utilizar da melhor maneira estas ferramentas por isto deixarei aqui mais algumas referencias:

    Até a próxima!