1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Oracle Cloud] Autonomous Database) Select AIの回答精度を高めるビジネスコンテキスト機能(role / additional_instructions属性)を試してみた。(2026/08/17)

1
Posted at

はじめに

Oracle Select AIの「AIプロファイル」に role属性とadditional_instructions属性があります。
これらの属性は、Select AIが生成するプロンプトに追加される「システムプロンプト」のような役割を果たします。業務ルールを毎回のリクエストで繰り返し指定する代わりに、プロファイル側に一度だけ定義しておけば、そのプロファイルを使うすべてのリクエストに自動的に適用されます。

Select AIでは目的にそって複数のプロファイルタイプを作成しますが、role / additional_instructionsをどこに書くべきかはプロファイルの種類によって変わります。

プロファイルの種類 主な用途 role属性の例 additional_instructions属性の例
NL2SQLプロファイル 自然言語からのSQL生成・実行 SQL特化のアシスタント人格 日付解釈ルール、業務用語の定義、フィルタ条件、カラム表示ルール
RAGプロファイル ベクトル検索に基づく回答生成 検索結果に基づく回答アシスタント人格 検索結果のみに基づく回答の強制、ハルシネーション防止、回答スタイル
エージェントLLMプロファイル エージェント推論用のLLM設定 基本的に空、または複数エージェントで共有する場合のみ設定 複数エージェントで共有する場合のみ設定

サンプルとして航空会社(airline)の例にとって、以下の3パターンを実機検証します。

  1. NL2SQLプロファイルでのrole / additional_instructions設定とRUNSQL / EXPLAINSQLでの動作確認
  2. DBMS_CLOUD_AI.GENERATEのコール単位オーバーライド
  3. RAGプロファイル(ベクトルインデックス連携)でのNARRATE動作確認
  4. Select AI Agent Frameworkを使ったエージェントチーム(SQLツール+RAGツール)での利用

事前準備

  • Select AIを利用するための初期構成:Select AI Getting Started
  • OCI Generative AIサービス用のAI資格情報(OCI_AI_CRED)の作成:DBMS_CLOUD_AI Package
  • オブジェクトストレージ資格情報(OCI_OBJECT_STORE_CRED)の作成
  • RAG用ドキュメントのObject Storageへのアップロード:検証用のサンプル文書(英語版4件・日本語訳4件)
  • サンプルとして参照するAIRLINE.FLIGHT_OPERATIONSAIRLINE.BOOKINGSAIRLINE.ROUTE_REVENUEテーブルの作成とデータ投入、およびSelect AIプロファイルからの参照権限(object_listで指定するオブジェクトへのSELECT権限)付与:DDLとサンプルデータ生成スクリプトを本記事末に掲載しています。

手順

Step 1: NL2SQLプロファイルを作成

サンプルデータを対象としたNL2SQLプロファイルを作成します。このプロファイルには、対象データベースオブジェクト(object_list)とSQL特有の業務ルールを持たせます。

BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
    profile_name => 'AIRLINE_NL2SQL_AI',
    attributes => q'~
      {
      "provider": "oci",
      "credential_name": "OCI_AI_CRED",
      "model": "meta.llama-3.3-70b-instruct",
      "object_list": [{"owner": "AIRLINE", "name": "FLIGHT_OPERATIONS"},
                      {"owner": "AIRLINE", "name": "BOOKINGS"},
                      {"owner": "AIRLINE","name": "ROUTE_REVENUE"}],
      "role": "You are an Oracle airline analytics SQL assistant. You help analysts answer questions about flight operations, route performance, bookings, revenue, and passenger demand using the database objects available through this Oracle Select AI profile.",
      "additional_instructions": "Use the current database date when interpreting relative dates such as today, yesterday, this week, last week, this month, and last month. Treat a delayed flight as a flight with arrival_delay_minutes greater than 15. Exclude cancelled flights unless the request explicitly asks about cancellations. For route analysis, group routes by origin_airport_code and destination_airport_code. When generating SQL, prefer clear column aliases that business analysts can understand. Keep answers focused on operational metrics available from the configured database objects."
      }
    ~'
  );
END;
/
  • role:
    • あなたは、Oracle Airline Analytics SQL Assistantです。このOracle Select AIプロファイルで使用可能なデータベース・オブジェクトを使用して、アナリストがフライト・オペレーション、ルート・パフォーマンス、予約、収益および乗客需要に関する質問に回答できるようにします。
  • additional_instructions:
    • 現在のデータベース日付は、今日、昨日、今週、先週、今月、先月などの相対的な日付を解釈するときに使用します。遅延フライトを、arrival_delay_minutesが15を超えるフライトとして処理します。リクエストが明示的にキャンセルを要求しないかぎり、キャンセルされたフライトを除外します。ルート分析では、origin_airport_codeおよびdestination_airport_codeでルートをグループ化します。SQLを生成する場合は、ビジネス・アナリストが理解できる明確な列の別名を優先します。構成済データベース・オブジェクトから使用可能な操作メトリックにフォーカスした回答を保持します。

<credential_name>OCI_AI_CRED)と<object_list>内の<owner> / <name>は、実際に用意した資格情報名・テーブル名に置き換えてください。

Step 2: プロファイルを有効化し、roleの反映を確認

作成したプロファイルをSQL用のアクティブプロファイルとして設定します。

EXEC DBMS_CLOUD_AI.SET_PROFILE('AIRLINE_NL2SQL_AI');

