<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Dotnet | The .NET Blog</title><link>https://thedotnetblog.com/es/tags/dotnet/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>es</language><managingEditor>@thedotnetblog (The .NET Blog)</managingEditor><webMaster>@thedotnetblog</webMaster><lastBuildDate>Mon, 11 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/es/tags/dotnet/index.xml" rel="self" type="application/rss+xml"/><item><title>SDD Conference 2026</title><link>https://thedotnetblog.com/es/events/sdd-conference-2026/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/es/events/sdd-conference-2026/</guid><description>Una conferencia de 5 días sobre desarrollo de software en el Barbican Centre de Londres con 78 sesiones y 14 talleres sobre arquitectura, .NET, IA, Azure, DevOps y más.</description><content:encoded>&lt;p&gt;&lt;strong&gt;SDD 2026&lt;/strong&gt; se celebra del &lt;strong&gt;11 al 15 de mayo de 2026&lt;/strong&gt; en el &lt;strong&gt;Barbican Centre de Londres&lt;/strong&gt;. La conferencia principal de 3 días es de martes a jueves, con talleres opcionales de día completo el lunes y el viernes.&lt;/p&gt;
&lt;p&gt;Con &lt;strong&gt;78 sesiones&lt;/strong&gt; y &lt;strong&gt;14 talleres&lt;/strong&gt;, es una de las conferencias más completas para desarrolladores en Europa.&lt;/p&gt;
&lt;h2 id="temas"&gt;Temas&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Pensamiento Arquitectónico&lt;/li&gt;
&lt;li&gt;Código Funcional en C# 13&lt;/li&gt;
&lt;li&gt;Diseño Serverless&lt;/li&gt;
&lt;li&gt;IA Semántica&lt;/li&gt;
&lt;li&gt;Azure Kubernetes Services&lt;/li&gt;
&lt;li&gt;Estrategias Lean DevOps&lt;/li&gt;
&lt;li&gt;The Model Context Protocol (MCP)&lt;/li&gt;
&lt;li&gt;IA Agéntica en .NET&lt;/li&gt;
&lt;li&gt;Refactorizando el Monolito&lt;/li&gt;
&lt;li&gt;Programar Más Rápido con LLMs&lt;/li&gt;
&lt;li&gt;Criptografía en un Mundo Post-Cuántico&lt;/li&gt;
&lt;li&gt;Desarrollo Local First&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ponentes"&gt;Ponentes&lt;/h2&gt;
&lt;p&gt;Elenco de primer nivel incluyendo a &lt;strong&gt;Kevlin Henney&lt;/strong&gt;, &lt;strong&gt;Neal Ford&lt;/strong&gt;, &lt;strong&gt;Sander Hoogendoorn&lt;/strong&gt;, &lt;strong&gt;Andrew Clymer&lt;/strong&gt;, &lt;strong&gt;Jacqui Read&lt;/strong&gt;, &lt;strong&gt;Christian Weyer&lt;/strong&gt;, &lt;strong&gt;Jeff Prosise&lt;/strong&gt;, &lt;strong&gt;Jules May&lt;/strong&gt;, &lt;strong&gt;Oliver Sturm&lt;/strong&gt; y &lt;strong&gt;Raju Gandhi&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="entradas-e-información"&gt;Entradas e información&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sddconf.com/"&gt;Sitio web del evento&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sddvault.s3.amazonaws.com/assets/SDD_2026_schedule.pdf"&gt;PDF con la agenda completa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sddconf.com/register"&gt;Opciones de registro&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El 98% de los asistentes de SDD 2025 calificaron la experiencia general como buena, muy buena o excelente.&lt;/p&gt;</content:encoded></item><item><title>Hooks de azd en Python, TypeScript y .NET: adiós a los scripts de shell</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/azd-hooks-python-javascript-typescript-dotnet/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/azd-hooks-python-javascript-typescript-dotnet/</guid><description>La CLI de Azure Developer ahora permite escribir hooks en Python, JavaScript, TypeScript o .NET. Se acabó el cambio de contexto a Bash solo para ejecutar un script de migración.</description><content:encoded>&lt;p&gt;&lt;em&gt;Esta publicación fue traducida automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/azd-hooks-python-javascript-typescript-dotnet/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Si alguna vez has tenido un proyecto completamente en .NET y aun así tuviste que escribir scripts Bash solo para los hooks de azd, conoces bien ese dolor. ¿Por qué cambiar a sintaxis de shell en un paso de pre-provisioning cuando todo lo demás en el proyecto es C#?&lt;/p&gt;
&lt;p&gt;Esa frustración tiene solución oficial. La Azure Developer CLI &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-multi-language-hooks/"&gt;acaba de lanzar soporte multi-lenguaje para hooks&lt;/a&gt;, y es exactamente tan bueno como suena.&lt;/p&gt;
&lt;h2 id="hooks-brevemente-por-si-no-los-conoces"&gt;Hooks, brevemente, por si no los conoces&lt;/h2&gt;
&lt;p&gt;Los hooks son scripts que se ejecutan en puntos clave del ciclo de vida de &lt;code&gt;azd&lt;/code&gt; — antes del provisioning, después del despliegue, y más. Se definen en &lt;code&gt;azure.yaml&lt;/code&gt; y permiten inyectar lógica personalizada sin modificar la CLI.&lt;/p&gt;
&lt;p&gt;Antes solo se admitían Bash y PowerShell. Ahora puedes usar &lt;strong&gt;Python, JavaScript, TypeScript o .NET&lt;/strong&gt; — y &lt;code&gt;azd&lt;/code&gt; se encarga del resto automáticamente.&lt;/p&gt;
&lt;h2 id="cómo-funciona-la-detección"&gt;Cómo funciona la detección&lt;/h2&gt;
&lt;p&gt;Simplemente apuntas el hook a un archivo y &lt;code&gt;azd&lt;/code&gt; infiere el lenguaje por la extensión:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;preprovision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/setup.py&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postdeploy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/seed.ts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postprovision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/migrate.cs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Eso es todo. Sin config adicional. Si la extensión es ambigua, puedes añadir &lt;code&gt;kind: python&lt;/code&gt; (o el que corresponda) para especificarlo explícitamente.&lt;/p&gt;
&lt;h2 id="detalles-importantes-por-lenguaje"&gt;Detalles importantes por lenguaje&lt;/h2&gt;
&lt;h3 id="python"&gt;Python&lt;/h3&gt;
&lt;p&gt;Coloca un &lt;code&gt;requirements.txt&lt;/code&gt; o &lt;code&gt;pyproject.toml&lt;/code&gt; junto al script (o en cualquier directorio padre) y &lt;code&gt;azd&lt;/code&gt; crea un entorno virtual, instala dependencias y ejecuta el script:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hooks/
├── setup.py
└── requirements.txt
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sin gestión manual de virtualenv. &lt;code&gt;azd&lt;/code&gt; busca hacia arriba desde el script el archivo de proyecto más cercano.&lt;/p&gt;
&lt;h3 id="javascript-y-typescript"&gt;JavaScript y TypeScript&lt;/h3&gt;
&lt;p&gt;El mismo patrón — pon un &lt;code&gt;package.json&lt;/code&gt; cerca del script y &lt;code&gt;azd&lt;/code&gt; ejecutará &lt;code&gt;npm install&lt;/code&gt; primero. Para TypeScript, usa &lt;code&gt;npx tsx&lt;/code&gt; sin paso de compilación ni &lt;code&gt;tsconfig.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hooks/
├── seed.ts
└── package.json
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;¿Quieres usar pnpm o yarn? Hay una opción &lt;code&gt;config.packageManager&lt;/code&gt; para eso.&lt;/p&gt;
&lt;h3 id="net"&gt;.NET&lt;/h3&gt;
&lt;p&gt;Dos modos disponibles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Modo proyecto&lt;/strong&gt;: Si hay un &lt;code&gt;.csproj&lt;/code&gt; junto al script, &lt;code&gt;azd&lt;/code&gt; ejecuta &lt;code&gt;dotnet restore&lt;/code&gt; y &lt;code&gt;dotnet build&lt;/code&gt; automáticamente.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Modo single-file&lt;/strong&gt;: En .NET 10+, puedes poner un archivo &lt;code&gt;.cs&lt;/code&gt; independiente y se ejecuta directamente con &lt;code&gt;dotnet run script.cs&lt;/code&gt;. Sin archivo de proyecto.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postprovision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/migrate.cs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si ya estás en .NET 10, el modo single-file es la opción más limpia para scripts simples de migración o seeding. Sin scaffolding, sin &lt;code&gt;.csproj&lt;/code&gt; que mantener.&lt;/p&gt;
&lt;h2 id="config-por-ejecutor"&gt;Config por ejecutor&lt;/h2&gt;
&lt;p&gt;Cada lenguaje soporta un bloque &lt;code&gt;config&lt;/code&gt; opcional para ajustar los valores por defecto:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;preprovision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/setup.ts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;packageManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pnpm&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postdeploy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/seed.py&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;virtualEnvName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;.venv&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postprovision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/migrate.cs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Release&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;framework&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;net10.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;También puedes mezclar formatos en el mismo bloque &lt;code&gt;hooks:&lt;/code&gt; — distintos lenguajes para distintos eventos del ciclo de vida, overrides por plataforma para Windows vs. Linux, lo que necesites.&lt;/p&gt;
&lt;h2 id="por-qué-importa-para-desarrolladores-net"&gt;Por qué importa para desarrolladores .NET&lt;/h2&gt;
&lt;p&gt;La respuesta aburrida es &amp;ldquo;consistencia&amp;rdquo;. Pero en la práctica va más allá. Los hooks eran el último lugar de un proyecto basado en azd que te obligaba a usar otro lenguaje. Ahora todo el pipeline de despliegue — código de app, scripts de infraestructura y hooks del ciclo de vida — puede vivir en un solo lenguaje.&lt;/p&gt;
&lt;p&gt;Más concreto: puedes reutilizar tus utilidades .NET existentes en los hooks. ¿Tienes una librería compartida para gestión de esquemas de base de datos? Simplemente referencíala en el proyecto del hook. ¿Tienes un script Python de seeding que ya escribiste? Ponlo directamente en &lt;code&gt;azure.yaml&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Es uno de esos cambios que parecen pequeños pero que eliminan mucha fricción del día a día con azd. El soporte multi-lenguaje para hooks ya está disponible — revisa el &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-multi-language-hooks/"&gt;post oficial&lt;/a&gt; para la documentación completa y el &lt;a href="https://github.com/Azure/azure-dev"&gt;repositorio de azd en GitHub&lt;/a&gt; para probarlo en tu próximo proyecto.&lt;/p&gt;</content:encoded></item><item><title>Windows App Dev CLI v0.3: F5 desde la terminal y automatización de UI para agentes</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/windows-app-dev-cli-v03-run-ui-automation/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/windows-app-dev-cli-v03-run-ui-automation/</guid><description>Windows App Development CLI v0.3 llega con winapp run para lanzar y depurar desde la terminal, winapp ui para automatización de UI, y un paquete NuGet que hace que dotnet run funcione con apps empaquetadas.</description><content:encoded>&lt;p&gt;&lt;em&gt;Esta publicación fue traducida automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/windows-app-dev-cli-v03-run-ui-automation/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;La experiencia F5 de Visual Studio es fantástica. Pero tener que abrir VS solo para lanzar y depurar una app Windows empaquetada es excesivo cuando estás en un pipeline de CI, ejecutando un workflow automatizado, o — cada vez más — cuando un agente de IA está haciendo las pruebas.&lt;/p&gt;
&lt;p&gt;Windows App Development CLI v0.3 acaba de &lt;a href="https://devblogs.microsoft.com/ifdef-windows/windows-app-development-cli-v0-3-new-run-and-ui-commands-plus-dotnet-run-support-for-packaged-apps/"&gt;salir&lt;/a&gt; y lo aborda directamente con dos funciones destacadas: &lt;code&gt;winapp run&lt;/code&gt; y &lt;code&gt;winapp ui&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="winapp-run-f5-desde-cualquier-sitio"&gt;winapp run: F5 desde cualquier sitio&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;winapp run&lt;/code&gt; toma una carpeta de app sin empaquetar y un manifiesto, y hace todo lo que VS hace en un debug launch: registra un paquete loose, lanza la app y preserva el &lt;code&gt;LocalState&lt;/code&gt; entre re-deploys.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Construye tu app, luego ejecútala como app empaquetada&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winapp run ./bin/Debug
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Funciona para WinUI, WPF, WinForms, Console, Avalonia y más. Los modos están pensados tanto para desarrolladores como para workflows automatizados:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--detach&lt;/code&gt;&lt;/strong&gt;: Lanza y devuelve el control a la terminal inmediatamente. Perfecto para CI/automation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--unregister-on-exit&lt;/code&gt;&lt;/strong&gt;: Limpia el paquete registrado al cerrar la app. Ejecuciones de test limpias.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--debug-output&lt;/code&gt;&lt;/strong&gt;: Captura mensajes &lt;code&gt;OutputDebugString&lt;/code&gt; y excepciones en tiempo real. Añade &lt;code&gt;--symbols&lt;/code&gt; para PDBs del Microsoft Symbol Server.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="nuevo-paquete-nuget-dotnet-run-para-apps-empaquetadas"&gt;Nuevo paquete NuGet: dotnet run para apps empaquetadas&lt;/h2&gt;
&lt;p&gt;Para desarrolladores .NET hay un nuevo paquete NuGet: &lt;code&gt;Microsoft.Windows.SDK.BuildTools.WinApp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Añádelo al proyecto (o deja que &lt;code&gt;winapp init&lt;/code&gt; lo haga), y &lt;code&gt;dotnet run&lt;/code&gt; maneja todo el inner loop: build, preparar un paquete loose-layout, registrar en Windows y lanzar — todo en un paso.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Deja que winapp init lo configure&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winapp init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# O instala directamente&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet add package Microsoft.Windows.SDK.BuildTools.WinApp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Funciona con WinUI, WPF, WinForms, Console, Avalonia. Sin comandos adicionales, sin registro manual. Solo &lt;code&gt;dotnet run&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="winapp-ui-ui-automation-desde-la-línea-de-comandos"&gt;winapp ui: UI Automation desde la línea de comandos&lt;/h2&gt;
&lt;p&gt;Este es el que abre los escenarios agénticos. &lt;code&gt;winapp ui&lt;/code&gt; te da acceso completo de UI Automation a cualquier app Windows en ejecución — WPF, WinForms, Win32, Electron, WinUI3 — todo desde la terminal.&lt;/p&gt;
&lt;p&gt;Lo que puedes hacer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Listar todas las ventanas de nivel superior&lt;/li&gt;
&lt;li&gt;Navegar el árbol completo de UI Automation de cualquier ventana&lt;/li&gt;
&lt;li&gt;Buscar elementos por nombre, tipo o ID de automatización&lt;/li&gt;
&lt;li&gt;Hacer clic, invocar y establecer valores&lt;/li&gt;
&lt;li&gt;Tomar capturas de pantalla&lt;/li&gt;
&lt;li&gt;Esperar a que aparezcan elementos — ideal para sincronización de tests&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Combina &lt;code&gt;winapp ui&lt;/code&gt; con &lt;code&gt;winapp run&lt;/code&gt; y tienes un workflow completo build → lanzar → verificar desde la terminal. Un agente puede ejecutar tu app, inspeccionar el estado de UI, interactuar con ella programáticamente y validar el resultado.&lt;/p&gt;
&lt;h2 id="otras-novedades"&gt;Otras novedades&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;winapp unregister&lt;/code&gt;&lt;/strong&gt;: Elimina un paquete sideloaded cuando terminas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;winapp manifest add-alias&lt;/code&gt;&lt;/strong&gt;: Añade un &lt;code&gt;uap5:AppExecutionAlias&lt;/code&gt; para lanzar la app por nombre desde la terminal.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tab completion&lt;/strong&gt;: Configura completado con un solo comando para PowerShell.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Package.appxmanifest&lt;/code&gt; por defecto&lt;/strong&gt;: Ahora &lt;code&gt;winapp init&lt;/code&gt; crea &lt;code&gt;Package.appxmanifest&lt;/code&gt; (convención VS) en lugar de &lt;code&gt;appxmanifest.xml&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cómo-obtenerlo"&gt;Cómo obtenerlo&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winget install Microsoft.WinAppCli
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# o&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install -g @microsoft/winappcli
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La CLI está en preview pública. Consulta el &lt;a href="https://github.com/microsoft/WinAppCli"&gt;repositorio en GitHub&lt;/a&gt; para documentación completa y el &lt;a href="https://devblogs.microsoft.com/ifdef-windows/windows-app-development-cli-v0-3-new-run-and-ui-commands-plus-dotnet-run-support-for-packaged-apps/"&gt;anuncio original&lt;/a&gt; para todos los detalles.&lt;/p&gt;</content:encoded></item><item><title>Deja de vigilar tu terminal: el modo desacoplado de Aspire cambia el flujo de trabajo</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-detached-mode-free-your-terminal/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-detached-mode-free-your-terminal/</guid><description>Aspire 13.2 te permite ejecutar tu AppHost en segundo plano y recuperar tu terminal. Combinado con los nuevos comandos CLI y el soporte para agentes, esto es más importante de lo que parece.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-detached-mode-free-your-terminal/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cada vez que ejecutas un AppHost de Aspire, tu terminal desaparece. Bloqueada. Ocupada hasta que presionas Ctrl+C. ¿Necesitas ejecutar un comando rápido? Abre otra pestaña. ¿Quieres revisar los logs? Otra pestaña. Es una pequeña fricción que se acumula rápido.&lt;/p&gt;
&lt;p&gt;Aspire 13.2 soluciona esto. James Newton-King &lt;a href="https://devblogs.microsoft.com/aspire/aspire-detached-mode-and-process-management/"&gt;escribió todos los detalles&lt;/a&gt;, y honestamente, esta es una de esas funcionalidades que cambia inmediatamente tu forma de trabajar.&lt;/p&gt;
&lt;h2 id="modo-desacoplado-un-comando-terminal-de-vuelta"&gt;Modo desacoplado: un comando, terminal de vuelta&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ese es el atajo para &lt;code&gt;aspire run --detach&lt;/code&gt;. Tu AppHost arranca en segundo plano y recuperas tu terminal de inmediato. Sin pestañas extra. Sin multiplexor de terminal. Solo tu prompt, listo para usar.&lt;/p&gt;
&lt;h2 id="gestionando-lo-que-está-en-ejecución"&gt;Gestionando lo que está en ejecución&lt;/h2&gt;
&lt;p&gt;La cuestión es que ejecutar en segundo plano solo es útil si puedes gestionar lo que hay ahí fuera. Aspire 13.2 incluye un conjunto completo de comandos CLI para exactamente eso:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# List all running AppHosts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire ps
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Inspect the state of a specific AppHost&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire describe
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Stream logs from a running AppHost&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire logs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Stop a specific AppHost&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire stop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esto convierte el CLI de Aspire en un gestor de procesos completo. Puedes iniciar múltiples AppHosts, verificar su estado, seguir sus logs y apagarlos — todo desde una sola sesión de terminal.&lt;/p&gt;
&lt;h2 id="combínalo-con-el-modo-aislado"&gt;Combínalo con el modo aislado&lt;/h2&gt;
&lt;p&gt;El modo desacoplado se combina naturalmente con el modo aislado. ¿Quieres ejecutar dos instancias del mismo proyecto en segundo plano sin conflictos de puertos?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire start --isolated
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire start --isolated
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cada uno obtiene puertos aleatorios, secretos separados y su propio ciclo de vida. Usa &lt;code&gt;aspire ps&lt;/code&gt; para ver ambos, &lt;code&gt;aspire stop&lt;/code&gt; para detener el que ya no necesites.&lt;/p&gt;
&lt;h2 id="por-qué-esto-es-enorme-para-los-agentes-de-código"&gt;Por qué esto es enorme para los agentes de código&lt;/h2&gt;
&lt;p&gt;Aquí es donde se pone realmente interesante. Un agente de código trabajando en tu terminal ahora puede:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Iniciar la app con &lt;code&gt;aspire start&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Consultar su estado con &lt;code&gt;aspire describe&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Revisar logs con &lt;code&gt;aspire logs&lt;/code&gt; para diagnosticar problemas&lt;/li&gt;
&lt;li&gt;Detenerla con &lt;code&gt;aspire stop&lt;/code&gt; cuando termine&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Todo sin perder la sesión de terminal. Antes del modo desacoplado, un agente que ejecutara tu AppHost se bloqueaba a sí mismo en su propia terminal. Ahora puede iniciar, observar, iterar y limpiar — exactamente como querrías que funcione un agente autónomo.&lt;/p&gt;
&lt;p&gt;El equipo de Aspire se volcó en esto. Ejecutar &lt;code&gt;aspire agent init&lt;/code&gt; configura un archivo de habilidades de Aspire que enseña estos comandos a los agentes. Así, herramientas como el agente de código de Copilot pueden gestionar tus cargas de trabajo de Aspire directamente.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;El modo desacoplado es una mejora de flujo de trabajo disfrazada de un simple flag. Dejas de cambiar contexto entre terminales, los agentes dejan de bloquearse a sí mismos, y los nuevos comandos CLI te dan visibilidad real de lo que está en ejecución. Es práctico, es limpio, y hace que el ciclo de desarrollo diario sea notablemente más fluido.&lt;/p&gt;
&lt;p&gt;Lee el &lt;a href="https://devblogs.microsoft.com/aspire/aspire-detached-mode-and-process-management/"&gt;post completo&lt;/a&gt; para todos los detalles y obtén Aspire 13.2 con &lt;code&gt;aspire update --self&lt;/code&gt;.&lt;/p&gt;</content:encoded></item><item><title>El clustering de pines por fin llega a .NET MAUI Maps — Una propiedad, cero complicaciones</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/maui-maps-pin-clustering-finally/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/maui-maps-pin-clustering-finally/</guid><description>.NET MAUI 11 Preview 3 añade clustering nativo de pines al control Map. Una propiedad, grupos de clustering independientes y manejo de taps — todo integrado.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Esta publicación fue traducida automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/maui-maps-pin-clustering-finally/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;¿Conoces ese momento en el que cargas un mapa con cien pines y todo se convierte en una mancha ilegible? Sí, esa ha sido la experiencia con .NET MAUI Maps hasta ahora. Se acabó.&lt;/p&gt;
&lt;p&gt;David Ortinau &lt;a href="https://devblogs.microsoft.com/dotnet/pin-clustering-in-dotnet-maui-maps/"&gt;acaba de anunciar&lt;/a&gt; que .NET MAUI 11 Preview 3 trae clustering de pines de serie en Android e iOS/Mac Catalyst. Y lo mejor — es ridículamente fácil de activar.&lt;/p&gt;
&lt;h2 id="una-propiedad-para-gobernarlos-a-todos"&gt;Una propiedad para gobernarlos a todos&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;maps:Map&lt;/span&gt; &lt;span class="na"&gt;IsClusteringEnabled=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;True&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Eso es todo. Los pines cercanos se agrupan en clusters con un badge de cantidad. Haces zoom y se expanden. Alejas y se colapsan. El tipo de comportamiento que los usuarios esperan de cualquier mapa moderno — y ahora lo consigues con una sola propiedad.&lt;/p&gt;
&lt;h2 id="grupos-de-clustering-independientes"&gt;Grupos de clustering independientes&lt;/h2&gt;
&lt;p&gt;Aquí es donde se pone interesante. No todos los pines deberían agruparse juntos. Las cafeterías y los parques son cosas distintas, y tu mapa debería saberlo.&lt;/p&gt;
&lt;p&gt;La propiedad &lt;code&gt;ClusteringIdentifier&lt;/code&gt; te permite separar pines en grupos independientes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Label&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Pike Place Coffee&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;47.6097&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;122.3331&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ClusteringIdentifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;coffee&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Label&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Occidental Square&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;47.6064&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;122.3325&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ClusteringIdentifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;parks&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Los pines con el mismo identificador se agrupan juntos. Identificadores diferentes forman clusters independientes incluso cuando están geográficamente cerca. ¿Sin identificador? Grupo por defecto. Limpio y predecible.&lt;/p&gt;
&lt;h2 id="manejo-de-taps-en-clusters"&gt;Manejo de taps en clusters&lt;/h2&gt;
&lt;p&gt;Cuando un usuario toca un cluster, recibes un evento &lt;code&gt;ClusterClicked&lt;/code&gt; con todo lo que necesitas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClusterClicked&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Label&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;DisplayAlert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;$&amp;#34;Cluster ({e.Pins.Count} pins)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;OK&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Suppress default zoom-to-cluster behavior:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// e.Handled = true;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Los argumentos del evento te dan &lt;code&gt;Pins&lt;/code&gt; (los pines del cluster), &lt;code&gt;Location&lt;/code&gt; (el centro geográfico) y &lt;code&gt;Handled&lt;/code&gt; (ponlo a &lt;code&gt;true&lt;/code&gt; si quieres anular el zoom por defecto). Simple, práctico, exactamente lo que esperarías.&lt;/p&gt;
&lt;h2 id="detalles-de-plataforma-que-vale-la-pena-conocer"&gt;Detalles de plataforma que vale la pena conocer&lt;/h2&gt;
&lt;p&gt;En Android, el clustering usa un algoritmo personalizado basado en rejilla que recalcula con los cambios de zoom — sin dependencias externas. En iOS y Mac Catalyst, aprovecha el soporte nativo de &lt;code&gt;MKClusterAnnotation&lt;/code&gt; de MapKit, lo que significa animaciones suaves y nativas de la plataforma.&lt;/p&gt;
&lt;p&gt;Este es uno de esos casos en los que el equipo de MAUI tomó la decisión correcta — apoyarse en la plataforma donde tiene sentido.&lt;/p&gt;
&lt;h2 id="por-qué-esto-importa"&gt;Por qué esto importa&lt;/h2&gt;
&lt;p&gt;El clustering de pines ha sido una de las características más solicitadas en .NET MAUI (&lt;a href="https://github.com/dotnet/maui/issues/11811"&gt;issue #11811&lt;/a&gt;), y con razón. Todas las apps que muestran ubicaciones en un mapa — seguimiento de envíos, localizadores de tiendas, bienes raíces — lo necesitan. Antes tenías que construirlo tú mismo o recurrir a una librería de terceros. Ahora viene integrado.&lt;/p&gt;
&lt;p&gt;Para nosotros los desarrolladores .NET que construimos apps móviles multiplataforma, este es el tipo de mejora de calidad de vida que hace de MAUI una opción genuinamente práctica para escenarios con uso intensivo de mapas.&lt;/p&gt;
&lt;h2 id="empieza-ya"&gt;Empieza ya&lt;/h2&gt;
&lt;p&gt;Instala &lt;a href="https://dotnet.microsoft.com/download/dotnet/11.0"&gt;.NET 11 Preview 3&lt;/a&gt; y actualiza el workload de .NET MAUI. El &lt;a href="https://github.com/dotnet/maui-samples/tree/main/10.0/UserInterface/Views/Map/MapDemo/WorkingWithMaps"&gt;ejemplo de Maps&lt;/a&gt; incluye una nueva página de Clustering con la que puedes jugar de inmediato.&lt;/p&gt;
&lt;p&gt;Ve y construye algo con ello — y deja que tus mapas por fin respiren.&lt;/p&gt;</content:encoded></item><item><title>.NET Abril 2026 Servicing — Parches de seguridad que deberías aplicar hoy</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/dotnet-april-2026-servicing-security-patches/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/dotnet-april-2026-servicing-security-patches/</guid><description>La actualización de servicing de abril 2026 corrige 6 CVEs en .NET 10, .NET 9, .NET 8 y .NET Framework — incluyendo dos vulnerabilidades de ejecución remota de código.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/dotnet-april-2026-servicing-security-patches/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Las &lt;a href="https://devblogs.microsoft.com/dotnet/dotnet-and-dotnet-framework-april-2026-servicing-updates/"&gt;actualizaciones de servicing de abril 2026&lt;/a&gt; para .NET y .NET Framework ya están disponibles, y esta incluye correcciones de seguridad que vas a querer aplicar pronto. Seis CVEs parcheados, incluyendo dos vulnerabilidades de ejecución remota de código (RCE).&lt;/p&gt;
&lt;h2 id="qué-se-ha-parcheado"&gt;Qué se ha parcheado&lt;/h2&gt;
&lt;p&gt;Aquí va el resumen rápido:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CVE&lt;/th&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;th&gt;Afecta a&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-26171&lt;/td&gt;
&lt;td&gt;Omisión de característica de seguridad&lt;/td&gt;
&lt;td&gt;.NET 10, 9, 8 + .NET Framework&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-32178&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Ejecución remota de código&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;.NET 10, 9, 8 + .NET Framework&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-33116&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Ejecución remota de código&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;.NET 10, 9, 8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-32203&lt;/td&gt;
&lt;td&gt;Denegación de servicio&lt;/td&gt;
&lt;td&gt;.NET 10, 9, 8 + .NET Framework&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-23666&lt;/td&gt;
&lt;td&gt;Denegación de servicio&lt;/td&gt;
&lt;td&gt;.NET Framework 3.0–4.8.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-32226&lt;/td&gt;
&lt;td&gt;Denegación de servicio&lt;/td&gt;
&lt;td&gt;.NET Framework 2.0–4.8.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Los dos CVEs de RCE (CVE-2026-32178 y CVE-2026-33116) afectan al mayor rango de versiones de .NET y deberían ser la prioridad.&lt;/p&gt;
&lt;h2 id="versiones-actualizadas"&gt;Versiones actualizadas&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;.NET 10&lt;/strong&gt;: 10.0.6&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.NET 9&lt;/strong&gt;: 9.0.15&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.NET 8&lt;/strong&gt;: 8.0.26&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Todas están disponibles a través de los canales habituales — &lt;a href="https://dotnet.microsoft.com/download/dotnet/10.0"&gt;dotnet.microsoft.com&lt;/a&gt;, imágenes de contenedores en MCR y gestores de paquetes de Linux.&lt;/p&gt;
&lt;h2 id="qué-hacer"&gt;Qué hacer&lt;/h2&gt;
&lt;p&gt;Actualiza tus proyectos y pipelines de CI/CD a las últimas versiones parcheadas. Si estás corriendo contenedores, descarga las últimas imágenes. Si estás en .NET Framework, revisa las &lt;a href="https://learn.microsoft.com/dotnet/framework/release-notes/release-notes"&gt;notas de versión de .NET Framework&lt;/a&gt; para los parches correspondientes.&lt;/p&gt;
&lt;p&gt;Para quienes están corriendo .NET 10 en producción (es la versión actual), 10.0.6 es una actualización obligatoria. Lo mismo para .NET 9.0.15 y .NET 8.0.26 si estás en esas versiones LTS. Dos vulnerabilidades de RCE no son algo que se pospone.&lt;/p&gt;</content:encoded></item><item><title>Azure MCP Server 2.0 Acaba de Llegar — La Automatización Agentic en la Nube Auto-Alojada ya Está Aquí</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/azure-mcp-server-2-self-hosted-agentic-cloud/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/azure-mcp-server-2-self-hosted-agentic-cloud/</guid><description>Azure MCP Server 2.0 alcanza estabilidad con implementaciones remotas auto-alojadas, 276 herramientas en 57 servicios de Azure, y seguridad de nivel empresarial — aquí está lo que importa para desarrolladores .NET que construyen flujos de trabajo agentic.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este artículo fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/azure-mcp-server-2-self-hosted-agentic-cloud/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si has estado construyendo algo con MCP y Azure últimamente, probablemente ya sepas que la experiencia local funciona bien. Conecta un servidor MCP, deja que tu agente de IA hable con recursos de Azure, y continúa. Pero en el momento en que necesitas compartir esa configuración entre un equipo? Ahí es donde las cosas se complicaban.&lt;/p&gt;
&lt;p&gt;Ya no más. Azure MCP Server &lt;a href="https://devblogs.microsoft.com/azure-sdk/announcing-azure-mcp-server-2-0-stable-release/"&gt;acaba de alcanzar 2.0 estable&lt;/a&gt;, y la característica principal es exactamente lo que los equipos empresariales han estado pidiendo: &lt;strong&gt;soporte para servidor MCP remoto auto-alojado&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="qué-es-azure-mcp-server"&gt;¿Qué es Azure MCP Server?&lt;/h2&gt;
&lt;p&gt;Un repaso rápido. Azure MCP Server implementa la especificación del &lt;a href="https://modelcontextprotocol.io/docs/getting-started/intro"&gt;Protocolo de Contexto del Modelo&lt;/a&gt; y expone capacidades de Azure como herramientas estructuradas y detectables que los agentes de IA pueden invocar. Piénsalo como un puente estandarizado entre tu agente y Azure — provisioning, implementación, monitoreo, diagnósticos, todo a través de una interfaz consistente.&lt;/p&gt;
&lt;p&gt;Los números hablan por sí solos: &lt;strong&gt;276 herramientas MCP en 57 servicios de Azure&lt;/strong&gt;. Esa es una cobertura seria.&lt;/p&gt;
&lt;h2 id="lo-importante-implementaciones-remotas-auto-alojadas"&gt;Lo importante: implementaciones remotas auto-alojadas&lt;/h2&gt;
&lt;p&gt;Aquí está la cosa. Ejecutar MCP localmente en tu máquina está bien para desarrollo y experimentos. Pero en un escenario de equipo real, necesitas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Acceso compartido para desarrolladores y sistemas de agentes internos&lt;/li&gt;
&lt;li&gt;Configuración centralizada (contexto de tenant, valores predeterminados de suscripción, telemetría)&lt;/li&gt;
&lt;li&gt;Límites de red y políticas empresariales&lt;/li&gt;
&lt;li&gt;Integración en tuberías CI/CD&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Azure MCP Server 2.0 aborda todo esto. Puedes desplegarlo como un servicio interno administrado centralmente con transporte basado en HTTP, autenticación adecuada y gobernanza consistente.&lt;/p&gt;
&lt;p&gt;Para autenticación, tienes dos opciones sólidas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Identidad Administrada&lt;/strong&gt; — cuando se ejecuta junto a &lt;a href="https://aka.ms/azmcp/self-host/foundry"&gt;Microsoft Foundry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flujo On-Behalf-Of (OBO)&lt;/strong&gt; — delegación de OpenID Connect que llama a APIs de Azure usando el contexto del usuario conectado&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ese flujo OBO es particularmente interesante para nosotros los desarrolladores .NET. Significa que tus flujos de trabajo agentic pueden operar con los permisos reales del usuario, no con alguna cuenta de servicio con excesivos privilegios. Principio de privilegio mínimo, integrado desde el principio.&lt;/p&gt;
&lt;h2 id="endurecimiento-de-seguridad"&gt;Endurecimiento de seguridad&lt;/h2&gt;
&lt;p&gt;Esto no es solo un lanzamiento de características — también es uno de seguridad. El lanzamiento 2.0 añade:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Validación de extremos más fuerte&lt;/li&gt;
&lt;li&gt;Protecciones contra patrones de inyección en herramientas orientadas a consultas&lt;/li&gt;
&lt;li&gt;Controles de aislamiento más estrictos para entornos de desarrollo&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si vas a exponer MCP como un servicio compartido, estas salvaguardas importan. Mucho.&lt;/p&gt;
&lt;h2 id="dónde-puedes-usarlo"&gt;¿Dónde puedes usarlo?&lt;/h2&gt;
&lt;p&gt;La historia de compatibilidad con clientes es amplia. Azure MCP Server 2.0 funciona con:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IDEs&lt;/strong&gt;: VS Code, Visual Studio, IntelliJ, Eclipse, Cursor&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agentes CLI&lt;/strong&gt;: GitHub Copilot CLI, Claude Code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Independiente&lt;/strong&gt;: servidor local para configuraciones simples&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remoto auto-alojado&lt;/strong&gt;: la nueva estrella de 2.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Además hay soporte de nube soberana para Azure US Government y Azure operado por 21Vianet, que es crítico para implementaciones reguladas.&lt;/p&gt;
&lt;h2 id="por-qué-esto-importa-para-desarrolladores-net"&gt;Por qué esto importa para desarrolladores .NET&lt;/h2&gt;
&lt;p&gt;Si estás construyendo aplicaciones agentic con .NET — ya sea Semantic Kernel, Microsoft Agent Framework, u orquestación propia — Azure MCP Server 2.0 te da una forma lista para producción de dejar que tus agentes interactúen con la infraestructura de Azure. Sin wrappers REST personalizados. Sin patrones de integración específicos del servicio. Solo MCP.&lt;/p&gt;
&lt;p&gt;Combinado con la &lt;a href="https://devblogs.microsoft.com/azure-sdk/mcp-as-easy-as-1-2-3-introducing-the-fluent-api-for-mcp-apps/"&gt;API fluida para MCP Apps&lt;/a&gt; que salió hace unos días, el ecosistema .NET MCP está madurando rápidamente.&lt;/p&gt;
&lt;h2 id="empezando"&gt;Empezando&lt;/h2&gt;
&lt;p&gt;Elige tu ruta:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp"&gt;Repositorio de GitHub&lt;/a&gt;&lt;/strong&gt; — código fuente, documentación, todo&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/download/docker"&gt;Imagen de Docker&lt;/a&gt;&lt;/strong&gt; — implementación contenedorizada&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/download/vscode"&gt;Extensión de VS Code&lt;/a&gt;&lt;/strong&gt; — integración con IDE&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/self-host"&gt;Guía de auto-alojamiento&lt;/a&gt;&lt;/strong&gt; — la característica insignia de 2.0&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="resumiendo"&gt;Resumiendo&lt;/h2&gt;
&lt;p&gt;Azure MCP Server 2.0 es exactamente el tipo de actualización de infraestructura que no se ve llamativa en una demostración pero lo cambia todo en la práctica. MCP remoto auto-alojado con autenticación adecuada, endurecimiento de seguridad y soporte de nube soberana significa que MCP está listo para equipos reales construyendo flujos de trabajo agentic reales en Azure. Si has estado esperando la señal de &amp;ldquo;listo para empresas&amp;rdquo; — esto es.&lt;/p&gt;</content:encoded></item><item><title>.NET Aspire 13.2 Quiere Ser el Mejor Amigo de Tu Agente de IA</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-agentic-development-build-run-observe/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-agentic-development-build-run-observe/</guid><description>Aspire 13.2 apuesta todo por el desarrollo agéntico — salida CLI estructurada, ejecuciones aisladas, entornos auto-reparables y datos OpenTelemetry completos para que tus agentes de IA puedan realmente construir, ejecutar y observar tus apps.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-agentic-development-build-run-observe/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;¿Conoces ese momento cuando tu agente de IA escribe código sólido, te emocionas, y luego todo se desmorona cuando intenta &lt;em&gt;ejecutar&lt;/em&gt; la cosa? Conflictos de puertos, procesos fantasma, variables de entorno incorrectas — de repente tu agente está quemando tokens depurando problemas de arranque en vez de construir funcionalidades.&lt;/p&gt;
&lt;p&gt;El equipo de Aspire acaba de publicar un &lt;a href="https://devblogs.microsoft.com/aspire/agentic-dev-aspirations/"&gt;post muy bien pensado&lt;/a&gt; sobre exactamente este problema, y su respuesta es convincente: Aspire 13.2 está diseñado no solo para humanos, sino para agentes de IA.&lt;/p&gt;
&lt;h2 id="el-problema-es-real"&gt;El problema es real&lt;/h2&gt;
&lt;p&gt;Los agentes de IA son increíbles escribiendo código. Pero enviar una app full-stack funcional involucra mucho más que generar archivos. Necesitas iniciar servicios en el orden correcto, gestionar puertos, configurar variables de entorno, conectar bases de datos y obtener retroalimentación cuando algo se rompe. Ahora mismo, la mayoría de agentes manejan todo esto por prueba y error — ejecutando comandos, leyendo errores, intentando de nuevo.&lt;/p&gt;
&lt;p&gt;Le metemos instrucciones en Markdown, skills personalizados y prompts para guiarlos, pero son impredecibles, no se pueden compilar y cuestan tokens solo para parsear. El equipo de Aspire dio en el clavo con la idea central: los agentes necesitan &lt;strong&gt;compiladores y APIs estructuradas&lt;/strong&gt;, no más Markdown.&lt;/p&gt;
&lt;h2 id="aspire-como-infraestructura-para-agentes"&gt;Aspire como infraestructura para agentes&lt;/h2&gt;
&lt;p&gt;Esto es lo que Aspire 13.2 trae a la mesa del desarrollo agéntico:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Todo tu stack en código tipado.&lt;/strong&gt; El AppHost define tu topología completa — API, frontend, base de datos, caché — en TypeScript o C# compilable:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createBuilder&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;./.modules/aspire.js&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;createBuilder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postgres&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addPostgres&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;addDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;catalog&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addRedis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cache&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addNodeApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;api&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./api&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;src/index.ts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withHttpEndpoint&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PORT&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addViteApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;frontend&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./frontend&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;waitFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Un agente puede leer esto para entender la topología de la app, agregar recursos, conectar componentes y &lt;em&gt;compilar para verificar&lt;/em&gt;. El compilador le dice inmediatamente si algo está mal. Sin adivinanzas, sin prueba y error con archivos de configuración.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Un solo comando para gobernarlos a todos.&lt;/strong&gt; En vez de que los agentes malabareen &lt;code&gt;docker compose up&lt;/code&gt;, &lt;code&gt;npm run dev&lt;/code&gt; y scripts de arranque de bases de datos, todo es simplemente &lt;code&gt;aspire start&lt;/code&gt;. Todos los recursos se lanzan en el orden correcto, en los puertos correctos, con la configuración correcta. Los procesos de larga duración tampoco cuelgan al agente — Aspire los gestiona.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Modo aislado para agentes en paralelo.&lt;/strong&gt; Con &lt;code&gt;--isolated&lt;/code&gt;, cada ejecución de Aspire obtiene sus propios puertos aleatorios y secretos de usuario separados. ¿Tienes múltiples agentes trabajando en git worktrees? No colisionarán. Esto es enorme para herramientas como los agentes en segundo plano de VS Code que crean entornos paralelos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ojos de agente a través de telemetría.&lt;/strong&gt; Aquí es donde se pone realmente potente. El CLI de Aspire expone datos OpenTelemetry completos durante el desarrollo — trazas, métricas, logs estructurados. Tu agente no solo lee la salida de consola esperando lo mejor. Puede rastrear una petición fallida entre servicios, perfilar endpoints lentos e identificar exactamente dónde se rompen las cosas. Eso es observabilidad de nivel producción en el ciclo de desarrollo.&lt;/p&gt;
&lt;h2 id="la-analogía-de-los-parachoques-de-boliche"&gt;La analogía de los parachoques de boliche&lt;/h2&gt;
&lt;p&gt;El equipo de Aspire usa una gran analogía: piensa en Aspire como los parachoques de una pista de boliche para agentes de IA. Si el agente no es perfecto (y no lo será), los parachoques evitan que tire canaletas. La definición del stack previene mala configuración, el compilador atrapa errores, el CLI maneja la gestión de procesos y la telemetría provee el ciclo de retroalimentación.&lt;/p&gt;
&lt;p&gt;Combina esto con algo como Playwright CLI, y tu agente puede realmente &lt;em&gt;usar&lt;/em&gt; tu app — haciendo clic en flujos, revisando el DOM, viendo cosas rotas en telemetría, arreglando el código, reiniciando y probando de nuevo. Construir, ejecutar, observar, arreglar. Ese es el ciclo de desarrollo autónomo que hemos estado persiguiendo.&lt;/p&gt;
&lt;h2 id="primeros-pasos"&gt;Primeros pasos&lt;/h2&gt;
&lt;p&gt;¿Nuevo en Aspire? Instala el CLI desde &lt;a href="https://get.aspire.dev"&gt;get.aspire.dev&lt;/a&gt; y sigue la &lt;a href="https://aspire.dev/get-started/first-app"&gt;guía de inicio&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;¿Ya usas Aspire? Ejecuta &lt;code&gt;aspire update --self&lt;/code&gt; para obtener la 13.2, luego apunta tu agente de código favorito a tu repo. Te sorprenderá lo mucho más lejos que llega con los guardrails de Aspire.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Aspire 13.2 ya no es solo un framework para aplicaciones distribuidas — se está convirtiendo en infraestructura esencial para agentes. Definiciones de stack estructuradas, arranque con un comando, ejecuciones paralelas aisladas y telemetría en tiempo real le dan a los agentes de IA exactamente lo que necesitan para pasar de escribir código a enviar apps.&lt;/p&gt;
&lt;p&gt;Lee el &lt;a href="https://devblogs.microsoft.com/aspire/agentic-dev-aspirations/"&gt;post completo&lt;/a&gt; del equipo de Aspire para todos los detalles y videos de demostración.&lt;/p&gt;</content:encoded></item><item><title>Conecta tus servidores MCP en Azure Functions a Foundry Agents — Así es como</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/foundry-agents-mcp-servers-azure-functions/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/foundry-agents-mcp-servers-azure-functions/</guid><description>Construye tu servidor MCP una vez, despliégalo en Azure Functions y conéctalo a agentes de Microsoft Foundry con autenticación adecuada. Tus herramientas funcionan en todas partes — VS Code, Cursor y ahora agentes de IA empresariales.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/foundry-agents-mcp-servers-azure-functions/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Esto es algo que me encanta del ecosistema MCP: construyes tu servidor una vez y funciona en todas partes. VS Code, Visual Studio, Cursor, ChatGPT — cada cliente MCP puede descubrir y usar tus herramientas. Ahora, Microsoft está añadiendo otro consumidor a esa lista: los agentes de Foundry.&lt;/p&gt;
&lt;p&gt;Lily Ma del equipo de Azure SDK &lt;a href="https://devblogs.microsoft.com/azure-sdk/give-your-foundry-agent-custom-tools-with-mcp-servers-on-azure-functions/"&gt;publicó una guía práctica&lt;/a&gt; sobre cómo conectar servidores MCP desplegados en Azure Functions con agentes de Microsoft Foundry. Si ya tienes un servidor MCP, esto es puro valor agregado — no necesitas reconstruir nada.&lt;/p&gt;
&lt;h2 id="por-qué-esta-combinación-tiene-sentido"&gt;Por qué esta combinación tiene sentido&lt;/h2&gt;
&lt;p&gt;Azure Functions te da infraestructura escalable, autenticación integrada y facturación serverless para alojar servidores MCP. Microsoft Foundry te da agentes de IA que pueden razonar, planificar y tomar acciones. Conectar ambos significa que tus herramientas personalizadas — consultar una base de datos, llamar a una API de negocio, ejecutar lógica de validación — se convierten en capacidades que los agentes de IA empresariales pueden descubrir y usar de forma autónoma.&lt;/p&gt;
&lt;p&gt;El punto clave: tu servidor MCP se mantiene igual. Solo estás añadiendo Foundry como otro consumidor. Las mismas herramientas que funcionan en tu configuración de VS Code ahora potencian un agente de IA con el que tu equipo o clientes interactúan.&lt;/p&gt;
&lt;h2 id="opciones-de-autenticación"&gt;Opciones de autenticación&lt;/h2&gt;
&lt;p&gt;Aquí es donde el post realmente aporta valor. Cuatro métodos de autenticación según tu escenario:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Método&lt;/th&gt;
&lt;th&gt;Caso de uso&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Basado en clave&lt;/strong&gt; (predeterminado)&lt;/td&gt;
&lt;td&gt;Desarrollo o servidores sin autenticación Entra&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Microsoft Entra&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Producción con identidades administradas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Passthrough de identidad OAuth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Producción donde cada usuario se autentica individualmente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sin autenticación&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Desarrollo/pruebas o solo datos públicos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Para producción, Microsoft Entra con identidad del agente es el camino recomendado. El passthrough de identidad OAuth es para cuando el contexto del usuario importa — el agente pide a los usuarios que inicien sesión, y cada solicitud lleva el token propio del usuario.&lt;/p&gt;
&lt;h2 id="configurándolo"&gt;Configurándolo&lt;/h2&gt;
&lt;p&gt;El flujo general:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Despliega tu servidor MCP en Azure Functions&lt;/strong&gt; — hay ejemplos disponibles para &lt;a href="https://github.com/Azure-Samples/remote-mcp-functions-dotnet"&gt;.NET&lt;/a&gt;, Python, TypeScript y Java&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Habilita la autenticación MCP integrada&lt;/strong&gt; en tu function app&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Obtén tu URL de endpoint&lt;/strong&gt; — &lt;code&gt;https://&amp;lt;FUNCTION_APP_NAME&amp;gt;.azurewebsites.net/runtime/webhooks/mcp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Añade el servidor MCP como herramienta en Foundry&lt;/strong&gt; — navega a tu agente en el portal, añade una nueva herramienta MCP, proporciona endpoint y credenciales&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Luego pruébalo en el playground de Agent Builder enviando un prompt que active una de tus herramientas.&lt;/p&gt;
&lt;h2 id="mi-opinión"&gt;Mi opinión&lt;/h2&gt;
&lt;p&gt;La historia de composabilidad aquí se está volviendo realmente fuerte. Construye tu servidor MCP una vez en .NET (o Python, TypeScript, Java), despliégalo en Azure Functions, y cada cliente compatible con MCP puede usarlo — herramientas de programación, apps de chat, y ahora agentes de IA empresariales. Es un patrón de &amp;ldquo;escribe una vez, usa en todas partes&amp;rdquo; que realmente funciona.&lt;/p&gt;
&lt;p&gt;Para desarrolladores .NET específicamente, la &lt;a href="https://github.com/Azure-Samples/remote-mcp-functions-dotnet"&gt;extensión MCP de Azure Functions&lt;/a&gt; hace esto sencillo. Defines tus herramientas como Azure Functions, despliegas, y tienes un servidor MCP de nivel producción con toda la seguridad y escalabilidad que Azure Functions proporciona.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Si tienes herramientas MCP ejecutándose en Azure Functions, conectarlas a agentes de Foundry es una victoria rápida — tus herramientas personalizadas se convierten en capacidades de IA empresarial con autenticación adecuada y sin cambios de código en el servidor.&lt;/p&gt;
&lt;p&gt;Lee la &lt;a href="https://devblogs.microsoft.com/azure-sdk/give-your-foundry-agent-custom-tools-with-mcp-servers-on-azure-functions/"&gt;guía completa&lt;/a&gt; para instrucciones paso a paso sobre cada método de autenticación, y consulta la &lt;a href="https://learn.microsoft.com/azure/azure-functions/functions-mcp-foundry-tools?tabs=entra%2Cmcp-extension%2Cfoundry"&gt;documentación detallada&lt;/a&gt; para configuraciones de producción.&lt;/p&gt;</content:encoded></item><item><title>El Modo Aislado de Aspire Resuelve la Pesadilla de Conflictos de Puertos en Desarrollo Paralelo</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-isolated-mode-parallel-instances/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-isolated-mode-parallel-instances/</guid><description>Aspire 13.2 introduce el modo --isolated: puertos aleatorios, secretos separados y cero colisiones al ejecutar múltiples instancias del mismo AppHost. Perfecto para agentes de IA, worktrees y flujos de trabajo paralelos.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-isolated-mode-parallel-instances/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si alguna vez intentaste ejecutar dos instancias del mismo proyecto al mismo tiempo, conoces el dolor. El puerto 8080 ya está en uso. El puerto 17370 está ocupado. Mata algo, reinicia, malabarea variables de entorno — es un asesino de productividad.&lt;/p&gt;
&lt;p&gt;Este problema está empeorando, no mejorando. Los agentes de IA crean git worktrees para trabajar de forma independiente. Los agentes en segundo plano levantan entornos separados. Los desarrolladores hacen checkout del mismo repo dos veces para ramas de funcionalidades. Cada uno de estos escenarios choca con la misma pared: dos instancias de la misma app peleando por los mismos puertos.&lt;/p&gt;
&lt;p&gt;Aspire 13.2 resuelve esto con un solo flag. James Newton-King del equipo de Aspire &lt;a href="https://devblogs.microsoft.com/aspire/aspire-isolated-mode-parallel-development/"&gt;escribió todos los detalles&lt;/a&gt;, y es una de esas funcionalidades de &amp;ldquo;¿por qué no teníamos esto antes?&amp;rdquo;&lt;/p&gt;
&lt;h2 id="la-solución---isolated"&gt;La solución: &lt;code&gt;--isolated&lt;/code&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire run --isolated
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Eso es todo. Cada ejecución obtiene:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Puertos aleatorios&lt;/strong&gt; — no más colisiones entre instancias&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secretos de usuario aislados&lt;/strong&gt; — cadenas de conexión y claves API permanecen separados por instancia&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sin reasignación manual de puertos. Sin malabarismo de variables de entorno. Cada ejecución obtiene un entorno limpio y libre de colisiones automáticamente.&lt;/p&gt;
&lt;h2 id="escenarios-reales-donde-esto-brilla"&gt;Escenarios reales donde esto brilla&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Múltiples checkouts.&lt;/strong&gt; Tienes una rama de funcionalidad en un directorio y un bugfix en otro:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Terminal 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/projects/my-app-feature
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire run --isolated
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Terminal 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/projects/my-app-bugfix
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire run --isolated
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ambos se ejecutan sin conflictos. El dashboard muestra qué está corriendo y dónde.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agentes en segundo plano en VS Code.&lt;/strong&gt; Cuando el agente en background de Copilot Chat crea un git worktree para trabajar en tu código de forma independiente, puede necesitar ejecutar tu AppHost de Aspire. Sin &lt;code&gt;--isolated&lt;/code&gt;, eso es una colisión de puertos con tu worktree principal. Con él, ambas instancias simplemente funcionan.&lt;/p&gt;
&lt;p&gt;El skill de Aspire que viene con &lt;code&gt;aspire agent init&lt;/code&gt; instruye automáticamente a los agentes a usar &lt;code&gt;--isolated&lt;/code&gt; cuando trabajan en worktrees. Así que el agente en background de Copilot debería manejar esto de forma nativa.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tests de integración junto al desarrollo.&lt;/strong&gt; ¿Necesitas ejecutar tests contra un AppHost en vivo mientras sigues construyendo funcionalidades? El modo aislado le da a cada contexto sus propios puertos y configuración.&lt;/p&gt;
&lt;h2 id="cómo-funciona-internamente"&gt;Cómo funciona internamente&lt;/h2&gt;
&lt;p&gt;Cuando pasas &lt;code&gt;--isolated&lt;/code&gt;, el CLI genera un ID de instancia único para la ejecución. Esto impulsa dos comportamientos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Aleatorización de puertos&lt;/strong&gt; — en vez de vincularse a puertos predecibles definidos en la configuración de tu AppHost, el modo aislado elige puertos aleatorios disponibles para todo — el dashboard, los endpoints de servicio, todo. El service discovery se ajusta automáticamente, así que los servicios se encuentran entre sí sin importar qué puertos les tocaron.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Aislamiento de secretos&lt;/strong&gt; — cada ejecución aislada obtiene su propio almacén de secretos de usuario, identificado por el ID de instancia. Las cadenas de conexión y claves API de una ejecución no se filtran a otra.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Tu código no necesita cambios. El service discovery de Aspire resuelve los endpoints en tiempo de ejecución, así que todo se conecta correctamente sin importar la asignación de puertos.&lt;/p&gt;
&lt;h2 id="cuándo-usarlo"&gt;Cuándo usarlo&lt;/h2&gt;
&lt;p&gt;Usa &lt;code&gt;--isolated&lt;/code&gt; cuando ejecutes múltiples instancias del mismo AppHost simultáneamente — ya sea desarrollo paralelo, tests automatizados, agentes de IA o git worktrees. Para desarrollo de instancia única donde prefieras puertos predecibles, el &lt;code&gt;aspire run&lt;/code&gt; regular sigue funcionando bien.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;El modo aislado es una funcionalidad pequeña que resuelve un problema real y cada vez más común. A medida que el desarrollo asistido por IA nos empuja hacia más flujos paralelos — múltiples agentes, múltiples worktrees, múltiples contextos — la capacidad de simplemente levantar otra instancia sin pelear por puertos es esencial.&lt;/p&gt;
&lt;p&gt;Lee el &lt;a href="https://devblogs.microsoft.com/aspire/aspire-isolated-mode-parallel-development/"&gt;post completo&lt;/a&gt; para todos los detalles técnicos y pruébalo con &lt;code&gt;aspire update --self&lt;/code&gt; para obtener la 13.2.&lt;/p&gt;</content:encoded></item><item><title>La evaluación de modernización de GitHub Copilot es la mejor herramienta de migración que aún no estás usando</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/dotnet-modernization-assessment-github-copilot/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/dotnet-modernization-assessment-github-copilot/</guid><description>La extensión de modernización de GitHub Copilot no solo sugiere cambios de código — produce una evaluación completa de migración con issues accionables, comparaciones de destinos Azure y un flujo de trabajo colaborativo. Aquí te explico por qué el documento de evaluación es la clave de todo.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/dotnet-modernization-assessment-github-copilot/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Migrar una aplicación legacy de .NET Framework a .NET moderno es una de esas tareas que todos saben que deberían hacer pero nadie quiere empezar. Nunca es solo &amp;ldquo;cambiar el target framework.&amp;rdquo; Son APIs que desaparecieron, paquetes que ya no existen, modelos de hosting que funcionan completamente diferente, y un millón de pequeñas decisiones sobre qué containerizar, qué reescribir y qué dejar como está.&lt;/p&gt;
&lt;p&gt;Jeffrey Fritz acaba de publicar una &lt;a href="https://devblogs.microsoft.com/dotnet/your-migrations-source-of-truth-the-modernization-assessment/"&gt;inmersión profunda en la evaluación de modernización de GitHub Copilot&lt;/a&gt;, y honestamente, es el mejor tooling de migración que he visto para .NET. No por la generación de código — eso ya es estándar. Por el documento de evaluación que produce.&lt;/p&gt;
&lt;h2 id="no-es-solo-un-motor-de-sugerencias-de-código"&gt;No es solo un motor de sugerencias de código&lt;/h2&gt;
&lt;p&gt;La extensión de VS Code sigue un modelo de &lt;strong&gt;Evaluar → Planificar → Ejecutar&lt;/strong&gt;. La fase de evaluación analiza todo tu código base y produce un documento estructurado que captura todo: qué necesita cambiar, qué recursos de Azure aprovisionar, qué modelo de despliegue usar. Todo lo posterior — infraestructura como código, containerización, manifiestos de despliegue — fluye de lo que la evaluación encuentra.&lt;/p&gt;
&lt;p&gt;La evaluación se almacena en &lt;code&gt;.github/modernize/assessment/&lt;/code&gt; en tu proyecto. Cada ejecución produce un reporte independiente, así que acumulas un historial y puedes rastrear cómo evoluciona tu postura de migración a medida que corriges issues.&lt;/p&gt;
&lt;h2 id="dos-formas-de-empezar"&gt;Dos formas de empezar&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Evaluación Recomendada&lt;/strong&gt; — el camino rápido. Elige entre dominios curados (Actualización Java/.NET, Cloud Readiness, Seguridad) y obtén resultados significativos sin tocar configuración. Genial para una primera mirada a dónde está tu aplicación.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Evaluación Personalizada&lt;/strong&gt; — el camino dirigido. Configura exactamente qué analizar: cómputo objetivo (App Service, AKS, Container Apps), SO objetivo, análisis de containerización. Elige múltiples destinos Azure para comparar enfoques de migración lado a lado.&lt;/p&gt;
&lt;p&gt;Esa vista de comparación es genuinamente útil. Una app con 3 issues obligatorios para App Service podría tener 7 para AKS. Ver ambos ayuda a decidir el hosting antes de comprometerse con un camino de migración.&lt;/p&gt;
&lt;h2 id="el-desglose-de-issues-es-accionable"&gt;El desglose de issues es accionable&lt;/h2&gt;
&lt;p&gt;Cada issue viene con un nivel de criticidad:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Obligatorio&lt;/strong&gt; — debe corregirse o la migración falla&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Potencial&lt;/strong&gt; — podría impactar la migración, necesita juicio humano&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Opcional&lt;/strong&gt; — mejoras recomendadas, no bloquean la migración&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Y cada issue enlaza a archivos afectados y números de línea, proporciona una descripción detallada de qué está mal y por qué importa para tu plataforma objetivo, da pasos concretos de remediación (no solo &amp;ldquo;arregla esto&amp;rdquo;), e incluye enlaces a documentación oficial.&lt;/p&gt;
&lt;p&gt;Puedes asignar issues individuales a desarrolladores y tienen todo lo que necesitan para actuar. Esa es la diferencia entre una herramienta que te dice &amp;ldquo;hay un problema&amp;rdquo; y una que te dice cómo resolverlo.&lt;/p&gt;
&lt;h2 id="las-rutas-de-actualización-cubiertas"&gt;Las rutas de actualización cubiertas&lt;/h2&gt;
&lt;p&gt;Para .NET específicamente:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.NET Framework → .NET 10&lt;/li&gt;
&lt;li&gt;ASP.NET → ASP.NET Core&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cada ruta de actualización tiene reglas de detección que saben qué APIs fueron eliminadas, qué patrones no tienen equivalente directo, y qué issues de seguridad necesitan atención.&lt;/p&gt;
&lt;p&gt;Para equipos que gestionan múltiples aplicaciones, también hay un CLI que soporta evaluaciones batch multi-repo — clona todos los repos, evalúalos todos, obtén reportes por app más una vista de portafolio agregada.&lt;/p&gt;
&lt;h2 id="mi-opinión"&gt;Mi opinión&lt;/h2&gt;
&lt;p&gt;Si estás sentado sobre aplicaciones legacy de .NET Framework (y seamos honestos, la mayoría de los equipos empresariales lo están), esta es &lt;em&gt;la&lt;/em&gt; herramienta con la que empezar. Solo el documento de evaluación vale el tiempo — convierte un vago &amp;ldquo;deberíamos modernizar&amp;rdquo; en una lista concreta y priorizada de elementos de trabajo con caminos claros hacia adelante.&lt;/p&gt;
&lt;p&gt;El flujo de trabajo colaborativo también es inteligente: exporta evaluaciones, compártelas con tu equipo, impórtalas sin re-ejecutar. ¿Revisiones de arquitectura donde los que toman decisiones no son los que ejecutan las herramientas? Cubierto.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;La evaluación de modernización de GitHub Copilot transforma la migración de .NET de un proyecto aterrador e indefinido en un proceso estructurado y rastreable. Empieza con una evaluación recomendada para ver dónde estás, luego usa evaluaciones personalizadas para comparar destinos Azure y construir tu plan de migración.&lt;/p&gt;
&lt;p&gt;Lee el &lt;a href="https://devblogs.microsoft.com/dotnet/your-migrations-source-of-truth-the-modernization-assessment/"&gt;walkthrough completo&lt;/a&gt; y descarga la &lt;a href="https://aka.ms/ghcp-appmod/vscode-ext"&gt;extensión de VS Code&lt;/a&gt; para probarlo en tu propio código.&lt;/p&gt;</content:encoded></item><item><title>Las MCP Apps tienen una API fluida — Construye interfaces ricas para herramientas de IA en .NET en tres pasos</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/mcp-fluent-api-azure-functions-dotnet/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/mcp-fluent-api-azure-functions-dotnet/</guid><description>La nueva API de configuración fluida para MCP Apps en Azure Functions te permite convertir cualquier herramienta MCP de .NET en una app completa con vistas, permisos y políticas CSP en pocas líneas de código.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/mcp-fluent-api-azure-functions-dotnet/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Las herramientas MCP son geniales para darle capacidades a los agentes de IA. Pero ¿qué pasa si tu herramienta necesita mostrarle algo al usuario — un dashboard, un formulario, una visualización interactiva? Ahí es donde entran las MCP Apps, y ahora son mucho más fáciles de construir.&lt;/p&gt;
&lt;p&gt;Lilian Kasem del equipo de Azure SDK &lt;a href="https://devblogs.microsoft.com/azure-sdk/mcp-as-easy-as-1-2-3-introducing-the-fluent-api-for-mcp-apps/"&gt;presentó la nueva API de configuración fluida&lt;/a&gt; para MCP Apps en Azure Functions con .NET, y es el tipo de mejora en experiencia de desarrollador que te hace preguntarte por qué no fue siempre así de simple.&lt;/p&gt;
&lt;h2 id="qué-son-las-mcp-apps"&gt;¿Qué son las MCP Apps?&lt;/h2&gt;
&lt;p&gt;Las MCP Apps extienden el Model Context Protocol permitiendo que las herramientas lleven sus propias vistas de UI, assets estáticos y controles de seguridad. En lugar de solo devolver texto, tu herramienta MCP puede renderizar experiencias HTML completas — dashboards interactivos, visualizaciones de datos, formularios de configuración — todo invocable por agentes de IA y presentado a los usuarios por clientes MCP.&lt;/p&gt;
&lt;p&gt;El problema era que conectar todo esto manualmente requería conocer la especificación MCP a fondo: URIs &lt;code&gt;ui://&lt;/code&gt;, tipos MIME especiales, coordinación de metadatos entre herramientas y recursos. No era difícil, pero sí tedioso.&lt;/p&gt;
&lt;h2 id="la-api-fluida-en-tres-pasos"&gt;La API fluida en tres pasos&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Paso 1: Define tu función.&lt;/strong&gt; Una herramienta MCP de Azure Functions estándar:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;[Function(nameof(HelloApp))]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;HelloApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [McpToolTrigger(&amp;#34;HelloApp&amp;#34;, &amp;#34;A simple MCP App that says hello.&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ToolInvocationContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Hello from app&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Paso 2: Promuévela a MCP App.&lt;/strong&gt; En el startup de tu programa:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConfigureMcpTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;HelloApp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsMcpApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;assets/hello-app.html&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello App&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithPermissions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpAppPermissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClipboardWrite&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;McpAppPermissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClipboardRead&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithCsp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;csp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowBaseUri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://www.microsoft.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://www.microsoft.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Paso 3: Añade tu vista HTML.&lt;/strong&gt; Crea &lt;code&gt;assets/hello-app.html&lt;/code&gt; con la interfaz que necesites.&lt;/p&gt;
&lt;p&gt;Eso es todo. La API fluida se encarga de toda la plomería del protocolo MCP — genera la función de recurso sintético, establece el tipo MIME correcto e inyecta los metadatos que conectan tu herramienta con su vista.&lt;/p&gt;
&lt;h2 id="la-superficie-de-la-api-está-bien-diseñada"&gt;La superficie de la API está bien diseñada&lt;/h2&gt;
&lt;p&gt;Algunas cosas que me gustan mucho:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Las fuentes de las vistas son flexibles.&lt;/strong&gt; Puedes servir HTML desde archivos en disco, o embeber recursos directamente en tu ensamblado para despliegues autónomos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpViewSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;assets/my-view.html&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpViewSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromEmbeddedResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;MyApp.Resources.view.html&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;El CSP es componible.&lt;/strong&gt; Explícitamente permites los orígenes que tu app necesita, siguiendo principios de mínimo privilegio. Llama a &lt;code&gt;WithCsp&lt;/code&gt; varias veces y los orígenes se acumulan:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithCsp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;csp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://api.example.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoadResourcesFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://cdn.example.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://youtube.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Control de visibilidad.&lt;/strong&gt; Puedes hacer que una herramienta sea visible solo para el LLM, solo para la UI del host, o ambos. ¿Quieres una herramienta que solo renderice UI y no deba ser llamada por el modelo? Fácil:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithVisibility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpVisibility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// UI-only, hidden from the model&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="primeros-pasos"&gt;Primeros pasos&lt;/h2&gt;
&lt;p&gt;Añade el paquete preview:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Mcp --version 1.5.0-preview.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si ya estás construyendo herramientas MCP con Azure Functions, esto es solo una actualización de paquete. El &lt;a href="https://learn.microsoft.com/azure/azure-functions/scenario-mcp-apps?tabs=bash%2Clinux&amp;amp;pivots=programming-language-csharp"&gt;quickstart de MCP Apps&lt;/a&gt; es el mejor lugar para empezar si eres nuevo en el concepto.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Las MCP Apps son uno de los desarrollos más emocionantes en el espacio de herramientas de IA — herramientas que no solo &lt;em&gt;hacen cosas&lt;/em&gt; sino que pueden &lt;em&gt;mostrar cosas&lt;/em&gt; a los usuarios. La API fluida elimina la complejidad del protocolo y te permite enfocarte en lo que importa: la lógica de tu herramienta y su interfaz.&lt;/p&gt;
&lt;p&gt;Lee el &lt;a href="https://devblogs.microsoft.com/azure-sdk/mcp-as-easy-as-1-2-3-introducing-the-fluent-api-for-mcp-apps/"&gt;post completo&lt;/a&gt; para la referencia completa de la API y ejemplos.&lt;/p&gt;</content:encoded></item><item><title>C# 15 trae los tipos unión — y son exactamente lo que estábamos pidiendo</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/csharp-15-union-types-exhaustive-matching/</link><pubDate>Sun, 05 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/csharp-15-union-types-exhaustive-matching/</guid><description>C# 15 introduce la palabra clave union — uniones discriminadas con coincidencia de patrones exhaustiva impuesta por el compilador. Así se ven, por qué importan y cómo probarlas hoy.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/csharp-15-union-types-exhaustive-matching/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Esta es la que estuve esperando. C# 15 introduce la palabra clave &lt;code&gt;union&lt;/code&gt; — uniones discriminadas con coincidencia de patrones exhaustiva impuesta por el compilador. Si alguna vez envidiaste las uniones discriminadas de F# o los enums de Rust, sabés exactamente por qué esto importa.&lt;/p&gt;
&lt;p&gt;Bill Wagner &lt;a href="https://devblogs.microsoft.com/dotnet/csharp-15-union-types/"&gt;publicó el análisis a fondo&lt;/a&gt; en el blog de .NET, y sinceramente? El diseño es limpio, práctico y muy C#. Déjame mostrarte qué hay realmente y por qué es más importante de lo que parece a primera vista.&lt;/p&gt;
&lt;h2 id="el-problema-que-resuelven-las-uniones"&gt;El problema que resuelven las uniones&lt;/h2&gt;
&lt;p&gt;Antes de C# 15, devolver &amp;ldquo;uno de varios tipos posibles&amp;rdquo; desde un método siempre era un compromiso:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;object&lt;/code&gt;&lt;/strong&gt; — sin restricciones, sin ayuda del compilador, casting defensivo por todos lados&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interfaces marcadoras&lt;/strong&gt; — mejor, pero cualquiera puede implementarlas. El compilador nunca puede considerar el conjunto completo&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clases base abstractas&lt;/strong&gt; — mismo problema, además los tipos necesitan un ancestro común&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ninguna de estas opciones te da lo que realmente querés: un conjunto cerrado de tipos donde el compilador garantiza que manejaste todos los casos. Eso es lo que hacen los tipos unión.&lt;/p&gt;
&lt;h2 id="la-sintaxis-es-hermosamente-simple"&gt;La sintaxis es hermosamente simple&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Bird&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="n"&gt;Pet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bird&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Una línea. &lt;code&gt;Pet&lt;/code&gt; puede contener un &lt;code&gt;Cat&lt;/code&gt;, un &lt;code&gt;Dog&lt;/code&gt; o un &lt;code&gt;Bird&lt;/code&gt;. Las conversiones implícitas se generan automáticamente:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Pet&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Rex&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Dog { Name = Rex }&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Y acá está la magia — el compilador impone la coincidencia exhaustiva:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Dog&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Cat&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Bird&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;No se necesita descarte &lt;code&gt;_&lt;/code&gt;. El compilador sabe que este switch cubre todos los casos posibles. Si después agregás un cuarto tipo a la unión, cada expresión switch que no lo maneje produce una advertencia. Casos faltantes detectados en tiempo de compilación, no en tiempo de ejecución.&lt;/p&gt;
&lt;h2 id="donde-esto-se-vuelve-práctico"&gt;Donde esto se vuelve práctico&lt;/h2&gt;
&lt;p&gt;El ejemplo de &lt;code&gt;Pet&lt;/code&gt; es simpático, pero acá es donde las uniones realmente brillan en código real.&lt;/p&gt;
&lt;h3 id="respuestas-de-api-que-devuelven-diferentes-formas"&gt;Respuestas de API que devuelven diferentes formas&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="n"&gt;ApiResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ApiError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ValidationFailure&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ahora cada consumidor está obligado a manejar éxito, error y fallo de validación. No más bugs de &amp;ldquo;me olvidé de chequear el caso de error&amp;rdquo;.&lt;/p&gt;
&lt;h3 id="valor-único-o-colección"&gt;Valor único o colección&lt;/h3&gt;
&lt;p&gt;El patrón &lt;code&gt;OneOrMore&amp;lt;T&amp;gt;&lt;/code&gt; muestra cómo las uniones pueden tener un cuerpo con métodos auxiliares:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="n"&gt;OneOrMore&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AsEnumerable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;single&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;single&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;multiple&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;multiple&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Los consumidores pasan la forma que les resulte conveniente:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;OneOrMore&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;dotnet&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;OneOrMore&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;moreTags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;csharp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;unions&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;preview&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsEnumerable&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;[{tag}] &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// [dotnet]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="componer-tipos-no-relacionados"&gt;Componer tipos no relacionados&lt;/h3&gt;
&lt;p&gt;Esta es la funcionalidad definitiva sobre las jerarquías tradicionales. Podés unir tipos que no tienen nada en común — &lt;code&gt;string&lt;/code&gt; y &lt;code&gt;Exception&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt; e &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;. No se necesita un ancestro común.&lt;/p&gt;
&lt;h2 id="uniones-personalizadas-para-bibliotecas-existentes"&gt;Uniones personalizadas para bibliotecas existentes&lt;/h2&gt;
&lt;p&gt;Acá hay una decisión de diseño inteligente: cualquier clase o struct con un atributo &lt;code&gt;[Union]&lt;/code&gt; es reconocida como tipo unión, siempre que siga el patrón básico (constructores públicos para los tipos de caso y una propiedad &lt;code&gt;Value&lt;/code&gt;). Bibliotecas como OneOf que ya proveen tipos similares a uniones pueden optar por el soporte del compilador sin reescribir sus internos.&lt;/p&gt;
&lt;p&gt;Para escenarios sensibles al rendimiento con tipos de valor, las bibliotecas pueden implementar un patrón de acceso sin boxing con los métodos &lt;code&gt;HasValue&lt;/code&gt; y &lt;code&gt;TryGetValue&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="el-panorama-general"&gt;El panorama general&lt;/h2&gt;
&lt;p&gt;Los tipos unión son parte de una historia más amplia de exhaustividad que viene a C#:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tipos unión&lt;/strong&gt; — coincidencia exhaustiva sobre un conjunto cerrado de tipos (disponible ahora en preview)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Jerarquías cerradas&lt;/strong&gt; — el modificador &lt;code&gt;closed&lt;/code&gt; previene clases derivadas fuera del assembly que las define (propuesto)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enums cerrados&lt;/strong&gt; — previene la creación de valores distintos a los miembros declarados (propuesto)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Juntas, estas tres funcionalidades le darán a C# uno de los sistemas de coincidencia de patrones con seguridad de tipos más completos en cualquier lenguaje mainstream.&lt;/p&gt;
&lt;h2 id="probalo-hoy"&gt;Probalo hoy&lt;/h2&gt;
&lt;p&gt;Los tipos unión están disponibles en .NET 11 Preview 2:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Instalá el &lt;a href="https://dotnet.microsoft.com/download/dotnet"&gt;SDK de .NET 11 Preview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Apuntá a &lt;code&gt;net11.0&lt;/code&gt; en tu proyecto&lt;/li&gt;
&lt;li&gt;Configurá &lt;code&gt;&amp;lt;LangVersion&amp;gt;preview&amp;lt;/LangVersion&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Una aclaración: en Preview 2, vas a necesitar declarar &lt;code&gt;UnionAttribute&lt;/code&gt; e &lt;code&gt;IUnion&lt;/code&gt; en tu proyecto ya que todavía no están en el runtime. Agarrá &lt;a href="https://github.com/dotnet/docs/blob/e68b5dd1e557b53c45ca43e61b013bc919619fb9/docs/csharp/language-reference/builtin-types/snippets/unions/RuntimePolyfill.cs"&gt;RuntimePolyfill.cs&lt;/a&gt; del repo de docs, o agregá esto:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;System.Runtime.CompilerServices&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; AllowMultiple = false)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UnionAttribute&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Attribute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IUnion&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;object?&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Los tipos unión son una de esas funcionalidades que te hacen preguntarte cómo sobrevivimos sin ellas. Coincidencia exhaustiva impuesta por el compilador, sintaxis limpia, soporte genérico e integración con el pattern matching existente — es todo lo que pedimos, hecho a la manera de C#.&lt;/p&gt;
&lt;p&gt;Probalos en .NET 11 Preview 2, rompé cosas y &lt;a href="https://github.com/dotnet/csharplang/discussions/9663"&gt;compartí tu feedback en GitHub&lt;/a&gt;. Esto es preview, y el equipo de C# está escuchando activamente. Tus casos extremos y feedback de diseño van a dar forma a la versión final.&lt;/p&gt;
&lt;p&gt;Para la referencia completa del lenguaje, consultá la &lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/union"&gt;documentación de tipos unión&lt;/a&gt; y la &lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/unions"&gt;especificación de la funcionalidad&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Aspire 13.2 incluye una CLI de documentación — y tu agente de IA también puede usarla</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-docs-cli-ai-skills/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-docs-cli-ai-skills/</guid><description>.NET Aspire 13.2 añade aspire docs — una CLI para buscar, explorar y leer documentación oficial sin salir de tu terminal. También funciona como herramienta para agentes de IA. Te cuento por qué esto importa.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-docs-cli-ai-skills/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;¿Conocés ese momento cuando estás metido hasta el cuello en un Aspire AppHost, conectando integraciones, y necesitás verificar exactamente qué parámetros espera la integración de Redis? Hacés alt-tab al navegador, buscás por aspire.dev, entrecerrás los ojos mirando los docs de la API, y volvés a tu editor. Contexto perdido. Flujo roto.&lt;/p&gt;
&lt;p&gt;Aspire 13.2 acaba de &lt;a href="https://devblogs.microsoft.com/aspire/aspire-docs-in-your-terminal/"&gt;lanzar una solución para eso&lt;/a&gt;. La CLI &lt;code&gt;aspire docs&lt;/code&gt; te permite buscar, explorar y leer documentación oficial de Aspire directamente desde tu terminal. Y como está respaldada por servicios reutilizables, los agentes de IA y skills pueden usar los mismos comandos para consultar docs en lugar de alucinar APIs que no existen.&lt;/p&gt;
&lt;h2 id="el-problema-que-esto-realmente-resuelve"&gt;El problema que esto realmente resuelve&lt;/h2&gt;
&lt;p&gt;David Pine lo clava en el post original: los agentes de IA eran &lt;em&gt;terribles&lt;/em&gt; ayudando a los desarrolladores a construir apps con Aspire. Recomendaban &lt;code&gt;dotnet run&lt;/code&gt; en vez de &lt;code&gt;aspire run&lt;/code&gt;, referenciaban learn.microsoft.com para docs que viven en aspire.dev, sugerían paquetes NuGet desactualizados, y — mi favorito personal — alucinaban APIs que no existen.&lt;/p&gt;
&lt;p&gt;¿Por qué? Porque Aspire fue específico de .NET por mucho más tiempo del que lleva siendo políglota, y los LLMs trabajan con datos de entrenamiento que preceden las últimas funcionalidades. Cuando le das a un agente de IA la capacidad de buscar los docs actuales, deja de adivinar y empieza a ser útil.&lt;/p&gt;
&lt;h2 id="tres-comandos-cero-pestañas-del-navegador"&gt;Tres comandos, cero pestañas del navegador&lt;/h2&gt;
&lt;p&gt;La CLI es refrescantemente simple:&lt;/p&gt;
&lt;h3 id="listar-todos-los-docs"&gt;Listar todos los docs&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Devuelve cada página de documentación disponible en aspire.dev. ¿Necesitás salida legible por máquina? Agregá &lt;code&gt;--format Json&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="buscar-un-tema"&gt;Buscar un tema&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs search &lt;span class="s2"&gt;&amp;#34;redis&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Busca tanto en títulos como en contenido con puntuación de relevancia ponderada. El mismo motor de búsqueda que alimenta la herramienta de documentación internamente. Obtenés resultados rankeados con títulos, slugs y puntuaciones de relevancia.&lt;/p&gt;
&lt;h3 id="leer-una-página-completa-o-solo-una-sección"&gt;Leer una página completa (o solo una sección)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs get redis-integration
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Transmite la página completa como markdown a tu terminal. ¿Necesitás solo una sección?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs get redis-integration --section &lt;span class="s2"&gt;&amp;#34;Add Redis resource&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Precisión quirúrgica. Sin hacer scroll por 500 líneas. Solo la parte que necesitás.&lt;/p&gt;
&lt;h2 id="el-ángulo-del-agente-de-ia"&gt;El ángulo del agente de IA&lt;/h2&gt;
&lt;p&gt;Acá es donde se pone interesante para los que desarrollamos con herramientas de IA. Los mismos comandos de &lt;code&gt;aspire docs&lt;/code&gt; funcionan como herramientas para agentes de IA — a través de skills, servidores MCP, o wrappers simples de CLI.&lt;/p&gt;
&lt;p&gt;En vez de que tu asistente de IA invente APIs de Aspire basándose en datos de entrenamiento obsoletos, puede llamar a &lt;code&gt;aspire docs search &amp;quot;postgres&amp;quot;&lt;/code&gt;, encontrar los docs oficiales de integración, leer la página correcta, y darte el enfoque documentado. Documentación en tiempo real y actual — no lo que el modelo memorizó hace seis meses.&lt;/p&gt;
&lt;p&gt;La arquitectura detrás de esto es intencional. El equipo de Aspire construyó servicios reutilizables (&lt;code&gt;IDocsIndexService&lt;/code&gt;, &lt;code&gt;IDocsSearchService&lt;/code&gt;, &lt;code&gt;IDocsFetcher&lt;/code&gt;, &lt;code&gt;IDocsCache&lt;/code&gt;) en lugar de una integración única. Eso significa que el mismo motor de búsqueda funciona para humanos en la terminal, agentes de IA en tu editor, y automatización en tu pipeline de CI.&lt;/p&gt;
&lt;h2 id="escenarios-del-mundo-real"&gt;Escenarios del mundo real&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Consultas rápidas en terminal:&lt;/strong&gt; Estás tres archivos adentro y necesitás los parámetros de configuración de Redis. Dos comandos, noventa segundos, de vuelta al trabajo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs search &lt;span class="s2"&gt;&amp;#34;redis&amp;#34;&lt;/span&gt; --limit &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs get redis-integration --section &lt;span class="s2"&gt;&amp;#34;Configuration&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Desarrollo asistido por IA:&lt;/strong&gt; Tu skill de VS Code envuelve los comandos de la CLI. Preguntás &amp;ldquo;Agregá una base de datos PostgreSQL a mi AppHost&amp;rdquo; y el agente busca los docs reales antes de responder. Sin alucinaciones.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Validación en CI/CD:&lt;/strong&gt; Tu pipeline valida configuraciones de AppHost contra documentación oficial de forma programática. La salida &lt;code&gt;--format Json&lt;/code&gt; se conecta limpiamente con &lt;code&gt;jq&lt;/code&gt; y otras herramientas.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bases de conocimiento personalizadas:&lt;/strong&gt; ¿Estás construyendo tu propia herramienta de IA? Enviá la salida JSON estructurada directamente a tu base de conocimiento:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs search &lt;span class="s2"&gt;&amp;#34;monitoring&amp;#34;&lt;/span&gt; --format Json &lt;span class="p"&gt;|&lt;/span&gt; jq &lt;span class="s1"&gt;&amp;#39;[.[] | {slug, title, summary}]&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Sin web scraping. Sin API keys. Los mismos datos estructurados que usa internamente la herramienta de documentación.&lt;/p&gt;
&lt;h2 id="la-documentación-siempre-está-actualizada"&gt;La documentación siempre está actualizada&lt;/h2&gt;
&lt;p&gt;Esta es la parte que más aprecio. La CLI no descarga una captura estática — consulta aspire.dev con caché basado en ETag. En el momento en que los docs se actualizan, tu CLI y cualquier skill construido sobre ella lo refleja. Sin copias obsoletas, sin momentos de &amp;ldquo;pero el wiki decía&amp;hellip;&amp;rdquo;.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;aspire docs&lt;/code&gt; es una de esas funcionalidades pequeñas que resuelve un problema real de forma limpia. Los humanos obtienen acceso a documentación nativa de terminal. Los agentes de IA obtienen una forma de dejar de adivinar y empezar a referenciar docs reales. Y todo está respaldado por la misma fuente de verdad.&lt;/p&gt;
&lt;p&gt;Si estás construyendo con .NET Aspire y todavía no probaste la CLI, ejecutá &lt;code&gt;aspire docs search &amp;quot;tu-tema-aquí&amp;quot;&lt;/code&gt; y fijate cómo se siente. Después considerá envolver esos comandos en cualquier skill de IA o configuración de automatización que estés usando — tus agentes te lo van a agradecer.&lt;/p&gt;
&lt;p&gt;Mirá el &lt;a href="https://davidpine.dev/posts/aspire-docs-mcp-tools/"&gt;análisis profundo de David Pine&lt;/a&gt; sobre cómo se armó la herramienta de documentación, y la &lt;a href="https://aspire.dev/reference/cli/commands/aspire-docs/"&gt;referencia oficial de la CLI&lt;/a&gt; para todos los detalles.&lt;/p&gt;</content:encoded></item><item><title>Microsoft Agent Framework Llega a 1.0 — Esto Es Lo Que Realmente Importa para Desarrolladores .NET</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/agent-framework-1-0-production-ready/</link><pubDate>Fri, 03 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/agent-framework-1-0-production-ready/</guid><description>Microsoft Agent Framework 1.0 está listo para producción con APIs estables, orquestación multi-agente y conectores para todos los principales proveedores de IA. Esto es lo que necesitas saber como desarrollador .NET.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/agent-framework-1-0-production-ready/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si has estado siguiendo el camino de Agent Framework desde los primeros días de Semantic Kernel y AutoGen, esto es importante. Microsoft Agent Framework acaba de &lt;a href="https://devblogs.microsoft.com/agent-framework/microsoft-agent-framework-version-1-0/"&gt;llegar a la versión 1.0&lt;/a&gt; — listo para producción, APIs estables, compromiso de soporte a largo plazo. Está disponible tanto para .NET como para Python, y está genuinamente preparado para cargas de trabajo reales.&lt;/p&gt;
&lt;p&gt;Voy a cortar el ruido del anuncio y centrarme en lo que importa si estás construyendo apps con IA usando .NET.&lt;/p&gt;
&lt;h2 id="la-versión-corta"&gt;La versión corta&lt;/h2&gt;
&lt;p&gt;Agent Framework 1.0 unifica lo que solían ser Semantic Kernel y AutoGen en un único SDK de código abierto. Una abstracción de agente. Un motor de orquestación. Múltiples proveedores de IA. Si has estado saltando entre Semantic Kernel para patrones empresariales y AutoGen para flujos de trabajo multi-agente de nivel investigación, puedes parar. Este es el único SDK ahora.&lt;/p&gt;
&lt;h2 id="empezar-es-casi-injustamente-simple"&gt;Empezar es casi injustamente simple&lt;/h2&gt;
&lt;p&gt;Aquí tienes un agente funcional en .NET:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// dotnet add package Microsoft.Agents.AI.OpenAI --prerelease&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Agents.AI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Agents.AI.Foundry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Azure.Identity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;https://your-project.services.ai.azure.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetResponsesClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;gpt-5.3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsAIAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;HaikuBot&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;You are an upbeat assistant that writes beautifully.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Write a haiku about shipping 1.0.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Eso es todo. Un puñado de líneas y tienes un agente de IA ejecutándose contra Azure Foundry. El equivalente en Python es igual de conciso. Añade herramientas de funciones, conversaciones multi-turno y streaming a medida que avanzas — la superficie de la API escala sin volverse rara.&lt;/p&gt;
&lt;h2 id="orquestación-multi-agente--esto-va-en-serio"&gt;Orquestación multi-agente — esto va en serio&lt;/h2&gt;
&lt;p&gt;Los agentes individuales están bien para demos, pero los escenarios de producción generalmente necesitan coordinación. Agent Framework 1.0 viene con patrones de orquestación probados en batalla directamente de Microsoft Research y AutoGen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Secuencial&lt;/strong&gt; — los agentes procesan en orden (escritor → revisor → editor)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Concurrente&lt;/strong&gt; — distribuye a múltiples agentes en paralelo, converge resultados&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handoff&lt;/strong&gt; — un agente delega a otro basándose en la intención&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chat grupal&lt;/strong&gt; — múltiples agentes discuten y convergen en una solución&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Magentic-One&lt;/strong&gt; — el patrón multi-agente de nivel investigación de MSR&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Todos soportan streaming, checkpointing, aprobaciones con humano en el bucle, y pausa/reanudación. La parte de checkpointing es crucial — los flujos de trabajo de larga duración sobreviven a reinicios de proceso. Para nosotros los desarrolladores .NET que hemos construido flujos de trabajo durables con Azure Functions, esto se siente familiar.&lt;/p&gt;
&lt;h2 id="las-funcionalidades-que-más-importan"&gt;Las funcionalidades que más importan&lt;/h2&gt;
&lt;p&gt;Aquí va mi lista de lo que vale la pena saber:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hooks de middleware.&lt;/strong&gt; ¿Sabes cómo ASP.NET Core tiene pipelines de middleware? Mismo concepto, pero para la ejecución de agentes. Intercepta cada etapa — añade seguridad de contenido, logging, políticas de cumplimiento — sin tocar los prompts del agente. Así es como haces que los agentes estén listos para empresa.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Memoria conectable.&lt;/strong&gt; Historial conversacional, estado persistente clave-valor, recuperación basada en vectores. Elige tu backend: Foundry Agent Service, Mem0, Redis, Neo4j, o crea el tuyo propio. La memoria es lo que convierte una llamada LLM sin estado en un agente que realmente recuerda el contexto.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agentes declarativos en YAML.&lt;/strong&gt; Define las instrucciones de tu agente, herramientas, memoria y topología de orquestación en archivos YAML versionados. Carga y ejecuta con una sola llamada a la API. Esto es un cambio radical para equipos que quieren iterar en el comportamiento del agente sin redesplegar código.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Soporte A2A y MCP.&lt;/strong&gt; MCP (Model Context Protocol) permite a los agentes descubrir e invocar herramientas externas dinámicamente. A2A (protocolo Agent-to-Agent) habilita la colaboración entre runtimes — tus agentes .NET pueden coordinarse con agentes ejecutándose en otros frameworks. El soporte para A2A 1.0 llegará pronto.&lt;/p&gt;
&lt;h2 id="las-funcionalidades-en-preview-que-vale-la-pena-seguir"&gt;Las funcionalidades en preview que vale la pena seguir&lt;/h2&gt;
&lt;p&gt;Algunas funcionalidades se lanzaron como preview en 1.0 — funcionales pero las APIs pueden evolucionar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DevUI&lt;/strong&gt; — un depurador local basado en navegador para visualizar la ejecución del agente, flujos de mensajes y llamadas a herramientas en tiempo real. Piensa en Application Insights, pero para el razonamiento del agente.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Copilot SDK y Claude Code SDK&lt;/strong&gt; — usa Copilot o Claude como un harness de agente directamente desde tu código de orquestación. Compón un agente capaz de programar junto a tus otros agentes en el mismo flujo de trabajo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent Harness&lt;/strong&gt; — un runtime local personalizable que da a los agentes acceso a shell, sistema de archivos y bucles de mensajería. Piensa en agentes de programación y patrones de automatización.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skills&lt;/strong&gt; — paquetes reutilizables de capacidades de dominio que dan a los agentes capacidades estructuradas listas para usar.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="migrando-desde-semantic-kernel-o-autogen"&gt;Migrando desde Semantic Kernel o AutoGen&lt;/h2&gt;
&lt;p&gt;Si tienes código existente de Semantic Kernel o AutoGen, hay asistentes de migración dedicados que analizan tu código y generan planes de migración paso a paso. La &lt;a href="https://learn.microsoft.com/en-us/agent-framework/migration-guide/from-semantic-kernel"&gt;guía de migración de Semantic Kernel&lt;/a&gt; y la &lt;a href="https://learn.microsoft.com/en-us/agent-framework/migration-guide/from-autogen"&gt;guía de migración de AutoGen&lt;/a&gt; te guían a través de todo.&lt;/p&gt;
&lt;p&gt;Si has estado en los paquetes RC, actualizar a 1.0 es solo un cambio de versión.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Agent Framework 1.0 es el hito de producción que los equipos empresariales han estado esperando. APIs estables, soporte multi-proveedor, patrones de orquestación que realmente funcionan a escala, y rutas de migración desde tanto Semantic Kernel como AutoGen.&lt;/p&gt;
&lt;p&gt;El framework es &lt;a href="https://github.com/microsoft/agent-framework"&gt;completamente open source en GitHub&lt;/a&gt;, y puedes empezar hoy con &lt;code&gt;dotnet add package Microsoft.Agents.AI&lt;/code&gt;. Echa un vistazo a la &lt;a href="https://learn.microsoft.com/en-us/agent-framework/get-started/"&gt;guía de inicio rápido&lt;/a&gt; y los &lt;a href="https://github.com/microsoft/agent-framework"&gt;ejemplos&lt;/a&gt; para ponerte manos a la obra.&lt;/p&gt;
&lt;p&gt;Si has estado esperando la señal de &amp;ldquo;seguro para usar en producción&amp;rdquo; — esta es.&lt;/p&gt;</content:encoded></item><item><title>azd ahora te permite ejecutar y depurar agentes IA localmente — Esto es lo que cambió en marzo 2026</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/azd-march-2026-local-ai-agent-debugging/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/azd-march-2026-local-ai-agent-debugging/</guid><description>El Azure Developer CLI publicó siete versiones en marzo 2026. Lo destacado: un bucle local de ejecución y depuración para agentes IA, integración con GitHub Copilot en la configuración de proyectos, y soporte para Container App Jobs.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/azd-march-2026-local-ai-agent-debugging/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Siete versiones en un mes. Eso es lo que el equipo del Azure Developer CLI (&lt;code&gt;azd&lt;/code&gt;) publicó en marzo 2026, y la función estrella es la que estaba esperando: &lt;strong&gt;un bucle local de ejecución y depuración para agentes IA&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;PC Chan &lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-developer-cli-azd-march-2026/"&gt;publicó el resumen completo&lt;/a&gt;, y aunque hay mucho contenido, déjame filtrarlo a lo que realmente importa para desarrolladores .NET que construyen apps con IA.&lt;/p&gt;
&lt;h2 id="ejecutar-y-depurar-agentes-ia-sin-desplegar"&gt;Ejecutar y depurar agentes IA sin desplegar&lt;/h2&gt;
&lt;p&gt;Esta es la grande. La nueva extensión &lt;code&gt;azure.ai.agents&lt;/code&gt; añade un conjunto de comandos que te dan una experiencia de bucle interno adecuada para agentes IA:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;azd ai agent run&lt;/code&gt; — inicia tu agente localmente&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent invoke&lt;/code&gt; — le envía mensajes (local o desplegado)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent show&lt;/code&gt; — muestra el estado del contenedor y su salud&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent monitor&lt;/code&gt; — transmite logs del contenedor en tiempo real&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Antes, probar un agente IA significaba desplegarlo en Microsoft Foundry cada vez que hacías un cambio. Ahora puedes iterar localmente, probar el comportamiento de tu agente, y solo desplegarlo cuando estés listo. Si has estado construyendo agentes con el Microsoft Agent Framework o Semantic Kernel, esto cambia tu flujo de trabajo diario.&lt;/p&gt;
&lt;p&gt;El comando invoke funciona tanto contra agentes locales como desplegados, lo que significa que puedes usar el mismo flujo de pruebas sin importar dónde esté corriendo el agente. Ese es el tipo de detalle que te ahorra mantener dos conjuntos de scripts de prueba.&lt;/p&gt;
&lt;h2 id="github-copilot-configura-tu-proyecto-azd"&gt;GitHub Copilot configura tu proyecto azd&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azd init&lt;/code&gt; ahora ofrece una opción &amp;ldquo;Set up with GitHub Copilot (Preview)&amp;rdquo;. En lugar de responder prompts manualmente sobre la estructura de tu proyecto, un agente Copilot genera la configuración por ti. Verifica que el directorio de trabajo esté limpio antes de modificar archivos y pide consentimiento de herramientas MCP por adelantado.&lt;/p&gt;
&lt;p&gt;Cuando un comando falla, &lt;code&gt;azd&lt;/code&gt; ahora ofrece troubleshooting asistido por IA: elige una categoría (explicar, guiar, solucionar o saltar), deja que el agente sugiera una corrección, y reintenta — todo sin salir de la terminal. Para configuraciones de infraestructura complejas, eso ahorra tiempo real.&lt;/p&gt;
&lt;h2 id="container-app-jobs-y-mejoras-de-despliegue"&gt;Container App Jobs y mejoras de despliegue&lt;/h2&gt;
&lt;p&gt;Algunas funciones de despliegue que vale la pena mencionar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Container App Jobs&lt;/strong&gt;: &lt;code&gt;azd&lt;/code&gt; ahora despliega &lt;code&gt;Microsoft.App/jobs&lt;/code&gt; a través de la configuración existente &lt;code&gt;host: containerapp&lt;/code&gt;. Tu plantilla Bicep determina si el destino es un Container App o un Job — sin configuración extra.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timeouts configurables&lt;/strong&gt;: Nueva flag &lt;code&gt;--timeout&lt;/code&gt; en &lt;code&gt;azd deploy&lt;/code&gt; y un campo &lt;code&gt;deployTimeout&lt;/code&gt; en &lt;code&gt;azure.yaml&lt;/code&gt;. Sin más adivinanzas sobre el límite predeterminado de 1200 segundos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fallback de build remoto&lt;/strong&gt;: Cuando falla el build remoto en ACR, &lt;code&gt;azd&lt;/code&gt; hace fallback automático a Docker/Podman local.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validación preflight local&lt;/strong&gt;: Los parámetros de Bicep se validan localmente antes de desplegar, detectando parámetros faltantes sin un viaje de ida y vuelta a Azure.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="pulido-en-la-experiencia-de-desarrollador"&gt;Pulido en la experiencia de desarrollador&lt;/h2&gt;
&lt;p&gt;Algunas mejoras más pequeñas que se suman:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Detección automática de pnpm/yarn&lt;/strong&gt; para proyectos JS/TS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Soporte para pyproject.toml&lt;/strong&gt; para paquetes Python&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Directorios de plantillas locales&lt;/strong&gt; — &lt;code&gt;azd init --template&lt;/code&gt; ahora acepta rutas del sistema de archivos para iteración offline&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mejores mensajes de error&lt;/strong&gt; en modo &lt;code&gt;--no-prompt&lt;/code&gt; — todos los valores faltantes reportados de una vez con comandos de resolución&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Variables de entorno de build&lt;/strong&gt; inyectadas en todos los subprocesos de build (.NET, Node.js, Java, Python)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La última es sutil pero importante: tu build .NET ahora tiene acceso a las variables de entorno de &lt;code&gt;azd&lt;/code&gt;, lo que significa que puedes hacer inyección de configuración en tiempo de compilación sin scripting adicional.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;El bucle de depuración local de agentes IA es la estrella de esta versión, pero la acumulación de mejoras de despliegue y refinamiento de DX hace que &lt;code&gt;azd&lt;/code&gt; se sienta más maduro que nunca. Si estás desplegando apps .NET en Azure — especialmente agentes IA — esta actualización vale la pena.&lt;/p&gt;
&lt;p&gt;Revisa las &lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-developer-cli-azd-march-2026/"&gt;notas completas de la versión&lt;/a&gt; para todos los detalles, o comienza con &lt;a href="https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd"&gt;la instalación de azd&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>El Dashboard de Aspire 13.2 ahora tiene una API de telemetría — y lo cambia todo</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-132-dashboard-export-telemetry/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-132-dashboard-export-telemetry/</guid><description>.NET Aspire 13.2 trae exportación inteligente de telemetría, una API programática para trazas y logs, y mejoras en la visualización de GenAI. Te cuento por qué importa para tu flujo de depuración.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/aspire-132-dashboard-export-telemetry/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si has estado construyendo aplicaciones distribuidas con .NET Aspire, ya sabes que el dashboard es lo mejor de toda la experiencia. Todas tus trazas, logs y métricas en un solo lugar — sin Jaeger externo, sin configuración de Seq, sin momentos de &amp;ldquo;déjame revisar la otra terminal&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Aspire 13.2 acaba de mejorar todo significativamente. James Newton-King &lt;a href="https://devblogs.microsoft.com/aspire/aspire-dashboard-improvements-export-and-telemetry/"&gt;anunció la actualización&lt;/a&gt;, y honestamente, las funciones de exportación de telemetría y la API por sí solas justifican la actualización.&lt;/p&gt;
&lt;h2 id="exportar-telemetría-como-una-persona-normal"&gt;Exportar telemetría como una persona normal&lt;/h2&gt;
&lt;p&gt;Este es el escenario que todos hemos vivido: estás depurando un problema distribuido, finalmente lo reproduces después de veinte minutos de configuración, y ahora necesitas compartir lo que pasó con tu equipo. ¿Antes? Capturas de pantalla. Copiar y pegar IDs de trazas. El desastre de siempre.&lt;/p&gt;
&lt;p&gt;Aspire 13.2 añade un diálogo de &lt;strong&gt;Gestión de logs y telemetría&lt;/strong&gt; donde puedes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Limpiar toda la telemetría (útil antes de reproducir un bug)&lt;/li&gt;
&lt;li&gt;Exportar telemetría seleccionada a un archivo ZIP en formato estándar OTLP/JSON&lt;/li&gt;
&lt;li&gt;Re-importar ese ZIP en cualquier dashboard de Aspire después&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esa última parte es la función estrella. Reproduces un bug, exportas la telemetría, la adjuntas a tu work item, y tu compañero puede importarla en su propio dashboard para ver exactamente lo que tú viste. No más &amp;ldquo;¿puedes reproducirlo en tu máquina?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Las trazas, spans y logs individuales también tienen una opción &amp;ldquo;Export JSON&amp;rdquo; en sus menús contextuales. ¿Necesitas compartir una traza específica? Clic derecho, copiar JSON, pegar en la descripción de tu PR. Listo.&lt;/p&gt;
&lt;h2 id="la-api-de-telemetría-es-el-verdadero-cambio-de-juego"&gt;La API de telemetría es el verdadero cambio de juego&lt;/h2&gt;
&lt;p&gt;Esto es lo que más me emociona. El dashboard ahora expone una API HTTP bajo &lt;code&gt;/api/telemetry&lt;/code&gt; para consultar datos de telemetría programáticamente. Endpoints disponibles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/resources&lt;/code&gt; — listar recursos con telemetría&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/spans&lt;/code&gt; — consultar spans con filtros&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/logs&lt;/code&gt; — consultar logs con filtros&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/traces&lt;/code&gt; — listar trazas&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/traces/{traceId}&lt;/code&gt; — obtener todos los spans de una traza&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Todo vuelve en formato OTLP JSON. Esto potencia los nuevos comandos &lt;code&gt;aspire agent mcp&lt;/code&gt; y &lt;code&gt;aspire otel&lt;/code&gt; del CLI, pero la implicación real es mayor: ahora puedes construir herramientas, scripts e integraciones con agentes IA que consulten la telemetría de tu app directamente.&lt;/p&gt;
&lt;p&gt;Imagina un agente de IA que pueda ver tus trazas distribuidas reales mientras depuras. Eso ya no es hipotético — es lo que esta API permite.&lt;/p&gt;
&lt;h2 id="la-telemetría-de-genai-se-vuelve-práctica"&gt;La telemetría de GenAI se vuelve práctica&lt;/h2&gt;
&lt;p&gt;Si estás construyendo apps con IA usando Semantic Kernel o Microsoft.Extensions.AI, apreciarás el visualizador de telemetría GenAI mejorado. Aspire 13.2 añade:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Descripciones de herramientas IA renderizadas como Markdown&lt;/li&gt;
&lt;li&gt;Un botón dedicado de GenAI en la página de trazas para acceso rápido&lt;/li&gt;
&lt;li&gt;Mejor manejo de errores para JSON de GenAI truncado o no estándar&lt;/li&gt;
&lt;li&gt;Navegación click-to-highlight entre definiciones de herramientas&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El post menciona que VS Code Copilot chat, Copilot CLI y OpenCode soportan configurar un &lt;code&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/code&gt;. Apúntalos al dashboard de Aspire y literalmente puedes ver a tus agentes IA pensar en tiempo real a través de la telemetría. Esa es una experiencia de depuración que no encontrarás en ningún otro lado.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Aspire 13.2 transforma el dashboard de &amp;ldquo;bonita UI de depuración&amp;rdquo; a &amp;ldquo;plataforma de observabilidad programable&amp;rdquo;. El flujo de exportación/importación por sí solo ahorra tiempo real en depuración distribuida, y la API de telemetría abre la puerta al diagnóstico asistido por IA.&lt;/p&gt;
&lt;p&gt;Si ya estás en Aspire, actualiza. Si no — esta es una buena razón para echarle un vistazo a &lt;a href="https://aspire.dev"&gt;aspire.dev&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>La actualización de marzo de Visual Studio te permite crear agentes Copilot personalizados — y find_symbol es clave</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/visual-studio-march-2026-custom-copilot-agents/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/visual-studio-march-2026-custom-copilot-agents/</guid><description>La actualización de marzo 2026 de Visual Studio trae agentes Copilot personalizados, skills reutilizables, la herramienta find_symbol con reconocimiento de lenguaje, y profiling con Copilot desde Test Explorer.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/visual-studio-march-2026-custom-copilot-agents/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Visual Studio acaba de recibir su actualización de Copilot más significativa hasta ahora. Mark Downie &lt;a href="https://devblogs.microsoft.com/visualstudio/visual-studio-march-update-build-your-own-custom-agents/"&gt;anunció la versión de marzo&lt;/a&gt;, y el titular son los agentes personalizados — pero honestamente, la herramienta &lt;code&gt;find_symbol&lt;/code&gt; podría ser la función que más cambie tu flujo de trabajo.&lt;/p&gt;
&lt;h2 id="agentes-copilot-personalizados-en-tu-repo"&gt;Agentes Copilot personalizados en tu repo&lt;/h2&gt;
&lt;p&gt;¿Quieres que Copilot siga los estándares de código de tu equipo, ejecute tu pipeline de build, o consulte tus docs internos? Ahora puedes construir exactamente eso.&lt;/p&gt;
&lt;p&gt;Los agentes personalizados se definen como archivos &lt;code&gt;.agent.md&lt;/code&gt; que colocas en &lt;code&gt;.github/agents/&lt;/code&gt; en tu repositorio. Cada agente tiene acceso completo al workspace, comprensión del código, herramientas, tu modelo preferido, y conexiones MCP a servicios externos.&lt;/p&gt;
&lt;h2 id="agent-skills-paquetes-de-instrucciones-reutilizables"&gt;Agent skills: paquetes de instrucciones reutilizables&lt;/h2&gt;
&lt;p&gt;Los skills se cargan automáticamente desde &lt;code&gt;.github/skills/&lt;/code&gt; en tu repo o &lt;code&gt;~/.copilot/skills/&lt;/code&gt; en tu perfil. Piensa en los skills como experiencia modular que puedes mezclar y combinar.&lt;/p&gt;
&lt;h2 id="find_symbol-navegación-con-reconocimiento-de-lenguaje"&gt;find_symbol: navegación con reconocimiento de lenguaje&lt;/h2&gt;
&lt;p&gt;La nueva herramienta &lt;code&gt;find_symbol&lt;/code&gt; le da al modo agente de Copilot navegación de símbolos basada en servicios de lenguaje. En lugar de buscar texto, el agente puede encontrar todas las referencias a un símbolo, acceder a información de tipos, declaraciones y alcance.&lt;/p&gt;
&lt;p&gt;Para desarrolladores .NET, esto es una mejora enorme — las bases de código C# con jerarquías de tipos profundas e interfaces se benefician enormemente.&lt;/p&gt;
&lt;h2 id="perfilar-tests-con-copilot"&gt;Perfilar tests con Copilot&lt;/h2&gt;
&lt;p&gt;Hay un nuevo comando &lt;strong&gt;Profile with Copilot&lt;/strong&gt; en el menú contextual del Test Explorer. Selecciona un test, haz clic en perfilar, y el Profiling Agent lo ejecuta y analiza automáticamente.&lt;/p&gt;
&lt;h2 id="perf-tips-durante-debugging-en-vivo"&gt;Perf tips durante debugging en vivo&lt;/h2&gt;
&lt;p&gt;La optimización de rendimiento ahora ocurre mientras depuras. Visual Studio muestra tiempo de ejecución y señales de rendimiento inline. ¿Ves una línea lenta? Haz clic en el Perf Tip y pídele a Copilot sugerencias de optimización.&lt;/p&gt;
&lt;h2 id="corregir-vulnerabilidades-de-nuget-desde-solution-explorer"&gt;Corregir vulnerabilidades de NuGet desde Solution Explorer&lt;/h2&gt;
&lt;p&gt;Cuando se detecta una vulnerabilidad en un paquete NuGet, verás un enlace &lt;strong&gt;Fix with GitHub Copilot&lt;/strong&gt; directamente en Solution Explorer.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Agentes personalizados y skills son el titular, pero &lt;code&gt;find_symbol&lt;/code&gt; es la joya oculta — cambia fundamentalmente la precisión de Copilot al refactorizar código .NET. Combinado con profiling en vivo y corrección de vulnerabilidades, esta actualización hace que las funciones de IA de Visual Studio se sientan genuinamente prácticas.&lt;/p&gt;
&lt;p&gt;Descarga &lt;a href="https://visualstudio.microsoft.com/downloads/"&gt;Visual Studio 2026 Insiders&lt;/a&gt; para probarlo todo.&lt;/p&gt;</content:encoded></item><item><title>KubeCon Europe 2026: Lo que los desarrolladores .NET deberían saber de verdad</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/kubecon-2026-aks-updates-dotnet-developers/</link><pubDate>Sun, 29 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/kubecon-2026-aks-updates-dotnet-developers/</guid><description>Microsoft lanzó una avalancha de anuncios de Kubernetes en KubeCon Europe 2026. Aquí va la versión filtrada — solo las actualizaciones de AKS y cloud-native que importan si trabajas con apps .NET.</description><content:encoded>&lt;p&gt;&lt;em&gt;Esta publicación fue traducida automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/news/emiliano-montesdeoca/kubecon-2026-aks-updates-dotnet-developers/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;¿Conoces esa sensación cuando cae un post de anuncios enorme y estás scrolleando pensando &amp;ldquo;genial, pero qué cambia esto realmente para mí&amp;rdquo;? Eso me pasa cada temporada de KubeCon.&lt;/p&gt;
&lt;p&gt;Microsoft acaba de publicar su &lt;a href="https://opensource.microsoft.com/blog/2026/03/24/whats-new-with-microsoft-in-open-source-and-kubernetes-at-kubecon-cloudnativecon-europe-2026/"&gt;resumen completo de KubeCon Europe 2026&lt;/a&gt; — escrito por el mismísimo Brendan Burns — y sinceramente, hay sustancia real aquí. No solo checkboxes de features, sino mejoras operacionales que cambian cómo manejas las cosas en producción.&lt;/p&gt;
&lt;p&gt;Te resumo lo que realmente importa para nosotros los desarrolladores .NET.&lt;/p&gt;
&lt;h2 id="mtls-sin-el-impuesto-del-service-mesh"&gt;mTLS sin el impuesto del service mesh&lt;/h2&gt;
&lt;p&gt;Aquí va la cosa sobre los service meshes: todo el mundo quiere las garantías de seguridad, nadie quiere la carga operacional. AKS por fin está cerrando esa brecha.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aka.ms/aks/application-network"&gt;Azure Kubernetes Application Network&lt;/a&gt; te da TLS mutuo, autorización basada en identidad de aplicación y telemetría de tráfico — sin desplegar un mesh pesado con sidecars. Combinado con &lt;a href="https://aka.ms/acns/cilium-mtls"&gt;Cilium mTLS en Advanced Container Networking Services&lt;/a&gt;, tienes comunicación encriptada pod-a-pod usando certificados X.509 y SPIRE para gestión de identidades.&lt;/p&gt;
&lt;p&gt;¿Qué significa esto en la práctica? Tus APIs de ASP.NET Core hablando con workers en segundo plano, tus servicios gRPC llamándose entre sí — todo encriptado y verificado a nivel de red, sin cambios en el código de la aplicación. Eso es enorme.&lt;/p&gt;
&lt;p&gt;Para equipos migrando desde &lt;code&gt;ingress-nginx&lt;/code&gt;, también hay &lt;a href="https://aka.ms/aks/app-routing/gateway-api"&gt;Application Routing con Meshless Istio&lt;/a&gt; con soporte completo de Kubernetes Gateway API. Sin sidecars. Basado en estándares. Y lanzaron herramientas &lt;code&gt;ingress2gateway&lt;/code&gt; para migración incremental.&lt;/p&gt;
&lt;h2 id="observabilidad-de-gpu-que-no-es-un-añadido-secundario"&gt;Observabilidad de GPU que no es un añadido secundario&lt;/h2&gt;
&lt;p&gt;Si estás ejecutando inferencia de IA junto a tus servicios .NET (y seamos honestos, ¿quién no está empezando a hacerlo?), probablemente has topado con el punto ciego del monitoreo de GPU. Tenías dashboards geniales de CPU/memoria y luego&amp;hellip; nada para GPUs sin configuración manual de exportadores.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aka.ms/aks/managed-gpu-metrics"&gt;AKS ahora expone métricas de GPU nativamente&lt;/a&gt; en Prometheus y Grafana gestionados. Mismo stack, mismos dashboards, mismo pipeline de alertas. Sin exportadores custom, sin agentes de terceros.&lt;/p&gt;
&lt;p&gt;En el lado de red, añadieron visibilidad por flujo para tráfico HTTP, gRPC y Kafka con una &lt;a href="https://learn.microsoft.com/en-us/azure/aks/container-network-observability-logs"&gt;experiencia one-click en Azure Monitor&lt;/a&gt;. IPs, puertos, workloads, dirección de flujo, decisiones de políticas — todo en dashboards integrados.&lt;/p&gt;
&lt;p&gt;Y aquí viene la que me hizo mirar dos veces: &lt;a href="https://learn.microsoft.com/en-us/azure/aks/advanced-container-networking-services-overview"&gt;agentic container networking&lt;/a&gt; añade una UI web donde puedes hacer preguntas en lenguaje natural sobre el estado de red de tu cluster. &amp;ldquo;¿Por qué el pod X no llega al servicio Y?&amp;rdquo; → diagnósticos de solo lectura desde telemetría en vivo. Eso es genuinamente útil a las 2 AM.&lt;/p&gt;
&lt;h2 id="networking-cross-cluster-que-no-requiere-un-doctorado"&gt;Networking cross-cluster que no requiere un doctorado&lt;/h2&gt;
&lt;p&gt;Multi-cluster en Kubernetes históricamente ha sido una experiencia de &amp;ldquo;trae tu propio pegamento de red&amp;rdquo;. Azure Kubernetes Fleet Manager ahora incluye &lt;a href="https://aka.ms/kubernetes-fleet/networking/cross-cluster"&gt;networking cross-cluster&lt;/a&gt; mediante Cilium cluster mesh gestionado:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Conectividad unificada entre clusters AKS&lt;/li&gt;
&lt;li&gt;Registro global de servicios para descubrimiento cross-cluster&lt;/li&gt;
&lt;li&gt;Configuración gestionada centralmente, no repetida por cluster&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si estás corriendo microservicios .NET en varias regiones por resiliencia o cumplimiento, esto reemplaza mucho pegamento custom frágil. El Servicio A en West Europe puede descubrir y llamar al Servicio B en East US a través del mesh, con políticas de routing y seguridad consistentes.&lt;/p&gt;
&lt;h2 id="upgrades-que-no-requieren-valentía"&gt;Upgrades que no requieren valentía&lt;/h2&gt;
&lt;p&gt;Seamos honestos — los upgrades de Kubernetes en producción son estresantes. &amp;ldquo;Actualizar y rezar&amp;rdquo; ha sido la estrategia de facto para demasiados equipos, y es la razón principal por la que los clusters se quedan atrás en versiones.&lt;/p&gt;
&lt;p&gt;Dos nuevas capacidades cambian esto:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Blue-green agent pool upgrades&lt;/strong&gt; crean un pool de nodos paralelo con la nueva configuración. Valida el comportamiento, mueve tráfico gradualmente y mantén un camino limpio de rollback. No más mutaciones in-place en nodos de producción.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agent pool rollback&lt;/strong&gt; te permite revertir un pool de nodos a su versión anterior de Kubernetes e imagen de nodo después de que un upgrade sale mal — sin reconstruir el cluster.&lt;/p&gt;
&lt;p&gt;Juntos, finalmente dan a los operadores control real sobre el ciclo de vida de upgrades. Para equipos .NET, esto importa porque la velocidad de la plataforma controla directamente qué tan rápido puedes adoptar nuevos runtimes, parches de seguridad y capacidades de red.&lt;/p&gt;
&lt;h2 id="los-workloads-de-ia-se-convierten-en-ciudadanos-de-primera-clase-de-kubernetes"&gt;Los workloads de IA se convierten en ciudadanos de primera clase de Kubernetes&lt;/h2&gt;
&lt;p&gt;El trabajo upstream en open-source es igualmente importante. Dynamic Resource Allocation (DRA) acaba de llegar a GA en Kubernetes 1.36, haciendo del scheduling de GPU una feature de primera clase en lugar de un workaround.&lt;/p&gt;
&lt;p&gt;Algunos proyectos que vale la pena seguir:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Proyecto&lt;/th&gt;
&lt;th&gt;Qué hace&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/kaito-project/kubeairunway"&gt;AI Runway&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;API común de Kubernetes para inferencia — despliega modelos sin saber K8s, con descubrimiento en HuggingFace y estimaciones de costo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.cncf.io/blog/2026/01/07/holmesgpt-agentic-troubleshooting-built-for-the-cloud-native-era/"&gt;HolmesGPT&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Troubleshooting agéntico para cloud-native — ahora proyecto CNCF Sandbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/project-dalec/dalec"&gt;Dalec&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Builds declarativos de imágenes de contenedor con generación de SBOM — menos CVEs en la etapa de build&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;La dirección es clara: tu API .NET, tu capa de orquestación con Semantic Kernel y tus workloads de inferencia deberían correr todos en un modelo de plataforma consistente. Estamos llegando ahí.&lt;/p&gt;
&lt;h2 id="por-dónde-empezaría-esta-semana"&gt;Por dónde empezaría esta semana&lt;/h2&gt;
&lt;p&gt;Si estás evaluando estos cambios para tu equipo, esta es mi lista honesta de prioridades:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Observabilidad primero&lt;/strong&gt; — habilita métricas de GPU y logs de flujo de red en un cluster no-prod. Mira lo que te has estado perdiendo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prueba blue-green upgrades&lt;/strong&gt; — testea el workflow de rollback antes de tu próximo upgrade de cluster en producción. Construye confianza en el proceso.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pilotea networking con identidad&lt;/strong&gt; — elige un path de servicio interno y habilita mTLS con Cilium. Mide el overhead (spoiler: es mínimo).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evalúa Fleet Manager&lt;/strong&gt; — si corres más de dos clusters, el networking cross-cluster se paga solo en reducción de pegamento custom.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Experimentos pequeños, feedback rápido. Esa es siempre la jugada.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Los anuncios de KubeCon pueden ser abrumadores, pero esta tanda genuinamente mueve la aguja para equipos .NET en AKS. Mejor seguridad de red sin overhead de mesh, observabilidad real de GPU, upgrades más seguros y bases más fuertes para infraestructura de IA.&lt;/p&gt;
&lt;p&gt;Si ya estás en AKS, es un gran momento para ajustar tu baseline operacional. Y si estás planeando mover workloads .NET a Kubernetes — la plataforma acaba de ponerse significativamente más lista para producción.&lt;/p&gt;</content:encoded></item><item><title>Foundry Agent Service está en GA: Lo que realmente importa para constructores de agentes .NET</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/foundry-agent-service-ga-what-matters/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/foundry-agent-service-ga-what-matters/</guid><description>El Foundry Agent Service de Microsoft acaba de llegar a GA con redes privadas, Voice Live, evaluaciones de producción y un runtime multi-modelo abierto. Esto es lo que necesitas saber.</description><content:encoded>&lt;p&gt;Seamos honestos — construir un prototipo de agente IA es la parte fácil. La parte difícil es todo lo que viene después: ponerlo en producción con aislamiento de red adecuado, ejecutar evaluaciones que realmente signifiquen algo, manejar requisitos de cumplimiento, y no romper cosas a las 2 AM.&lt;/p&gt;
&lt;p&gt;El &lt;a href="https://devblogs.microsoft.com/foundry/foundry-agent-service-ga/"&gt;Foundry Agent Service acaba de llegar a GA&lt;/a&gt;, y esta versión está enfocada como un láser en esa brecha del &amp;ldquo;todo lo que viene después&amp;rdquo;.&lt;/p&gt;
&lt;h2 id="construido-sobre-la-responses-api"&gt;Construido sobre la Responses API&lt;/h2&gt;
&lt;p&gt;El titular: el Foundry Agent Service de nueva generación está construido sobre la OpenAI Responses API. Si ya estás construyendo con ese protocolo, migrar a Foundry requiere cambios mínimos de código. Lo que ganas: seguridad empresarial, redes privadas, RBAC con Entra, trazabilidad completa y evaluación — sobre tu lógica de agente existente.&lt;/p&gt;
&lt;p&gt;La arquitectura es intencionalmente abierta. No estás atado a un proveedor de modelos ni a un framework de orquestación. Usa DeepSeek para planificación, OpenAI para generación, LangGraph para orquestación — el runtime maneja la capa de consistencia.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptAgentDefinition&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_PROJECT_ENDPOINT&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_openai_client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-enterprise-agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PromptAgentDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_MODEL_DEPLOYMENT_NAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conversation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conversations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;What are best practices for building AI agents?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;extra_body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Si vienes del paquete &lt;code&gt;azure-ai-agents&lt;/code&gt;, los agentes ahora son operaciones de primera clase en &lt;code&gt;AIProjectClient&lt;/code&gt; en &lt;code&gt;azure-ai-projects&lt;/code&gt;. Elimina la dependencia independiente y usa &lt;code&gt;get_openai_client()&lt;/code&gt; para manejar las respuestas.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="redes-privadas-el-bloqueador-empresarial-eliminado"&gt;Redes privadas: el bloqueador empresarial eliminado&lt;/h2&gt;
&lt;p&gt;Esta es la característica que desbloquea la adopción empresarial. Foundry ahora soporta redes privadas completas de extremo a extremo con BYO VNet:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sin egress público&lt;/strong&gt; — el tráfico del agente nunca toca internet público&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inyección de contenedores/subredes&lt;/strong&gt; en tu red para comunicación local&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conectividad de herramientas incluida&lt;/strong&gt; — servidores MCP, Azure AI Search, agentes de datos Fabric, todos operan sobre rutas privadas&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ese último punto es crítico. No son solo las llamadas de inferencia las que se mantienen privadas — cada invocación de herramienta y llamada de recuperación también permanece dentro del límite de tu red. Para equipos que operan bajo políticas de clasificación de datos que prohíben el enrutamiento externo, esto era lo que faltaba.&lt;/p&gt;
&lt;h2 id="autenticación-mcp-hecha-correctamente"&gt;Autenticación MCP hecha correctamente&lt;/h2&gt;
&lt;p&gt;Las conexiones a servidores MCP ahora soportan el espectro completo de patrones de autenticación:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Método de auth&lt;/th&gt;
&lt;th&gt;Cuándo usarlo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basado en clave&lt;/td&gt;
&lt;td&gt;Acceso compartido simple para herramientas internas de toda la organización&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entra Agent Identity&lt;/td&gt;
&lt;td&gt;Servicio a servicio; el agente se autentica como él mismo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entra Managed Identity&lt;/td&gt;
&lt;td&gt;Aislamiento por proyecto; sin gestión de credenciales&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OAuth Identity Passthrough&lt;/td&gt;
&lt;td&gt;Acceso delegado por usuario; el agente actúa en nombre de los usuarios&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;OAuth Identity Passthrough es el interesante. Cuando los usuarios necesitan dar a un agente acceso a sus datos personales — su OneDrive, su organización de Salesforce, una API SaaS con alcance por usuario — el agente actúa en su nombre con flujos OAuth estándar. Sin identidad de sistema compartida pretendiendo ser todos.&lt;/p&gt;
&lt;h2 id="voice-live-voz-a-voz-sin-la-fontanería"&gt;Voice Live: voz a voz sin la fontanería&lt;/h2&gt;
&lt;p&gt;Agregar voz a un agente solía significar unir STT, LLM y TTS — tres servicios, tres saltos de latencia, tres superficies de facturación, todo sincronizado a mano. &lt;strong&gt;Voice Live&lt;/strong&gt; colapsa eso en una única API administrada con:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Detección semántica de actividad de voz y fin de turno (entiende significado, no solo silencio)&lt;/li&gt;
&lt;li&gt;Supresión de ruido y cancelación de eco del lado del servidor&lt;/li&gt;
&lt;li&gt;Soporte de interrupción (los usuarios pueden interrumpir a mitad de respuesta)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Las interacciones de voz pasan por el mismo runtime de agente que el texto. Mismos evaluadores, mismas trazas, misma visibilidad de costos. Para soporte al cliente, servicio en campo o escenarios de accesibilidad, esto reemplaza lo que antes requería un pipeline de audio personalizado.&lt;/p&gt;
&lt;h2 id="evaluaciones-de-checkbox-a-monitoreo-continuo"&gt;Evaluaciones: de checkbox a monitoreo continuo&lt;/h2&gt;
&lt;p&gt;Aquí es donde Foundry se pone serio sobre la calidad en producción. El sistema de evaluación ahora tiene tres capas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Evaluadores incorporados&lt;/strong&gt; — coherencia, relevancia, fundamentación, calidad de recuperación, seguridad. Conecta a un dataset o tráfico en vivo y obtén puntuaciones.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Evaluadores personalizados&lt;/strong&gt; — codifica tu propia lógica de negocio, estándares de tono y reglas de cumplimiento específicas del dominio.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Evaluación continua&lt;/strong&gt; — Foundry muestrea tráfico de producción en vivo, ejecuta tu suite de evaluadores y muestra resultados en dashboards. Configura alertas de Azure Monitor para cuando la fundamentación baje o los umbrales de seguridad se superen.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Todo se publica en Azure Monitor Application Insights. Calidad del agente, salud de la infraestructura, costo y telemetría de la aplicación — todo en un solo lugar.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;eval_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;evals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Agent Quality Evaluation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;data_source_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DataSourceConfigCustom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;custom&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;item_schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;required&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;include_sample_schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;testing_criteria&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;azure_ai_evaluator&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fluency&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;evaluator_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;builtin.fluency&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;initialization_parameters&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;deployment_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_MODEL_DEPLOYMENT_NAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;data_mapping&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;{{item.query}}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;response&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;{{sample.output_text}}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="seis-nuevas-regiones-para-agentes-hospedados"&gt;Seis nuevas regiones para agentes hospedados&lt;/h2&gt;
&lt;p&gt;Los agentes hospedados ahora están disponibles en East US, North Central US, Sweden Central, Southeast Asia, Japan East y más. Esto importa para requisitos de residencia de datos y para comprimir la latencia cuando tu agente corre cerca de sus fuentes de datos.&lt;/p&gt;
&lt;h2 id="por-qué-esto-importa-para-desarrolladores-net"&gt;Por qué esto importa para desarrolladores .NET&lt;/h2&gt;
&lt;p&gt;Aunque los ejemplos de código en el anuncio de GA son Python-first, la infraestructura subyacente es agnóstica al lenguaje — y el SDK de .NET para &lt;code&gt;azure-ai-projects&lt;/code&gt; sigue los mismos patrones. La Responses API, el framework de evaluación, las redes privadas, la autenticación MCP — todo esto está disponible desde .NET.&lt;/p&gt;
&lt;p&gt;Si has estado esperando a que los agentes IA pasen de &amp;ldquo;demo genial&amp;rdquo; a &amp;ldquo;realmente puedo enviar esto al trabajo&amp;rdquo;, esta versión GA es la señal. Redes privadas, autenticación adecuada, evaluación continua y monitoreo de producción son las piezas que faltaban.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Foundry Agent Service está disponible ahora. Instala el SDK, abre &lt;a href="https://ai.azure.com"&gt;el portal&lt;/a&gt;, y empieza a construir. La &lt;a href="https://learn.microsoft.com/azure/foundry/quickstarts/get-started-code"&gt;guía de inicio rápido&lt;/a&gt; te lleva de cero a un agente en ejecución en minutos.&lt;/p&gt;
&lt;p&gt;Para el análisis técnico completo con todos los ejemplos de código, revisa el &lt;a href="https://devblogs.microsoft.com/foundry/foundry-agent-service-ga/"&gt;anuncio de GA&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Respuestas en segundo plano en Microsoft Agent Framework: Se acabó la ansiedad por timeouts</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/background-responses-agent-framework-long-running-tasks/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/background-responses-agent-framework-long-running-tasks/</guid><description>Microsoft Agent Framework ahora te permite descargar tareas de IA de larga duración con tokens de continuación. Así es cómo funcionan las respuestas en segundo plano y por qué importan para tus agentes .NET.</description><content:encoded>&lt;p&gt;Si has construido algo con modelos de razonamiento como o3 o GPT-5.2, conoces el dolor. Tu agente empieza a pensar en una tarea compleja, el cliente se queda esperando, y en algún punto entre &amp;ldquo;todo está bien&amp;rdquo; y &amp;ldquo;¿se habrá colgado?&amp;rdquo; tu conexión se corta por timeout. ¿Todo ese trabajo? Perdido.&lt;/p&gt;
&lt;p&gt;Microsoft Agent Framework acaba de lanzar &lt;a href="https://devblogs.microsoft.com/agent-framework/handling-long-running-operations-with-background-responses/"&gt;respuestas en segundo plano&lt;/a&gt; — y honestamente, esta es una de esas funcionalidades que deberían haber existido desde el primer día.&lt;/p&gt;
&lt;h2 id="el-problema-con-las-llamadas-bloqueantes"&gt;El problema con las llamadas bloqueantes&lt;/h2&gt;
&lt;p&gt;En un patrón tradicional de petición-respuesta, tu cliente se bloquea hasta que el agente termine. Eso funciona bien para tareas rápidas. Pero cuando le pides a un modelo de razonamiento que haga investigación profunda, análisis de múltiples pasos, o genere un informe de 20 páginas? Estás mirando minutos de tiempo real. Durante esa ventana:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Las conexiones HTTP pueden expirar&lt;/li&gt;
&lt;li&gt;Los cortes de red matan toda la operación&lt;/li&gt;
&lt;li&gt;Tu usuario se queda mirando un spinner preguntándose si algo está pasando&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Las respuestas en segundo plano le dan la vuelta a esto.&lt;/p&gt;
&lt;h2 id="cómo-funcionan-los-tokens-de-continuación"&gt;Cómo funcionan los tokens de continuación&lt;/h2&gt;
&lt;p&gt;En lugar de bloquear, lanzas la tarea del agente y recibes un &lt;strong&gt;token de continuación&lt;/strong&gt;. Piénsalo como un ticket de recogida en un taller de reparaciones — no te quedas parado en el mostrador esperando, vuelves cuando está listo.&lt;/p&gt;
&lt;p&gt;El flujo es directo:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Envía tu petición con &lt;code&gt;AllowBackgroundResponses = true&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Si el agente soporta procesamiento en segundo plano, recibes un token de continuación&lt;/li&gt;
&lt;li&gt;Consulta a tu ritmo hasta que el token vuelva &lt;code&gt;null&lt;/code&gt; — eso significa que el resultado está listo&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Aquí está la versión .NET:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AIAgent&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AzureOpenAIClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://&amp;lt;myresource&amp;gt;.openai.azure.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetResponsesClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;lt;deployment-name&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsAIAgent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentRunOptions&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AllowBackgroundResponses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentSession&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateSessionAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Write a detailed market analysis for the Q4 product launch.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Consultar hasta completar&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si el agente completa inmediatamente (tareas simples, modelos que no necesitan procesamiento en segundo plano), no se devuelve ningún token de continuación. Tu código simplemente funciona — sin manejo especial necesario.&lt;/p&gt;
&lt;h2 id="streaming-con-reanudación-la-verdadera-magia"&gt;Streaming con reanudación: la verdadera magia&lt;/h2&gt;
&lt;p&gt;El polling está bien para escenarios de disparar y olvidar, pero ¿qué pasa cuando quieres progreso en tiempo real? Las respuestas en segundo plano también soportan streaming con reanudación incorporada.&lt;/p&gt;
&lt;p&gt;Cada actualización del stream lleva su propio token de continuación. Si tu conexión se cae a mitad del stream, retomas exactamente donde lo dejaste:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentRunOptions&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AllowBackgroundResponses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentSession&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateSessionAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentResponseUpdate&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;latestUpdate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunStreamingAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Write a detailed market analysis for the Q4 product launch.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;latestUpdate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Simular una interrupción de red&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Reanudar desde exactamente donde lo dejamos&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;latestUpdate&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunStreamingAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El agente sigue procesando en el servidor independientemente de lo que pase con tu cliente. Eso es tolerancia a fallos incorporada sin que tú escribas lógica de reintentos o circuit breakers.&lt;/p&gt;
&lt;h2 id="cuándo-usar-esto-realmente"&gt;Cuándo usar esto realmente&lt;/h2&gt;
&lt;p&gt;No toda llamada al agente necesita respuestas en segundo plano. Para completaciones rápidas, estás añadiendo complejidad sin razón. Pero aquí es donde brillan:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tareas de razonamiento complejo&lt;/strong&gt; — análisis de múltiples pasos, investigación profunda, cualquier cosa que haga a un modelo de razonamiento realmente pensar&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generación de contenido largo&lt;/strong&gt; — informes detallados, documentos de múltiples partes, análisis extenso&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Redes poco fiables&lt;/strong&gt; — clientes móviles, despliegues en el edge, VPNs corporativas inestables&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Patrones UX asíncronos&lt;/strong&gt; — envía una tarea, ve a hacer otra cosa, vuelve por los resultados&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para nosotros los desarrolladores .NET construyendo apps empresariales, ese último es particularmente interesante. Piensa en una app Blazor donde un usuario solicita un informe complejo — lanzas la tarea del agente, les muestras un indicador de progreso, y les dejas seguir trabajando. Sin gimnasia con WebSockets, sin infraestructura de colas personalizada, solo un token y un bucle de polling.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Las respuestas en segundo plano están disponibles ahora tanto en .NET como en Python a través de Microsoft Agent Framework. Si estás construyendo agentes que hacen algo más complejo que simple Q&amp;amp;A, vale la pena añadir esto a tu toolkit. El patrón de token de continuación mantiene las cosas simples mientras resuelve un problema de producción muy real.&lt;/p&gt;
&lt;p&gt;Revisa la &lt;a href="https://devblogs.microsoft.com/agent-framework/handling-long-running-operations-with-background-responses/"&gt;documentación completa&lt;/a&gt; para la referencia completa de la API y más ejemplos.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.112: Lo que los desarrolladores .NET realmente deberían importarles</title><link>https://thedotnetblog.com/es/news/emiliano-montesdeoca/vscode-1-112-dotnet-developers/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/news/emiliano-montesdeoca/vscode-1-112-dotnet-developers/</guid><description>VS Code 1.112 acaba de salir y viene cargado con mejoras de agentes, un depurador de navegador integrado, sandboxing MCP y soporte para monorepos. Esto es lo que realmente importa si desarrollas con .NET.</description><content:encoded>&lt;p&gt;VS Code 1.112 acaba de aterrizar, y ¿honestamente? Este pega diferente si pasas tus días en territorio .NET. Hay mucho en las &lt;a href="https://code.visualstudio.com/updates/v1_112"&gt;notas de la versión oficial&lt;/a&gt;, pero déjame ahorrarte algo de scroll y enfocarme en lo que realmente nos importa.&lt;/p&gt;
&lt;h2 id="copilot-cli-se-volvió-mucho-más-útil"&gt;Copilot CLI se volvió mucho más útil&lt;/h2&gt;
&lt;p&gt;El gran tema de esta versión es la &lt;strong&gt;autonomía del agente&lt;/strong&gt; — dar a Copilot más espacio para hacer lo suyo sin que tengas que supervisar cada paso.&lt;/p&gt;
&lt;h3 id="direccionamiento-y-cola-de-mensajes"&gt;Direccionamiento y cola de mensajes&lt;/h3&gt;
&lt;p&gt;¿Conoces ese momento cuando Copilot CLI va a la mitad de una tarea y te das cuenta de que olvidaste mencionar algo? Antes, tenías que esperar. Ahora puedes enviar mensajes mientras una solicitud aún está en progreso — ya sea para dirigir la respuesta actual o encolar instrucciones de seguimiento.&lt;/p&gt;
&lt;p&gt;Esto es enorme para esas tareas más largas de scaffolding con &lt;code&gt;dotnet&lt;/code&gt; donde estás viendo a Copilot configurar un proyecto y piensas &amp;ldquo;oh espera, también necesito MassTransit ahí&amp;rdquo;.&lt;/p&gt;
&lt;h3 id="niveles-de-permisos"&gt;Niveles de permisos&lt;/h3&gt;
&lt;p&gt;Este es el que más me emociona. Las sesiones de Copilot CLI ahora soportan tres niveles de permisos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Permisos por defecto&lt;/strong&gt; — el flujo usual donde las herramientas piden confirmación antes de ejecutarse&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Omitir aprobaciones&lt;/strong&gt; — auto-aprueba todo y reintenta en errores&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Autopiloto&lt;/strong&gt; — totalmente autónomo: aprueba herramientas, responde sus propias preguntas, y sigue hasta que la tarea está completa&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si estás haciendo algo como crear desde cero una nueva API ASP.NET Core con Entity Framework, migraciones, y un setup de Docker — el modo Autopiloto significa que describes lo que quieres y vas por un café. Él lo resolverá.&lt;/p&gt;
&lt;p&gt;Puedes habilitar Autopiloto con la configuración &lt;code&gt;chat.autopilot.enabled&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="previsualizar-cambios-antes-de-delegar"&gt;Previsualizar cambios antes de delegar&lt;/h3&gt;
&lt;p&gt;Cuando delegas una tarea a Copilot CLI, crea un worktree. Antes, si tenías cambios sin commit, tenías que revisar el Control de Código Fuente para ver qué se afectaría. Ahora la vista de Chat muestra los cambios pendientes ahí mismo antes de que decidas si copiarlos, moverlos o ignorarlos.&lt;/p&gt;
&lt;p&gt;Algo pequeño, pero te salva de ese momento de &amp;ldquo;espera, ¿qué tenía en staging?&amp;rdquo;.&lt;/p&gt;
&lt;h2 id="depura-apps-web-sin-salir-de-vs-code"&gt;Depura apps web sin salir de VS Code&lt;/h2&gt;
&lt;p&gt;El navegador integrado ahora soporta &lt;strong&gt;depuración completa&lt;/strong&gt;. Puedes poner breakpoints, hacer step through del código, e inspeccionar variables — todo dentro de VS Code. Se acabó cambiar a Edge DevTools.&lt;/p&gt;
&lt;p&gt;Hay un nuevo tipo de depuración &lt;code&gt;editor-browser&lt;/code&gt;, y si ya tienes configuraciones de lanzamiento &lt;code&gt;msedge&lt;/code&gt; o &lt;code&gt;chrome&lt;/code&gt; existentes, migrar es tan simple como cambiar el campo &lt;code&gt;type&lt;/code&gt; en tu &lt;code&gt;launch.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;editor-browser&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;launch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Debug Blazor App&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://localhost:5001&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Para desarrolladores de Blazor, esto es un game changer. Ya estás ejecutando &lt;code&gt;dotnet watch&lt;/code&gt; en la terminal — ahora tu depuración se queda en la misma ventana también.&lt;/p&gt;
&lt;p&gt;El navegador también obtuvo niveles de zoom independientes (por fin), menús de contexto con clic derecho apropiados, y el zoom se recuerda por sitio web.&lt;/p&gt;
&lt;h2 id="sandboxing-de-servidores-mcp"&gt;Sandboxing de servidores MCP&lt;/h2&gt;
&lt;p&gt;Esto importa más de lo que podrías pensar. Si estás usando servidores MCP — quizás has configurado uno personalizado para tus recursos de Azure o consultas de base de datos — han estado ejecutándose con los mismos permisos que tu proceso de VS Code. Eso significa acceso total a tu sistema de archivos, red, todo.&lt;/p&gt;
&lt;p&gt;Ahora puedes ponerlos en sandbox. En tu &lt;code&gt;mcp.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;servers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;my-azure-tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./mcp-server.js&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;sandboxEnabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cuando un servidor en sandbox necesita acceso a algo que no tiene, VS Code te solicita que otorgues permiso. Mucho mejor que el enfoque de &amp;ldquo;esperar que nadie haga nada raro&amp;rdquo;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; El sandboxing está disponible en macOS y Linux por ahora. El soporte para Windows viene pronto — aunque los escenarios remotos como WSL sí funcionan.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="descubrimiento-de-personalizaciones-en-monorepos"&gt;Descubrimiento de personalizaciones en monorepos&lt;/h2&gt;
&lt;p&gt;Si trabajas en un monorepo (y seamos honestos, muchas soluciones empresariales .NET terminan siendo uno), esto resuelve un punto de dolor real.&lt;/p&gt;
&lt;p&gt;Anteriormente, si abrías una subcarpeta de tu repo, VS Code no encontraba tu &lt;code&gt;copilot-instructions.md&lt;/code&gt;, &lt;code&gt;AGENTS.md&lt;/code&gt;, o skills personalizados ubicados en la raíz del repositorio. Ahora con la configuración &lt;code&gt;chat.useCustomizationsInParentRepositories&lt;/code&gt;, sube hasta la raíz &lt;code&gt;.git&lt;/code&gt; y descubre todo.&lt;/p&gt;
&lt;p&gt;Esto significa que tu equipo puede compartir instrucciones de agente, archivos de prompt y herramientas personalizadas a través de todos los proyectos en un monorepo sin que todos tengan que abrir la carpeta raíz.&lt;/p&gt;
&lt;h2 id="troubleshoot-para-depuración-de-agentes"&gt;/troubleshoot para depuración de agentes&lt;/h2&gt;
&lt;p&gt;¿Alguna vez configuraste instrucciones personalizadas o skills y te preguntaste por qué no se están detectando? El nuevo skill &lt;code&gt;/troubleshoot&lt;/code&gt; lee los logs de depuración del agente y te dice qué pasó — qué herramientas se usaron o se saltaron, por qué las instrucciones no cargaron, y qué está causando respuestas lentas.&lt;/p&gt;
&lt;p&gt;Habilítalo con:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;github.copilot.chat.agentDebugLog.enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;github.copilot.chat.agentDebugLog.fileLogging.enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Luego simplemente escribe &lt;code&gt;/troubleshoot why is my custom skill not loading?&lt;/code&gt; en el chat.&lt;/p&gt;
&lt;p&gt;También puedes exportar e importar estos logs de depuración ahora, lo cual es genial para compartir con tu equipo cuando algo no funciona como se esperaba.&lt;/p&gt;
&lt;h2 id="soporte-para-archivos-de-imagen-y-binarios"&gt;Soporte para archivos de imagen y binarios&lt;/h2&gt;
&lt;p&gt;Los agentes ahora pueden leer archivos de imagen desde disco y archivos binarios de forma nativa. Los archivos binarios se presentan en formato hexdump, y las salidas de imagen (como capturas de pantalla del navegador integrado) aparecen en una vista de carrusel.&lt;/p&gt;
&lt;p&gt;Para desarrolladores .NET, piensa: pega una captura de pantalla de un bug de UI en el chat y haz que el agente entienda qué está mal, o haz que analice la salida del renderizado de un componente Blazor.&lt;/p&gt;
&lt;h2 id="referencias-automáticas-de-símbolos"&gt;Referencias automáticas de símbolos&lt;/h2&gt;
&lt;p&gt;Pequeña mejora de calidad de vida: cuando copias el nombre de un símbolo (una clase, método, etc.) y lo pegas en el chat, VS Code ahora lo convierte automáticamente en una referencia &lt;code&gt;#sym:Name&lt;/code&gt;. Esto le da al agente contexto completo sobre ese símbolo sin que tengas que agregarlo manualmente.&lt;/p&gt;
&lt;p&gt;Si quieres texto plano en su lugar, usa &lt;code&gt;Ctrl+Shift+V&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="los-plugins-ahora-se-pueden-habilitardeshabilitar"&gt;Los plugins ahora se pueden habilitar/deshabilitar&lt;/h2&gt;
&lt;p&gt;Anteriormente, deshabilitar un servidor MCP o plugin significaba desinstalarlo. Ahora puedes activarlos y desactivarlos — tanto globalmente como por workspace. Clic derecho en la vista de Extensiones o la vista de Personalizaciones y listo.&lt;/p&gt;
&lt;p&gt;Los plugins de npm y pypi también pueden auto-actualizarse ahora, aunque pedirán aprobación primero ya que las actualizaciones significan ejecutar código nuevo en tu máquina.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;VS Code 1.112 está claramente empujando fuerte en la experiencia del agente — más autonomía, mejor depuración, seguridad más ajustada. Para desarrolladores .NET, la depuración del navegador integrado y las mejoras de Copilot CLI son las características destacadas.&lt;/p&gt;
&lt;p&gt;Si aún no has probado ejecutar una sesión completa de Copilot CLI en modo Autopiloto para un proyecto .NET, esta versión es un buen momento para empezar. Solo recuerda configurar tus permisos y dejarlo cocinar.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/updates/v1_112"&gt;Descarga VS Code 1.112&lt;/a&gt; o actualiza desde dentro de VS Code vía &lt;strong&gt;Ayuda &amp;gt; Buscar actualizaciones&lt;/strong&gt;.&lt;/p&gt;</content:encoded></item></channel></rss>