アーキテクチャ

Text-to-SQLとは?LLMで自然言語からSQLを生成する仕組みと精度の実務ライン

Text-to-SQLとは?LLMで自然言語からSQLを生成する仕組みと精度の実務ライン

Text-to-SQL(Text2SQL)は、「先月の関東エリアの売上を店舗別に出して」といった自然言語の質問を、そのままデータベースへ投げられるSQLへ変換する技術です。LLMの登場で実用圏に入った一方、ベンチマークを丁寧に読むと、教科書的な課題では9割に届くのに実務のDWHへ近づけるほどスコアが崩れるという段差が見えてきます。ここでは仕組みとRAG連携、モデルとツールの選択肢、そして「効く施策・効かない施策」を、公開されている一次情報の数値に沿って整理します。

まとめ

  • Text-to-SQLは、自然言語の質問をスキーマ情報とともにLLMへ渡し、SQLを生成・実行して結果を返す仕組み。中核はモデルの賢さではなくスキーマリンキング(どの表・列を使うかの特定)。
  • 実データに近いBIRDベンチマークのSOTAは81.95%、人間のベースラインは92.96%(2026-07-13時点)。約11ポイントの差が残る。
  • 教科書的なSpider 1.0は飽和(86.6%)だが、企業DWH相当のSpider 2.0は2024年の初期ベースラインでo1-previewが17.1%。ベンチマークの9割を自社DBの期待値にしてはいけない。
  • 精度への寄与が最大なのは質問-SQLペアのRAG検索によるfew-shot。DAIL-SQLではSpider devの実行精度が例なし72.3%から5例82.4%へ伸びた。
  • 誤りを示さずLLMに自己レビューさせるだけの修正は精度を下げる(BIRDで相対-1.52%)。効くのは実行エラーを根拠として返すexecution feedback。
  • 安全設計の要は最小権限のread-onlyロールとDML禁止。LangChain公式も標準のDBツールを「本番利用を想定していない」と明記している。

Text-to-SQLの定義と、ベンチマークが示す精度の現在地

Text2SQLの定義と処理の流れ

Text-to-SQL(Text2SQL、T2SQL)とは、自然言語で書かれた質問文を、対象データベースの構造に沿った実行可能なSQLへ変換する技術を指します。処理は概ね4段階です。質問文を受け取り、対象DBのスキーマ(テーブル定義・列名・型・リレーション)から関連部分を絞り込み、質問とスキーマをプロンプトとしてLLMへ渡してSQLを生成し、実行して結果を返します。

この4段階のうち生成の品質を左右するのは、3つ目のLLM呼び出しではなく2つ目のスキーマ絞り込みです。数千列規模のDWHでは、正しい表を選べていない時点で、どれほど高性能なモデルでも正しいSQLは書けません。

BIRDのSOTAは81.95%、人間は92.96%

実世界のデータベースを模したベンチマークがBIRDです。95個のDB・計33.4GBという規模で、表記ゆれや欠損を含む「汚いデータ」をそのまま扱わせる点がSpiderとの違いです。2026-07-13時点の公式リーダーボードでは、テストセットの実行精度(EX)でAskData+GPT-4oが81.95%を記録して首位、Ant GroupのAgentar-Scale-SQLが81.67%、Sber Text2SQLが81.33%と続きます。

同じ指標で測った人間のベースラインは92.96%です。データエンジニアとDB専攻の学生が解いた結果に対し、最先端の手法でもまだ約11ポイント届いていません。BIRDは正しさだけでなく効率も見るR-VES(実行効率を加味したスコア)を併用しており、動くが遅いSQLも減点されます。

Spider 1.0は飽和、Spider 2.0では初期ベースラインが17.1%

ベンチマークの数字を引用するときに最も事故りやすいのがここです。教科書的なSpider 1.0では、DAIL-SQL(GPT-4)にself-consistencyを併用した構成がtestセットで86.6%に達し、すでに飽和しています。一方、企業のDWHを想定して作られたSpider 2.0では、2024年の論文が報告した初期ベースラインでGPT-4oが10.1%、o1-previewでも17.1%まで崩れました。

差を生むのは規模と現実性です。Spider 2.0は3,000列を超えるスキーマ、BigQuery・Snowflake・DuckDB・PostgreSQLなど複数の方言、ネストした実務クエリを含みます。その後のエージェント型手法によって公式リーダーボードのSpider 2.0-Liteでは73%台の報告も出ていますが、上位エントリはベンダーの自己申告で第三者検証を経ておらず、査読論文の水準とは開きがあります。