role属性が反映されているかは、簡単なchatリクエストで確認できます。

SELECT AI CHAT 'who are you?'

想定レスポンス例は以下の通りです。

RESPONSE
------------------------------------------------------------
I am an Oracle airline analytics SQL assistant. I can help you
analyze flight operations, route performance, bookings, revenue,
and passenger demand using the database objects available through
this profile.

実行例)

SQL> EXEC DBMS_CLOUD_AI.SET_PROFILE('AIRLINE_NL2SQL_AI');

PL/SQL procedure successfully completed.

SQL> SELECT AI CHAT 'who are you?';

RESPONSE
--------------------------------------------------------------------------------
I am an Oracle airline analytics SQL assistant. I help analysts answer questions
 about flight operations, route performance, bookings, revenue, and passenger de
mand using the database objects available. I provide SQL queries to extract insi
ghts from the data, focusing on operational metrics such as flight delays, cance
llations, route performance, and passenger demand.

日本語訳)
私はOracle Airline Analytics SQL Assistantです。アナリストが、利用可能なデータベース・オブジェクトを使用して、フライト・オペレーション、ルート・パフォーマンス、予約、収益および乗客の需要に関する質問に回答できるように支援します。フライトの遅延、キャンセル、ルートのパフォーマンス、乗客の需要などの運用メトリックに焦点を当てて、データからインサイトを抽出するSQLクエリを提供します。

role / additional_instructions属性は、以下のプロシージャで設定・変更できます。

  • DBMS_CLOUD_AI.CREATE_PROFILE — AIプロファイルに永続的な属性を設定する
  • DBMS_CLOUD_AI.SET_ATTRIBUTE — 既存プロファイルの属性を変更する
  • DBMS_CLOUD_AI.GENERATE — 個々のSelect AIリクエストに対して属性を動的にオーバーライドする

Step 3: 業務ルールを繰り返さずにSQLアクションを実行

遅延・日付・キャンセル・ルートのグルーピングに関するルールを繰り返さずに、業務上の質問をそのまま投げます。

SELECT AI RUNSQL What were the top 5 delayed routes last week?

NL2SQLプロファイルに再利用可能なSQL用の指示がすでに含まれているため、Select AIは「delayed」「route」「last week」を一貫した意味で解釈できます。生成されるSQLは、相対的な日付範囲に現在のデータベース日付を使用し、キャンセル便を除外し、標準の遅延定義を適用し、出発地・到着地の空港コードで結果をグルーピングします。

実行例)

SQL> SELECT AI RUNSQL What were the top 5 delayed routes last week?;

Ori Des Number of Delayed Flights Average Delay Minutes
--- --- ------------------------- ---------------------
SFO LAX                        14            56.5714286
BOS ATL                        12            41.6666667
ORD DFW                        11                    37
DFW ORD                        11            41.7272727
SEA DEN                        11            42.8181818

EXPLAINSQLアクションを使うと、Select AIがどのようにクエリを解釈したかを確認できます。

SELECT AI EXPLAINSQL What were the top 5 delayed routes last week?

この説明にも、NL2SQLプロファイルのガイダンス(遅延便の定義がarrival_delay_minutes > 15であること、出発地・到着地空港コードでルートをグルーピングすることなど)が反映されます。

実行例)

SQL> SELECT AI EXPLAINSQL What were the top 5 delayed routes last week?;

RESPONSE
------------------------------------------------------------------------------------------------------------------------
To find the top 5 delayed routes last week, we need to consider flights from the "AIRLINE"."FLIGHT_OPERATIONS" table whe
re the "ARRIVAL_DELAY_MINUTES" is greater than 15 and the "CANCELLED_FLAG" is 'N'. We will filter the flights to only in
clude those that occurred last week.

Here is the SQL query to solve this problem:

SELECT
  fo."ORIGIN_AIRPORT_CODE" AS "Origin Airport",
  fo."DESTINATION_AIRPORT_CODE" AS "Destination Airport",
  COUNT(fo."FLIGHT_ID") AS "Number of Delayed Flights",
  AVG(fo."ARRIVAL_DELAY_MINUTES") AS "Average Delay Minutes"
FROM
  "AIRLINE"."FLIGHT_OPERATIONS" fo
WHERE
  fo."CANCELLED_FLAG" = 'N'
  AND fo."ARRIVAL_DELAY_MINUTES" > 15
  AND fo."FLIGHT_DATE" >= TRUNC(SYSDATE) - 7
  AND fo."FLIGHT_DATE" < TRUNC(SYSDATE)
GROUP BY
  fo."ORIGIN_AIRPORT_CODE", fo."DESTINATION_AIRPORT_CODE"
ORDER BY
  COUNT(fo."FLIGHT_ID") DESC
FETCH FIRST 5 ROWS ONLY;

This query works as follows:

1. It selects the origin airport code, destination airport code, the number of delayed flights, and the average delay mi
nutes for each route.
2. It filters the flights to exclude cancelled flights and only include flights with an arrival delay greater than 15 mi
nutes.
3. It filters the flights to only include those that occurred last week by comparing the flight date to the current date
.
4. It groups the results by the origin and destination airport codes.
5. It orders the results by the number of delayed flights in descending order and returns the top 5 routes.

Note: The `TRUNC(SYSDATE)` function is used to get the current date without the time component, and `TRUNC(SYSDATE) - 7`
 is used to get the date from last week. The `FETCH FIRST 5 ROWS ONLY` clause is used to return only the top 5 routes.

