3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Select AI Agent】Oracle DBの中だけでReAct型AIエージェントを動かしてみた -NL2SQL×RAG-

Last updated at Posted at 2025-11-24

■ はじめに

Oracle AI World 2025で発表されたOracle AI Database 26aiの機能「Select AI Agent」を試してみます。

Select AI Agent は、Autonomous AI Database の内部だけで ReAct(Reasoning + Acting)型 のエージェントを動作させられる仕組みです。
Oracle Autonomous AI Database上でネイティブに動作するため、外部のサーバーやフレームワークを用意することなく、自然言語 → SQL の生成(Select AI)RAG によるドキュメント検索Web検索などを組み合わせたのエージェントを構築・実行できます。

つまり、「データベース単体で自律エージェントを動かす」 ことができます!

今回の記事では、売上データの分析のユースケースを題材に、Select AI Agent を動かしてみたいと思います。

■ 試してみること

  • Select AI Agent を使って、自然言語でデータ分析を実行する
  • Select AI(構造化データ)と RAG(PDFカタログ/非構造化データ)を組み合わせて回答する仕組みを作る
  • 「いつ・どの製品が・どんな特徴で売れているのか?」を、注文データ(2015〜2025 の10年分)+商品カタログ PDF の両方を参照しながら回答できるか検証する
  • 回答を生成するのにどのような内部動作が行われているかログを確認する

■ Select AI Agentとは

Select AI Agentとは、Autonomous AI Database内で利用できる自律型エージェントを作成・管理するためのプログラムです。
作成されたエージェントは、ReAct(Reasoning and Acting) という推論の仕組みを使っています。

ReActとは

「思考(Reasoning)」と「行動(Acting)」を交互に繰り返すことで、より高度で柔軟なタスクを実行させるAIエージェントの設計パターンを指します。

Select AI Agentを使うと、RAG、自然言語からSQLを作るNL2SQL、また独自のPL/SQL処理を “ツール” として呼び出しながら、必要なタスクを実行できます。さらに、会話の流れを記憶し、複数ターンにわたって文脈を理解し続けてくれます。
これらの一連の流れをAutonomous AI Database上で実行できます。
DBMS_CLOUD_AI_AGENTパッケージを利用して、PL/SQLでエージェントやそのエージェントが使うツールを定義してワークフローを構築します。

image.png

必要なコンポーネント

Select AI Agentを利用する上で作成していく4つのコンポーネントを押さえていきます。

コンポーネント 役割のイメージ 説明
Agent Team チーム 複数Agentを連携させ、順序や文脈を共有しながら処理する
Agent 作業者 リクエストを理解し、適切なツールを選び、タスクを実行する
Task 作業指示書 どんな処理を行うか、どのツールを使うかを定義
Tool 道具 SQL / RAG / PL/SQL / Web検索などの機能パーツ

エージェント・チーム

1つ以上のエージェントを組み合わせてエージェント指向のワークフローを実行する仕組みです。
役割分担を調整し、共通のコンテキストを共有しながら、エージェントとタスクの組み合わせを順番に動かして、複数ステップの処理を安定して完了させます。

それぞれのエージェントは専門分野の作業を担当し、チームはその流れを整理して一連の結果をつなげます。
最終的に、共有した情報をもとに統一された回答を作り上げます。

エージェント

特定の目的を達成するためにタスクを進める“実行役”です。
リクエストの内容を理解し、必要なツールを選び、ステップを実行して結果を評価し、データベースの情報に基づいた回答を作ります。

エージェントには、その用途に合わせた振る舞い・ルール・利用可能なツールがまとめられており、たとえば返品処理やナレッジ検索など、特定の業務に合わせて動作します。

タスク

「1つのまとまった処理」を表すものです。
どのツールを使うか、どんなパラメータで実行するか、どう進めるかといった方針を決め、後続の処理が読める形で結果を出します。

タスクには、目的・入力・使うツール・制約(ガードレール)などが含まれており、実行すると後のステップで活用できる整った出力を返します。

