<?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>The .NET Blog</title><link>https://thedotnetblog.com/es/</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, 14 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/es/index.xml" rel="self" type="application/rss+xml"/><item><title>NDC Oslo 2026</title><link>https://thedotnetblog.com/es/events/ndc-oslo-2026/</link><pubDate>Mon, 14 Sep 2026 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/es/events/ndc-oslo-2026/</guid><description>Una de las conferencias de desarrolladores más grandes de Europa — 5 días de talleres, sesiones y networking en Oslo Spektrum con más de 150 ponentes y 160 sesiones.</description><content:encoded>&lt;p&gt;&lt;strong&gt;NDC Oslo 2026&lt;/strong&gt; se celebra del &lt;strong&gt;14 al 18 de septiembre de 2026&lt;/strong&gt; en &lt;strong&gt;Oslo Spektrum&lt;/strong&gt;, Oslo, Noruega.&lt;/p&gt;
&lt;p&gt;NDC Oslo es una de las conferencias de desarrolladores más grandes y respetadas de Europa, cubriendo todo, desde .NET y cloud hasta seguridad, arquitectura, IA y más. La edición 2026 está actualmente en fase de reservas, con una programación masiva en preparación.&lt;/p&gt;
&lt;h2 id="en-números"&gt;En números&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;160 sesiones&lt;/strong&gt; (en reserva)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;150 ponentes&lt;/strong&gt; (en reserva)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;15 talleres&lt;/strong&gt; (en reserva)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5 días&lt;/strong&gt; — talleres + conferencia&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ponentes-confirmados"&gt;Ponentes confirmados&lt;/h2&gt;
&lt;p&gt;La lista de ponentes se está completando, con nombres confirmados como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Nick Chapsas&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maddy Montaquila&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Troy Hunt&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kevlin Henney&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Venkat Subramaniam&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Jeff Fritz&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Philippe De Ryck&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nhlanhla Lucky Nkosi&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aleksander Stensby&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="entradas"&gt;Entradas&lt;/h2&gt;
&lt;p&gt;Las entradas Early Bird están disponibles — la oferta Early Bird finaliza el &lt;strong&gt;22 de mayo de 2026&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;La convocatoria de ponencias (CFP) también está abierta.&lt;/p&gt;
&lt;h2 id="otros-eventos-ndc-en-2026"&gt;Otros eventos NDC en 2026&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;NDC Sydney — 22–24 de abril, 2026&lt;/li&gt;
&lt;li&gt;NDC Toronto — 5–8 de mayo, 2026&lt;/li&gt;
&lt;li&gt;NDC Copenhagen — 1–4 de junio, 2026&lt;/li&gt;
&lt;li&gt;NDC AI — 8–10 de junio, 2026&lt;/li&gt;
&lt;li&gt;NDC TechTown — 21–24 de septiembre, 2026&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="enlaces"&gt;Enlaces&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ndcoslo.com/"&gt;Sitio web del evento&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ndcoslo.com/tickets"&gt;Entradas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ndcoslo.com/call-for-papers"&gt;Convocatoria de ponencias&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ndcoslo.com/speakers"&gt;Ponentes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>.NET Day Switzerland 2026</title><link>https://thedotnetblog.com/es/events/dotnet-day-switzerland-2026/</link><pubDate>Tue, 25 Aug 2026 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/es/events/dotnet-day-switzerland-2026/</guid><description>Una conferencia comunitaria sin fines de lucro para desarrolladores, arquitectos y expertos en .NET — cubriendo .NET, C#, ASP.NET Core, Azure y más — en Zúrich.</description><content:encoded>&lt;p&gt;&lt;strong&gt;.NET Day Switzerland 2026&lt;/strong&gt; se celebra el &lt;strong&gt;25 de agosto de 2026&lt;/strong&gt; en &lt;strong&gt;Arena Cinemas Sihlcity&lt;/strong&gt; (Kalanderplatz 8, 8045 Zúrich).&lt;/p&gt;
&lt;p&gt;Es una conferencia comunitaria independiente y sin fines de lucro para desarrolladores, arquitectos y expertos, donde se habla de .NET, C#, ASP.NET Core, Azure y el ecosistema de desarrollo de Microsoft en general. Todos los ponentes y el personal colaboran de forma voluntaria, y cualquier excedente de la venta de entradas se destina a caridad o a la comunidad .NET suiza.&lt;/p&gt;
&lt;h2 id="qué-incluye"&gt;Qué incluye&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Sesiones de alta calidad con expertos internacionales&lt;/li&gt;
&lt;li&gt;Networking con otros participantes&lt;/li&gt;
&lt;li&gt;Comida, snacks y bebidas durante las pausas, el almuerzo y el aperitivo&lt;/li&gt;
&lt;li&gt;Oportunidades profesionales a través de interacciones con patrocinadores&lt;/li&gt;
&lt;li&gt;Conversaciones directas con los ponentes durante las pausas&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="entradas"&gt;Entradas&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;th&gt;Precio&lt;/th&gt;
&lt;th&gt;Disponibilidad&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Very Early Bird (1–30 Abr)&lt;/td&gt;
&lt;td&gt;299 CHF&lt;/td&gt;
&lt;td&gt;Máx. 100 entradas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Early Bird&lt;/td&gt;
&lt;td&gt;399 CHF&lt;/td&gt;
&lt;td&gt;Máx. 100 entradas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regular&lt;/td&gt;
&lt;td&gt;449 CHF&lt;/td&gt;
&lt;td&gt;Hasta agotar&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Los ponentes y el programa aún no se han anunciado — la convocatoria está abierta en &lt;a href="https://sessionize.com/net-day-switzerland-2026/"&gt;Sessionize&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="organizadores"&gt;Organizadores&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/FabianGosebrink"&gt;Fabian Gosebrink&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/manumeyer1"&gt;Manuel Meyer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/gassmannt"&gt;Thomas Gassmann&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="enlaces"&gt;Enlaces&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dotnetday.ch/"&gt;Sitio web del evento&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://eepurl.com/dDoFEn"&gt;Suscripción al newsletter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><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>Actualización de Abril del Azure DevOps MCP Server: Consultas WIQL, Auth PAT y MCP Apps Experimental</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-devops-mcp-server-april-2026-wiql-pat-apps/</link><pubDate>Mon, 27 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-devops-mcp-server-april-2026-wiql-pat-apps/</guid><description>El Azure DevOps MCP Server recibe consultas de work items con WIQL, autenticación con Personal Access Token, anotaciones MCP, y una característica experimental de MCP Apps que empaqueta flujos de trabajo comunes.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/azure-devops-mcp-server-april-2026-wiql-pat-apps/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;El Azure DevOps MCP Server sigue mejorando. La actualización de abril de Dan Hellem cubre tanto los servidores local como remoto, y hay algunas adiciones genuinamente útiles.&lt;/p&gt;
&lt;h2 id="soporte-de-consultas-wiql"&gt;Soporte de Consultas WIQL&lt;/h2&gt;
&lt;p&gt;La nueva herramienta &lt;code&gt;wit_query_by_wiql&lt;/code&gt; permite ejecutar consultas Work Item Query Language directamente desde tu cliente MCP. Tus sesiones de Copilot pueden ahora obtener conjuntos precisos de work items sin filtrar manualmente.&lt;/p&gt;
&lt;h2 id="personal-access-tokens-en-el-servidor-local"&gt;Personal Access Tokens en el Servidor Local&lt;/h2&gt;
&lt;p&gt;El servidor MCP local ahora soporta autenticación PAT — importante para escenarios de integración donde la autenticación interactiva no está disponible.&lt;/p&gt;
&lt;h2 id="anotaciones-mcp-en-el-servidor-remoto"&gt;Anotaciones MCP en el Servidor Remoto&lt;/h2&gt;
&lt;p&gt;Etiquetas de metadatos para herramientas de solo lectura, destructivas y de mundo abierto — fundamentales para la fiabilidad de los agentes.&lt;/p&gt;
&lt;h2 id="consolidación-de-herramientas-wiki"&gt;Consolidación de Herramientas Wiki&lt;/h2&gt;
&lt;p&gt;5 herramientas separadas de wiki → 2 herramientas más capaces. Menos herramientas = mejor rendimiento del LLM.&lt;/p&gt;
&lt;h2 id="experimental-mcp-apps"&gt;Experimental: MCP Apps&lt;/h2&gt;
&lt;p&gt;Flujos de trabajo empaquetados que se ejecutan dentro del entorno del servidor MCP. La idea es correcta — más composición de flujos de trabajo en la capa MCP, menos encadenamiento ad-hoc de herramientas.&lt;/p&gt;
&lt;p&gt;Post original de Dan Hellem: &lt;a href="https://devblogs.microsoft.com/devops/azure-devops-mcp-server-april-update/"&gt;Azure DevOps MCP Server April Update&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>SQL Server 2025 como Base de Datos Lista para Agentes: Seguridad, Backup y MCP en un Solo Motor</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/sql-server-2025-agent-ready-security-mcp/</link><pubDate>Sun, 26 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/sql-server-2025-agent-ready-security-mcp/</guid><description>La parte final de la serie Polyglot Tax aborda los problemas difíciles de producción: seguridad unificada de Row-Level Security en datos relacionales, JSON, grafos y vectores, más integración MCP que hace a SQL Server 2025 genuinamente listo para agentes.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/sql-server-2025-agent-ready-security-mcp/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;He seguido la serie Polyglot Tax de Aditya Badramraju con mucho interés. Las partes 1-3 construyeron un caso convincente para SQL Server 2025 como una base de datos genuinamente multi-modelo. La parte 4 cierra la serie con las partes que realmente determinan si confiarías en esta arquitectura en producción.&lt;/p&gt;
&lt;h2 id="un-modelo-de-seguridad-para-todos-los-modelos-de-datos"&gt;Un Modelo de Seguridad para Todos los Modelos de Datos&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SECURITY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;POLICY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TenantIsolation&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="k"&gt;ADD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FILTER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PREDICATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn_TenantFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TenantID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customers&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="k"&gt;ADD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FILTER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PREDICATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn_TenantFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TenantID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Events&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="k"&gt;ADD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FILTER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PREDICATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn_TenantFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TenantID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Relationships&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="k"&gt;ADD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FILTER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PREDICATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn_TenantFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TenantID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Embeddings&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="k"&gt;WITH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;STATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Una política, una prueba. Para un auditor que pregunta &amp;ldquo;demuestra que el Tenant A no puede ver los datos del Tenant B&amp;rdquo;, esto es oro.&lt;/p&gt;
&lt;h2 id="backup-unificado--recuperación-atómica"&gt;Backup Unificado = Recuperación Atómica&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;RESTORE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DATABASE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MultiModelApp&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="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://storage.blob.core.windows.net/backups/MultiModelApp.bak&amp;#39;&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="k"&gt;WITH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;STOPAT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;2026-02-01 10:30:00&amp;#39;&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En un stack políglota, coordinar la recuperación de cinco bases de datos es una pesadilla de consistencia. Con una sola base de datos y un log de transacciones, la recuperación es atómica por definición.&lt;/p&gt;
&lt;h2 id="integración-mcp-agentes-sin-middleware-codificado-a-mano"&gt;Integración MCP: Agentes Sin Middleware Codificado a Mano&lt;/h2&gt;
&lt;p&gt;SQL Server 2025 soporta el SQL MCP Server directamente. Los agentes llaman herramientas, el motor impone aislamiento de tenant y enmascaramiento de columnas automáticamente.&lt;/p&gt;
&lt;h2 id="resumiendo"&gt;Resumiendo&lt;/h2&gt;
&lt;p&gt;Para desarrolladores .NET construyendo aplicaciones con agentes en Azure SQL, esta arquitectura merece consideración seria. Post original de Aditya Badramraju: &lt;a href="https://devblogs.microsoft.com/azure-sql/the-polyglot-tax-part-4/"&gt;The Polyglot Tax – Part 4&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>¿Dónde Recuerda las Cosas tu Agente? Guía Práctica sobre el Almacenamiento del Historial de Chat</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/chat-history-storage-patterns-agent-framework/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/chat-history-storage-patterns-agent-framework/</guid><description>¿Gestionado por el servicio o por el cliente? ¿Lineal o con bifurcaciones? La decisión arquitectónica que define lo que tu agente IA puede hacer realmente, con ejemplos de código en C# y Python.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/posts/emiliano-montesdeoca/chat-history-storage-patterns-agent-framework/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Cuando construyes un agente IA, dedicas la mayor parte de tu energía al modelo, las herramientas y los prompts. La pregunta de &lt;em&gt;dónde vive el historial de conversación&lt;/em&gt; parece un detalle de implementación — pero es una de las decisiones arquitectónicas más importantes que tomarás.&lt;/p&gt;
&lt;p&gt;Determina si los usuarios pueden bifurcar conversaciones, deshacer respuestas, reanudar sesiones después de un reinicio, y si tus datos salen alguna vez de tu infraestructura. El &lt;a href="https://devblogs.microsoft.com/agent-framework/chat-history-storage-patterns-in-microsoft-agent-framework/"&gt;equipo de Agent Framework publicó un análisis en profundidad&lt;/a&gt; y vale la pena entender el panorama completo.&lt;/p&gt;
&lt;h2 id="dos-patrones-fundamentales"&gt;Dos patrones fundamentales&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Gestionado por el servicio&lt;/strong&gt;: el servicio de IA almacena el estado de la conversación. Tu app mantiene una referencia (un ID de hilo, un ID de respuesta) y el servicio incluye automáticamente el historial relevante en cada solicitud. Más simple de configurar. Menos control.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gestionado por el cliente&lt;/strong&gt;: tu app mantiene el historial completo y envía mensajes relevantes con cada solicitud. El servicio no tiene estado. Controlas todo.&lt;/p&gt;
&lt;h2 id="gestionado-por-servicio-lineal-vs-bifurcación"&gt;Gestionado por servicio: lineal vs bifurcación&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Lineal (hilo único)&lt;/strong&gt;: los mensajes forman una secuencia ordenada. Puedes añadir pero no bifurcar. Ideal para chatbots y flujos simples. Malo para &amp;ldquo;inténtalo de nuevo&amp;rdquo; o exploración paralela.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Con capacidad de bifurcación&lt;/strong&gt;: cada respuesta tiene un ID único, y las nuevas solicitudes pueden referenciar cualquier respuesta anterior como punto de continuación. Esto es lo que soporta la API de Responses (Microsoft Foundry, Azure OpenAI, OpenAI). Permite bifurcar conversaciones y construir flujos de &amp;ldquo;deshacer&amp;rdquo;.&lt;/p&gt;
&lt;h2 id="cómo-agent-framework-abstrae-esto"&gt;Cómo Agent Framework abstrae esto&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="c1"&gt;// C# — funciona igual independientemente del proveedor&lt;/span&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;first&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;Me llamo Alice.&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&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;second&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;¿Cuál es mi nombre?&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&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&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="c1"&gt;# Python&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&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;create_session&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;first&lt;/span&gt; &lt;span class="o"&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Me llamo Alice.&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="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;session&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;second&lt;/span&gt; &lt;span class="o"&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;¿Cuál es mi nombre?&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="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;session&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;La sesión maneja las diferencias subyacentes. Este desacoplamiento es valioso para experimentar con diferentes proveedores sin reescribir tu código.&lt;/p&gt;
&lt;h2 id="referencia-rápida-de-proveedores"&gt;Referencia rápida de proveedores&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Proveedor&lt;/th&gt;
&lt;th&gt;Almacenamiento&lt;/th&gt;
&lt;th&gt;Modelo&lt;/th&gt;
&lt;th&gt;Compactación&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI/Azure Chat Completions&lt;/td&gt;
&lt;td&gt;Cliente&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Tú&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Foundry Agent Service&lt;/td&gt;
&lt;td&gt;Servicio&lt;/td&gt;
&lt;td&gt;Lineal&lt;/td&gt;
&lt;td&gt;Servicio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Responses API (por defecto)&lt;/td&gt;
&lt;td&gt;Servicio&lt;/td&gt;
&lt;td&gt;Bifurcación&lt;/td&gt;
&lt;td&gt;Servicio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Responses API (&lt;code&gt;store=false&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Cliente&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Tú&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic Claude, Ollama&lt;/td&gt;
&lt;td&gt;Cliente&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Tú&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="cómo-elegir"&gt;Cómo elegir&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;¿Necesitas bifurcación o &amp;ldquo;deshacer&amp;rdquo;?&lt;/strong&gt; → Responses API gestionado por servicio&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;¿Necesitas soberanía total de datos?&lt;/strong&gt; → Gestionado por cliente con proveedor respaldado por base de datos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;¿Es un chatbot sencillo?&lt;/strong&gt; → Lineal gestionado por servicio está bien&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;¿Necesitas portabilidad entre proveedores?&lt;/strong&gt; → Gestionado por cliente da portabilidad&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Lee el &lt;a href="https://devblogs.microsoft.com/agent-framework/chat-history-storage-patterns-in-microsoft-agent-framework/"&gt;post completo&lt;/a&gt; para el árbol de decisión completo y los detalles de la API de Conversations.&lt;/p&gt;</content:encoded></item><item><title>.NET 10 Se Incluye con Ubuntu 26.04 LTS — Qué hay de Nuevo</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/dotnet-ubuntu-2604-resolute-raccoon-net10/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/dotnet-ubuntu-2604-resolute-raccoon-net10/</guid><description>Ubuntu 26.04 LTS (Resolute Raccoon) llegó con .NET 10 como toolchain de primera clase. Native AOT, contenedores chiseled, Linux 7.0 — esto es lo que necesitas saber.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/posts/emiliano-montesdeoca/dotnet-ubuntu-2604-resolute-raccoon-net10/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Es el día de Ubuntu LTS. &lt;a href="https://canonical.com/blog/canonical-releases-ubuntu-26-04-lts-resolute-raccoon"&gt;Ubuntu 26.04 (Resolute Raccoon)&lt;/a&gt; llegó hoy, y como con cada Ubuntu LTS, incluye el último .NET LTS — en este caso, &lt;a href="https://devblogs.microsoft.com/dotnet/whats-new-for-dotnet-in-ubuntu-2604/"&gt;.NET 10&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;LTS sobre LTS — cinco años de soporte para el OS, alineados con la ventana de soporte a largo plazo de .NET 10.&lt;/p&gt;
&lt;h2 id="instala-net-10-en-dos-comandos"&gt;Instala .NET 10 en dos comandos&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;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install dotnet-sdk-10.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;.NET es uno de los &lt;a href="https://ubuntu.com/toolchains"&gt;toolchains oficialmente soportados en Ubuntu&lt;/a&gt; — no un add-on de terceros.&lt;/p&gt;
&lt;h2 id="pruébalo-de-inmediato"&gt;Pruébalo de inmediato&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;docker run --rm -it ubuntu:resolute
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install -y dotnet-sdk-10.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet run - &lt;span class="s"&gt;&amp;lt;&amp;lt; &amp;#39;EOF&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;using System.Runtime.InteropServices;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Console.WriteLine($&amp;#34;Hello {RuntimeInformation.OSDescription} from .NET {RuntimeInformation.FrameworkDescription}&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="contenedores-actualiza--noble-a--resolute"&gt;Contenedores: actualiza &lt;code&gt;-noble&lt;/code&gt; a &lt;code&gt;-resolute&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;La migración es de una línea:&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;sed -i &lt;span class="s2"&gt;&amp;#34;s/noble/resolute/g&amp;#34;&lt;/span&gt; Dockerfile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Todos los sabores de imagen existentes — incluyendo &lt;a href="https://devblogs.microsoft.com/dotnet/announcing-dotnet-chiseled-containers/"&gt;Chiseled&lt;/a&gt; — están disponibles.&lt;/p&gt;
&lt;h2 id="native-aot-arranque-en-3ms-binario-de-14mb"&gt;Native AOT: arranque en 3ms, binario de 1.4MB&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;apt install -y dotnet-sdk-aot-10.0 clang
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet publish app.cs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# artifacts/app/app — binario nativo de 1.4MB&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# real 0m0.003s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Para cargas de trabajo cloud-native donde el tiempo de arranque en frío importa — Functions, contenedores, serverless — esto es un cambio real.&lt;/p&gt;
&lt;h2 id="necesitas-net-8-o-9"&gt;¿Necesitas .NET 8 o 9?&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;apt install -y software-properties-common
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;add-apt-repository ppa:dotnet/backports
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install -y dotnet-sdk-8.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El &lt;a href="https://devblogs.microsoft.com/dotnet/whats-new-for-dotnet-in-ubuntu-2604/"&gt;post completo&lt;/a&gt; tiene más detalles sobre cgroup v2, post-quantum cryptography y Linux 7.0.&lt;/p&gt;</content:encoded></item><item><title>Azure SDK Abril 2026: AI Foundry 2.0 y Lo Que Deben Saber los Desarrolladores .NET</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-sdk-april-2026-ai-foundry-2-stable/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-sdk-april-2026-ai-foundry-2-stable/</guid><description>El lanzamiento del Azure SDK de abril 2026 incluye Azure.AI.Projects 2.0.0 stable con cambios importantes, correcciones críticas de seguridad en Cosmos DB y nuevas bibliotecas de Provisioning para .NET.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/azure-sdk-april-2026-ai-foundry-2-stable/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Los lanzamientos mensuales del SDK son fáciles de ignorar. Este tiene algunas cosas que vale la pena atender — especialmente si construyes con AI Foundry, Cosmos DB en Java, o haces aprovisionamiento de infraestructura desde código .NET.&lt;/p&gt;
&lt;h2 id="azureaiprojects-200--cambios-breaking-que-tienen-sentido"&gt;Azure.AI.Projects 2.0.0 — Cambios Breaking que Tienen Sentido&lt;/h2&gt;
&lt;p&gt;El paquete NuGet &lt;code&gt;Azure.AI.Projects&lt;/code&gt; alcanza la versión estable 2.0.0 con cambios arquitectónicos significativos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Divisiones de namespace&lt;/strong&gt;: Evaluaciones movidas a &lt;code&gt;Azure.AI.Projects.Evaluation&lt;/code&gt;, operaciones de memoria a &lt;code&gt;Azure.AI.Projects.Memory&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tipos renombrados&lt;/strong&gt;: &lt;code&gt;Insights&lt;/code&gt; → &lt;code&gt;ProjectInsights&lt;/code&gt;, &lt;code&gt;Schedules&lt;/code&gt; → &lt;code&gt;ProjectSchedules&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Convenciones de nomenclatura&lt;/strong&gt;: Propiedades booleanas siguen consistentemente la convención &lt;code&gt;Is*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Estos son los cambios breaking que duelen una vez y luego se sienten correctos para siempre.&lt;/p&gt;
&lt;h2 id="cosmos-db-java-corrección-crítica-de-seguridad-rce"&gt;Cosmos DB Java: Corrección Crítica de Seguridad (RCE)&lt;/h2&gt;
&lt;p&gt;Esta es seria. La biblioteca Java Cosmos DB versión 4.79.0 incluye una corrección crítica para una &lt;strong&gt;vulnerabilidad de Ejecución Remota de Código (CWE-502)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Si tienes servicios Java usando Azure Cosmos DB, actualiza a 4.79.0 inmediatamente.&lt;/p&gt;
&lt;h2 id="nuevas-bibliotecas-de-provisioning-para-net"&gt;Nuevas Bibliotecas de Provisioning para .NET&lt;/h2&gt;
&lt;p&gt;Varias bibliotecas estables de Provisioning llegan a 1.0.0:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nuget.org/packages/Azure.Provisioning.Network/1.0.0"&gt;Azure.Provisioning.Network 1.0.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nuget.org/packages/Azure.Provisioning.PrivateDns/1.0.0"&gt;Azure.Provisioning.PrivateDns 1.0.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="resumiendo"&gt;Resumiendo&lt;/h2&gt;
&lt;p&gt;Lo más destacado para desarrolladores .NET es &lt;code&gt;Azure.AI.Projects 2.0.0&lt;/code&gt; alcanzando estabilidad. Post original: &lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-sdk-release-april-2026/"&gt;Azure SDK Release (April 2026)&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>CodeAct en Agent Framework: Cómo Reducir la Latencia de tu Agente a la Mitad</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/codeact-agent-framework-hyperlight-50-percent-faster/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/codeact-agent-framework-hyperlight-50-percent-faster/</guid><description>CodeAct colapsa cadenas de herramientas de múltiples pasos en un único bloque de código sandboxed — reduciendo la latencia un 52% y el uso de tokens un 64%. Aquí está lo que significa para tus agentes y cuándo usarlo.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/posts/emiliano-montesdeoca/codeact-agent-framework-hyperlight-50-percent-faster/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Hay un momento en todo proyecto de agentes en que miras el trace y piensas: &amp;ldquo;¿por qué tarda tanto esto?&amp;rdquo; El modelo está bien. Las herramientas funcionan. Pero hay siete round trips para obtener un resultado que podría calcularse de una sola vez.&lt;/p&gt;
&lt;p&gt;Ese es exactamente el problema que resuelve CodeAct — y el &lt;a href="https://devblogs.microsoft.com/agent-framework/codeact-with-hyperlight/"&gt;equipo de Agent Framework acaba de publicar soporte alpha para ello&lt;/a&gt; a través de un nuevo paquete &lt;code&gt;agent-framework-hyperlight&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="qué-es-codeact"&gt;¿Qué es CodeAct?&lt;/h2&gt;
&lt;p&gt;El &lt;a href="https://arxiv.org/abs/2402.01030"&gt;patrón CodeAct&lt;/a&gt; es elegantemente simple: en lugar de darle al modelo una lista de herramientas y dejar que las llame una por una, le das una única herramienta &lt;code&gt;execute_code&lt;/code&gt; y le permites expresar el &lt;em&gt;plan completo&lt;/em&gt; como un programa Python corto. El agente escribe el código una vez, el sandbox lo ejecuta, y obtienes de vuelta un único resultado consolidado.&lt;/p&gt;
&lt;p&gt;Un plan de cinco pasos que antes requería cinco turnos del modelo ahora se convierte en un turno &lt;code&gt;execute_code&lt;/code&gt; que contiene un script Python que llama a tus herramientas vía &lt;code&gt;call_tool(...)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;El benchmark del repositorio lo hace concreto. Ocho usuarios, docenas de pedidos, cinco herramientas (listar usuarios, obtener pedidos, tasa de descuento, tasa de impuesto, calcular total de línea). Mismo modelo, mismas herramientas, mismo prompt — solo cableado diferente:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cableado&lt;/th&gt;
&lt;th&gt;Tiempo&lt;/th&gt;
&lt;th&gt;Tokens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tradicional&lt;/td&gt;
&lt;td&gt;27.81s&lt;/td&gt;
&lt;td&gt;6.890&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeAct&lt;/td&gt;
&lt;td&gt;13.23s&lt;/td&gt;
&lt;td&gt;2.489&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mejora&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;52,4%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;63,9%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Eso no es un micro-benchmark. Es una carga de trabajo realista con overhead de orquestación real.&lt;/p&gt;
&lt;h2 id="la-pieza-de-seguridad-micro-vms-de-hyperlight"&gt;La pieza de seguridad: micro-VMs de Hyperlight&lt;/h2&gt;
&lt;p&gt;Aquí está lo que me entusiasmó realmente: la seguridad ha sido históricamente el talón de Aquiles de CodeAct. Si estás ejecutando código generado por el modelo, ¿exactamente dónde se ejecuta? ¿Contra tu proceso? ¿En un contenedor compartido?&lt;/p&gt;
&lt;p&gt;El paquete &lt;code&gt;agent-framework-hyperlight&lt;/code&gt; resuelve esto con micro-VMs de &lt;a href="https://github.com/hyperlight-dev/hyperlight"&gt;Hyperlight&lt;/a&gt;. Cada llamada &lt;code&gt;execute_code&lt;/code&gt; obtiene su propia micro-VM recién creada — con su propia memoria, sin acceso al sistema de archivos del host más allá de lo que montes explícitamente, y sin acceso a la red más allá de los dominios que permitas. El arranque se mide en milisegundos. El aislamiento es prácticamente gratuito.&lt;/p&gt;
&lt;p&gt;Tus herramientas siguen ejecutándose en el host (son tu código, con tu acceso). El &lt;em&gt;pegamento&lt;/em&gt; generado por el modelo — el Python que decide qué herramientas llamar y en qué orden — se ejecuta en el sandbox. Esa es la división correcta.&lt;/p&gt;
&lt;h2 id="cómo-conectarlo"&gt;Cómo conectarlo&lt;/h2&gt;
&lt;p&gt;La configuración mínima es sencilla:&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;agent_framework&lt;/span&gt; &lt;span class="kn"&gt;import&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;tool&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;agent_framework_hyperlight&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HyperlightCodeActProvider&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="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;str&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;&amp;#34;&amp;#34;Return the current weather for a city.&amp;#34;&amp;#34;&amp;#34;&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="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;temperature_c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;21.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;conditions&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;partly cloudy&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="n"&gt;codeact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HyperlightCodeActProvider&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;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&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;approval_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;never_require&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&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;Agent&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;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;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;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;CodeActAgent&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="n"&gt;context_providers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;codeact&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;result&lt;/span&gt; &lt;span class="o"&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&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;Get the weather for Seattle and Amsterdam and compare them.&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;El proveedor registra &lt;code&gt;execute_code&lt;/code&gt; en cada ejecución e inyecta las instrucciones de CodeAct en el prompt del sistema automáticamente.&lt;/p&gt;
&lt;h2 id="mezclando-codeact-con-herramientas-que-requieren-aprobación"&gt;Mezclando CodeAct con herramientas que requieren aprobación&lt;/h2&gt;
&lt;p&gt;Aquí se pone interesante. No todas las herramientas deberían ejecutarse dentro del sandbox sin aprobación. Puede que quieras aprobar &lt;code&gt;send_email&lt;/code&gt; o &lt;code&gt;charge_credit_card&lt;/code&gt; individualmente. El framework maneja esto de forma limpia:&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="nd"&gt;@tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;approval_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;always_require&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;def&lt;/span&gt; &lt;span class="nf"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&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;&amp;#34;&amp;#34;Send an email. Requires approval on every call.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&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;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&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;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;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;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;MixedToolsAgent&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="n"&gt;context_providers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;codeact&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;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# invocado directamente, con aprobación&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;Herramientas en el proveedor → el modelo las alcanza vía &lt;code&gt;call_tool(...)&lt;/code&gt; dentro del sandbox, baratas y encadenables.&lt;br&gt;
Herramientas directamente en el agente → el modelo las llama como herramientas de primera clase, la aprobación aplica individualmente.&lt;/p&gt;
&lt;h2 id="cuándo-usar-codeact-y-cuándo-no"&gt;Cuándo usar CodeAct (y cuándo no)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Usa CodeAct cuando:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La tarea encadena muchas llamadas pequeñas a herramientas (búsquedas, joins, cálculos, formateo)&lt;/li&gt;
&lt;li&gt;Te importa la latencia y el costo de tokens&lt;/li&gt;
&lt;li&gt;Quieres aislamiento fuerte por llamada en código generado por el modelo por defecto&lt;/li&gt;
&lt;li&gt;Las herramientas son baratas y seguras para invocar en secuencia&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Quédate con el tool-calling tradicional cuando:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El agente solo hace una o dos llamadas a herramientas por turno&lt;/li&gt;
&lt;li&gt;Cada llamada a herramienta tiene efectos secundarios que quieres aprobar individualmente&lt;/li&gt;
&lt;li&gt;Las descripciones de herramientas son escasas o ambiguas — CodeAct depende de buenos docstrings&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="pruébalo-ahora"&gt;Pruébalo ahora&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;pip install agent-framework-hyperlight --pre
&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;uv add --prerelease&lt;span class="o"&gt;=&lt;/span&gt;allow agent-framework-hyperlight
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Los ejemplos están en &lt;a href="https://github.com/microsoft/agent-framework/tree/main/python/packages/hyperlight/samples"&gt;&lt;code&gt;python/packages/hyperlight/samples/&lt;/code&gt;&lt;/a&gt;. El &lt;a href="https://github.com/microsoft/agent-framework/blob/main/python/packages/hyperlight/samples/codeact_benchmark.py"&gt;ejemplo de benchmark&lt;/a&gt; es el mejor punto de partida.&lt;/p&gt;
&lt;p&gt;Vale la pena mencionar: Linux y Windows son compatibles hoy. El soporte para macOS está en camino. Un equivalente para .NET también está llegando.&lt;/p&gt;
&lt;h2 id="resumiendo"&gt;Resumiendo&lt;/h2&gt;
&lt;p&gt;CodeAct no es magia — es un patrón sensato que era demasiado arriesgado de usar sin sandboxing adecuado. Hyperlight cambia esa ecuación. Aislamiento en micro-VM por llamada, arranque en milisegundos, mejora de latencia del 50%+ en las cargas de trabajo adecuadas. Vale la pena experimentar.&lt;/p&gt;
&lt;p&gt;Consulta el &lt;a href="https://devblogs.microsoft.com/agent-framework/codeact-with-hyperlight/"&gt;post completo en el blog de Agent Framework&lt;/a&gt; para cobertura más profunda sobre montajes de sistema de archivos, política de red y el cableado independiente de &lt;code&gt;HyperlightExecuteCodeTool&lt;/code&gt;.&lt;/p&gt;</content:encoded></item><item><title>El Azure MCP Server Ahora es un .mcpb — Instálalo sin Ningún Runtime</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-mcp-server-mcpb-no-runtime-install/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-mcp-server-mcpb-no-runtime-install/</guid><description>El Azure MCP Server ya está disponible como MCP Bundle (.mcpb) — descárgalo, arrástralo a Claude Desktop y listo. Sin Node.js, Python ni .NET requeridos.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-mcp-server-mcpb-no-runtime-install/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;¿Sabes qué era molesto de configurar servidores MCP? Necesitabas un runtime. Node.js para la versión npm, Python para pip/uvx, .NET SDK para la variante dotnet, Docker si querías contenedores. Solo para conectar una herramienta a tu cliente IA.&lt;/p&gt;
&lt;p&gt;El &lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-mcp-server-mcpb-support/"&gt;Azure MCP Server acaba de cambiar eso&lt;/a&gt;. Ahora está disponible como &lt;code&gt;.mcpb&lt;/code&gt; — un MCP Bundle — y la configuración es arrastrar y soltar.&lt;/p&gt;
&lt;h2 id="qué-es-un-mcp-bundle"&gt;¿Qué es un MCP Bundle?&lt;/h2&gt;
&lt;p&gt;Piénsalo como una extensión de VS Code (&lt;code&gt;.vsix&lt;/code&gt;) o una extensión de navegador (&lt;code&gt;.crx&lt;/code&gt;), pero para servidores MCP. Un archivo &lt;code&gt;.mcpb&lt;/code&gt; es un archivo ZIP autónomo que incluye el binario del servidor y todas sus dependencias. Todo lo necesario para ejecutarlo en tu plataforma, empaquetado junto.&lt;/p&gt;
&lt;p&gt;El resultado: descargas un archivo, lo abres en un cliente compatible y el servidor funciona. Sin runtime que instalar, sin &lt;code&gt;package.json&lt;/code&gt; que gestionar, sin conflictos de versiones.&lt;/p&gt;
&lt;h2 id="cómo-instalarlo"&gt;Cómo instalarlo&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1. Descarga el bundle para tu plataforma&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ve a la &lt;a href="https://github.com/microsoft/mcp/releases?q=Azure.Mcp.Server"&gt;página de GitHub Releases&lt;/a&gt; y descarga el archivo &lt;code&gt;.mcpb&lt;/code&gt; para tu OS y arquitectura. Asegúrate de elegir el correcto — &lt;code&gt;osx-arm64&lt;/code&gt; para Apple Silicon, &lt;code&gt;osx-x64&lt;/code&gt; para Mac Intel, etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Instala en Claude Desktop&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;La forma más fácil: arrastra y suelta el archivo &lt;code&gt;.mcpb&lt;/code&gt; en la ventana de Claude Desktop mientras estás en la página de configuración de Extensiones (&lt;code&gt;☰ → Archivo → Configuración → Extensiones&lt;/code&gt;). Revisa los detalles del servidor, haz clic en Instalar y confirma.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Autentícate en Azure&lt;/strong&gt;&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;az login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Eso es todo. El Azure MCP Server usa tus credenciales de Azure existentes.&lt;/p&gt;
&lt;h2 id="qué-puedes-hacer-con-él"&gt;Qué puedes hacer con él&lt;/h2&gt;
&lt;p&gt;Una vez instalado, tienes acceso a más de 100 herramientas de servicios Azure directamente desde tu cliente IA:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Consultar y administrar Cosmos DB, Storage, Key Vault, App Service, Foundry&lt;/li&gt;
&lt;li&gt;Generar comandos &lt;code&gt;az&lt;/code&gt; CLI para cualquier tarea&lt;/li&gt;
&lt;li&gt;Crear plantillas Bicep y Terraform&lt;/li&gt;
&lt;li&gt;Obtener recomendaciones de arquitectura y diagnósticos&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prueba prompts como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Lista todos los grupos de recursos en mi suscripción&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Genera una plantilla Bicep para una app web con base de datos SQL&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="qué-método-de-instalación-usar"&gt;¿Qué método de instalación usar?&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Método&lt;/th&gt;
&lt;th&gt;Ideal para&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.mcpb&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Usuarios de Claude Desktop que quieren cero configuración&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extensión VS Code&lt;/td&gt;
&lt;td&gt;Desarrolladores en VS Code + GitHub Copilot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;npm/npx&lt;/td&gt;
&lt;td&gt;Desarrolladores que ya tienen Node.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;Pipelines CI/CD y contenedores&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="para-empezar"&gt;Para empezar&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Descarga&lt;/strong&gt;: &lt;a href="https://github.com/microsoft/mcp/releases?q=Azure.Mcp.Server-"&gt;GitHub Releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Repositorio&lt;/strong&gt;: &lt;a href="https://aka.ms/azmcp"&gt;aka.ms/azmcp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docs&lt;/strong&gt;: &lt;a href="https://aka.ms/azmcp/docs"&gt;aka.ms/azmcp/docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Consulta el &lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-mcp-server-mcpb-support/"&gt;post completo&lt;/a&gt; para consejos de solución de problemas.&lt;/p&gt;</content:encoded></item><item><title>GPT-5.5 Ya Está Aquí en Azure Foundry — Lo que los Desarrolladores .NET Necesitan Saber</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/gpt-55-foundry-ga-what-dotnet-developers-need-to-know/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/gpt-55-foundry-ga-what-dotnet-developers-need-to-know/</guid><description>GPT-5.5 ya está disponible en Microsoft Foundry. La progresión desde GPT-5 hasta 5.5, qué mejoró realmente y cómo empezar a usarlo en tus agentes hoy.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/posts/emiliano-montesdeoca/gpt-55-foundry-ga-what-dotnet-developers-need-to-know/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Microsoft acaba de anunciar que &lt;a href="https://azure.microsoft.com/en-us/blog/openais-gpt-5-5-in-microsoft-foundry-frontier-intelligence-on-an-enterprise-ready-platform/"&gt;GPT-5.5 ya está disponible en Microsoft Foundry&lt;/a&gt;. Si has estado construyendo agentes en Azure, esta es la actualización que esperabas.&lt;/p&gt;
&lt;h2 id="la-progresión-de-gpt-5"&gt;La progresión de GPT-5&lt;/h2&gt;
&lt;p&gt;No es solo un incremento de versión:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPT-5&lt;/strong&gt;: unificó razonamiento y velocidad en un solo sistema&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-5.4&lt;/strong&gt;: razonamiento multi-paso más robusto, capacidades agénticas tempranas para empresas&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-5.5&lt;/strong&gt;: razonamiento de largo contexto más profundo, ejecución agéntica más fiable, mayor eficiencia de tokens&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="qué-cambió-realmente"&gt;Qué cambió realmente&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Mejor codificación agéntica&lt;/strong&gt;: GPT-5.5 mantiene el contexto a través de grandes bases de código, diagnostica fallos arquitectónicos y anticipa requisitos de pruebas. El modelo razona sobre &lt;em&gt;qué más&lt;/em&gt; afecta una corrección antes de actuar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Eficiencia de tokens&lt;/strong&gt;: Salidas de mayor calidad con menos tokens y menos reintentos. Esto se traduce directamente en menor costo y latencia en producción.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Análisis de largo contexto&lt;/strong&gt;: Maneja documentos extensos, bases de código y historiales multi-sesión sin perder el hilo.&lt;/p&gt;
&lt;h2 id="precios"&gt;Precios&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Modelo&lt;/th&gt;
&lt;th&gt;Entrada ($/M tokens)&lt;/th&gt;
&lt;th&gt;Entrada en caché&lt;/th&gt;
&lt;th&gt;Salida ($/M tokens)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.5&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;$30.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.5 Pro&lt;/td&gt;
&lt;td&gt;$30.00&lt;/td&gt;
&lt;td&gt;$3.00&lt;/td&gt;
&lt;td&gt;$180.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="por-qué-importa-foundry"&gt;Por qué importa Foundry&lt;/h2&gt;
&lt;p&gt;Foundry Agent Service permite definir agentes en YAML o conectarlos con Microsoft Agent Framework, GitHub Copilot SDK, LangGraph o el SDK de OpenAI Agents — y ejecutarlos como agentes hospedados aislados con sistema de archivos persistente, identidad de Microsoft Entra y precios de escala a cero.&lt;/p&gt;
&lt;h2 id="cómo-empezar"&gt;Cómo empezar&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="c1"&gt;// C# — solo actualiza el nombre del modelo&lt;/span&gt;
&lt;/span&gt;&lt;/span&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="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="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsAIAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;gpt-5.5&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&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;Eres un asistente útil.&amp;#34;&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 class="s"&gt;&amp;#34;MiAgente&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;Consulta el &lt;a href="https://azure.microsoft.com/en-us/blog/openais-gpt-5-5-in-microsoft-foundry-frontier-intelligence-on-an-enterprise-ready-platform/"&gt;anuncio completo&lt;/a&gt; para los detalles completos.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.118: Copilot CLI Obtiene Nombres de Sesión, Insignias de Modelo y TypeScript 7.0 Nightly</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/vscode-1-118-copilot-cli-session-names-model-badge/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/vscode-1-118-copilot-cli-session-names-model-badge/</guid><description>Visual Studio Code 1.118 es un lanzamiento enfocado en mejoras de Copilot CLI — nombrado de sesiones, insignias de modelo, selección automática de modelo y opt-in a TypeScript 7.0 nightly.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/es/posts/emiliano-montesdeoca/vscode-1-118-copilot-cli-session-names-model-badge/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/updates/v1_118"&gt;Visual Studio Code 1.118&lt;/a&gt; es un lanzamiento pequeño y enfocado — principalmente refinamientos de Copilot CLI — pero hay algunas cosas a destacar.&lt;/p&gt;
&lt;h2 id="copilot-cli-las-sesiones-tienen-nombres-reales"&gt;Copilot CLI: las sesiones tienen nombres reales&lt;/h2&gt;
&lt;p&gt;Las APIs de título de sesión del SDK de Copilot CLI ahora se usan como fuente de verdad para los nombres de sesión. Antes obtenías etiquetas auto-generadas; ahora las sesiones muestran el nombre real del SDK. Mejora de calidad de vida que hace mucho menos confusa la navegación entre múltiples sesiones de agente.&lt;/p&gt;
&lt;h2 id="cambia-de-sesión-más-rápido-con-atajos-de-teclado"&gt;Cambia de sesión más rápido con atajos de teclado&lt;/h2&gt;
&lt;p&gt;La app de Agents ahora tiene &lt;code&gt;Ctrl+1&lt;/code&gt;, &lt;code&gt;Ctrl+2&lt;/code&gt;, etc. asignados para cambiar rápidamente entre sesiones. Si estás ejecutando múltiples sesiones de Copilot CLI en paralelo, esto elimina mucho clic con el ratón.&lt;/p&gt;
&lt;h2 id="insignias-de-modelo-en-el-chat"&gt;Insignias de modelo en el chat&lt;/h2&gt;
&lt;p&gt;Las respuestas de Copilot CLI en el panel de chat ahora muestran una insignia de modelo — puedes ver de un vistazo qué modelo manejó cada solicitud.&lt;/p&gt;
&lt;h2 id="selección-automática-de-modelo-en-copilot-cli"&gt;Selección automática de modelo en Copilot CLI&lt;/h2&gt;
&lt;p&gt;La selección automática de modelo — previamente disponible en otras partes de Copilot — ahora funciona también en el agente Copilot CLI.&lt;/p&gt;
&lt;h2 id="opt-in-a-typescript-70-nightly"&gt;Opt-in a TypeScript 7.0 nightly&lt;/h2&gt;
&lt;p&gt;Ahora puedes optar por probar los nightly de TypeScript 7.0 directamente desde la configuración de VS Code. TypeScript 7.0 es un lanzamiento importante (la &lt;a href="https://devblogs.microsoft.com/typescript/announcing-typescript-7-0-beta/"&gt;beta llegó hace unos días&lt;/a&gt;), y el path de opt-in facilita la prueba sin cambiar tu instalación global de TypeScript.&lt;/p&gt;
&lt;h2 id="bajo-el-capó-limpieza-de-node-pty"&gt;Bajo el capó: limpieza de &lt;code&gt;node-pty&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;El SDK de Copilot CLI ahora resuelve &lt;code&gt;node-pty&lt;/code&gt; desde VS Code via &lt;code&gt;hostRequire&lt;/code&gt; en lugar de copiar binarios a la carpeta prebuilds del SDK. Cambio interno que simplifica la distribución.&lt;/p&gt;
&lt;p&gt;Consulta las &lt;a href="https://code.visualstudio.com/updates/v1_118"&gt;notas de versión completas&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Aspire 13.2: Soporte para Bun, Mejores Contenedores y Menos Fricción en el Debug</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/aspire-132-bun-container-enhancements/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/aspire-132-bun-container-enhancements/</guid><description>Aspire 13.2 añade soporte de primera clase para Bun en apps Vite, corrige la fiabilidad de Yarn y trae mejoras en contenedores que hacen el comportamiento local más predecible.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/aspire-132-bun-container-enhancements/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Si llevas tiempo construyendo backends .NET con frontends JavaScript en Aspire, la versión 13.2 es el tipo de actualización que mejora tu día sin anunciar grandes cambios. Sin nuevos paradigmas llamativos. Solo mejoras sólidas a cosas que eran levemente molestas.&lt;/p&gt;
&lt;h2 id="bun-es-ahora-ciudadano-de-primera-clase"&gt;Bun es Ahora Ciudadano de Primera Clase&lt;/h2&gt;
&lt;p&gt;La característica principal: soporte para Bun en apps Vite. Una llamada fluida, listo.&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="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;withBun&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 tu equipo ya usa Bun — con sus tiempos de instalación dramáticamente más rápidos — Aspire ya no te hace pelear contra la corriente.&lt;/p&gt;
&lt;h2 id="yarn-es-más-confiable"&gt;Yarn es Más Confiable&lt;/h2&gt;
&lt;p&gt;Los usuarios de Yarn reciben algo igualmente importante: menos fallos misteriosos. Aspire 13.2 mejora la fiabilidad de &lt;code&gt;withYarn()&lt;/code&gt; con &lt;code&gt;addViteApp()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="mejoras-en-contenedores"&gt;Mejoras en Contenedores&lt;/h2&gt;
&lt;h3 id="pull-policy-explícita"&gt;Pull Policy Explícita&lt;/h3&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;const&lt;/span&gt; &lt;span class="nx"&gt;worker&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;addContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;worker&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;myorg/worker:latest&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;withImagePullPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ImagePullPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Never&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;Perfecto para flujos donde construyes imágenes localmente y quieres que Compose use exactamente esa sin ir al registry.&lt;/p&gt;
&lt;h3 id="postgresql-18-funciona-correctamente"&gt;PostgreSQL 18+ Funciona Correctamente&lt;/h3&gt;
&lt;p&gt;PostgreSQL 18 cambió su estructura interna de directorios, lo que rompía silenciosamente el mapeo de volúmenes. Aspire 13.2 lo corrige.&lt;/p&gt;
&lt;h2 id="mejoras-de-depuración"&gt;Mejoras de Depuración&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;DebuggerDisplayAttribute&lt;/code&gt; en tipos core — valores útiles en el debugger en lugar de árboles de objetos&lt;/li&gt;
&lt;li&gt;Mensajes de error más claros para &lt;code&gt;WaitFor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BeforeResourceStartedEvent&lt;/code&gt; se dispara en el momento correcto&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="resumiendo"&gt;Resumiendo&lt;/h2&gt;
&lt;p&gt;Aspire 13.2 es una versión de calidad enfocada. Vale la pena actualizar, especialmente si usas PostgreSQL 18 con volúmenes de datos.&lt;/p&gt;
&lt;p&gt;Post original de David Pine: &lt;a href="https://devblogs.microsoft.com/aspire/aspire-bun-support-and-container-enhancements/"&gt;Aspire 13.2: Bun Support and Container Enhancements&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>¿68 Minutos al Día Re-Explicando Código a Copilot? Hay una Solución</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/auto-memory-stop-re-explaining-code-to-copilot/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/auto-memory-stop-re-explaining-code-to-copilot/</guid><description>El 'context rot' es real — tu agente de IA se pierde después de 30 turnos y pagas el impuesto de la compactación cada hora. auto-memory le da a GitHub Copilot CLI una memoria quirúrgica sin quemar miles de tokens.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/auto-memory-stop-re-explaining-code-to-copilot/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;¿Conoces ese momento en que tu sesión de Copilot llega al &lt;code&gt;/compact&lt;/code&gt; y el agente olvida completamente lo que estabas haciendo? Pasas los siguientes cinco minutos re-explicando la estructura de archivos, el test fallido, los tres enfoques que ya intentaste. Y luego vuelve a pasar. Y otra vez.&lt;/p&gt;
&lt;p&gt;Desi Villanueva lo midió: &lt;strong&gt;68 minutos al día&lt;/strong&gt; — solo en re-orientación. No escribiendo código. No revisando PRs. Solo poniéndole al día a la IA en cosas que ya sabía.&lt;/p&gt;
&lt;p&gt;Resulta que hay una razón concreta por la que esto pasa, y una solución concreta.&lt;/p&gt;
&lt;h2 id="la-mentira-de-la-ventana-de-contexto"&gt;La Mentira de la Ventana de Contexto&lt;/h2&gt;
&lt;p&gt;Tu agente viene con un número grande en la caja. 200K tokens. Suena masivo. En la práctica es un techo, no una garantía.&lt;/p&gt;
&lt;p&gt;Aquí está la matemática real:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;200K de contexto total&lt;/li&gt;
&lt;li&gt;Menos ~65K para herramientas MCP cargadas al inicio (~33%)&lt;/li&gt;
&lt;li&gt;Menos ~10K para archivos de instrucciones como &lt;code&gt;AGENTS.md&lt;/code&gt; o &lt;code&gt;copilot-instructions.md&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Eso te deja aproximadamente &lt;strong&gt;125K antes de escribir una sola palabra&lt;/strong&gt;. Y empeora — los LLMs no se degradan de forma gradual al llenarse el contexto. Tienen un tope al llegar al 60% de capacidad. El modelo empieza a perder cosas mencionadas hace 30 turnos, contradice respuestas anteriores, alucina nombres de archivos que declaró con confianza hace 10 minutos. La industria llama a esto el problema del &amp;ldquo;lost in the middle&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Límite efectivo: &lt;strong&gt;45K tokens&lt;/strong&gt; antes de que la calidad se degrade. Eso son tal vez 20-30 turnos de conversación activa antes de que el agente empiece a derivar. Por eso estás usando &lt;code&gt;/compact&lt;/code&gt; cada 45 minutos — no porque hayas llenado 200K tokens, sino porque el modelo ya está &amp;ldquo;podrido&amp;rdquo; a los 120K.&lt;/p&gt;
&lt;h2 id="el-impuesto-de-la-compactación"&gt;El Impuesto de la Compactación&lt;/h2&gt;
&lt;p&gt;Cada &lt;code&gt;/compact&lt;/code&gt; te cuesta el estado de flujo. Llevas 30 minutos en una sesión de depuración. El agente conoce la estructura de archivos, el test fallido, la hipótesis. Luego llega la advertencia.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ignorarla → el agente se vuelve progresivamente más tonto, alucina el estado anterior&lt;/li&gt;
&lt;li&gt;Ejecutar &lt;code&gt;/compact&lt;/code&gt; → el agente tiene un resumen de 2 párrafos de una investigación de 30 minutos&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;De cualquier manera pierdes. De cualquier manera estás narrando tu propio proyecto como si fuera un empleado nuevo en su primer día.&lt;/p&gt;
&lt;p&gt;La parte cruel: &lt;strong&gt;la memoria ya existe&lt;/strong&gt;. Copilot CLI escribe cada sesión en una base de datos SQLite local en &lt;code&gt;~/.copilot/session-store.db&lt;/code&gt; — cada archivo tocado, cada turno, cada checkpoint. Todo está en el disco. El agente simplemente no puede leerlo.&lt;/p&gt;
&lt;h2 id="auto-memory-una-capa-de-recall-no-un-sistema-de-memoria"&gt;auto-memory: Una Capa de Recall, No un Sistema de Memoria&lt;/h2&gt;
&lt;p&gt;Esa es la idea central detrás de &lt;a href="https://github.com/dezgit2025/auto-memory"&gt;auto-memory&lt;/a&gt;: no construyas un nuevo sistema de memoria — construye una capa de consulta de solo lectura sobre el que ya existe.&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;pip install auto-memory
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;~1.900 líneas de Python. Cero dependencias. Se instala en 30 segundos.&lt;/p&gt;
&lt;p&gt;En lugar de inundar el contexto con resultados de grep, le das al agente acceso quirúrgico a lo que realmente importa:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operación&lt;/th&gt;
&lt;th&gt;Tokens&lt;/th&gt;
&lt;th&gt;Qué obtienes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;grep -r &amp;quot;auth&amp;quot; src/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~5.000–10.000&lt;/td&gt;
&lt;td&gt;500 resultados, la mayoría irrelevantes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;find . -name &amp;quot;*.py&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~2.000&lt;/td&gt;
&lt;td&gt;Todos los archivos Python, sin contexto&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Re-orientación del agente&lt;/td&gt;
&lt;td&gt;~2.000&lt;/td&gt;
&lt;td&gt;Tú explicando lo que ya debería saber&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;auto-memory files --json --limit 10&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~50&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Los 10 archivos que tocaste ayer&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Una mejora de 200x. El agente se salta la excavación arqueológica y va directo a lo que importa.&lt;/p&gt;
&lt;h2 id="por-qué-importa-esto-para-desarrolladores-net"&gt;¿Por Qué Importa Esto para Desarrolladores .NET?&lt;/h2&gt;
&lt;p&gt;Si usas GitHub Copilot CLI para trabajo con .NET — scaffolding de servicios, depuración de queries EF Core, iterando en componentes Blazor — el problema del context rot golpea igual de fuerte. Soluciones complejas con múltiples proyectos y librerías compartidas son exactamente el tipo de código donde el agente pierde el hilo más rápido.&lt;/p&gt;
&lt;h2 id="resumiendo"&gt;Resumiendo&lt;/h2&gt;
&lt;p&gt;El context rot es una restricción arquitectónica real, no un bug que se parchará. auto-memory lo soluciona dándole a tu agente un mecanismo de recall barato y preciso en lugar de re-exploración costosa y ruidosa. Si haces desarrollo serio asistido por IA con GitHub Copilot CLI, vale la pena el install de 30 segundos.&lt;/p&gt;
&lt;p&gt;Échale un vistazo: &lt;a href="https://github.com/dezgit2025/auto-memory"&gt;auto-memory en GitHub&lt;/a&gt;. Post original de Desi Villanueva: &lt;a href="https://devblogs.microsoft.com/all-things-azure/i-wasted-68-minutes-a-day-re-explaining-my-code-then-i-built-auto-memory/"&gt;I Wasted 68 Minutes a Day Re-Explaining My Code&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Foundry Toolboxes: Un único endpoint para todas las herramientas de tus agentes</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/foundry-toolboxes-curate-manage-tools-ai-agents/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/foundry-toolboxes-curate-manage-tools-ai-agents/</guid><description>Microsoft Foundry acaba de lanzar Toolboxes en preview pública — una forma de curar, gestionar y exponer herramientas de agentes IA a través de un único endpoint compatible con MCP, sin tener que reconfigurar todo en cada agente.</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/posts/emiliano-montesdeoca/foundry-toolboxes-curate-manage-tools-ai-agents/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Aquí hay un problema que parece aburrido hasta que lo sufres en carne propia: tu organización está construyendo múltiples agentes de IA, cada uno necesita herramientas, y cada equipo las conecta desde cero. La misma integración de búsqueda web, la misma config de Azure AI Search, la misma conexión al servidor MCP de GitHub — pero en otro repositorio, por otro equipo, con otras credenciales y sin ninguna gobernanza compartida.&lt;/p&gt;
&lt;p&gt;Microsoft Foundry acaba de lanzar &lt;a href="https://devblogs.microsoft.com/foundry/introducing-toolboxes-in-foundry/"&gt;Toolboxes&lt;/a&gt; en preview pública, y es una respuesta directa a ese problema.&lt;/p&gt;
&lt;h2 id="qué-es-un-toolbox"&gt;¿Qué es un Toolbox?&lt;/h2&gt;
&lt;p&gt;Un Toolbox es un bundle de herramientas con nombre, reutilizable, que defines una vez en Foundry y expones a través de un único endpoint compatible con MCP. Cualquier runtime de agente que hable MCP puede consumirlo — no estás bloqueado en Foundry Agents.&lt;/p&gt;
&lt;p&gt;La propuesta es simple: &lt;strong&gt;build once, consume anywhere&lt;/strong&gt;. Define las herramientas, configura la autenticación de forma centralizada (OAuth passthrough, identidad administrada de Entra), publica el endpoint. Cada agente que necesite esas herramientas se conecta al endpoint y las obtiene todas.&lt;/p&gt;
&lt;p&gt;Sin configuración por herramienta. Sin gestión de credenciales por agente.&lt;/p&gt;
&lt;h2 id="los-cuatro-pilares-dos-disponibles-hoy"&gt;Los cuatro pilares (dos disponibles hoy)&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pilar&lt;/th&gt;
&lt;th&gt;Estado&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;strong&gt;Discover&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Próximamente&lt;/td&gt;
&lt;td&gt;Encuentra herramientas aprobadas sin buscar manualmente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Build&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Disponible hoy&lt;/td&gt;
&lt;td&gt;Agrupa herramientas en un bundle reutilizable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consume&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Disponible hoy&lt;/td&gt;
&lt;td&gt;Un único endpoint MCP expone todas las herramientas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Govern&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Próximamente&lt;/td&gt;
&lt;td&gt;Auth centralizada + observabilidad en todas las llamadas&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Hoy el foco está en Build y Consume. Suficiente para eliminar la fricción más inmediata.&lt;/p&gt;
&lt;h2 id="empezando-en-la-práctica"&gt;Empezando en la práctica&lt;/h2&gt;
&lt;p&gt;El SDK es Python primero por ahora. Comienzas creando un &lt;code&gt;AIProjectClient&lt;/code&gt; y luego construyes un toolbox:&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.identity&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DefaultAzureCredential&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&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;import&lt;/span&gt; &lt;span class="nn"&gt;os&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&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;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;FOUNDRY_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;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&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Luego creas una versión del toolbox con las herramientas que quieres agrupar:&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;toolbox_version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toolboxes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_toolbox_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;toolbox_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;customer-feedback-triaging-toolbox&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;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Buscar en documentación y responder a issues de GitHub.&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;tools&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 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;web_search&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Buscar documentación pública&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="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_search&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;index_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;internal-docs&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="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;mcp_server&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;server_url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://your-github-mcp-server.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;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;Una vez publicado, Foundry te da un endpoint unificado que cualquier runtime MCP puede consumir. Un punto de conexión, todas las herramientas.&lt;/p&gt;
&lt;h2 id="no-estás-bloqueado-en-foundry-agents"&gt;No estás bloqueado en Foundry Agents&lt;/h2&gt;
&lt;p&gt;Los Toolboxes se &lt;strong&gt;crean y gestionan&lt;/strong&gt; en Foundry, pero la superficie de consumo es el protocolo MCP abierto. Puedes usarlos desde agentes personalizados con Microsoft Agent Framework o LangGraph, GitHub Copilot y otros IDEs compatibles con MCP, o cualquier runtime que hable MCP.&lt;/p&gt;
&lt;h2 id="por-qué-importa-ahora"&gt;Por qué importa ahora&lt;/h2&gt;
&lt;p&gt;La ola de multi-agentes está llegando a producción. Los equipos están construyendo 5, 10, 20 agentes — y el problema de la configuración de herramientas escala rápido. Cada nuevo agente es una nueva superficie para configuración duplicada, credenciales desactualizadas y comportamiento inconsistente.&lt;/p&gt;
&lt;p&gt;Los Toolboxes no resuelven la gobernanza y el discovery todavía (esos pilares están por venir), pero la base de Build + Consume es suficiente para empezar a centralizar. Cuando llegue el pilar Govern, tendrás una capa de herramientas observable y controlada centralmente para toda tu flota de agentes.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Esto es pronto — preview pública, SDK Python primero, con Discover y Govern todavía por llegar. Pero el modelo es sólido, y el diseño nativo de MCP significa que funciona con las herramientas que ya estás construyendo. Echa un vistazo al &lt;a href="https://devblogs.microsoft.com/foundry/introducing-toolboxes-in-foundry/"&gt;anuncio oficial&lt;/a&gt; para empezar.&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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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>Parchea Esto Ahora: Actualización de Seguridad OOB .NET 10.0.7 para ASP.NET Core Data Protection</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/dotnet-10-0-7-oob-security-patch-data-protection/</link><pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/dotnet-10-0-7-oob-security-patch-data-protection/</guid><description>.NET 10.0.7 es un lanzamiento fuera de banda que corrige una vulnerabilidad de seguridad en Microsoft.AspNetCore.DataProtection — el encriptador autenticado computaba HMAC sobre bytes incorrectos, llevando a posible elevación de privilegios.</description><content:encoded>&lt;p&gt;&lt;em&gt;Este post fue traducido automáticamente. Para la versión original, &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/dotnet-10-0-7-oob-security-patch-data-protection/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Esta no es opcional. Si tu aplicación usa &lt;code&gt;Microsoft.AspNetCore.DataProtection&lt;/code&gt;, necesitas actualizar a 10.0.7.&lt;/p&gt;
&lt;h2 id="qué-pasó"&gt;Qué Pasó&lt;/h2&gt;
&lt;p&gt;Después del lanzamiento de Patch Tuesday &lt;code&gt;.NET 10.0.6&lt;/code&gt;, algunos usuarios reportaron que el descifrado fallaba. Mientras investigaban la regresión, el equipo descubrió que también exponía una vulnerabilidad de seguridad: &lt;strong&gt;CVE-2026-40372&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;En versiones &lt;code&gt;10.0.0&lt;/code&gt; a &lt;code&gt;10.0.6&lt;/code&gt; de &lt;code&gt;Microsoft.AspNetCore.DataProtection&lt;/code&gt;, el encriptador autenticado calculaba su etiqueta de validación HMAC sobre los &lt;strong&gt;bytes incorrectos&lt;/strong&gt; del payload. Resultado: posible elevación de privilegios.&lt;/p&gt;
&lt;h2 id="cómo-solucionarlo"&gt;Cómo Solucionarlo&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;dotnet add package Microsoft.AspNetCore.DataProtection --version 10.0.7
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Luego &lt;strong&gt;reconstruye y redespliega&lt;/strong&gt; tu aplicación.&lt;/p&gt;
&lt;h2 id="el-panorama-general"&gt;El Panorama General&lt;/h2&gt;
&lt;p&gt;Los lanzamientos OOB son poco comunes — ocurren cuando una vulnerabilidad es lo suficientemente seria para no esperar al próximo Patch Tuesday.&lt;/p&gt;
&lt;p&gt;Anuncio original de Rahul Bhandari: &lt;a href="https://devblogs.microsoft.com/dotnet/dotnet-10-0-7-oob-security-update/"&gt;.NET 10.0.7 Out-of-Band Security Update&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>azd + GitHub Copilot: Configuración de proyectos con IA y resolución inteligente de errores</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azd-copilot-integration-ai-setup-troubleshooting/</link><pubDate>Tue, 21 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azd-copilot-integration-ai-setup-troubleshooting/</guid><description>El Azure Developer CLI ahora se integra con GitHub Copilot para generar la infraestructura de tu proyecto y resolver errores de despliegue — sin salir del terminal.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este artículo fue traducido automáticamente. Para ver la versión original en inglés, &lt;a href="https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azd-copilot-integration-ai-setup-troubleshooting/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;¿Conoces ese momento en que quieres desplegar una app existente en Azure y te quedas mirando un &lt;code&gt;azure.yaml&lt;/code&gt; en blanco, intentando recordar si tu API Express debería usar Container Apps o App Service? Ese momento acaba de volverse mucho más corto.&lt;/p&gt;
&lt;p&gt;El Azure Developer CLI (&lt;code&gt;azd&lt;/code&gt;) ahora se integra con GitHub Copilot de dos formas muy concretas: scaffolding asistido por IA durante &lt;code&gt;azd init&lt;/code&gt;, y resolución inteligente de errores cuando los despliegues fallan. Ambas funciones se quedan completamente en tu terminal, que es exactamente donde quiero que estén.&lt;/p&gt;
&lt;h2 id="configuración-con-copilot-durante-azd-init"&gt;Configuración con Copilot durante azd init&lt;/h2&gt;
&lt;p&gt;Cuando ejecutas &lt;code&gt;azd init&lt;/code&gt;, ahora aparece la opción &amp;ldquo;Set up with GitHub Copilot (Preview)&amp;rdquo;. Selecciónala y Copilot analiza tu codebase para generar el &lt;code&gt;azure.yaml&lt;/code&gt;, las plantillas de infraestructura y los módulos Bicep — basándose en tu código real, no en suposiciones.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;azd init
# Selecciona: &amp;#34;Set up with GitHub Copilot (Preview)&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para que funcione necesitas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;azd 1.23.11 o superior&lt;/strong&gt; — comprueba con &lt;code&gt;azd version&lt;/code&gt; o actualiza con &lt;code&gt;azd update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Una suscripción activa de GitHub Copilot&lt;/strong&gt; (Individual, Business o Enterprise)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub CLI (&lt;code&gt;gh&lt;/code&gt;)&lt;/strong&gt; — &lt;code&gt;azd&lt;/code&gt; pedirá login si es necesario&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lo que me parece genuinamente útil es que funciona en los dos sentidos. ¿Construyendo desde cero? Copilot te ayuda a configurar los servicios Azure correctos desde el principio. ¿Tienes una app existente que llevas tiempo sin desplegar? Apunta Copilot hacia ella y genera la configuración sin que tengas que reestructurar nada.&lt;/p&gt;
&lt;h3 id="lo-que-hace-realmente"&gt;Lo que hace realmente&lt;/h3&gt;
&lt;p&gt;Imagina que tienes una API Express en Node.js con dependencia de PostgreSQL. En lugar de decidir manualmente entre Container Apps o App Service, y luego escribir Bicep desde cero, Copilot detecta tu stack y genera:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un &lt;code&gt;azure.yaml&lt;/code&gt; con los ajustes correctos de &lt;code&gt;language&lt;/code&gt;, &lt;code&gt;host&lt;/code&gt; y &lt;code&gt;build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Un módulo Bicep para Azure Container Apps&lt;/li&gt;
&lt;li&gt;Un módulo Bicep para Azure Database for PostgreSQL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Y hace comprobaciones previas antes de tocar nada — verifica que tu directorio git esté limpio, pide consentimiento para las herramientas del servidor MCP. Nada ocurre sin que sepas exactamente qué va a cambiar.&lt;/p&gt;
&lt;h2 id="resolución-de-errores-potenciada-por-copilot"&gt;Resolución de errores potenciada por Copilot&lt;/h2&gt;
&lt;p&gt;Los errores de despliegue son inevitables. Parámetros faltantes, problemas de permisos, disponibilidad de SKUs — y el mensaje de error raramente te dice lo único que realmente necesitas saber: &lt;em&gt;cómo solucionarlo&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Sin Copilot, el ciclo es: copiar el error → buscar en docs → leer tres respuestas irrelevantes de Stack Overflow → ejecutar algunos comandos &lt;code&gt;az&lt;/code&gt; CLI → volver a intentarlo y rezar. Con Copilot integrado en &lt;code&gt;azd&lt;/code&gt;, ese ciclo se colapsa. Cuando cualquier comando &lt;code&gt;azd&lt;/code&gt; falla, ofrece inmediatamente cuatro opciones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Explain&lt;/strong&gt; — descripción en lenguaje natural de qué salió mal&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Guidance&lt;/strong&gt; — instrucciones paso a paso para solucionarlo&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diagnose and Guide&lt;/strong&gt; — análisis completo + Copilot aplica la solución (con tu aprobación) + reintento opcional&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skip&lt;/strong&gt; — gestionarlo tú mismo&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lo clave: Copilot ya tiene contexto sobre tu proyecto, el comando que falló y la salida del error. Sus sugerencias son específicas para &lt;em&gt;tu situación&lt;/em&gt;, no documentación genérica.&lt;/p&gt;
&lt;h3 id="ejemplos-reales-donde-brilla"&gt;Ejemplos reales donde brilla&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Proveedor de recursos no registrado:&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ERROR: deployment failed: MissingSubscriptionRegistration:
The subscription is not registered to use namespace &amp;#39;Microsoft.App&amp;#39;.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Esto falla a cualquiera que despliega en una suscripción nueva. Copilot puede registrar el proveedor y relanzar el despliegue automáticamente.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SKU no disponible:&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ERROR: deployment failed: SkuNotAvailable:
The requested VM size &amp;#39;Standard_D2s_v3&amp;#39; is not available in location &amp;#39;westus&amp;#39;.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Copilot explica qué tamaño de VM o región está bloqueado y sugiere alternativas disponibles en tu suscripción.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Colisión de nombre de cuenta de almacenamiento:&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ERROR: deployment failed: StorageAccountAlreadyTaken:
The storage account named &amp;#39;myappstorage&amp;#39; is already taken.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;La unicidad global le pasa a todo el mundo al menos una vez. Copilot sugiere añadir el nombre del entorno o un sufijo aleatorio a tus parámetros Bicep.&lt;/p&gt;
&lt;h3 id="configurar-un-comportamiento-predeterminado"&gt;Configurar un comportamiento predeterminado&lt;/h3&gt;
&lt;p&gt;Si siempre quieres la misma opción, salta el prompt interactivo:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;azd config set copilot.errorHandling.category troubleshoot
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Opciones: &lt;code&gt;explain&lt;/code&gt;, &lt;code&gt;guidance&lt;/code&gt;, &lt;code&gt;troubleshoot&lt;/code&gt;, &lt;code&gt;fix&lt;/code&gt;, &lt;code&gt;skip&lt;/code&gt;. También puedes habilitar auto-fix y reintento:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;azd config set copilot.errorHandling.fix allow
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Vuelve al modo interactivo en cualquier momento:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;azd config unset copilot.errorHandling.category
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="por-qué-importa-esto-para-los-desarrolladores-net"&gt;Por qué importa esto para los desarrolladores .NET&lt;/h2&gt;
&lt;p&gt;Si estás construyendo en Azure — ya sea una app .NET Aspire, una API en contenedor, o cualquier otra cosa — &lt;code&gt;azd&lt;/code&gt; es la herramienta que debes conocer. Esta integración con Copilot elimina la última barrera de fricción que antes hacía que necesitaras una chuleta para empezar.&lt;/p&gt;
&lt;p&gt;La pieza de scaffolding es genial para proyectos brownfield. Tienes una app ASP.NET Core funcionando localmente perfectamente, pero llevarla a Azure siempre ha requerido algo de conocimiento de infraestructura. Ahora Copilot tiende ese puente. Y la función de resolución de errores es algo que desearía haber tenido la última vez que pasé 45 minutos depurando un error &lt;code&gt;SkuNotAvailable&lt;/code&gt; en tres regiones diferentes.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Esta es exactamente el tipo de integración de Copilot que aporta valor real — no IA por el gusto de la IA, sino IA que entiende tu contexto y te ahorra tiempo real. Pruébalo ejecutando &lt;code&gt;azd update&lt;/code&gt; para obtener la última versión, y usa &lt;code&gt;azd init&lt;/code&gt; en tu próximo proyecto. El equipo está trabajando en funciones más profundas incluyendo personalización de infraestructura asistida por Copilot, así que ahora es un buen momento para &lt;a href="https://aka.ms/azd-user-research-signup"&gt;apuntarte a la investigación de usuarios&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Lee el &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-copilot-integration/"&gt;anuncio original aquí&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Escribir addons nativos de Node.js en C# con .NET Native AOT</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/nodejs-addons-csharp-native-aot/</link><pubDate>Tue, 21 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/nodejs-addons-csharp-native-aot/</guid><description>El equipo de C# Dev Kit reemplazó addons de Node.js escritos en C++ con .NET Native AOT — el resultado es más limpio, más seguro y solo necesita el SDK de .NET.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este artículo fue traducido automáticamente. Para ver la versión original en inglés, &lt;a href="https://thedotnetblog.com/es/posts/emiliano-montesdeoca/nodejs-addons-csharp-native-aot/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Este es un escenario que me encanta: un equipo que trabaja en herramientas .NET tenía addons nativos de Node.js escritos en C++ y compilados con &lt;code&gt;node-gyp&lt;/code&gt;. Funcionaba. Pero requería instalar Python en la máquina de cada desarrollador — una versión antigua de Python, nada menos — solo para construir un paquete que nadie del equipo tocaría directamente.&lt;/p&gt;
&lt;p&gt;Así que se hicieron una pregunta muy razonable: ya tenemos el SDK de .NET instalado, ¿por qué escribimos C++ en absoluto?&lt;/p&gt;
&lt;p&gt;La respuesta fue Native AOT, y el resultado es genuinamente elegante. Drew Noakes del equipo de C# Dev Kit documentó cómo lo hicieron, y creo que vale la pena entenderlo aunque no estés construyendo extensiones de VS Code.&lt;/p&gt;
&lt;h2 id="la-idea-básica"&gt;La idea básica&lt;/h2&gt;
&lt;p&gt;Un addon nativo de Node.js es una biblioteca compartida (&lt;code&gt;.dll&lt;/code&gt; en Windows, &lt;code&gt;.so&lt;/code&gt; en Linux, &lt;code&gt;.dylib&lt;/code&gt; en macOS) que Node.js puede cargar en tiempo de ejecución. La interfaz se llama &lt;a href="https://nodejs.org/api/n-api.html"&gt;N-API&lt;/a&gt; — una API C estable y compatible con ABI. A N-API no le importa qué lenguaje produjo la biblioteca, solo que exporte los símbolos correctos.&lt;/p&gt;
&lt;p&gt;.NET Native AOT puede producir exactamente eso. Compila tu código C# ahead-of-time en una biblioteca nativa compartida con puntos de entrada arbitrarios. Ese es todo el truco.&lt;/p&gt;
&lt;h2 id="configuración-del-proyecto"&gt;Configuración del proyecto&lt;/h2&gt;
&lt;p&gt;El archivo de proyecto es mínimo:&lt;/p&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;Project&lt;/span&gt; &lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Microsoft.NET.Sdk&amp;#34;&lt;/span&gt;&lt;span class="nt"&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="nt"&gt;&amp;lt;PropertyGroup&amp;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;lt;TargetFramework&amp;gt;&lt;/span&gt;net10.0&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;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;lt;PublishAot&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/PublishAot&amp;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;lt;AllowUnsafeBlocks&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/AllowUnsafeBlocks&amp;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;lt;/PropertyGroup&amp;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;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;PublishAot&lt;/code&gt; indica al SDK que produzca una biblioteca compartida al ejecutar &lt;code&gt;dotnet publish&lt;/code&gt;. &lt;code&gt;AllowUnsafeBlocks&lt;/code&gt; es necesario para el interop con N-API que usa punteros a funciones y buffers fijos.&lt;/p&gt;
&lt;h2 id="exportar-el-punto-de-entrada"&gt;Exportar el punto de entrada&lt;/h2&gt;
&lt;p&gt;Node.js espera que tu biblioteca exporte &lt;code&gt;napi_register_module_v1&lt;/code&gt;. En C#, &lt;code&gt;[UnmanagedCallersOnly]&lt;/code&gt; hace exactamente eso:&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="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;unsafe&lt;/span&gt; &lt;span class="kd"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RegistryAddon&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; [UnmanagedCallersOnly(
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; EntryPoint = &amp;#34;napi_register_module_v1&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; CallConvs = [typeof(CallConvCdecl)]&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="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;Init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;exports&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;Initialize&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;RegisterFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;readStringValue&amp;#34;&lt;/span&gt;&lt;span class="n"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ReadStringValue&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;return&lt;/span&gt; &lt;span class="n"&gt;exports&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;Algunas cosas que vale la pena señalar: &lt;code&gt;nint&lt;/code&gt; es un entero de tamaño nativo — el equivalente gestionado de &lt;code&gt;intptr_t&lt;/code&gt;. El sufijo &lt;code&gt;u8&lt;/code&gt; produce un &lt;code&gt;ReadOnlySpan&amp;lt;byte&amp;gt;&lt;/code&gt; con un literal de cadena UTF-8, pasado directamente a N-API sin ninguna asignación de codificación. Y &lt;code&gt;[UnmanagedCallersOnly]&lt;/code&gt; exporta el método con el nombre de punto de entrada exacto que Node.js busca.&lt;/p&gt;
&lt;h2 id="resolver-n-api-contra-el-proceso-host"&gt;Resolver N-API contra el proceso host&lt;/h2&gt;
&lt;p&gt;Las funciones de N-API las exporta &lt;code&gt;node.exe&lt;/code&gt; en sí mismo, no una biblioteca separada. Así que en lugar de enlazar contra algo, las resuelves contra el proceso en ejecución al inicio:&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;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Initialize&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;NativeLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetDllImportResolver&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;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reflection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetExecutingAssembly&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;ResolveDllImport&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;static&lt;/span&gt; &lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;ResolveDllImport&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="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;libraryName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Assembly&lt;/span&gt; &lt;span class="n"&gt;assembly&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DllImportSearchPath&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;searchPath&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;libraryName&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&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;return&lt;/span&gt; &lt;span class="n"&gt;NativeLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetMainProgramHandle&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;Con eso en su lugar, las declaraciones P/Invoke funcionan limpiamente, con &lt;code&gt;[LibraryImport]&lt;/code&gt; y marshalling generado por código fuente.&lt;/p&gt;
&lt;h2 id="una-función-exportada-real"&gt;Una función exportada real&lt;/h2&gt;
&lt;p&gt;Aquí está el lector de registro que construyeron — la función completa, desde leer argumentos hasta devolver un resultado:&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;[UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)]&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;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;ReadStringValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;info&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;try&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;var&lt;/span&gt; &lt;span class="n"&gt;keyPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetStringArg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;valueName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetStringArg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyPath&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;valueName&lt;/span&gt; &lt;span class="k"&gt;is&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="n"&gt;ThrowError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Expected two string arguments: keyPath, valueName&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;return&lt;/span&gt; &lt;span class="m"&gt;0&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="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenSubKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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;return&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valueName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="k"&gt;value&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;CreateString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;value&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;GetUndefined&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&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;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&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;ThrowError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;$&amp;#34;Registry read failed: {ex.Message}&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;return&lt;/span&gt; &lt;span class="m"&gt;0&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;Nota importante sobre el &lt;code&gt;try/catch&lt;/code&gt;: una excepción no manejada en un método &lt;code&gt;[UnmanagedCallersOnly]&lt;/code&gt; provoca el crash del proceso host. Siempre captura y reenvía a JavaScript mediante &lt;code&gt;ThrowError&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="llamándolo-desde-typescript"&gt;Llamándolo desde TypeScript&lt;/h2&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;interface&lt;/span&gt; &lt;span class="nx"&gt;RegistryAddon&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="nx"&gt;readStringValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyPath&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;valueName&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&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="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;registry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./native/win32-x64/RegistryAddon.node&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;RegistryAddon&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;sdkPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readStringValue&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="s1"&gt;&amp;#39;SOFTWARE\\dotnet\\Setup\\InstalledVersions\\x64\\sdk&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 class="s1"&gt;&amp;#39;InstallLocation&amp;#39;&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;TypeScript → C#, sin Python, sin C++.&lt;/p&gt;
&lt;h2 id="lo-que-ganaron"&gt;Lo que ganaron&lt;/h2&gt;
&lt;p&gt;La victoria inmediata fue en la experiencia del contribuidor: ya no se necesita ninguna versión específica de Python, &lt;code&gt;yarn install&lt;/code&gt; funciona solo con Node.js y el SDK de .NET. Los pipelines de CI también se simplificaron.&lt;/p&gt;
&lt;p&gt;El rendimiento fue comparable a la implementación en C++. Native AOT produce código nativo optimizado, y para marshalling de cadenas y acceso al registro, la diferencia es insignificante.&lt;/p&gt;
&lt;h2 id="por-qué-me-parece-interesante-más-allá-de-las-extensiones-vs-code"&gt;Por qué me parece interesante más allá de las extensiones VS Code&lt;/h2&gt;
&lt;p&gt;Cualquier entorno que pueda cargar una biblioteca nativa compartida — apps Electron, extensiones Python vía ctypes, Rust vía FFI, Node.js vía N-API — es ahora un posible host para código C#. Para desarrolladores .NET que tenían escenarios de interop en mente pero no querían aprender un sistema de compilación C++, este patrón vale la pena conocerlo.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;El equipo de C# Dev Kit reemplazó la sobrecarga de Python/C++ con código C# limpio que todo el equipo ya sabe escribir y depurar. Si quieres el recorrido completo con todos los helpers de marshalling de cadenas, consulta el &lt;a href="https://devblogs.microsoft.com/dotnet/writing-nodejs-addons-with-dotnet-native-aot/"&gt;artículo original en el blog de .NET&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.117: Los Agentes Están Obteniendo Sus Propias Ramas de Git y Estoy Totalmente a Favor</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/vscode-1-117-agents-autopilot-worktrees/</link><pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/vscode-1-117-agents-autopilot-worktrees/</guid><description>VS Code 1.117 trae aislamiento con worktrees para sesiones de agentes, modo Autopilot persistente y soporte para subagentes. El flujo de trabajo con agentes de código se puso mucho más serio.</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/posts/emiliano-montesdeoca/vscode-1-117-agents-autopilot-worktrees/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;La línea entre &amp;ldquo;asistente de IA&amp;rdquo; y &amp;ldquo;compañero de equipo de IA&amp;rdquo; sigue haciéndose más delgada. VS Code 1.117 acaba de salir y las &lt;a href="https://code.visualstudio.com/updates/v1_117"&gt;notas de la versión completas&lt;/a&gt; están cargadas, pero la historia está clara: los agentes se están convirtiendo en ciudadanos de primera clase en tu flujo de trabajo de desarrollo.&lt;/p&gt;
&lt;p&gt;Esto es lo que realmente importa.&lt;/p&gt;
&lt;h2 id="el-modo-autopilot-finalmente-recuerda-tu-preferencia"&gt;El modo Autopilot finalmente recuerda tu preferencia&lt;/h2&gt;
&lt;p&gt;Antes, tenías que volver a activar Autopilot cada vez que iniciabas una nueva sesión. Molesto. Ahora tu modo de permisos persiste entre sesiones y puedes configurar el valor por defecto.&lt;/p&gt;
&lt;p&gt;El Agent Host soporta tres configuraciones de sesión:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Default&lt;/strong&gt; — las herramientas piden confirmación antes de ejecutarse&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bypass&lt;/strong&gt; — aprueba todo automáticamente&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Autopilot&lt;/strong&gt; — totalmente autónomo, responde sus propias preguntas y sigue adelante&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si estás creando un nuevo proyecto .NET con migraciones, Docker y CI — configúralo en Autopilot una vez y olvídate. Esa preferencia se mantiene.&lt;/p&gt;
&lt;h2 id="worktree-y-aislamiento-de-git-para-sesiones-de-agentes"&gt;Worktree y aislamiento de git para sesiones de agentes&lt;/h2&gt;
&lt;p&gt;Esta es la grande. Las sesiones de agentes ahora soportan aislamiento completo con worktrees y git. Eso significa que cuando un agente trabaja en una tarea, obtiene su propia rama y directorio de trabajo. Tu rama principal queda intacta.&lt;/p&gt;
&lt;p&gt;Mejor aún — Copilot CLI genera nombres de rama significativos para estas sesiones de worktree. Se acabó el &lt;code&gt;agent-session-abc123&lt;/code&gt;. Obtienes algo que realmente describe lo que el agente está haciendo.&lt;/p&gt;
&lt;p&gt;Para desarrolladores .NET que manejan múltiples ramas de features o corrigen bugs mientras una tarea larga de scaffolding corre, esto es un cambio total. Puedes tener un agente construyendo tus controladores de API en un worktree mientras tú depuras un problema en la capa de servicios en otro. Sin conflictos. Sin stashing. Sin desorden.&lt;/p&gt;
&lt;h2 id="subagentes-y-equipos-de-agentes"&gt;Subagentes y equipos de agentes&lt;/h2&gt;
&lt;p&gt;El Agent Host Protocol ahora soporta subagentes. Un agente puede lanzar otros agentes para manejar partes de una tarea. Piénsalo como delegar — tu agente principal coordina, y agentes especializados se encargan de las piezas.&lt;/p&gt;
&lt;p&gt;Esto es temprano, pero el potencial para flujos de trabajo .NET es obvio. Imagina un agente manejando tus migraciones de EF Core mientras otro configura tus pruebas de integración. No estamos totalmente ahí todavía, pero que el soporte del protocolo aterrice ahora significa que las herramientas vendrán rápido.&lt;/p&gt;
&lt;h2 id="la-salida-del-terminal-se-incluye-automáticamente-cuando-los-agentes-envían-input"&gt;La salida del terminal se incluye automáticamente cuando los agentes envían input&lt;/h2&gt;
&lt;p&gt;Pequeño pero significativo. Cuando un agente envía input al terminal, la salida del terminal ahora se incluye automáticamente en el contexto. Antes, el agente tenía que hacer un turno extra solo para leer lo que pasó.&lt;/p&gt;
&lt;p&gt;Si alguna vez viste a un agente ejecutar &lt;code&gt;dotnet build&lt;/code&gt;, fallar, y luego tomar otro viaje de ida y vuelta solo para ver el error — esa fricción desapareció. Ve la salida inmediatamente y reacciona.&lt;/p&gt;
&lt;h2 id="la-app-de-agents-en-macos-se-auto-actualiza"&gt;La app de Agents en macOS se auto-actualiza&lt;/h2&gt;
&lt;p&gt;La app independiente de Agents en macOS ahora se auto-actualiza. No más descargas manuales de nuevas versiones. Simplemente se mantiene al día.&lt;/p&gt;
&lt;h2 id="las-cosas-más-pequeñas-que-vale-la-pena-saber"&gt;Las cosas más pequeñas que vale la pena saber&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Los &lt;strong&gt;hovers de package.json&lt;/strong&gt; ahora muestran tanto la versión instalada como la última disponible. Útil si manejas herramientas npm junto con tus proyectos .NET.&lt;/li&gt;
&lt;li&gt;Las &lt;strong&gt;imágenes en comentarios JSDoc&lt;/strong&gt; se renderizan correctamente en hovers y completados.&lt;/li&gt;
&lt;li&gt;Las &lt;strong&gt;sesiones de Copilot CLI&lt;/strong&gt; ahora indican si fueron creadas por VS Code o externamente — práctico cuando saltas entre terminales.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copilot CLI, Claude Code y Gemini CLI&lt;/strong&gt; son reconocidos como tipos de shell. El editor sabe lo que estás ejecutando.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="la-conclusión"&gt;La conclusión&lt;/h2&gt;
&lt;p&gt;VS Code 1.117 no es un volcado de features llamativas. Es infraestructura. Aislamiento con worktrees, permisos persistentes, protocolos de subagentes — estos son los bloques de construcción para un flujo de trabajo donde los agentes manejan tareas reales y paralelas sin pisar tu código.&lt;/p&gt;
&lt;p&gt;Si estás construyendo con .NET y todavía no te has metido en el flujo de trabajo con agentes, honestamente, ahora es el momento de empezar.&lt;/p&gt;</content:encoded></item><item><title>El RFT de Foundry ahora es más barato e inteligente — Esto es lo que cambió</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/foundry-fine-tuning-april-2026-rft-graders/</link><pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/foundry-fine-tuning-april-2026-rft-graders/</guid><description>Microsoft Foundry lanzó tres actualizaciones de RFT este mes: entrenamiento global para o4-mini, nuevos evaluadores de modelo GPT-4.1 y una guía de mejores prácticas que te ahorrará horas 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/posts/emiliano-montesdeoca/foundry-fine-tuning-april-2026-rft-graders/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si estás desarrollando aplicaciones .NET que dependen de modelos fine-tuneados, las actualizaciones de Foundry de este mes merecen tu atención. El Reinforcement Fine-Tuning ahora es más accesible y significativamente más barato.&lt;/p&gt;
&lt;p&gt;Los detalles completos están en el &lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-foundry-finetune-april-2026/"&gt;anuncio oficial&lt;/a&gt;, pero aquí va el resumen práctico.&lt;/p&gt;
&lt;h2 id="entrenamiento-global-para-o4-mini"&gt;Entrenamiento Global para o4-mini&lt;/h2&gt;
&lt;p&gt;o4-mini es el modelo preferido para cargas de trabajo pesadas en razonamiento y agentes. La gran noticia: ahora puedes lanzar trabajos de fine-tuning desde más de 13 regiones de Azure con tarifas de entrenamiento por token más bajas en comparación con el entrenamiento Standard. Misma infraestructura, misma calidad, mayor alcance.&lt;/p&gt;
&lt;p&gt;Si tu equipo está distribuido geográficamente, esto importa. Ya no estás limitado a un puñado de regiones para entrenar.&lt;/p&gt;
&lt;p&gt;Aquí está la llamada a la API REST para iniciar un trabajo de entrenamiento global:&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;curl -X POST &lt;span class="s2"&gt;&amp;#34;https://&amp;lt;your-resource&amp;gt;.openai.azure.com/openai/fine_tuning/jobs?api-version=2025-04-01-preview&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -H &lt;span class="s2"&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -H &lt;span class="s2"&gt;&amp;#34;api-key: &lt;/span&gt;&lt;span class="nv"&gt;$AZURE_OPENAI_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -d &lt;span class="s1"&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;model&amp;#34;: &amp;#34;o4-mini&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;training_file&amp;#34;: &amp;#34;&amp;lt;your-training-file-id&amp;gt;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;method&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;type&amp;#34;: &amp;#34;reinforcement&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;reinforcement&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;grader&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;type&amp;#34;: &amp;#34;string_check&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;name&amp;#34;: &amp;#34;answer-check&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;input&amp;#34;: &amp;#34;{{sample.output_text}}&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;reference&amp;#34;: &amp;#34;{{item.reference_answer}}&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;operation&amp;#34;: &amp;#34;eq&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;hyperparameters&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;n_epochs&amp;#34;: 2,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;compute_multiplier&amp;#34;: 1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;trainingType&amp;#34;: &amp;#34;globalstandard&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ese flag &lt;code&gt;trainingType: globalstandard&lt;/code&gt; es la diferencia clave.&lt;/p&gt;
&lt;h2 id="nuevos-evaluadores-de-modelo-familia-gpt-41"&gt;Nuevos Evaluadores de Modelo: Familia GPT-4.1&lt;/h2&gt;
&lt;p&gt;Los evaluadores definen la señal de recompensa contra la cual tu modelo optimiza. Hasta ahora, los evaluadores basados en modelo estaban limitados a un conjunto más pequeño de modelos. Ahora tienes tres nuevas opciones: GPT-4.1, GPT-4.1-mini y GPT-4.1-nano.&lt;/p&gt;
&lt;p&gt;¿Cuándo deberías usar evaluadores de modelo en lugar de determinísticos? Cuando la salida de tu tarea es abierta, cuando necesitas puntuación parcial en múltiples dimensiones, o cuando estás construyendo flujos de trabajo con agentes donde la corrección de las llamadas a herramientas depende del contexto semántico.&lt;/p&gt;
&lt;p&gt;La cuestión es que la estrategia de niveles es práctica:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPT-4.1-nano&lt;/strong&gt; para iteraciones iniciales. Bajo costo, ciclos de retroalimentación rápidos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-4.1-mini&lt;/strong&gt; una vez que tu rúbrica de evaluación sea estable y necesites mayor fidelidad.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-4.1&lt;/strong&gt; para evaluación en producción o rúbricas complejas donde cada decisión de puntuación cuenta.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Incluso puedes mezclar tipos de evaluadores en un solo trabajo de RFT. Usa string-match para la dimensión de &amp;ldquo;respuesta correcta&amp;rdquo; y un evaluador de modelo para evaluar la calidad del razonamiento. Esa flexibilidad es honestamente lo que lo hace útil para cargas de trabajo reales.&lt;/p&gt;
&lt;h2 id="el-problema-del-formato-de-datos-de-rft"&gt;El Problema del Formato de Datos de RFT&lt;/h2&gt;
&lt;p&gt;Esto confunde a mucha gente. El formato de datos de RFT es diferente al de SFT. El último mensaje en cada fila debe tener rol User o Developer — no Assistant. La respuesta esperada va en una clave de nivel superior como &lt;code&gt;reference_answer&lt;/code&gt; que el evaluador referencia directamente.&lt;/p&gt;
&lt;p&gt;Si has estado haciendo supervised fine-tuning y quieres cambiar a RFT, necesitas reestructurar tus datos de entrenamiento. No te saltes este paso o tus trabajos fallarán silenciosamente.&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 llamando modelos fine-tuneados desde tus aplicaciones .NET a través del SDK de Azure OpenAI, un entrenamiento más barato significa que puedes iterar de forma más agresiva. Las opciones de evaluadores de modelo significan que puedes hacer fine-tuning para tareas con matices — no solo escenarios de coincidencia exacta. Y la guía de mejores prácticas en &lt;a href="https://github.com/microsoft-foundry/fine-tuning/blob/main/Demos/Agentic_RFT_PrivatePreview/RFT_Best_Practice.md"&gt;GitHub&lt;/a&gt; te ahorrará tiempo real de depuración.&lt;/p&gt;
&lt;p&gt;Empieza pequeño. De diez a cien muestras. Evaluador simple. Valida el ciclo. Luego escala.&lt;/p&gt;</content:encoded></item><item><title>Global Azure Spain 2026</title><link>https://thedotnetblog.com/es/events/global-azure-spain-2026/</link><pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/es/events/global-azure-spain-2026/</guid><description>El mayor evento de la comunidad Azure en España — un día completo de sesiones sobre Azure, IA, datos, seguridad y desarrollo cloud-native con 38 ponentes en 3 tracks.</description><content:encoded>&lt;p&gt;Global Azure Spain 2026 se celebra el &lt;strong&gt;18 de abril de 2026&lt;/strong&gt; en &lt;strong&gt;Kinépolis Diversia&lt;/strong&gt; en Alcobendas, Madrid. Es el mayor evento de la comunidad Azure en España, reuniendo a 38 ponentes en 3 tracks paralelos que cubren agentes de IA, networking en Azure, Cosmos DB, Fabric, IoT, seguridad y mucho más.&lt;/p&gt;
&lt;p&gt;El evento transcurre de &lt;strong&gt;08:30 a 18:30&lt;/strong&gt; e incluye keynote, pausas para café, almuerzo y una sesión de cierre con preguntas.&lt;/p&gt;
&lt;h2 id="puntos-destacados-de-la-agenda"&gt;Puntos destacados de la agenda&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Domando Agentes de IA&lt;/strong&gt;: gobernanza, herramientas y APIs con Azure AI Foundry y Azure API Management&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Construyendo agentes con LibreChat en Azure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How Can I Steal Your Data with Azure Private Endpoints&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stop Building APIs. Forge Agents with Azure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agentic DevOps Meets IoT: Real-Time Systems with Fabric and GitHub Copilot&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;El regreso de los tamagotchis!&lt;/strong&gt;: sistemas multi-agente en acción&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Foundry Control Plane como plataforma de Agentes global&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rompiendo el perímetro: Zero Trust aplicado en Azure&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="entradas"&gt;Entradas&lt;/h2&gt;
&lt;p&gt;La inscripción es una donación simbólica — el precio completo de la entrada se destina directamente a &lt;strong&gt;Plan International&lt;/strong&gt;, apoyando los derechos de los niños y la igualdad en todo el mundo. Aforo limitado, así que reserva tu plaza pronto.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.eventbrite.es/e/entradas-global-azure-spain-2026-en-madrid-1981594189564"&gt;Consigue entradas en Eventbrite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://globalazure.es/"&gt;Sitio web del evento&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="azure-tour-2026"&gt;Azure Tour 2026&lt;/h2&gt;
&lt;p&gt;Además de Madrid, el Global Azure Tour 2026 también incluye paradas en &lt;strong&gt;Zaragoza&lt;/strong&gt;, &lt;strong&gt;Tenerife&lt;/strong&gt; y &lt;strong&gt;Sevilla&lt;/strong&gt;.&lt;/p&gt;</content:encoded></item><item><title>Tus experimentos de IA en Azure están quemando dinero — Así es como solucionarlo</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/cloud-cost-optimization-ai-workloads-azure/</link><pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/cloud-cost-optimization-ai-workloads-azure/</guid><description>Las cargas de trabajo de IA en Azure pueden volverse caras rápidamente. Hablemos de lo que realmente funciona para mantener los costos bajo control sin frenar tu desarrollo.</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/posts/emiliano-montesdeoca/cloud-cost-optimization-ai-workloads-azure/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si estás construyendo aplicaciones con IA en Azure ahora mismo, probablemente hayas notado algo: tu factura de la nube se ve diferente a como solía ser. No solo más alta — más rara. Con picos. Difícil de predecir.&lt;/p&gt;
&lt;p&gt;Microsoft acaba de publicar un excelente artículo sobre &lt;a href="https://azure.microsoft.com/en-us/blog/cloud-cost-optimization-principles-that-still-matter/"&gt;principios de optimización de costos en la nube que siguen importando&lt;/a&gt;, y honestamente, el momento no podría ser mejor. Porque las cargas de trabajo de IA han cambiado las reglas del juego en cuanto a costos.&lt;/p&gt;
&lt;h2 id="por-qué-las-cargas-de-trabajo-de-ia-pegan-diferente"&gt;Por qué las cargas de trabajo de IA pegan diferente&lt;/h2&gt;
&lt;p&gt;La cosa es esta. Las cargas de trabajo tradicionales de .NET son relativamente predecibles. Conoces tu nivel de App Service, conoces tus DTUs de SQL, puedes estimar el gasto mensual con bastante precisión. ¿Cargas de trabajo de IA? No tanto.&lt;/p&gt;
&lt;p&gt;Estás probando múltiples modelos para ver cuál encaja. Estás levantando infraestructura con GPU para fine-tuning. Estás haciendo llamadas a la API de Azure OpenAI donde el consumo de tokens varía enormemente dependiendo de la longitud del prompt y el comportamiento del usuario. Cada experimento cuesta dinero real, y podrías ejecutar docenas antes de dar con el enfoque correcto.&lt;/p&gt;
&lt;p&gt;Esa imprevisibilidad es lo que hace que la optimización de costos sea crítica — no como algo secundario, sino desde el día uno.&lt;/p&gt;
&lt;h2 id="gestión-vs-optimización--conoce-la-diferencia"&gt;Gestión vs. optimización — conoce la diferencia&lt;/h2&gt;
&lt;p&gt;Una distinción del artículo que creo que los desarrolladores pasan por alto: hay una diferencia entre &lt;em&gt;gestión&lt;/em&gt; de costos y &lt;em&gt;optimización&lt;/em&gt; de costos.&lt;/p&gt;
&lt;p&gt;La gestión es seguimiento y reportes. Configuras presupuestos en Azure Cost Management, recibes alertas, ves dashboards. Eso es lo básico.&lt;/p&gt;
&lt;p&gt;La optimización es donde realmente tomas decisiones. ¿Realmente necesitas ese tier S3, o el S1 manejaría tu carga? ¿Esa instancia de compute siempre encendida está ociosa los fines de semana? ¿Podrías usar instancias spot para tus trabajos de entrenamiento?&lt;/p&gt;
&lt;p&gt;Como desarrolladores .NET, tendemos a enfocarnos en el código y dejar las decisiones de infraestructura al &amp;ldquo;equipo de operaciones&amp;rdquo;. Pero si estás desplegando en Azure, esas decisiones también son tus decisiones.&lt;/p&gt;
&lt;h2 id="qué-es-lo-que-realmente-funciona"&gt;Qué es lo que realmente funciona&lt;/h2&gt;
&lt;p&gt;Basándome en el artículo y en mi propia experiencia, esto es lo que marca la diferencia:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sabe qué estás gastando y dónde.&lt;/strong&gt; Etiqueta tus recursos. En serio. Si no puedes distinguir qué proyecto o experimento se está comiendo tu presupuesto, no puedes optimizar nada. Azure Cost Management con etiquetado adecuado es tu mejor aliado.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Establece límites antes de experimentar.&lt;/strong&gt; Usa Azure Policy para restringir SKUs costosos en entornos de dev/test. Establece límites de gasto en tus despliegues de Azure OpenAI. No esperes a que llegue la factura para darte cuenta de que alguien dejó un clúster de GPU corriendo todo el fin de semana.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ajusta el tamaño continuamente.&lt;/strong&gt; ¿Esa VM que elegiste durante el prototipado? Probablemente no sea la correcta para producción. Azure Advisor te da recomendaciones — realmente míralas. Revisa mensualmente, no anualmente.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Piensa en el ciclo de vida.&lt;/strong&gt; Los recursos de desarrollo deberían apagarse. Los entornos de prueba no necesitan correr 24/7. Usa políticas de apagado automático. Para cargas de trabajo de IA específicamente, considera opciones serverless donde pagas por ejecución en lugar de mantener el compute encendido.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mide el valor, no solo el costo.&lt;/strong&gt; Esta es fácil de olvidar. Un modelo que cuesta más pero entrega resultados significativamente mejores podría ser la decisión correcta. El objetivo no es gastar lo menos posible — es gastar inteligentemente.&lt;/p&gt;
&lt;h2 id="la-conclusión"&gt;La conclusión&lt;/h2&gt;
&lt;p&gt;La optimización de costos en la nube no es una limpieza de una sola vez. Es un hábito. Y con las cargas de trabajo de IA haciendo que el gasto sea menos predecible que nunca, construir ese hábito temprano te ahorra sorpresas dolorosas más adelante.&lt;/p&gt;
&lt;p&gt;Si eres un desarrollador .NET construyendo sobre Azure, empieza a tratar tu factura de la nube como tratas tu código — revísala regularmente, refactoriza cuando se ponga desordenada, y nunca despliegues sin entender lo que te va a costar.&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/posts/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/posts/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/posts/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>Docker Sandbox permite a los agentes de Copilot refactorizar tu código sin poner en riesgo tu máquina</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/copilot-docker-sandbox-agentic-refactoring/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/copilot-docker-sandbox-agentic-refactoring/</guid><description>Docker Sandbox ofrece a los agentes de GitHub Copilot una microVM segura donde pueden refactorizar sin límites — sin prompts de permisos, sin riesgos para tu host. Así es como esto cambia todo para la modernización de .NET a gran escala.</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/posts/emiliano-montesdeoca/copilot-docker-sandbox-agentic-refactoring/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si usaste el modo agente de Copilot para algo más que ediciones pequeñas, conocés el dolor. Cada escritura de archivo, cada comando en terminal — otro prompt de permisos. Ahora imaginá eso multiplicado por 50 proyectos. No es divertido.&lt;/p&gt;
&lt;p&gt;El equipo de Azure acaba de publicar un post sobre &lt;a href="https://devblogs.microsoft.com/all-things-azure/best-of-both-worlds-for-agentic-refactoring-github-copilot-microvms-via-docker-sandbox/"&gt;Docker Sandbox para agentes de GitHub Copilot&lt;/a&gt;, y honestamente, es una de las mejoras más prácticas que he visto en herramientas agénticas. Usa microVMs para darle a Copilot un entorno completamente aislado donde puede hacer de todo — instalar paquetes, ejecutar builds, correr tests — sin tocar tu sistema host.&lt;/p&gt;
&lt;h2 id="qué-te-da-realmente-docker-sandbox"&gt;Qué te da realmente Docker Sandbox&lt;/h2&gt;
&lt;p&gt;La idea central es simple: levantar una microVM liviana con un entorno Linux completo, sincronizar tu workspace dentro de ella, y dejar que el agente de Copilot opere libremente adentro. Cuando termina, los cambios se sincronizan de vuelta.&lt;/p&gt;
&lt;p&gt;Esto es lo que lo hace más que simplemente &amp;ldquo;ejecutar cosas en un contenedor&amp;rdquo;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sincronización bidireccional del workspace&lt;/strong&gt; que preserva rutas absolutas. La estructura de tu proyecto se ve idéntica dentro del sandbox. Sin fallos de build por rutas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker daemon privado&lt;/strong&gt; corriendo dentro de la microVM. El agente puede construir y ejecutar contenedores sin montar jamás el socket de Docker de tu host. Eso es importante para la seguridad.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proxies de filtrado HTTP/HTTPS&lt;/strong&gt; que controlan lo que el agente puede alcanzar en la red. Vos decidís qué registries y endpoints están permitidos. ¿Ataques a la cadena de suministro por un &lt;code&gt;npm install&lt;/code&gt; malicioso dentro del sandbox? Bloqueados.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Modo YOLO&lt;/strong&gt; — sí, así lo llaman. El agente corre sin prompts de permisos porque literalmente no puede dañar tu host. Toda acción destructiva está contenida.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="por-qué-los-desarrolladores-net-deberían-prestar-atención"&gt;Por qué los desarrolladores .NET deberían prestar atención&lt;/h2&gt;
&lt;p&gt;Pensá en el trabajo de modernización que tantos equipos están enfrentando ahora mismo. Tenés una solución .NET Framework con 30 proyectos, y necesitás moverla a .NET 9. Son cientos de cambios en archivos — archivos de proyecto, actualizaciones de namespaces, reemplazos de APIs, migraciones de NuGet.&lt;/p&gt;
&lt;p&gt;Con Docker Sandbox, podés apuntar un agente de Copilot a un proyecto, dejarlo refactorizar libremente dentro de la microVM, ejecutar &lt;code&gt;dotnet build&lt;/code&gt; y &lt;code&gt;dotnet test&lt;/code&gt; para validar, y solo aceptar los cambios que realmente funcionan. Sin riesgo de que accidentalmente destruya tu entorno de desarrollo local mientras experimenta.&lt;/p&gt;
&lt;p&gt;El post también describe ejecutar una &lt;strong&gt;flota de agentes en paralelo&lt;/strong&gt; — cada uno en su propio sandbox — trabajando en diferentes proyectos simultáneamente. Para soluciones .NET grandes o arquitecturas de microservicios, eso ahorra una cantidad enorme de tiempo. Un agente por servicio, todos corriendo aislados, todos validados independientemente.&lt;/p&gt;
&lt;h2 id="el-ángulo-de-seguridad-importa"&gt;El ángulo de seguridad importa&lt;/h2&gt;
&lt;p&gt;Acá está lo que la mayoría pasa por alto: cuando dejás que un agente de IA ejecute comandos arbitrarios, le estás confiando toda tu máquina. Docker Sandbox invierte ese modelo. El agente tiene autonomía total dentro de un entorno desechable. El proxy de red asegura que solo pueda descargar de fuentes aprobadas. Tu filesystem host, tu Docker daemon y tus credenciales quedan intactos.&lt;/p&gt;
&lt;p&gt;Para equipos con requisitos de compliance — y eso es la mayoría de las empresas .NET — esta es la diferencia entre &amp;ldquo;no podemos usar IA agéntica&amp;rdquo; y &amp;ldquo;podemos adoptarla de forma segura&amp;rdquo;.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Docker Sandbox resuelve la tensión fundamental de la programación agéntica: los agentes necesitan libertad para ser útiles, pero libertad en tu máquina host es peligroso. Las microVMs te dan ambas cosas. Si estás planificando cualquier refactorización o modernización de .NET a gran escala, vale la pena configurar esto ahora. La combinación de la inteligencia de código de Copilot con un entorno de ejecución seguro es exactamente lo que los equipos de producción estaban esperando.&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/posts/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/posts/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/posts/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>Las herramientas Azure MCP ahora vienen integradas en Visual Studio 2022 — Sin extensión necesaria</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-mcp-tools-built-into-visual-studio-2022/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-mcp-tools-built-into-visual-studio-2022/</guid><description>Las herramientas Azure MCP se incluyen como parte de la carga de trabajo de desarrollo Azure en Visual Studio 2022. Más de 230 herramientas, 45 servicios de Azure, cero extensiones que instalar.</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/posts/emiliano-montesdeoca/azure-mcp-tools-built-into-visual-studio-2022/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si has estado usando las herramientas Azure MCP en Visual Studio a través de la extensión separada, ya conoces el proceso — instalar el VSIX, reiniciar, cruzar los dedos para que no se rompa, gestionar incompatibilidades de versiones. Esa fricción se acabó.&lt;/p&gt;
&lt;p&gt;Yun Jung Choi &lt;a href="https://devblogs.microsoft.com/visualstudio/azure-mcp-tools-now-ship-built-into-visual-studio-2022-no-extension-required/"&gt;anunció&lt;/a&gt; que las herramientas Azure MCP ahora se incluyen directamente como parte de la carga de trabajo de desarrollo Azure en Visual Studio 2022. Sin extensión. Sin VSIX. Sin el baile de reiniciar.&lt;/p&gt;
&lt;h2 id="qué-significa-esto-realmente"&gt;Qué significa esto realmente&lt;/h2&gt;
&lt;p&gt;A partir de Visual Studio 2022 versión 17.14.30, el Azure MCP Server viene incluido con la carga de trabajo de desarrollo Azure. Si ya tienes esa carga de trabajo instalada, solo necesitas activarlo en GitHub Copilot Chat y listo.&lt;/p&gt;
&lt;p&gt;Más de 230 herramientas en 45 servicios de Azure — accesibles directamente desde la ventana de chat. Lista tus cuentas de almacenamiento, despliega una app ASP.NET Core, diagnostica problemas en App Service, consulta Log Analytics — todo sin abrir una pestaña del navegador.&lt;/p&gt;
&lt;h2 id="por-qué-esto-importa-más-de-lo-que-parece"&gt;Por qué esto importa más de lo que parece&lt;/h2&gt;
&lt;p&gt;La cosa con las herramientas de desarrollo es esta: cada paso extra es fricción, y la fricción mata la adopción. Tener MCP como extensión separada significaba incompatibilidades de versiones, fallos en la instalación, y una cosa más que mantener actualizada. Integrarlo en la carga de trabajo significa:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Una sola vía de actualización&lt;/strong&gt; a través del Visual Studio Installer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sin desviaciones de versión&lt;/strong&gt; entre la extensión y el IDE&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Siempre actualizado&lt;/strong&gt; — el MCP Server se actualiza con las versiones regulares de VS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para equipos que estandarizan en Azure, esto es muy importante. Instalas la carga de trabajo una vez, activas las herramientas, y están ahí para cada sesión.&lt;/p&gt;
&lt;h2 id="qué-puedes-hacer-con-esto"&gt;Qué puedes hacer con esto&lt;/h2&gt;
&lt;p&gt;Las herramientas cubren todo el ciclo de vida del desarrollo a través de Copilot Chat:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Aprender&lt;/strong&gt; — pregunta sobre servicios de Azure, buenas prácticas, patrones de arquitectura&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diseñar y desarrollar&lt;/strong&gt; — obtén recomendaciones de servicios, configura el código de tu aplicación&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Desplegar&lt;/strong&gt; — aprovisiona recursos y despliega directamente desde el IDE&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Solucionar problemas&lt;/strong&gt; — consulta logs, verifica el estado de los recursos, diagnostica problemas en producción&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Un ejemplo rápido — escribe esto en Copilot Chat:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;List my storage accounts in my current subscription.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Copilot llama a las herramientas Azure MCP detrás de escena, consulta tus suscripciones, y devuelve una lista formateada con nombres, ubicaciones y SKUs. Sin necesidad del portal.&lt;/p&gt;
&lt;h2 id="cómo-activarlo"&gt;Cómo activarlo&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Actualiza a Visual Studio 2022 &lt;strong&gt;17.14.30&lt;/strong&gt; o superior&lt;/li&gt;
&lt;li&gt;Asegúrate de tener instalada la carga de trabajo &lt;strong&gt;Azure development&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Abre GitHub Copilot Chat&lt;/li&gt;
&lt;li&gt;Haz clic en el botón &lt;strong&gt;Select tools&lt;/strong&gt; (el icono de las dos llaves)&lt;/li&gt;
&lt;li&gt;Activa &lt;strong&gt;Azure MCP Server&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Eso es todo. Se mantiene activado entre sesiones.&lt;/p&gt;
&lt;h2 id="una-advertencia"&gt;Una advertencia&lt;/h2&gt;
&lt;p&gt;Las herramientas están desactivadas por defecto — necesitas activarlas manualmente. Y las herramientas específicas de VS 2026 no están disponibles en VS 2022. La disponibilidad de herramientas también depende de los permisos de tu suscripción de Azure, igual que en el portal.&lt;/p&gt;
&lt;h2 id="el-panorama-general"&gt;El panorama general&lt;/h2&gt;
&lt;p&gt;Esto es parte de una tendencia clara: MCP se está convirtiendo en el estándar para exponer herramientas de la nube en los IDEs de desarrollo. Ya hemos visto el &lt;a href="https://devblogs.microsoft.com/azure-sdk/announcing-azure-mcp-server-2-0-stable-release/"&gt;lanzamiento estable de Azure MCP Server 2.0&lt;/a&gt; e integraciones de MCP en VS Code y otros editores. Tenerlo integrado en el sistema de cargas de trabajo de Visual Studio es la progresión natural.&lt;/p&gt;
&lt;p&gt;Para los que somos desarrolladores .NET y vivimos en Visual Studio, esto elimina una razón más para cambiar de contexto al portal de Azure. Y sinceramente, mientras menos cambio de pestañas, mejor.&lt;/p&gt;</content:encoded></item><item><title>¿Dónde deberías alojar tus agentes de IA en Azure? Una guía práctica de decisión</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-ai-agent-hosting-options-guide/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-ai-agent-hosting-options-guide/</guid><description>Azure ofrece seis formas de alojar agentes de IA — desde contenedores crudos hasta Foundry Hosted Agents completamente gestionados. Así es como elegir el adecuado para tu carga de trabajo .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/posts/emiliano-montesdeoca/azure-ai-agent-hosting-options-guide/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si estás construyendo agentes de IA con .NET ahora mismo, probablemente hayas notado algo: hay &lt;em&gt;muchas&lt;/em&gt; formas de alojarlos en Azure. Container Apps, AKS, Functions, App Service, Foundry Agents, Foundry Hosted Agents — y todos suenan razonables hasta que realmente necesitas elegir uno. Microsoft acaba de publicar una &lt;a href="https://devblogs.microsoft.com/all-things-azure/hostedagent/"&gt;guía completa sobre alojamiento de agentes IA en Azure&lt;/a&gt; que aclara esto, y quiero desglosarlo desde la perspectiva práctica de un desarrollador .NET.&lt;/p&gt;
&lt;h2 id="las-seis-opciones-de-un-vistazo"&gt;Las seis opciones de un vistazo&lt;/h2&gt;
&lt;p&gt;Así es como yo resumiría el panorama:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Opción&lt;/th&gt;
&lt;th&gt;Ideal para&lt;/th&gt;
&lt;th&gt;Tú gestionas&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Container Apps&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Control total de contenedores sin complejidad K8s&lt;/td&gt;
&lt;td&gt;Observabilidad, estado, ciclo de vida&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AKS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cumplimiento empresarial, multi-clúster, redes personalizadas&lt;/td&gt;
&lt;td&gt;Todo (ese es el punto)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Azure Functions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tareas de agentes cortas y dirigidas por eventos&lt;/td&gt;
&lt;td&gt;Casi nada — serverless puro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;App Service&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agentes HTTP simples, tráfico predecible&lt;/td&gt;
&lt;td&gt;Despliegue, configuración de escalado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foundry Agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agentes sin código vía portal/SDK&lt;/td&gt;
&lt;td&gt;Casi nada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foundry Hosted Agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agentes con framework personalizado e infra gestionada&lt;/td&gt;
&lt;td&gt;Solo tu código de agente&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Las primeras cuatro son computación de propósito general — &lt;em&gt;puedes&lt;/em&gt; ejecutar agentes en ellas, pero no fueron diseñadas para eso. Las dos últimas son nativas de agentes: entienden conversaciones, llamadas a herramientas y ciclos de vida de agentes como conceptos de primera clase.&lt;/p&gt;
&lt;h2 id="foundry-hosted-agents--el-punto-ideal-para-desarrolladores-net-de-agentes"&gt;Foundry Hosted Agents — el punto ideal para desarrolladores .NET de agentes&lt;/h2&gt;
&lt;p&gt;Esto es lo que me llamó la atención. Foundry Hosted Agents se sitúan justo en el medio: obtienes la flexibilidad de ejecutar tu propio código (Semantic Kernel, Agent Framework, LangGraph — lo que sea) pero la plataforma gestiona infraestructura, observabilidad y gestión de conversaciones.&lt;/p&gt;
&lt;p&gt;La pieza clave es el &lt;strong&gt;Hosting Adapter&lt;/strong&gt; — una capa de abstracción fina que conecta tu framework de agentes con la plataforma Foundry. Para Microsoft Agent Framework, se ve así:&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.agentserver.agentframework&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;from_agent_framework&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;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatAgent&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;chat_client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AzureAIAgentClient&lt;/span&gt;&lt;span class="p"&gt;(&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="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="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_local_time&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="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&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;from_agent_framework&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&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;Esa es toda tu historia de hosting. El adapter gestiona traducción de protocolos, streaming vía server-sent events, historial de conversación y trazado OpenTelemetry — todo automáticamente. Sin middleware personalizado, sin plomería manual.&lt;/p&gt;
&lt;h2 id="desplegar-es-genuinamente-simple"&gt;Desplegar es genuinamente simple&lt;/h2&gt;
&lt;p&gt;He desplegado agentes en Container Apps antes y funciona, pero terminas escribiendo mucho código de pegamento para gestión de estado y observabilidad. Con Hosted Agents y &lt;code&gt;azd&lt;/code&gt;, el despliegue es:&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;# Instalar la extensión de agente IA&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ext install azure.ai.agents
&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;# Inicializar desde una plantilla&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ai agent 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;# Construir, subir, desplegar — listo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ese único &lt;code&gt;azd up&lt;/code&gt; construye tu contenedor, lo sube a ACR, provisiona el proyecto Foundry, despliega endpoints de modelo e inicia tu agente. Cinco pasos colapsados en un solo comando.&lt;/p&gt;
&lt;h2 id="gestión-de-conversaciones-integrada"&gt;Gestión de conversaciones integrada&lt;/h2&gt;
&lt;p&gt;Esta es la parte que ahorra más tiempo en producción. En lugar de construir tu propio almacén de estado de conversación, Hosted Agents lo gestionan nativamente:&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="c1"&gt;# Crear una conversación persistente&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;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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Primer turno&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response1&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="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 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="s2"&gt;&amp;#34;MyAgent&amp;#34;&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="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Remember: my favorite number is 42.&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Segundo turno — el contexto se preserva&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response2&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="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 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="s2"&gt;&amp;#34;MyAgent&amp;#34;&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="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Multiply my favorite number by 10.&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;Sin Redis. Sin almacén de sesiones Cosmos DB. Sin middleware personalizado para serialización de mensajes. La plataforma simplemente lo gestiona.&lt;/p&gt;
&lt;h2 id="mi-framework-de-decisión"&gt;Mi framework de decisión&lt;/h2&gt;
&lt;p&gt;Después de revisar las seis opciones, aquí está mi modelo mental rápido:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;¿Necesitas cero infraestructura?&lt;/strong&gt; → Foundry Agents (portal/SDK, sin contenedores)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;¿Tienes código de agente personalizado pero quieres hosting gestionado?&lt;/strong&gt; → Foundry Hosted Agents&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;¿Necesitas tareas de agente cortas dirigidas por eventos?&lt;/strong&gt; → Azure Functions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;¿Necesitas máximo control de contenedores sin K8s?&lt;/strong&gt; → Container Apps&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;¿Necesitas cumplimiento estricto y multi-clúster?&lt;/strong&gt; → AKS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;¿Tienes un agente HTTP simple con tráfico predecible?&lt;/strong&gt; → App Service&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Para la mayoría de desarrolladores .NET que construyen con Semantic Kernel o Microsoft Agent Framework, Hosted Agents es probablemente el punto de partida correcto. Obtienes scale-to-zero, OpenTelemetry integrado, gestión de conversaciones y flexibilidad de framework — sin gestionar Kubernetes ni montar tu propia pila de observabilidad.&lt;/p&gt;
&lt;h2 id="para-terminar"&gt;Para terminar&lt;/h2&gt;
&lt;p&gt;El panorama de alojamiento de agentes en Azure está madurando rápido. Si estás empezando un nuevo proyecto de agente IA hoy, consideraría seriamente Foundry Hosted Agents antes de recurrir a Container Apps o AKS por costumbre. La infraestructura gestionada ahorra tiempo real, y el patrón de hosting adapter te permite mantener tu elección de framework.&lt;/p&gt;
&lt;p&gt;Echa un vistazo a la &lt;a href="https://devblogs.microsoft.com/all-things-azure/hostedagent/"&gt;guía completa de Microsoft&lt;/a&gt; y al &lt;a href="https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents"&gt;repositorio de ejemplos de Foundry&lt;/a&gt; para ejemplos funcionales.&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/posts/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/posts/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/posts/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>Aspire 13.2 incorpora MongoDB EF Core y Azure Data Lake — Dos integraciones que vale la pena probar</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/aspire-132-mongodb-efcore-data-lake/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/aspire-132-mongodb-efcore-data-lake/</guid><description>Aspire 13.2 añade integraciones de MongoDB Entity Framework Core y Azure Data Lake Storage con health checks y service discovery sin configuración. Así es como se ven en la práctica.</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/posts/emiliano-montesdeoca/aspire-132-mongodb-efcore-data-lake/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Aspire 13.2 acaba de llegar con &lt;a href="https://devblogs.microsoft.com/aspire/aspire-new-database-integrations/"&gt;dos nuevas integraciones de bases de datos&lt;/a&gt; que merecen tu atención: MongoDB Entity Framework Core y Azure Data Lake Storage. Si querías usar EF Core con MongoDB en una app de Aspire, o necesitabas conectar cargas de trabajo de data lake con service discovery, esta versión trae ambas cosas.&lt;/p&gt;
&lt;h2 id="mongodb-se-encuentra-con-ef-core-en-aspire"&gt;MongoDB se encuentra con EF Core en Aspire&lt;/h2&gt;
&lt;p&gt;Esta es la que más me entusiasma. Aspire ha soportado MongoDB desde hace tiempo, pero siempre fue con el driver directo — sin EF Core, sin &lt;code&gt;DbContext&lt;/code&gt;, sin consultas LINQ contra tus documentos. Ahora tienes la experiencia completa de EF Core con MongoDB, además de los health checks automáticos y el service discovery de Aspire.&lt;/p&gt;
&lt;p&gt;Configurarlo sigue el patrón típico de Aspire. En tu AppHost:&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;var&lt;/span&gt; &lt;span class="n"&gt;mongodb&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddMongoDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;mongodb&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;WithDataVolume&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;WithLifetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContainerLifetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Persistent&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;apiService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddProject&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ApiService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;api&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;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mongodb&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;Luego en tu proyecto consumidor, añade la integración de EF Core:&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 Aspire.MongoDB.EntityFrameworkCore
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Y registra tu &lt;code&gt;DbContext&lt;/code&gt;:&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;AddMongoDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;mongodb&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;mydb&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;A partir de ahí, es EF Core estándar. Define tus entidades, usa tu &lt;code&gt;DbContext&lt;/code&gt; como lo harías con cualquier otro proveedor. La integración se encarga del connection pooling, trazas de OpenTelemetry y health checks en segundo plano.&lt;/p&gt;
&lt;p&gt;Para desarrolladores .NET que han estado usando MongoDB con el driver directo y configurando connection strings manualmente, esto es una mejora de calidad de vida muy bienvenida. Obtienes la abstracción completa de EF Core sin perder el service discovery de Aspire.&lt;/p&gt;
&lt;h2 id="azure-data-lake-storage-se-une-a-la-fiesta"&gt;Azure Data Lake Storage se une a la fiesta&lt;/h2&gt;
&lt;p&gt;La segunda gran adición es una &lt;a href="https://aspire.dev/integrations/cloud/azure/azure-storage-datalake/"&gt;integración de Azure Data Lake Storage (ADLS)&lt;/a&gt;. Si estás construyendo pipelines de datos, procesos ETL o plataformas de analítica, ahora puedes conectar recursos de Data Lake de la misma forma que conectarías cualquier otra dependencia de Aspire.&lt;/p&gt;
&lt;p&gt;En el AppHost:&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;var&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddAzureStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;azure-storage&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dataLake&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDataLake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;data-lake&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileSystem&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDataLakeFileSystem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;data-lake-file-system&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;analyticsService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddProject&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AnalyticsService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;analytics&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;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataLake&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;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileSystem&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;En el proyecto consumidor:&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;AddAzureDataLakeServiceClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;data-lake&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;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddAzureDataLakeFileSystemClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;data-lake-file-system&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;Sin gestión manual de connection strings, sin buscar credenciales. Aspire aprovisiona los recursos y los inyecta. Para los que construimos apps .NET cloud-native que tocan tanto datos operacionales como cargas de trabajo analíticas, esto hace que el data lake se sienta como un ciudadano de primera clase en el modelo de Aspire.&lt;/p&gt;
&lt;h2 id="las-pequeñas-correcciones-que-importan"&gt;Las pequeñas correcciones que importan&lt;/h2&gt;
&lt;p&gt;Más allá de las funcionalidades principales, hay algunas mejoras de calidad de vida que vale la pena mencionar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Corrección del connection string de MongoDB&lt;/strong&gt; — la barra diagonal antes del nombre de la base de datos ahora se maneja correctamente. Si habías implementado un workaround, ya puedes eliminarlo&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exports de SQL Server&lt;/strong&gt; — &lt;code&gt;Aspire.Hosting.SqlServer&lt;/code&gt; ahora exporta opciones de configuración adicionales del servidor para un control más granular&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Actualizaciones de emuladores&lt;/strong&gt; — emulador de ServiceBus 2.0.0, emulador de App Configuration 1.0.2, y el emulador preview de CosmosDB ahora incluye una verificación de disponibilidad&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure Managed Redis&lt;/strong&gt; — ahora usa &lt;code&gt;rediss://&lt;/code&gt; (Redis Secure) por defecto, así que las conexiones están cifradas desde el inicio&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esa última es sutil pero importante — Redis cifrado por defecto significa una cosa menos que configurar en producción.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Aspire 13.2 es una versión incremental, pero las integraciones de MongoDB EF Core y Data Lake llenan vacíos reales. Si estabas esperando soporte adecuado de EF Core con MongoDB en Aspire, o necesitabas que Data Lake fuera una dependencia de primera clase, &lt;a href="https://get.aspire.dev"&gt;actualiza a 13.2&lt;/a&gt; y pruébalas. El comando &lt;code&gt;aspire add&lt;/code&gt; genera todo lo que necesitas.&lt;/p&gt;
&lt;p&gt;Lee las &lt;a href="https://aspire.dev/whats-new/aspire-13-2/#-integrations-updates"&gt;notas de la versión completas&lt;/a&gt; para más detalles, y consulta la &lt;a href="https://aspire.dev/integrations/gallery/"&gt;galería de integraciones&lt;/a&gt; para la lista completa.&lt;/p&gt;</content:encoded></item><item><title>azd update — Un solo comando para gobernar todos tus gestores de paquetes</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azd-update-universal-upgrade-command/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azd-update-universal-upgrade-command/</guid><description>Azure Developer CLI ahora tiene un comando de actualización universal que funciona sin importar cómo lo instalaste — winget, Homebrew, Chocolatey o script de instalació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/posts/emiliano-montesdeoca/azd-update-universal-upgrade-command/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;¿Conoces ese mensaje de &amp;ldquo;Hay una nueva versión de azd disponible&amp;rdquo; que aparece cada pocas semanas? ¿Ese que ignoras porque no recuerdas si instalaste &lt;code&gt;azd&lt;/code&gt; con winget, Homebrew o ese script de curl que ejecutaste hace seis meses? Bueno, eso por fin tiene solución.&lt;/p&gt;
&lt;p&gt;Microsoft acaba de lanzar &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-update/"&gt;&lt;code&gt;azd update&lt;/code&gt;&lt;/a&gt; — un único comando que actualiza Azure Developer CLI a la última versión sin importar cómo lo instalaste originalmente. Windows, macOS, Linux — da igual. Un solo comando.&lt;/p&gt;
&lt;h2 id="cómo-funciona"&gt;Cómo funciona&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;azd update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Eso es todo. Si quieres acceso anticipado a nuevas funcionalidades, puedes cambiar a la build diaria de insiders:&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;azd update --channel daily
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd update --channel stable
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El comando detecta tu método de instalación actual y usa el mecanismo de actualización apropiado internamente. Se acabó el &amp;ldquo;espera, ¿usé winget o choco en esta máquina?&amp;rdquo;&lt;/p&gt;
&lt;h2 id="el-pequeño-detalle"&gt;El pequeño detalle&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azd update&lt;/code&gt; viene a partir de la versión 1.23.x. Si estás en una versión anterior, necesitarás hacer una última actualización manual usando tu método de instalación original. Después de eso, &lt;code&gt;azd update&lt;/code&gt; se encarga de todo en adelante.&lt;/p&gt;
&lt;p&gt;Comprueba tu versión actual con &lt;code&gt;azd version&lt;/code&gt;. Si necesitas una instalación desde cero, la &lt;a href="https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd"&gt;documentación de instalación&lt;/a&gt; te cubre.&lt;/p&gt;
&lt;h2 id="por-qué-importa"&gt;Por qué importa&lt;/h2&gt;
&lt;p&gt;Es una pequeña mejora de calidad de vida, pero para los que usamos &lt;code&gt;azd&lt;/code&gt; a diario para desplegar agentes de IA y apps de Aspire en Azure, estar actualizado significa menos momentos de &amp;ldquo;ese bug ya estaba corregido en la última versión&amp;rdquo;. Una cosa menos en la que pensar.&lt;/p&gt;
&lt;p&gt;Lee el &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-update/"&gt;anuncio completo&lt;/a&gt; y el &lt;a href="https://blog.jongallant.com/2026/04/azd-update"&gt;análisis más detallado&lt;/a&gt; de Jon Gallant para más contexto.&lt;/p&gt;</content:encoded></item><item><title>Azure DevOps Server Parche Abril 2026 — Corrección en Completado de PRs y Actualizaciones de Seguridad</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-devops-server-april-2026-patch/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-devops-server-april-2026-patch/</guid><description>Azure DevOps Server recibe el Parche 3 con una corrección para fallos en el completado de PRs, validación mejorada en cierre de sesión y restauración de conexiones PAT con GitHub Enterprise Server.</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/posts/emiliano-montesdeoca/azure-devops-server-april-2026-patch/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Aviso rápido para equipos que ejecutan Azure DevOps Server en sus propios servidores: Microsoft lanzó el &lt;a href="https://devblogs.microsoft.com/devops/april-patches-for-azure-devops-server/"&gt;Parche 3 de abril 2026&lt;/a&gt; con tres correcciones específicas.&lt;/p&gt;
&lt;h2 id="qué-se-corrigió"&gt;Qué se corrigió&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fallos en el completado de pull requests&lt;/strong&gt; — una excepción de referencia nula durante el auto-completado de work items podía hacer que los merges de PRs fallaran. Si te topaste con errores aleatorios al completar PRs, esta es probablemente la causa&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validación en la redirección de cierre de sesión&lt;/strong&gt; — se mejoró la validación durante el cierre de sesión para prevenir posibles redirecciones maliciosas. Esta es una corrección de seguridad que vale la pena aplicar pronto&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conexiones PAT con GitHub Enterprise Server&lt;/strong&gt; — la creación de conexiones con Personal Access Token hacia GitHub Enterprise Server estaba rota, ahora se restauró&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cómo-actualizar"&gt;Cómo actualizar&lt;/h2&gt;
&lt;p&gt;Descarga el &lt;a href="https://aka.ms/devopsserverpatch3"&gt;Parche 3&lt;/a&gt; y ejecuta el instalador. Para verificar que el parche se aplicó:&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;&amp;lt;patch-installer&amp;gt;.exe CheckInstall
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si estás ejecutando Azure DevOps Server en tus propias instalaciones, Microsoft recomienda encarecidamente mantenerse en el último parche tanto por seguridad como por fiabilidad. Consulta las &lt;a href="https://learn.microsoft.com/azure/devops/server/release-notes/azuredevopsserver?view=azure-devops#azure-devops-server-patch-3-release-date-april-14-2026"&gt;notas de la versión&lt;/a&gt; para todos los detalles.&lt;/p&gt;</content:encoded></item><item><title>Azure Smart Tier ya está en GA — Optimización automática de costes en Blob Storage sin reglas de ciclo de vida</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-smart-tier-blob-storage-ga/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-smart-tier-blob-storage-ga/</guid><description>El smart tier de Azure Blob Storage ya está disponible de forma general, moviendo objetos automáticamente entre los niveles hot, cool y cold según los patrones reales de acceso — sin necesidad de reglas de ciclo de vida.</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/posts/emiliano-montesdeoca/azure-smart-tier-blob-storage-ga/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si alguna vez dedicaste tiempo a ajustar las políticas de ciclo de vida de Azure Blob Storage y luego las viste desmoronarse cuando cambiaron los patrones de acceso, esto te interesa. Microsoft acaba de anunciar la &lt;a href="https://azure.microsoft.com/en-us/blog/optimize-object-storage-costs-automatically-with-smart-tier-now-generally-available/"&gt;disponibilidad general de smart tier&lt;/a&gt; para Azure Blob y Data Lake Storage — una capacidad de tiering completamente administrada que mueve automáticamente los objetos entre los niveles hot, cool y cold según el uso real.&lt;/p&gt;
&lt;h2 id="qué-hace-realmente-smart-tier"&gt;Qué hace realmente smart tier&lt;/h2&gt;
&lt;p&gt;El concepto es sencillo: smart tier evalúa continuamente el último tiempo de acceso de cada objeto en tu cuenta de almacenamiento. Los datos accedidos frecuentemente se quedan en hot, los datos inactivos pasan a cool después de 30 días, y luego a cold tras otros 60 días. Cuando se accede de nuevo a los datos, se promueven de vuelta a hot inmediatamente. El ciclo se reinicia.&lt;/p&gt;
&lt;p&gt;Sin reglas de ciclo de vida que configurar. Sin predicciones de patrones de acceso. Sin ajustes manuales.&lt;/p&gt;
&lt;p&gt;Durante la preview, Microsoft reportó que &lt;strong&gt;más del 50% de la capacidad gestionada por smart tier se movió automáticamente a niveles más fríos&lt;/strong&gt; según los patrones reales de acceso. Es una reducción de costes significativa para cuentas de almacenamiento grandes.&lt;/p&gt;
&lt;h2 id="por-qué-esto-importa-para-los-desarrolladores-net"&gt;Por qué esto importa para los desarrolladores .NET&lt;/h2&gt;
&lt;p&gt;Si estás construyendo aplicaciones que generan logs, telemetría, datos analíticos, o cualquier tipo de patrimonio de datos creciente — y seamos honestos, ¿quién no? — los costes de almacenamiento se acumulan rápido. El enfoque tradicional era escribir políticas de gestión de ciclo de vida, probarlas, y luego reajustarlas cuando los patrones de acceso de tu aplicación cambiaban. Smart tier elimina todo ese flujo de trabajo.&lt;/p&gt;
&lt;p&gt;Algunos escenarios prácticos donde esto ayuda:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Telemetría y logs de aplicaciones&lt;/strong&gt; — hot cuando estás depurando, rara vez accedidos después de unas semanas&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipelines de datos y salidas de ETL&lt;/strong&gt; — accedidos intensamente durante el procesamiento, luego mayormente cold&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contenido generado por usuarios&lt;/strong&gt; — las subidas recientes están en hot, el contenido más antiguo se enfría gradualmente&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Datos de backup y archivo&lt;/strong&gt; — accedidos ocasionalmente por cumplimiento, mayormente inactivos&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cómo-configurarlo"&gt;Cómo configurarlo&lt;/h2&gt;
&lt;p&gt;Habilitar smart tier es una configuración de una sola vez:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cuentas nuevas&lt;/strong&gt;: Selecciona smart tier como el nivel de acceso predeterminado durante la creación de la cuenta de almacenamiento (se requiere redundancia zonal)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cuentas existentes&lt;/strong&gt;: Cambia el nivel de acceso de blob de tu configuración actual a smart tier&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Los objetos menores de 128 KiB se quedan en hot y no incurren en la tarifa de monitoreo. Para todo lo demás, pagas las tarifas estándar de capacidad hot/cool/cold sin cargos por transición de nivel, sin penalizaciones por eliminación temprana, y sin costes de recuperación de datos. Una tarifa mensual de monitoreo por objeto cubre la orquestación.&lt;/p&gt;
&lt;h2 id="el-compromiso-que-debes-conocer"&gt;El compromiso que debes conocer&lt;/h2&gt;
&lt;p&gt;Las reglas de tiering de smart tier son estáticas (30 días → cool, 90 días → cold). Si necesitas umbrales personalizados — digamos, mover a cool después de 7 días para una carga de trabajo específica — las reglas de ciclo de vida siguen siendo el camino a seguir. Y no mezcles ambos: evita usar reglas de ciclo de vida sobre objetos gestionados por smart tier, ya que pueden entrar en conflicto.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Esto no es revolucionario, pero resuelve un dolor de cabeza operacional real. Si gestionas cuentas de blob storage en crecimiento y estás cansado de mantener políticas de ciclo de vida, &lt;a href="https://learn.microsoft.com/en-us/azure/storage/blobs/access-tiers-smart"&gt;habilita smart tier&lt;/a&gt; y deja que Azure se encargue. Está disponible hoy en casi todas las regiones zonales de la nube pública.&lt;/p&gt;</content:encoded></item><item><title>Las Agent Skills en .NET se volvieron muy flexibles</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/agent-skills-dotnet-three-authoring-patterns/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/agent-skills-dotnet-three-authoring-patterns/</guid><description>El Microsoft Agent Framework ahora soporta tres formas de crear skills — archivos, clases y código inline — todas compuestas a través de un único provider. Aquí te cuento por qué importa y cómo usar cada una.</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/posts/emiliano-montesdeoca/agent-skills-dotnet-three-authoring-patterns/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si has estado construyendo agentes con el Microsoft Agent Framework, ya conoces la dinámica: defines skills, las conectas a un provider y dejas que el agente decida cuál invocar. Lo nuevo es &lt;em&gt;cómo&lt;/em&gt; creas esas skills — y el salto en flexibilidad es importante.&lt;/p&gt;
&lt;p&gt;La última actualización introduce tres patrones de autoría para agent skills: &lt;strong&gt;basadas en archivos&lt;/strong&gt;, &lt;strong&gt;basadas en clases&lt;/strong&gt; y &lt;strong&gt;definidas en código inline&lt;/strong&gt;. Las tres se conectan a un único &lt;code&gt;AgentSkillsProviderBuilder&lt;/code&gt;, lo que significa que puedes mezclar y combinar sin lógica de enrutamiento ni código especial. Te explico cada una y cuándo usarla.&lt;/p&gt;
&lt;h2 id="skills-basadas-en-archivos-el-punto-de-partida"&gt;Skills basadas en archivos: el punto de partida&lt;/h2&gt;
&lt;p&gt;Las skills basadas en archivos son exactamente lo que suenan — un directorio en disco con un archivo &lt;code&gt;SKILL.md&lt;/code&gt;, scripts opcionales y documentos de referencia. Es la forma más directa de darle nuevas capacidades a tu agente:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;skills/
└── onboarding-guide/
├── SKILL.md
├── scripts/
│ └── check-provisioning.py
└── references/
└── onboarding-checklist.md
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;El frontmatter del &lt;code&gt;SKILL.md&lt;/code&gt; declara el nombre y descripción, y la sección de instrucciones le dice al agente cómo usar los scripts y referencias:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&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;name: onboarding-guide
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;description: &amp;gt;-
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Walk new hires through their first-week setup checklist.
&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Instructions
&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;1.&lt;/span&gt; Ask for the employee&amp;#39;s name and start date.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;2.&lt;/span&gt; Run &lt;span class="sb"&gt;`scripts/check-provisioning.py`&lt;/span&gt; to verify accounts.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;3.&lt;/span&gt; Walk through &lt;span class="sb"&gt;`references/onboarding-checklist.md`&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;4.&lt;/span&gt; Follow up on incomplete items.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Luego lo conectas con &lt;code&gt;SubprocessScriptRunner.RunAsync&lt;/code&gt; para la ejecución de scripts:&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;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&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;AgentSkillsProvider&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;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&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;SubprocessScriptRunner&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&gt;&lt;/span&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 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="n"&gt;endpoint&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;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&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 class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ChatClientAgentOptions&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;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;HRAgent&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;ChatOptions&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="n"&gt;Instructions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;You are a helpful HR 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="n"&gt;AIContextProviders&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;skillsProvider&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;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;deploymentName&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;El agente descubre la skill automáticamente e invoca el script de provisión cuando necesita verificar el estado de las cuentas. Limpio y simple.&lt;/p&gt;
&lt;h2 id="skills-basadas-en-clases-distribuir-vía-nuget"&gt;Skills basadas en clases: distribuir vía NuGet&lt;/h2&gt;
&lt;p&gt;Aquí es donde se pone interesante para los equipos. Las skills basadas en clases derivan de &lt;code&gt;AgentClassSkill&amp;lt;T&amp;gt;&lt;/code&gt; y usan atributos como &lt;code&gt;[AgentSkillResource]&lt;/code&gt; y &lt;code&gt;[AgentSkillScript]&lt;/code&gt; para que el framework descubra todo por reflexión:&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="kd"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BenefitsEnrollmentSkill&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentClassSkill&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BenefitsEnrollmentSkill&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="kd"&gt;override&lt;/span&gt; &lt;span class="n"&gt;AgentSkillFrontmatter&lt;/span&gt; &lt;span class="n"&gt;Frontmatter&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 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="s"&gt;&amp;#34;benefits-enrollment&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="s"&gt;&amp;#34;Enroll an employee in health, dental, or vision plans.&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="kd"&gt;protected&lt;/span&gt; &lt;span class="kd"&gt;override&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Instructions&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;1.&lt;/span&gt; &lt;span class="n"&gt;Read&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plans&lt;/span&gt; &lt;span class="n"&gt;resource&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="m"&gt;2.&lt;/span&gt; &lt;span class="n"&gt;Confirm&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="n"&gt;wants&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="m"&gt;3.&lt;/span&gt; &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;enroll&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;complete&lt;/span&gt; &lt;span class="n"&gt;enrollment&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;&amp;#34;&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&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; [AgentSkillResource(&amp;#34;available-plans&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [Description(&amp;#34;Plan options with monthly pricing.&amp;#34;)]&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;AvailablePlans&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;##&lt;/span&gt; &lt;span class="n"&gt;Available&lt;/span&gt; &lt;span class="n"&gt;Plans&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2026&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;Health&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Basic&lt;/span&gt; &lt;span class="n"&gt;HMO&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Premium&lt;/span&gt; &lt;span class="n"&gt;PPO&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&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;Dental&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Standard&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Enhanced&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&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;Vision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Basic&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&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;&amp;#34;&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&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; [AgentSkillScript(&amp;#34;enroll&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [Description(&amp;#34;Enrolls employee in the specified benefit plan.&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Enroll&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;employeeId&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;planCode&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="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HrClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnrollInPlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;planCode&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;return&lt;/span&gt; &lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialize&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="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;planCode&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;Lo mejor es que un equipo puede empaquetar esto como un paquete NuGet. Lo agregas a tu proyecto, lo metes en el builder y funciona junto a tus skills basadas en archivos sin coordinación:&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;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&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;AgentSkillsProviderBuilder&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;UseFileSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&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;UseSkill&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;BenefitsEnrollmentSkill&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;UseFileScriptRunner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SubprocessScriptRunner&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="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Build&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;Ambas skills aparecen en el system prompt del agente. El agente decide cuál usar según la conversación — sin código de enrutamiento.&lt;/p&gt;
&lt;h2 id="skills-inline-el-puente-rápido"&gt;Skills inline: el puente rápido&lt;/h2&gt;
&lt;p&gt;¿Conoces ese momento cuando otro equipo está construyendo exactamente la skill que necesitas, pero no la tendrán lista hasta el próximo sprint? &lt;code&gt;AgentInlineSkill&lt;/code&gt; es tu puente:&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;var&lt;/span&gt; &lt;span class="n"&gt;timeOffSkill&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;AgentInlineSkill&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;time-off-balance&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;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Calculate remaining vacation and sick days.&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;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;1.&lt;/span&gt; &lt;span class="n"&gt;Ask&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;provided&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="m"&gt;2.&lt;/span&gt; &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="n"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="n"&gt;balance&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="m"&gt;3.&lt;/span&gt; &lt;span class="n"&gt;Present&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="n"&gt;clearly&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;&amp;#34;&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 class="n"&gt;AddScript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;calculate-balance&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&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;employeeId&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;leaveType&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;int&lt;/span&gt; &lt;span class="n"&gt;totalDays&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HrDatabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAnnualAllowance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leaveType&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;daysUsed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HrDatabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDaysUsed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leaveType&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;totalDays&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;daysUsed&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;return&lt;/span&gt; &lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialize&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="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leaveType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;totalDays&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;daysUsed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remaining&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;Agrégala al builder igual que las demás:&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;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&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;AgentSkillsProviderBuilder&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;UseFileSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&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;UseSkill&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;BenefitsEnrollmentSkill&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;UseSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeOffSkill&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;UseFileScriptRunner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SubprocessScriptRunner&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="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Build&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;Cuando el paquete NuGet finalmente salga, intercambias la skill inline por la basada en clases. El agente no nota la diferencia.&lt;/p&gt;
&lt;p&gt;Pero las skills inline no son solo para puentes. También son la opción correcta cuando necesitas generar skills dinámicamente en runtime — piensa en una skill por unidad de negocio cargada desde configuración — o cuando un script necesita capturar estado local que no pertenece a un contenedor DI.&lt;/p&gt;
&lt;h2 id="aprobación-de-scripts-humano-en-el-bucle"&gt;Aprobación de scripts: humano en el bucle&lt;/h2&gt;
&lt;p&gt;Para los que construimos agentes de producción en .NET, esta es la parte que realmente desbloquea las conversaciones de despliegue. Algunos scripts tienen consecuencias reales — inscribir a alguien en beneficios, consultar infraestructura de producción. Activa &lt;code&gt;UseScriptApproval&lt;/code&gt; y el agente se pausa antes de ejecutar cualquier script:&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;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&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;AgentSkillsProviderBuilder&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;UseFileSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&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;UseSkill&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;BenefitsEnrollmentSkill&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;UseSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeOffSkill&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;UseFileScriptRunner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SubprocessScriptRunner&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="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseScriptApproval&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="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Build&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;Cuando el agente quiere ejecutar un script, devuelve una solicitud de aprobación. Tu app recoge la decisión — aprobar o rechazar — y el agente continúa. En entornos regulados, esta es la diferencia entre &amp;ldquo;podemos desplegar esto&amp;rdquo; y &amp;ldquo;legal dice que no.&amp;rdquo;&lt;/p&gt;
&lt;h2 id="por-qué-esta-combinación-importa"&gt;Por qué esta combinación importa&lt;/h2&gt;
&lt;p&gt;El verdadero poder no está en ningún patrón individual — está en la composición. Puedes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Empezar pequeño&lt;/strong&gt; con una skill basada en archivos, iterar en las instrucciones y publicarla sin escribir C#&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Distribuir skills reutilizables&lt;/strong&gt; como paquetes NuGet que otros equipos pueden agregar con una línea&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cubrir huecos&lt;/strong&gt; con skills inline cuando necesitas algo &lt;em&gt;ya&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Filtrar directorios compartidos&lt;/strong&gt; con predicados para que tu agente solo cargue lo que debe&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agregar supervisión humana&lt;/strong&gt; para scripts que tocan sistemas de producción&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Todo esto se compone a través de &lt;code&gt;AgentSkillsProviderBuilder&lt;/code&gt;. Sin enrutamiento especial, sin lógica condicional, sin verificaciones de tipo de skill.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Las agent skills en .NET ahora tienen un modelo de autoría genuinamente flexible. Ya sea que seas un desarrollador solo prototipando con skills basadas en archivos o un equipo enterprise distribuyendo capacidades empaquetadas vía NuGet, los patrones encajan. Y el mecanismo de aprobación de scripts lo hace listo para producción en entornos donde necesitas ese checkpoint humano.&lt;/p&gt;
&lt;p&gt;Echa un vistazo al &lt;a href="https://devblogs.microsoft.com/agent-framework/agent-skills-in-net-three-ways-to-author-one-provider-to-run-them/"&gt;anuncio original&lt;/a&gt;, la &lt;a href="https://learn.microsoft.com/en-us/agent-framework/agents/skills"&gt;documentación de Agent Skills&lt;/a&gt; en Microsoft Learn y los &lt;a href="https://github.com/microsoft/agent-framework/tree/main/dotnet/samples/02-agents/AgentSkills"&gt;ejemplos en .NET en GitHub&lt;/a&gt; para ponerte manos a la obra.&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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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>Construyendo UIs Multi-Agente en Tiempo Real Que No Se Sientan Como una Caja Negra</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/ag-ui-real-time-multi-agent-ui-maf/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/ag-ui-real-time-multi-agent-ui-maf/</guid><description>AG-UI y Microsoft Agent Framework se unen para darle a los flujos multi-agente un frontend de verdad — con streaming en tiempo real, aprobaciones humanas y visibilidad total de lo que hacen tus agentes.</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/posts/emiliano-montesdeoca/ag-ui-real-time-multi-agent-ui-maf/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;La verdad sobre los sistemas multi-agente: se ven increíbles en las demos. Tres agentes pasándose trabajo, resolviendo problemas, tomando decisiones. Luego intentas ponerlo frente a usuarios reales y&amp;hellip; silencio. Un indicador girando. Sin idea de qué agente está haciendo qué ni por qué el sistema se pausó. Eso no es un producto — es un problema de confianza.&lt;/p&gt;
&lt;p&gt;El equipo de Microsoft Agent Framework acaba de publicar un &lt;a href="https://devblogs.microsoft.com/agent-framework/ag-ui-multi-agent-workflow-demo/"&gt;fantástico tutorial&lt;/a&gt; sobre cómo combinar flujos MAF con &lt;a href="https://github.com/ag-ui-protocol/ag-ui"&gt;AG-UI&lt;/a&gt;, un protocolo abierto para transmitir eventos de ejecución de agentes a un frontend mediante Server-Sent Events. Y sinceramente, este es el puente que nos hacía falta.&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 apps potenciadas por IA, probablemente ya te topaste con esta pared. Tu orquestación backend funciona perfecto — los agentes se pasan tareas, las herramientas se ejecutan, las decisiones se toman. Pero el frontend no tiene ni idea de lo que pasa detrás de escena. AG-UI resuelve esto definiendo un protocolo estándar para transmitir eventos de agentes (piensa en &lt;code&gt;RUN_STARTED&lt;/code&gt;, &lt;code&gt;STEP_STARTED&lt;/code&gt;, &lt;code&gt;TOOL_CALL_*&lt;/code&gt;, &lt;code&gt;TEXT_MESSAGE_*&lt;/code&gt;) directamente a tu capa de UI por SSE.&lt;/p&gt;
&lt;p&gt;La demo que construyeron es un flujo de soporte al cliente con tres agentes: un agente de triaje que enruta solicitudes, un agente de reembolsos que maneja temas de dinero, y un agente de pedidos que gestiona reemplazos. Cada agente tiene sus propias herramientas, y la topología de handoff está definida explícitamente — nada de &amp;ldquo;descúbrelo desde el prompt&amp;rdquo;.&lt;/p&gt;
&lt;h2 id="la-topología-de-handoff-es-la-verdadera-estrella"&gt;La topología de handoff es la verdadera estrella&lt;/h2&gt;
&lt;p&gt;Lo que me llamó la atención es cómo &lt;code&gt;HandoffBuilder&lt;/code&gt; te permite declarar un grafo dirigido de enrutamiento entre agentes:&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;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HandoffBuilder&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;ag_ui_handoff_workflow_demo&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;participants&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&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;termination_condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;termination_condition&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="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;builder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Refunds, damaged-item claims...&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Replacement, exchange...&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Replacement logistics needed after refund.&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;After replacement/shipping tasks complete.&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;Cada &lt;code&gt;add_handoff&lt;/code&gt; crea una arista dirigida con una descripción en lenguaje natural. El framework genera herramientas de handoff para cada agente basándose en esta topología. Así que las decisiones de enrutamiento están fundamentadas en tu estructura de orquestación, no solo en lo que al LLM se le ocurra hacer. Eso es un cambio enorme para la confiabilidad en producción.&lt;/p&gt;
&lt;h2 id="human-in-the-loop-que-realmente-funciona"&gt;Human-in-the-loop que realmente funciona&lt;/h2&gt;
&lt;p&gt;La demo muestra dos patrones de interrupción que cualquier app de agentes del mundo real necesita:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interrupciones de aprobación de herramientas&lt;/strong&gt; — cuando un agente llama a una herramienta marcada con &lt;code&gt;approval_mode=&amp;quot;always_require&amp;quot;&lt;/code&gt;, el flujo se pausa y emite un evento. El frontend renderiza un modal de aprobación con el nombre de la herramienta y sus argumentos. Sin bucles de reintento que quemen tokens — solo un flujo limpio de pausa-aprobación-reanudación.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interrupciones de solicitud de información&lt;/strong&gt; — cuando un agente necesita más contexto del usuario (como un ID de pedido), se pausa y pregunta. El frontend muestra la pregunta, el usuario responde, y la ejecución se reanuda exactamente donde se detuvo.&lt;/p&gt;
&lt;p&gt;Ambos patrones se transmiten como eventos estándar de AG-UI, así que tu frontend no necesita lógica personalizada por agente — simplemente renderiza cualquier evento que llegue por la conexión SSE.&lt;/p&gt;
&lt;h2 id="conectarlo-todo-es-sorprendentemente-simple"&gt;Conectarlo todo es sorprendentemente simple&lt;/h2&gt;
&lt;p&gt;La integración entre MAF y AG-UI se reduce a una sola llamada de función:&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;agent_framework.ag_ui&lt;/span&gt; &lt;span class="kn"&gt;import&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;AgentFrameworkWorkflow&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;add_agent_framework_fastapi_endpoint&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FastAPI&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;demo_workflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AgentFrameworkWorkflow&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;workflow_factory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;_thread_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;create_handoff_workflow&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;ag_ui_handoff_workflow_demo&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;add_agent_framework_fastapi_endpoint&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="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;app&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;demo_workflow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/handoff_demo&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;El &lt;code&gt;workflow_factory&lt;/code&gt; crea un flujo nuevo por hilo, así cada conversación obtiene estado aislado. El endpoint maneja toda la plomería SSE automáticamente. Si ya estás usando FastAPI (o puedes añadirlo como una capa ligera), esto tiene prácticamente cero fricción.&lt;/p&gt;
&lt;h2 id="mi-opinión"&gt;Mi opinión&lt;/h2&gt;
&lt;p&gt;Para nosotros los desarrolladores .NET, la pregunta inmediata es: &amp;ldquo;¿Puedo hacer esto en C#?&amp;rdquo; El Agent Framework está disponible tanto para .NET como para Python, y el protocolo AG-UI es agnóstico de lenguaje (solo es SSE). Así que aunque esta demo específica usa Python y FastAPI, el patrón se traduce directamente. Podrías montar una API mínima de ASP.NET Core con endpoints SSE siguiendo el mismo esquema de eventos de AG-UI.&lt;/p&gt;
&lt;p&gt;La conclusión más importante es que las UIs multi-agente se están convirtiendo en una preocupación de primera clase, no algo que se deja para después. Si estás construyendo cualquier cosa donde los agentes interactúan con humanos — soporte al cliente, flujos de aprobación, procesamiento de documentos — esta combinación de orquestación MAF y transparencia AG-UI es el patrón a seguir.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;AG-UI + Microsoft Agent Framework te da lo mejor de ambos mundos: orquestación multi-agente robusta en el backend y visibilidad en tiempo real en el frontend. No más interacciones de agentes como cajas negras.&lt;/p&gt;
&lt;p&gt;Revisa el &lt;a href="https://devblogs.microsoft.com/agent-framework/ag-ui-multi-agent-workflow-demo/"&gt;tutorial completo&lt;/a&gt; y el &lt;a href="https://github.com/ag-ui-protocol/ag-ui"&gt;repositorio del protocolo AG-UI&lt;/a&gt; para profundizar más.&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/posts/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/posts/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/posts/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>Esa Configuración de Ventanas Flotantes de Visual Studio Que No Conocías (Pero Deberías)</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/visual-studio-floating-windows-powertoys/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/visual-studio-floating-windows-powertoys/</guid><description>Una configuración oculta de Visual Studio te da control total sobre las ventanas flotantes — entradas independientes en la barra de tareas, comportamiento adecuado con múltiples monitores e integración perfecta con FancyZones. Un desplegable lo cambia 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/posts/emiliano-montesdeoca/visual-studio-floating-windows-powertoys/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si usas múltiples monitores con Visual Studio (y honestamente, ¿quién no lo hace hoy en día?), probablemente hayas experimentado la molestia: las ventanas flotantes de herramientas desaparecen cuando minimizas el IDE principal, siempre se quedan encima de todo lo demás, y no aparecen como botones separados en la barra de tareas. Funciona para algunos flujos de trabajo, pero para configuraciones con múltiples monitores es frustrante.&lt;/p&gt;
&lt;p&gt;Mads Kristensen del equipo de Visual Studio &lt;a href="https://devblogs.microsoft.com/visualstudio/take-full-control-of-your-floating-windows-in-visual-studio/"&gt;compartió una configuración poco conocida&lt;/a&gt; que cambia completamente cómo se comportan las ventanas flotantes. Un desplegable. Eso es todo.&lt;/p&gt;
&lt;h2 id="la-configuración"&gt;La configuración&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Tools &amp;gt; Options &amp;gt; Environment &amp;gt; Windows &amp;gt; Floating Windows&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;El desplegable &amp;ldquo;These floating windows are owned by the main window&amp;rdquo; tiene tres opciones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;None&lt;/strong&gt; — independencia total. Cada ventana flotante tiene su propia entrada en la barra de tareas y se comporta como una ventana normal de Windows.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool Windows&lt;/strong&gt; (predeterminado) — los documentos flotan libremente, las ventanas de herramientas quedan vinculadas al IDE.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Documents and Tool Windows&lt;/strong&gt; — comportamiento clásico de Visual Studio, todo vinculado a la ventana principal.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="por-qué-none-es-la-mejor-opción-para-configuraciones-con-múltiples-monitores"&gt;Por qué &amp;ldquo;None&amp;rdquo; es la mejor opción para configuraciones con múltiples monitores&lt;/h2&gt;
&lt;p&gt;Configúralo en &lt;strong&gt;None&lt;/strong&gt; y de repente todas tus ventanas flotantes de herramientas y documentos se comportan como aplicaciones reales de Windows. Aparecen en la barra de tareas, permanecen visibles cuando minimizas la ventana principal de Visual Studio, y dejan de forzarse al frente de todo.&lt;/p&gt;
&lt;p&gt;Combina esto con &lt;strong&gt;PowerToys FancyZones&lt;/strong&gt; y es un cambio total. Crea diseños personalizados a través de tus monitores, coloca tu Explorador de Soluciones en una zona, el depurador en otra, y los archivos de código donde quieras. Todo se mantiene en su lugar, todo es accesible de forma independiente, y tu espacio de trabajo se siente organizado en lugar de caótico.&lt;/p&gt;
&lt;h2 id="recomendaciones-rápidas"&gt;Recomendaciones rápidas&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Usuarios avanzados con múltiples monitores&lt;/strong&gt;: Configura en &lt;strong&gt;None&lt;/strong&gt;, combina con FancyZones&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flotadores ocasionales&lt;/strong&gt;: &lt;strong&gt;Tool Windows&lt;/strong&gt; (predeterminado) es un buen punto medio&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flujo de trabajo tradicional&lt;/strong&gt;: &lt;strong&gt;Documents and Tool Windows&lt;/strong&gt; mantiene todo clásico&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Consejo pro: &lt;strong&gt;Ctrl + doble clic&lt;/strong&gt; en la barra de título de cualquier ventana de herramientas para flotarla o anclarla instantáneamente. No se necesita reiniciar después de cambiar la configuración.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Es una de esas configuraciones de &amp;ldquo;no puedo creer que no lo sabía&amp;rdquo;. Si las ventanas flotantes en Visual Studio alguna vez te han molestado, ve a cambiar esto ahora mismo.&lt;/p&gt;
&lt;p&gt;Lee el &lt;a href="https://devblogs.microsoft.com/visualstudio/take-full-control-of-your-floating-windows-in-visual-studio/"&gt;post completo&lt;/a&gt; para los detalles y capturas de pantalla.&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/posts/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/posts/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/posts/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>La Ingeniería de Plataformas Agéntica Se Está Haciendo Real — Git-APE Muestra Cómo</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/agentic-platform-engineering-git-ape/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/agentic-platform-engineering-git-ape/</guid><description>El proyecto Git-APE de Microsoft pone en práctica la ingeniería de plataformas agéntica — usando agentes de GitHub Copilot y Azure MCP para convertir solicitudes en lenguaje natural en infraestructura cloud validada.</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/posts/emiliano-montesdeoca/agentic-platform-engineering-git-ape/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;La ingeniería de plataformas ha sido uno de esos términos que suena genial en conferencias pero que normalmente significa &amp;ldquo;construimos un portal interno y un wrapper de Terraform.&amp;rdquo; La verdadera promesa — infraestructura self-service que realmente sea segura, gobernada y rápida — siempre ha estado a unos pasos de distancia.&lt;/p&gt;
&lt;p&gt;El equipo de Azure acaba de publicar la &lt;a href="https://devblogs.microsoft.com/all-things-azure/putting-agentic-platform-engineering-to-the-test/"&gt;Parte 2 de su serie sobre ingeniería de plataformas agéntica&lt;/a&gt;, y esta es sobre la implementación práctica. Lo llaman &lt;strong&gt;Git-APE&lt;/strong&gt; (sí, el acrónimo es intencional), y es un proyecto open source que usa agentes de GitHub Copilot más servidores Azure MCP para convertir solicitudes en lenguaje natural en infraestructura validada y desplegada.&lt;/p&gt;
&lt;h2 id="qué-hace-git-ape-realmente"&gt;Qué hace Git-APE realmente&lt;/h2&gt;
&lt;p&gt;La idea central: en vez de que los desarrolladores aprendan módulos de Terraform, naveguen por UIs de portales o abran tickets al equipo de plataforma, hablan con un agente de Copilot. El agente interpreta la intención, genera Infrastructure-as-Code, la valida contra políticas y despliega — todo dentro de VS Code.&lt;/p&gt;
&lt;p&gt;Aquí está la configuració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;git clone https://github.com/Azure/git-ape
&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; git-ape
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Abre el workspace en VS Code, y los archivos de configuración del agente son descubiertos automáticamente por GitHub Copilot. Interactúas con el agente directamente:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;@git-ape deploy a function app with storage in West Europe
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;El agente usa Azure MCP Server internamente para interactuar con los servicios de Azure. La configuración de MCP en las opciones de VS Code habilita capacidades específicas:&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;azureMcp.serverMode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;namespace&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;azureMcp.enabledServices&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;deploy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;bestpractices&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;group&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;subscription&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;functionapp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;storage&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;sql&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;monitor&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 class="nt"&gt;&amp;#34;azureMcp.readOnly&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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="por-qué-esto-importa"&gt;Por qué esto importa&lt;/h2&gt;
&lt;p&gt;Para los que construimos en Azure, esto cambia la conversación de ingeniería de plataformas de &amp;ldquo;cómo construimos un portal&amp;rdquo; a &amp;ldquo;cómo describimos nuestras barreras de seguridad como APIs.&amp;rdquo; Cuando la interfaz de tu plataforma es un agente de IA, la calidad de tus restricciones y políticas se convierte en el producto.&lt;/p&gt;
&lt;p&gt;El blog de la Parte 1 planteó la teoría: APIs bien descritas, esquemas de control y barreras explícitas hacen las plataformas agent-ready. La Parte 2 lo demuestra funcionando con herramientas reales. El agente no genera recursos ciegamente — valida contra mejores prácticas, respeta convenciones de nomenclatura y aplica las políticas de tu organización.&lt;/p&gt;
&lt;p&gt;La limpieza es igual de sencilla:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;@git-ape destroy my-resource-group
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="mi-opinión"&gt;Mi opinión&lt;/h2&gt;
&lt;p&gt;Seré honesto — esta es más sobre el patrón que sobre la herramienta específica. Git-APE en sí es una demo/arquitectura de referencia. Pero la idea subyacente — agentes como la interfaz de tu plataforma, MCP como protocolo, GitHub Copilot como host — es hacia donde se dirige la experiencia del desarrollador empresarial.&lt;/p&gt;
&lt;p&gt;Si eres un equipo de plataforma buscando cómo hacer tu herramienta interna amigable para agentes, no hay mejor punto de partida. Y si eres un desarrollador .NET preguntándote cómo se conecta esto con tu mundo: el Azure MCP Server y los agentes de GitHub Copilot funcionan con cualquier carga de trabajo de Azure. Tu API ASP.NET Core, tu stack .NET Aspire, tus microservicios contenerizados — todo puede ser el objetivo de un flujo de despliegue agéntico.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Git-APE es una mirada temprana pero concreta a la ingeniería de plataformas agéntica en la práctica. Clona el &lt;a href="https://github.com/Azure/git-ape"&gt;repo&lt;/a&gt;, prueba la demo y empieza a pensar en cómo las APIs y políticas de tu plataforma necesitarían verse para que un agente las use de forma segura.&lt;/p&gt;
&lt;p&gt;Lee el &lt;a href="https://devblogs.microsoft.com/all-things-azure/putting-agentic-platform-engineering-to-the-test/"&gt;post completo&lt;/a&gt; para el walkthrough y videos de demostración.&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/posts/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/posts/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/posts/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>Microsoft Foundry Marzo 2026 — GPT-5.4, Agent Service GA y la Renovación del SDK Que lo Cambia Todo</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/microsoft-foundry-march-2026-whats-new/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/microsoft-foundry-march-2026-whats-new/</guid><description>La actualización de marzo 2026 de Microsoft Foundry es enorme: Agent Service llega a GA, GPT-5.4 trae razonamiento confiable, el SDK azure-ai-projects se estabiliza en todos los lenguajes, y Fireworks AI trae modelos abiertos a Azure.</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/posts/emiliano-montesdeoca/microsoft-foundry-march-2026-whats-new/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Los posts mensuales de &amp;ldquo;Novedades en Microsoft Foundry&amp;rdquo; suelen ser una mezcla de mejoras incrementales y alguna que otra característica destacada. ¿La &lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-microsoft-foundry-mar-2026/"&gt;edición de marzo 2026&lt;/a&gt;? Básicamente son todas características destacadas. Foundry Agent Service llega a GA, GPT-5.4 se lanza para producción, el SDK recibe una versión estable importante, y Fireworks AI trae inferencia de modelos abiertos a Azure. Vamos a desglosar lo que importa para los desarrolladores .NET.&lt;/p&gt;
&lt;h2 id="foundry-agent-service-está-listo-para-producción"&gt;Foundry Agent Service está listo para producción&lt;/h2&gt;
&lt;p&gt;Esta es la grande. El runtime de agentes de nueva generación está disponible de forma general — construido sobre la API de Responses de OpenAI, compatible a nivel de protocolo con los agentes de OpenAI, y abierto a modelos de múltiples proveedores. Si estás construyendo con la API de Responses hoy, migrar a Foundry añade seguridad empresarial, redes privadas, RBAC de Entra, trazabilidad completa y evaluación sobre tu lógica de agentes existente.&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="n"&gt;project_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&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;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;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&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;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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Adiciones clave: redes privadas de extremo a extremo, expansión de autenticación MCP (incluyendo passthrough de OAuth), vista previa de Voice Live para agentes de voz a voz, y agentes alojados en 6 nuevas regiones.&lt;/p&gt;
&lt;h2 id="gpt-54--confiabilidad-sobre-inteligencia-pura"&gt;GPT-5.4 — confiabilidad sobre inteligencia pura&lt;/h2&gt;
&lt;p&gt;GPT-5.4 no se trata de ser más inteligente. Se trata de ser más confiable. Razonamiento más sólido en interacciones largas, mejor adherencia a instrucciones, menos fallos en medio de flujos de trabajo, y capacidades integradas de uso de computadora. Para agentes en producción, esa confiabilidad importa mucho más que las puntuaciones en benchmarks.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Modelo&lt;/th&gt;
&lt;th&gt;Precio (por M tokens)&lt;/th&gt;
&lt;th&gt;Ideal Para&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 (≤272K)&lt;/td&gt;
&lt;td&gt;$2.50 / $15 salida&lt;/td&gt;
&lt;td&gt;Agentes en producción, código, flujos de documentos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 Pro&lt;/td&gt;
&lt;td&gt;$30 / $180 salida&lt;/td&gt;
&lt;td&gt;Análisis profundo, razonamiento científico&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 Mini&lt;/td&gt;
&lt;td&gt;Económico&lt;/td&gt;
&lt;td&gt;Clasificación, extracción, llamadas ligeras a herramientas&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;La jugada inteligente es una estrategia de enrutamiento: GPT-5.4 Mini maneja el trabajo de alto volumen y baja latencia mientras GPT-5.4 se encarga de las solicitudes con razonamiento pesado.&lt;/p&gt;
&lt;h2 id="el-sdk-finalmente-es-estable"&gt;El SDK finalmente es estable&lt;/h2&gt;
&lt;p&gt;El SDK &lt;code&gt;azure-ai-projects&lt;/code&gt; lanzó versiones estables en todos los lenguajes — Python 2.0.0, JS/TS 2.0.0, Java 2.0.0 y .NET 2.0.0 (1 de abril). La dependencia de &lt;code&gt;azure-ai-agents&lt;/code&gt; desapareció — todo vive bajo &lt;code&gt;AIProjectClient&lt;/code&gt;. Instala con &lt;code&gt;pip install azure-ai-projects&lt;/code&gt; y el paquete incluye &lt;code&gt;openai&lt;/code&gt; y &lt;code&gt;azure-identity&lt;/code&gt; como dependencias directas.&lt;/p&gt;
&lt;p&gt;Para los desarrolladores .NET, esto significa un único paquete NuGet para toda la superficie de Foundry. No más malabarismo con SDKs de agentes separados.&lt;/p&gt;
&lt;h2 id="fireworks-ai-trae-modelos-abiertos-a-azure"&gt;Fireworks AI trae modelos abiertos a Azure&lt;/h2&gt;
&lt;p&gt;Quizás la adición más interesante arquitectónicamente: Fireworks AI procesando más de 13 billones de tokens diarios a ~180K solicitudes/segundo, ahora disponible a través de Foundry. DeepSeek V3.2, gpt-oss-120b, Kimi K2.5 y MiniMax M2.5 en el lanzamiento.&lt;/p&gt;
&lt;p&gt;La verdadera historia es &lt;strong&gt;trae-tus-propios-pesos&lt;/strong&gt; — sube pesos cuantizados o ajustados desde cualquier lugar sin cambiar la pila de servicio. Despliega mediante pago por token sin servidor o throughput provisionado.&lt;/p&gt;
&lt;h2 id="otros-destacados"&gt;Otros destacados&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Phi-4 Reasoning Vision 15B&lt;/strong&gt; — razonamiento multimodal para gráficos, diagramas y diseños de documentos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evaluaciones GA&lt;/strong&gt; — evaluadores listos para usar con monitoreo continuo de producción canalizado a Azure Monitor&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Procesamiento Prioritario&lt;/strong&gt; (Preview) — carril de cómputo dedicado para cargas de trabajo sensibles a la latencia&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voice Live&lt;/strong&gt; — runtime de voz a voz que se conecta directamente a los agentes de Foundry&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tracing GA&lt;/strong&gt; — inspección de trazas de agentes de extremo a extremo con ordenamiento y filtrado&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deprecación de PromptFlow&lt;/strong&gt; — migración a Microsoft Framework Workflows para enero de 2027&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Marzo 2026 es un punto de inflexión para Foundry. Agent Service GA, SDKs estables en todos los lenguajes, GPT-5.4 para agentes de producción confiables, e inferencia de modelos abiertos vía Fireworks AI — la plataforma está lista para cargas de trabajo serias.&lt;/p&gt;
&lt;p&gt;Lee el &lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-microsoft-foundry-mar-2026/"&gt;resumen completo&lt;/a&gt; y &lt;a href="https://learn.microsoft.com/azure/foundry/quickstarts/get-started-code"&gt;construye tu primer agente&lt;/a&gt; para empezar.&lt;/p&gt;</content:encoded></item><item><title>SQL MCP Server — La forma correcta de darle acceso a bases de datos a los agentes de IA</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/sql-mcp-server-data-api-builder/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/sql-mcp-server-data-api-builder/</guid><description>SQL MCP Server de Data API builder da a los agentes de IA acceso seguro y determinista a bases de datos sin exponer esquemas ni depender de NL2SQL. RBAC, caché, soporte multi-base de datos — todo incluido.</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/posts/emiliano-montesdeoca/sql-mcp-server-data-api-builder/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Seamos honestos: la mayoría de los servidores MCP de bases de datos disponibles hoy son aterradores. Toman una consulta en lenguaje natural, generan SQL al vuelo y lo ejecutan contra tus datos de producción. ¿Qué podría salir mal? (Todo. Todo podría salir mal.)&lt;/p&gt;
&lt;p&gt;El equipo de Azure SQL acaba de &lt;a href="https://devblogs.microsoft.com/azure-sql/introducing-sql-mcp-server/"&gt;presentar SQL MCP Server&lt;/a&gt;, y toma un enfoque fundamentalmente diferente. Construido como una característica de Data API builder (DAB) 2.0, da a los agentes de IA acceso estructurado y determinista a operaciones de base de datos — sin NL2SQL, sin exponer tu esquema, y con RBAC completo en cada paso.&lt;/p&gt;
&lt;h2 id="por-qué-no-nl2sql"&gt;¿Por qué no NL2SQL?&lt;/h2&gt;
&lt;p&gt;Esta es la decisión de diseño más interesante. Los modelos no son deterministas, y las consultas complejas son las más propensas a producir errores sutiles. Las consultas exactas que los usuarios esperan que la IA genere son también las que necesitan más escrutinio cuando se producen de forma no determinista.&lt;/p&gt;
&lt;p&gt;En su lugar, SQL MCP Server usa un enfoque &lt;strong&gt;NL2DAB&lt;/strong&gt;. El agente trabaja con la capa de abstracción de entidades de Data API builder y su constructor de consultas integrado para producir T-SQL preciso y bien formado de manera determinista. Mismo resultado para el usuario, pero sin el riesgo de JOINs alucinados o exposición accidental de datos.&lt;/p&gt;
&lt;h2 id="siete-herramientas-no-setecientas"&gt;Siete herramientas, no setecientas&lt;/h2&gt;
&lt;p&gt;SQL MCP Server expone exactamente siete herramientas DML, sin importar el tamaño de la base de datos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;describe_entities&lt;/code&gt; — descubrir entidades y operaciones disponibles&lt;/li&gt;
&lt;li&gt;&lt;code&gt;create_record&lt;/code&gt; — insertar filas&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read_records&lt;/code&gt; — consultar tablas y vistas&lt;/li&gt;
&lt;li&gt;&lt;code&gt;update_record&lt;/code&gt; — modificar filas&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delete_record&lt;/code&gt; — eliminar filas&lt;/li&gt;
&lt;li&gt;&lt;code&gt;execute_entity&lt;/code&gt; — ejecutar procedimientos almacenados&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aggregate_records&lt;/code&gt; — consultas de agregación&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto es inteligente porque las ventanas de contexto son el espacio de pensamiento del agente. Inundarlas con cientos de definiciones de herramientas deja menos espacio para el razonamiento. Siete herramientas fijas mantienen al agente enfocado en &lt;em&gt;pensar&lt;/em&gt; en lugar de &lt;em&gt;navegar&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Cada herramienta puede habilitarse o deshabilitarse individualmente:&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="s2"&gt;&amp;#34;runtime&amp;#34;&lt;/span&gt;&lt;span class="err"&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;mcp&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;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;path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/mcp&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;dml-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;describe-entities&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;create-record&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;read-records&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;update-record&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;delete-record&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;execute-entity&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;aggregate-records&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;h2 id="empezando-en-tres-comandos"&gt;Empezando en tres comandos&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;dab init &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --database-type mssql &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --connection-string &lt;span class="s2"&gt;&amp;#34;@env(&amp;#39;sql_connection_string&amp;#39;)&amp;#34;&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;dab add Customers &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --source dbo.Customers &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --permissions &lt;span class="s2"&gt;&amp;#34;anonymous:*&amp;#34;&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;dab start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Eso es un SQL MCP Server funcionando y exponiendo tu tabla Customers. La capa de abstracción de entidades significa que puedes crear alias para nombres y columnas, limitar campos por rol, y controlar exactamente lo que ven los agentes — sin exponer detalles internos del esquema.&lt;/p&gt;
&lt;h2 id="la-historia-de-seguridad-es-sólida"&gt;La historia de seguridad es sólida&lt;/h2&gt;
&lt;p&gt;Aquí es donde la madurez de Data API builder da frutos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RBAC en cada capa&lt;/strong&gt; — cada entidad define qué roles pueden leer, crear, actualizar o eliminar, y qué campos son visibles&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integración con Azure Key Vault&lt;/strong&gt; — cadenas de conexión y secretos gestionados de forma segura&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft Entra + OAuth personalizado&lt;/strong&gt; — autenticación de nivel producción&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Content Security Policy&lt;/strong&gt; — los agentes interactúan a través de un contrato controlado, no SQL crudo&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La abstracción del esquema es particularmente importante. Los nombres internos de tus tablas y columnas nunca se exponen al agente. Defines entidades, alias y descripciones que tienen sentido para la interacción con IA — no tu diagrama ERD de la base de datos.&lt;/p&gt;
&lt;h2 id="multi-base-de-datos-y-multi-protocolo"&gt;Multi-base de datos y multi-protocolo&lt;/h2&gt;
&lt;p&gt;SQL MCP Server soporta Microsoft SQL, PostgreSQL, Azure Cosmos DB y MySQL. Y como es una característica de DAB, obtienes endpoints REST, GraphQL y MCP simultáneamente desde la misma configuración. Mismas definiciones de entidades, mismas reglas RBAC, misma seguridad — en los tres protocolos.&lt;/p&gt;
&lt;p&gt;La auto-configuración en DAB 2.0 puede incluso inspeccionar tu base de datos y construir la configuración dinámicamente, si te resulta cómodo menos abstracción para prototipado rápido.&lt;/p&gt;
&lt;h2 id="mi-opinión"&gt;Mi opinión&lt;/h2&gt;
&lt;p&gt;Así es como debería funcionar el acceso empresarial a bases de datos para agentes de IA. No &amp;ldquo;hey LLM, escríbeme algo de SQL y YOLO contra producción.&amp;rdquo; En su lugar: una capa de entidades bien definida, generación determinista de consultas, RBAC en cada paso, caché, monitoreo y telemetría. Es aburrido de la mejor manera posible.&lt;/p&gt;
&lt;p&gt;Para desarrolladores .NET, la historia de integración es limpia — DAB es una herramienta .NET, el MCP Server se ejecuta como contenedor, y funciona con Azure SQL, que la mayoría ya estamos usando. Si estás construyendo agentes de IA que necesitan acceso a datos, empieza aquí.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;SQL MCP Server es gratuito, de código abierto y se ejecuta en cualquier lugar. Es el enfoque prescriptivo de Microsoft para dar acceso seguro a bases de datos a los agentes de IA. Consulta el &lt;a href="https://devblogs.microsoft.com/azure-sql/introducing-sql-mcp-server/"&gt;post completo&lt;/a&gt; y la &lt;a href="https://aka.ms/sql/mcp"&gt;documentación&lt;/a&gt; para empezar.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.116 — La App de Agentes Obtiene Navegación por Teclado y Autocompletado de Contexto de Archivos</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/vscode-1-116-agents-app-updates/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/vscode-1-116-agents-app-updates/</guid><description>VS Code 1.116 se enfoca en pulir la app de Agentes — atajos de teclado dedicados, mejoras de accesibilidad, autocompletado de contexto de archivos y resolución de enlaces CSS @import.</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/posts/emiliano-montesdeoca/vscode-1-116-agents-app-updates/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;VS Code 1.116 es la versión de abril de 2026, y aunque es más ligera que algunas actualizaciones recientes, los cambios son enfocados y significativos — especialmente si estás usando la app de Agentes a diario.&lt;/p&gt;
&lt;p&gt;Esto es lo que llegó, basado en las &lt;a href="https://code.visualstudio.com/updates/v1_116"&gt;notas de la versión oficial&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="mejoras-en-la-app-de-agentes"&gt;Mejoras en la app de Agentes&lt;/h2&gt;
&lt;p&gt;La app de Agentes sigue madurando con pulido de usabilidad que marca una diferencia real en los flujos de trabajo diarios:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Atajos de teclado dedicados&lt;/strong&gt; — ahora puedes enfocar la vista de Cambios, el árbol de archivos dentro de Cambios, y la vista de Personalizaciones del Chat con comandos dedicados y atajos de teclado. Si has estado haciendo clic por toda la app de Agentes para navegar, esto trae flujos de trabajo completamente controlados por teclado.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Diálogo de ayuda de accesibilidad&lt;/strong&gt; — presionar &lt;code&gt;Alt+F1&lt;/code&gt; en el cuadro de entrada del chat ahora abre un diálogo de ayuda de accesibilidad que muestra los comandos y atajos disponibles. Los usuarios de lectores de pantalla también pueden controlar la verbosidad de los anuncios. La buena accesibilidad beneficia a todos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Autocompletado de contexto de archivos&lt;/strong&gt; — escribe &lt;code&gt;#&lt;/code&gt; en el chat de la app de Agentes para activar el autocompletado de contexto de archivos dentro de tu espacio de trabajo actual. Esta es una de esas pequeñas mejoras de calidad de vida que aceleran cada interacción — no más escribir rutas completas de archivos al referenciar código.&lt;/p&gt;
&lt;h2 id="resolución-de-enlaces-css-import"&gt;Resolución de enlaces CSS &lt;code&gt;@import&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Una buena para los desarrolladores frontend: VS Code ahora resuelve las referencias CSS &lt;code&gt;@import&lt;/code&gt; que usan rutas de node_modules. Puedes hacer &lt;code&gt;Ctrl+clic&lt;/code&gt; a través de imports como &lt;code&gt;@import &amp;quot;some-module/style.css&amp;quot;&lt;/code&gt; cuando usas bundlers. Pequeño pero elimina un punto de fricción en los flujos de trabajo CSS.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;VS Code 1.116 trata sobre refinamiento — hacer la app de Agentes más navegable, más accesible y más amigable con el teclado. Si pasas tiempo significativo en la app de Agentes (y sospecho que muchos de nosotros lo hacemos), estos cambios se acumulan.&lt;/p&gt;
&lt;p&gt;Revisa las &lt;a href="https://code.visualstudio.com/updates/v1_116"&gt;notas de la versión completas&lt;/a&gt; para la lista completa.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.115 — Notificaciones de Terminal en Segundo Plano, Modo Agente SSH y Más</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/vscode-1-115-agent-improvements/</link><pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/vscode-1-115-agent-improvements/</guid><description>VS Code 1.115 trae notificaciones de terminal en segundo plano para agentes, hosting remoto de agentes por SSH, pegado de archivos en terminales y seguimiento de ediciones con reconocimiento de sesión. Esto es lo que importa para desarrolladores .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/posts/emiliano-montesdeoca/vscode-1-115-agent-improvements/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;VS Code 1.115 acaba de &lt;a href="https://code.visualstudio.com/updates/v1_115"&gt;lanzarse&lt;/a&gt;, y aunque es una versión más ligera en cuanto a funcionalidades destacadas, las mejoras relacionadas con agentes son genuinamente útiles si trabajás con asistentes de código con IA todos los días.&lt;/p&gt;
&lt;p&gt;Déjame resaltar lo que realmente vale la pena saber.&lt;/p&gt;
&lt;h2 id="las-terminales-en-segundo-plano-ahora-se-comunican-con-los-agentes"&gt;Las terminales en segundo plano ahora se comunican con los agentes&lt;/h2&gt;
&lt;p&gt;Esta es la funcionalidad estrella. Las terminales en segundo plano ahora notifican automáticamente a los agentes cuando los comandos terminan, incluyendo el código de salida y la salida de la terminal. Las solicitudes de entrada en terminales en segundo plano también se detectan y se muestran al usuario.&lt;/p&gt;
&lt;p&gt;¿Por qué importa esto? Si usaste el modo agente de Copilot para ejecutar comandos de compilación o suites de tests en segundo plano, conocés el dolor del &amp;ldquo;¿ya terminó eso?&amp;rdquo; — las terminales en segundo plano eran básicamente disparar-y-olvidar. Ahora el agente recibe una notificación cuando tu &lt;code&gt;dotnet build&lt;/code&gt; o &lt;code&gt;dotnet test&lt;/code&gt; termina, ve la salida y puede reaccionar en consecuencia. Es un cambio pequeño que hace que los flujos de trabajo impulsados por agentes sean significativamente más confiables.&lt;/p&gt;
&lt;p&gt;También hay una nueva herramienta &lt;code&gt;send_to_terminal&lt;/code&gt; que permite a los agentes enviar comandos a terminales en segundo plano con confirmación del usuario, solucionando el problema donde &lt;code&gt;run_in_terminal&lt;/code&gt; con un timeout movía las terminales al segundo plano y las dejaba como solo lectura.&lt;/p&gt;
&lt;h2 id="hosting-remoto-de-agentes-por-ssh"&gt;Hosting remoto de agentes por SSH&lt;/h2&gt;
&lt;p&gt;VS Code ahora soporta conectarse a máquinas remotas por SSH, instalando automáticamente el CLI e iniciándolo en modo host de agentes. Esto significa que tus sesiones de agentes de IA pueden apuntar a entornos remotos directamente — útil para desarrolladores .NET que compilan y prueban en servidores Linux o VMs en la nube.&lt;/p&gt;
&lt;h2 id="seguimiento-de-ediciones-en-sesiones-de-agentes"&gt;Seguimiento de ediciones en sesiones de agentes&lt;/h2&gt;
&lt;p&gt;Las ediciones de archivos realizadas durante sesiones de agentes ahora se rastrean y restauran, con diffs, deshacer/rehacer y restauración de estado. Si un agente hace cambios en tu código y algo sale mal, podés ver exactamente qué cambió y revertirlo. Tranquilidad para dejar que los agentes modifiquen tu codebase.&lt;/p&gt;
&lt;h2 id="reconocimiento-de-pestañas-del-navegador-y-otras-mejoras"&gt;Reconocimiento de pestañas del navegador y otras mejoras&lt;/h2&gt;
&lt;p&gt;Algunas mejoras adicionales de calidad de vida:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Seguimiento de pestañas del navegador&lt;/strong&gt; — el chat ahora puede rastrear y enlazar a pestañas del navegador abiertas durante una sesión, para que los agentes puedan referenciar páginas web que estás viendo&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pegado de archivos en la terminal&lt;/strong&gt; — pegá archivos (incluyendo imágenes) en la terminal con Ctrl+V, arrastrar y soltar, o clic derecho&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cobertura de tests en el minimapa&lt;/strong&gt; — los indicadores de cobertura de tests ahora se muestran en el minimapa para una vista visual rápida&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pellizcar para zoom en Mac&lt;/strong&gt; — el navegador integrado soporta gestos de pellizcar para zoom&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Derechos de Copilot en Sesiones&lt;/strong&gt; — la barra de estado muestra información de uso en la vista de Sesiones&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Favicon en Ir a Archivo&lt;/strong&gt; — las páginas web abiertas muestran favicons en la lista de selección rápida&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;VS Code 1.115 es una versión incremental, pero las mejoras de agentes — notificaciones de terminal en segundo plano, hosting de agentes por SSH y seguimiento de ediciones — se suman a una experiencia notablemente más fluida para el desarrollo asistido por IA. Si estás usando el modo agente de Copilot para proyectos .NET, estos son el tipo de mejoras de calidad de vida que reducen la fricción diaria.&lt;/p&gt;
&lt;p&gt;Mirá las &lt;a href="https://code.visualstudio.com/updates/v1_115"&gt;notas de la versión completas&lt;/a&gt; para cada detalle.&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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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>Azure DevOps por fin arregla el editor Markdown que todos odiaban</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-devops-markdown-editor-work-items/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-devops-markdown-editor-work-items/</guid><description>El editor Markdown de Azure DevOps para work items ahora tiene una distinción clara entre modo vista previa y edición. Es un cambio pequeño que arregla un problema de UX genuinamente molesto.</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/posts/emiliano-montesdeoca/azure-devops-markdown-editor-work-items/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Si usas Azure Boards, probablemente has vivido esto: estás leyendo la descripción de un work item, tal vez revisando los criterios de aceptación, y accidentalmente haces doble clic. Boom — estás en modo edición. No querías editar nada. Solo estabas leyendo.&lt;/p&gt;
&lt;p&gt;Dan Hellem &lt;a href="https://devblogs.microsoft.com/devops/improving-the-markdown-editor-for-work-items/"&gt;anunció la corrección&lt;/a&gt;, y es uno de esos cambios que suenan pequeños pero realmente eliminan fricción de tu flujo de trabajo diario.&lt;/p&gt;
&lt;h2 id="qué-cambió"&gt;Qué cambió&lt;/h2&gt;
&lt;p&gt;El editor Markdown para campos de texto de work items ahora abre en &lt;strong&gt;modo vista previa por defecto&lt;/strong&gt;. Puedes leer e interactuar con el contenido — seguir enlaces, revisar formato — sin preocuparte por entrar accidentalmente en modo edición.&lt;/p&gt;
&lt;p&gt;Cuando realmente quieres editar, haces clic en el ícono de edición en la parte superior del campo. Cuando terminas, sales explícitamente al modo vista previa. Simple, intencional, predecible.&lt;/p&gt;
&lt;p&gt;Eso es. Ese es el cambio.&lt;/p&gt;
&lt;h2 id="por-qué-importa-más-de-lo-que-parece"&gt;Por qué importa más de lo que parece&lt;/h2&gt;
&lt;p&gt;El &lt;a href="https://developercommunity.visualstudio.com/t/Markdown-editor-for-work-item-multi-line/10935496"&gt;hilo de feedback de la comunidad&lt;/a&gt; sobre esto era largo. El comportamiento de doble clic para editar se introdujo con el editor Markdown en julio 2025, y las quejas empezaron casi inmediatamente. El problema no eran solo las ediciones accidentales — era que toda la interacción se sentía impredecible.&lt;/p&gt;
&lt;p&gt;Para equipos que hacen planificación de sprints, refinamiento de backlog o revisión de código con Azure Boards, este tipo de micro-fricción se acumula. Cada entrada accidental al modo edición es un cambio de contexto. Cada momento de &amp;ldquo;espera, ¿cambié algo?&amp;rdquo; es atención desperdiciada.&lt;/p&gt;
&lt;h2 id="estado-del-despliegue"&gt;Estado del despliegue&lt;/h2&gt;
&lt;p&gt;Ya se está implementando para un subconjunto de clientes y se expandirá a todos en las próximas dos o tres semanas.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;No toda mejora necesita ser una función titular. A veces la mejor actualización es simplemente eliminar algo molesto. Esta es una de esas — una pequeña corrección de UX que hace que Azure Boards se sienta menos hostil para las personas que solo quieren leer sus work items en paz.&lt;/p&gt;</content:encoded></item><item><title>Bookmark Studio trae navegación por slots y compartir a los marcadores de Visual Studio</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/bookmark-studio-visual-studio-extension/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/bookmark-studio-visual-studio-extension/</guid><description>La nueva extensión Bookmark Studio de Mads Kristensen añade navegación por slots con teclado, un gestor de marcadores, colores, etiquetas y capacidades de exportación a Visual Studio.</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/posts/emiliano-montesdeoca/bookmark-studio-visual-studio-extension/"&gt;haz clic aquí&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Los marcadores en Visual Studio siempre han sido&amp;hellip; aceptables. Pones uno, navegas al siguiente, olvidas cuál es cuál. Funcionan, pero nunca han sido una función que llamarías poderosa.&lt;/p&gt;
&lt;p&gt;Mads Kristensen acaba de &lt;a href="https://devblogs.microsoft.com/visualstudio/bookmark-studio-evolving-bookmarks-in-visual-studio/"&gt;lanzar Bookmark Studio&lt;/a&gt;, una extensión experimental que llena exactamente los vacíos que probablemente has encontrado si usas marcadores regularmente.&lt;/p&gt;
&lt;h2 id="navegación-por-slots"&gt;Navegación por slots&lt;/h2&gt;
&lt;p&gt;Los marcadores se pueden asignar a slots del 1 al 9 y saltar directamente con &lt;code&gt;Alt+Shift+1&lt;/code&gt; hasta &lt;code&gt;Alt+Shift+9&lt;/code&gt;. Los nuevos marcadores obtienen automáticamente el siguiente slot disponible.&lt;/p&gt;
&lt;h2 id="el-gestor-de-marcadores"&gt;El Gestor de Marcadores&lt;/h2&gt;
&lt;p&gt;Una nueva ventana de herramientas muestra todos tus marcadores en un solo lugar con filtrado por nombre, archivo, ubicación, color o slot.&lt;/p&gt;
&lt;h2 id="organización-con-etiquetas-colores-y-carpetas"&gt;Organización con etiquetas, colores y carpetas&lt;/h2&gt;
&lt;p&gt;Los marcadores pueden tener opcionalmente etiquetas, colores y agruparse en carpetas. Toda la metadata se almacena por solución.&lt;/p&gt;
&lt;h2 id="exportar-y-compartir"&gt;Exportar y compartir&lt;/h2&gt;
&lt;p&gt;Bookmark Studio permite exportar marcadores como texto plano, Markdown o CSV. Puedes incluir rutas de marcadores en descripciones de PR o compartir caminos de investigación con compañeros.&lt;/p&gt;
&lt;h2 id="marcadores-que-siguen-al-código"&gt;Marcadores que siguen al código&lt;/h2&gt;
&lt;p&gt;Bookmark Studio rastrea los marcadores relativos al texto al que están anclados, así que no se desplazan a líneas incorrectas mientras editas.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;Bookmark Studio no reinventa nada. Toma una función que ha sido &amp;ldquo;suficiente&amp;rdquo; durante años y la hace genuinamente útil. Descárgalo del &lt;a href="https://marketplace.visualstudio.com/items?itemName=MadsKristensen.BookmarkStudio"&gt;Visual Studio Marketplace&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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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>SQL MCP Server, Copilot en SSMS y un Database Hub con agentes de IA: Lo que realmente importa de SQLCon 2026</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/agentic-ai-microsoft-databases-what-matters/</link><pubDate>Sat, 28 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/agentic-ai-microsoft-databases-what-matters/</guid><description>Microsoft soltó un montón de anuncios de bases de datos en SQLCon 2026. Esto es lo que realmente importa si estás construyendo apps con IA sobre Azure SQL.</description><content:encoded>&lt;p&gt;Microsoft acaba de arrancar &lt;a href="https://www.microsoft.com/en-us/sql-server/blog/2026/03/18/advancing-agentic-ai-with-microsoft-databases-across-a-unified-data-estate/"&gt;SQLCon 2026 junto con FabCon en Atlanta&lt;/a&gt;, y hay mucho que desempacar. El anuncio original cubre de todo, desde planes de ahorro hasta funciones de compliance empresarial. Yo me voy a saltar las diapositivas de precios enterprise y enfocarme en lo que importa si eres un desarrollador construyendo cosas con Azure SQL e IA.&lt;/p&gt;
&lt;h2 id="sql-mcp-server-está-en-public-preview"&gt;SQL MCP Server está en public preview&lt;/h2&gt;
&lt;p&gt;Este es el titular para mí. Azure SQL Database Hyperscale ahora tiene un &lt;strong&gt;SQL MCP Server&lt;/strong&gt; en public preview que te permite conectar de forma segura tus datos SQL a agentes de IA y Copilots usando el &lt;a href="https://modelcontextprotocol.io/"&gt;Model Context Protocol&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Si has estado siguiendo la ola de MCP — y honestamente, es difícil no verla ahora mismo — esto es importante. En lugar de construir pipelines de datos personalizados para alimentar a tus agentes de IA con contexto de tu base de datos, tienes un protocolo estandarizado para exponer datos SQL directamente. Tus agentes pueden consultar, razonar y actuar sobre información de base de datos en tiempo real.&lt;/p&gt;
&lt;p&gt;Para los que estamos construyendo agentes de IA con Semantic Kernel o el Microsoft Agent Framework, esto abre un camino de integración limpio. ¿Tu agente necesita verificar inventario? ¿Buscar un registro de cliente? ¿Validar un pedido? MCP le da una forma estructurada de hacerlo sin que tengas que escribir código a medida para cada escenario.&lt;/p&gt;
&lt;h2 id="github-copilot-en-ssms-22-ya-está-en-ga"&gt;GitHub Copilot en SSMS 22 ya está en GA&lt;/h2&gt;
&lt;p&gt;Si pasas algo de tiempo en SQL Server Management Studio — y seamos honestos, la mayoría todavía lo hacemos — GitHub Copilot ya está disponible de forma general en SSMS 22. La misma experiencia de Copilot que ya usas en VS Code y Visual Studio, pero para T-SQL.&lt;/p&gt;
&lt;p&gt;El valor práctico es directo: asistencia por chat para escribir queries, refactorizar stored procedures, resolver problemas de rendimiento y manejar tareas de administración. Nada revolucionario en concepto, pero tenerlo ahí mismo en SSMS significa que no necesitas cambiar de contexto a otro editor solo para obtener ayuda de IA con tu trabajo de base de datos.&lt;/p&gt;
&lt;h2 id="los-índices-vectoriales-recibieron-una-mejora-seria"&gt;Los índices vectoriales recibieron una mejora seria&lt;/h2&gt;
&lt;p&gt;Azure SQL Database ahora tiene índices vectoriales más rápidos y capaces con soporte completo de insert, update y delete. Eso significa que tus datos vectoriales se mantienen actualizados en tiempo real — sin necesidad de reindexar por lotes.&lt;/p&gt;
&lt;p&gt;Esto es lo nuevo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cuantización&lt;/strong&gt; para tamaños de índice más pequeños sin perder demasiada precisión&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Filtrado iterativo&lt;/strong&gt; para resultados más precisos&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integración más ajustada con el optimizador de queries&lt;/strong&gt; para rendimiento predecible&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si estás haciendo retrieval-augmented generation (RAG) con Azure SQL como tu almacén vectorial, estas mejoras son directamente útiles. Puedes mantener tus vectores junto con tus datos relacionales en la misma base de datos, lo que simplifica tu arquitectura significativamente comparado con ejecutar una base de datos vectorial separada.&lt;/p&gt;
&lt;p&gt;Las mismas mejoras vectoriales también están disponibles en SQL database en Fabric, ya que ambos corren sobre el mismo motor SQL por debajo.&lt;/p&gt;
&lt;h2 id="database-hub-en-fabric-gestión-agéntica"&gt;Database Hub en Fabric: gestión agéntica&lt;/h2&gt;
&lt;p&gt;Este es más orientado al futuro, pero es interesante. Microsoft anunció el &lt;strong&gt;Database Hub en Microsoft Fabric&lt;/strong&gt; (acceso anticipado), que te da una vista unificada de Azure SQL, Cosmos DB, PostgreSQL, MySQL y SQL Server vía Arc.&lt;/p&gt;
&lt;p&gt;El ángulo interesante no es solo la vista unificada — es el enfoque agéntico para la gestión. Agentes de IA monitorean continuamente tu estate de bases de datos, te muestran qué cambió, explican por qué importa y sugieren qué hacer. Es un modelo human-in-the-loop donde el agente hace el trabajo pesado y tú tomas las decisiones.&lt;/p&gt;
&lt;p&gt;Para equipos que gestionan más de un puñado de bases de datos, esto podría genuinamente reducir el ruido operacional. En lugar de saltar entre portales y revisar métricas manualmente, el agente te trae la señal.&lt;/p&gt;
&lt;h2 id="qué-significa-esto-para-desarrolladores-net"&gt;Qué significa esto para desarrolladores .NET&lt;/h2&gt;
&lt;p&gt;El hilo que conecta todos estos anuncios es claro: Microsoft está integrando agentes de IA en cada capa del stack de bases de datos. No como un truco, sino como una capa práctica de herramientas.&lt;/p&gt;
&lt;p&gt;Si estás construyendo apps .NET respaldadas por Azure SQL, esto es lo que yo haría:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prueba el SQL MCP Server&lt;/strong&gt; si estás construyendo agentes de IA. Es la forma más limpia de darles acceso a base de datos sin plomería personalizada.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Activa Copilot en SSMS&lt;/strong&gt; si no lo has hecho — ganancia de productividad gratis para el trabajo diario con SQL.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Investiga los índices vectoriales&lt;/strong&gt; si estás haciendo RAG y actualmente tienes un almacén vectorial separado. Consolidar en Azure SQL significa un servicio menos que gestionar.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;El anuncio completo tiene más — planes de ahorro, asistentes de migración, funciones de compliance — pero la historia para desarrolladores está en el MCP Server, las mejoras vectoriales y la capa de gestión agéntica. Estas son las piezas que cambian cómo construyes, no solo cómo presupuestas.&lt;/p&gt;
&lt;p&gt;Revisa el &lt;a href="https://www.microsoft.com/en-us/sql-server/blog/2026/03/18/advancing-agentic-ai-with-microsoft-databases-across-a-unified-data-estate/"&gt;anuncio completo de Shireesh Thota&lt;/a&gt; para la foto completa, y &lt;a href="https://aka.ms/database-hub"&gt;regístrate para el acceso anticipado del Database Hub&lt;/a&gt; si quieres probar la nueva experiencia de gestión.&lt;/p&gt;</content:encoded></item><item><title>Del portátil a producción: desplegando agentes de IA en Microsoft Foundry con dos comandos</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/deploy-ai-agents-foundry-azd-two-commands/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/deploy-ai-agents-foundry-azd-two-commands/</guid><description>El Azure Developer CLI ahora tiene comandos 'azd ai agent' que llevan tu agente de IA desde el desarrollo local a un endpoint en Foundry en minutos. Aquí está el flujo de trabajo completo.</description><content:encoded>&lt;p&gt;¿Conoces esa brecha entre &amp;ldquo;funciona en mi máquina&amp;rdquo; y &amp;ldquo;está desplegado y sirviendo tráfico&amp;rdquo;? Para agentes de IA, esa brecha ha sido dolorosamente amplia. Necesitas provisionar recursos, desplegar modelos, configurar identidad, montar monitoreo — y eso es antes de que alguien pueda realmente llamar a tu agente.&lt;/p&gt;
&lt;p&gt;El Azure Developer CLI acaba de convertir esto en &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-ai-agent-end-to-end/"&gt;un asunto de dos comandos&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="el-nuevo-flujo-de-trabajo-azd-ai-agent"&gt;El nuevo flujo de trabajo &lt;code&gt;azd ai agent&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Déjame mostrarte cómo se ve esto realmente. Tienes un proyecto de agente de IA — digamos un agente concierge de hotel. Funciona localmente. Quieres que corra en Microsoft Foundry.&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;azd ai agent init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Eso es todo. Dos comandos. &lt;code&gt;azd ai agent init&lt;/code&gt; genera la infraestructura como código en tu repositorio, y &lt;code&gt;azd up&lt;/code&gt; provisiona todo en Azure y publica tu agente. Obtienes un enlace directo a tu agente en el portal de Foundry.&lt;/p&gt;
&lt;h2 id="qué-pasa-por-debajo"&gt;Qué pasa por debajo&lt;/h2&gt;
&lt;p&gt;El comando &lt;code&gt;init&lt;/code&gt; genera plantillas Bicep reales e inspeccionables en tu repositorio:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un &lt;strong&gt;Foundry Resource&lt;/strong&gt; (contenedor de nivel superior)&lt;/li&gt;
&lt;li&gt;Un &lt;strong&gt;Foundry Project&lt;/strong&gt; (donde vive tu agente)&lt;/li&gt;
&lt;li&gt;Configuración de &lt;strong&gt;despliegue de modelo&lt;/strong&gt; (GPT-4o, etc.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Identidad administrada&lt;/strong&gt; con asignaciones de roles RBAC apropiadas&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azure.yaml&lt;/code&gt; para el mapa de servicios&lt;/li&gt;
&lt;li&gt;&lt;code&gt;agent.yaml&lt;/code&gt; con metadatos del agente y variables de entorno&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La parte clave: todo esto es tuyo. Es Bicep versionado en tu repositorio. Puedes inspeccionarlo, personalizarlo y hacer commit junto con el código de tu agente. Sin cajas negras mágicas.&lt;/p&gt;
&lt;h2 id="el-ciclo-interno-de-desarrollo"&gt;El ciclo interno de desarrollo&lt;/h2&gt;
&lt;p&gt;Lo que realmente me gusta es la historia de desarrollo local. Cuando estás iterando sobre la lógica del agente, no quieres redesplegar cada vez que cambias un prompt:&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;azd ai agent run
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esto inicia tu agente localmente. Combínalo con &lt;code&gt;azd ai agent invoke&lt;/code&gt; para enviar prompts de prueba, y tienes un ciclo de retroalimentación rápido. Editar código, reiniciar, invocar, repetir.&lt;/p&gt;
&lt;p&gt;El comando &lt;code&gt;invoke&lt;/code&gt; es inteligente con el enrutamiento también — cuando un agente local está corriendo, lo apunta automáticamente. Cuando no, apunta al endpoint remoto.&lt;/p&gt;
&lt;h2 id="monitoreo-en-tiempo-real"&gt;Monitoreo en tiempo real&lt;/h2&gt;
&lt;p&gt;Esta es la característica que me convenció. Una vez que tu agente está desplegado:&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;azd ai agent monitor --follow
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cada petición y respuesta que fluye a través de tu agente se transmite a tu terminal en tiempo real. Para depurar problemas en producción, esto es invaluable. Sin buscar en log analytics, sin esperar a que las métricas se agreguen — ves lo que está pasando ahora mismo.&lt;/p&gt;
&lt;h2 id="el-set-completo-de-comandos"&gt;El set completo de comandos&lt;/h2&gt;
&lt;p&gt;Aquí la referencia rápida:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Comando&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;code&gt;azd ai agent init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Genera un proyecto de agente Foundry con IaC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd up&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Provisiona recursos Azure y despliega el agente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent invoke&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Envía prompts al agente remoto o local&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent run&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ejecuta el agente localmente para desarrollo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent monitor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Transmite logs en tiempo real del agente publicado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent show&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verifica la salud y estado del agente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd down&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Limpia todos los recursos Azure&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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 el ejemplo del anuncio está basado en Python, la historia de infraestructura es agnóstica al lenguaje. Tu agente .NET obtiene el mismo scaffolding Bicep, la misma configuración de identidad administrada, el mismo pipeline de monitoreo. Y si ya estás usando &lt;code&gt;azd&lt;/code&gt; para tus apps .NET Aspire o despliegues Azure, esto encaja directamente en tu flujo de trabajo existente.&lt;/p&gt;
&lt;p&gt;La brecha de despliegue para agentes de IA ha sido uno de los mayores puntos de fricción en el ecosistema. Pasar de un prototipo funcional a un endpoint de producción con identidad, networking y monitoreo adecuados no debería requerir una semana de trabajo DevOps. Ahora requiere dos comandos y unos minutos.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azd ai agent&lt;/code&gt; está disponible ahora. Si has estado posponiendo el despliegue de tus agentes de IA porque la configuración de infraestructura parecía demasiado trabajo, dale una oportunidad. Revisa el &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-ai-agent-end-to-end/"&gt;tutorial completo&lt;/a&gt; para el paso a paso completo incluyendo integración de app de chat frontend.&lt;/p&gt;</content:encoded></item><item><title>El MCP Server de Azure DevOps llega a Microsoft Foundry: Qué significa para tus agentes de IA</title><link>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-devops-mcp-server-microsoft-foundry/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/es/posts/emiliano-montesdeoca/azure-devops-mcp-server-microsoft-foundry/</guid><description>El MCP Server de Azure DevOps ya está disponible en Microsoft Foundry. Conecta tus agentes de IA directamente a flujos de trabajo de DevOps — work items, repos, pipelines — con unos pocos clics.</description><content:encoded>&lt;p&gt;MCP (Model Context Protocol) está teniendo su momento. Si has estado siguiendo el ecosistema de agentes de IA, probablemente hayas notado que los servidores MCP están apareciendo por todas partes — dándoles a los agentes la capacidad de interactuar con herramientas y servicios externos a través de un protocolo estandarizado.&lt;/p&gt;
&lt;p&gt;Ahora el &lt;a href="https://devblogs.microsoft.com/devops/remote-mcp-server-preview-in-microsoft-foundry/"&gt;MCP Server de Azure DevOps está disponible en Microsoft Foundry&lt;/a&gt;, y esta es una de esas integraciones que te hace pensar en las posibilidades prácticas.&lt;/p&gt;
&lt;h2 id="qué-está-pasando-realmente-aquí"&gt;Qué está pasando realmente aquí&lt;/h2&gt;
&lt;p&gt;Microsoft ya lanzó el MCP Server de Azure DevOps como &lt;a href="https://devblogs.microsoft.com/devops/azure-devops-remote-mcp-server-public-preview"&gt;public preview&lt;/a&gt; — ese es el servidor MCP en sí. Lo nuevo es la integración con Foundry. Ahora puedes agregar el MCP Server de Azure DevOps a tus agentes de Foundry directamente desde el catálogo de herramientas.&lt;/p&gt;
&lt;p&gt;Para los que no están familiarizados con Foundry todavía: es la plataforma unificada de Microsoft para construir y gestionar aplicaciones y agentes impulsados por IA a escala. Acceso a modelos, orquestación, evaluación, despliegue — todo en un solo lugar.&lt;/p&gt;
&lt;h2 id="configurándolo"&gt;Configurándolo&lt;/h2&gt;
&lt;p&gt;La configuración es sorprendentemente sencilla:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;En tu agente de Foundry, ve a &lt;strong&gt;Add Tools&lt;/strong&gt; &amp;gt; &lt;strong&gt;Catalog&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Busca &amp;ldquo;Azure DevOps&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Selecciona el Azure DevOps MCP Server (preview) y haz clic en &lt;strong&gt;Create&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Ingresa el nombre de tu organización y conecta&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Eso es todo. Tu agente ahora tiene acceso a las herramientas de Azure DevOps.&lt;/p&gt;
&lt;h2 id="controlando-a-qué-puede-acceder-tu-agente"&gt;Controlando a qué puede acceder tu agente&lt;/h2&gt;
&lt;p&gt;Esta es la parte que aprecio: no estás atrapado con un enfoque de todo o nada. Puedes especificar qué herramientas están disponibles para tu agente. Así que si solo quieres que lea work items pero no toque pipelines, puedes configurar eso. Principio de mínimo privilegio, aplicado a tus agentes de IA.&lt;/p&gt;
&lt;p&gt;Esto importa para escenarios empresariales donde no quieres que un agente accidentalmente dispare un pipeline de despliegue porque alguien le pidió que &amp;ldquo;ayude con el release.&amp;rdquo;&lt;/p&gt;
&lt;h2 id="por-qué-esto-es-interesante-para-equipos-net"&gt;Por qué esto es interesante para equipos .NET&lt;/h2&gt;
&lt;p&gt;Piensa en lo que esto habilita en la práctica:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Asistentes de planificación de sprint&lt;/strong&gt; — agentes que pueden obtener work items, analizar datos de velocidad y sugerir capacidad de sprint&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bots de code review&lt;/strong&gt; — agentes que entienden el contexto de tu PR porque realmente pueden leer tus repos y work items vinculados&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Respuesta a incidentes&lt;/strong&gt; — agentes que pueden crear work items, consultar despliegues recientes y correlacionar bugs con cambios recientes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Onboarding de desarrolladores&lt;/strong&gt; — &amp;ldquo;¿En qué debería trabajar?&amp;rdquo; obtiene una respuesta real respaldada por datos reales del proyecto&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para equipos .NET que ya usan Azure DevOps para sus pipelines de CI/CD y gestión de proyectos, tener un agente de IA que pueda interactuar directamente con esos sistemas es un paso significativo hacia la automatización útil (no solo chatbot-como-servicio).&lt;/p&gt;
&lt;h2 id="el-panorama-más-amplio-de-mcp"&gt;El panorama más amplio de MCP&lt;/h2&gt;
&lt;p&gt;Esto es parte de una tendencia más amplia: los servidores MCP se están convirtiendo en la forma estándar en que los agentes de IA interactúan con el mundo exterior. Los estamos viendo para GitHub, Azure DevOps, bases de datos, APIs SaaS — y Foundry se está convirtiendo en el hub donde todas estas conexiones se unen.&lt;/p&gt;
&lt;p&gt;Si estás construyendo agentes en el ecosistema .NET, vale la pena prestar atención a MCP. El protocolo está estandarizado, las herramientas están madurando, y la integración con Foundry lo hace accesible sin tener que conectar manualmente las conexiones del servidor.&lt;/p&gt;
&lt;h2 id="para-cerrar"&gt;Para cerrar&lt;/h2&gt;
&lt;p&gt;El MCP Server de Azure DevOps en Foundry está en preview, así que espera que evolucione. Pero el flujo de trabajo principal es sólido: conectar, configurar acceso a herramientas, y dejar que tus agentes trabajen con tus datos de DevOps. Si ya estás en el ecosistema de Foundry, esto está a unos pocos clics. Dale una oportunidad y ve qué flujos de trabajo puedes construir.&lt;/p&gt;
&lt;p&gt;Revisa el &lt;a href="https://devblogs.microsoft.com/devops/remote-mcp-server-preview-in-microsoft-foundry/"&gt;anuncio completo&lt;/a&gt; para la configuración paso a paso y más detalles.&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/posts/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/posts/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/posts/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/posts/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/posts/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/posts/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><item><title>Emiliano Montesdeoca</title><link>https://thedotnetblog.com/es/authors/emiliano-montesdeoca/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/es/authors/emiliano-montesdeoca/</guid><description/><content:encoded/></item><item><title>Escribe para The .NET Blog</title><link>https://thedotnetblog.com/es/contribute/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/es/contribute/</guid><description>Comparte tu conocimiento con la comunidad .NET. Aprende cómo unirte como autor y enviar tu primer artículo.</description><content:encoded>&lt;p&gt;The .NET Blog es una publicación impulsada por la comunidad donde los desarrolladores comparten ideas, tutoriales e historias sobre .NET, Azure, IA y desarrollo cloud-native. &lt;strong&gt;Damos la bienvenida a contribuciones de desarrolladores de todos los niveles&lt;/strong&gt; — tanto si es tu primer artículo técnico como si eres un ponente con experiencia.&lt;/p&gt;
&lt;h2 id="cómo-unirse"&gt;Cómo Unirse&lt;/h2&gt;
&lt;p&gt;Todo vive en GitHub y sigue un flujo de trabajo de pull requests. Así puedes empezar:&lt;/p&gt;
&lt;h3 id="1-haz-un-fork-del-repositorio"&gt;1. Haz un Fork del Repositorio&lt;/h3&gt;
&lt;p&gt;Ve a &lt;a href="https://github.com/thedotnetblog/blog"&gt;github.com/thedotnetblog/blog&lt;/a&gt; y haz un fork a tu cuenta de GitHub.&lt;/p&gt;
&lt;h3 id="2-crea-tu-perfil-de-autor"&gt;2. Crea tu Perfil de Autor&lt;/h3&gt;
&lt;p&gt;Si es tu primera contribución, añádete como autor creando una carpeta en &lt;code&gt;content/authors/tu-usuario/&lt;/code&gt; con un archivo &lt;code&gt;index.md&lt;/code&gt;:&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="nn"&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="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Tu Nombre&amp;#34;&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="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tu-usuario&amp;#34;&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="nt"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Tu cargo o título&amp;#34;&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="nt"&gt;bio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Una breve biografía sobre ti.&amp;#34;&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="nt"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/img/authors/tu-avatar.jpg&amp;#34;&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="nt"&gt;socials&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;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;GitHub&amp;#34;&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;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://github.com/tu-usuario&amp;#34;&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;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Twitter&amp;#34;&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;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://x.com/tu-usuario&amp;#34;&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="nn"&gt;---&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;Añade tu imagen de avatar (cuadrada, mínimo 200×200px) en &lt;code&gt;static/img/authors/&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="3-escribe-tu-artículo"&gt;3. Escribe tu Artículo&lt;/h3&gt;
&lt;p&gt;Crea una nueva carpeta en &lt;code&gt;content/posts/tu-usuario/slug-de-tu-articulo/&lt;/code&gt; y añade un archivo &lt;code&gt;index.md&lt;/code&gt;:&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="nn"&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="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Título de tu Artículo&amp;#34;&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="nt"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ld"&gt;2025-01-01&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="nt"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tu-usuario&amp;#34;&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="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Una descripción breve de tu artículo.&amp;#34;&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="nt"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;dotnet&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;azure&amp;#34;&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="nn"&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;El contenido de tu artículo en Markdown...&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;h3 id="4-abre-un-pull-request"&gt;4. Abre un Pull Request&lt;/h3&gt;
&lt;p&gt;Sube tus cambios a tu fork y abre un pull request contra la rama &lt;code&gt;main&lt;/code&gt;. Nuestro equipo lo revisará y te dará feedback en unos días.&lt;/p&gt;
&lt;h2 id="qué-buscamos"&gt;Qué Buscamos&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tutoriales&lt;/strong&gt; — guías paso a paso sobre .NET, Azure, IA, Blazor, Aspire y más&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Análisis profundos&lt;/strong&gt; — exploraciones detalladas de una tecnología, patrón o arquitectura&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Historias de la comunidad&lt;/strong&gt; — tu experiencia construyendo con .NET en producción&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resúmenes de eventos&lt;/strong&gt; — resúmenes de conferencias, meetups o webinars&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="directrices"&gt;Directrices&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;El contenido debe ser técnico y relevante para el ecosistema .NET&lt;/li&gt;
&lt;li&gt;Los ejemplos de código deben ser precisos y probados en un proyecto real&lt;/li&gt;
&lt;li&gt;Incluye una descripción significativa y al menos una etiqueta relevante&lt;/li&gt;
&lt;li&gt;Los artículos se traducen automáticamente a todos los idiomas disponibles&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="contacto"&gt;Contacto&lt;/h2&gt;
&lt;p&gt;Abre un issue en &lt;a href="https://github.com/thedotnetblog/blog/issues"&gt;GitHub&lt;/a&gt; o contáctanos en &lt;a href="https://x.com/thedotnetblog"&gt;X / Twitter&lt;/a&gt;. ¡Nos encantaría tenerte en la comunidad!&lt;/p&gt;</content:encoded></item></channel></rss>