Step 4: GENERATEコール単位でrole / additional_instructionsをオーバーライドする

永続的なプロファイル属性は、そのプロファイルを使うすべてのリクエストに適用したいガイダンスに向いています。一方で、保存済みのAIプロファイルを変更せずに、1回のリクエストだけアシスタントの振る舞いを調整したい場合もあります。そのようなときはDBMS_CLOUD_AI.GENERATEattributesパラメータでコール単位のオーバーライドが可能です。

以下の例では、AIRLINE_NL2SQL_AIプロファイルのプロバイダー・モデル・資格情報・object_listはそのまま使いつつ、1回の「エグゼクティブ向けレポート」リクエストに限ってroleadditional_instructionsを上書きしています。

SELECT DBMS_CLOUD_AI.GENERATE(
  prompt => 'What were the top 5 delayed routes last week?',
  profile_name => 'AIRLINE_NL2SQL_AI',
  action => 'runsql',
  attributes => q'~
    {
    "role": "You are an Oracle airline executive reporting SQL assistant. Prioritize concise operational summaries for airline executives.",
    "additional_instructions": "For this request, treat last week as the previous Monday through Sunday based on the current database date. Return only the top 5 routes. Include delayed flight counts and average delay minutes. Use the profile's delayed-flight definition. Keep column aliases short and executive-friendly."
    }
    ~'
  ) AS response
FROM dual;

このオーバーライドはAIRLINE_NL2SQL_AIプロファイル自体を変更しません。今回のリクエストに対してのみSelect AIの解釈・制約を一時的に変え、次の呼び出しではプロファイルは通常の振る舞いに戻ります。シナリオ固有の挙動やセッションごとのパーソナライズ、レスポンススタイルの選択、一時的な制約などが必要な場面で、別の永続プロファイルを増やしたり共有プロファイルを書き換えたりせずに対応できます。

実行例)

SQL> SELECT DBMS_CLOUD_AI.GENERATE(
  prompt => 'What were the top 5 delayed routes last week?',
  profile_name => 'AIRLINE_NL2SQL_AI',
  action => 'runsql',
  attributes => q'~
    {
    "role": "You are an Oracle airline executive reporting SQL assistant. Prioritize concise operational summaries for airline executives.",
    "additional_instructions": "For this request, treat last week as the previous Monday through Sunday based on the current database date. Return only the top 5 routes. Include delayed flight counts and average delay minutes. Use the profile's delayed-flight definition. Keep column aliases short and executive-friendly."
    }
    ~'
    ) AS response
FROM dual;

RESPONSE
--------------------------------------------------------------------------------
[
  {
    "ORIG" : "SFO",
    "DEST" : "LAX",
    "DELAYED_COUNT" : 12,
    "AVG_DELAY" : 52.5
  },
  {
    "ORIG" : "DFW",
    "DEST" : "ORD",
    "DELAYED_COUNT" : 12,
    "AVG_DELAY" : 31.08333333333333333333333333333333333333
  },
  {
    "ORIG" : "LAX",
    "DEST" : "SFO",
    "DELAYED_COUNT" : 12,
    "AVG_DELAY" : 30.33333333333333333333333333333333333333
  },
  {
    "ORIG" : "ORD",
    "DEST" : "DFW",
    "DELAYED_COUNT" : 12,
    "AVG_DELAY" : 30.75
  },
  {
    "ORIG" : "SEA",
    "DEST" : "DEN",
    "DELAYED_COUNT" : 11,
    "AVG_DELAY" : 33.81818181818181818181818181818181818182
  }
] 

Step 5: RAGプロファイルを作成

RAGプロファイルは、検索拡張生成(RAG)用に構成され、根拠のある応答を生成します。ここでは、承認済みの航空会社ポリシー・運航・カスタマーサービス関連文書に対するベクトルインデックスを参照するRAGプロファイルを作成します。

BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
    profile_name => 'AIRLINE_POLICY_RAG_AI',
    attributes => q'~
      {
      "provider": "oci",
      "credential_name": "OCI_AI_CRED",
      "model": "meta.llama-3.3-70b-instruct",
      "vector_index_name": "AIRLINE_POLICY_INDEX",
      "oci_compartment_id": "ocid1.compartment.oc1..example",
      "max_tokens": 3000,
      "role": "You are an Oracle airline policy retrieval assistant. You help operations and support teams answer questions using retrieved airline policy, operations, and customer service content.",
      "additional_instructions": "Answer using retrieved content from approved airline policy, operations, and customer service documents. Do not invent policy details that are not present in the retrieved content. Distinguish domestic and international policy when the retrieved content makes that distinction. Keep responses concise and suitable for operations or customer support teams. Include source references when available."
      }
    ~'
  );
END;
/

<oci_compartment_id>ocid1.compartment.oc1..example)は、実際に利用するOCIコンパートメントのOCIDに置き換えてください。

続けて、このRAGプロファイルが参照するベクトルインデックスを作成します。

BEGIN
  DBMS_CLOUD_AI.CREATE_VECTOR_INDEX(
    index_name => 'AIRLINE_POLICY_INDEX',
    attributes => q'~
      {
      "vector_db_provider": "oracle",
      "location": "https://objectstorage.example.com/n/namespace/b/bucket/o/airline_policy_docs/",
      "object_storage_credential_name": "OCI_OBJECT_STORE_CRED",
      "profile_name": "AIRLINE_POLICY_RAG_AI",
      "chunk_overlap": 128,
      "chunk_size": 1024
      }
    ~'
  );
