GPT関数呼び出すの1：SQL文の生成

# 概要

強大な関数呼び出しをテストしてみます。

- 公式サイトによれば、関数呼び出しを使用することで、特定のフォーマットでJSONを返すことができる
- 公式の例は非常に基本的なものであり、イメージが掴めない人もいる
- 実際に想像以上に幅広い範囲で活用できるので、少し簡単に紹介

# イメージ

## インプットイメージ

```
2023年5月31日に、商品価格が1,000円以上の売上を出してください
```

## アウトプットイメージ

### 1回目の紹介は、SQL文の生成

このような結果を出したい

```sql
SELECT *
FROM sales
WHERE DATE = '05-31' AND ItemPrice > 1000;
```

# 背景

先にイメージを出してしまったけど、何故かSQL文を生成したい

- 一般人がSQL文がわからない
- 文章からSQL文に変換できると、一般人でもクエリを叩くことができる
- 昔のような、一般人がクエリできるような、画面上で複雑な選択項目を作る必要がなくなる

# プログラム

## 使う関数

説明通りに、文章から、年・月・日と最低価格を取り出す

```python
prompt_function = [
    {
        "name": "get_date_and_price",
        "description": "get month, day from date and minimum item price",
        "parameters": {
            "type": "object",
            "properties": {
                "month": {
                    "type": "integer",
                    "description": "month of the date"
                },
                "day": {
                    "type": "integer",
                    "description": "day of the date"
                },
                "price": {
                    "type": "integer",
                    "description": "minimum item price"
                }
            },
            "required": ["month", "day"],
        },
    }
]
```

## ユーザープロンプト

```python
prompt_user = '''
2023年5月31日に、商品価格が1,000円以上の売上を出してください
'''
```

## APIをコール

```python
response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo-0613",
    messages=[
        {"role": "user", "content": prompt_user},
    ],
    functions=prompt_function,
    function_call="auto",
)

print(json.loads(response["choices"][0]["message"]["function_call"]["arguments"]))
```

## 結果

```
{'month': 5, 'day': 31, 'price': 1000}
```

## 最後にSQL文に変換

```python
response_dict = json.loads(response["choices"][0]["message"]["function_call"]["arguments"])
SQL = f"SELECT * FROM sales WHERE DATE = '{response_dict['month']:02d}-{response_dict['day']:02d}' AND ItemPrice > {response_dict['price']};"
print(SQL)
```

-----

柔軟に対応できるように、さきほどの関数で、'price'は必須（"required"）ではないので、これでGPTがどう返すのか見ていきます。

## 最低価格指定していない場合

```python
prompt_user = '''
2023年5月1日の売上を出してください
'''

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo-0613",
    messages=[
        {"role": "user", "content": prompt_user},
    ],
    functions=prompt_function,
    function_call="auto",
)

print(json.loads(response["choices"][0]["message"]["function_call"]["arguments"]))
```

うまく月と日だけ返します。

```
{'month': 5, 'day': 1}
```

## SQL文に変換

これで分岐を作ると、SQL文の生成も簡単に対応できる

```python
response_dict = json.loads(response["choices"][0]["message"]["function_call"]["arguments"])
if 'price' in response_dict:
    SQL = f"SELECT * FROM sales WHERE DATE = '{response_dict['month']:02d}-{response_dict['day']:02d}' AND ItemPrice > {response_dict['price']};"
else:
    SQL = f"SELECT * FROM sales WHERE DATE = '{response_dict['month']:02d}-{response_dict['day']:02d}';"
print(SQL)
```

```
SELECT * FROM sales WHERE DATE = '05-01';
```

-----

# GPTがどこまで賢い

ここからはもうちょっといろんな日本語表現で試してみたい

## 四半期

```python
prompt_user = "2022年2Qの売上を出してください"
```

### 結果

```
{'month': 4, 'day': 1}
```

## 月末

```python
prompt_user = "4月最後の日の売上を出してください"
```

### 結果

```
{'month': 4, 'day': 30}
```

## 祝日・特別な日

```python
prompt_user = "バレンタインデーの売上を出してください"
```

### 結果

```
{'month': 2, 'day': 14}
```

# 最後

精度的には完全に問題ないと思っているけど、
1個だけ注意しないといけないのは、
GPT自体が現在の時刻が知らないので、

```python
prompt_user = "今日の売上を出してください"
```

### 結果

```
{'month': 10, 'day': 29}
```

"今日"みたいな単語で日付に変換すると、別の関数呼び出しで、Pythonのdatetimeとかで現在の時刻の取得が必要です。

-----

もちろんさきほど紹介したのは一部の活用方法しかないので、より複雑な関数を使うと、もっと長いSQL文の生成もできるでしょう。

また次回さらに高度な使い方を紹介します。