OCIから Generative AI Agent (以降、生成AIエージェント)の機能が新たに追加されました。すでにいくつかの記事がQiita上にも投稿されていますが、RAGツールを使ったものが多く、残念ながらSQLツールと関数呼び出しツールについては影が薄いようです。
というわけで、今回はOCI生成エージェントのSQLツールがどのようなものなのか確認してみます。また昨年から利用できるようになった SELECT AI との違いも見てみたいと思います。
OCI生成AIエージェントのSQLツールは、生成AIエージェントに自然言語で問い合わせをすると、それをSQLに変換してくれるものです。
また、結果セットの取得(SQLの実行)を行わなければデータベースと接続している必要はなく、データベース・スキーマ情報およびテーブルと列の説明があればエージェントはSQLを生成してくれます。
まず、今回のデモ用に以下のようなテーブルがある想定とします。
- 売上データ(Sales)
- 製品マスタ(Products)
- 製品カテゴリマスタ(Cateogries)
- 部署(店舗)マスタ(Departments)
また、テーブルの定義は以下のような想定です。
CREATE TABLE Sales (
RecordKey INT PRIMARY KEY,
FiscalYear INT NOT NULL,
SalesDate DATE NOT NULL,
DepartmentKey VARCHAR(50) NOT NULL,
ProductKey VARCHAR(50) NOT NULL,
Quantity INT NOT NULL,
Amount INT NOT NULL,
FOREIGN KEY (ProductKey) REFERENCES Products(ProductKey),
FOREIGN KEY (DepartmentKey) REFERENCES Departments(DepartmentKey)
);
CREATE TABLE Products (
ProductKey VARCHAR(50) PRIMARY KEY,
ProductId VARCHAR(50) NOT NULL,
ProductName VARCHAR(50) NOT NULL,
CategoryKey VARCHAR(50) NOT NULL,
FOREIGN KEY (CategoryKey) REFERENCES Categories(CategoryKey)
);
CREATE TABLE Categories (
CategoryKey VARCHAR(50) PRIMARY KEY,
CategoryId VARCHAR(50) NOT NULL,
CategoryName VARCHAR(50) NOT NULL
);
CREATE TABLE Departments (
DepartmentKey VARCHAR(50) PRIMARY KEY,
DepartmentId VARCHAR(50) NOT NULL,
DepartmentName VARCHAR(50) NOT NULL
);
ここで大切なのは、しっかりと主キーおよび外部キーを定義しておくことです。エージェントがテーブル間のJOINをする上で必要な情報となります。
実際にOCI生成AIエージェントでSQLツールを作成してみたいと思います。生成AIエージェントを使用できるリージョンは限られていますのでご注意ください。生成AIエージェントを利用できるリージョンは以下のドキュメントで確認できます。今回は大阪リージョンを使用しています。
エージェントの作成
OCIの画面から「アナリティクスとAI」を選択、その中の「AIサービス」から「生成AIエージェント」をクリックします。
エージェントをクリックします。
エージェントの作成をクリックします。
名前を入力し、コンパートメントを選択して次をクリックします。
SQLツールの作成
続けてツールの作成画面になるので、ツールの作成をクリックします。
SQLをクリックします。
作成するSQLツールの名前と説明を入力します。
このツールのデータベース・スキーマ構成のインポートでインラインを選択します。データベース・スキーマには、先ほど記載した各テーブルのCREATE TABLE文を入力します。
モデルのカスタマイズは今回は「小(コスト節約)」を選択します。言語はOracle SQLを選択します。コンテキスト内学習の例はいったん「なし」を選択します。データベース接続は今回行わないので未入力のままにしておきます。
カスタム指示はエージェントの動作を変更するためのプロンプトです。今回はガイドラインの例をそのまま入力します。
表と列の説明はインラインを選択します。テキストボックスが表示されるので、下記のように各テーブルとテーブルの各列の説明を入力します。
表と列の説明
Description of the important tables in the schema:
Sales Sales data, quantity and amount.
Categories Category names and other information
Products Product names and other information
Departments Department names and other information
Description of the important columns of the tables in the schema:
SALES TABLE
sales.FiscalYear A fiscal year of SalesDate column.
sales.SalesDate sales date.
sales.Quantity Quantity of sales.
sales.Amount Amount of sales.
---------------------------------------------------------------------
CATEGORIES TABLE
categories.CategoryKey Unique key that identifies the category of a product.
categories.CategoryName Name of the category.
---------------------------------------------------------------------
PRODUCTS TABLE
products.ProductKey Unique key that identifies the product.
products.ProductName Name of the product.
---------------------------------------------------------------------
DEPARTMENTS TABLE
departments.DepartmentKey Unique key that identifies the department.
departments.DepartmentName Name of the department.
ツールの作成をクリックします。
エージェント・エンドポイントの設定画面では、「このエージェントのエンドポイントの自動生成」にチェックが入っていることを確認します。その他の項目は今回デフォルトのままで、次をクリックします。
エージェントの作成をクリックします。
Llama 3に関する確認画面が表示されたら、同意にチェックを入れて送信ボタンをクリックします。
正常に作成されれば、以下の画面のようにエージェントが作成されアクティブになります。
それでは早速実際にチャットしてみたいと思います。今回はSDKを使わず、お手軽に試すことのできるOCI上のチャットのインターフェースで試してみたいと思います。
エージェントの画面で「チャットの開始」をクリックします。
チャット画面が表示されます。
試しに「2024年4月から2024年9月までの製品カテゴリが食品の月別の売上金額の合計」と日本語で入力して送信してみます。
日本語でも問題なくSQLが生成されました。
参照するテーブルと列、JOINの内容は問題ありません。しかし、月別と指定しましたが、SalesDateをそのまま使用しているので日別になってしまっています。
生成されたSQL
SELECT
c.CategoryName,
s.FiscalYear,
s.SalesDate,
SUM(s.Amount) AS Total_Sales
FROM
Sales s
JOIN
Products p
ON
s.ProductKey = p.ProductKey
JOIN
Categories c
ON
p.CategoryKey = c.CategoryKey
WHERE
c.CategoryName = '食品' AND
s.FiscalYear = 2024 AND
TO_CHAR(s.SalesDate, 'MM') BETWEEN '04' AND '09'
GROUP BY
c.CategoryName,
s.FiscalYear,
s.SalesDate
ORDER BY
s.FiscalYear,
TO_CHAR(s.SalesDate, 'MM');
SQLツールの編集画面で、作成時に指定しなかったコンテキスト内学習の例に今回の質問と期待するSQLを回答として入力してみます。
SQLツールの更新内容を保存して、SQLツールがアクティブになったら再びエージェントのチャットで質問をしてみます。
コンテキスト内学習の例をもとにSQL文が期待するものになっています。データベース・スキーマに問題がなく、表と列の説明が十分な内容でも期待するようなSQLが生成されない場合は、コンテキスト内学習の例を登録することで結果の改善が期待できそうです。
生成AIエージェントのSQLツールと同じように生成AIを活用したものとして、SELECT AIがありますが、簡単にこの2つの違いを見てみたいと思います。
SELECT AIも生成AIエージェントのSQLツールと同様、自然言語での問い合わせをSQLに変換してくれる機能です。すでにQiitaなどでSELECT AIについて解説している記事がありますので、詳しく知りたい方は以下の記事をご参照ください。
生成AIエージェントのSQLツールとSELECT AIの違いは以下のようになっています。
生成AIエージェントのSQLツール | SELECT AI | |
---|---|---|
実行場所 | SDKなどを使用して開発したチャットアプリ | SQLを実行できる環境 |
実行方法 | チャットでエージェントに問い合わせ | SELECT AI を使用可能なユーザーで Autonomous Database にログインし、先頭に「SELECT AI」を付けたクエリを実行 |
対応データベース(SQL) | Oracleデータベース全般、SQLite | Autonomous Database のみ |
テーブルなどの情報 | Create Table文や、表と列の説明を登録 | どのテーブルを使用できるかはAIプロファイル作成時に指定 表や列の説明についてはSQLのCOMMENT文で登録 |
機能 | 基本的にはSQLの生成 結果セットの取得もできるが、大きな結果セットの場合オブジェクトストレージに保存される場合がある データベースと接続していなくても使える |
基本的には結果セットを返す
オプションパラメータとして以下のものがある データの生成も可能(GENERATE_SYNTHETIC_DATAプロシージャ) |
使用するLLM | 選べない | AIプロファイルの作成時に選択可能 (OpenAI、Cohere、Azure OpenAI Service、Google、Anthropic、Hugging Face、Google Gemini、OCI生成AIサービス) |
権限など | SQLの実行まで含める場合はOCI上でデータベース接続の作成、動的グループの作成などおこなう必要あり | 接続ユーザーにDBMS_CLOUD_AIパッケージの実行権限の付与が必要 CREATE_CREDENTIALプロシージャを使用して、生成AIサービスに接続するためのクレデンシャルを作成する必要あり |
OCI生成AIエージェントのSQLツールは、今回のデモでは多少の間違いはあったものの、おおむね問題なくSQLを生成してくれました。ただし、やはり生成AIは完璧ではないので、生成されたSQLが正しいかの最終的なチェックについては人間が行う必要があると思います。
ポイントとしては
- 主キー、外部キーの定義をしておく
- 表および列の説明を作成する
- 期待通りの結果にならない場合はコンテキスト内学習の例で改善
の3つになると思います。
実際にPythonでSDKを使用してOCIの生成AIエージェントと連携するアプリを構築しようと考えている方は、こちらの記事がとても参考になります。
Views: 2