END;
/

<location>https://objectstorage.example.com/n/namespace/b/bucket/o/airline_policy_docs/)と<object_storage_credential_name>OCI_OBJECT_STORE_CRED)は、実際に用意したObject Storageのパスと資格情報名に置き換えてください。

Step 6: RAGプロファイルで根拠付きの回答を確認する

検索結果に基づいた回答を得るために、RAGプロファイルをアクティブに切り替えます。

EXEC DBMS_CLOUD_AI.SET_PROFILE('AIRLINE_POLICY_RAG_AI');

サポート担当者は、共通の指示を繰り返さずにポリシーに関する質問ができるようになります。

SELECT AI NARRATE Summarize the customer service policy for passengers affected by delayed flights.

実行例)RAGプロファイルの検索特有の指示が含まれているため、出典情報も含めた回答になります。

SQL> EXEC DBMS_CLOUD_AI.SET_PROFILE('AIRLINE_POLICY_RAG_AI');

PL/SQL procedure successfully completed.



SQL> SELECT AI NARRATE Summarize the customer service policy for passengers affected by delayed flights.;

RESPONSE
------------------------------------------------------------------------------------------------------------------------
Passengers affected by delayed flights are entitled to certain services and compensations based on the duration and caus
e of the delay. For delays of 3 hours or more, or cancellations, passengers will be offered rebooking options, and may b
e eligible for cash compensation or travel credits, depending on the reason for the delay and the route. Care services s
uch as meal vouchers and hotel accommodations may also be provided. The airline's customer service policy is outlined in
 documents such as "Customer Service Policy: Delayed Flight Handling" and "Compensation and Rebooking Policy".

Sources:
  - compensation_and_rebooking_policy.txt (https://objectstorage.example.com/n/namespace/b/bucket/o/airline_policy_docs/compensation_and_rebooking_policy.txt)
  - customer_notification_procedures.txt (https:/objectstorage.example.com/n/namespace/b/bucket/o/airline_policy_docs/customer_notification_procedures.txt)
  - operations_playbook_delay_classification.txt (https://objectstorage.example.com/n/namespace/b/bucket/o/airline_policy_docs/operations_playbook_delay_classification.txt)

補足: 応答を日本語にする

Select AIには応答言語を指定する専用の属性(languageのようなもの)はありません。source_language / target_language属性はTRANSLATEアクション専用であり、NARRATEのような通常のアクションの応答言語には使えません。日本語で回答させたい場合は、role / additional_instructionsに日本語指定を明示する必要があります。

AIRLINE_POLICY_RAG_AIプロファイルを使うすべてのリクエストで日本語回答を強制したい場合は、SET_ATTRIBUTEadditional_instructionsを更新します。

BEGIN
  DBMS_CLOUD_AI.SET_ATTRIBUTE(
    profile_name => 'AIRLINE_POLICY_RAG_AI',
    attribute_name => 'additional_instructions',
    attribute_value => 'Answer using retrieved content from approved airline policy, operations, and customer service documents. Do not invent policy details that are not present in the retrieved content. Distinguish domestic and international policy when the retrieved content makes that distinction. Keep responses concise and suitable for operations or customer support teams. Include source references when available. Always respond in Japanese (日本語で回答してください), regardless of the language of the retrieved source documents or the language of the question.'
  );
END;
/

これで、英語で質問しても英語ドキュメントを検索対象にしていても、応答は日本語になります。

SELECT AI NARRATE Summarize the customer service policy for passengers affected by delayed flights.

プロファイル自体は変更せず、1回のリクエストだけ日本語で受け取りたい場合は、DBMS_CLOUD_AI.GENERATEでコール単位のオーバーライドもできます。

SELECT DBMS_CLOUD_AI.GENERATE(
  prompt => 'Summarize the customer service policy for passengers affected by delayed flights.',
  profile_name => 'AIRLINE_POLICY_RAG_AI',
  action => 'narrate',
  attributes => q'~
    {
    "additional_instructions": "Always respond in Japanese (日本語で回答してください), regardless of the language of the retrieved source documents."
    }
    ~'
  ) AS response
FROM dual;

実行例)

SQL>  SELECT AI NARRATE フライトの遅延により影響を受けた乗客向けのカスタマーサービス・ポリシーを要約してください。;

RESPONSE
------------------------------------------------------------------------------------------------------------------------
フライトの遅延により影響を受けた乗客向けのカスタマーサービス・ポリシーは、遅延の重大度に応じてサービス回復措置を適用する
ものである。軽度遅延(15分以上59分以下)については、補償義務はないが、ゲート担当者の裁量により無料の飲料券を提供する場合
がある。長時間遅延(60分以上179分以下)については、乗客に対し追加費用なしで次の利用可能な便への振替を提案しなければなら
ない。重大遅延(180分以上)については、乗客に対し振替便の手配、食事券の発行に加え、宿泊を伴う運航中断となる場合はホテル
宿泊と送迎の手配を行わなければならない。

Sources:
  - customer_service_policy_delayed_flights.txt (https://objectstorage.example.com/n/namespace/b/bucket/o/airline_policy_docs/customer_service_policy_delayed_flights.txt)

検索そのもの(どのドキュメントがヒットするか)は言語指定の影響を受けません。

Step 7: エージェントチーム用の最小LLMプロファイルを作成

Select AI Agent Frameworkでは、エージェント自身がroleパラメータを持ちます。エージェント固有のペルソナやジョブはそちらで定義するのが基本です。そのため、エージェント推論用のLLMプロファイルは、フル装備のロールを持たせず最小限にとどめます。

BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
    profile_name => 'AIRLINE_AGENT_LLM',
    attributes => q'~
      {
      "provider": "oci",
      "credential_name": "OCI_AI_CRED",
      "model": "meta.llama-3.3-70b-instruct",
      "temperature": 0.2
      }
    ~'
  );
END;
/

このプロファイルには航空運用のロールを持たせません。ロールはエージェントオブジェクト側に属します。こうすることで、エージェント固有のロール指示と競合させずに、エージェント推論用としてプロファイルを再利用可能な状態に保てます。

Step 8: SQLツールとRAGツールをそれぞれ別プロファイルで作成

SQLツールはNL2SQLプロファイルを、RAGツールはRAGプロファイルを使用します。2つのツールで1つのプロファイルを共有しません。

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name => 'AIRLINE_SQL_TOOL',
    attributes => '{
      "tool_type": "SQL",
      "tool_params": {"profile_name": "AIRLINE_NL2SQL_AI"}
    }'
  );