実務として押さえる結論はひとつです。「Text-to-SQLはもう9割の精度がある」はSpider 1.0の話であり、自社の本番DWHへ当てはめてはいけない。導入時の期待値は、汚いデータを含むBIRDと、大規模スキーマのSpider 2.0の側で見積もってください。

LLMが自然言語をSQLへ変換する仕組みとモデル選定

汎用LLMで組むか、Text-to-SQL特化モデルを使うか

実装方針は大きく2つに分かれます。ひとつはIn-Context Learning(ICL)で、GPT-4oやClaudeのような汎用LLMへスキーマと例をプロンプトで与え、都度SQLを書かせる方式です。もうひとつがファインチューニングで、Text-to-SQLに特化して学習させたモデルを使います。

汎用LLMのICLは、学習データを用意せずに始められ、スキーマ変更にも即応できます。BIRDリーダーボードの上位が依然としてGPT-4o系を土台にしているとおり、到達点も高い水準です。弱点はコストと機密性で、質問1件ごとに数千から数万トークンのスキーマを送るためレイテンシと課金が積み上がり、スキーマそのものを外部APIへ渡す構成になります。API選定や学習除外設定など外部APIへデータを渡す際の確認点は、自然言語処理APIの比較と実装組み込み手順で整理しています。

特化モデルはこの裏返しです。XiYanSQL-QwenCoderは32BというサイズでBIRDのtestセットに69.03%を記録しており、自社環境で動かせる規模でも実用圏に届くことを示しています。オンプレミスで完結させたい、あるいは大量のクエリを捌いて単価を抑えたいなら現実的な選択肢になります。まず汎用LLMのICLでプロトタイプを作り、コストか機密要件が壁になった時点で特化モデルへ移すのが、遠回りの少ない順序です。

プロンプトに何を入れるかで精度が決まる

LLMベースのText-to-SQLで実際にモデルへ渡すものは、質問文だけではありません。最低限、対象テーブルのDDL(CREATE TABLE文)、列の意味を補う説明、そして値のサンプルが要ります。値のサンプルが必要なのは、「関東エリア」という質問語が実データでは region = 'KANTO' なのか area_cd = '13' なのかを、モデルが知り得ないからです。BIRDが難しいのは、まさにこの語彙のギャップを含むためです。

方言の指定も精度を左右します。同じ「先月」でもBigQueryでは DATE_SUB、Snowflakeでは DATEADD と書き分ける必要があり、方言を明示しないプロンプトは構文エラーを量産します。

スキーマリンキングがボトルネックになる理由

研究側でも、スキーマリンキングは大規模・マルチDB環境へ適用する際の重大なボトルネックだと指摘されています(LinkAlign, arXiv:2503.18596)。問題は2つに分かれます。多数のDBから対象DBを選ぶ検索の問題と、冗長なスキーマの中から正しい表・列を特定するグラウンディングの問題です。

精度を追うとコストが跳ねる点にも注意が要ります。第三者がBIRD devで高精度手法CHESSを計測した報告(Rethinking Schema Linking, arXiv:2510.14296)では、スキーマリンキングのrecallが97.12%に達する一方、偽陽性率は30.57%、1リクエストあたり平均78回のLLM呼び出しと約339,965トークンを消費しています。関連しない表を掴む偽陽性は、存在しない列名を生成する幻覚の温床にもなります。誤答そのものを減らす一般的な打ち手はAIハルシネーション対策|プロンプト・RAG・検出APIで誤答を減らす実装手順で整理しています。

RAGと組み合わせるText-to-SQL

スキーマRAG:関連するテーブルだけをプロンプトへ入れる

数千列のスキーマを丸ごとプロンプトへ詰めるのは、コンテキスト長の面でも精度の面でも成立しません。そこで、テーブル定義や列コメントをベクトル化して保存し、質問文で検索して上位の表だけをプロンプトへ渡します。これがスキーマRAGです。RAG全般の検索戦略や複数ソースの統合についてはOmniRAGとは?基本概念と従来のRAGとの違いが参考になります。

検索はベクトル類似度だけに頼らず、列名の完全一致を拾うキーワード検索と併用したほうが安定します。両者のランキングを統合する手法としてはRRFが定番で、仕組みとスコア計算はRRF(Reciprocal Rank Fusion)とは?RAG-Fusionでの仕組み・スコア計算・実装を解説で解説しています。

few-shot例のRAG検索が効く:72.3%が82.4%になる

Text-to-SQLで費用対効果が最も高い施策は、過去の「質問とSQLのペア」を蓄積し、新しい質問に似た例をベクトル検索で引いて動的にプロンプトへ差し込むことです。DAIL-SQL(arXiv:2308.15363)がGPT-4で測ったSpider devの実行精度(EX)は次のとおりです。

