Agent Framework

Spread the love

En el mundo del desarrollo moderno, los agentes inteligentes están ganando terreno como una forma poderosa de automatizar tareas, integrar servicios y construir flujos conversacionales más humanos. En esta entrada quiero compartir mi experiencia explorando Agent Framework, una herramienta que permite crear agentes modulares, extensibles y altamente personalizables, y cómo he comenzado a experimentar con ella en mi propio repositorio: Demo Agent Framework

¿Qué es Agent Framework?

Agent Framework es una arquitectura que facilita la creación de agentes inteligentes capaces de interactuar con múltiples herramientas, razonar sobre tareas complejas y adaptarse a distintos contextos. Su diseño modular permite definir:

  • Memoria: para que el agente recuerde información relevante.
  • Herramientas: como buscadores, generadores de imágenes o analizadores de datos.
  • Orquestadores: que deciden qué acción tomar en cada momento.
  • Prompting inteligente: para guiar la conversación y mantener coherencia.

Este enfoque se alinea con la tendencia actual de construir agentes que no solo respondan, sino que actúen.

Demo: Hola Mundo en Modo Stream

using Azure.AI.OpenAI;
using demo_agent_framework.Config;
using Microsoft.Agents.AI;
using OpenAI;
using System;
using System.ClientModel;
using System.Threading.Tasks;

namespace demo_agent_framework.Demos
{
    public static class ModoStream
    {
        public static async Task RunAsync()
        {
            Console.WriteLine();
            Console.WriteLine("=== Demo 2: Hola Mundo con Azure OpenAI y Stream ===");

            // Los valores esperados son:
            // - AZURE_OPENAI_ENDPOINT: URL del endpoint de Azure OpenAI (por ejemplo https://tuservidor.openai.azure.com/)
            // - AZURE_OPENAI_KEY: clave API para autenticar peticiones al servicio
            // - AZURE_OPENAI_MODEL: nombre del despliegue del modelo a usar (deployment name)
            var endpoint = Credentials.Endpoint;
            var apiKey = Credentials.ApiKey;
            var model = Credentials.Model;
            var prompt = "¿Qué es el modo stream en los LLMs y para qué sirve?";
            // Crear cliente y agente usando las librerías de Azure/Microsoft.
            // AzureOpenAIClient: cliente de alto nivel que encapsula la comunicación con el servicio Azure OpenAI.
            // ApiKeyCredential: credencial simple que envía la API key en las cabeceras de la petición.
            // GetChatClient(model).CreateAIAgent(): obtiene un cliente de chat para el despliegue especificado
            // y crea una instancia de AIAgent que proporciona métodos para ejecutar prompts y flujos de agente.
            AzureOpenAIClient client = new AzureOpenAIClient(new Uri(endpoint), new ApiKeyCredential(apiKey));
            AIAgent agent = client.GetChatClient(model).CreateAIAgent();

            //NUEVO: Ejecutar una petición al agente en modo streaming.
            await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(prompt))
            {
                Console.Write(update);
            }

            Console.WriteLine();
            Console.WriteLine("Demostración finalizada. Pulsa Enter para volver al menú principal.");
            Console.ReadLine();
        }
    }
}

 

Demo con Ollama

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OllamaSharp;

namespace demo_agent_framework.Demos
{
    public static class Ollama
    {
        public static async Task RunAsync()
        {
            Console.WriteLine();
            Console.WriteLine("=== Demo 4 - Ollama ===");

            var model = "llama3.1:8b";
            var prompt = "Que son los modelos locales con Ollama";
            var endpoint = "http://localhost:11434";
            try
            {
                IChatClient client = new OllamaApiClient(endpoint, model);
                AIAgent agent = new ChatClientAgent(client);

                await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(prompt))
                {
                    Console.Write(update);
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine("Debe tener instalado Ollama y modelos locales");
                Console.WriteLine($"Error: {ex.Message}");
            }

            Console.WriteLine("Demostración finalizada. Pulsa Enter para volver al menú principal.");
            Console.ReadLine();
        }
    }
}

 

Demo con Foundry

using System;
using System.Threading.Tasks;
using System.IO;
using Azure.Core;
using Azure;
using Azure.AI.Agents.Persistent;
using Azure.Identity;
using Microsoft.Agents.AI;
using demo_agent_framework.Config;