END;
/
BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name => 'AIRLINE_RAG_TOOL',
    attributes => '{
      "tool_type": "RAG",
      "tool_params": {"profile_name": "AIRLINE_POLICY_RAG_AI"}
      }'
    );
END;
/

Step 9: エージェント・タスク・チームを作成し、実行する

エージェントのロールはエージェントオブジェクト側に、オーケストレーションのガイダンスはタスク側に定義します。エージェント固有の振る舞いはここに置くのが基本です。

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
    agent_name => 'AIRLINE_OPS_AGENT',
    attributes => q'~
      {
      "profile_name": "AIRLINE_AGENT_LLM",
      "role": "You are an airline operations coordinator. Use the available tools to answer operational questions, combine metrics and policy context when needed, and explain assumptions clearly."
      }
    ~'
  );
END;
/
BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TASK(
    task_name => 'INVESTIGATE_DELAY_TASK',
    attributes => q'~
      {
      "instruction": "Investigate the user's airline operations question: {query}. Use AIRLINE_SQL_TOOL for flight performance metrics and AIRLINE_RAG_TOOL for policy or operations-document context. Keep the final response concise and call out any SQL metric definitions or policy sources used.",
      "tools": ["AIRLINE_SQL_TOOL", "AIRLINE_RAG_TOOL"],
      "enable_human_tool": "true"
    }
  ~'
);
END;
/
BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TEAM(
    team_name => 'AIRLINE_OPS_TEAM',
    attributes => '{
      "agents": [
        {"name": "AIRLINE_OPS_AGENT", "task": "INVESTIGATE_DELAY_TASK"}
      ],
      "process": "sequential"
    }'
  );
END;
/

チームを設定して実行します。

EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('AIRLINE_OPS_TEAM');
SELECT AI AGENT Investigate why delayed flights increased last week and summarize the likely causes.

このパターンでは、エージェントが運航実績にはSQLツールを、ポリシーや運用ドキュメントにはRAGツールを使い分けます。各ツールはそれぞれのジョブに適したプロファイルレベルの指示を持ち、エージェントのロールとタスク指示がワークフロー全体を調整します。1つのプロファイルにNL2SQLとRAGの両方の役割を持たせる必要はありません。

実行例)

SQL> SELECT AI AGENT Investigate why delayed flights increased last week and summarize the likely causes.;

RESPONSE
------------------------------------------------------------------------------------------------------------------------
The likely causes of the increased delayed flights last week can be attributed to various factors such as operational de
lays, weather-related delays, ATC delays, maintenance-related delays, and crew-related delays. To determine the exact ca
uses, it is recommended to analyze the root causes tagged in the OCC system within 60 minutes of the delay being identif
ied, as per the guidelines in the "Operations Playbook: Delay Classification" document. Additionally, the "Customer Serv
ice Policy: Delayed Flight Handling" document provides guidance on handling delayed flights, including notification proc
edures and compensation policies for affected passengers.

クリーンアップ

検証で作成したリソースを削除します。

-- エージェントチーム関連の削除
EXEC DBMS_CLOUD_AI_AGENT.DROP_TEAM('AIRLINE_OPS_TEAM');
EXEC DBMS_CLOUD_AI_AGENT.DROP_TASK('INVESTIGATE_DELAY_TASK');
EXEC DBMS_CLOUD_AI_AGENT.DROP_AGENT('AIRLINE_OPS_AGENT');
EXEC DBMS_CLOUD_AI_AGENT.DROP_TOOL('AIRLINE_RAG_TOOL');
EXEC DBMS_CLOUD_AI_AGENT.DROP_TOOL('AIRLINE_SQL_TOOL');

-- ベクトルインデックスの削除
EXEC DBMS_CLOUD_AI.DROP_VECTOR_INDEX('AIRLINE_POLICY_INDEX');

-- AIプロファイルの削除
EXEC DBMS_CLOUD_AI.DROP_PROFILE('AIRLINE_AGENT_LLM');
EXEC DBMS_CLOUD_AI.DROP_PROFILE('AIRLINE_POLICY_RAG_AI');
EXEC DBMS_CLOUD_AI.DROP_PROFILE('AIRLINE_NL2SQL_AI');

おわりに