プロンプト構成 実行精度(EX)
Zero-shot(例なし) 72.3%
ランダム1例 77.4%
質問類似度で1例選択 78.8%
DAIL Selection(質問類似+SQL構造類似)1例 80.2%
ランダム5例 79.5%
DAIL Selection 5例 82.4%

読み取るべき点は2つあります。例を1つ入れるだけで72.3%から77.4%へ上がること、そして選び方を工夫した5例(82.4%)がランダム5例(79.5%)を2.9ポイント上回ることです。例を入れる効果と、似た例を選ぶ検索の質は別々に効きます。運用では、承認済みの質問-SQLペアをリポジトリとして育てるのが最短ルートです。後述する人手レビューを通したSQLがそのまま資産になるため、検証工程と例文の蓄積は同じ導線に載せられます。

テキストからSQLを生成する手段の選び方

まず試す:DDLを貼って動かす最小プロンプト

ツールを比較検討する前に、手元のスキーマで精度の当たりを付けるのが先です。最小構成は「方言の指定・DDL・値のサンプル・出力形式の制約・質問」の5点で、汎用LLMのチャット画面にそのまま貼れます。

あなたはPostgreSQLのアナリストです。以下のスキーマだけを使い、SELECT文を1つだけ出力してください。
説明文は不要です。スキーマに無い列は使わないでください。

# スキーマ
CREATE TABLE stores (
  store_id   INT PRIMARY KEY,
  store_name TEXT,
  area_cd    TEXT   -- '13'=東京, '14'=神奈川, '11'=埼玉, '12'=千葉
);
CREATE TABLE sales (
  sale_id    INT PRIMARY KEY,
  store_id   INT REFERENCES stores(store_id),
  sold_at    DATE,
  amount     NUMERIC
);

# 質問
先月の関東エリアの売上を店舗別に合計し、多い順に出してください。

ポイントは、列コメントで area_cd のコード値を明かしている点です。この1行が無いと、モデルは「関東」を文字列比較しようとして空の結果を返します。この雛形で自社の代表的な質問を20件ほど流し、どこで外れるかを見てから、ツール選定に進んでください。

マネージドサービス:Cortex Analyst・Genie・BigQuery data canvas

すでにDWHが決まっているなら、自社基盤の機能から評価するのが早道です。Snowflake Cortex Analystはセマンティックモデルで列の意味と同義語を定義させる方式で、2024年8月のエンジニアリングブログでは90%超の精度、単発プロンプトのGPT-4o比で約2倍と説明されています。定義方法は従来のYAMLに加え、ネイティブオブジェクトのSemantic Viewsが推奨に変わりました。DatabricksのAI/BI Genieは2025-06-12にGAとなり、Unity Catalogのメトリクスや列レベルの同義語定義で精度を担保します。BigQueryはdata canvasが自然言語からのSQL生成に対応していますが、Geminiによるチャットアシスタント部分はプレビュー扱いです(2026-07-13時点)。

マネージド側に共通するのは、精度の源泉がモデルではなくセマンティックレイヤ(列の意味・同義語・結合関係の人手定義)だという点です。裏返せば、この定義作業を省くとどのサービスを選んでも精度は出ません。

OSS・自前実装:Vannaはアーカイブ済み、LangChainはcreate_agentへ

RAGベースのOSSとして広く知られるVanna(vanna-ai/vanna、MIT、約23,800スター)は、GitHubリポジトリがアーカイブ済み(read-only)です。エージェント型へ全面的に書き直したVanna 2.0を出した直後にリポジトリごとアーカイブされており、維持されている後継リポジトリはありません(アーカイブは2026-03-29、最終リリースはv2.0.2/2026-02-02)。DDL・ドキュメント・過去SQLをベクトル化して学習させるという設計思想は今も有効ですが、活発にメンテされるOSSとして選定すると保守で行き詰まります。

LangChainで自作する場合も、記事でよく見る SQLDatabaseChain や create_sql_agent は現行の公式チュートリアルに登場しません。公式のSQL agentページは create_agent でエージェントを組み、SQL操作は自前のツール関数として定義する形に移行しています。基盤となるLangGraphとの関係はLangChainとLangGraphの違い|v1.0で逆転した関係と使い分けで整理しています。現行の骨格は次のようになります。

import sqlite3
from langchain.agents import create_agent
from langchain.tools import tool

conn = sqlite3.connect("analytics.db", check_same_thread=False)