namespace demo_agent_framework.Demos
{
    public static class AiFoundryAgent
    {
        public static async Task RunAsync()
        {
            // Encabezado de la demo
            Console.WriteLine();
            Console.WriteLine("=== Demo 3 - AI Foundry Agent ===");

            // --------------------------------------------------
            // Configuración básica de la demo
            // --------------------------------------------------
            // Endpoint del servicio de Persistent Agents (puedes cambiar por tu endpoint o leerlo desde .env)
            const string endpoint = "https://bri-ai-openai.services.ai.azure.com/api/projects/AIBRI";
            // El modelo se lee desde las credenciales centralizadas (Config/Credentials.cs)
            var model = Credentials.Model;

            // Prompt de ejemplo para ejecutar en el agente
            var prompt = "Ayudarme a crear un agente para mi tienda de informática";

            // Metadatos del agente que queremos crear (nombre, descripción, system prompt)
            var aiFoundryAgentName = "AgenteBri";
            var aiFoundryAgentDescription = "Agente de prueba para la tienda de informática de Bri";
            var aiFoundryAgentSystemPrompt = "Eres un agente experto en tiendas de informática y ayudas a los clientes a encontrar productos y resolver dudas técnicas.";

            // --------------------------------------------------
            // Selección de credencial para autenticación con Azure
            // --------------------------------------------------
            // Preferimos credenciales de Service Principal (ClientSecretCredential) si están definidas en .env
            // Si no, hacemos fallback a AzureCliCredential (requiere `az login`).
            TokenCredential credential;
            var clientId = Credentials.ClientId;
            var tenantId = Credentials.TenantId;
            var clientSecret = Credentials.ClientSecret;

            if (!string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(tenantId) && !string.IsNullOrEmpty(clientSecret))
            {
                // Usar credenciales de aplicación (Service Principal)
                Console.WriteLine("Usando ClientSecretCredential con credenciales de aplicación.");
                credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
            }
            else
            {
                // Fallback a credenciales del CLI de Azure (usuario debe haber hecho `az login`)
                Console.WriteLine("Usando AzureCliCredential. Asegúrate de haber hecho 'az login' previamente.");
                credential = new AzureCliCredential();
            }

            // --------------------------------------------------
            // Crear cliente de Persistent Agents con la credencial seleccionada
            // --------------------------------------------------
            PersistentAgentsClient client = new PersistentAgentsClient(endpoint, credential);

            try
            {
                // --------------------------------------------------
                // Almacenamiento local simple para evitar crear agentes duplicados
                // - Guardamos el Id del agente en .agents/{name}.id la primera vez que lo creamos
                // - En ejecuciones posteriores, leemos ese fichero para recuperar el Id y usar el agente existente
                // --------------------------------------------------
                var repoRoot = Directory.GetCurrentDirectory();
                var agentsDir = Path.Combine(repoRoot, ".agents");
                Directory.CreateDirectory(agentsDir);
                var agentIdFile = Path.Combine(agentsDir, aiFoundryAgentName + ".id");

                AIAgent agent = null;

                // 1) Intentar usar Id guardado si existe
                if (File.Exists(agentIdFile))
                {
                    var existingId = File.ReadAllText(agentIdFile).Trim();
                    if (!string.IsNullOrEmpty(existingId))
                    {
                        try
                        {
                            // Obtener AIAgent por Id guardado
                            agent = await client.GetAIAgentAsync(existingId);
                            Console.WriteLine($"Agente con nombre '{aiFoundryAgentName}' ya existe (id guardado). Id: {existingId}");
                        }
                        catch
                        {
                            // Si no se puede obtener por id (p. ej. borrado o id inválido), continuamos para crear uno nuevo
                            Console.WriteLine("Id de agente guardado no válido o agente no encontrado. Se intentará crear uno nuevo.");
                            agent = null;
                        }
                    }
                }

                // 2) Si no encontramos un agente por id guardado, intentar buscar por nombre (opcional)
                //    NOTA: el SDK puede no exponer una lista directa; si tu servicio lo permite puedes implementar
                //    una búsqueda por nombre aquí. Para simplicidad usamos el fichero local + creación si no existe.

                // 3) Si todavía no tenemos un AIAgent, crear uno nuevo
                if (agent == null)
                {
                    // Crear el agente persistente en el servicio de administración
                    var createResponse = await client.Administration.CreateAgentAsync(
                        model,
                        aiFoundryAgentName,
                        aiFoundryAgentDescription,
                        aiFoundryAgentSystemPrompt
                    );

                    var createdMeta = createResponse.Value;
                    Console.WriteLine($"Agente creado. Id: {createdMeta.Id}");

                    // Guardar id localmente para próximas ejecuciones
                    try
                    {
                        File.WriteAllText(agentIdFile, createdMeta.Id);
                    }
                    catch
                    {
                        // Ignorar errores al escribir el fichero, no es crítico para la demo
                    }

                    // Obtener AIAgent a partir del Id creado
                    agent = await client.GetAIAgentAsync(createdMeta.Id);
                }

                // --------------------------------------------------
                // Ejecutar la interacción con el agente (usando AIAgent obtenido o creado)
                // --------------------------------------------------
                if (agent is not null)
                {
           

                    // Ejecutar en modo streaming para recibir actualizaciones parciales
                    await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(prompt))
                    {
                        // Cada 'update' puede contener texto parcial o eventos; lo mostramos en consola
                        Console.Write(update);
                    }
                }
                else
                {
                    Console.WriteLine("No se pudo obtener ni crear el agente. Revisa permisos y configuración.");
                }
            }
            catch (Exception ex)
            {
                // Manejo de errores genérico: mostrar detalle para depuración
                Console.WriteLine("Error en la operación de agentes persistentes:");
                Console.WriteLine(ex.ToString());
            }