ツール

エージェントがタスクを進めるときに使う“機能パーツ”のことです。ツールには次のものがあります。

  • 同じ入力に対して同じ出力を返すPL/SQLファンクションなどの確定的(deterministic)ツール。
  • Web検索やLLMベースの要約などの非決定的(non-deterministic)なツール。出力はタイミング、ネットワーク結果またはランダム性によって異なる場合がある。

Select AI Agentで、利用できるツールは次のいずれかです。

  • PL/SQL プロシージャーやファンクション
  • 用意されている組込みツール(SQL、RAG、Web検索など)

現段階で利用できる組込みツール・タイプの詳細は以下のとおりです。

参考:DBMS_CLOUD_AI_AGENTパッケージの組込みツール・タイプ

ツール・タイプ 説明 必須パラメータ
SQL 自然言語をSQL問合せに変換(NL2SQL) profile_name
RAG  ベクトル検索を行いRAG( Retrieval-Augmented Generation)を実行 profile_name
NOTIFICATION - Slackチャネルにメッセージを送信
- SMTPを使用して電子メールを送信
notification_type
slackの場合:
credential_name
slack_channel
emailの場合:
credential_name
recipient
sender
smtp_host
WEBSEARCH Webから情報を検索 credential_name

■ 使用するデータ

今回は、検証用に以下の2つのデータを用意しました。

1. 販売データ(構造化データ)

Autonomous Database 上に以下の3つのテーブルを作成し、
注文データ(orders)・注文明細(order_items)・製品マスタ(products) を格納します。

  • products:製品ID、名称、カテゴリなどのマスタ情報
  • orders:注文日、顧客ID、店舗IDなどの注文情報
  • order_items:注文に紐づく購入製品と数量

👉テーブル作成時のSQLコマンドは以下をクリック

3つの表の作成📝
  • 3つの表の作成

-- orders

CREATE TABLE orders (
    order_id     NUMBER PRIMARY KEY,
    order_date   DATE,
    customer_id  NUMBER,
    store_id     NUMBER
);

-- order_items

CREATE TABLE order_items (
    item_id     NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    order_id    NUMBER REFERENCES orders(order_id),
    product_id  VARCHAR2(10) REFERENCES products(product_id),
    quantity    NUMBER
);

-- products

CREATE TABLE products (
    product_id   VARCHAR2(10) PRIMARY KEY,
    product_name VARCHAR2(200),
    category     VARCHAR2(200)
);

さらに、2015〜2025年の期間で 500件分の架空売上データを以下のPL/SQLで生成します。
今回は、完全にランダムではなく、年ごとに売れ筋が変わる「傾向」を持たせています。

  • 2015〜2017年:A101(冷蔵庫)と A104(エアコン)がよく売れる
  • 2022〜2025年:A104(エアコン)・A105(お掃除ロボット)がよく売れる

2015〜2017年は省エネ家電(A101/A104)、2022年以降はAI家電(A104/A105)が売れやすくなるように調整しており、この後ドキュメントとして登録する商品カタログの中に「省エネ」「AI機能」などの特徴を記載しています。

👉データ生成のサンプルコードは以下をクリック

product表のデータ挿入📝
INSERT INTO products VALUES (
    'A101',
    'AERIS Frost300 Eco+(エアリス フロスト300 エコプラス)',
    '省エネ冷蔵庫 300L'
);

INSERT INTO products VALUES (
    'A102',
    'SILENTIA WashMaster 7.0(サイレンティア ウォッシュマスター)',
    '静音洗濯機 7kg'
);

INSERT INTO products VALUES (
    'A103',
    'DuraHeat Pro 20(デュラヒート プロ20)',
    '高耐久電子レンジ'
);

INSERT INTO products VALUES (
    'A104',
    'ClimaSense AI 10X(クリマセンス AI 10X)',
    '省エネエアコン 10畳対応'
);