今回の検証で確認できたポイントは以下の通りです。

  • role / additional_instructions属性をAIプロファイルに設定すると、業務ルールや日付解釈・回答スタイルなどのガイダンスを毎回のプロンプトに書かずに、chat / runsql / showsql / explainsql / narrateのいずれのアクションでも一貫して適用できる。
  • NL2SQL用・RAG用・エージェントLLM用でプロファイルを分けることで、それぞれの目的に合ったガイダンスだけを持たせる「目的別プロファイル」の設計が実現できる。
  • DBMS_CLOUD_AI.GENERATEattributesパラメータを使うことで、永続プロファイルを変更せずにコール単位でロールや指示を一時的にオーバーライドできる。
  • Select AI Agent Frameworkでは、SQLツール・RAGツールにそれぞれ専用プロファイルを紐づけ、エージェント自体のペルソナはエージェントオブジェクトのroleとタスクの指示に持たせる構成が確認できる。
  • role / additional_instructionsはモデルの振る舞いを誘導するものであり、アクセス制御はデータベース権限・object_list・プロファイル構成・アプリケーションやエージェントの設計で担保する必要がある。

この機能は、複数の分析担当者やアプリケーションがSelect AIを利用する組織において、プロンプトの重複を減らしつつ、部署ごと・用途ごとに一貫したアシスタントの振る舞いをガバナンスしたい管理者や開発者に特に有用だと考えられます。

参考情報

setup_airline_sample_data.sql
-- =====================================================================
-- Select AI 検証用サンプルスキーマ: AIRLINE
-- 対象テーブル: FLIGHT_OPERATIONS / BOOKINGS / ROUTE_REVENUE
--
-- 「先週」「昨日」「当四半期」等の相対日付クエリが意味のある結果を返すよう、
-- サンプルデータは SYSDATE を基準にした相対日付で生成しています。
-- =====================================================================

-- ---------------------------------------------------------------------
-- 0. AIRLINEユーザー(スキーマ)の作成 ※既に存在する場合はスキップ
--    Autonomous Databaseの場合、ADMINユーザーで実行してください。
-- ---------------------------------------------------------------------
-- CREATE USER AIRLINE IDENTIFIED BY "<強力なパスワード>";
-- GRANT DB_DEVELOPER_ROLE TO AIRLINE;
-- ALTER USER AIRLINE QUOTA UNLIMITED ON DATA;

-- 以降は AIRLINE ユーザーに接続して実行してください。
-- ALTER SESSION SET CURRENT_SCHEMA = AIRLINE;

-- ---------------------------------------------------------------------
-- 1. テーブル定義
-- ---------------------------------------------------------------------

-- 1-1. 運航実績テーブル
--      additional_instructions 内の "arrival_delay_minutes" 判定、
--      "origin_airport_code" / "destination_airport_code" による
--      ルートのグルーピング、キャンセル便の除外に対応する列を持ちます。
CREATE TABLE AIRLINE.FLIGHT_OPERATIONS (
    flight_id                  NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    flight_date                DATE            NOT NULL,
    carrier_code                VARCHAR2(2)     NOT NULL,
    flight_number                VARCHAR2(6)     NOT NULL,
    origin_airport_code          VARCHAR2(3)     NOT NULL,
    destination_airport_code     VARCHAR2(3)     NOT NULL,
    scheduled_departure_time     TIMESTAMP       NOT NULL,
    actual_departure_time        TIMESTAMP,
    scheduled_arrival_time       TIMESTAMP       NOT NULL,
    actual_arrival_time          TIMESTAMP,
    departure_delay_minutes      NUMBER          DEFAULT 0,
    arrival_delay_minutes        NUMBER          DEFAULT 0,
    cancelled_flag                CHAR(1)         DEFAULT 'N'
        CONSTRAINT chk_flt_cancelled CHECK (cancelled_flag IN ('Y','N')),
    cancellation_reason           VARCHAR2(100),
    aircraft_type                  VARCHAR2(20),
    seats_available                 NUMBER,
    passengers_boarded              NUMBER
);

COMMENT ON COLUMN AIRLINE.FLIGHT_OPERATIONS.arrival_delay_minutes IS
  '到着遅延分数。additional_instructionsで「15分超を遅延便」と定義';
COMMENT ON COLUMN AIRLINE.FLIGHT_OPERATIONS.cancelled_flag IS
  'Y=キャンセル便。additional_instructionsで明示的な要求が無い限り除外対象';

-- 1-2. 予約テーブル(旅客需要・搭乗クラス)
CREATE TABLE AIRLINE.BOOKINGS (
    booking_id                   NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    flight_id                     NUMBER          NOT NULL
        CONSTRAINT fk_bkg_flight REFERENCES AIRLINE.FLIGHT_OPERATIONS(flight_id),
    booking_date                   DATE            NOT NULL,
    passenger_id                    NUMBER          NOT NULL,
    origin_airport_code               VARCHAR2(3)     NOT NULL,
    destination_airport_code          VARCHAR2(3)     NOT NULL,
    ticket_class                       VARCHAR2(10)    DEFAULT 'ECONOMY'
        CONSTRAINT chk_bkg_class CHECK (ticket_class IN ('ECONOMY','PREMIUM','BUSINESS','FIRST')),
    fare_amount                         NUMBER(10,2)    NOT NULL,
    booking_status                       VARCHAR2(12)    DEFAULT 'CONFIRMED'
        CONSTRAINT chk_bkg_status CHECK (booking_status IN ('CONFIRMED','CANCELLED','WAITLISTED'))
);