            // Fin de la demo: esperar que el usuario pulse Enter para volver al menú
            Console.WriteLine();
            Console.WriteLine("Demostración finalizada. Pulsa Enter para volver al menú principal.");
            Console.ReadLine();
        }
    }
}

 

Demo con Tools

using Azure.AI.OpenAI;
using demo_agent_framework.Config;
using Microsoft.Extensions.AI;
using OpenAI;
using System;
using System.ClientModel;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace demo_agent_framework.Demos
{
    public static class AgentTools
    {
        public static async Task RunAsync()
        {
            Console.WriteLine("=== Demo 6: Herramientas funcionales con Agent Tools ===");

            var endpoint = Credentials.Endpoint;
            var apiKey = Credentials.ApiKey;
            var model = Credentials.Model;
            var prompt = "Eres un asistente útil que puede consultar el clima y recomendar platos típicos.";    

            var client = new AzureOpenAIClient(new Uri(endpoint), new ApiKeyCredential(apiKey));

            // Tool 1: Clima
            [Description("Obtiene el clima para una ciudad dada.")]
            static string ObtenerClima([Description("La ciudad para consultar el clima.")] string ciudad)
                => $"El clima en {ciudad} es nublado con una máxima de 15°C.";

            // Tool 2: Plato típico
            [Description("Recomienda un plato típico según la ciudad.")]
            static string RecomendarPlato([Description("Ciudad para recomendar comida.")] string ciudad)
                => ciudad.ToLower() switch
                {
                    "madrid" => "Cocido madrileño",
                    "lisboa" => "Bacalhau à Brás",
                    "parís" => "Coq au vin",
                    _ => $"No tengo datos sobre platos típicos en {ciudad}."
                };

            // Crear agente con ambas herramientas
            var agent = client.GetChatClient(model).CreateAIAgent(
                instructions: prompt,
                tools: [
                    AIFunctionFactory.Create(ObtenerClima),
            AIFunctionFactory.Create(RecomendarPlato)
                ]
            );

            // Leer pregunta desde consola
            Console.Write("\nEscribe tu pregunta: ");
            var pregunta = Console.ReadLine();

            // Ejecutar en modo streaming
            Console.WriteLine("\nRespuesta del agente:\n");
            await foreach (var update in agent.RunStreamingAsync(pregunta))
                Console.Write(update);

            Console.WriteLine("\n\nPulsa Enter para continuar.");
            Console.ReadLine();
        }
    }
}

 

Continuaré probando el producto y creando nuevas pruebas de conceptos para más información consulte el repositorio oficial:  https://github.com/microsoft/agent-framework

 

Deja un comentario