【ITニュース解説】I Tried to Make Natural Language a SQL Predicate. The Numbers Said No.
2026年10月01日に「Dev.to」が公開したITニュース「I Tried to Make Natural Language a SQL Predicate. The Numbers Said No.」について初心者にもわかりやすく解説しています。
ITニュース概要
SQLのWHERE句に「顧客が返金を求めている」のような自然言語の条件を直接記述できるか検証するプロトタイプ「SemPred」が開発された。非構造化テキストを意味で検索する仕組みだが、目標とした精度とカバー率を同時に達成できなかった。現行アーキテクチャでの実用化は困難と判断し、今後はモデルの入力方法変更など改善を検討する。
ITニュース解説
このニュース記事は、データベースのSQLクエリで日常の言葉(自然言語)を直接検索条件として使えないか、という斬新なアイデアとその実験について述べている。通常、データベースで情報を検索する際には、「金額が1000より大きい」や「通貨がUSDである」といった、あらかじめ決められた形式(構造化された条件)を用いる。しかし、顧客からの問い合わせ内容のような、決まった形式に当てはまらない「テキストデータ」は多く、これらを効率的に検索することは難しいという課題があった。
記事の筆者は、顧客サポートのチケット管理を例に挙げ、「顧客が返金を求めているチケットを見つける」といった条件をSQLで直接書きたいと考えた。これまでの方法としては、チケットのテキストから特定のキーワードを探す、事前にチケットを分類しておく、あるいは最近注目されている大規模言語モデル(LLM)を使って一つずつ判断するといった方法がある。しかし、キーワード検索には限界があり、LLMを多数のデータに適用すると、費用がかさみ、処理速度も遅くなるといった問題が生じる。そこで筆者は、自然言語による条件を、データベースが通常の検索条件と同じように扱える「第四の選択肢」を模索した。
この新しい試みは「SemPred」と名付けられ、主に二つの関数から構成されている。一つはSEM_SCOREで、与えられたテキストが指定された自然言語の条件にどれだけ合致するかを数値(スコア)で示す。もう一つはSEM_PREDICTで、テキストがその条件を満たすか(TRUE)、満たさないか(FALSE)、または判断できないか(UNKNOWN)を返す。特に「UNKNOWN」という三番目の状態があることが重要だ。これは、モデルが自信を持てない場合に無理に回答せず、「わからない」と明確に伝えることで、誤った情報を提供してしまうリスクを減らすための工夫である。SQLでは、このUNKNOWNがNULLとして扱われるため、データベースシステムに自然に組み込める。
SemPredの最初のバージョンは、いくつかの厳しい制約のもとに開発された。例えば、データの行ごとに外部のサービスに問い合わせるような高コストな処理は避ける。代わりに、一度にまとめて複数のデータを処理する「バッチ処理」を採用する。また、テキストデータを「埋め込み」と呼ばれる数値の並び(ベクトル)に変換し、この埋め込みは一度作れば繰り返し使えるようにした。この埋め込みを作る部分(エンコーダー)は学習させずに固定しておき、各自然言語条件(述語)ごとに、その埋め込みを受け取って判定する小さなモデル(ヘッド)を用意した。同じテキストが何度も登場する場合に備え、一度計算した埋め込みはキャッシュしておき、再利用する仕組みも取り入れている。
データベースのDuckDBと連携する際も、効率が重視された。Pythonで実装されたモデルとDuckDBの間でデータをやり取りする際には、一度に複数のデータをまとめて送受信するArrow UDFという経路を使うことで、大量のデータでも高速に処理できるようにした。もし一つずつデータをやり取りすると、データが増えるにつれて処理が非常に遅くなるからだ。
SemPredのもう一つの特徴的な機能が「棄権(abstention)」である。これは、モデルが出したスコアが、TRUEかFALSEかを判断する境界線(閾値)の近くにある場合に、「UNKNOWN」と判断して回答を保留する仕組みだ。例えば、0.5を閾値とし、0.1の範囲(0.4から0.6)を棄権ゾーンと設定すると、スコアが0.4未満ならFALSE、0.6以上ならTRUE、その間ならUNKNOWNと判断する。これにより、モデルが自信のない判断を下すことを避け、結果として高い精度を保つことを目指した。
筆者は、このシステムが実際にどれほどの性能を発揮するかを評価するため、Banking77という顧客問い合わせのカテゴリ分類データセットを使ってベンチマーク(性能測定)を行った。各条件(述語)に対して少数の学習データ(例えば8個や16個の例文)を与え、未見のテキストがその条件に合致するかを判断できるかを試した。結果として、SemPredの基盤となっているMiniLMというモデルは、少数の学習データでは従来のキーワードベースの手法(TF-IDF)よりも高い精度を示した。しかし、TF-IDFを全ての学習データで訓練した「フルデータTF-IDF」と比較すると、MiniLMの精度は劣るという結果になった。
さらに、より高性能なエンコーダー(MPNet)も試したが、精度はわずかに向上したものの、処理速度が大幅に低下し、事前に設定した「80%以上の精度」という目標を達成できなかった。
この実験で特に重要だったのが、「精度とカバレッジ(システムが回答できる質問の割合)のトレードオフ」である。棄権機能を活用すれば、モデルが自信を持って回答する質問だけを選べば、その精度は非常に高くなる。例えば、約半分の質問にしか答えられないが、その回答の96.3%は正しかった、といった具合だ。しかし、これでは実用的なシステムとしては不十分である。筆者は、事前に「90%以上の精度かつ50%以上のカバレッジ」という目標(ゲート)を設定していたが、このシステムではその両方を満たすことはできなかった。棄権の範囲を広げれば精度は上がるが、回答できる質問の割合が極端に減ってしまうからだ。
最終的に、筆者はこのアーキテクチャでの開発を停止した。なぜなら、事前に設定した目標(ゲート)を達成できなかったからである。この「目標達成に至らなかった」という結果自体が、今後の開発において非常に有用な情報となる。どこに問題があったのか、何を改善すべきか、あるいはこの方向性では難しいのか、という判断の指針になるからだ。
この実験から得られた教訓は多い。まず、モデルを開発する前に、具体的な目標となる「ゲート」を明確に設定しておくことの重要性。これにより、主観的な判断ではなく客観的な基準で成果を評価できる。次に、精度だけでなく、カバレッジ(どれだけの質問に答えられるか)、コスト(処理費用)、レイテンシー(処理時間)など、複数の側面から総合的に評価することの必要性。また、棄権という機能は精度を向上させる効果があるが、その際には必ずカバレッジとセットで報告すべきだという点も指摘されている。闇雲にモデルの規模を大きくしても、必ずしも良い結果につながるとは限らないという教訓も得られた。
筆者は、今回のアーキテクチャの課題として、「述語(自然言語の条件)そのものの情報がモデルに十分に活用されていない」点を挙げている。現在は、テキストを埋め込みに変換し、その埋め込みと述語の「名前」で定義されたモデルが判断しているが、述語の「言葉そのもの」をモデルの入力として与える「ペアワイズスコアリング」という新しいアプローチが、次の実験の焦点となるだろう。
大規模言語モデル(LLM)の可能性についても触れられているが、LLMは高コストで処理に時間がかかる、プライバシーの問題があるなどの懸念がある。そのため、SemPredのようなコンパクトなモデルで大部分を処理し、判断が難しい「UNKNOWN」なケースだけをLLMにエスカレーションするという使い方が現実的かもしれないと述べられている。
筆者は、このプロジェクトを通して、テキスト分類の技術的な問題以上に、「大規模なデータシステム上で、不確実な予測をいかに安全かつ効率的に実行するか」というデータシステム側の課題がより複雑であると認識を改めた。キャッシング、コスト管理、適切な棄権戦略、再現性、異なるデータベースシステムへの統合といった問題は、自然言語処理の領域を超えた、システム全体に関わる課題だ。
今回の実験は、製品としてそのまま使えるレベルには至らなかったが、「SQLに自然言語の条件を取り入れることはできるのか?」という問いに対し、具体的なプロトタイプとベンチマーク、性能数値、そして設計上の課題を明確にするという点で、非常に価値のある一歩だったと言える。