-- 1-3. ルート別収益テーブル(月次)
--      "monthly revenue by route for the current quarter" のような
--      SHOWSQL/RUNSQLクエリの対象になる集計テーブルです。
CREATE TABLE AIRLINE.ROUTE_REVENUE (
    revenue_id                  NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    revenue_month                 DATE            NOT NULL,  -- 対象月の月初日
    origin_airport_code             VARCHAR2(3)     NOT NULL,
    destination_airport_code        VARCHAR2(3)     NOT NULL,
    net_ticket_revenue               NUMBER(12,2)    NOT NULL, -- 税・手数料を除く純運賃収益
    taxes_and_fees                     NUMBER(12,2)    NOT NULL,
    gross_revenue                       NUMBER(12,2) GENERATED ALWAYS AS
        (net_ticket_revenue + taxes_and_fees) VIRTUAL,
    currency_code                        VARCHAR2(3)     DEFAULT 'USD'
);

COMMENT ON COLUMN AIRLINE.ROUTE_REVENUE.net_ticket_revenue IS
  'additional_instructionsで「Revenueは税・手数料を除く純運賃収益」と定義';

-- ---------------------------------------------------------------------
-- 2. Select AIプロファイル所有者への参照権限付与
--    (プロファイルをAIRLINE以外のユーザーで作成する場合のみ実行)
-- ---------------------------------------------------------------------
-- GRANT SELECT ON AIRLINE.FLIGHT_OPERATIONS TO <Select AIプロファイル作成ユーザー>;
-- GRANT SELECT ON AIRLINE.BOOKINGS         TO <Select AIプロファイル作成ユーザー>;
-- GRANT SELECT ON AIRLINE.ROUTE_REVENUE    TO <Select AIプロファイル作成ユーザー>;

-- ---------------------------------------------------------------------
-- 3. サンプルデータ生成
-- ---------------------------------------------------------------------

-- 3-1. FLIGHT_OPERATIONS: 過去21日分 × 8ルート × 1日2便
--      SFO-LAX を意図的に遅延多め(元記事の結果例に近い傾向)にしています。
DECLARE
    TYPE route_rec IS RECORD (origin VARCHAR2(3), destination VARCHAR2(3));
    TYPE route_tab IS TABLE OF route_rec;
    v_routes   route_tab := route_tab(
        route_rec('SFO','LAX'), route_rec('JFK','MIA'), route_rec('ORD','DFW'),
        route_rec('SEA','DEN'), route_rec('ATL','BOS'), route_rec('LAX','SFO'),
        route_rec('DFW','ORD'), route_rec('BOS','ATL')
    );
    v_carriers SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST('AA','UA','DL','WN');
    v_flight_date DATE;
    v_delay       NUMBER;
    v_dep_delay   NUMBER;
    v_cancelled   CHAR(1);
    v_seats       NUMBER := 150;
    v_pax         NUMBER;
BEGIN
    FOR d IN 0..20 LOOP                       -- 過去21日分(直近3週間)
        v_flight_date := TRUNC(SYSDATE) - d;
        FOR r IN 1..v_routes.COUNT LOOP
            FOR f IN 1..2 LOOP                -- 1ルートあたり1日2便
                v_cancelled := CASE WHEN DBMS_RANDOM.VALUE(0,1) < 0.03 THEN 'Y' ELSE 'N' END;
                v_delay     := ROUND(DBMS_RANDOM.VALUE(0,60));

                -- SFO-LAXを遅延多めの傾向にする(元記事の結果例に寄せる)
                IF v_routes(r).origin = 'SFO' AND v_routes(r).destination = 'LAX' THEN
                    v_delay := v_delay + ROUND(DBMS_RANDOM.VALUE(15,45));
                END IF;

                v_dep_delay := GREATEST(0, v_delay - ROUND(DBMS_RANDOM.VALUE(0,10)));
                v_pax       := ROUND(v_seats * DBMS_RANDOM.VALUE(0.6, 0.98));

                INSERT INTO AIRLINE.FLIGHT_OPERATIONS (
                    flight_date, carrier_code, flight_number,
                    origin_airport_code, destination_airport_code,
                    scheduled_departure_time, actual_departure_time,
                    scheduled_arrival_time, actual_arrival_time,
                    departure_delay_minutes, arrival_delay_minutes,
                    cancelled_flag, cancellation_reason,
                    aircraft_type, seats_available, passengers_boarded
                ) VALUES (
                    v_flight_date,
                    v_carriers(MOD(r + f, v_carriers.COUNT) + 1),
                    LPAD(TO_CHAR(1000 + r * 10 + f), 4, '0'),
                    v_routes(r).origin, v_routes(r).destination,
                    CAST(v_flight_date AS TIMESTAMP) + NUMTODSINTERVAL(6 + f, 'HOUR'),
                    CAST(v_flight_date AS TIMESTAMP) + NUMTODSINTERVAL(6 + f, 'HOUR')
                        + NUMTODSINTERVAL(v_dep_delay, 'MINUTE'),
                    CAST(v_flight_date AS TIMESTAMP) + NUMTODSINTERVAL(9 + f, 'HOUR'),
                    CASE WHEN v_cancelled = 'Y' THEN NULL
                         ELSE CAST(v_flight_date AS TIMESTAMP) + NUMTODSINTERVAL(9 + f, 'HOUR')
                              + NUMTODSINTERVAL(v_delay, 'MINUTE')
                    END,
                    v_dep_delay,
                    CASE WHEN v_cancelled = 'Y' THEN NULL ELSE v_delay END,
                    v_cancelled,
                    CASE WHEN v_cancelled = 'Y' THEN 'WEATHER' ELSE NULL END,
                    CASE MOD(r,3) WHEN 0 THEN 'B737' WHEN 1 THEN 'A320' ELSE 'B787' END,
                    v_seats,
                    CASE WHEN v_cancelled = 'Y' THEN 0 ELSE v_pax END
                );
            END LOOP;
        END LOOP;
    END LOOP;
    COMMIT;
