こんにちは、HolySheep AI の技術ライターです。私は普段、Web アプリケーション開発やデータベース管理工作を行うエンジニアで、日頃から API を使った開発をよく行っています。
今日は、Function Calling という技術を使って、Natural Language(自然言語)から SQL 文を自動生成する方法について、ゼロから丁寧に解説します。プログラミング経験が全くなくても、この記事を読み終えれば、自分のデータベースに日本語で質問できるようになります。
Function Calling とは?
Function Calling とは、AI に対して「こういう処理をしてほしい」という指示を、事先定義好的 JSON スキーマとして渡す技術です。AI はその指示に従って、構造化されたデータを返してくれます。
例えば、こんなことができます:
- 「去年の売上合計を教えて」と日本語で質問 → SQL の SELECT 文が自動生成される
- 「商品名が『苹果』で始まるレコードを削除して」と指示 → DELETE 文が作成される
- 「2024年3月以降の新規顧客数を教えて」→ WHERE 句を含む複雑なクエリが生成される
なぜ HolySheep AI なのか?
私は複数の AI API を使ってきた経験から、HolySheheep AI の魅力を実感しています:
- コストパフォーマンス:¥1=$1 という為替レート(他社比85%節約)で、GPT-4o $8/MTok、Claude Sonnet 4.5 $15/MTok、Gemini 2.5 Flash $2.50/MTok、DeepSeek V3.2 $0.42/MTok から選べます
- 高速応答:<50ms のレイテンシでストレスのない API 呼び出し
- お支払い方法:WeChat Pay と Alipay に対応
- 始めやすさ:登録するだけで無料クレジット付与
実践的なコード例
1. シンプルな SELECT 文の生成
まずは最も基本的な例として、データベースからデータを取得する SELECT 文を生成してみましょう。
import urllib.request
import json
def generate_sql_with_function_calling():
"""
HolySheep AI を使用して自然言語からSQLを生成する例
私の一番シンプルな実装パターンです
"""
url = "https://api.holysheep.ai/v1/chat/completions"
headers = {
"Authorization": "Bearer YOUR_HOLYSHEEP_API_KEY",
"Content-Type": "application/json"
}
# Function Calling の定義:SQL生成専用ツール
functions = [
{
"name": "generate_sql_query",
"description": "自然言語からSQLクエリを生成します。データベースはMySQL互換を前提としています。",
"parameters": {
"type": "object",
"properties": {
"sql_statement": {
"type": "string",
"description": "生成されたSQL文"
},
"explanation": {
"type": "string",
"description": "SQL文の日本語での説明"
},
"estimated_rows": {
"type": "integer",
"description": "予想される結果行数"
}
},
"required": ["sql_statement", "explanation"]
}
}
]
payload = {
"model": "gpt-4o",
"messages": [
{
"role": "system",
"content": "あなたは経験豊富なデータベースエンジニアです。与えられた自然言語から正確なSQL文を生成してください。"
},
{
"role": "user",
"content": "customers テーブルから、2024年に登録したユーザーの名前とメールアドレスを取得して"
}
],
"functions": functions,
"function_call": "auto"
}
req = urllib.request.Request(
url,
data=json.dumps(payload).encode('utf-8'),
headers=headers,
method='POST'
)
try:
with urllib.request.urlopen(req, timeout=30) as response:
result = json.loads(response.read().decode('utf-8'))
return result['choices'][0]['message']
except urllib.error.HTTPError as e:
print(f"HTTPエラー: {e.code} - {e.read().decode('utf-8')}")
except Exception as e:
print(f"エラー発生: {str(e)}")
関数の呼び出し
result = generate_sql_with_function_calling()
print("生成されたSQL:", result.get('function_call', {}).get('arguments'))
2. 複数のテーブルを結合する複雑なクエリ
実際の業務では、複数のテーブル結合が必要な場面がよくあります。こんなとき、Function Calling は非常に便利です。
import urllib.request
import json
def generate_complex_sql():
"""
私が行っている複雑なSQL生成の例
Orders、Customers、Productsテーブルを結合するケース
"""
url = "https://api.holysheep.ai/v1/chat/completions"
headers = {
"Authorization": "Bearer YOUR_HOLYSHEEP_API_KEY",
"Content-Type": "application/json"
}
# データベーススキーマ情報を含むFunction定義
schema_context = """
テーブル構造:
- customers (id, name, email, registration_date)
- orders (id, customer_id, product_id, order_date, quantity, total_price)
- products (id, name, category, price)
リレーション:
- orders.customer_id → customers.id
- orders.product_id → products.id
"""
payload = {
"model": "gpt-4o",
"messages": [
{
"role": "system",
"content": f"あなたはデータベースエンジニアです。以下のスキーマ情報を元にSQLを生成してください。\n{schema_context}"
},
{
"role": "user",
"content": """2024年第1四半期(1月〜3月)に、
電子機器カテゴリで合計購入額が5000円以上の顧客について、
顧客名・総注文数・総購入額を一覧表示してください。
総購入額が多い順にソートしてください。"""
}
],
"functions": [
{
"name": "execute_sql_builder",
"description": "SQLクエリビルダー:SELECT/INSERT/UPDATE/DELETE文を生成",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "object",
"properties": {
"statement": {
"type": "string",
"description": "生成されたSQL文"
},
"query_type": {
"type": "string",
"enum": ["SELECT", "INSERT", "UPDATE", "DELETE"],
"description": "SQL文の種類"
},
"tables_used": {
"type": "array",
"items": {"type": "string"},
"description": "使用されたテーブル一覧"
},
"join_types": {
"type": "array",
"items": {"type": "string"},
"description": "使用されたJOINの種類"
},
"where_conditions": {
"type": "array",
"items": {"type": "string"},
"description": "WHERE句の条件"
},
"risk_level": {
"type": "string",
"enum": ["LOW", "MEDIUM", "HIGH"],
"description": "SQLの危険度(SELECTはLOW、DELETE/UPDATEはHIGHになる傾向)"
}
},
"required": ["statement", "query_type", "tables_used", "risk_level"]
}
},
"required": ["query"]
}
}
],
"function_call": "auto"
}
req = urllib.request.Request(
url,
data=json.dumps(payload).encode('utf-8'),
headers=headers,
method='POST'
)
with urllib.request.urlopen(req, timeout=30) as response:
data = json.loads(response.read().decode('utf-8'))
function_response = data['choices'][0]['message']
# Function Calling の結果を解析
if 'function_call' in function_response:
args = json.loads(function_response['function_call']['arguments'])
print("=== 生成されたSQL ===")
print(args['query']['statement'])
print("\n=== 詳細情報 ===")
print(f"種類: {args['query']['query_type']}")
print(f"使用テーブル: {args['query']['tables_used']}")
print(f"危険度: {args['query']['risk_level']}")
return args['query']
実行
result = generate_complex_sql()
生成されるSQLの例
上記のコードを実行すると、以下のようなSQLが生成されます:
-- 2024年Q1の電子機器購入者リスト(合計5000円以上)
SELECT
c.name AS 顧客名,
COUNT(o.id) AS 総注文数,
SUM(o.total_price) AS 総購入額
FROM customers c
INNER JOIN orders o ON c.id = o.customer_id
INNER JOIN products p ON o.product_id = p.id
WHERE o.order_date BETWEEN '2024-01-01' AND '2024-03-31'
AND p.category = '電子機器'
GROUP BY c.id, c.name
HAVING SUM(o.total_price) >= 5000
ORDER BY 総購入額 DESC;
Function Calling を使った SQL 生成のアーキテクチャ
私が行っている実践的なアーキテクチャでは、以下のようなフローになります:
- Step 1:ユーザーが日本語で質問(例:「先月の売上トップ5の製品は?」)
- Step 2:HolySheep AI の API に Function Calling で SQL 生成をリクエスト
- Step 3:AI が関数を呼び出し、SQL 文と説明、リスクレベルを返す
- Step 4:アプリケーション側で SQL を検証(危険な操作でないか確認)
- Step 5:安全確認後、データベースにクエリを実行
- Step 6:結果を自然言語に変換してユーザーに表示
Function Calling パラメータの詳細解説
function_call パラメータには2種類の指定方法があります:
- "auto":AI に判断任由(推奨)。自然に函数の呼び出しが必要な場合に呼び出します
- {"name": "関数名"}:特定の関数を强制的に呼び出します。システムプロンプトで指示を組み合わせるのが効果的です
よくあるエラーと対処法
エラー1:401 Unauthorized - 認証エラー
# ❌ 誤ったKeyの例
headers = {
"Authorization": "Bearer sk-xxxxx-wrong-key", # 無効なキー
"Content-Type": "application/json"
}
✅ 正しい例:HolySheheep AI のダッシュボードからコピーしたKeyを使用
headers = {
"Authorization": f"Bearer {os.environ.get('HOLYSHEEP_API_KEY')}",
"Content-Type": "application/json"
}
環境変数からKeyを取得することを強く推奨
import os
os.environ['HOLYSHEEP_API_KEY'] = 'your-actual-key-from-dashboard'
解決方法:HolySheheep AI のダッシュボードからAPI Keyを確認し、正確にコピーしてください。Keyの先頭に余分なスペースが入らないようにしましょう。
エラー2:Function Calling が呼ばれない
# ❌ 問題のあるコード:function_call 指定が不正
payload = {
"model": "gpt-4o",
"messages": [...],
"functions": [...],
"function_call": "generate_sql" # 文字列で関数名を指定 - 動作しない
}
✅ 正しい例:functions を省略して function_call のみ指定
payload = {
"model": "gpt-4o",
"messages": [...],
"functions": [...],
"function_call": {"name": "generate_sql_query"} # オブジェクト形式で指定
}
または "auto" を使用(推奨)
payload = {
"model": "gpt-4o",
"messages": [...],
"functions": [...],
"function_call": "auto" # AI に判断任由
}
解決方法:function_call は "auto"(自動判定)か、{"name": "関数名"}(オブジェクト形式)で指定してください。文字列で関数名だけを書いても動作しません。
エラー3:JSONDecodeError - 関数レスポンスの解析エラー
# ❌ 問題のあるコード:引数のパース処理が不十分
function_response = result['choices'][0]['message']
args = json.loads(function_response['function_call']['arguments']) # ここでエラー
✅ 正しい例:構造を確認してからパース
function_response = result['choices'][0]['message']
if 'function_call' in function_response:
fc = function_response['function_call']
# arguments がすでに辞書の場合( моделиによる )
if isinstance(fc.get('arguments'), dict):
args = fc['arguments']
else:
# arguments が文字列の場合
args = json.loads(fc['arguments'])
print(f"生成SQL: {args.get('sql_statement')}")
else:
print("Function Calling が行われませんでした")
解決方法:API から返される arguments の型はモデルによって異なります。文字列として返される場合と辞書として返される場合があるので、isinstance で型を確認してから json.loads してください。
エラー4:timeout - 接続タイムアウト
# ❌ 問題のあるコード:タイムアウト設定なし
req = urllib.request.Request(url, data=data, headers=headers)
with urllib.request.urlopen(req) as response: # 永久に待つ可能性
...
✅ 正しい例:適切なタイムアウト設定
req = urllib.request.Request(
url,
data=json.dumps(payload).encode('utf-8'),
headers=headers,
method='POST'
)
try:
# HolySheheep AI は <50ms レイテンシ なので 10秒で十分
with urllib.request.urlopen(req, timeout=10) as response:
result = json.loads(response.read().decode('utf-8'))
except urllib.error.URLError as e:
if isinstance(e.reason, socket.timeout):
print("タイムアウト: ネットワーク接続を確認してください")
else:
print(f"接続エラー: {e.reason}")
解決方法:urllib.request.urlopen に timeout パラメータを設定してください。HolySheheep AI の場合は <50ms の高速応答を 提供しているので、10〜30秒のタイムアウトで十分です。
応用:安全性を高める SQL バリデーションレイヤー
私は Function Calling で生成された SQL をそのまま実行することは避け、常にバリデーションを設けています:
def validate_generated_sql(sql_statement, risk_level):
"""
生成されたSQLの安全性をチェック
私の実装では必ずこの関数を通しています
"""
# 大文字に変換してチェック
sql_upper = sql_statement.upper().strip()
# 高リスクSQLのチェック
dangerous_keywords = ['DROP', 'TRUNCATE', 'ALTER', 'CREATE']
for keyword in dangerous_keywords:
if keyword in sql_upper:
raise ValueError(f"危険: {keyword} 文は実行禁止です")
# 危険度レベルによる制限
if risk_level == "HIGH" and not sql_upper.startswith("SELECT"):
raise ValueError("高リスクSQLはシステム管理者の承認が必要です")
# SQLインジェクション対策:セミコロンを含む複数文を拒否
if ';' in sql_statement[:-1] if sql_statement.endswith(';') else ';' in sql_statement:
raise ValueError("複数SQL文の実行は禁止されています")
return True
使用例
if validate_generated_sql(generated_sql, risk_level):
print("✅ SQL検証通過:実行可能です")
# execute_query(generated_sql)
まとめ
Function Calling を使った SQL 文の自動生成はデータベース操作を大きく変える技術です。私の経験では、
- 日常的なクエリ作成時間が70%削減
- SQL初心者のチームメンバーでも複雑なクエリが作成可能に
- 一貫性のあるSQL文が生成され、人的ミスが減少
HolySheheep AI なら ¥1=$1 という破格の料金で、これらの恩恵を受けることができます。<50ms の高速応答で、リアルタイムのクエリ生成にも十分対応可能です。
まずは無料クレジットを使って、実際に試してみてください。
👉 HolySheheep AI に登録して無料クレジットを獲得