INSERT INTO products VALUES (
    'A105',
    'RoboClean NaviX 120(ロボクリーン ナビエックス120)',
    'スマート掃除ロボット'
);
orders表とorder_items表のデータ生成📝
DECLARE
    v_order_id NUMBER := 1;
    v_date DATE;
    v_prod VARCHAR2(10);
    v_qty NUMBER;

    v_total_per_year NUMBER := 500 / 11;  -- 約45件
BEGIN
    FOR year IN 2015 .. 2025 LOOP
        FOR i IN 1 .. v_total_per_year LOOP

            v_date := DATE '2000-01-01'
                        + (year - 2000) * 365
                        + TRUNC(DBMS_RANDOM.VALUE(1, 365));

            -------------------------------------------------------------------
            -- 年代別:商品ID(件数の偏り)
            -------------------------------------------------------------------
            IF year BETWEEN 2015 AND 2017 THEN
                -- A101 & A104 が強い
                v_prod := CASE
                    WHEN DBMS_RANDOM.VALUE < 0.40 THEN 'A101'
                    WHEN DBMS_RANDOM.VALUE < 0.75 THEN 'A104'
                    WHEN DBMS_RANDOM.VALUE < 0.85 THEN 'A102'
                    WHEN DBMS_RANDOM.VALUE < 0.95 THEN 'A103'
                    ELSE 'A105'
                END;

            ELSIF year BETWEEN 2018 AND 2021 THEN
                -- 全商品ほぼ均等
                v_prod := CASE
                    WHEN DBMS_RANDOM.VALUE < 0.20 THEN 'A101'
                    WHEN DBMS_RANDOM.VALUE < 0.40 THEN 'A102'
                    WHEN DBMS_RANDOM.VALUE < 0.60 THEN 'A103'
                    WHEN DBMS_RANDOM.VALUE < 0.80 THEN 'A104'
                    ELSE 'A105'
                END;

            ELSE
                -------------------------------------------------------------------
                -- 2022〜2025:A104 & A105 がトップ2になるよう調整
                -------------------------------------------------------------------
                v_prod := CASE
                    WHEN DBMS_RANDOM.VALUE < 0.10 THEN 'A101'
                    WHEN DBMS_RANDOM.VALUE < 0.20 THEN 'A102'
                    WHEN DBMS_RANDOM.VALUE < 0.30 THEN 'A103'
                    WHEN DBMS_RANDOM.VALUE < 0.60 THEN 'A104'  -- 30%
                    ELSE 'A105'                               -- 40%
                END;
            END IF;

            -------------------------------------------------------------------
            -- 年代別:数量(quantityの偏り)
            -------------------------------------------------------------------
            IF year BETWEEN 2015 AND 2017 THEN
                IF v_prod IN ('A101','A104') THEN
                    v_qty := TRUNC(DBMS_RANDOM.VALUE(2,5));  -- 2〜4
                ELSE
                    v_qty := TRUNC(DBMS_RANDOM.VALUE(1,4));  -- 1〜3
                END IF;

            ELSIF year BETWEEN 2022 AND 2025 THEN
                -- A104 / A105 が quantity も高くなる
                IF v_prod = 'A105' THEN
                    v_qty := TRUNC(DBMS_RANDOM.VALUE(3,6));  -- 3〜5(最強)
                ELSIF v_prod = 'A104' THEN
                    v_qty := TRUNC(DBMS_RANDOM.VALUE(2,5));  -- 2〜4
                ELSE
                    v_qty := TRUNC(DBMS_RANDOM.VALUE(1,4));  -- 1〜3
                END IF;

            ELSE
                v_qty := TRUNC(DBMS_RANDOM.VALUE(1,4));  -- 均等
            END IF;

            -------------------------------------------------------------------
            -- orders
            -------------------------------------------------------------------
            INSERT INTO orders(order_id, order_date, customer_id, store_id)
            VALUES (
                v_order_id,
                v_date,
                TRUNC(DBMS_RANDOM.VALUE(1000, 2000)),
                TRUNC(DBMS_RANDOM.VALUE(1, 6))
            );

            -------------------------------------------------------------------
            -- order_items
            -------------------------------------------------------------------
            INSERT INTO order_items(order_id, product_id, quantity)
            VALUES (
                v_order_id,
                v_prod,
                v_qty
            );

            v_order_id := v_order_id + 1;
        END LOOP;
    END LOOP;

    -- 500件まで調整
    WHILE v_order_id <= 500 LOOP
        INSERT INTO orders(order_id, order_date, customer_id, store_id)
        VALUES (
            v_order_id,
            DATE '2025-12-31',
            TRUNC(DBMS_RANDOM.VALUE(1000, 2000)),
            3
        );

        INSERT INTO order_items(order_id, product_id, quantity)
        VALUES (
            v_order_id,
            'A105',
            1
        );

        v_order_id := v_order_id + 1;
    END LOOP;

    COMMIT;
