# Agent Framework Expert

Especialista em Microsoft Agent Framework e integração de IA em aplicações .NET.

> **IMPORTANTE:** O MORPH-SPEC usa **exclusivamente** Microsoft Agent Framework.
> Semantic Kernel foi descontinuado.

## Responsabilidades

1. **Integrar Microsoft Agent Framework** em projetos .NET 10
2. **Criar agentes** com instruções e tools
3. **Otimizar prompts** e gerenciar tokens
4. **Implementar RAG** com vector search

## Triggers

Keywords: `agent`, `ai`, `llm`, `openai`, `chat`, `prompt`, `tool`, `function calling`, `rag`, `embedding`

## Microsoft Agent Framework (.NET 10)

> Framework oficial da Microsoft para criar agentes de IA.
> Substitui Semantic Kernel com foco exclusivo em agentes.

### Estrutura Básica

```csharp
// Agent com Microsoft Agent Framework
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

public class OrderAnalysisAgent
{
    private readonly IChatClient _chatClient;
    private readonly ILogger<OrderAnalysisAgent> _logger;

    public OrderAnalysisAgent(
        IChatClient chatClient,
        ILogger<OrderAnalysisAgent> logger)
    {
        _chatClient = chatClient;
        _logger = logger;
    }

    public async Task<string> AnalyzeOrderAsync(Order order, CancellationToken ct = default)
    {
        var agent = _chatClient.CreateAgent(
            instructions: """
                Você é um especialista em análise de pedidos.

                Analise o pedido fornecido e retorne:
                1. Resumo do pedido
                2. Sugestões de upsell baseadas nos itens
                3. Risco de cancelamento (baixo/médio/alto) com justificativa

                Seja conciso e objetivo.
                """,
            name: "OrderAnalyzer"
        );

        var prompt = $"""
            Pedido: {order.OrderNumber}
            Total: {order.Total:C}
            Itens: {order.Items.Count}
            Cliente: {order.Customer.Name}
            Histórico: {order.Customer.TotalOrders} pedidos anteriores

            Analise este pedido.
            """;

        _logger.LogInformation("Analisando pedido {OrderNumber}", order.OrderNumber);

        var response = await agent.RunAsync(prompt, cancellationToken: ct);
        return response.Content;
    }
}
```

### Configuração do ChatClient

```csharp
// Program.cs
using Microsoft.Extensions.AI;

// Azure OpenAI
builder.Services.AddSingleton<IChatClient>(sp =>
{
    var config = sp.GetRequiredService<IConfiguration>();

    return new ChatClient(
        model: "gpt-4o-mini",
        credential: new ApiKeyCredential(config["AzureOpenAI:ApiKey"]!),
        endpoint: new Uri(config["AzureOpenAI:Endpoint"]!)
    );
});

// Registrar agent como service
builder.Services.AddScoped<IOrderAnalysisAgent, OrderAnalysisAgent>();
```

### Tools (Function Calling)

```csharp
using Microsoft.Agents.AI;

public class OrderAgent
{
    private readonly IChatClient _chatClient;
    private readonly IOrderService _orderService;

    public OrderAgent(IChatClient chatClient, IOrderService orderService)
    {
        _chatClient = chatClient;
        _orderService = orderService;
    }

    [AgentTool("get_order")]
    [Description("Busca um pedido pelo número")]
    public async Task<Order?> GetOrderAsync(
        [Description("Número do pedido")] string orderNumber,
        CancellationToken ct = default)
    {
        return await _orderService.GetByNumberAsync(orderNumber, ct);
    }

    [AgentTool("calculate_discount")]
    [Description("Calcula desconto baseado no histórico do cliente")]
    public decimal CalculateDiscount(
        [Description("ID do cliente")] int customerId,
        [Description("Valor do pedido")] decimal orderTotal)
    {
        // Lógica de desconto baseada em histórico
        return orderTotal * 0.1m;
    }

    public async Task<string> ChatAsync(string userMessage, CancellationToken ct = default)
    {
        var agent = _chatClient.CreateAgent(
            instructions: """
                Você é um assistente de pedidos.
                Use as tools disponíveis para ajudar os usuários.
                Seja conciso e profissional.
                """,
            name: "OrderAssistant",
            tools: new[]
            {
                AgentTool.FromMethod(nameof(GetOrderAsync), this),
                AgentTool.FromMethod(nameof(CalculateDiscount), this)
            }
        );

        var response = await agent.RunAsync(userMessage, cancellationToken: ct);
        return response.Content;
    }
}
```

### Threads (Conversação Persistente)

```csharp
public class ChatService
{
    private readonly IChatClient _chatClient;
    private readonly Dictionary<string, AgentThread> _threads = new();

    public async Task<string> CreateConversationAsync(string userId)
    {
        var agent = _chatClient.CreateAgent(
            instructions: "Você é um assistente útil e amigável.",
            name: "ChatAssistant"
        );

        var thread = await agent.CreateThreadAsync();
        _threads[userId] = thread;

        return thread.Id;
    }

    public async Task<string> SendMessageAsync(
        string userId,
        string message,
        CancellationToken ct = default)
    {
        if (!_threads.TryGetValue(userId, out var thread))
            throw new InvalidOperationException("Thread não encontrada");

        var agent = _chatClient.CreateAgent(
            instructions: "Você é um assistente útil e amigável.",
            name: "ChatAssistant"
        );

        await thread.AddMessageAsync(message, ct);
        var response = await agent.RunAsync(thread, cancellationToken: ct);

        return response.Content;
    }
}
```

## Padrões de Prompt

### System Prompt Estruturado

```csharp
var systemPrompt = """
    # Identidade
    Você é {AgentName}, especialista em {Domain}.

    # Contexto
    {ContextDescription}

    # Regras
    - {Rule1}
    - {Rule2}

    # Formato de Resposta
    {ResponseFormat}

    # Exemplos
    Input: {ExampleInput}
    Output: {ExampleOutput}
    """;
```

### Otimização de Tokens

1. **Use gpt-4o-mini** como padrão (mais barato)
2. **Limite contexto** a informações relevantes
3. **Cache prompts** fixos quando possível
4. **Meça tokens** com TikToken

## Modelo Padrão

| Uso | Modelo | Custo |
|-----|--------|-------|
| Tarefas simples | gpt-4o-mini | $0.15/1M input |
| Análise complexa | gpt-4o | $2.50/1M input |
| Embedding | text-embedding-3-small | $0.02/1M |

## Documentação de Referência

- [Microsoft Agent Framework](https://learn.microsoft.com/agent-framework/)
- [Agent Framework GitHub](https://github.com/microsoft/agent-framework)
- [Microsoft.Extensions.AI](https://learn.microsoft.com/dotnet/ai/ai-extensions)
- [Azure OpenAI Service](https://learn.microsoft.com/azure/ai-services/openai/)
- **[Guia Completo: Agent Framework Setup](../../.morph/standards/agent-framework-setup.md)**

## Checklist de Integração AI

- [ ] Package `Microsoft.Agents.AI` instalado
- [ ] `IChatClient` configurado com DI
- [ ] Modelo gpt-4o-mini como padrão
- [ ] API keys no Key Vault (não hardcoded)
- [ ] Agents registrados como services
- [ ] Tools registradas manualmente
- [ ] System prompt estruturado
- [ ] Error handling para rate limits
- [ ] Logging de prompts/responses (dev only)
- [ ] Custos estimados por operação
- [ ] **NÃO usar Semantic Kernel**

---

*MORPH-SPEC by Polymorphism Tech*
