<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: JULIO SAMUEL CORTEZ MAMANI</title>
    <description>The latest articles on DEV Community by JULIO SAMUEL CORTEZ MAMANI (@julio_samuelcortezmaman).</description>
    <link>https://dev.to/julio_samuelcortezmaman</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4014114%2Fa7fa57d6-e81a-47c6-992d-437303f15bff.jpg</url>
      <title>DEV Community: JULIO SAMUEL CORTEZ MAMANI</title>
      <link>https://dev.to/julio_samuelcortezmaman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/julio_samuelcortezmaman"/>
    <language>en</language>
    <item>
      <title>Vanna AI (El estándar de la industria para Text-to-SQL)</title>
      <dc:creator>JULIO SAMUEL CORTEZ MAMANI</dc:creator>
      <pubDate>Fri, 03 Jul 2026 23:40:49 +0000</pubDate>
      <link>https://dev.to/julio_samuelcortezmaman/vanna-ai-el-estandar-de-la-industria-para-text-to-sql-6k2</link>
      <guid>https://dev.to/julio_samuelcortezmaman/vanna-ai-el-estandar-de-la-industria-para-text-to-sql-6k2</guid>
      <description>&lt;h2&gt;
  
  
  Idea central
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Vanna&lt;/strong&gt; es uno de los frameworks de código abierto más utilizados hoy en día para crear asistentes de SQL con IA. Funciona en dos pasos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Entrenas un modelo de IA (o un índice vectorial) con tu esquema, documentación y consultas SQL reales pasadas.&lt;/li&gt;
&lt;li&gt;El modelo genera código con una precisión quirúrgica.
### Ventajas&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Se conecta nativamente a &lt;strong&gt;Snowflake, BigQuery, PostgreSQL y MySQL&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Incluye interfaces gráficas listas para usar en &lt;strong&gt;Slack&lt;/strong&gt; o aplicaciones web.&lt;/p&gt;
&lt;h2&gt;
  
  
  Novedades de la versión 2.0
&lt;/h2&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Atención al usuario en cada nivel:&lt;/strong&gt; las consultas se filtran automáticamente según los permisos del usuario.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interfaz web moderna &lt;code&gt;&amp;lt;vanna-chat&amp;gt;&lt;/code&gt;:&lt;/strong&gt; un componente prediseñado de gran belleza.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Respuestas en tiempo real:&lt;/strong&gt; tablas, gráficos y actualizaciones de progreso en tiempo real.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Seguridad empresarial:&lt;/strong&gt; seguridad a nivel de fila (RLS), registros de auditoría y &lt;em&gt;rate limiting&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Listo para producción:&lt;/strong&gt; integración con FastAPI, observabilidad y &lt;em&gt;lifecycle hooks&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  ¿Cómo funciona? (conceptos clave)
&lt;/h2&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;User Resolver:&lt;/strong&gt; define cómo extraer la identidad del usuario de las solicitudes (cookies, JWT, etc.).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Herramientas con reconocimiento de usuario:&lt;/strong&gt; comprueban automáticamente los permisos según los grupos del usuario.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Componentes de transmisión:&lt;/strong&gt; el backend transmite componentes de UI estructurados (tablas, gráficos) al frontend en tiempo real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interfaz web integrada:&lt;/strong&gt; el componente &lt;code&gt;&amp;lt;vanna-chat&amp;gt;&lt;/code&gt; lo renderiza todo automáticamente.
## Ejemplo de código: configuración de producción con autorización&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Backend (Python + FastAPI)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vanna&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vanna.servers.fastapi.routes&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;register_chat_routes&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vanna.servers.base&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatHandler&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vanna.core.user&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;UserResolver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RequestContext&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vanna.integrations.anthropic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AnthropicLlmService&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vanna.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunSqlTool&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vanna.integrations.sqlite&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SqliteRunner&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vanna.core.registry&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ToolRegistry&lt;/span&gt;

&lt;span class="c1"&gt;# App de FastAPI existente
&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Define tu user resolver (usando tu propio sistema de auth)
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyUserResolver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserResolver&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;resolve_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request_context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RequestContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Extraer desde cookies, JWTs o sesión
&lt;/span&gt;        &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;user_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode_jwt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Tu lógica existente
&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;group_memberships&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;groups&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Usado para permisos
&lt;/span&gt;        &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Configurar el agente con herramientas
&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AnthropicLlmService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-3-5-sonnet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ToolRegistry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RunSqlTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql_runner&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;SqliteRunner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./data.db&lt;/span&gt;&lt;span class="sh"&gt;"&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="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;llm_service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tool_registry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user_resolver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;MyUserResolver&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Añadir las rutas de Vanna a tu aplicación
&lt;/span&gt;&lt;span class="n"&gt;chat_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatHandler&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="nf"&gt;register_chat_routes&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="n"&gt;chat_handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Endpoint listo: POST /api/vanna/v2/chat_sse (streaming)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Frontend (componente web)
&lt;/h3&gt;

&lt;p&gt;Agrega esta etiqueta HTML en tu página. Funciona con React, Vue o HTML simple, y utiliza tus cookies/JWT existentes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://img.vanna.ai/vanna-components.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;vanna-chat&lt;/span&gt;
  &lt;span class="na"&gt;sse-endpoint=&lt;/span&gt;&lt;span class="s"&gt;"/api/vanna/v2/chat_sse"&lt;/span&gt;
  &lt;span class="na"&gt;theme=&lt;/span&gt;&lt;span class="s"&gt;"dark"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/vanna-chat&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Al hacer una pregunta en lenguaje natural, el componente frontend recibe por streaming:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Actualizaciones del progreso de la transmisión.&lt;/li&gt;
