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.
- ▶️ Gravação da aula e playlist completa no YouTube
- 💻 Código da aula (.NET) · versão Python
- 📑 Slides em PDF
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) eFOUNDRY_MODEL(nome do deployment). - Os pacotes são os mesmos e nas mesmas versões.
Microsoft.Extensions.AIeMicrosoft.Extensions.AI.OpenAIficam em 10.4.1 — é a única versão compatível com oOpenAI 2.9.1que os pacotes Azure exigem. Subir sem--versioncompila e quebra em runtime. - O
<NoWarn>OPENAI001</NoWarn>no.csprojnã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.
Deixe um comentário