END;
/

2. 商品カタログ(非構造化データ)

Object Storage に サンプルとして作成した商品カタログのPDF を配置し、
Select AI with RAG(DBMS_CLOUD_AI.CREATE_VECTOR_INDEX)を使用してベクトル化・検索を行えるようにしています。

サンプルの商品カタログは以下からダウンロードできます。

📄 商品カタログ PDF
👉 product_catalog.pdf をダウンロード

これらの2つのデータにより、いつどんな特徴のある製品がよく売れているのか、Select AI Agentを利用して推論・検索できるのかを確認していきます!

今回構築する構成

今回作成してみる構成では、Autonomous AI Database の中で Select AI Agent を動かし、
2種類のデータソース:構造化データ(注文・売上データ) と 非構造化データ(商品カタログ) の両方を参照できるエージェントを作成してみます。
そのために、2つのAgentを作成します。

  • ORDERS_ANALYST(Agent#1)
    → NL2SQL(Select AI)を使い、データベースの注文・商品データを検索

  • PRODUCT_CATALOG_SEARCHER(Agent#2)
    → RAG(Select AI with RAG)を使い、Object Storage にある PDF カタログを検索

この2つのエージェントを Agent Team として連携させることで、
「いつ・どの商品が・どんな特長で売れているか?」といった複合的な質問に対し、
テーブルデータとPDFカタログを参照しながら回答できる仕組みになっています。

image.png

■ 手順

ADBの構築

Autonomous Database (バージョン26ai)を作成します。

image.png

ユーザーの作成と必要な権限の付与

adb_agentというユーザーを作り権限を付与します。

GRANT DB_DEVELOPER_ROLE TO adb_agent identified by <your password>;
GRANT DWROLE to adb_agent;
GRANT EXECUTE on DBMS_CLOUD_AI_AGENT to adb_agent;
GRANT EXECUTE on DBMS_CLOUD_AI to adb_agent;
GRANT EXECUTE on DBMS_CLOUD_PIPELINE to adb_agent;

ADB上でACL(Access Control List)設定

以下、外部APIの利用を許可するためACLの設定をAdminユーザーで行います。

BEGIN
    DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
        host => '*', 
        ace => xs$ace_type(privilege_list => xs$name_list('connect'),
                           principal_name => 'adb_agent', 
                           principal_type => xs_acl.ptype_db)
    );

END;
/

サンプルデータのアップロード

adb_agentスキーマにテーブルを作成します。
新規作成したユーザーでデータベース・アクションからアクセスできるように、Adminユーザーでadb_agentでRESTの有効化をします。

image.png

また、「編集」からresourceconnect権限を付与します。

image.png

今回は、「使用するデータ」で説明した以下の3つの表を作成しました。

  • orders
  • order_items
  • products

クレデンシャルの作成

LLMとObject Storageを利用するためにクレデンシャルを作成します。
OCI Generative AIを利用していきます。

 BEGIN
  DBMS_CLOUD.CREATE_CREDENTIAL (
    credential_name   => 'OCI_GENAI_CRED',
    user_ocid         => '<your_user_ocid>',
    tenancy_ocid      => '<your_tenancy_ocid>',
    private_key       => '<your_private_key>',
    fingerprint       => '<your_fingerprint>'
  );
END;

AIプロファイルの作成

Select AIとSelect AI with RAGの2種類の機能を使って、それぞれデータベースと、PDFの検索を行っていくのでその準備をします。

Select AI

AIプロファイルを作成します。

BEGIN
    DBMS_CLOUD_AI.CREATE_PROFILE(
        profile_name =>'GENAI',
        attributes   =>'{
            "provider"              : "oci"
            "credential_name"       : "OCI_GENAI_CRED",
            "oci_compartment_id"    : "<your_compartment_ocid>",
            "comments"              : "TRUE",
            "conversation"          : "TRUE",
            "object_list": [
					{ "owner": "adb_agent", "name": "orders" },
					{ "owner": "adb_agent", "name": "order_items" },
					{ "owner": "adb_agent", "name": "products" }
					]
        }'
    );
