{"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\/de\/docs\/text-to-sql-example\/","title":{"rendered":"Text-zu-SQL-Beispiel"},"content":{"rendered":"<p>In diesem Tutorial werden wir sehen, wie man einen Agenten implementiert, der SQL mit&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>Beginnen wir mit der goldenen Frage: Warum sollte man es nicht einfach halten und eine standardm\u00e4\u00dfige Text-zu-SQL-Pipeline verwenden?<\/p>\n<\/blockquote>\n\n\n\n<p>Eine standardm\u00e4\u00dfige Text-zu-SQL-Pipeline ist br\u00fcchig, da die generierte SQL-Abfrage falsch sein kann. Noch schlimmer ist, dass die Abfrage zwar falsch sein kann, aber keinen Fehler ausl\u00f6st, sondern stattdessen einige falsche\/unbrauchbare Ausgaben liefert, ohne einen Alarm auszul\u00f6sen.<\/p>\n\n\n\n<p>Stattdessen ist ein Agentensystem in der Lage, die Ausgaben kritisch zu pr\u00fcfen und zu entscheiden, ob die Abfrage ge\u00e4ndert werden muss oder nicht, wodurch es einen enormen Leistungsschub erh\u00e4lt.<\/p>\n\n\n\n<p>Lasst uns diesen Agenten bauen! \ud83d\udcaa<\/p>\n\n\n\n<p>Zun\u00e4chst richten wir die SQL-Umgebung ein:<\/p>\n\n\n\n<p>Kopiert<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">from sqlalchemy importieren (\n    create_engine,\n    MetaData,\n    Tabelle,\n    Spalte,\n    String,\n    Ganzzahl,\n    Float,\n    einf\u00fcgen,\n    pr\u00fcfen,\n    Text,\n)\n\nengine = create_engine(\"sqlite:\/\/\/:memory:\")\nmetadata_obj = MetaData()\n\n<em># SQL-Tabelle Stadt erstellen<\/em>\ntable_name = \"Quittungen\"\nquittungen = Tabelle(\n    table_name,\n    metadata_obj,\n    Column(\"receipt_id\", Integer, primary_key=True),\n    Column(\"customer_name\", String(16), primary_key=True),\n    Column(\"price\", Float),\n    Spalte(\"Trinkgeld\", Float),\n)\nmetadata_obj.create_all(engine)\n\nrows = [\n    {\"receipt_id\": 1, \"customer_name\": \"Alan Payne\", \"price\": 12.06, \"tip\": 1.20},\n    {\"receipt_id\": 2, \"kunden_name\": \"Alex Mason\", \"preis\": 23.86, \"Trinkgeld\": 0.24},\n    {\"receipt_id\": 3, \"kunden_name\": \"Woodrow Wilson\", \"preis\": 53.43, \"Trinkgeld\": 5.43},\n    {\"receipt_id\": 4, \"kunden_name\": \"Margaret James\", \"preis\": 21.11, \"Trinkgeld\": 1.00},\n]\nfor row in rows:\n    stmt = insert(receipts).values(**row)\n    with engine.begin() as connection:\n        cursor = 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>Bauen Sie unseren Agenten<\/h3>\n\n\n\n<p>Lassen Sie uns nun unsere SQL-Tabelle mit einem Werkzeug abrufbar machen.<\/p>\n\n\n\n<p>Das Beschreibungsattribut des Werkzeugs wird vom Agentensystem in die Eingabeaufforderung des LLM eingebettet: es gibt dem LLM Informationen dar\u00fcber, wie das Werkzeug zu verwenden ist. An dieser Stelle wollen wir die SQL-Tabelle beschreiben.<\/p>\n\n\n\n<p>Kopiert<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">inspector = inspect(engine)\ncolumns_info = [(col[\"name\"], col[\"type\"]) for col in inspector.get_columns(\"receipts\")]\n\ntable_description = \"Columns:\\n\" + \"\\n\".join([f\" - {name}: {col_type}\" for name, col_type in columns_info])\nprint(table_description)<\/pre>\n\n\n\n<p>Kopiert<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Spalten:\n  - receipt_id: INTEGER\n  - kunden_name: VARCHAR(16)\n  - Preis: FLOAT\n  - Trinkgeld: FLOAT<\/pre>\n\n\n\n<p>Lassen Sie uns nun unser Werkzeug bauen. Es ben\u00f6tigt das Folgende: (lesen\u00a0<a href=\"https:\/\/huggingface.co\/docs\/smolagents\/tutorials\/tools\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">das Tool doc<\/a>\u00a0f\u00fcr mehr Details)<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ein Docstring mit einer\u00a0<code>Args:<\/code>\u00a0Teil Argumente auflisten.<\/li>\n\n\n\n<li>Tippen Sie Hinweise zu den Ein- und Ausg\u00e4ngen.<\/li>\n<\/ul>\n\n\n\n<p>Kopiert<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">von smolagents importieren Werkzeug\n\n@tool\ndef sql_engine(abfrage: str) -&gt; str:\n    \"\"\"\n    Erm\u00f6glicht die Durchf\u00fchrung von SQL-Abfragen auf die Tabelle. Gibt eine String-Repr\u00e4sentation des Ergebnisses zur\u00fcck.\n    Die Tabelle hat den Namen \"receipts\". Ihre Beschreibung lautet wie folgt:\n        Spalten:\n        - receipt_id: INTEGER\n        - kunden_name: VARCHAR(16)\n        - Preis: FLOAT\n        - Trinkgeld: FLOAT\n\n    Args:\n        Abfrage: Die auszuf\u00fchrende Abfrage. Dies sollte korrektes SQL sein.\n    \"\"\"\n    output = \"\"\n    mit engine.connect() as con:\n        rows = con.execute(text(query))\n        for row in rows:\n            output += \"\\n\" + str(row)\n    return output<\/pre>\n\n\n\n<p>Lassen Sie uns nun einen Agenten erstellen, der dieses Werkzeug nutzt.<\/p>\n\n\n\n<p>Wir verwenden die&nbsp;<code>CodeAgent<\/code>ist die Hauptagenten-Klasse von smolagents: ein Agent, der Aktionen in Code schreibt und auf der Grundlage des ReAct-Frameworks die vorherigen Ausgaben wiederholen kann.<\/p>\n\n\n\n<p>Das Modell ist die LLM, die das Agentensystem antreibt. Mit HfApiModel k\u00f6nnen Sie LLMs \u00fcber die Inferenz-API von HF aufrufen, entweder \u00fcber Serverless oder Dedicated Endpoint, aber Sie k\u00f6nnen auch eine beliebige propriet\u00e4re API verwenden.<\/p>\n\n\n\n<p>Kopiert<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">von smolagents importieren CodeAgent, HfApiModel\n\nagent = CodeAgent(\n    tools=[sql_engine],\n    model=HfApiModel(\"meta-llama\/Meta-Llama-3.1-8B-Instruct\"),\n)\nagent.run(\"K\u00f6nnen Sie mir den Namen des Kunden nennen, der die teuerste Quittung erhalten hat?\")<\/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>Ebene 2: Tabellenverkn\u00fcpfungen<\/h3>\n\n\n\n<p>Jetzt wollen wir es etwas anspruchsvoller machen! Wir wollen, dass unser Agent Joins \u00fcber mehrere Tabellen hinweg verarbeitet.<\/p>\n\n\n\n<p>Erstellen wir also eine zweite Tabelle, in der die Namen der Kellner f\u00fcr jede receipt_id gespeichert werden!<\/p>\n\n\n\n<p>Kopiert<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">table_name = \"kellner\"\nquittungen = Tabelle(\n    table_name,\n    metadata_obj,\n    Column(\"receipt_id\", Integer, primary_key=True),\n    Column(\"kellner_name\", String(16), primary_key=True),\n)\nmetadata_obj.create_all(engine)\n\nrows = [\n    {\"receipt_id\": 1, \"waiter_name\": \"Corey Johnson\"},\n    {\"receipt_id\": 2, \"kellner_name\": \"Michael Watts\"},\n    {\"receipt_id\": 3, \"kellner_name\": \"Michael Watts\"},\n    {\"receipt_id\": 4, \"kellner_name\": \"Margaret James\"},\n]\nfor row in rows:\n    stmt = insert(quittungen).werte(**zeile)\n    with engine.begin() as connection:\n        cursor = connection.execute(stmt)<\/pre>\n\n\n\n<p>Da wir die Tabelle ge\u00e4ndert haben, aktualisieren wir die&nbsp;<code>SQLExecutorTool<\/code>&nbsp;mit der Beschreibung dieser Tabelle, damit der LLM die Informationen aus dieser Tabelle richtig nutzen kann.<\/p>\n\n\n\n<p>Kopiert<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">updated_description = \"\"\"Erm\u00f6glicht die Ausf\u00fchrung von SQL-Abfragen f\u00fcr die Tabelle. Beachten Sie, dass die Ausgabe dieses Tools eine String-Darstellung der Ausf\u00fchrungsausgabe ist.\nEs kann die folgenden Tabellen verwenden:\"\"\"\n\ninspector = inspect(engine)\nfor table in [\"receipts\", \"waiters\"]:\n    columns_info = [(col[\"name\"], col[\"type\"]) for col in inspector.get_columns(table)]\n\n    table_description = f \"Tabelle '{table}':\\n\"\n\n    table_description += \"Spalten:\\n\" + \"\\n\".join([f\" - {name}: {col_type}\" for name, col_type in columns_info])\n    updated_description += \"\\n\\n\" + table_description\n\nprint(aktualisierte_Beschreibung)<\/pre>\n\n\n\n<p>Da diese Anfrage etwas schwieriger ist als die vorherige, werden wir die LLM-Engine so umstellen, dass sie die leistungsf\u00e4higere\u00a0<a href=\"https:\/\/huggingface.co\/Qwen\/Qwen2.5-Coder-32B-Instruct\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Qwen\/Qwen2.5-Coder-32B-Instruct<\/a>!<\/p>\n\n\n\n<p>Kopiert<\/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(\"Welcher Kellner hat insgesamt mehr Geld durch Trinkgeld eingenommen?\")<\/pre>\n\n\n\n<p>Es funktioniert direkt! Die Einrichtung war erstaunlich einfach, nicht wahr?<\/p>\n\n\n\n<p>Dieses Beispiel ist fertig! Wir haben uns mit diesen Konzepten besch\u00e4ftigt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bau neuer Werkzeuge.<\/li>\n\n\n\n<li>Aktualisierung der Beschreibung eines Werkzeugs.<\/li>\n\n\n\n<li>Der Wechsel zu einem st\u00e4rkeren LLM hilft dem Agenten bei seiner Argumentation.<\/li>\n<\/ul>\n\n\n\n<p>\u2705 Jetzt k\u00f6nnen Sie das Text-to-SQL-System aufbauen, von dem Sie schon immer getr\u00e4umt haben! \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":"4415","reactions":{"happy":"1","normal":"0","sad":"0"},"author_info":{"name":"smolagents","author_nicename":"wd-gstargmail-com","author_url":"https:\/\/smolagents.org\/de\/author\/wd-gstargmail-com\/"},"doc_category_info":[{"term_name":"Examples","term_url":"https:\/\/smolagents.org\/de\/docs-category\/examples\/"}],"doc_tag_info":[],"_links":{"self":[{"href":"https:\/\/smolagents.org\/de\/wp-json\/wp\/v2\/docs\/598","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/smolagents.org\/de\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/smolagents.org\/de\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/smolagents.org\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/smolagents.org\/de\/wp-json\/wp\/v2\/comments?post=598"}],"version-history":[{"count":1,"href":"https:\/\/smolagents.org\/de\/wp-json\/wp\/v2\/docs\/598\/revisions"}],"predecessor-version":[{"id":599,"href":"https:\/\/smolagents.org\/de\/wp-json\/wp\/v2\/docs\/598\/revisions\/599"}],"wp:attachment":[{"href":"https:\/\/smolagents.org\/de\/wp-json\/wp\/v2\/media?parent=598"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/smolagents.org\/de\/wp-json\/wp\/v2\/doc_category?post=598"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/smolagents.org\/de\/wp-json\/wp\/v2\/doc_tag?post=598"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}