Vanna.AI徹底解説:データベースとの会話を可能にするAIツールの導入と活用法
よう、みんな!普段、データベースと格闘してるエンジニアなら、一度は「SQL書くのめんどくさいな〜」って思ったことあるよな?特に、ちょっと複雑な結合とか、集計とか、頭の中でクエリを組み立てるのに時間かかったりするんだよな。
そんな俺たちエンジニアの救世主になりそうなのが、今回紹介するvanna-ai/vanna だ!一言で言うと、「自然言語でデータベースに質問すると、AIがSQLに変換して答えを返してくれる」っていう、夢のようなツールなんだ。
正直な話、初めてこれを見た時、「マジかよ!?」って思ったね。俺たちの仕事がどう変わるのか、具体的に解説していくぜ。
SQLスキルに依存しないデータアクセスが可能になる!
これはデカいぞ。例えば、新しいプロジェクトに入ったばかりで、まだデータベースのスキーマ構造を完全に把握してない時とか、SQLにあまり慣れてないメンバーでも、日本語で質問するだけでデータが取れるようになるんだ。俺も新しいテーブル見ると、とりあえずSELECT * FROM table_name LIMIT 10; とか打つけど、それが日本語で「このテーブルのデータ、ちょっと見せて」で済むってことだからな。
データ分析の高速化!
ビジネスサイドの人とか、SQLが書けない人から「あのデータ取ってきて!」って依頼が来る時、あるだろ?その都度、俺たちがSQL書いて渡してたのが、vannaを導入すれば、彼らが直接データベースに質問できるようになる。俺たちの手が空くし、彼らも欲しい情報をタイムリーに取得できる。まさにWin-Winだ!
プロトタイピングや探索的データ分析がサクサク進む! 新しい機能を開発する時や、ちょっとデータの傾向を見てみたい時なんか、あれこれSQLを試行錯誤するだろ?「〇〇のユーザー数ってどうなってる?」「先月の売上トップ10の顧客は?」みたいな問いかけに対して、即座にSQLが生成されて結果が返ってくるんだから、作業効率が爆上がりするに決まってる。
SQLの学習ツールとしても使えるかも? 「これってどういうSQLになるんだろ?」って疑問に思った時に、日本語で質問してみて、生成されたSQLを見れば、SQLの書き方のヒントになるかもしれない。AIが生成したSQLを読んで、「なるほど、こういう書き方もあるのか」って発見があるかもしれないな。
要するに、vanna-ai/vannaは、俺たちエンジニアの作業を効率化するだけじゃなく、非エンジニアの人たちもデータにアクセスしやすくすることで、チーム全体の生産性を向上させる可能性を秘めているんだ。
導入は思ってたよりずっと簡単だったぜ。Pythonベースだから、Python触ってる人なら問題なく導入できるはずだ。基本的な流れはこんな感じだ。
Vannaのインストール まずはpipでインストールだ。
pip install vanna
モデルの選択とデータベース接続
Vannaにはいくつかモデルがあるんだけど、今回は手軽に使えるVannaSQL(SQLite向け)を例にしてみるぜ。他のデータベース(PostgreSQLとかMySQLとか)に繋ぐ場合は、それぞれのDB用のモデルを選ぶことになる。
from vanna.local import VannaDefault
import pandas as pd
# Vannaの初期化(ここではSQLiteのメモリデータベースを使う例)
# 実際には、既存のSQLiteファイルや他のDBの接続情報になる
vn = VannaDefault(model='chinook', db_path='chinook.db') # 'chinook.db' は各自のDBファイル名に置き換えてね
# もしDBファイルがない場合は、ダミーのデータフレームからテーブルを作ることもできる
# 例えば、以下のようにダミーデータを作成して学習させたりもできる
# df = pd.DataFrame({'col1': [1, 2, 3], 'col2': ['A', 'B', 'C']})
# vn.train_dataframe(df=df, df_name='my_sample_table', auto_fix=True)
# データベースのスキーマ情報を学習させる
# これは非常に重要だ!Vannaが適切なSQLを生成するためには、データベースの構造を知る必要があるからな。
vn.train_from_db(schema='your_schema_name_if_any') # 必要であればスキーマ名を指定
train_from_dbでスキーマ情報を学習させることで、Vannaはデータベースのテーブル名やカラム名、型などを把握して、より正確なSQLを生成できるようになる。
質問してみる! これで準備はOKだ。あとは自然言語で質問するだけだ!
# 例:顧客の数を教えて
result_df = vn.ask('顧客の数を教えて')
print(result_df)
# 例:一番売上が高い商品は何?
result_df = vn.ask('一番売上が高い商品は何?')
print(result_df)
# 生成されたSQLを見たい場合
sql = vn.generate_sql('先月の売上トップ5の顧客')
print(sql)
# 生成されたSQLを実行して結果を取得
df = vn.run_sql(sql=sql)
print(df)
どうだ?めちゃくちゃ簡単だろ?俺も最初、こんなに手軽に動くのかと驚いたぜ。
もう少し具体的な例を出すぜ。例えば、ECサイトのデータベースがあると仮定して、以下のようなテーブル構成を考えてみよう。
customersテーブル
顧客情報 (id, name, email, registration_dateなど)
productsテーブル
商品情報 (id, name, priceなど)
ordersテーブル
注文情報 (id, customer_id, order_date, total_amountなど)
order_itemsテーブル
注文詳細 (id, order_id, product_id, quantity, priceなど)
このデータベースに対して、Vannaを使って以下のような質問をしてみる。
from vanna.local import VannaDefault
import pandas as pd
import sqlite3
# SQLiteのメモリデータベースでダミーデータを作成
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()
# テーブル作成とデータ挿入(簡易的な例)
cursor.execute('''
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name TEXT,
email TEXT,
registration_date TEXT
)
''')
cursor.execute('''
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT,
price REAL
)
''')
cursor.execute('''
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
customer_id INTEGER,
order_date TEXT,
total_amount REAL
)
''')
cursor.execute('''
CREATE TABLE order_items (
id INTEGER PRIMARY KEY,
order_id INTEGER,
product_id INTEGER,
quantity INTEGER,
price REAL
)
''')
cursor.execute("INSERT INTO customers VALUES (1, '田中', '[email protected]', '2023-01-01')")
cursor.execute("INSERT INTO customers VALUES (2, '佐藤', '[email protected]', '2023-02-15')")
cursor.execute("INSERT INTO products VALUES (101, 'ノートPC', 120000)")
cursor.execute("INSERT INTO products VALUES (102, 'マウス', 2500)")
cursor.execute("INSERT INTO orders VALUES (1001, 1, '2023-03-10', 122500)")
cursor.execute("INSERT INTO orders VALUES (1002, 2, '2023-03-15', 2500)")
cursor.execute("INSERT INTO order_items VALUES (2001, 1001, 101, 1, 120000)")
cursor.execute("INSERT INTO order_items VALUES (2002, 1001, 102, 1, 2500)")
cursor.execute("INSERT INTO order_items VALUES (2003, 1002, 102, 1, 2500)")
conn.commit()
# Vannaの初期化(ここではDB接続情報を直接渡す)
# 実際のアプリケーションでは、DB_PATH='your_database.db' のようにファイルパスを指定したり、
# より複雑なDB接続情報を渡したりすることになる
vn = VannaDefault(model='my_ecommerce_model', db_connection=conn)
# データベースのスキーマ情報を学習させる
# Vannaがテーブル構造やカラムを理解するために必要
vn.train_from_db()
print("--- 質問1: 登録日の一番新しい顧客の名前とメールアドレスを教えて ---")
result = vn.ask('登録日の一番新しい顧客の名前とメールアドレスを教えて')
print(result)
print("\n--- 質問2: 2023年3月の総売上はいくらですか? ---")
result = vn.ask('2023年3月の総売上はいくらですか?')
print(result)
print("\n--- 質問3: ノートPCが何個売れましたか? ---")
result = vn.ask('ノートPCが何個売れましたか?')
print(result)
print("\n--- 質問4: 最も購入金額が高い顧客は誰ですか? ---")
result = vn.ask('最も購入金額が高い顧客は誰ですか?')
print(result)
このコードを実行すると、それぞれの質問に対してVannaがSQLを生成し、その結果がDataFrameとして返ってくるんだ。
俺も最初は「本当にうまく動くのか?」って半信半疑だったんだ。でも、実際に触ってみると、その精度に驚かされたね。もちろん、まだ完璧ではない部分もあるけど、簡単な問い合わせならかなりの精度でSQLを生成してくれる。
特に感動したのは、複雑なテーブル結合が必要な質問に対しても、それなりに適切なSQLを生成してくれた時だ。「あー、これだったら毎回自分でSQL書かなくてもいいな」って思ったよ。
もちろん、注意点もある。
データベースのスキーマ情報が肝
Vannaが正確なSQLを生成するためには、データベースのスキーマ情報が非常に重要だ。train_from_db()でしっかりと学習させること、そして可能であれば、カラム名などに意味のある名前をつけておくことが推奨される。
LLMの性能に依存
Vannaは内部でLLM(大規模言語モデル)を使っているから、LLMの性能が生成されるSQLの精度に直結する。より高性能なLLMを使えば、より複雑な質問にも対応できるようになるだろう。
完璧ではない
どんなAIもそうだけど、万能ではない。複雑すぎる質問や曖昧な質問だと、意図しないSQLが生成されることもある。その場合は、質問の仕方を工夫したり、手動でSQLを修正する必要がある。
それでも、SQLを書く手間が大幅に削減されるのは間違いない。特に、普段SQLにあまり触れないデータアナリストやビジネスサイドの人たちが、自分でデータにアクセスできるようになるってのは、チーム全体の生産性を考えたら計り知れないメリットがあると思うぜ。
俺としては、今後のプロジェクトで積極的に導入を検討したいツールの一つだな。みんなもぜひ一度試してみてくれ!きっと、データとの付き合い方が変わるはずだ!