END;
/

Select AI with RAG

上記に加えてPDFを検索するための設定をします。
設定の詳細は、こちらの記事で丁寧に解説されていますので、ご参照ください!
Qiita:Select AI with RAGを使ってオブジェクトストレージ内のデータと会話してみる

ドキュメントのアプロードとURIの取得

まずObject StorageにPDFファイルを格納しておきます。
今回は製品情報のカタログです。

アップロードしたドキュメントの右側の三点ボタンから「オブジェクト詳細の表示」をクリックします。

image.png

オブジェクトストレージのURI(赤枠部分)をメモしておきます。(ファイル名より前)

image.png

AIプロファイルの作成

AIプロファイルを作成します。

BEGIN
 DBMS_CLOUD_AI.CREATE_PROFILE(
       profile_name =>'RAG_PROFILE',
       attributes   =>'{"provider": "oci",
         "credential_name": "OCI_GENAI_CRED",
         "vector_index_name": "MY_INDEX",
         "embedding_model": "cohere.embed-v4.0",
         "model": "cohere.command-r-plus-08-2024"
       }');
end;
/

ベクトル索引の作成

ベクトル索引を作成します。

BEGIN
       DBMS_CLOUD_AI.CREATE_VECTOR_INDEX(
         index_name  => 'MY_INDEX',
         attributes  => '{"vector_db_provider": "oracle",
                          "location": "https://xxxxxx.objectstorage.ap-osaka-1.oci.customer-oci.com/n/xxxxxxxxx/b/backet/o/",
                          "object_storage_credential_name": "OCI_GENAI_CRED",
                          "profile_name": "RAG_PROFILE",
                          "vector_dimension": 1536,
                          "vector_distance_metric": "cosine",
                          "chunk_overlap":128,
                          "chunk_size":400,
                          "refresh_rate":1
      }');
END;
/

それぞれの検索テスト

エージェントとして動かす前に、念の為Select AIとSelect AI with RAGが正しく動くか確認しておきます。

Select AI:OK

image.png

Select AI with RAG:OK

image.png

Agent・Task・Toolの作成

ここからいよいよ"AIエージェント"部分の実装です。

Agent#1の作成:売上テーブルを検索するエージェント

Select AI(NL2SQL)を実行してテーブル検索を行うAgentを作成します。

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
        agent_name => 'ORDERS_ANALYST',
        attributes => '{"profile_name": "GENAI",
           "role": "あなたの役割は、データベース上にある注文・売り上げ・商品データなどの情報を抽出して答える役割です。"
        }'
    );
END;
/

Toolの作成

Agent#1用のSelect AIを実行するToolを作成します。

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
        tool_name  => 'ORDERS_QUERY',
        attributes => '{"instruction": "データベースにあるORDERS、ORDER_ITEMS、PRODUCTSの各テーブルを参照してデータを抽出する際に使うツールです。必要に応じて集計やフィルタリングも行います。",
            "tool_type": "SQL",
            "tool_params": {"profile_name": "GENAI"}}'
    );
END;
/

Taskの作成

