<?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>Python | The .NET Blog</title><link>https://thedotnetblog.com/es/tags/python/</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>Sat, 25 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/es/tags/python/index.xml" rel="self" type="application/rss+xml"/><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>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>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></channel></rss>