{"id":598,"date":"2025-01-11T15:28:59","date_gmt":"2025-01-11T15:28:59","guid":{"rendered":"https:\/\/smolagents.org\/?post_type=docs&#038;p=598"},"modified":"2025-01-11T15:40:54","modified_gmt":"2025-01-11T15:40:54","password":"","slug":"text-to-sql-example","status":"publish","type":"docs","link":"https:\/\/smolagents.org\/it\/docs\/text-to-sql-example\/","title":{"rendered":"Esempio di passaggio da testo a SQL"},"content":{"rendered":"<p>In questa esercitazione, vedremo come implementare un agente che sfrutta SQL utilizzando&nbsp;<code>smolagents<\/code>.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Cominciamo con la domanda d'oro: perch\u00e9 non mantenere le cose semplici e utilizzare una pipeline standard da testo a SQL?<\/p>\n<\/blockquote>\n\n\n\n<p>Una pipeline standard da testo a sql \u00e8 fragile, poich\u00e9 la query SQL generata pu\u00f2 essere errata. Ancor peggio, la query potrebbe essere errata, ma non generare un errore, fornendo invece alcuni output errati\/inutili senza dare l'allarme.<\/p>\n\n\n\n<p>\ud83d\udc49 Invece, un sistema ad agenti \u00e8 in grado di ispezionare criticamente gli output e decidere se la query deve essere modificata o meno, ottenendo cos\u00ec un enorme aumento delle prestazioni.<\/p>\n\n\n\n<p>Costruiamo questo agente! \ud83d\udcaa<\/p>\n\n\n\n<p>Per prima cosa, configuriamo l'ambiente SQL:<\/p>\n\n\n\n<p>Copiato<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">da sqlalchemy import (\n    create_engine,\n    MetaDati,\n    Tabella,\n    Colonna,\n    Stringa,\n    intero,\n    variabile,\n    inserire,\n    ispezionare,\n    testo,\n)\n\nmotore = create_engine(\"sqlite:\/\/\/:memory:\")\nmetadata_obj = MetaData()\n\n<em># creare tabella SQL citt\u00e0<\/em>\nnome_tabella = \"ricevute\"\nricevute = Tabella(\n    nome_tabella,\n    metadata_obj,\n    Colonna(\"receipt_id\", Integer, primary_key=True),\n    Colonna(\"nome_cliente\", String(16), primary_key=True),\n    Colonna(\"prezzo\", Float),\n    Colonna(\"mancia\", Float),\n)\nmetadata_obj.create_all(engine)\n\nrighe = [\n    {\"receipt_id\": 1, \"nome_cliente\": \"Alan Payne\", \"prezzo\": 12,06, \"mancia\": 1.20},\n    {\"receipt_id\": 2, \"nome_cliente\": \"Alex Mason\", \"prezzo\": 23,86, \"mancia\": 0.24},\n    {\"receipt_id\": 3, \"nome_cliente\": \"Woodrow Wilson\", \"prezzo\": 53,43, \"mancia\": 5.43},\n    {\"receipt_id\": 4, \"nome_cliente\": \"Margaret James\", \"prezzo\": 21,11, \"mancia\": 1.00},\n]\nper riga in righe:\n    stmt = insert(receipts).values(**row)\n    con engine.begin() as connection:\n        cursore = connection.execute(stmt)<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/huggingface.co\/docs\/smolagents\/examples\/text_to_sql#build-our-agent\" target=\"_blank\" rel=\"noopener\"><\/a>Costruire il nostro agente<\/h3>\n\n\n\n<p>Ora rendiamo la nostra tabella SQL richiamabile da uno strumento.<\/p>\n\n\n\n<p>L'attributo description dello strumento sar\u00e0 incorporato dal sistema agente nel prompt dell'LLM: fornisce all'LLM informazioni su come utilizzare lo strumento. Qui si vuole descrivere la tabella SQL.<\/p>\n\n\n\n<p>Copiato<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">inspector = inspect(engine)\ncolumns_info = [(col[\"nome\"], col[\"tipo\"]) for col in inspector.get_columns(\"receipts\")]\n\ntable_description = \"Colonne:\\n\" + \"\\n\".join([f\" - {nome}: {col_tipo}\" per nome, col_tipo in columns_info])\nprint(descrizione_tabella)<\/pre>\n\n\n\n<p>Copiato<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Colonne:\n  - receipt_id: INTEGER\n  - nome_cliente: VARCHAR(16)\n  - prezzo: VARIABILE\n  - mancia: VARIABILE<\/pre>\n\n\n\n<p>Ora costruiamo il nostro strumento. Ha bisogno di quanto segue: (leggi\u00a0<a href=\"https:\/\/huggingface.co\/docs\/smolagents\/tutorials\/tools\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">lo strumento doc<\/a>\u00a0per maggiori dettagli)<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Una stringa di documenti con un elemento\u00a0<code>Args:<\/code>\u00a0parte che elenca gli argomenti.<\/li>\n\n\n\n<li>Suggerimenti di tipo su entrambi gli ingressi e le uscite.<\/li>\n<\/ul>\n\n\n\n<p>Copiato<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">da smolagents importiamo lo strumento\n\n@strumento\ndef sql_engine(query: str) -&gt; str:\n    \"\"\"\n    Consente di eseguire query SQL sulla tabella. Restituisce una rappresentazione in stringa del risultato.\n    La tabella si chiama \"ricevute\". La sua descrizione \u00e8 la seguente:\n        Colonne:\n        - receipt_id: INTEGER\n        - nome_cliente: VARCHAR(16)\n        - prezzo: VARIABILE\n        - mancia: VARIABILE\n\n    Args:\n        query: La query da eseguire. Dovrebbe essere un SQL corretto.\n    \"\"\"\n    output = \"\"\n    con engine.connect() as con:\n        rows = con.execute(text(query))\n        per riga in righe:\n            output += \"\\n\" + str(row)\n    restituire l'output<\/pre>\n\n\n\n<p>Ora creiamo un agente che sfrutti questo strumento.<\/p>\n\n\n\n<p>Utilizziamo il&nbsp;<code>CodiceAgente<\/code>che \u00e8 la classe agente principale di smolagents: un agente che scrive azioni in codice e pu\u00f2 iterare sui risultati precedenti secondo il framework ReAct.<\/p>\n\n\n\n<p>Il modello \u00e8 l'LLM che alimenta il sistema di agenti. HfApiModel consente di chiamare gli LLM utilizzando l'API di inferenza di HF, tramite endpoint Serverless o Dedicated, ma si pu\u00f2 anche utilizzare qualsiasi API proprietaria.<\/p>\n\n\n\n<p>Copiato<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">da smolagents import CodeAgent, HfApiModel\n\nagent = CodeAgent(\n    tools=[sql_engine],\n    model=HfApiModel(\"meta-llama\/Meta-Llama-3.1-8B-Instruct\"),\n)\nagent.run(\"Pu\u00f2 darmi il nome del cliente che ha ricevuto la ricevuta pi\u00f9 costosa?\")<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/huggingface.co\/docs\/smolagents\/examples\/text_to_sql#level-2-table-joins\" target=\"_blank\" rel=\"noopener\"><\/a>Livello 2: join di tabelle<\/h3>\n\n\n\n<p>Ora rendiamolo pi\u00f9 impegnativo! Vogliamo che il nostro agente gestisca le giunzioni tra pi\u00f9 tabelle.<\/p>\n\n\n\n<p>Creiamo quindi una seconda tabella che registra i nomi dei camerieri per ogni ID scontrino!<\/p>\n\n\n\n<p>Copiato<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">nome_tabella = \"camerieri\"\nricevute = Tabella(\n    nome_tavola,\n    metadata_obj,\n    Colonna(\"receipt_id\", Integer, primary_key=True),\n    Colonna(\"nome_cameriere\", String(16), primary_key=True),\n)\nmetadata_obj.create_all(engine)\n\nrighe = [\n    {\"receipt_id\": 1, \"nome_cameriere\": \"Corey Johnson\"},\n    {\"receipt_id\": 2, \"nome del cameriere\": \"Michael Watts\",}\n    {\"receipt_id\": 3, \"nome del cameriere\": \"Michael Watts\"},\n    {\"receipt_id\": 4, \"nome del cameriere\": \"Margaret James\"},\n]\nper riga in righe:\n    stmt = insert(receipts).values(**row)\n    con engine.begin() as connection:\n        cursore = connection.execute(stmt)<\/pre>\n\n\n\n<p>Dal momento che abbiamo cambiato la tabella, aggiorniamo il file&nbsp;<code>Strumento SQLExecutor<\/code>&nbsp;con la descrizione di questa tabella, per consentire all'LLM di sfruttare correttamente le informazioni di questa tabella.<\/p>\n\n\n\n<p>Copiato<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">updated_description = \"\"\"Consente di eseguire query SQL sulla tabella. Si noti che l'output di questo strumento \u00e8 una rappresentazione in stringa dell'output dell'esecuzione.\nPu\u00f2 utilizzare le seguenti tabelle:\"\"\"\n\ninspector = inspect(engine)\nfor table in [\"receipts\", \"waiters\"]:\n    columns_info = [(col[\"nome\"], col[\"tipo\"]) for col in inspector.get_columns(table)]\n\n    table_description = f \"Tabella '{tabella}':\\n\"\n\n    table_description += \"Colonne:\\n\" + \"\\n\".join([f\" - {nome}: {col_tipo}\" per nome, col_tipo in columns_info])\n    updated_description += \"\\n\\n\" + table_description\n\nprint(descrizione_aggiornata)<\/pre>\n\n\n\n<p>Poich\u00e9 questa richiesta \u00e8 un po' pi\u00f9 difficile della precedente, si cambier\u00e0 il motore LLM per usare il pi\u00f9 potente\u00a0<a href=\"https:\/\/huggingface.co\/Qwen\/Qwen2.5-Coder-32B-Instruct\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Qwen\/Qwen2.5-Coder-32B-Istruzione<\/a>!<\/p>\n\n\n\n<p>Copiato<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sql_engine.description = updated_description\n\nagent = CodeAgent(\n    tools=[sql_engine],\n    model=HfApiModel(\"Qwen\/Qwen2.5-Coder-32B-Instruct\"),\n)\n\nagent.run(\"Quale cameriere ha ottenuto pi\u00f9 soldi in totale dalle mance?\")<\/pre>\n\n\n\n<p>Funziona direttamente! La configurazione \u00e8 stata sorprendentemente semplice, non \u00e8 vero?<\/p>\n\n\n\n<p>Questo esempio \u00e8 finito! Abbiamo toccato questi concetti:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Costruire nuovi strumenti.<\/li>\n\n\n\n<li>Aggiornamento della descrizione di uno strumento.<\/li>\n\n\n\n<li>Il passaggio a un LLM pi\u00f9 forte aiuta il ragionamento dell'agente.<\/li>\n<\/ul>\n\n\n\n<p>Ora potete costruire il sistema text-to-SQL che avete sempre sognato! \u2728<\/p>","protected":false},"excerpt":{"rendered":"<p>In this tutorial, we\u2019ll see how to implement an agent that leverages SQL using&nbsp;smolagents. Let\u2019s start with the golden question: why not keep it simple and use a standard text-to-SQL pipeline? A standard text-to-sql pipeline is brittle, since the generated SQL query can be incorrect. Even worse, the query could be incorrect, but not raise&#8230;<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"_kadence_starter_templates_imported_post":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"doc_category":[10],"doc_tag":[],"class_list":["post-598","docs","type-docs","status-publish","hentry","doc_category-examples"],"year_month":"2026-04","word_count":879,"total_views":"4412","reactions":{"happy":"1","normal":"0","sad":"0"},"author_info":{"name":"smolagents","author_nicename":"wd-gstargmail-com","author_url":"https:\/\/smolagents.org\/it\/author\/wd-gstargmail-com\/"},"doc_category_info":[{"term_name":"Examples","term_url":"https:\/\/smolagents.org\/it\/docs-category\/examples\/"}],"doc_tag_info":[],"_links":{"self":[{"href":"https:\/\/smolagents.org\/it\/wp-json\/wp\/v2\/docs\/598","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/smolagents.org\/it\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/smolagents.org\/it\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/smolagents.org\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/smolagents.org\/it\/wp-json\/wp\/v2\/comments?post=598"}],"version-history":[{"count":1,"href":"https:\/\/smolagents.org\/it\/wp-json\/wp\/v2\/docs\/598\/revisions"}],"predecessor-version":[{"id":599,"href":"https:\/\/smolagents.org\/it\/wp-json\/wp\/v2\/docs\/598\/revisions\/599"}],"wp:attachment":[{"href":"https:\/\/smolagents.org\/it\/wp-json\/wp\/v2\/media?parent=598"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/smolagents.org\/it\/wp-json\/wp\/v2\/doc_category?post=598"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/smolagents.org\/it\/wp-json\/wp\/v2\/doc_tag?post=598"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}