Agent#1(Select AI)用のTaskを作成します。

  • enable_human_toolパラメータは、trueにすることで、エージェントがユーザーに質問して情報や説明を求めることを可能にします。デフォルト値はtrueです。

  • ここでは指定していませんが、input属性を使用してタスク間の依存関係を定義することで、Select AIは1つのタスクの出力を別のタスクに渡すことができます。これにより、連鎖推論と複数ステップのワークフローがサポートされます。

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TASK(
        task_name => 'ORDERS_ANALYSIS_TASK',
        attributes => 
            '{
                "instruction": "ORDERS表、ORDER_ITEMS表、PRODUCTS表に対するデータ検索を支援してください。ユーザからの質問: {query}。' ||
                'ORDERS表、ORDER_ITEMS表、PRODUCTS表を参照する際には ORDERS_QUERY ツールを利用してください。",
                "tools": ["ORDERS_QUERY"],
                "enable_human_tool": "False"
            }'
    );
END;
/

Agent#2の作成:商品カタログを参照するエージェント

続いてSelect AI with RAGを利用してPDFの商品カタログを参照するエージェントを作成します。

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
        agent_name => 'PRODUCT_CATALOG_SEARCHER',
        attributes => '{"profile_name": "RAG_PROFILE",
           "role": "あなたの役割は、登録されている商品カタログの情報を検索してその内容に基づいて回答する役割です。"
        }'
    );
END;
/

Toolの作成

Toolを作成します。

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
        tool_name  => 'RAG_TOOL',
        attributes => '{"instruction": "製品情報が格納されている商品カタログを参照してデータを抽出する際に使うツールです。",
            "tool_type": "RAG",
            "tool_params": {"profile_name": "RAG_PROFILE"}}'
    );
END;
/

Taskの作成

Taskを作成します。

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TASK(
        task_name => 'ANALYZE_CATALOG_TASK',
        attributes => '{"instruction": "ORDERS表、ORDER_ITEMS表、PRODUCTS表からの結果を元に、さらに製品情報に関するデータ検索してユーザーからの質問に回答します。ユーザからの質問: {query}。' ||
                '回答する際に商品情報が登録されているナレッジベースの情報を検索する時は RAG_TOOL を利用してください。",
            "tools": ["RAG_TOOL"],
            "enable_human_tool" : "False",
            "input" : "ORDERS_ANALYSIS_TASK"
        }'
    );
END;
/

Agent Teamの作成

ここまでで作成した2つのAgentをまとめて、Agent Teamを作成します。

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TEAM(  
        team_name  => 'SALES_AGENT_TEAM',
        attributes => '{"agents": [
            {"name":"ORDERS_ANALYST","task":"ORDERS_ANALYSIS_TASK"},
            {"name":"PRODUCT_CATALOG_SEARCHER","task":"ANALYZE_CATALOG_TASK"}],
        "process": "sequential"
    }');
END;
/

準備が整いました!いよいよ使ってみましょう!

■ 使ってみる!

今回はSQL Seveloperを使って試してみます。

Select ai agentを有効化

まずは今回使用するAgent teamを、DBMS_CLOUD_AI_AGENT.SET_TEAMファンクションで指定します。
Agent teamが設定されると、そのセッションではselect ai agentアクションが有効になり、他のSelect AIアクションは実行されません。

EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('SALES_AGENT_TEAM');

問い合わせを行う

それではselect ai agentに続いて、自然言語で質問を入力します。

まずは、"2025年に売れている商品の傾向"を聞いてみたいと思います。
データベースから2025年に売れている商品を特定して、その後商品カタログを参照して特徴を指摘してもらいます。

select ai agent 2025年で多く売れている上位2つの商品を特定してください。それらの商品の特徴を商品情報から分析して。;

◆ 実行結果

⇒ 事前に想定した通り、2025年に売れている商品は「AI機能」を備えていることを特徴としてまとめてくれました。