&lt;li&gt;Bloque de código SQL (por defecto, solo visible para usuarios &lt;code&gt;admin&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Tabla de datos interactiva.&lt;/li&gt;
&lt;li&gt;Gráficos (visualizaciones de Plotly).&lt;/li&gt;
&lt;li&gt;Resumen en lenguaje natural.
### 3. Herramientas personalizadas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Puedes extender Vanna con herramientas específicas para tu caso de uso de negocio, por ejemplo, enviar un correo automático con los resultados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vanna.core.tool&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ToolContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ToolResult&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;recipient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Email recipient&lt;/span&gt;&lt;span class="sh"&gt;"&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="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Email subject&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EmailArgs&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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 class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;access_groups&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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;list&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Verificación de permisos
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_args_schema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EmailArgs&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EmailArgs&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ToolContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EmailArgs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ToolResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;  &lt;span class="c1"&gt;# Inyectado automáticamente por Vanna
&lt;/span&gt;
        &lt;span class="c1"&gt;# Tu lógica de negocio
&lt;/span&gt;        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;from_email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recipient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;args&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="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ToolResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result_for_llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Email sent to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recipient&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Registrar tu herramienta personalizada
&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EmailTool&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Características avanzadas y casos de uso
&lt;/h2&gt;

&lt;p&gt;Vanna 2.0 incluye potentes funciones empresariales para producción:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lifecycle Hooks:&lt;/strong&gt; agrega comprobación de cuotas, registro personalizado y filtrado de contenido.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Middlewares de LLM:&lt;/strong&gt; implementa caching, ingeniería de prompts o seguimiento de costos.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Almacenamiento de conversaciones:&lt;/strong&gt; guarda y recupera el historial por usuario.&lt;/p&gt;
&lt;h3&gt;
  
  
  ¿Para qué casos es ideal?
&lt;/h3&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Aplicaciones de análisis de datos con interfaces de lenguaje natural.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SaaS multiusuario que requiere permisos con reconocimiento de usuario (RLS).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aplicaciones empresariales con requisitos estrictos de seguridad y auditoría.&lt;/p&gt;
&lt;h2&gt;
  
  
  Flujo de arquitectura
&lt;/h2&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El siguiente flujo detalla el ciclo de vida de una solicitud en Vanna 2.0, desde que el usuario hace la pregunta hasta que se renderizan los componentes visuales:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;El usuario escribe una pregunta como &lt;em&gt;"Show Q4 sales"&lt;/em&gt; en el componente &lt;code&gt;&amp;lt;vanna-chat&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;El frontend envía un &lt;code&gt;POST&lt;/code&gt; al endpoint &lt;code&gt;/api/vanna/v2/chat_sse&lt;/code&gt; de tu servidor FastAPI, adjuntando las credenciales de autenticación.&lt;/li&gt;
&lt;li&gt;Tu servidor resuelve la identidad del usuario (ej. Alice) y sus grupos de acceso (&lt;code&gt;read_sales&lt;/code&gt;), y se los pasa al Agente.&lt;/li&gt;
&lt;li&gt;El Agente invoca la herramienta de ejecución de SQL (&lt;em&gt;User-Aware Tool&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;La herramienta aplica automáticamente las reglas de seguridad a nivel de fila (RLS) según el grupo del usuario.&lt;/li&gt;
&lt;li&gt;La base de datos retorna únicamente los resultados filtrados y autorizados al Agente.&lt;/li&gt;
&lt;li&gt;El Agente transmite (&lt;em&gt;streams&lt;/em&gt;) la respuesta en bloques estructurados (Tabla → Gráfico → Resumen) de vuelta al componente web.
## Comparativa rápida de enfoques&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Enfoque&lt;/th&gt;
&lt;th&gt;Complejidad&lt;/th&gt;
&lt;th&gt;Mejor para&lt;/th&gt;
&lt;th&gt;Herramientas clave&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LLM + Python puro&lt;/td&gt;
&lt;td&gt;Baja&lt;/td&gt;
&lt;td&gt;Prototipos rápidos, scripts internos&lt;/td&gt;
&lt;td&gt;API de OpenAI, sqlite3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agentes (&lt;code&gt;smolagents&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Media-Alta&lt;/td&gt;
&lt;td&gt;Consultas complejas, autocorrección&lt;/td&gt;
&lt;td&gt;Hugging Face, smolagents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Streamlit + HF&lt;/td&gt;
&lt;td&gt;Media&lt;/td&gt;
&lt;td&gt;Paneles para usuarios no técnicos&lt;/td&gt;
&lt;td&gt;Streamlit, transformers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAG Dinámico&lt;/td&gt;
&lt;td&gt;Alta&lt;/td&gt;
&lt;td&gt;Entornos enterprise con cientos de tablas&lt;/td&gt;
&lt;td&gt;BD vectoriales, DB-GPT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vanna AI&lt;/td&gt;
&lt;td&gt;Media-Alta&lt;/td&gt;
&lt;td&gt;Producción escalable, UI web lista y segura&lt;/td&gt;
&lt;td&gt;Vanna, FastAPI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusiones y buenas prácticas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nunca ejecutes SQL generado por IA sin validarlo.&lt;/strong&gt; Usa listas de operaciones permitidas (&lt;code&gt;SELECT&lt;/code&gt; solamente) y usuarios de base de datos de solo lectura.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;El contexto del esquema es clave.&lt;/strong&gt; Cuanto más claro y completo sea el esquema que le das al modelo, mejor será el SQL generado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Los agentes brillan en tareas multipaso&lt;/strong&gt;, pero cuestan más tokens y latencia que una llamada simple.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streamlit es la vía más rápida&lt;/strong&gt; para llevar un prototipo a manos de usuarios no técnicos.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>sql</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