@tool
def list_tables() -> str:
    """利用可能なテーブル名の一覧を返す。"""
    rows = conn.execute(
        "SELECT name FROM sqlite_master WHERE type='table'"
    ).fetchall()
    return ", ".join(r[0] for r in rows)

@tool
def get_schema(table: str) -> str:
    """指定テーブルのDDLを返す。"""
    row = conn.execute(
        "SELECT sql FROM sqlite_master WHERE type='table' AND name=?", (table,)
    ).fetchone()
    return row[0] if row else "not found"

@tool
def run_query(query: str) -> str:
    """SELECT文を実行して結果を返す。SELECT以外は拒否する。"""
    if not query.lstrip().upper().startswith("SELECT"):
        return "error: SELECT statements only"
    return str(conn.execute(query).fetchmany(50))

SYSTEM = """あなたは読み取り専用のSQLアナリストです。
まずテーブル一覧とスキーマを確認し、確認できた列だけを使ってSELECT文を組み立てます。
INSERT, UPDATE, DELETE, DROP などの更新系ステートメントは決して実行しないこと。
実行がエラーになった場合は、エラーメッセージを読んでクエリを修正し、再実行すること。"""

agent = create_agent(
    model="claude-sonnet-5",
    tools=[list_tables, get_schema, run_query],
    system_prompt=SYSTEM,
)

公式ドキュメントは、チュートリアルで提示するDBツール群について「デモ用の最小ラッパーであり、セキュアでも本番利用向けでもない」と明記しています。上の run_query にある文字列レベルのSELECT判定も同じ水準で、本番では後述するパーサによる検証層へ置き換える前提です。

精度が上がらないときの切り分け:効く施策と、逆効果になる施策

誤りを示さない自己修正は、精度を下げる

「生成したSQLをもう一度LLMに見直させれば精度が上がる」という説明をよく見かけますが、これは条件付きで誤りです。誤りの所在を示さずブラックボックスに再考させる素朴な自己修正(vanilla self-correction)は、BIRDとSpiderの双方で精度を落とします。GPT-4oを使った報告(ErrorLLM, arXiv:2603.03742)ではBIRDが55.87%から55.02%へ、相対で1.52%の低下でした。モデルは自分の誤りに気づけず、幻覚を上書きして累積させるためです。

効くのは根拠を与える修正です。生成したSQLを実際に実行し、構文エラーや存在しない列のエラーをそのままモデルへ返して再生成させるexecution feedbackでは、LLaMA-3.1 70Bに反復DPOを組み合わせたExCoT(arXiv:2503.19988)がBIRDでdev 68.51%/test 68.53%を報告しています。伸びは1回目の修正が最も大きく、以降は逓減します。同じErrorLLMの報告でも、誤り箇所を明示するプロンプトを与えた自己修正はBIRDで改善に転じており、境目は「誤りの根拠を渡しているかどうか」にあります。自己レビューのループを増やす前に、実行してエラーを食わせる経路を1本作るほうが確実です。存在しない列名の幻覚は実行すれば必ずエラーとして落ちるため、実行こそ最も安価な検出器になります。

self-consistency(複数生成して多数決)の寄与は小さい

複数のSQLを生成して投票させるself-consistencyは、DAIL-SQL(GPT-4)のSpider testで86.2%から86.6%へ、0.4ポイントの上乗せにとどまります。生成回数に比例してコストとレイテンシは増える一方、得られる精度は誤差レベルです。予算をかけるなら、多数決よりfew-shot例の検索精度とスキーマ定義の整備に回してください。

マルチテーブル結合が壊れるときに疑う場所

複数テーブルの結合を含む質問で誤りが集中するのは、モデルの推論力ではなく結合関係の情報がプロンプトに届いていないケースがほとんどです。外部キー制約が張られていないDWHでは、モデルは結合キーを名前の類似から推測するしかありません。user_id と customer_id が同じ実体を指すことは、明示しなければ伝わらないのです。対処は、主キー・外部キーと典型的な結合パスをスキーマの説明文としてプロンプトへ渡すこと、そして頻出する結合パターンをfew-shot例として登録することの2点です。

本番導入で外してはいけない安全設計

最小権限のread-onlyロールとDML禁止

Text-to-SQLは、LLMが生成した文字列をそのままデータベースで実行する仕組みです。プロンプトインジェクションで DROP TABLE を生成させられる可能性は常に残ります。LangChain公式も「エージェントのDB接続権限は、必要最小限の範囲へ常にスコープを絞ること」と警告しています。

