10-02-02 — Desenvolvimento em .NET, JavaScript, Python
TL;DR
O M365 Agents SDK tem suporte first-class para .NET (recomendado para equipes Microsoft), JavaScript/TypeScript e Python. O padrão é o mesmo nos três: criar um AgentApplication, registrar handlers de atividade e expor um endpoint HTTP. Em .NET, a integração com Semantic Kernel e Azure OpenAI é nativa. Em Python, a integração com LangChain é simples.
Desenvolvimento em .NET (recomendado para Impar)
Setup inicial
// 1. Criar projeto
// dotnet new webapi -n MeuAgente
// dotnet add package Microsoft.Agents.Hosting.AspNetCore
// Program.cs
using Microsoft.Agents.Hosting.AspNetCore;
using Microsoft.SemanticKernel;
var builder = WebApplication.CreateBuilder(args);
// Registra Semantic Kernel
builder.Services.AddKernel()
.AddAzureOpenAIChatCompletion(
deploymentName: "gpt-4o",
endpoint: builder.Configuration["AzureOpenAI:Endpoint"],
apiKey: builder.Configuration["AzureOpenAI:ApiKey"]);
// Registra o agente
builder.AddAgent();
var app = builder.Build();
app.MapControllers();
app.MapAgentEndpoint("/api/messages");
app.Run();
// MeuAgente.cs
using Microsoft.Agents.BotBuilder;
using Microsoft.Agents.Core.Models;
using Microsoft.SemanticKernel;
public class MeuAgente : ActivityHandler
{
private readonly Kernel _kernel;
public MeuAgente(Kernel kernel)
{
_kernel = kernel;
}
protected override async Task OnMessageActivityAsync(
ITurnContext<IMessageActivity> turnContext,
CancellationToken cancellationToken)
{
var userMessage = turnContext.Activity.Text;
// Integração com Semantic Kernel
var response = await _kernel.InvokePromptAsync(
$"Você é um assistente especializado da Impar. Responda: {userMessage}");
await turnContext.SendActivityAsync(
MessageFactory.Text(response.ToString()),
cancellationToken);
}
protected override async Task OnMembersAddedAsync(
IList<ChannelAccount> membersAdded,
ITurnContext<IConversationUpdateActivity> turnContext,
CancellationToken cancellationToken)
{
foreach (var member in membersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
await turnContext.SendActivityAsync(
MessageFactory.Text("Olá! Como posso ajudar?"),
cancellationToken);
}
}
}
}
Estado de conversação
// Gerenciamento de estado com Azure Blob Storage
builder.Services.AddSingleton<IStorage>(
new BlobsStorage(
builder.Configuration["Storage:ConnectionString"],
"agent-state"));
builder.Services.AddSingleton<ConversationState>();
builder.Services.AddSingleton<UserState>();
// No agente, use state para memória de curta duração
public class MeuAgente : ActivityHandler
{
private readonly ConversationState _conversationState;
private readonly IStatePropertyAccessor<ConversationData> _conversationDataAccessor;
public MeuAgente(ConversationState conversationState)
{
_conversationState = conversationState;
_conversationDataAccessor = conversationState
.CreateProperty<ConversationData>("ConversationData");
}
}
Desenvolvimento em JavaScript/TypeScript
// Mesmo padrão, mas em TypeScript
// npm install @microsoft/agents-botbuilder
import { AgentApplication, TurnContext } from "@microsoft/agents-botbuilder";
const agent = new AgentApplication();
agent.message("/help", async (context: TurnContext) => {
await context.sendActivity("Comandos disponíveis: /help, /status, /tickets");
});
agent.message(/.*/i, async (context: TurnContext) => {
// Handler genérico — chama seu LLM
const response = await callAzureOpenAI(context.activity.text);
await context.sendActivity(response);
});
export default agent;
Desenvolvimento em Python
# pip install microsoft-agents-botbuilder
from microsoft.agents.botbuilder import ActivityHandler, TurnContext
from microsoft.agents.core.models import Activity
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
class MeuAgente(ActivityHandler):
def __init__(self, kernel: Kernel):
self.kernel = kernel
async def on_message_activity(self, turn_context: TurnContext):
user_message = turn_context.activity.text
# Usa Semantic Kernel Python
result = await self.kernel.invoke_prompt(
f"Assistente Impar. Responda: {user_message}"
)
await turn_context.send_activity(str(result))
Qual linguagem escolher?
- .NET — Se sua equipe é .NET, sem discussão. Melhor suporte, mais exemplos, integração nativa com SK e Azure
- Python — Se o agente é pesado em ML/data science ou usa modelos locais (Hugging Face)
- JavaScript — Se o agente precisa rodar em Azure Functions ou edge (serverless)
Adaptive Cards em .NET
// Enviando Adaptive Card como resposta
var card = new AdaptiveCard(new AdaptiveSchemaVersion(1, 5))
{
Body = new List<AdaptiveElement>
{
new AdaptiveTextBlock { Text = "Ticket criado!", Size = AdaptiveTextSize.Large },
new AdaptiveFactSet
{
Facts = new List<AdaptiveFact>
{
new AdaptiveFact("Número:", "TK-20250429"),
new AdaptiveFact("Status:", "Aberto"),
new AdaptiveFact("SLA:", "4 horas")
}
}
}
};
var attachment = new Attachment
{
ContentType = AdaptiveCard.ContentType,
Content = card
};
await turnContext.SendActivityAsync(
MessageFactory.Attachment(attachment),
cancellationToken);
Como isso se conecta
- 10-02-03 — Multi-agent: cada agente especializado é buildado com esse mesmo padrão
- 10-03-01 — O endpoint /api/messages é registrado no Azure Bot Service para publicação
- Módulo 9 — Semantic Kernel é o orquestrador usado dentro do ActivityHandler