2025年の売上上位2つの商品は、スマート家電製品として生活の利便性を高める機能を備えています。商品ID A104の「ClimaSense AI 10X」は、AIを搭載したスマートエアコンで、部屋の温度や湿度を自動で調節し、快適な室内環境を実現します。商品ID A105の「RoboClean NaviX 120」は、スマート掃除ロボットで、最新のマッピングAIにより効率的な清掃ルートを計算し、短時間で部屋全体を均一に掃除できることが特徴です。
両商品に共通する特徴は、AI技術を活用した自動化機能です。AIが環境を認識し、最適な動作を自動で行い、ユーザーの負担を軽減します。この自動化機能により、ユーザーは快適な生活環境を実現し、時間を効率的に活用することができます。

image.png


続いて、2015年の傾向を聞いてみます。
以下のクエリを実行しました。

select ai agent 2015年に最も多く売れている2つの商品を特定してください。それらの商品について商品カタログで情報を検索し、共通する特徴を分析してください。;

◆ 実行結果

⇒ 期待した通り、2015年に売れている商品の共通した特徴として「省エネ」家電であることをまとめてくれました。

ClimaSense AI 10XAERIS Frost300 Eco+ は、どちらも省エネ機能に優れた製品です。ClimaSense AI 10X はエアコンで、高効率インバーターと独自の熱交換システムにより省エネを実現し、AI 制御で最適な運転モードを選択します。AERIS Frost300 Eco+ は冷蔵庫で、高効率コンプレッサーと独自の断熱構造により省エネ性能を高めています。
これらの商品の共通点は、環境に配慮した省エネ性能の高さです。AI や独自の技術により、消費電力を削減しながら快適な使用環境を提供しています。

image.png

どのように動いているか?

ここでは、上で試してみた 「2015年の売れ行きの傾向」 を尋ねたときのログをもとに、エージェントが内部でどのように動いたのかを確認します。
(提供されている履歴ビューについては、この後の章でまとめています。)

USER_AI_AGENT_TOOL_HISTORYビューを確認することで、ユーザーが質問してから最終的な回答が返ってくるまでに、複数のタスクが次のような順序で実行されたことが分かりました。
なお、どのツールに何をInputとして渡すかはAIがその都度推論して決めるため、実行の流れは質問内容によって毎回変わります。
同じ質問をまったく同じ文で繰り返した場合は、キャッシュが使われ高速に返ってきました。

以下に、今回の問い合わせで実際に使われた Agent・Tool、
それぞれが実行されたときの Input と、ツールから返ってきた Output をまとめます。

Agent Tool input output(要約版)
1 ORDERS_ANALYST ORDERS_QUERY 2015年に最も売れた上位2つの商品は何ですか? ✔ 成功。
① ClimaSense AI 10X(52個)
② AERIS Frost300 Eco+(40個)
2 ORDERS_ANALYST ORDERS_QUERY ClimaSense AI 10X と AERIS Frost300 Eco+ の製品詳細を教えてください。 ⚠ データなし(No data found)
3 ORDERS_ANALYST ORDERS_QUERY ClimaSense AI 10X と AERIS Frost300 Eco+ の製品IDを教えてください。 ⚠ データなし(No data found)
4 ORDERS_ANALYST ORDERS_QUERY 2015年に最も売れた上位2つの商品IDを教えてください。 ✔ 成功。
A104, A101
5 ORDERS_ANALYST ORDERS_QUERY 製品ID A104 と A101 の製品詳細を教えてください。 ✔ 成功。
A104:省エネエアコン(ClimaSense AI 10X)
A101:省エネ冷蔵庫(AERIS Frost300 Eco+)
6 PRODUCT_CATALOG_SEARCHER RAG_TOOL ClimaSense AI 10X と AERIS Frost300 Eco+ の商品情報 ✔ 成功。
PDF から両製品の説明文を抽出(AI制御エアコン/省エネ冷蔵庫)