実務では、アプリケーション用の接続ユーザーとは別に、対象スキーマへのSELECT権限だけを持つ専用ロールを切ってText-to-SQL専用に割り当てます。権限そのもので封じるのが第一で、システムプロンプトでのDML禁止指示は二重化の保険と位置づけてください。プロンプトは破られますが、権限は破られません。

生成SQLの静的検証と人手承認

実行前に生成SQLをパースし、構文木のレベルで検証する層を挟むと、権限とは別の角度で事故を止められます。SELECT以外のステートメントの拒否、参照先テーブルのallowlist照合、LIMIT句の強制付与といった検査は、正規表現ではなくパーサで行うのが安全です。PythonであればSQLGlotが方言を跨いだパースと変換に対応しており、使い方はSQLGlotとは?Python製SQLパーサの使い方・インストール・方言変換(transpile)を徹底解説にまとめています。

そのうえで、影響範囲の大きいクエリは実行前に人が承認する経路を残します。LangChain公式もSQL agentの発展手順として、実行前に人間の確認を挟むHuman-in-the-loopのミドルウェアを任意で追加する構成を示しています。自社DWHでの精度はBIRDの81.95%を下回る前提に立ち、全社の非エンジニアへ開放する前に、まずアナリストの下書き支援として入れるのが現実的な着地点です。承認の過程で確定したSQLは、そのままfew-shot例のリポジトリへ積み上がっていきます。

スキーマを外部LLMへ渡すことの是非

見落とされがちですが、Text-to-SQLは質問だけでなくスキーマ定義そのものを毎回LLMへ送る技術です。テーブル名や列名は事業構造を映すため、外部APIへ渡す時点で機微情報の外部送信にあたる場合があります。値のサンプルをプロンプトへ含める運用なら、実データの一部を送っていることにもなります。

判断の分かれ目は、送るのがスキーマだけか実データを含むかです。値のサンプルが精度に効くのは前述のとおりですが、機微な列ではマスクした代表値や列コメントによる説明で代替できます。それでも要件を満たせないなら、XiYanSQL-QwenCoderのような特化モデルを自社環境で動かす構成に切り替えるのが筋です。

よくある質問

Text-to-SQLとText2SQLは違うものですか?

同じ技術を指します。論文ではText-to-SQL、実装コミュニティではText2SQLやT2SQLと略されることが多いだけで、意味の違いはありません。

Text-to-SQLの精度はどのくらい信頼できますか?

実データに近いBIRDのSOTAで81.95%、人間は92.96%です(2026-07-13時点)。ただしこれは専用にチューニングされたシステムの上限値で、企業DWH相当のSpider 2.0では2024年時点の初期ベースラインが17.1%でした。自社環境では81.95%を下回る前提に立ち、結果を検証する工程を必ず残してください。

RAGはText-to-SQLのどこで使うのですか?

2箇所です。ひとつは巨大なスキーマから関連テーブルだけを引くスキーマ検索、もうひとつは過去の質問-SQLペアから似た例を引いてfew-shotに使う例文検索です。精度への寄与が大きいのは後者で、DAIL-SQLではSpider devの実行精度が例なし72.3%から5例で82.4%へ伸びました。

生成されたSQLが存在しない列名を使ってしまいます。どう防ぎますか?

プロンプトへ渡すスキーマの絞り込みが外れているサインです。まず実行してエラーをモデルへ返す経路を作り、そのうえで列コメントや値のサンプルを追加して検索の当たりを改善します。誤り箇所を示さずLLMに自己レビューさせるだけの修正は、かえって精度を下げるため避けてください。

VannaやLangChainのサンプルコードがそのまま動きません。

情報が古い可能性が高いです。Vannaのリポジトリは2.0のリリース後にアーカイブされ、read-onlyになっています。LangChainも公式チュートリアルが create_sql_agent から create_agent ベースへ移行しており、旧APIを前提とした記事のコードは現行版と一致しません。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.08 テックブログ 大阪公立大学のランサムウェア被害と仮想化基盤の停止|全授業休講に至った経緯とバックアップを守る設定
  2. 2026.10.06 テックブログ アフラックの情報漏洩440万人|大量照会を止められなかった原因と照会量制御の実装
  3. 2026.10.07 テックブログ 旭化成ファーマのサイバー攻撃:Pharma DIGITAL会員51.4万人の漏えいと委託先DBの監視設計
  4. 2026.10.06 テックブログ 焼肉きんぐの不正アクセスと1,078万件の会員情報|全件規模の流出を防ぐAPIとログの点検
  5. 2024.06.11 コラム 個人情報漏えい件数の推移をグラフで解説|最新データと過去最多(約1.9万件)

RELATED POSTS 関連記事

目次