END;
/

-- 3-2. BOOKINGS: 各便に対して3〜8件の予約をランダム生成
DECLARE
    v_num_bookings NUMBER;
    v_class        VARCHAR2(10);
    v_fare         NUMBER;
    v_status       VARCHAR2(12);
BEGIN
    FOR flt IN (
        SELECT flight_id, flight_date, origin_airport_code,
               destination_airport_code, cancelled_flag
        FROM AIRLINE.FLIGHT_OPERATIONS
    ) LOOP
        v_num_bookings := ROUND(DBMS_RANDOM.VALUE(3,8));
        FOR b IN 1..v_num_bookings LOOP
            v_class := CASE
                           WHEN DBMS_RANDOM.VALUE(0,1) < 0.70 THEN 'ECONOMY'
                           WHEN DBMS_RANDOM.VALUE(0,1) < 0.90 THEN 'PREMIUM'
                           ELSE 'BUSINESS'
                       END;
            v_fare := CASE v_class
                          WHEN 'ECONOMY'  THEN ROUND(DBMS_RANDOM.VALUE(120,320),2)
                          WHEN 'PREMIUM'  THEN ROUND(DBMS_RANDOM.VALUE(320,550),2)
                          ELSE                  ROUND(DBMS_RANDOM.VALUE(550,1200),2)
                      END;
            v_status := CASE WHEN flt.cancelled_flag = 'Y' THEN 'CANCELLED' ELSE 'CONFIRMED' END;

            INSERT INTO AIRLINE.BOOKINGS (
                flight_id, booking_date, passenger_id,
                origin_airport_code, destination_airport_code,
                ticket_class, fare_amount, booking_status
            ) VALUES (
                flt.flight_id,
                flt.flight_date - ROUND(DBMS_RANDOM.VALUE(1,30)),  -- 搭乗日より前に予約
                ROUND(DBMS_RANDOM.VALUE(100000,999999)),
                flt.origin_airport_code, flt.destination_airport_code,
                v_class, v_fare, v_status
            );
        END LOOP;
    END LOOP;
    COMMIT;
END;
/

-- 3-3. ROUTE_REVENUE: 過去6ヶ月分(当四半期を含む)のルート別月次収益
DECLARE
    TYPE route_rec IS RECORD (origin VARCHAR2(3), destination VARCHAR2(3));
    TYPE route_tab IS TABLE OF route_rec;
    v_routes route_tab := route_tab(
        route_rec('SFO','LAX'), route_rec('JFK','MIA'), route_rec('ORD','DFW'),
        route_rec('SEA','DEN'), route_rec('ATL','BOS'), route_rec('LAX','SFO'),
        route_rec('DFW','ORD'), route_rec('BOS','ATL')
    );
    v_month DATE;
    v_net   NUMBER;
    v_tax   NUMBER;
BEGIN
    FOR m IN 0..5 LOOP                        -- 当月を含む過去6ヶ月(=当四半期をカバー)
        v_month := ADD_MONTHS(TRUNC(SYSDATE,'MM'), -m);
        FOR r IN 1..v_routes.COUNT LOOP
            v_net := ROUND(DBMS_RANDOM.VALUE(180000, 420000), 2);
            v_tax := ROUND(v_net * DBMS_RANDOM.VALUE(0.08, 0.14), 2);

            INSERT INTO AIRLINE.ROUTE_REVENUE (
                revenue_month, origin_airport_code, destination_airport_code,
                net_ticket_revenue, taxes_and_fees, currency_code
            ) VALUES (
                v_month, v_routes(r).origin, v_routes(r).destination,
                v_net, v_tax, 'USD'
            );
        END LOOP;
    END LOOP;
    COMMIT;
END;
/

-- ---------------------------------------------------------------------
-- 4. 動作確認用クエリ(Select AIを使わない素のSQLでの検証)
-- ---------------------------------------------------------------------

-- 先週の遅延便トップ5(手動SQL版。SELECT AI RUNSQLの結果と比較する用)
-- SELECT origin_airport_code, destination_airport_code,
--        COUNT(*) AS delayed_flights
-- FROM AIRLINE.FLIGHT_OPERATIONS
-- WHERE arrival_delay_minutes > 15
--   AND cancelled_flag = 'N'
--   AND flight_date >= TRUNC(SYSDATE, 'IW') - 7
--   AND flight_date <  TRUNC(SYSDATE, 'IW')
-- GROUP BY origin_airport_code, destination_airport_code
-- ORDER BY delayed_flights DESC
-- FETCH FIRST 5 ROWS ONLY;

-- 件数確認
-- SELECT (SELECT COUNT(*) FROM AIRLINE.FLIGHT_OPERATIONS) AS flights,
--        (SELECT COUNT(*) FROM AIRLINE.BOOKINGS)          AS bookings,
--        (SELECT COUNT(*) FROM AIRLINE.ROUTE_REVENUE)     AS route_revenue
-- FROM dual;
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?