SQLで最も売れている商品を特定したあと、エージェントは続けてその製品詳細をSQLで取得しようとしました。しかし、データベース側に該当情報がなかったため、このステップは失敗しています。
本来、製品カタログのような非構造化データの検索は RAG(Agent#2)が担当することを意図しています。今回のログを確認すると、エージェントが「製品詳細もSQLで取得しよう」と判断した経緯が分かり、どこで役割分担の認識がずれたのかを把握できます。
このようにログを追うことで、エージェントがどんな判断を行ったのか理解でき、必要に応じてプロンプト改善のヒントを得ることができます。

DBMS_CLOUD_AI_AGENT.RUN_TEAMファンクションでの問い合わせ

APEXやDatabase Actions、アプリケーションから実行する場合はDBMS_CLOUD_AI_AGENT.RUN_TEAMファンクションを利用します。
詳細はこちらをご参照ください。

DBMS_CLOUD_AI_AGENT.RUN_TEAMを利用する場合は以下のようなコードを実行します。
conversation_idは、Agent Teamに関連付けられた会話セッションを識別するために指定します。

DECLARE
    l_conversation_id VARCHAR2(50);
    l_final_answer VARCHAR2(4000);
BEGIN
    SELECT DBMS_CLOUD_AI.CREATE_CONVERSATION INTO l_conversation_id;
    
    l_final_answer := DBMS_CLOUD_AI_AGENT.RUN_TEAM(
        team_name => 'SALES_AGENT_TEAM',
        user_prompt => 'どんな商品がありますか',
        params => '{"conversation_id": "' || l_conversation_id || '"}'
    );
    
    DBMS_OUTPUT.PUT_LINE(l_final_answer);
END;

実行履歴の確認

エージェントがどのように処理を進めたかを確認したい場合は、以下のログから挙動を追うことができます。

今回上記の検証結果を得るために、これらのログを参照しながらプロンプトを調整しました。
もともとはドキュメントに掲載されているサンプルを参考に、各 Agent/Task/Tool の指示文を自然言語で記述していましたが、一度では上手く回答が出ず、その際、ログに残っている入力内容(Input)と出力内容(Output)を確認しながら指示文を数回修正して、より意図に沿った動作へと改善していきました。

Agent Teamの履歴

  • DBA_AI_AGENT_TEAM_HISTORY
  • USER_AI_AGENT_TEAM_HISTORY

Agent Teamがいつ実行されたかの履歴。

SELECT * FROM USER_AI_AGENT_TEAM_HISTORY;

image.png

Task単位の履歴

  • DBA_AI_AGENT_TASK_HISTORY
  • USER_AI_AGENT_TASK_HISTORY

Agent Team内でどのAgentがどのTaskをどの順番で実行されたのか、その結果を確認できます。

SELECT * FROM USER_AI_AGENT_TASK_HISTORY;

Tool単位の履歴

  • DBA_AI_AGENT_TOOL_HISTORY
  • USER_AI_AGENT_TOOL_HISTORY

Task単位の履歴で確認できる情報に加え、各ツールに対して行われた入力と出力を表示することができます。

SELECT * FROM USER_AI_AGENT_TOOL_HISTORY;

■ 終わりに

今回は、Select AI Agentを使ったAIエージェントの作成を検証しました。
実装が想像以上にシンプルで、検索の流れをイメージしながらエージェントのツールの作成を行うことが体感出来ました。

実務に応用したときの精度や使い勝手については、今後さらに試していきたいところですが、
PL/SQL だけで Agent / Task / Tool / Team が定義でき、
外部アプリケーションなしで ReAct の多段推論が動く という点は、想像以上に強力だと感じました。

今後は、より複雑なユースケースでも動かしながら、エージェント同士の連携やプロンプト設計の工夫なども試していこうと思います。今後のアップデートも楽しみです。

■ 参考

Select AI Agentのフレームワーク・構成要素・実装例などを紹介する公式ブログ

Select AI Agent の全体像・機能一覧

実際のサンプルコードなど

利用するパッケージについて

エージェントの動作を確認する履歴ビューについて

Qiita記事

大変参考にさせて頂きました。ありがとうございます。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?