■ はじめに
こんにちは。
OCI Data Catalogシリーズとして、これまで次の内容を実施しました。
| 回 | 内容 |
|---|---|
| 第1回 | Object Storage上のCSV、ParquetファイルをOCI Data Catalogへハーベスト |
| 第2回 | Oracle DatabaseマニュアルPDFと文書インベントリParquetを作成し、文書名、製品バージョン、公式URL、Object Storage上の保存場所などをカタログ化 |
| 第3回 | Object Storage上のOracle AI Database 26aiマニュアルPDFからVector Indexを作成し、Select AI with RAGで検索 |
| 第4回 | Data Lakeの文書インベントリ、ADBのRDBMS表、既存Vector Storeを統合し、LakehouseをSelect AIとRAGで検索 |
第2回では、Oracle Databaseマニュアルを管理するdocument_inventory.parquetを作成しました。
文書インベントリには、次のような構造化Metadataが格納されています。
document_id
document_family_id
product_name
product_version
document_title
document_type
category
subcategory
language_code
document_number
publication_year
publication_month
official_url
object_name
rag_enabled
document_priority
data_owner
tags
bucket_name
object_uri
第3回では、Object Storage上の4つのOracle AI Database 26aiマニュアルをAutonomous AI Databaseへ取り込み、9,590件のチャンクとEmbeddingを持つVector Storeを作成しました。
ただし、ここまでの構成では、次のデータがそれぞれ別の用途で利用されています。
OCI Data Catalog/Data Lake
→ 文書名、製品バージョン、カテゴリ、公式URLなどを管理
ADBのRDBMS表
→ AI利用の承認状態、機密区分、レビュー担当などを管理
Vector Store
→ PDF本文のチャンクとEmbeddingを管理
今回は、OCI Data Catalogから同期したData Lakeの外部表と、Autonomous AI Database内のRDBMS表をJOINします。
さらに、第3回で作成したVector Storeのlocation_uriとobject_nameから完全なObject名を再構成し、文書インベントリのobject_nameと結び付けます。これにより、構造化MetadataとPDF本文のチャンクを同じAutonomous AI Database上で参照できるLakehouseを構築します。
そのうえで、次の2つの検索経路を確認します。
- Data Lake外部表とADB内部表をJOINしたViewを、Select AIのNL2SQLで検索
- 既存Vector Indexを、Select AI with RAGで検索
ということで今回は、第1回から第3回までに作成したData Lake、RDBMS、Vector Storeを再利用し、Select AIとRAGから検索できるAutonomous AI Database上のLakehouseを構築してみてみます。
■ Agenda
| 大項目 | 内容 |
|---|---|
|
|
Data Lake、RDBMS、Vector Storeの3レイヤーと、今回作成するObject・Profileの役割を整理 |
|
|
NL2SQLとRAGを分ける理由、3レイヤーをOracle SQLで統合する考え方を整理 |
|
|
OCI Data Catalog、Object Storage、ADB、Vector Store、Select AIの全体構成を確認 |
|
|
Bucket、Database User、Vector Index、Profile、Viewなど今回使用するリソースを確認 |
|
|
第2回の文書インベントリ、第3回のVector StoreとRAG Profileを確認 |
|
|
document_inventory Logical EntityとParquet、20 Attributesを確認 |
|
|
Resource Principal、Credential、Data Catalog接続を設定し、Logical EntityをADBへ同期 |
|
|
Data Catalog同期で生成されたSchemaとDOCUMENT_INVENTORY External Tableを確認 |
|
|
External Tableを安定した名前で参照するDOCUMENT_INVENTORY_EXT_Vを作成 |
|
|
AI利用承認、機密区分、レビュー状態を管理するDOCUMENT_GOVERNANCEを作成 |
|
|
document_idで結合し、V_DOCUMENT_LAKEHOUSEを作成 |
|
|
Viewと主要Columnへコメントを設定し、NL2SQLで意味を理解しやすくする |
|
|
Vector Storeの完全Object名を再構成し、V_DOCUMENT_VECTOR_CHUNKSで3レイヤーを統合 |
|
|
V_DOCUMENT_LAKEHOUSEをNL2SQL対象とするOCI_DB_LAKEHOUSE_SQLを作成 |
|
|
SQL用Profileを明示し、SHOWSQL、SELECT AI、NARRATEで構造化データを検索 |
|
|
DBMS_CLOUD_AI.GENERATEを使用したSHOWSQL、NARRATEの実行方法を確認 |
|
|
OCI_DB_MANUAL_RAGへ切り替え、PDF本文をSemantic Search+RAGで検索 |
|
|
構造化検索から対象文書を選び、RAG検索へつなぐ一連の流れを整理 |
|
|
NL2SQL用ProfileとRAG用Profileを分離する理由と責任範囲を整理 |
|
|
Data Lake+RDBMS+Vector Store+Generative AIを統合した構成を整理 |
|
|
Protected Schema、Object公開範囲、AI Providerへ送信されるデータなどを整理 |
|
|
DBMS_DCAT、Profile JSON、権限、JOIN、Profile切替などのエラー対処を整理 |
|
|
Profile、View、RDBMS表を依存関係の逆順で削除 |
|
|
第4回で構築・確認したLakehouseとSelect AI/RAGの内容を整理 |
|
|
AIDP Master Catalog、Private Agent Factory、APEXへの発展を整理 |
|
|
今回参照したOracle公式ドキュメント |
■ 今回のゴール
今回のゴールを一言で表すと、次のとおりです。
Object Storageにある文書台帳、ADB内部の文書ガバナンス情報、PDF本文のVector Storeを、文書単位とチャンク単位の2段階で関連付け、構造化データ検索とRAG検索を用途に応じて使い分けられるLakehouseを作成します。
初見ではObject名が多く見えるため、最初に「どこに実データがあり、どのObjectがViewで、どのProfileが何を検索するのか」を整理します。
● 第4回で新しく作るものと再利用するもの
第4回では、1つのRDBMS表、3つのView、1つのSelect AI Profileを新しく作成します。
第3回で作成したVector TableとRAG Profileは、そのまま再利用します。
| 区分 | Object | 種類 | 作成元/用途 |
|---|---|---|---|
| 自動生成 | DCAT$...DOCUMENT_INVENTORY |
External Table | OCI Data CatalogのLogical EntityをADBへ同期すると作成されるData Lake参照用Table |
| 新規作成 | DOCUMENT_INVENTORY_EXT_V |
View | 長いDCAT$...Schema名を隠し、文書インベントリを安定した名前で参照 |
| 新規作成 | DOCUMENT_GOVERNANCE |
RDBMS Table | AI利用承認、機密区分、レビュー担当、備考などを管理 |
| 新規作成 | V_DOCUMENT_LAKEHOUSE |
View | 文書インベントリとガバナンス表をdocument_idで統合 |
| 再利用 | OCI_DB_MANUAL_IDX$VECTAB |
Vector Table | 第3回で作成したPDF本文のチャンク、属性、Embeddingを保持 |
| 新規作成 | V_DOCUMENT_VECTOR_CHUNKS |
View | 文書単位のLakehouse情報とVector Storeの各チャンクを完全Object名で統合 |
| 新規作成 | OCI_DB_LAKEHOUSE_SQL |
Select AI Profile |
V_DOCUMENT_LAKEHOUSEをNL2SQLで検索 |
| 再利用 | OCI_DB_MANUAL_RAG |
Select AI RAG Profile |
OCI_DB_MANUAL_IDXを使用してPDF本文をSemantic Search |
DOCUMENT_INVENTORY_EXT_V、V_DOCUMENT_LAKEHOUSE、V_DOCUMENT_VECTOR_CHUNKSはViewです。Viewはデータを複製して保存するObjectではなく、参照時に元データを組み合わせて見せる論理レイヤーです。
● 各Objectが属するデータレイヤー
| Object | レイヤー | データの粒度 | 主な内容 | 主な利用先 |
|---|---|---|---|---|
DOCUMENT_INVENTORY_EXT_V |
Data Lakeアクセスレイヤー | 1行=1文書 | 文書ID、製品バージョン、文書名、カテゴリ、公式URL、Object名、RAG対象フラグ |
V_DOCUMENT_LAKEHOUSEの入力 |
DOCUMENT_GOVERNANCE |
ADB RDBMS/業務ガバナンスレイヤー | 1行=1文書の審査状態 | 承認状態、AI利用可否、機密区分、レビュー担当、備考 |
V_DOCUMENT_LAKEHOUSEの入力 |
V_DOCUMENT_LAKEHOUSE |
構造化Lakehouse統合/提供レイヤー | 1行=1文書 | Data Lakeの文書Metadata+ADBのガバナンス情報 |
OCI_DB_LAKEHOUSE_SQLによるNL2SQL |
OCI_DB_MANUAL_IDX$VECTAB |
Vector Storeレイヤー | 1行=1チャンク | PDF本文チャンク、ATTRIBUTES JSON、Embedding |
OCI_DB_MANUAL_RAGによるSemantic Search |
V_DOCUMENT_VECTOR_CHUNKS |
文書+Vector統合/検証レイヤー | 1行=1チャンク | 文書Metadata+ガバナンス情報+PDF本文チャンク+Embedding+Source URL | JOIN検証、監査、Custom SQL RAG、将来のAgent Tool |
この構成では、データの粒度が途中で変わります。
DOCUMENT_INVENTORY_EXT_V
1行 = 1文書
│
│ document_idでJOIN
▼
V_DOCUMENT_LAKEHOUSE
1行 = 1文書
│
│ 完全Object名でVector StoreとJOIN
▼
V_DOCUMENT_VECTOR_CHUNKS
1行 = 1チャンク
今回の検証では、文書インベントリは10文書です。そのうち第3回でVector化した26aiの4文書が、合計9,590チャンクとしてV_DOCUMENT_VECTOR_CHUNKSへ結び付きます。
● Object間の関係
次はER図に近い関係図です。
ただし、Vector Storeとの関係はDatabaseのForeign Keyではなく、Object Storage上の完全Object名を使用した論理JOINです。
JOIN Keyは2種類あります。
| JOIN対象 | JOIN Key | 理由 |
|---|---|---|
DOCUMENT_INVENTORY_EXT_V+DOCUMENT_GOVERNANCE
|
document_id |
文書単位の一意な業務キーとして使用 |
V_DOCUMENT_LAKEHOUSE+OCI_DB_MANUAL_IDX$VECTAB
|
文書インベントリのobject_name=Vector Storeのlocation_uri+object_name
|
Vector Storeには文書インベントリのdocument_idが自動保存されないため、PDF実体の完全Object名で対応付け |
V_DOCUMENT_LAKEHOUSEは、文書一覧、承認状態、優先度などを検索するための文書単位のViewです。
V_DOCUMENT_VECTOR_CHUNKSは、文書情報と本文チャンクが正しく結び付いていることを確認するためのチャンク単位のViewです。
この2つは用途が異なります。
● Select AI Profileは「検索経路」を定義する
Select AI Profileはデータを保存するObjectではありません。
Select AIに対して、次の内容を定義する設定です。
どのProvider/Modelを使用するか
どのTable/ViewまたはVector Indexを検索対象にするか
NL2SQLとRAGのどちらの検索経路を使用するか
追加の指示や公開範囲をどうするか
今回は、質問の種類が異なるため、Profileを2つに分けます。
| Profile | 検索方式 | 検索対象 | 得意な質問 | 例 |
|---|---|---|---|---|
OCI_DB_LAKEHOUSE_SQL |
NL2SQL | V_DOCUMENT_LAKEHOUSE |
完全一致条件、一覧、集計、並べ替え、承認状態の確認 | 「26aiでAI利用が承認された文書を優先度順に表示」 |
OCI_DB_MANUAL_RAG |
Vector Search+RAG |
OCI_DB_MANUAL_IDX/OCI_DB_MANUAL_IDX$VECTAB
|
PDF本文の意味検索、要約、比較、手順や仕様の説明 | 「HNSW索引とIVF索引の違いを説明」 |
検索経路は次のようになります。
● Profileを1つにまとめない理由
Profileを分ける理由は、単に設定を整理するためではありません。
1) 検索方法が異なるため
構造化データは、APPROVAL_STATUS = 'APPROVED'のような正確な条件、集計、並べ替えをOracle SQLで処理するのが適しています。
PDF本文は、質問と意味が近いチャンクをEmbeddingで探すSemantic Searchが適しています。
2) Vector Tableを通常の業務表としてNL2SQLへ公開しないため
OCI_DB_MANUAL_IDX$VECTABには9,590件のチャンクとEmbeddingがあります。これをSQL用Profileのobject_listへ直接登録すると、Metadata量が増え、LLMが巨大なチャンク表やEmbedding列を通常の業務列として扱う可能性があります。
SQL用Profileには、文書単位に整理したV_DOCUMENT_LAKEHOUSEだけを公開します。
3) 公開範囲と責任範囲を明確にするため
OCI_DB_LAKEHOUSE_SQL
→ 文書Metadataとガバナンス情報だけを検索
OCI_DB_MANUAL_RAG
→ PDF本文だけをSemantic Search
どのProfileがどのデータへアクセスするかを限定することで、検索結果の意味と権限範囲を理解しやすくなります。
4) 標準のSelect AIでは1回の質問で2経路を自動統合しないため
SQL用ProfileのNARRATEはSQL結果を、RAG用ProfileのNARRATEはVector Searchで取得したチャンクをLLMへ渡します。
第4回では、人が次の順番でProfileを切り替えます。
1. OCI_DB_LAKEHOUSE_SQLで対象文書を特定
2. document_id、document_title、承認状態を確認
3. OCI_DB_MANUAL_RAGへ切り替え
4. 対象文書名を指定してPDF本文へ質問
この2つの検索経路を質問内容に応じて自動選択し、SQL結果とRAG結果をまとめる処理は、第5回以降のAI Agentで実装します。
● V_DOCUMENT_VECTOR_CHUNKSはどのProfileで使うのか
V_DOCUMENT_VECTOR_CHUNKSは、今回の標準NL2SQL Profileや標準RAG Profileの直接の検索対象にはしません。
用途は次のとおりです。
Data Lake、RDBMS、Vector StoreのJOIN結果をSQLで検証
文書ごとのチャンク数やJOIN漏れを確認
承認状態と本文チャンクを同時に監査
Relational Filterを加えたCustom SQL RAG
Private Agent FactoryやSelect AI AgentのCustom Tool
標準RAGでは、OCI_DB_MANUAL_RAGがVector Indexを通じてOCI_DB_MANUAL_IDX$VECTABを検索します。
一方、V_DOCUMENT_VECTOR_CHUNKSは、将来のAgentやCustom SQL RAGから、ガバナンス条件を含めてチャンクを扱うための統合Viewとして残します。
● 第4回終了時の完成形
第4回の完了時点では、次の2種類の検索ができる状態になります。
構造化検索
OCI_DB_LAKEHOUSE_SQL
→ V_DOCUMENT_LAKEHOUSE
→ 文書一覧、版、カテゴリ、承認状態、AI利用可否を検索
本文検索
OCI_DB_MANUAL_RAG
→ OCI_DB_MANUAL_IDX$VECTAB
→ PDF本文をSemantic Searchし、Source付きで回答
さらに、V_DOCUMENT_VECTOR_CHUNKSを使用すると、Data Lake、RDBMS、Vector Storeが4文書、9,590チャンクで正しく結び付いていることをOracle SQLで確認できます。
SELECT AIは、現在のDatabase Sessionに設定されているProfileを使用します。そのため、本稿ではProfileの取り違えを防ぐため、各
SELECT AI検索の直前にSET_PROFILEを実行し、GET_PROFILEで確認してから検索します。
DBMS_CLOUD_AI.GENERATEを使用する場合は、Sessionの状態へ依存しないように、毎回profile_nameを明示します。
■ 今回の重要な設計ポイント
● 標準のSELECT AI NARRATEはSQL結果かVector検索結果のどちらかを使用
Select AIのnarrateアクションは、自然言語の回答を生成するとき、LLMへ次のいずれかを渡します。
- NL2SQLで実行したSQLの結果
- Vector StoreからSemantic Searchで取得したチャンク
そのため、今回の第4回では、SQL検索とRAG検索のProfileを分け、順番に実行します。
1. Select AIで構造化データを検索
↓
2. 対象文書のdocument_id、document_titleを確認
↓
3. RAG Profileへ切り替え
↓
4. 対象文書の本文へ質問
1回の自然言語質問からSQL ToolとRAG Toolを自動選択し、両方の結果を統合する処理は、次回以降のAI Agentで実装します。
参考: About Select AI
● Data Lake、RDBMS、Vector StoreのJOIN自体はOracle SQLで実行できる
Select AIの標準RAGとは別に、Oracle SQLでは外部表、RDBMS表、Vector Tableを同じ問合せでJOINできます。
今回は、Vector StoreのATTRIBUTES.location_uriから製品バージョンを含むObject Prefixを取り出し、ATTRIBUTES.object_nameを連結して完全Object名を再構成します。その完全Object名を文書インベントリのobject_nameと結び付けます。
これにより、次の情報を1つのSQL結果として確認できます。
文書ID
製品バージョン
文書タイトル
カテゴリ
公式URL
AI利用承認状態
レビュー担当
PDF本文チャンク
Embedding
RAGのSource URL
Oracle AI Vector Searchでは、VectorデータとRelationalデータ、JSONなどを組み合わせたEnterprise RAGを構築できます。
参考: Use Retrieval Augmented Generation to Complement LLMs
■ 今回の構成
■ 使用するリソース
今回使用する主なリソースです。
| 項目 | 設定値 |
|---|---|
| Object Storageリージョン | ap-tokyo-1 |
| Autonomous AI Databaseリージョン | ap-tokyo-1 |
| OCI Generative AIリージョン | ap-osaka-1 |
| Bucket | oracle-database-doc-catalog |
| 文書インベントリ | catalog/document_inventory/current/document_inventory.parquet |
| PDF保存Prefix | documents/oracle-database/26ai/ |
| Database User | RAG_USER |
| 既存RAG Profile | OCI_DB_MANUAL_RAG |
| 既存Vector Index | OCI_DB_MANUAL_IDX |
| 既存Vector Table | OCI_DB_MANUAL_IDX$VECTAB |
| 新規RDBMS表 | DOCUMENT_GOVERNANCE |
| Data Lake参照View | DOCUMENT_INVENTORY_EXT_V |
| Lakehouse統合View | V_DOCUMENT_LAKEHOUSE |
| Vector統合View | V_DOCUMENT_VECTOR_CHUNKS |
| 新規NL2SQL Profile | OCI_DB_LAKEHOUSE_SQL |
| Chat Model | cohere.command-a-03-2025 |
| Embedding Model | cohere.embed-v4.0 |
| Embedding次元 | 1536 |
■ 事前準備
● 第2回の文書インベントリ
第2回で作成した文書インベントリには、Oracle Database 26ai、19c、12.2の合計10文書を登録しています。
Object Storage上の配置先です。
catalog/document_inventory/current/document_inventory.parquet
今回のVector Indexには、文書インベントリに登録した文書のうち、Oracle AI Database 26aiの次の4文書を登録しています。
document_id |
文書 |
|---|---|
oracle_db_26ai_admin |
Database Administrator's Guide |
oracle_db_26ai_ladbi |
Oracle AI Database Installation Guide for Linux |
oracle_db_26ai_cncpt |
Database Concepts |
oracle_db_26ai_vecse |
AI Vector Search User's Guide |
● 第3回のVector Store
第3回で作成したVector Storeを残していることを確認します。
SELECT
index_name,
status,
description
FROM
user_cloud_vector_indexes
WHERE
index_name = 'OCI_DB_MANUAL_IDX';
INDEX_NAME STATUS DESCRIPTION
____________________ __________ __________________________________________________________
OCI_DB_MANUAL_IDX ENABLED Oracle Database 26ai manual PDF index for Select AI RAG
SELECT
COUNT(*) AS chunk_count
FROM
OCI_DB_MANUAL_IDX$VECTAB;
CHUNK_COUNT
______________
9590
第3回の検証では、4つのPDFから9,590件のチャンクが登録されました。
Vector Tableの構造です。
DESC OCI_DB_MANUAL_IDX$VECTAB
Name Null? Type
------------- -------- ----------------------
CONTENT CLOB
ATTRIBUTES JSON
EMBEDDING VECTOR(1536,*,DENSE)
● 第3回のRAG Profileを確認
第4回では、第3回で作成したOCI_DB_MANUAL_RAGをそのまま再利用します。
SELECT
profile_name,
status,
description
FROM
user_cloud_ai_profiles
WHERE
profile_name = 'OCI_DB_MANUAL_RAG';
PROFILE_NAME STATUS DESCRIPTION
____________________ __________ ________________________________________________________________
OCI_DB_MANUAL_RAG ENABLED RAG profile for Oracle Database manuals in OCI Object Storage
RAGに関係する主なAttributeを確認します。
SELECT
attribute_name,
DBMS_LOB.SUBSTR(attribute_value, 500, 1) AS attribute_value
FROM
user_cloud_ai_profile_attributes
WHERE
profile_name = 'OCI_DB_MANUAL_RAG'
AND LOWER(attribute_name) IN (
'model',
'embedding_model',
'vector_index_name',
'enable_custom_source_uri'
)
ORDER BY
attribute_name;
ATTRIBUTE_NAME ATTRIBUTE_VALUE
___________________________ ___________________________
embedding_model cohere.embed-v4.0
enable_custom_source_uri true
model cohere.command-a-03-2025
vector_index_name OCI_DB_MANUAL_IDX
確認する値です。
vector_index_name = OCI_DB_MANUAL_IDX
enable_custom_source_uri = true
enable_custom_source_uri = trueの場合は、第3回でObject Storage Metadataへ設定したOracle公式URLがRAG回答のSourcesへ表示されます。
■ 第2回で作成したLogical Entityを確認
第2回v1.3では、document_inventory.parquetをFilename Patternでグループ化し、document_inventoryというLogical Entityを作成しました。
第4回では同じ手順を繰り返さず、Autonomous AI Databaseとの同期に使用できる状態になっていることだけを確認します。
| 確認項目 | 確認結果 |
|---|---|
| Logical Entity | document_inventory |
| Status | Active |
| Filename Pattern | document-inventory-pattern |
| File Type | PARQUET |
| Number of Attributes | 20 |
| Number of Files | 1 |
| 対象Object | catalog/document_inventory/current/document_inventory.parquet |
Logical EntityのFilesタブに対象Parquetが表示され、20個のAttributesが確認できていれば、次のData Catalog同期へ進めます。
Filename Patternの作成、Data Assetへの割当て、Full Harvestの操作は第2回v1.3で実施しています。旧版の第2回を使用している場合は、先に第2回のLogical Entity作成手順を実施してください。
■ OCI Data CatalogとAutonomous AI Databaseを同期
OCI Data CatalogでハーベストしたLogical EntityをAutonomous AI Databaseと同期すると、Data Catalog管理のProtected Schema内にExternal Tableが作成されます。
Data CatalogのLogical EntityがExternal Tableへ、Logical EntityのAttributeがExternal Tableの列へマッピングされます。
参考: Query External Data with Data Catalog
第2回までの環境ですでにData Catalog同期を実施している場合、この節の接続・同期処理は省略し、生成済みExternal Tableの確認へ進みます。
● Resource Principal用Dynamic GroupとIAM Policyを確認
第3回で作成したAutonomous AI Database用Dynamic Groupを再利用できます。
Dynamic GroupのMatching Rule例です。
resource.id = '<Autonomous-AI-Database-OCID>'
DBMS_DCATからOCI Data Catalogへ接続するため、Autonomous AI DatabaseのResource Principalには次の権限が必要です。
allow dynamic-group <adb-dynamic-group-name> to manage data-catalog-family
in compartment <data-catalog-compartment-name>
allow dynamic-group <adb-dynamic-group-name> to read objects
in compartment <object-storage-compartment-name>
第3回でObject Storage読取りPolicyを設定済みの場合は、対象Bucketを読めることを確認します。今回追加になりやすいのは、manage data-catalog-familyです。
本番環境では、Data Catalog、Object Storage、Autonomous AI Databaseの配置Compartmentに合わせてPolicyのScopeを最小化します。
● DCAT_SYNC Roleを確認
DBMS_DCATを使用するDatabase Userには、DCAT_SYNC Roleが必要です。
この記事ではADMINユーザーで同期処理を実行します。ADMIN以外のローカルユーザーで同期する場合は、ADMINからRoleを付与します。
GRANT DCAT_SYNC TO <data-catalog-sync-user>;
現在のユーザーへ付与されているか確認します。
SELECT
granted_role
FROM
user_role_privs
WHERE
granted_role = 'DCAT_SYNC';
GRANTED_ROLE
_______________
DCAT_SYNC
● Data Catalog接続を確認
ADMINユーザーで実行します。
SELECT
*
FROM
all_dcat_connections;
no rows selected
no rows selectedと出力され、接続が未作成の場合は、Resource Principalを使用してOCI Data Catalog接続を作成します。
今回は、接続を識別しやすくするため、次のConnection IDを使用します。
OCI_DCAT_BLOG_01
dcat_con_idは複数のCatalogへ接続するときに必要です。1つだけ接続する場合は省略できますが、第5回以降のAIDPや外部Catalogとの比較を考慮し、第4回から明示します。
Connection IDには、次の条件があります。
Autonomous AI Database内で一意
英字から開始
英数字、_、$、#を使用可能
16文字以上
OCI_DCAT_BLOG_01は16文字で、この条件を満たしています。
・ Resource Principalを確認
最初に、ADMINユーザーでResource Principalが有効か確認します。
SELECT
owner,
credential_name
FROM
dba_credentials
WHERE
credential_name = 'OCI$RESOURCE_PRINCIPAL'
AND owner = 'ADMIN';
初回は、次の結果になりました。
no rows selected
Resource Principalを有効化します。
BEGIN
DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL();
END;
/
PL/SQL procedure successfully completed.
もう一度確認します。
SELECT
owner,
credential_name
FROM
dba_credentials
WHERE
credential_name = 'OCI$RESOURCE_PRINCIPAL'
AND owner = 'ADMIN';
OWNER CREDENTIAL_NAME
________ _________________________
ADMIN OCI$RESOURCE_PRINCIPAL
・ DBMS_DCATの引数定義を確認
Oracleのドキュメントでは、SET_DATA_CATALOG_CREDENTIALのcredential_nameは省略可能で、省略時はResource Principalが使用されると説明されています。
ただし、今回のAutonomous AI Database環境では、dcat_con_idだけを指定した次の呼出しは、PLS-00306になりました。
BEGIN
DBMS_DCAT.SET_DATA_CATALOG_CREDENTIAL(
dcat_con_id => 'OCI_DCAT_BLOG_01'
);
END;
/
PLS-00306: wrong number or types of arguments in call to
' SET_DATA_CATALOG_CREDENTIAL '
Databaseに実装されているPackageの定義を確認するため、次のSQLを実行します。
SELECT
owner,
overload,
position,
sequence,
argument_name,
data_type,
in_out,
defaulted
FROM
all_arguments
WHERE
package_name = 'DBMS_DCAT'
AND object_name = 'SET_DATA_CATALOG_CREDENTIAL'
ORDER BY
owner,
overload,
sequence;
OWNER OVERLOAD POSITION SEQUENCE ARGUMENT_NAME DATA_TYPE IN_OUT DEFAULTED
___________________ ___________ ___________ ___________ __________________ ____________ _________ ____________
C##CLOUD$SERVICE 1 1 CREDENTIAL_NAME VARCHAR2 IN N
C##CLOUD$SERVICE 2 2 DCAT_CON_ID VARCHAR2 IN Y
今回の手順では、環境差によるデフォルト引数の解決へ依存しないように、credential_nameとdcat_con_idの両方を明示します。
・ Data Catalog用CredentialをConnection IDへ設定
Data CatalogのMetadataへアクセスするCredentialとして、ADMINユーザーのResource Principalを設定します。
BEGIN
DBMS_DCAT.SET_DATA_CATALOG_CREDENTIAL(
credential_name => 'OCI$RESOURCE_PRINCIPAL',
dcat_con_id => 'OCI_DCAT_BLOG_01'
);
END;
/
PL/SQL procedure successfully completed.
・ Object Storage用CredentialをConnection IDへ設定
同期後に作成されるExternal TableからObject Storage上のParquetを読み取るため、Object Storage用Credentialも同じConnection IDへ設定します。
BEGIN
DBMS_DCAT.SET_OBJECT_STORE_CREDENTIAL(
credential_name => 'OCI$RESOURCE_PRINCIPAL',
dcat_con_id => 'OCI_DCAT_BLOG_01'
);
END;
/
PL/SQL procedure successfully completed.
Data Catalog用とObject Storage用のCredentialは、役割が異なります。
| Procedure | 用途 |
|---|---|
SET_DATA_CATALOG_CREDENTIAL |
OCI Data CatalogのMetadataへアクセス |
SET_OBJECT_STORE_CREDENTIAL |
External TableからObject Storage上の実データを読取り |
・ OCI Data Catalog接続を登録
SET_DATA_CATALOG_CONNは、同じConnection IDについて1回だけ実行します。
冒頭の接続確認でOCI_DCAT_BLOG_01が表示されなかった場合だけ、2つのCredentialを設定した後にOCI Data Catalog接続を登録します。すでに接続が表示されている場合は、このProcedureを再実行せず「接続結果を確認」へ進みます。
BEGIN
DBMS_DCAT.SET_DATA_CATALOG_CONN(
region => 'ap-tokyo-1',
catalog_id => '<OCI-Data-Catalog-OCID>',
dcat_con_id => 'OCI_DCAT_BLOG_01',
catalog_type => 'OCI_DCAT'
);
END;
/
catalog_idには、OCI Consoleで確認したData CatalogインスタンスのOCIDを指定します。
ocid1.datacatalog.oc1.ap-tokyo-1...
初回の登録が成功すると、次の結果になります。
PL/SQL procedure successfully completed.
すでにOCI_DCAT_BLOG_01が登録されている場合は、このSQLを再実行せず、次の「接続結果を確認」へ進みます。
・ ORA-20012: Connection identifier ... already existsが表示された場合
同じConnection IDでSET_DATA_CATALOG_CONNを再実行すると、次のエラーになります。
ORA-20012: Connection identifier OCI_DCAT_BLOG_01 already exists
これは新しい接続失敗ではなく、OCI_DCAT_BLOG_01がすでに登録されていることを示します。
SET_DATA_CATALOG_CONNは接続の新規作成用であり、既存Connection IDの上書きには使用しません。この場合は再登録せず、接続内容を確認してから同期へ進みます。
接続先のOCIDやRegionを誤って登録し、接続を作り直す必要がある場合だけ、次のProcedureで既存接続を削除します。
UNSET_DATA_CATALOG_CONNを実行すると、その接続の過去の同期で作成されたProtected SchemaとExternal Tableも削除されます。同期済み環境では、影響を確認してから実行します。
BEGIN
DBMS_DCAT.UNSET_DATA_CATALOG_CONN(
dcat_con_id => 'OCI_DCAT_BLOG_01'
);
END;
/
削除後は、Credentialの設定とSET_DATA_CATALOG_CONNをもう一度実行します。
・ 接続結果を確認
今回の環境では接続ID列がCONNECTION_IDだったため、次のSQLで確認します。
SELECT
connection_id,
name,
catalog_type,
region,
instance_id,
data_catalog_credential,
object_store_credential,
created,
last_updated
FROM
all_dcat_connections
WHERE
connection_id = 'OCI_DCAT_BLOG_01';
CONNECTION_ID NAME CATALOG_TYPE REGION INSTANCE_ID DATA_CATALOG_CREDENTIAL OBJECT_STORE_CREDENTIAL CREATED LAST_UPDATED
___________________ ____________________ _______________ _____________ ________________________________________________________________________________________________ _______________________________ _______________________________ __________________________________ __________________________________
OCI_DCAT_BLOG_01 Data-Catalog-Demo OCI_DCAT ap-tokyo-1 <data-catalog-ocid> ADMIN.OCI$RESOURCE_PRINCIPAL ADMIN.OCI$RESOURCE_PRINCIPAL 25-JUL-26 01.21.58.784000000 PM 10-AUG-26 04.09.31.139726000 PM
CONNECTION_ID = OCI_DCAT_BLOG_01
NAME = Data-Catalog-Demo
CATALOG_TYPE = OCI_DCAT
REGION = ap-tokyo-1
DATA_CATALOG_CREDENTIAL = ADMIN.OCI$RESOURCE_PRINCIPAL
OBJECT_STORE_CREDENTIAL = ADMIN.OCI$RESOURCE_PRINCIPAL
今回の実行結果では、Data Catalog用Credentialと
Object Storage用Credentialの両方に、
ADMINユーザーのResource Principalが設定されていることを
確認できました。
参考:
● Data Catalogを同期
検証環境でData Catalog内の全Assetを同期する例です。
BEGIN
DBMS_DCAT.RUN_SYNC(
synced_objects => q'~{"asset_list":["*"]}~',
sync_option => 'SYNC',
error_semantics => 'STOP_ON_ERROR',
log_level => 'INFO',
dcat_con_id => 'OCI_DCAT_BLOG_01'
);
END;
/
PL/SQL procedure successfully completed.
asset_list:["*"]は、対象が限定された検証用Data Catalogを想定しています。複数システムのAssetが登録された環境では、AssetまたはLogical Entityを選択したSelective Syncを使用します。
同期状況を確認します。
SELECT
id,
type,
start_time,
update_time,
status,
logfile_table
FROM
user_load_operations
WHERE
type = 'DCAT_SYNC'
ORDER BY
start_time DESC;
ID TYPE START_TIME UPDATE_TIME STATUS LOGFILE_TABLE
_____ ____________ _____________________________________________ _____________________________________________ ____________ _____________________
41 DCAT_SYNC 11-AUG-26 10.16.52.745653000 AM ASIA/TOKYO 11-AUG-26 10.17.05.287773000 AM ASIA/TOKYO COMPLETED "DBMS_DCAT$41_LOG"
STATUS = COMPLETEDになっていることを確認します。FAILEDの場合は、LOGFILE_TABLEまたは次のDBMS_DCAT$SYNC_LOGで原因を確認します。
直近の同期ログから、文書インベントリに関係する行だけを確認します。
SELECT
log_timestamp,
log_level,
log_details
FROM
DBMS_DCAT$SYNC_LOG
WHERE
LOWER(log_details) LIKE '%catalog/document_inventory%'
OR LOWER(log_details) LIKE '%entity document_inventory mapped to table%'
ORDER BY
log_timestamp;
LOG_LEVEL LOG_DETAILS
--------- ------------------------------------------------------------------------------
INFO Translating regex: catalog/document_inventory/current/.*\.parquet$
INFO Entity document_inventory mapped to table DCAT$OCI_DCAT_BLOG_01_...DOCUMENT_INVENTORY
● 同期されたLogical Entityを確認
SELECT
dcat_con_id,
oracle_schema_name,
oracle_table_name
FROM
dcat_entities
WHERE
dcat_con_id = 'OCI_DCAT_BLOG_01'
AND oracle_table_name = 'DOCUMENT_INVENTORY';
DCAT_CON_ID ORACLE_SCHEMA_NAME ORACLE_TABLE_NAME
---------------- ----------------------------------------------------------------------------------- --------------------
OCI_DCAT_BLOG_01 DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG DOCUMENT_INVENTORY
同期された文書インベントリのAttribute数も確認します。
SELECT
COUNT(*) AS attribute_count
FROM
dcat_attributes a
INNER JOIN dcat_entities e
ON e.dcat_con_id = a.dcat_con_id
AND e.asset_key = a.asset_key
AND e.entity_key = a.entity_key
WHERE
e.dcat_con_id = 'OCI_DCAT_BLOG_01'
AND e.oracle_table_name = 'DOCUMENT_INVENTORY';
ATTRIBUTE_COUNT
---------------
20
■ Data LakeのExternal Tableを確認
● DCAT Schemaを確認
Data Catalog同期で作成されたSchemaを確認します。
SELECT
username
FROM
all_users
WHERE
username LIKE 'DCAT$%'
ORDER BY
username;
USERNAME
______________________________________________________________________________________
DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_DATA_CATALOG_CSV_PARQUET_DEMO
DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG
Data Catalog同期で生成されるSchema名は、環境のData Catalog接続、Data Asset、Bucketなどから決まります。
DCAT$<dcat-con-id>_<data-asset-name>_<folder-name>
● External Tableを確認
Data CatalogのLogical Entityと、同期で生成されたExternal TableのMappingを確認します。
SELECT
e.display_name AS logical_entity_name,
m.oracle_schema_name,
m.oracle_table_name
FROM
all_dcat_entities e
INNER JOIN dcat_entities m
ON m.dcat_con_id = e.dcat_con_id
AND m.entity_key = e.key
WHERE
e.dcat_con_id = 'OCI_DCAT_BLOG_01'
AND UPPER(e.display_name) = 'DOCUMENT_INVENTORY';
LOGICAL_ENTITY_NAME ORACLE_SCHEMA_NAME ORACLE_TABLE_NAME
______________________ ____________________________________________________________________________________ _____________________
document_inventory DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG DOCUMENT_INVENTORY
ORACLE_SCHEMA_NAMEとORACLE_TABLE_NAMEが、後続のSQLで使用する実Object名です。
External Table一覧からも確認できます。
SELECT
owner,
table_name,
default_directory_name
FROM
all_external_tables
WHERE
owner LIKE 'DCAT$%'
ORDER BY
owner,
table_name;
OWNER TABLE_NAME DEFAULT_DIRECTORY_NAME
______________________________________________________________________________________ _______________________ _________________________
DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_DATA_CATALOG_CSV_PARQUET_DEMO SALES_ORDERS_CSV
DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_DATA_CATALOG_CSV_PARQUET_DEMO SALES_ORDERS_PARQUET
DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG DOCUMENT_INVENTORY
document_inventory.parquetに対応するExternal Tableを確認します。
以降の例では、次のPlaceholderを使用します。
Schema : <DCAT-schema-name>
Table : <document-inventory-external-table-name>
実際のSchema名とTable名へ置き換えます。
● External Tableの列を確認
SELECT
column_id,
column_name,
data_type,
data_length,
data_precision,
data_scale
FROM
all_tab_columns
WHERE
owner = 'DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG'
AND table_name = 'DOCUMENT_INVENTORY'
ORDER BY
column_id;
COLUMN_ID COLUMN_NAME DATA_TYPE DATA_LENGTH DATA_PRECISION DATA_SCALE
____________ _____________________ ____________ ______________ _________________ _____________
1 DOCUMENT_ID VARCHAR2 4000
2 DOCUMENT_FAMILY_ID VARCHAR2 4000
3 PRODUCT_NAME VARCHAR2 4000
4 PRODUCT_VERSION VARCHAR2 4000
5 DOCUMENT_TITLE VARCHAR2 4000
6 DOCUMENT_TYPE VARCHAR2 4000
7 CATEGORY VARCHAR2 4000
8 SUBCATEGORY VARCHAR2 4000
9 LANGUAGE_CODE VARCHAR2 4000
10 DOCUMENT_NUMBER VARCHAR2 4000
11 PUBLICATION_YEAR NUMBER 22 5 0
12 PUBLICATION_MONTH NUMBER 22 3 0
13 OFFICIAL_URL VARCHAR2 4000
14 OBJECT_NAME VARCHAR2 4000
15 RAG_ENABLED NUMBER 22 1 0
16 DOCUMENT_PRIORITY NUMBER 22 5 0
17 DATA_OWNER VARCHAR2 4000
18 TAGS VARCHAR2 4000
19 BUCKET_NAME VARCHAR2 4000
20 OBJECT_URI VARCHAR2 4000
20 rows selected.
ParquetのBOOLはExternal TableではNUMBER(1)へマッピングされます。今回のrag_enabledは、1がtrue、0がfalseです。
参考: DBMS_CLOUD Package Parquet to Oracle Data Type Mapping
Data Lake上のデータを確認します。
SELECT
document_id,
product_version,
document_title,
category,
official_url,
object_name,
rag_enabled,
document_priority
FROM
"DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG"."DOCUMENT_INVENTORY"
ORDER BY
product_version,
document_priority;
DOCUMENT_ID PRODUCT_VERSION DOCUMENT_TITLE CATEGORY OFFICIAL_URL OBJECT_NAME RAG_ENABLED DOCUMENT_PRIORITY
_______________________ __________________ __________________________________________________ __________________________ ___________________________________________________________________________________ __________________________________________________________________________________________ ______________ ____________________
oracle_db_12_2_admin 12.2 Database Administrator's Guide administration https://docs.oracle.com/en/database/oracle/oracle-database/12.2/admin/index.html documents/oracle-database/12.2/admin/database-administrators-guide.pdf 1 10
oracle_db_12_2_ladbi 12.2 Database Installation Guide for Linux installation https://docs.oracle.com/en/database/oracle/oracle-database/12.2/ladbi/index.html documents/oracle-database/12.2/installation_linux/database-installation-guide-linux.pdf 1 20
oracle_db_12_2_cncpt 12.2 Database Concepts architecture https://docs.oracle.com/en/database/oracle/oracle-database/12.2/cncpt/index.html documents/oracle-database/12.2/concepts/database-concepts.pdf 1 30
oracle_db_19c_admin 19c Database Administrator's Guide administration https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/index.html documents/oracle-database/19c/admin/database-administrators-guide.pdf 1 10
oracle_db_19c_ladbi 19c Database Installation Guide for Linux installation https://docs.oracle.com/en/database/oracle/oracle-database/19/ladbi/index.html documents/oracle-database/19c/installation_linux/database-installation-guide-linux.pdf 1 20
oracle_db_19c_cncpt 19c Database Concepts architecture https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/index.html documents/oracle-database/19c/concepts/database-concepts.pdf 1 30
oracle_db_26ai_vecse 26ai AI Vector Search User's Guide ai_and_machine_learning https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/index.html documents/oracle-database/26ai/vector_search/ai-vector-search-users-guide.pdf 1 5
oracle_db_26ai_admin 26ai Database Administrator's Guide administration https://docs.oracle.com/en/database/oracle/oracle-database/26/admin/index.html documents/oracle-database/26ai/admin/database-administrators-guide.pdf 1 10
oracle_db_26ai_ladbi 26ai Oracle AI Database Installation Guide for Linux installation https://docs.oracle.com/en/database/oracle/oracle-database/26/ladbi/index.html documents/oracle-database/26ai/installation_linux/oracle-ai-database-installation-guide-linux.pdf 1 20
oracle_db_26ai_cncpt 26ai Database Concepts architecture https://docs.oracle.com/en/database/oracle/oracle-database/26/cncpt/index.html documents/oracle-database/26ai/concepts/database-concepts.pdf 1 30
10 rows selected.
● 文書インベントリのURIとObject名を確認
第2回で修正したobject_uriが、全10件でHTTPS URIになっていることを確認します。
SELECT
COUNT(*) AS invalid_object_uri_count
FROM
"DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG"."DOCUMENT_INVENTORY"
WHERE
object_uri LIKE '%<%'
OR object_uri NOT LIKE 'https://%';
INVALID_OBJECT_URI_COUNT
------------------------
0
26ai Installation GuideのObject名も、実際のPDF名と一致していることを確認します。
SELECT
document_id,
object_name,
object_uri
FROM
"DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG"."DOCUMENT_INVENTORY"
WHERE
document_id = 'oracle_db_26ai_ladbi';
DOCUMENT_ID OBJECT_NAME OBJECT_URI
-------------------- -------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------
oracle_db_26ai_ladbi documents/oracle-database/26ai/installation_linux/oracle-ai-database-installation-guide-linux.pdf https://<namespace>.objectstorage.ap-tokyo-1.oci.customer-oci.com/...
今回はParquetのObject名、列名、データ型を変更せず、行値だけを更新したため、External Tableから修正後の値をそのまま参照できました。
● RAG_USERへREAD権限とCREATE VIEW権限を付与
Data Catalog同期Schemaは同期処理が管理するProtected Schemaです。
生成されたTableを直接変更せず、ADMINまたはDCAT_ADMINからRAG_USERへREAD権限を付与します。DBMS_DCAT.RUN_SYNCのgrant_read引数で自動付与する方法もありますが、今回は文書インベントリExternal Tableだけへ最小権限を付与します。
GRANT READ
ON "<DCAT-schema-name>"."<document-inventory-external-table-name>"
TO RAG_USER;
GRANT CREATE VIEW TO RAG_USER;
SQL> GRANT READ
ON "DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG"."DOCUMENT_INVENTORY"
TO RAG_USER;
Grant succeeded.
SQL> GRANT CREATE VIEW TO RAG_USER;
Grant succeeded.
Viewを作成するときは、Role経由ではなく、Objectに対する直接権限が必要です。
・ READ権限確認
SELECT
grantee,
owner,
table_name,
privilege,
grantor
FROM
dba_tab_privs
WHERE
grantee = 'RAG_USER'
AND owner =
'DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG'
AND table_name = 'DOCUMENT_INVENTORY'
ORDER BY
privilege;
GRANTEE OWNER TABLE_NAME PRIVILEGE GRANTOR
___________ ____________________________________________________________________________________ _____________________ ____________ __________
RAG_USER DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG DOCUMENT_INVENTORY READ ADMIN
・ CREATE VIEW権限確認
SELECT
grantee,
privilege
FROM
dba_sys_privs
WHERE
grantee = 'RAG_USER'
AND privilege = 'CREATE VIEW';
GRANTEE PRIVILEGE
___________ ______________
RAG_USER CREATE VIEW
■ Data Lake参照用Viewを作成
以降はRAG_USERで実行します。
Data Catalog同期で生成されたSchema名やTable名を、Select AIへ直接公開することもできます。
ただし、生成名が長い場合や、将来AIDPなど別のCatalogへ移行する場合を考慮し、今回はローカルSchemaに安定したView名を作成します。
CREATE OR REPLACE VIEW DOCUMENT_INVENTORY_EXT_V AS
SELECT
document_id,
document_family_id,
product_name,
product_version,
document_title,
document_type,
category,
subcategory,
language_code,
document_number,
publication_year,
publication_month,
official_url,
object_name,
rag_enabled,
document_priority,
data_owner,
tags,
bucket_name,
object_uri
FROM
"DCAT$OCI_DCAT_BLOG_01_OBJECT_STORAGE_CSV_PARQUET_DEMO_ORACLE_DATABASE_DOC_CATALOG"."DOCUMENT_INVENTORY";
View DOCUMENT_INVENTORY_EXT_V created.
件数を確認します。
SELECT
COUNT(*) AS document_count
FROM
DOCUMENT_INVENTORY_EXT_V;
DOCUMENT_COUNT
_________________
10
今回の文書インベントリでは、10件になる想定です。
SELECT
product_version,
COUNT(*) AS document_count
FROM
DOCUMENT_INVENTORY_EXT_V
GROUP BY
product_version
ORDER BY
product_version;
PRODUCT_VERSION DOCUMENT_COUNT
__________________ _________________
12.2 3
19c 3
26ai 4
■ ADBのRDBMS表を作成
Data Lakeの文書インベントリは、文書そのものに関する比較的安定したMetadataを保持します。
一方、AIでの利用可否、レビュー状態、機密区分などは、運用中に更新される業務データです。
今回は、これらをAutonomous AI Database内のRDBMS表として管理します。
● 文書ガバナンス表を作成
CREATE TABLE DOCUMENT_GOVERNANCE (
document_id VARCHAR2(100) NOT NULL,
approval_status VARCHAR2(20) NOT NULL,
ai_use_allowed CHAR(1) DEFAULT 'N' NOT NULL,
security_classification VARCHAR2(20) NOT NULL,
review_owner VARCHAR2(100),
reviewed_at TIMESTAMP,
notes VARCHAR2(1000),
CONSTRAINT PK_DOCUMENT_GOVERNANCE
PRIMARY KEY (document_id),
CONSTRAINT CK_DOCUMENT_GOV_APPROVAL
CHECK (approval_status IN ('APPROVED', 'REVIEW', 'BLOCKED')),
CONSTRAINT CK_DOCUMENT_GOV_AI_USE
CHECK (ai_use_allowed IN ('Y', 'N')),
CONSTRAINT CK_DOCUMENT_GOV_SECURITY
CHECK (security_classification IN ('PUBLIC', 'INTERNAL', 'CONFIDENTIAL'))
);
Table DOCUMENT_GOVERNANCE created.
ここで登録する承認状態や担当者は、第4回のLakehouse JOINを検証するためのサンプル値です。Oracle製品の正式なサポート状態や文書公開区分を表すものではありません。
● サンプルデータを登録
INSERT ALL
INTO DOCUMENT_GOVERNANCE (
document_id,
approval_status,
ai_use_allowed,
security_classification,
review_owner,
reviewed_at,
notes
) VALUES (
'oracle_db_26ai_vecse',
'APPROVED',
'Y',
'PUBLIC',
'ai_platform_team',
TIMESTAMP '2026-08-07 00:00:00',
'Vector SearchとRAG検証で優先利用'
)
INTO DOCUMENT_GOVERNANCE (
document_id,
approval_status,
ai_use_allowed,
security_classification,
review_owner,
reviewed_at,
notes
) VALUES (
'oracle_db_26ai_admin',
'APPROVED',
'Y',
'PUBLIC',
'database_platform_team',
TIMESTAMP '2026-08-07 00:00:00',
'Database管理機能の確認に利用'
)
INTO DOCUMENT_GOVERNANCE (
document_id,
approval_status,
ai_use_allowed,
security_classification,
review_owner,
reviewed_at,
notes
) VALUES (
'oracle_db_26ai_cncpt',
'APPROVED',
'Y',
'PUBLIC',
'architecture_team',
TIMESTAMP '2026-08-07 00:00:00',
'Databaseアーキテクチャの確認に利用'
)
INTO DOCUMENT_GOVERNANCE (
document_id,
approval_status,
ai_use_allowed,
security_classification,
review_owner,
reviewed_at,
notes
) VALUES (
'oracle_db_26ai_ladbi',
'REVIEW',
'N',
'PUBLIC',
'infrastructure_team',
TIMESTAMP '2026-08-07 00:00:00',
'Agent利用前に内容と運用手順を再確認'
)
SELECT 1 FROM dual;
COMMIT;
4 rows inserted.
Commit complete.
登録結果を確認します。
SELECT
document_id,
approval_status,
ai_use_allowed,
security_classification,
review_owner,
reviewed_at
FROM
DOCUMENT_GOVERNANCE
ORDER BY
document_id;
DOCUMENT_ID APPROVAL_STATUS AI_USE_ALLOWED SECURITY_CLASSIFICATION REVIEW_OWNER REVIEWED_AT
_______________________ __________________ _________________ __________________________ _________________________ __________________________________
oracle_db_26ai_admin APPROVED Y PUBLIC database_platform_team 07-AUG-26 12.00.00.000000000 AM
oracle_db_26ai_cncpt APPROVED Y PUBLIC architecture_team 07-AUG-26 12.00.00.000000000 AM
oracle_db_26ai_ladbi REVIEW N PUBLIC infrastructure_team 07-AUG-26 12.00.00.000000000 AM
oracle_db_26ai_vecse APPROVED Y PUBLIC ai_platform_team 07-AUG-26 12.00.00.000000000 AM
■ Data Lake外部表とADB内部表をJOIN
● Lakehouse統合Viewを作成
Data Lakeの文書インベントリと、ADB内の文書ガバナンス表をdocument_idでJOINします。
同時に、Vector Storeで確認しやすい相対Object名を生成します。
文書インベントリのobject_nameです。
documents/oracle-database/26ai/vector_search/ai-vector-search-users-guide.pdf
Vector StoreのATTRIBUTES.object_nameです。
vector_search/ai-vector-search-users-guide.pdf
documents/oracle-database/<product_version>/を除外すると、Vector Store側と同じ相対Object名になります。
ただし、相対Object名だけをJOIN Keyにはしません。
admin/database-administrators-guide.pdfやconcepts/database-concepts.pdfは、26ai、19c、12.2で同じ相対Object名になるためです。後続のVector StoreとのJOINでは、ATTRIBUTES.location_uriに含まれる製品バージョン付きPrefixとATTRIBUTES.object_nameを連結し、完全Object名を再構成します。
CREATE OR REPLACE VIEW V_DOCUMENT_LAKEHOUSE AS
SELECT
i.document_id,
i.document_family_id,
i.product_name,
i.product_version,
i.document_title,
i.document_type,
i.category,
i.subcategory,
i.language_code,
i.document_number,
i.publication_year,
i.publication_month,
i.official_url,
i.object_name,
i.object_uri,
i.bucket_name,
i.rag_enabled,
i.document_priority,
i.data_owner,
i.tags,
NVL(g.approval_status, 'NOT_REVIEWED') AS approval_status,
NVL(g.ai_use_allowed, 'N') AS ai_use_allowed,
NVL(g.security_classification, 'UNCLASSIFIED') AS security_classification,
g.review_owner,
g.reviewed_at,
g.notes,
CASE
WHEN i.object_name LIKE
'documents/oracle-database/' || i.product_version || '/%'
THEN SUBSTR(
i.object_name,
LENGTH(
'documents/oracle-database/' || i.product_version || '/'
) + 1
)
END AS vector_object_name
FROM
DOCUMENT_INVENTORY_EXT_V i
LEFT JOIN DOCUMENT_GOVERNANCE g
ON g.document_id = i.document_id;
View V_DOCUMENT_LAKEHOUSE created.
● JOIN結果を確認
SELECT
document_id,
product_version,
document_title,
rag_enabled,
approval_status,
ai_use_allowed,
review_owner,
vector_object_name
FROM
V_DOCUMENT_LAKEHOUSE
ORDER BY
product_version,
document_priority;
DOCUMENT_ID PRODUCT_VERSION DOCUMENT_TITLE RAG_ENABLED APPROVAL_STATUS AI_USE_ALLOWED REVIEW_OWNER VECTOR_OBJECT_NAME
_______________________ __________________ __________________________________________________ ______________ __________________ _________________ _________________________ ___________________________________________________________
oracle_db_12_2_admin 12.2 Database Administrator's Guide 1 NOT_REVIEWED N admin/database-administrators-guide.pdf
oracle_db_12_2_ladbi 12.2 Database Installation Guide for Linux 1 NOT_REVIEWED N installation_linux/database-installation-guide-linux.pdf
oracle_db_12_2_cncpt 12.2 Database Concepts 1 NOT_REVIEWED N concepts/database-concepts.pdf
oracle_db_19c_admin 19c Database Administrator's Guide 1 NOT_REVIEWED N admin/database-administrators-guide.pdf
oracle_db_19c_ladbi 19c Database Installation Guide for Linux 1 NOT_REVIEWED N installation_linux/database-installation-guide-linux.pdf
oracle_db_19c_cncpt 19c Database Concepts 1 NOT_REVIEWED N concepts/database-concepts.pdf
oracle_db_26ai_vecse 26ai AI Vector Search User's Guide 1 APPROVED Y ai_platform_team vector_search/ai-vector-search-users-guide.pdf
oracle_db_26ai_admin 26ai Database Administrator's Guide 1 APPROVED Y database_platform_team admin/database-administrators-guide.pdf
oracle_db_26ai_ladbi 26ai Oracle AI Database Installation Guide for Linux 1 REVIEW N infrastructure_team installation_linux/oracle-ai-database-installation-guide-linux.pdf
oracle_db_26ai_cncpt 26ai Database Concepts 1 APPROVED Y architecture_team concepts/database-concepts.pdf
10 rows selected.
Oracle AI Database 26aiの4文書について、Data LakeのMetadataとADBのガバナンス情報が結合されます。
19cと12.2の文書は、今回DOCUMENT_GOVERNANCEへ登録していないため、次の値になります。
approval_status = NOT_REVIEWED
ai_use_allowed = N
security_classification = UNCLASSIFIED
■ Select AI向けにTableとColumnの意味を追加
Select AIのNL2SQL精度を上げるため、Viewと主要列へコメントを設定します。
COMMENT ON TABLE V_DOCUMENT_LAKEHOUSE IS
'Object Storage上の文書インベントリとADB内部の文書ガバナンス情報をdocument_idで統合したLakehouse View';
Comment created.
COMMENT ON COLUMN V_DOCUMENT_LAKEHOUSE.DOCUMENT_ID IS
'製品バージョンを含む文書単位の一意なID';
COMMENT ON COLUMN V_DOCUMENT_LAKEHOUSE.DOCUMENT_FAMILY_ID IS
'製品バージョンをまたいだ文書系列のID';
COMMENT ON COLUMN V_DOCUMENT_LAKEHOUSE.PRODUCT_VERSION IS
'Oracle Databaseの製品バージョン。26ai、19c、12.2など';
COMMENT ON COLUMN V_DOCUMENT_LAKEHOUSE.RAG_ENABLED IS
'文書インベントリでRAG対象として管理されているかを示す値。ParquetのBOOLはExternal TableでNUMBER(1)へマッピングされ、1がtrue、0がfalse';
COMMENT ON COLUMN V_DOCUMENT_LAKEHOUSE.APPROVAL_STATUS IS
'ADBの業務表で管理するAI利用レビュー状態。APPROVED、REVIEW、BLOCKED、NOT_REVIEWED';
COMMENT ON COLUMN V_DOCUMENT_LAKEHOUSE.AI_USE_ALLOWED IS
'AI AgentやRAGでの利用を業務上許可している場合はY、それ以外はN';
COMMENT ON COLUMN V_DOCUMENT_LAKEHOUSE.DOCUMENT_PRIORITY IS
'数値が小さいほど利用優先度が高い';
COMMENT ON COLUMN V_DOCUMENT_LAKEHOUSE.VECTOR_OBJECT_NAME IS
'Vector Storeとの対応確認に使用する正規化済み相対Object名。バージョン間で重複するため、単独ではJOIN Keyにしない';
Comment created.
■ Vector StoreとJOIN
● Vector TableのATTRIBUTES確認
第3回でDBMS_CLOUD_AI.CREATE_VECTOR_INDEXを実行したとき、object_nameやstart_offsetなどの項目はVector Indexの作成構文へ明示的に指定していません。
しかし、作成されたOCI_DB_MANUAL_IDX$VECTABを確認すると、ATTRIBUTES列のJSONにSource ObjectやChunkに関する情報が自動的に格納されています。
OCI_DB_MANUAL_IDX$VECTAB
├── CONTENT
│ └── PDFから抽出・分割された本文Chunk
│
├── ATTRIBUTES
│ ├── object_name
│ ├── object_size
│ ├── last_modified
│ ├── location_uri
│ ├── custom_uri
│ ├── start_offset
│ └── end_offset
│
└── EMBEDDING
└── Chunk本文から生成されたEmbedding Vector
ATTRIBUTESは、CREATE_VECTOR_INDEXでユーザーが列定義したものではありません。
Vector Index作成時に自動作成されるData Load PipelineがObject Storage上のSource Objectを取得し、本文抽出、Chunk分割、Embedding生成を行う過程で、**「このChunkがどのSource Objectのどの位置から作成されたか」**を追跡するためのMetadataをJSONとして付加します。
今回のVector Indexでは、次のPipelineが自動作成されています。
OCI_DB_MANUAL_IDX$VECPIPELINE
また、CREATE_VECTOR_INDEXでは次のようにprofile_nameとObject Storageのlocationを指定しています。
profile_name = OCI_DB_MANUAL_RAG
location = Object Storage上の26ai PDF
このため、Vector StoreにはPDF本文だけではなく、Source ObjectとChunkを追跡するためのMetadataも保存されます。
・ ATTRIBUTESへ格納される情報
今回の環境で確認した主なPropertyは次のとおりです。
| Property | 内容 | 主な生成元 |
|---|---|---|
object_name |
Vector Indexのlocationを基準としたSource Object名 |
Object StorageのSource Object情報 |
object_size |
Source Objectのファイルサイズ | Object StorageのObject Metadata |
last_modified |
Source Objectの最終更新日時 | Object StorageのObject Metadata |
location_uri |
Vector Indexが参照したObject StorageのLocation情報 |
CREATE_VECTOR_INDEXのlocationと取込処理 |
custom_uri |
RAGのSourceとして使用するCustom URL。今回の環境で確認できたVector Store内部表現 | Object StorageのCustom Metadataを使用した取込結果 |
start_offset |
Chunkの開始位置 | Chunk分割処理 |
end_offset |
Chunkの終了位置 | Chunk分割処理 |
Databaseや取込処理のバージョンによって、これ以外のPropertyが追加される可能性があります。そのため、固定のProperty一覧を前提にするのではなく、後述のSQLで実際のATTRIBUTESを確認します。
・ custom_uriはどこから来るのか
custom_uriは、OCI Object Storageにcustom_uriという名前のMetadataを作成したものではありません。
第3回では、PDFをObject StorageへPutするときに、次のUser-defined Metadataを設定しています。
customized_url_source
=
https://docs.oracle.com/...
OCI Object Storageでは、User-defined Metadataはopc-meta-というPrefix付きのMetadata Headerとして管理・返却されます。
そのため、OCI ConsoleのObject Detailsでは次の名前で確認できます。
opc-meta-customized_url_source
今回の流れを整理すると次のようになります。
作業者がPDFをObject StorageへPut
│
└─ customized_url_source
= Oracle公式URL
│
▼
OCI Object Storage
│
└─ opc-meta-customized_url_source
= Oracle公式URL
│
│ Vector Index Data Load Pipeline
▼
OCI_DB_MANUAL_IDX$VECTAB
│
└─ ATTRIBUTES.custom_uri
= Oracle公式URL
│
▼
Select AI with RAG
└─ SourcesでOracle公式URLを表示
Select AI Profileでは、次のAttributeをtrueに設定しています。
enable_custom_source_uri = true
この設定により、Select AIはRAGのSourcesを表示するときに、Object Storage Objectのopc-meta-customized_url_sourceをCustom Source URLとして使用します。
今回の検証では、このMetadataを設定してVector Indexを再作成した後、同じURLがOCI_DB_MANUAL_IDX$VECTAB.ATTRIBUTESのcustom_uriとして格納されていることも確認できました。
opc-meta-customized_url_sourceをRAGのSourcesへ使用する動作はSelect AIの機能として定義されています。一方、Vector Table内部で
custom_uriというJSON Property名へ格納されることについては、今回の環境で実際に確認できた内部表現として扱います。custom_uriというProperty名そのものを固定的な公開Schemaとして前提にせず、実データを確認して使用します。
・ Data Catalogのofficial_urlが自動コピーされたわけではない
第2回で作成した文書インベントリには、Oracle公式URLを保持するofficial_urlがあります。
ただし、次の2つは別のMetadataです。
Data Lake / document_inventory.parquet
official_url
→ 文書インベントリとして管理するURL
OCI Object Storage
customized_url_source
→ RAGのSourcesとして使用するURL
Data Catalogやdocument_inventory.parquetのofficial_urlが、自動的にVector Storeへコピーされたわけではありません。
第3回では同じOracle公式URLをObject Storage Objectのcustomized_url_sourceへ別途設定し、それをVector Indexの取込処理とSelect AI with RAGから利用しています。
・ ATTRIBUTESのJSONをそのまま確認
まず、Vector Tableに実際に保存されているJSONをそのまま確認します。
SELECT
JSON_SERIALIZE(
attributes
RETURNING VARCHAR2(4000)
PRETTY
) AS attributes
FROM
OCI_DB_MANUAL_IDX$VECTAB
WHERE
JSON_VALUE(
attributes,
'$.object_name'
RETURNING VARCHAR2(1000)
) = 'vector_search/ai-vector-search-users-guide.pdf'
FETCH FIRST 1 ROW ONLY;
今回の環境では、次のようなSource MetadataとChunk Metadataを確認できます。
{
"object_name" : "vector_search/ai-vector-search-users-guide.pdf",
"object_size" : 6013363,
"last_modified" : "2026-08-06T13:32:21+00:00",
"location_uri" : "https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<namespace>/b/oracle-database-doc-catalog/o/documents/oracle-database/26ai/",
"custom_uri" : "https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/ai-vector-search-users-guide.pdf",
"start_offset" : 1001729,
"end_offset" : 1002752
}
・ Propertyを列として確認
JOINで利用するPropertyを列として取り出して確認します。
SELECT DISTINCT
JSON_VALUE(
attributes,
'$.object_name'
RETURNING VARCHAR2(1000)
) AS object_name,
JSON_VALUE(
attributes,
'$.object_size'
RETURNING NUMBER
) AS object_size,
JSON_VALUE(
attributes,
'$.last_modified'
RETURNING VARCHAR2(100)
) AS last_modified,
JSON_VALUE(
attributes,
'$.location_uri'
RETURNING VARCHAR2(2000)
) AS location_uri,
JSON_VALUE(
attributes,
'$.custom_uri'
RETURNING VARCHAR2(2000)
) AS custom_uri
FROM
OCI_DB_MANUAL_IDX$VECTAB
ORDER BY
object_name;
OBJECT_NAME OBJECT_SIZE LAST_MODIFIED LOCATION_URI CUSTOM_URI
_____________________________________________________________________ ______________ ____________________________ __________________________________________________________________________________________________________________________________ ________________________________________________________________________________________________________
admin/database-administrators-guide.pdf 9975856 2026-08-06T15:36:45+00:00 https://objectstorage.ap-tokyo-1.oraclecloud.com/n/idqcucnenh88/b/oracle-database-doc-catalog/o/documents/oracle-database/26ai/ https://docs.oracle.com/en/database/oracle/oracle-database/26/admin/database-administrators-guide.pdf
concepts/database-concepts.pdf 13348414 2026-08-06T13:32:04+00:00 https://objectstorage.ap-tokyo-1.oraclecloud.com/n/idqcucnenh88/b/oracle-database-doc-catalog/o/documents/oracle-database/26ai/ https://docs.oracle.com/cd/G47991_01/cncpt/database-concepts.pdf
installation_linux/oracle-ai-database-installation-guide-linux.pdf 1138151 2026-08-06T13:32:12+00:00 https://objectstorage.ap-tokyo-1.oraclecloud.com/n/idqcucnenh88/b/oracle-database-doc-catalog/o/documents/oracle-database/26ai/ https://docs.oracle.com/cd/G47991_01/ladbi/oracle-ai-database-installation-guide-linux.pdf
vector_search/ai-vector-search-users-guide.pdf 6013363 2026-08-06T13:32:21+00:00 https://objectstorage.ap-tokyo-1.oraclecloud.com/n/idqcucnenh88/b/oracle-database-doc-catalog/o/documents/oracle-database/26ai/ https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/ai-vector-search-users-guide.pdf
Chunk単位の位置情報も確認できます。
SELECT
JSON_VALUE(
attributes,
'$.object_name'
RETURNING VARCHAR2(1000)
) AS object_name,
JSON_VALUE(
attributes,
'$.start_offset'
RETURNING NUMBER
) AS start_offset,
JSON_VALUE(
attributes,
'$.end_offset'
RETURNING NUMBER
) AS end_offset,
DBMS_LOB.SUBSTR(content, 200, 1) AS chunk_content
FROM
OCI_DB_MANUAL_IDX$VECTAB
WHERE
JSON_VALUE(
attributes,
'$.object_name'
RETURNING VARCHAR2(1000)
) = 'vector_search/ai-vector-search-users-guide.pdf'
FETCH FIRST 5 ROWS ONLY;
OBJECT_NAME START_OFFSET END_OFFSET CHUNK_CONTENT
_________________________________________________ _______________ _____________ _____________________________________________________________________________________
vector_search/ai-vector-search-users-guide.pdf 542081 543104 se, the text may lose semantic context and may not be useful for queries
that target specific information.
Syntax:
SELECT C.*
FROM documentation_tab D, VECTOR_CHUNKS(D.text BY words MAX 4
vector_search/ai-vector-search-users-guide.pdf 528641 529664 ation of specialized indexes that
are designed for Artificial Intelligence (AI) workloads that allow you to
query data based on semantics
314 150 , rather than keywords.
Why Use Oracle A
vector_search/ai-vector-search-users-guide.pdf 570753 571776
columns stored in external
tables.
•
IVF indexes are supported only for external Iceberg tables. For more information,
see
IVF Indexing on External Iceberg Tables
.
Vector
vector_search/ai-vector-search-users-guide.pdf 606593 607616 87654E-002,3.45828459E-002,-3.45360823E-002,-4.4002533E-003,1.77463
517'||
'E-002,6.68234832E-004,6.14458732E-002,-5.07084019E-002,-1.21073434E-002,4.195
981'||
'85E-002,3.69152687E-002,1.
vector_search/ai-vector-search-users-guide.pdf 613761 614784
M77
0
1
1
0
0
M91
0
1
1
0
0
M49
0
0
0
1
1
M60
0
0
0
0
1
NGC1073
0
1
1
0
0
This nat
SQL>
・ どのJSON Propertyが存在するかを確認
ATTRIBUTESに格納されているJSON Propertyをまとめて確認したい場合は、JSON_DATAGUIDEを使用できます。
SQLclでは出力が長くなる場合があるため、最初に表示サイズを広げます。
SET LONG 100000
SET LONGCHUNKSIZE 100000
SELECT
JSON_DATAGUIDE(attributes) AS attributes_data_guide
FROM
OCI_DB_MANUAL_IDX$VECTAB;
ATTRIBUTES_DATA_GUIDE
_________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
[{"o:path":"$","type":"object","o:length":1},{"o:path":"$.custom_uri","type":"string","o:length":128},{"o:path":"$.end_offset","type":"number","o:length":8},{"o:path":"$.object_name","type":"string","o:length":128},{"o:path":"$.object_size","type":"number","o:length":8},{"o:path":"$.location_uri","type":"string","o:length":128},{"o:path":"$.start_offset","type":"number","o:length":8},{"o:path":"$.last_modified","type":"string","o:length":32}]
これにより、ATTRIBUTES内に実際に存在するJSON PathとDatatypeを確認できます。
● Vector TableのObject名を確認
ATTRIBUTES.location_uriはVector Index作成時に指定したObject StorageのPrefix、ATTRIBUTES.object_nameはそのPrefixからの相対Object名です。
SELECT DISTINCT
JSON_VALUE(
attributes,
'$.location_uri'
RETURNING VARCHAR2(2000)
) AS vector_location_uri,
JSON_VALUE(
attributes,
'$.object_name'
RETURNING VARCHAR2(1000)
) AS vector_object_name,
JSON_VALUE(
attributes,
'$.custom_uri'
RETURNING VARCHAR2(2000)
) AS source_uri
FROM
OCI_DB_MANUAL_IDX$VECTAB
ORDER BY
vector_object_name;
VECTOR_LOCATION_URI VECTOR_OBJECT_NAME SOURCE_URI
__________________________________________________________________________________________________________________________________ _____________________________________________________________________ ________________________________________________________________________________________________________
https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<namespace>/b/oracle-database-doc-catalog/o/documents/oracle-database/26ai/ admin/database-administrators-guide.pdf https://docs.oracle.com/en/database/oracle/oracle-database/26/admin/database-administrators-guide.pdf
https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<namespace>/b/oracle-database-doc-catalog/o/documents/oracle-database/26ai/ concepts/database-concepts.pdf https://docs.oracle.com/cd/G47991_01/cncpt/database-concepts.pdf
https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<namespace>/b/oracle-database-doc-catalog/o/documents/oracle-database/26ai/ installation_linux/oracle-ai-database-installation-guide-linux.pdf https://docs.oracle.com/cd/G47991_01/ladbi/oracle-ai-database-installation-guide-linux.pdf
https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<namespace>/b/oracle-database-doc-catalog/o/documents/oracle-database/26ai/ vector_search/ai-vector-search-users-guide.pdf https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/ai-vector-search-users-guide.pdf
4つのPDFについて、26aiを含むPrefix、相対Object名、Oracle公式URLが表示されます。
● 相対Object名の重複を確認
文書インベントリでは、同じ種類のマニュアルが複数の製品バージョンに存在します。
SELECT
vector_object_name,
COUNT(DISTINCT product_version) AS version_count
FROM
V_DOCUMENT_LAKEHOUSE
GROUP BY
vector_object_name
HAVING
COUNT(DISTINCT product_version) > 1
ORDER BY
vector_object_name;
VECTOR_OBJECT_NAME VERSION_COUNT
___________________________________________________________ ________________
admin/database-administrators-guide.pdf 3
concepts/database-concepts.pdf 3
installation_linux/database-installation-guide-linux.pdf 2
例えば、次の相対Object名は製品バージョン間で重複します。adminとconceptsは26ai、19c、12.2で重複し、installation_linux/database-installation-guide-linux.pdfは19cと12.2で重複します。
admin/database-administrators-guide.pdf
concepts/database-concepts.pdf
installation_linux/database-installation-guide-linux.pdf
このため、ATTRIBUTES.object_nameだけでJOINすると、26aiのVectorチャンクが19cや12.2の文書Metadataへ誤って結び付く可能性があります。
● Data Lake、RDBMS、Vector Storeの統合Viewを作成
Vector Storeのlocation_uriから/o/より後ろのPrefixを取り出し、末尾と先頭の/を正規化して相対Object名を連結します。
location_uriのObject Prefix
documents/oracle-database/26ai/
+ attributes.object_name
vector_search/ai-vector-search-users-guide.pdf
= 完全Object名
documents/oracle-database/26ai/vector_search/ai-vector-search-users-guide.pdf
この完全Object名を、文書インベントリのobject_nameとJOINします。
CREATE OR REPLACE VIEW V_DOCUMENT_VECTOR_CHUNKS AS
WITH VECTOR_SOURCE AS (
SELECT
content,
attributes,
embedding,
JSON_VALUE(
attributes,
'$.location_uri'
RETURNING VARCHAR2(2000)
) AS vector_location_uri,
JSON_VALUE(
attributes,
'$.object_name'
RETURNING VARCHAR2(1000)
) AS vector_object_name,
RTRIM(
REGEXP_SUBSTR(
JSON_VALUE(
attributes,
'$.location_uri'
RETURNING VARCHAR2(2000)
),
'/o/(.*)$',
1,
1,
NULL,
1
),
'/'
) || '/' ||
LTRIM(
JSON_VALUE(
attributes,
'$.object_name'
RETURNING VARCHAR2(1000)
),
'/'
) AS vector_full_object_name,
JSON_VALUE(
attributes,
'$.custom_uri'
RETURNING VARCHAR2(2000)
) AS source_uri,
JSON_VALUE(
attributes,
'$.start_offset'
RETURNING NUMBER
) AS start_offset,
JSON_VALUE(
attributes,
'$.end_offset'
RETURNING NUMBER
) AS end_offset
FROM
OCI_DB_MANUAL_IDX$VECTAB
)
SELECT
l.document_id,
l.document_family_id,
l.product_name,
l.product_version,
l.document_title,
l.document_type,
l.category,
l.subcategory,
l.official_url,
l.object_name AS inventory_object_name,
l.object_uri,
l.rag_enabled,
l.document_priority,
l.approval_status,
l.ai_use_allowed,
l.security_classification,
l.review_owner,
l.reviewed_at,
v.vector_location_uri,
v.vector_object_name,
v.vector_full_object_name,
v.source_uri,
v.start_offset,
v.end_offset,
v.content AS chunk_content,
v.embedding AS chunk_embedding
FROM
V_DOCUMENT_LAKEHOUSE l
INNER JOIN VECTOR_SOURCE v
ON v.vector_full_object_name = l.object_name;
View V_DOCUMENT_VECTOR_CHUNKS created.
このViewでは、次の3種類のデータが1行へ結び付きます。
Data Lake
document_title、product_version、category、official_url
RDBMS
approval_status、ai_use_allowed、review_owner
Vector Store
chunk_content、chunk_embedding、source_uri
● 文書ごとのチャンク数を確認
最初に、統合Viewへ結び付いた文書数とチャンク総数を確認します。
SELECT
COUNT(DISTINCT document_id) AS document_count,
COUNT(*) AS joined_chunk_count
FROM
V_DOCUMENT_VECTOR_CHUNKS;
DOCUMENT_COUNT JOINED_CHUNK_COUNT
_________________ _____________________
4 9590
第3回のVector Storeがそのまま残っており、4文書すべてのObject名が一致していれば、次の値になる想定です。
DOCUMENT_COUNT = 4
JOINED_CHUNK_COUNT = 9590
続いて、文書ごとのチャンク数を確認します。
SELECT
document_id,
document_title,
approval_status,
ai_use_allowed,
COUNT(*) AS chunk_count
FROM
V_DOCUMENT_VECTOR_CHUNKS
GROUP BY
document_id,
document_title,
approval_status,
ai_use_allowed
ORDER BY
document_id;
DOCUMENT_ID DOCUMENT_TITLE APPROVAL_STATUS AI_USE_ALLOWED CHUNK_COUNT
_______________________ __________________________________________________ __________________ _________________ ______________
oracle_db_26ai_admin Database Administrator's Guide APPROVED Y 4586
oracle_db_26ai_cncpt Database Concepts APPROVED Y 2386
oracle_db_26ai_ladbi Oracle AI Database Installation Guide for Linux REVIEW N 733
oracle_db_26ai_vecse AI Vector Search User's Guide APPROVED Y 1885
● Vector StoreとのJOIN漏れを確認
文書インベントリ側に存在する26ai文書のうち、Vector Storeへ結び付かなかった文書を確認します。
WITH VECTOR_OBJECTS AS (
SELECT DISTINCT
RTRIM(
REGEXP_SUBSTR(
JSON_VALUE(
attributes,
'$.location_uri'
RETURNING VARCHAR2(2000)
),
'/o/(.*)$',
1,
1,
NULL,
1
),
'/'
) || '/' ||
LTRIM(
JSON_VALUE(
attributes,
'$.object_name'
RETURNING VARCHAR2(1000)
),
'/'
) AS vector_full_object_name
FROM
OCI_DB_MANUAL_IDX$VECTAB
)
SELECT
l.document_id,
l.document_title,
l.object_name,
l.vector_object_name
FROM
V_DOCUMENT_LAKEHOUSE l
WHERE
l.product_version = '26ai'
AND l.rag_enabled = 1
AND NOT EXISTS (
SELECT
1
FROM
VECTOR_OBJECTS v
WHERE
v.vector_full_object_name = l.object_name
);
no rows selected
0件であれば、4文書すべてのObject名を正しく結び付けられています。
● 3レイヤーを1つのSQLで確認
SELECT
document_id,
product_version,
document_title,
category,
approval_status,
ai_use_allowed,
review_owner,
source_uri,
DBMS_LOB.SUBSTR(chunk_content, 300, 1) AS chunk_content
FROM
V_DOCUMENT_VECTOR_CHUNKS
WHERE
document_id = 'oracle_db_26ai_vecse'
FETCH FIRST 1 ROW ONLY;
DOCUMENT_ID PRODUCT_VERSION DOCUMENT_TITLE APPROVAL_STATUS AI_USE_ALLOWED REVIEW_OWNER SOURCE_URI CHUNK_CONTENT
-------------------- --------------- ------------------------------- --------------- -------------- ----------------- ---------------------------------------------- ----------------------------------------
oracle_db_26ai_vecse 26ai AI Vector Search User's Guide APPROVED Y ai_platform_team https://docs.oracle.com/.../vecse/...pdf Syntax: SELECT C.* FROM ... VECTOR_CHUNKS(...)
これで、Data Lakeの文書Metadata、ADBのガバナンス情報、Vector StoreのPDF本文チャンクを同じSQLで参照できました。
V_DOCUMENT_VECTOR_CHUNKSは、Vector Storeの内容をガバナンス情報と一緒に監査・確認したり、今後Custom SQL RAGやAI AgentのToolから利用したりするためのRelational Viewです。標準のSelect AI with RAGは、引き続きOCI_DB_MANUAL_IDXをVector Indexとして使用します。
■ Lakehouse検索用Select AI Profileを作成
Data Lake外部表とADB内部表をJOINしたV_DOCUMENT_LAKEHOUSEを、NL2SQLの対象にします。
Vectorの生チャンクやEmbeddingは、NL2SQLで自由に参照させる必要がありません。
そのため、SQL用Profileのobject_listには、安定したLakehouse Viewだけを登録します。
● 実行ユーザーを確認
ここからのProfile作成とSelect AIの実行は、RAG_USERで行います。
SHOW USER
USER is "RAG_USER"
● Profile属性JSONを事前検証
Profileを削除・作成する前に、最小構成の属性がStrict JSONとして有効であることを確認します。
<OCI-Generative-AI-Compartment-OCID>は、OCI Generative AIを利用するCompartmentのOCIDへ置き換えます。
SELECT
CASE
WHEN q'~{
"provider": "oci",
"credential_name": "OCI$RESOURCE_PRINCIPAL",
"region": "ap-osaka-1",
"oci_compartment_id": "<OCI-Generative-AI-Compartment-OCID>",
"model": "cohere.command-a-03-2025",
"object_list": [
{
"owner": "RAG_USER",
"name": "V_DOCUMENT_LAKEHOUSE"
}
]
}~' IS JSON STRICT
THEN 'VALID JSON'
ELSE 'INVALID JSON'
END AS json_status
FROM
dual;
JSON_STATUS
______________
VALID JSON
JSON文字列では、Property名と文字列値をダブルクォーテーションで囲みます。
次のようなJSON_OBJECT用構文を、q'~{...}~'のJSON文字列内へ混在させないようにします。
'oci_compartment_id' VALUE 'ocid1.compartment...'
● 同名Profileを削除
JSONがVALID JSONになったことを確認してから、同名Profileを削除します。
force = TRUEを指定すると、Profileが存在しない場合もエラーを無視できます。
BEGIN
DBMS_CLOUD_AI.DROP_PROFILE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
force => TRUE
);
END;
/
PL/SQL procedure successfully completed.
● 最小構成でProfileを作成
最初からすべてのAttributeを指定せず、まず接続とObject Listに必要な最小構成で作成します。
BEGIN
DBMS_CLOUD_AI.CREATE_PROFILE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
attributes => q'~{
"provider": "oci",
"credential_name": "OCI$RESOURCE_PRINCIPAL",
"region": "ap-osaka-1",
"oci_compartment_id": "<OCI-Generative-AI-Compartment-OCID>",
"model": "cohere.command-a-03-2025",
"object_list": [
{
"owner": "RAG_USER",
"name": "V_DOCUMENT_LAKEHOUSE"
}
]
}~',
status => 'ENABLED',
description => 'NL2SQL profile for Data Catalog external data joined with ADB document governance data'
);
END;
/
PL/SQL procedure successfully completed.
● Profileと基本Attributeを確認
SELECT
profile_name,
status,
description
FROM
user_cloud_ai_profiles
WHERE
profile_name = 'OCI_DB_LAKEHOUSE_SQL';
PROFILE_NAME STATUS DESCRIPTION
_______________________ __________ ___________________________________________________________________________________
OCI_DB_LAKEHOUSE_SQL ENABLED NL2SQL profile for Data Catalog external data joined with ADB document governanc
基本Attributeを確認します。
SELECT
attribute_name,
DBMS_LOB.SUBSTR(
attribute_value,
1000,
1
) AS attribute_value
FROM
user_cloud_ai_profile_attributes
WHERE
profile_name = 'OCI_DB_LAKEHOUSE_SQL'
ORDER BY
attribute_name;
ATTRIBUTE_NAME ATTRIBUTE_VALUE
_____________________ ______________________________________________________________________________________
credential_name OCI$RESOURCE_PRINCIPAL
model cohere.command-a-03-2025
object_list [{"owner":"RAG_USER","name":"V_DOCUMENT_LAKEHOUSE"}]
oci_compartment_id <OCI-Generative-AI-Compartment-OCID>
provider oci
region ap-osaka-1
6 rows selected.
● オプションAttributeを追加
最小構成のProfile作成が成功した後、オプションAttributeをSET_ATTRIBUTEで段階的に追加します。
この順序にすると、エラーが発生した場合に、どのAttributeが原因かを切り分けやすくなります。
・ Object Listの動作を設定
enforce_object_list = trueにすると、SQL生成でProfileのObject Listに登録したObjectだけを使用するよう制限できます。
BEGIN
DBMS_CLOUD_AI.SET_ATTRIBUTE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
attribute_name => 'object_list_mode',
attribute_value => 'all'
);
DBMS_CLOUD_AI.SET_ATTRIBUTE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
attribute_name => 'enforce_object_list',
attribute_value => 'true'
);
END;
/
PL/SQL procedure successfully completed.
・ コメントと制約を有効化
BEGIN
DBMS_CLOUD_AI.SET_ATTRIBUTE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
attribute_name => 'comments',
attribute_value => 'true'
);
DBMS_CLOUD_AI.SET_ATTRIBUTE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
attribute_name => 'constraints',
attribute_value => 'true'
);
END;
/
PL/SQL procedure successfully completed.
・ Modelパラメータを設定
BEGIN
DBMS_CLOUD_AI.SET_ATTRIBUTE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
attribute_name => 'temperature',
attribute_value => '0.1'
);
DBMS_CLOUD_AI.SET_ATTRIBUTE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
attribute_name => 'max_tokens',
attribute_value => '2000'
);
END;
/
PL/SQL procedure successfully completed.
・ 追加指示を設定
BEGIN
DBMS_CLOUD_AI.SET_ATTRIBUTE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
attribute_name => 'additional_instructions',
attribute_value =>
'回答は日本語で行ってください。文書の利用可否を判断するときは、RAG_ENABLEDだけでなくAPPROVAL_STATUSとAI_USE_ALLOWEDも確認してください。RAG_ENABLEDは1がtrue、0がfalseです。DOCUMENT_PRIORITYは数値が小さいほど優先度が高いものとして扱ってください。存在しない列や値を推測しないでください。'
);
END;
/
PL/SQL procedure successfully completed.
● 最終的なAttributeを確認
SELECT
attribute_name,
DBMS_LOB.SUBSTR(
attribute_value,
2000,
1
) AS attribute_value
FROM
user_cloud_ai_profile_attributes
WHERE
profile_name = 'OCI_DB_LAKEHOUSE_SQL'
ORDER BY
attribute_name;
ATTRIBUTE_NAME ATTRIBUTE_VALUE
__________________________ ________________________________________________________________________________________________________________________________________________________________________________________
additional_instructions 回答は日本語で行ってください。文書の利用可否を判断するときは、RAG_ENABLEDだけでなくAPPROVAL_STATUSとAI_USE_ALLOWEDも確認してください。RAG_ENABLEDは1がtrue、0がfalseです。DOCUMENT_PRIORITYは数値が小さいほど優先度が高いものとして扱ってください。存在しない列や値を推測しないでください。
comments true
constraints true
credential_name OCI$RESOURCE_PRINCIPAL
enforce_object_list true
max_tokens 2000
model cohere.command-a-03-2025
object_list [{"owner":"RAG_USER","name":"V_DOCUMENT_LAKEHOUSE"}]
object_list_mode all
oci_compartment_id <OCI-Generative-AI-Compartment-OCID>
provider oci
region ap-osaka-1
temperature 0.1
13 rows selected.
ここまでで、Lakehouseの構造化データを検索するSQL用Profileの作成は完了です。
ProfileのSession設定は、次の検索節で各検索の直前に実行します。
● 追加したオプションAttributeの役割
ここでは、OCI_DB_LAKEHOUSE_SQL Profileへ設定したAttribute全体を整理したうえで、今回追加したオプションAttributeの役割を確認します。
今回のOCI_DB_LAKEHOUSE_SQLでは、最終的に13個のAttributeを設定しました。
これらは、役割ごとに次の5グループへ整理できます。
| 分類 | Attribute | 今回の値 | 役割 |
|---|---|---|---|
| OCI Generative AI接続 | provider |
oci |
使用するAI Providerを指定 |
| OCI Generative AI接続 | credential_name |
OCI$RESOURCE_PRINCIPAL |
OCI Generative AIへ接続するときの認証情報を指定 |
| OCI Generative AI接続 | region |
ap-osaka-1 |
OCI Generative AIを利用するRegionを指定 |
| OCI Generative AI接続 | oci_compartment_id |
<OCI-Generative-AI-Compartment-OCID> |
OCI Generative AIを利用するCompartmentを指定 |
| OCI Generative AI接続 | model |
cohere.command-a-03-2025 |
NL2SQLや回答生成に使用するLLMを指定 |
| NL2SQL対象 | object_list |
RAG_USER.V_DOCUMENT_LAKEHOUSE |
NL2SQLの対象とするDatabase Objectを指定 |
| NL2SQL対象 | object_list_mode |
all |
object_list内のObject MetadataをすべてLLMへ渡す |
| NL2SQL対象 | enforce_object_list |
true |
SQL生成で使用するObjectをobject_list内へ制限 |
| Metadata拡張 | comments |
true |
Table/View、Columnに設定したCommentをLLMへ渡す |
| Metadata拡張 | constraints |
true |
Primary Key、Foreign KeyなどのConstraint情報をLLMへ渡す |
| LLM生成設定 | temperature |
0.1 |
LLMの出力のランダム性を低くし、SQL生成を安定させる |
| LLM生成設定 | max_tokens |
2000 |
1回の生成で出力できる最大Token数を指定 |
| 業務ルール | additional_instructions |
日本語の追加指示 | 文書利用可否、優先度、回答言語などの判断ルールを追加 |
このうち、Profile作成時に設定した基本Attributeは次の6個です。
provider
credential_name
region
oci_compartment_id
model
object_list
その後、NL2SQLの精度、検索範囲、安全性、業務ルールを補強するため、次の7個のオプションAttributeを追加しました。
object_list_mode
enforce_object_list
comments
constraints
temperature
max_tokens
additional_instructions
Profile全体を役割で見ると、次の構成になります。
OCI_DB_LAKEHOUSE_SQL
│
├─ OCI Generative AI接続
│ ├─ provider
│ ├─ credential_name
│ ├─ region
│ ├─ oci_compartment_id
│ └─ model
│
├─ NL2SQL対象
│ ├─ object_list
│ ├─ object_list_mode
│ └─ enforce_object_list
│
├─ Metadata拡張
│ ├─ comments
│ └─ constraints
│
├─ LLM生成設定
│ ├─ temperature
│ └─ max_tokens
│
└─ 業務ルール
└─ additional_instructions
以降では、今回追加した7個のオプションAttributeについて詳しく確認します。
object_list_mode = all
object_list_modeは、object_listに登録したDatabase ObjectのMetadataをLLMへどのように渡すかを指定します。
今回のProfileでは、次のViewだけをNL2SQL対象として登録しています。
[
{
"owner": "RAG_USER",
"name": "V_DOCUMENT_LAKEHOUSE"
}
]
今回は対象Objectが1つだけなので、allを指定し、このViewのMetadataをすべてLLMへ渡す構成にしています。
object_list
└─ RAG_USER.V_DOCUMENT_LAKEHOUSE
│
│ object_list_mode = all
▼
ViewのMetadataをLLMへ渡す
TableやViewが多数存在する環境では、質問に関連するObjectを絞り込む構成も考えられますが、今回のように公開するViewを1つへ限定した構成では、allが分かりやすくなります。
enforce_object_list = true
enforce_object_listは、Select AIがSQLを生成するときに、object_listへ登録したObjectだけを使用させるための設定です。
今回のProfileでは、次のように設定しています。
object_list
└─ V_DOCUMENT_LAKEHOUSE
enforce_object_list = true
このため、Select AIにはLakehouse統合ViewだけをNL2SQL対象として公開します。
V_DOCUMENT_LAKEHOUSE
│
├─ 使用可能
│
▼
Select AI
DOCUMENT_GOVERNANCE
DCAT$...DOCUMENT_INVENTORY
OCI_DB_MANUAL_IDX$VECTAB
│
└─ SQL用Profileから直接使用させない
Data Catalog同期で作成されたProtected SchemaやVector Tableを直接NL2SQL対象へ含めず、業務的に利用しやすいViewだけを公開することで、検索対象を分かりやすく限定できます。
comments = true
commentsをtrueにすると、Table/ViewやColumnへ設定したCommentをNL2SQL用MetadataとしてLLMへ渡せます。
今回、V_DOCUMENT_LAKEHOUSEには次のようなCommentを設定しました。
COMMENT ON COLUMN V_DOCUMENT_LAKEHOUSE.RAG_ENABLED IS
'文書インベントリでRAG対象として管理されているかを示す値。ParquetのBOOLはExternal TableでNUMBER(1)へマッピングされ、1がtrue、0がfalse';
COMMENT ON COLUMN V_DOCUMENT_LAKEHOUSE.APPROVAL_STATUS IS
'ADBの業務表で管理するAI利用レビュー状態。APPROVED、REVIEW、BLOCKED、NOT_REVIEWED';
COMMENT ON COLUMN V_DOCUMENT_LAKEHOUSE.DOCUMENT_PRIORITY IS
'数値が小さいほど利用優先度が高い';
Column名だけでは分かりにくい業務的な意味を、Commentを使ってLLMへ補足できます。
DOCUMENT_PRIORITY
│
│ comments = true
▼
「数値が小さいほど利用優先度が高い」
│
▼
LLM
今回のように、Data LakeのMetadataとADBの業務データを統合したViewを自然言語から検索する場合、Columnの意味を明示することはNL2SQLの精度向上に役立ちます。
constraints = true
constraintsをtrueにすると、Primary KeyやForeign KeyなどのConstraint情報をLLMへ渡せます。
例えば複数Tableを直接object_listへ登録する場合は、Foreign Key情報からTable間の関係を理解し、JOIN条件を生成する助けになります。
TABLE_A
PK: document_id
│
│ Foreign Key
▼
TABLE_B
FK: document_id
ただし、今回のobject_listには完成済みのV_DOCUMENT_LAKEHOUSEだけを登録しています。
Data LakeとRDBMSのJOINはView内部ですでに実装されているため、今回の構成ではconstraintsよりも、commentsやadditional_instructionsの方がNL2SQLへ与える影響は大きくなります。
temperature = 0.1
temperatureは、LLMが回答やSQLを生成するときのランダム性を調整します。
一般的には、値を低くすると出力が安定し、高くすると回答のバリエーションが大きくなります。
今回の用途はCreativeな文章生成ではなく、自然言語から安定してSQLを生成するNL2SQLです。
そのため、低めの値として0.1を設定しました。
temperature 高め
→ 出力のバリエーションが大きい
temperature 低め
→ 出力が安定しやすい
→ NL2SQL向き
今回
temperature = 0.1
max_tokens = 2000
max_tokensは、1回のLLM呼出しで生成できる最大Token数を指定します。
今回のProfileでは次の値を設定しました。
max_tokens = 2000
これは「必ず2000 Token生成する」という意味ではなく、生成可能な上限値です。
SHOWSQLで生成するSQLや、NARRATEで生成する説明が途中で切れにくいように、ある程度余裕を持たせています。
additional_instructions
additional_instructionsは、このProfileを使用するときに毎回LLMへ追加する指示です。
今回、次の内容を設定しました。
回答は日本語で行ってください。
文書の利用可否を判断するときは、RAG_ENABLEDだけでなく
APPROVAL_STATUSとAI_USE_ALLOWEDも確認してください。
RAG_ENABLEDは1がtrue、0がfalseです。
DOCUMENT_PRIORITYは数値が小さいほど優先度が高いものとして扱ってください。
存在しない列や値を推測しないでください。
この内容は、主に次の5つのルールをLLMへ伝えています。
| 指示 | 目的 |
|---|---|
| 回答は日本語 | 回答言語を固定 |
RAG_ENABLEDだけで利用可否を判断しない |
Data Lake側のRAG対象設定だけでAI利用可能と判断することを防ぐ |
APPROVAL_STATUSとAI_USE_ALLOWEDも確認 |
ADB側のガバナンス情報を利用可否の判断へ含める |
DOCUMENT_PRIORITYは小さいほど優先 |
数値の業務的な意味を伝える |
| 存在しない列や値を推測しない | Metadataに存在しない情報を補完しないよう指示 |
今回のLakehouseでは、同じ文書に対して次の3種類の状態を持ちます。
RAG_ENABLED
→ Data Lakeの文書インベントリ上でRAG対象か
APPROVAL_STATUS
→ ADBのガバナンス表で承認済みか
AI_USE_ALLOWED
→ AIから利用してよいか
例えば、Oracle AI Database Installation Guide for Linuxは次の状態です。
RAG_ENABLED = 1
APPROVAL_STATUS = REVIEW
AI_USE_ALLOWED = N
この文書は文書インベントリ上ではRAG対象ですが、業務上はまだAI利用が承認されていません。
そのため、
RAG_ENABLED = 1
だけを見て「AI利用可能」と判断しないように、additional_instructionsへ業務ルールを設定しています。
・ commentsとadditional_instructionsの違い
今回のProfileでは、commentsとadditional_instructionsの両方を使用しています。
役割は次のように分けられます。
comments
→ Table/Columnそのものの意味をLLMへ伝える
additional_instructions
→ そのMetadataを使って、
LLMがどのように判断すべきかを伝える
例えば、DOCUMENT_PRIORITYについては、Column Commentで次の意味を伝えます。
数値が小さいほど利用優先度が高い
一方、additional_instructionsでは、文書利用可否の判断方法として、
RAG_ENABLEDだけで判断せず、
APPROVAL_STATUSとAI_USE_ALLOWEDも確認する
という業務ルールを設定します。
・ object_list_modeとenforce_object_listの違い
この2つも似ていますが、役割が異なります。
object_list_mode = all
→ object_list内のObject Metadataを
どのようにLLMへ渡すか
enforce_object_list = true
→ 生成するSQLで
object_list外のObjectを使用させるか
今回の設定を図にすると、次のようになります。
object_list
└─ V_DOCUMENT_LAKEHOUSE
│
├─ object_list_mode = all
│ │
│ └─ ViewのMetadataをすべてLLMへ渡す
│
└─ enforce_object_list = true
│
└─ SQLもこのViewだけを対象にする
これにより、単にV_DOCUMENT_LAKEHOUSEをLLMへ公開するだけではなく、
どのObjectを検索してよいか
+
各Columnが何を意味するか
+
どのような業務ルールで判断するか
までProfile側で明示したうえで、Select AIのNL2SQLを実行できるようにしています。
■ Select AIでLakehouseを検索
以降のSELECT AIはSQLclから実行します。
NARRATEなどのCLOB結果が途中で切れないように、最初に表示設定を行います。
SET LONG 100000
SET LONGCHUNKSIZE 100000
SET LINESIZE 32767
SET PAGESIZE 50000
今回使用するProfileと検索先を整理します。
| 検索 | 直前に設定するProfile | 主な検索先 |
|---|---|---|
構造化データのSHOWSQL、SELECT AI、NARRATE
|
OCI_DB_LAKEHOUSE_SQL |
V_DOCUMENT_LAKEHOUSE |
PDF本文のSELECT AI NARRATE
|
OCI_DB_MANUAL_RAG |
OCI_DB_MANUAL_IDX$VECTAB |
DBMS_CLOUD_AI.GENERATE |
profile_name引数で明示 |
指定したProfileの検索先 |
SELECT AIはSessionに設定されているProfileを使用します。本稿では迷わないように、各検索の直前に
SET_PROFILEとGET_PROFILEを実行します。
● 構造化検索1:承認済み文書の生成SQLを確認
・ 直前にSQL用Profileを設定
BEGIN
DBMS_CLOUD_AI.SET_PROFILE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL'
);
END;
/
PL/SQL procedure successfully completed.
SELECT
DBMS_CLOUD_AI.GET_PROFILE AS current_profile
FROM
dual;
CURRENT_PROFILE
____________________________________
"RAG_USER"."OCI_DB_LAKEHOUSE_SQL"
・ 生成SQLを確認
Data Lakeのrag_enabledと、ADB内部表のapproval_status、ai_use_allowedを組み合わせて質問します。
SELECT AI SHOWSQL
Oracle AI Database 26aiの文書のうち、
文書インベントリでRAG対象になっていて、
ADBのガバナンス表でAI利用が承認されている文書を、
優先度の高い順に表示してください。
文書ID、文書タイトル、カテゴリ、公式URL、レビュー担当を含めてください;
RESPONSE
___________________________________________________
SELECT
dl."DOCUMENT_ID" AS "文書ID",
dl."DOCUMENT_TITLE" AS "文書タイトル",
dl."CATEGORY" AS "カテゴリ",
dl."OFFICIAL_URL" AS "公式URL",
dl."REVIEW_OWNER" AS "レビュー担当"
FROM
"RAG_USER"."V_DOCUMENT_LAKEHOUSE" dl
WHERE
UPPER(dl."PRODUCT_VERSION") = '26AI'
AND dl."RAG_ENABLED" = 1
AND UPPER(dl."APPROVAL_STATUS") = 'APPROVED'
AND UPPER(dl."AI_USE_ALLOWED") = 'Y'
ORDER BY
dl."DOCUMENT_PRIORITY" ASC
生成SQLで、次を確認します。
検索先 = V_DOCUMENT_LAKEHOUSE
PRODUCT_VERSION = 26ai
RAG_ENABLED = 1
APPROVAL_STATUS = APPROVED
AI_USE_ALLOWED = Y
並び順 = DOCUMENT_PRIORITYの昇順
・ 比較用の基準SQL
SELECT
document_id,
document_title,
category,
official_url,
review_owner,
document_priority
FROM
V_DOCUMENT_LAKEHOUSE
WHERE
product_version = '26ai'
AND rag_enabled = 1
AND approval_status = 'APPROVED'
AND ai_use_allowed = 'Y'
ORDER BY
document_priority;
DOCUMENT_ID DOCUMENT_TITLE CATEGORY OFFICIAL_URL REVIEW_OWNER DOCUMENT_PRIORITY
_______________________ _________________________________ __________________________ _________________________________________________________________________________ _________________________ ____________________
oracle_db_26ai_vecse AI Vector Search User's Guide ai_and_machine_learning https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/index.html ai_platform_team 5
oracle_db_26ai_admin Database Administrator's Guide administration https://docs.oracle.com/en/database/oracle/oracle-database/26/admin/index.html database_platform_team 10
oracle_db_26ai_cncpt Database Concepts architecture https://docs.oracle.com/en/database/oracle/oracle-database/26/cncpt/index.html architecture_team 30
● 構造化検索2:承認済み文書をSelect AIで取得
・ 直前にSQL用Profileを設定
BEGIN
DBMS_CLOUD_AI.SET_PROFILE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL'
);
END;
/
SELECT
DBMS_CLOUD_AI.GET_PROFILE AS current_profile
FROM
dual;
"RAG_USER"."OCI_DB_LAKEHOUSE_SQL"
・ SQLを実行
SELECT AI
Oracle AI Database 26aiの文書のうち、
文書インベントリでRAG対象になっていて、
ADBのガバナンス表でAI利用が承認されている文書を、
優先度の高い順に表示してください。
文書ID、文書タイトル、カテゴリ、公式URL、レビュー担当を含めてください;
文書ID 文書タイトル カテゴリ 公式URL レビュー担当
_______________________ _________________________________ __________________________ _________________________________________________________________________________ _________________________
oracle_db_26ai_vecse AI Vector Search User's Guide ai_and_machine_learning https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/index.html ai_platform_team
oracle_db_26ai_admin Database Administrator's Guide administration https://docs.oracle.com/en/database/oracle/oracle-database/26/admin/index.html database_platform_team
oracle_db_26ai_cncpt Database Concepts architecture https://docs.oracle.com/en/database/oracle/oracle-database/26/cncpt/index.html architecture_team
● 構造化検索3:SQL結果を自然言語で説明
・ 直前にSQL用Profileを設定
BEGIN
DBMS_CLOUD_AI.SET_PROFILE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL'
);
END;
/
SELECT
DBMS_CLOUD_AI.GET_PROFILE AS current_profile
FROM
dual;
"RAG_USER"."OCI_DB_LAKEHOUSE_SQL"
・ NARRATEを実行
SELECT AI NARRATE
Oracle AI Database 26aiの文書について、
RAG対象かつAI利用が承認されている文書を整理し、
どの文書から検証を開始すべきかを優先度とともに日本語で説明してください;
Oracle AI Database 26aiの文書のうち、RAG対象でAI利用が承認されているものを優先度順に整理しました。
...
ここでは、Data Lake外部表とADB内部表をJOINしたSQL結果がLLMへ送られ、自然言語の回答が生成されます。
● 構造化検索4:レビュー中またはAI利用不可の文書を確認
最初に基準SQLで、対象データが1件存在することを確認します。
SELECT
document_id,
document_title,
approval_status,
ai_use_allowed,
review_owner,
notes
FROM
V_DOCUMENT_LAKEHOUSE
WHERE
product_version = '26ai'
AND (
approval_status IN ('REVIEW', 'BLOCKED')
OR ai_use_allowed = 'N'
)
ORDER BY
document_priority;
DOCUMENT_ID DOCUMENT_TITLE APPROVAL_STATUS AI_USE_ALLOWED REVIEW_OWNER NOTES
-------------------- -------------------------------------------------- --------------- -------------- ------------------- ----------------------------------------
oracle_db_26ai_ladbi Oracle AI Database Installation Guide for Linux REVIEW N infrastructure_team Agent利用前に内容と運用手順を再確認
・ SHOWSQLの直前にSQL用Profileを設定
BEGIN
DBMS_CLOUD_AI.SET_PROFILE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL'
);
END;
/
SELECT
DBMS_CLOUD_AI.GET_PROFILE AS current_profile
FROM
dual;
CURRENT_PROFILE
____________________________________
"RAG_USER"."OCI_DB_LAKEHOUSE_SQL"
・ 生成SQLを確認
SELECT AI SHOWSQL
Oracle AI Database 26aiの文書のうち、
APPROVAL_STATUSがREVIEWまたはBLOCKED、
もしくはAI_USE_ALLOWEDがNの文書を表示してください。
文書ID、文書タイトル、承認状態、AI利用可否、
レビュー担当、備考を含めてください;
RESPONSE
_________________________________________________________________________________________________________
SELECT
dl."DOCUMENT_ID" AS "文書ID",
dl."DOCUMENT_TITLE" AS "文書タイトル",
dl."APPROVAL_STATUS" AS "承認状態",
dl."AI_USE_ALLOWED" AS "AI利用可否",
dl."REVIEW_OWNER" AS "レビュー担当",
dl."NOTES" AS "備考"
FROM
"RAG_USER"."V_DOCUMENT_LAKEHOUSE" dl
WHERE
(dl."APPROVAL_STATUS" = 'REVIEW' OR dl."APPROVAL_STATUS" = 'BLOCKED' OR dl."AI_USE_ALLOWED" = 'N')
AND dl."PRODUCT_VERSION" = '26ai'
OR条件が括弧でまとめられ、その後にPRODUCT_VERSION = '26ai'が適用されていることを確認します。
また、検索先が次のViewであることを確認します。
RAG_USER.V_DOCUMENT_LAKEHOUSE
生成SQLがOCI_DB_MANUAL_IDX$VECTABを参照している場合は、RAG用Profileが有効です。検索を実行せず、SQL用Profileへ設定し直します。
・ SELECT AIの直前にSQL用Profileをもう一度設定
SHOWSQLの後に別のProfileへ切り替わっていないことを確実にするため、実行直前にも設定します。
BEGIN
DBMS_CLOUD_AI.SET_PROFILE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL'
);
END;
/
SELECT
DBMS_CLOUD_AI.GET_PROFILE AS current_profile
FROM
dual;
"RAG_USER"."OCI_DB_LAKEHOUSE_SQL"
・ Select AIから実行
SELECT AI
Oracle AI Database 26aiの文書のうち、
APPROVAL_STATUSがREVIEWまたはBLOCKED、
もしくはAI_USE_ALLOWEDがNの文書を表示してください。
文書ID、文書タイトル、承認状態、AI利用可否、
レビュー担当、備考を含めてください;
文書ID 文書タイトル 承認状態 AI利用可否 レビュー担当 備考
_______________________ __________________________________________________ _________ _________ ______________________ _______________________
oracle_db_26ai_ladbi Oracle AI Database Installation Guide for Linux REVIEW N infrastructure_team Agent利用前に内容と運用手順を再確認
これにより、SQL用Profileを明示的に設定した状態で、レビュー中またはAI利用不可の文書を1件取得できました。
■ Database Actionsから実行する場合
SELECT AIのAI Keywordは、Database ActionsおよびAPEX Serviceでは使用できません。
Database ActionsのSQL Worksheetから実行する場合は、DBMS_CLOUD_AI.GENERATEを使用します。
DBMS_CLOUD_AI.GENERATEでは、各呼出しのprofile_nameへ使用するProfileを明示します。そのため、Sessionに設定されたProfileへ依存しません。
● SHOWSQL相当
SELECT
DBMS_LOB.SUBSTR(
DBMS_CLOUD_AI.GENERATE(
prompt => q'[
Oracle AI Database 26aiの文書のうち、
RAG対象かつAI利用が承認されている文書を、
優先度の高い順に表示してください。
文書ID、文書タイトル、カテゴリ、公式URL、
レビュー担当を含めてください。
]',
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
action => 'showsql'
),
32767,
1
) AS response
FROM
dual;
RESPONSE
___________________________________________________
SELECT
dl."DOCUMENT_ID" AS "文書ID",
dl."DOCUMENT_TITLE" AS "文書タイトル",
dl."CATEGORY" AS "カテゴリ",
dl."OFFICIAL_URL" AS "公式URL",
dl."REVIEW_OWNER" AS "レビュー担当"
FROM
"RAG_USER"."V_DOCUMENT_LAKEHOUSE" dl
WHERE
UPPER(dl."PRODUCT_VERSION") = '26AI'
AND dl."RAG_ENABLED" = 1
AND UPPER(dl."APPROVAL_STATUS") = 'APPROVED'
AND UPPER(dl."AI_USE_ALLOWED") = 'Y'
ORDER BY
dl."DOCUMENT_PRIORITY" ASC
● NARRATE相当
SELECT
DBMS_LOB.SUBSTR(
DBMS_CLOUD_AI.GENERATE(
prompt => q'[
Oracle AI Database 26aiの文書について、
RAG対象かつAI利用が承認されている文書を整理し、
どの文書から検証を開始すべきかを日本語で説明してください。
]',
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
action => 'narrate'
),
32767,
1
) AS response
FROM
dual;
Oracle AI Database 26aiの文書のうち、RAG対象でAI利用が承認されているものは、以下の3つです。
...
参考: Use AI Keyword to Enter Prompts
■ Select AI with RAGへ切り替える
構造化データの検索によって、AI利用が承認され、優先度が最も高い文書としてAI Vector Search User's Guideを確認できました。
次に、第3回で作成したRAG Profileへ切り替え、PDF本文へ質問します。
● RAG検索の直前にRAG Profileを設定
BEGIN
DBMS_CLOUD_AI.SET_PROFILE(
profile_name => 'OCI_DB_MANUAL_RAG'
);
END;
/
PL/SQL procedure successfully completed.
SELECT
DBMS_CLOUD_AI.GET_PROFILE AS current_profile
FROM
dual;
CURRENT_PROFILE
_________________________________
"RAG_USER"."OCI_DB_MANUAL_RAG"
● 選択した文書の本文へ質問
SELECT AI NARRATE
AI Vector Searchユーザーズ・ガイドの記載に基づき、
HNSW索引とIVF索引の違いを、
索引構造、検索特性、更新時の考慮点が分かるように日本語で説明してください。
取得した資料に記載されていないことは推測しないでください;
回答本文に加えて、AI Vector Search User's GuideのOracle公式URLがSourcesへ表示されることを確認します。
HNSW索引とIVF索引の違いは以下の通りです。
索引構造
- HNSW索引:階層的なナビゲーション可能な小世界グラフを使用します。
- IVF索引:インバーテッドファイル構造を使用し、ベクトルをクラスタリングして索引を作成します。
Sources:
- vector_search/ai-vector-search-users-guide.pdf
https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/ai-vector-search-users-guide.pdf
● Database ActionsからRAGを実行
profile_nameへRAG用Profileを明示するため、SessionのProfileには依存しません。
SELECT
DBMS_LOB.SUBSTR(
DBMS_CLOUD_AI.GENERATE(
prompt => q'[
AI Vector Search User's Guideの記載に基づき、
HNSW索引とIVF索引の違いを日本語で説明してください。
資料に記載されていないことは推測しないでください。
]',
profile_name => 'OCI_DB_MANUAL_RAG',
action => 'narrate'
),
32767,
1
) AS response
FROM
dual;
● RAG検索後にSQL用Profileへ戻す
後続の構造化検索を誤ってVector Storeへ実行しないように、検証の最後にSQL用Profileへ戻します。
BEGIN
DBMS_CLOUD_AI.SET_PROFILE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL'
);
END;
/
SELECT
DBMS_CLOUD_AI.GET_PROFILE AS current_profile
FROM
dual;
"RAG_USER"."OCI_DB_LAKEHOUSE_SQL"
■ 第4回で実現できた検索フロー
今回の検索フローを整理します。
ユーザーの質問
「AI利用が承認されている26ai文書はどれか」
↓
OCI_DB_LAKEHOUSE_SQL
↓
V_DOCUMENT_LAKEHOUSE
↓
Data Lake外部表+ADB内部表をJOIN
↓
AI Vector Search User's Guideを選択
↓
OCI_DB_MANUAL_RAGへ切替
↓
OCI_DB_MANUAL_IDX$VECTABをSemantic Search
↓
PDF本文を根拠に回答
第4回では、人がProfileを切り替え、構造化検索の結果を次のRAG質問へ引き継いでいます。
■ なぜ1つのProfileへすべて登録しないのか
narrateは、SQL生成用ProfileではSQL実行結果を、Vector Indexを設定したRAG用ProfileではSemantic Searchの取得結果をLLMへ渡します。SQL用ProfileへVector Indexも設定しても、Data Lake+RDBMSのSQL結果とPDFの検索結果が自動的に1つへ統合されるわけではありません。
また、Vector TableのCONTENTやEMBEDDINGをNL2SQLのobject_listへ直接登録すると、次の問題が発生します。
- Metadata量が増える
- LLMが巨大なチャンク表を通常表として選択する可能性がある
- Embedding列を通常の業務列として扱う可能性がある
- Select AIへ公開するObject範囲が広くなる
- SQL検索とRAG検索の責任範囲が不明確になる
そのため、今回は次のように責任を分離しました。
OCI_DB_LAKEHOUSE_SQL
object_list = V_DOCUMENT_LAKEHOUSE
用途 = 構造化データの検索、JOIN、集計
OCI_DB_MANUAL_RAG
vector_index_name = OCI_DB_MANUAL_IDX
用途 = PDF本文のSemantic Search、回答生成
この2つを自動的に選択して連携する処理が、次回以降のAI Agentの役割になります。
■ 第4回で構築したLakehouse
今回の構成は、単にData Lake上のParquetをSQLで参照するだけではありません。
Data Lake
Object Storage上のParquet
+
RDBMS
ADB内部の業務・ガバナンス表
+
Vector Store
PDF本文のチャンクとEmbedding
+
Generative AI
NL2SQL、RAG、自然言語回答
これらをAutonomous AI Database上で統合したことで、構造化データと非構造化データをAIから利用するためのLakehouse基盤を作成できました。
■ 運用上の考慮点
● Data Catalog同期Schemaを直接変更しない
Data Catalog同期で生成されたDCAT$...Schemaは、同期処理によって管理されます。
列名や型などを変更する場合はData Catalog側のMetadataやCustom Propertiesを更新し、再同期します。
ローカルで利用しやすい名前や業務ルールは、今回のようにViewで吸収します。
● Select AIへ公開するObjectを限定
object_listには、利用者へ公開するViewだけを登録します。
今回はenforce_object_list = trueを設定し、Select AIがProfile外のObjectを使用しないようにしています。
● NARRATEで外部AI Providerへ送られるデータを確認
NL2SQLのMetadata拡張では、Table名、Column名、型、コメントなどがAI Providerへ送信されます。
narrateでは、SQL実行結果またはVector Storeから取得したチャンクもLLMへ送信されます。
機密データを扱う場合は、次を検討します。
- Public文書とInternal文書のVector Index分離
- Database UserとProfileの分離
- Object Storage Bucket/Prefixの分離
-
object_listの最小化 - 機密列を含まないViewの作成
- AI Provider、Model、Region、データ保持条件の確認
● 大規模なExternal TableではLake Cacheを検討
今回の文書インベントリは10行のため、Performance対策は不要です。
将来、Data Lake上の大規模なParquetやIceberg表を繰り返し検索する場合は、Lake Cache、Data Lake Accelerator、Implicit Partitioningなどを検討できます。
参考: Use Lakehouse with Autonomous AI Database
■ トラブルシューティング
● PLS-00684: invalid data type for the JSON return value
CREATE_PROFILEのattributesへJSON_OBJECT(... RETURNING CLOB)を直接指定したところ、今回の環境ではPL/SQLコンパイル時にPLS-00684になりました。
今回のProfile属性は小さいため、RETURNING CLOBへ依存せず、q'~{...}~'形式のJSON文字列を使用します。
● ORA-20046: Profile attributes are not in valid JSON format
q'~{...}~'の中へ次のようなJSON_OBJECT用構文を混在させると、JSONとして無効になります。
誤り: 'oci_compartment_id' VALUE 'ocid1.compartment...'
正しい: "oci_compartment_id": "ocid1.compartment..."
CREATE_PROFILEの前にIS JSON STRICTでVALID JSONになることを確認します。
● ORA-01031: insufficient privilegesでViewを作成できない
RAG_USERにはCREATE VIEWシステム権限と、同期External Tableに対する直接のREAD権限が必要です。Role経由ではなく、Object権限をユーザー本人へ付与します。
GRANT CREATE VIEW TO RAG_USER;
GRANT READ
ON "<DCAT-schema-name>"."DOCUMENT_INVENTORY"
TO RAG_USER;
● ORA-20012: Connection identifier ... already exists
同じConnection IDでSET_DATA_CATALOG_CONNを再実行した場合に発生します。接続確認SQLで既存行が表示される場合は、接続を作り直さず、そのまま同期へ進みます。
● Select AIでレビュー中の文書が0件になる
自然言語の「未承認」が、実データに存在しない状態値へ変換される場合があります。まず基準SQLで対象行を確認し、SELECT AI SHOWSQLで生成条件を確認します。必要に応じてAPPROVAL_STATUS IN ('REVIEW','BLOCKED')やAI_USE_ALLOWED = 'N'をプロンプトへ明示します。
● PLS-00306:SET_DATA_CATALOG_CREDENTIALを呼び出せない
今回の環境では、次のようにdcat_con_idだけを指定すると、PLS-00306が発生しました。
BEGIN
DBMS_DCAT.SET_DATA_CATALOG_CREDENTIAL(
dcat_con_id => 'OCI_DCAT_BLOG_01'
);
END;
/
この場合は、Resource PrincipalのCredential名も明示します。
BEGIN
DBMS_DCAT.SET_DATA_CATALOG_CREDENTIAL(
credential_name => 'OCI$RESOURCE_PRINCIPAL',
dcat_con_id => 'OCI_DCAT_BLOG_01'
);
END;
/
Databaseに実装されている引数定義は、ALL_ARGUMENTSから確認できます。
SELECT
owner,
overload,
position,
sequence,
argument_name,
data_type,
in_out,
defaulted
FROM
all_arguments
WHERE
package_name = 'DBMS_DCAT'
AND object_name = 'SET_DATA_CATALOG_CREDENTIAL'
ORDER BY
owner,
overload,
sequence;
OracleのドキュメントとDatabaseに実装されているPackage Signatureに差がある場合は、実際のDatabaseで確認した引数定義を優先します。
● ORA-20000:Data catalog credential not set
SET_DATA_CATALOG_CONNを先に実行すると、次のエラーになる場合があります。
ORA-20000: Data catalog credential not set for connection with id
OCI_DCAT_BLOG_01
次の順序で実行します。
1. ENABLE_RESOURCE_PRINCIPAL
2. SET_DATA_CATALOG_CREDENTIAL
3. SET_OBJECT_STORE_CREDENTIAL
4. SET_DATA_CATALOG_CONN
5. ALL_DCAT_CONNECTIONSで確認
SET_DATA_CATALOG_CREDENTIALとSET_OBJECT_STORE_CREDENTIALには、同じdcat_con_idを指定します。
● ORA-00904: "DCAT_CON_ID": invalid identifier
今回の環境では、次のSQLでORA-00904が発生しました。
SELECT
*
FROM
all_dcat_connections
WHERE
dcat_con_id = 'OCI_DCAT_BLOG_01';
Oracleの現行ドキュメントではALL_DCAT_CONNECTIONS.DCAT_CON_IDが定義されていますが、今回の接続先で実際に解決されたViewでは、この列名を参照できませんでした。原因を推測せず、DESCまたはALL_TAB_COLUMNSで実環境の定義を確認します。
実環境の列定義を確認します。
DESC ALL_DCAT_CONNECTIONS
または、次を実行します。
SELECT
owner,
column_id,
column_name,
data_type
FROM
all_tab_columns
WHERE
table_name = 'ALL_DCAT_CONNECTIONS'
ORDER BY
owner,
column_id;
接続が1件の場合は、列名で絞り込まず、次のSQLで確認できます。
SELECT
*
FROM
all_dcat_connections;
SET_DATA_CATALOG_CONNがPL/SQL procedure successfully completed.で終了し、このSQLで接続行が表示されれば、接続登録は完了しています。Credentialや接続処理を作り直す必要はありません。
● DCAT$...Schemaが作成されない
確認する項目です。
Data Catalog Connection
Resource Principal
OCI IAM Policy
Object Storage読取り権限
Data Catalog AssetのHarvest完了
Logical Entityの作成
DBMS_DCAT.RUN_SYNCのStatus
USER_LOAD_OPERATIONSのLog
● ORA-00942: table or view does not exist
RAG_USERへExternal Tableの直接権限が付与されているか確認します。
SELECT
owner,
table_name,
privilege,
grantor
FROM
user_tab_privs_recd
WHERE
owner LIKE 'DCAT$%';
Role経由の権限だけでは、View作成時に参照できない場合があります。
● Vector StoreとのJOIN結果が0件
Data Lake側の完全Object名と、Vector Store側で再構成した完全Object名を比較します。
SELECT
document_id,
object_name,
vector_object_name
FROM
V_DOCUMENT_LAKEHOUSE
WHERE
product_version = '26ai';
SELECT DISTINCT
JSON_VALUE(
attributes,
'$.location_uri'
RETURNING VARCHAR2(2000)
) AS vector_location_uri,
JSON_VALUE(
attributes,
'$.object_name'
RETURNING VARCHAR2(1000)
) AS vector_object_name,
RTRIM(
REGEXP_SUBSTR(
JSON_VALUE(
attributes,
'$.location_uri'
RETURNING VARCHAR2(2000)
),
'/o/(.*)$',
1,
1,
NULL,
1
),
'/'
) || '/' ||
LTRIM(
JSON_VALUE(
attributes,
'$.object_name'
RETURNING VARCHAR2(1000)
),
'/'
) AS vector_full_object_name
FROM
OCI_DB_MANUAL_IDX$VECTAB
ORDER BY
vector_object_name;
次の点を確認します。
- Prefixの有無
- 製品バージョンの表記
- Directory名
- PDFファイル名
- ハイフンとアンダースコア
- 大文字と小文字
特にObject Storage上の実ファイル名と、文書インベントリのobject_nameを一致させます。
今回の検証では、26ai Installation Guideだけ文書インベントリが旧ファイル名になっていたため、最初は3文書、8,857チャンクしかJOINできませんでした。
修正前: documents/oracle-database/26ai/installation_linux/database-installation-guide-linux.pdf
修正後: documents/oracle-database/26ai/installation_linux/oracle-ai-database-installation-guide-linux.pdf
Parquetを修正して同じObject名へ上書きした後、4文書、9,590チャンク、JOIN漏れ0件になりました。
● object_uriに<your-namespace>またはoci://が残る
第2回の生成スクリプトが旧版の場合、HTTPS URIではなくPlaceholderを含む値が生成されることがあります。Object Storageへアップロードする前にローカルParquetを検査し、ADB側でも次が0件になることを確認します。
SELECT COUNT(*) AS invalid_object_uri_count
FROM DOCUMENT_INVENTORY_EXT_V
WHERE object_uri LIKE '%<%'
OR object_uri NOT LIKE 'https://%';
● Database ActionsでSELECT AIがエラーになる
Database ActionsではSELECT AI Keywordを使用せず、DBMS_CLOUD_AI.GENERATEを実行します。
また、Database ActionsではSET_PROFILEへ依存せず、profile_name引数を明示します。
● 構造化データの質問でVector Tableが検索される
構造化データの質問をSELECT AI SHOWSQLで確認したとき、生成SQLが次のVector Tableを参照する場合があります。
OCI_DB_MANUAL_IDX$VECTAB
また、生成SQL内のEmbedding作成で次のProfileが使用されている場合は、RAG用Profileが現在のSessionへ設定されています。
OCI_DB_MANUAL_RAG
構造化検索の直前に、SQL用Profileを明示的に設定します。
BEGIN
DBMS_CLOUD_AI.SET_PROFILE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL'
);
END;
/
SELECT
DBMS_CLOUD_AI.GET_PROFILE AS current_profile
FROM
dual;
次の結果を確認してから、SELECT AIを実行します。
"RAG_USER"."OCI_DB_LAKEHOUSE_SQL"
SQL用ProfileのSHOWSQLでは、検索先が次のViewになります。
RAG_USER.V_DOCUMENT_LAKEHOUSE
● RAGが意図しない文書を参照する
標準のSelect AI with RAGは、SQL用Viewのapproval_statusやdocument_idを自動的にVector検索条件へ適用しません。
次の対策があります。
文書種別ごとにVector Indexを分ける
公開区分ごとにVector Indexを分ける
質問へ対象文書名を明示する
Custom SQL RAGでRelational Filterを適用する
Select AI AgentまたはPrivate Agent FactoryでToolを制御する
第4回では、構造化検索で対象文書を確認した後、文書名を明示してRAGを実行します。
■ リソースを削除
第5回以降で今回のLakehouseを再利用するため、基本的には削除せずに残します。
検証環境を削除する場合は、依存関係の逆順で削除します。
● SQL用Profileを削除
BEGIN
DBMS_CLOUD_AI.DROP_PROFILE(
profile_name => 'OCI_DB_LAKEHOUSE_SQL',
force => TRUE
);
END;
/
● Vector統合Viewを削除
DROP VIEW V_DOCUMENT_VECTOR_CHUNKS;
● Lakehouse統合Viewを削除
DROP VIEW V_DOCUMENT_LAKEHOUSE;
● Data Lake参照Viewを削除
DROP VIEW DOCUMENT_INVENTORY_EXT_V;
● RDBMS表を削除
DROP TABLE DOCUMENT_GOVERNANCE PURGE;
Data Catalog接続、同期External Table、既存RAG Profile、Vector Indexは、第5回以降で再利用する場合は削除しません。
■ まとめ
今回は、第1回から第3回までに作成したデータ資産を再利用し、Autonomous AI Database上でLakehouseとして統合しました。
主な検証結果です。
| 確認項目 | 結果 |
|---|---|
| Data Catalog同期 | Logical EntityをExternal Tableとして参照 |
| Data Lake+RDBMS | 文書Metadataとガバナンス情報をdocument_idでJOIN |
| Vector Storeとの統合 | 4文書、9,590チャンクを完全Object名でJOIN |
| JOIN漏れ | 0件 |
| Select AI | AI利用が承認された3文書をNL2SQLで検索 |
| Select AI with RAG | 選択したPDF本文を検索し、Oracle公式URLをSourceとして表示 |
| Profile設計 | SQL検索用とRAG検索用を分離 |
今回一番面白かったのは、Data CatalogのMetadataが、単なる「ファイルの一覧」ではなく、RDBMSの業務データとVector StoreのPDF本文を結び付ける設計情報になったことです。
Data Catalogは、Object Storageへファイルを入れるだけで、すべてを自動的に仕分けしてくれる魔法の箱ではありません。
document_id、object_name、製品バージョン、カテゴリ、RAG対象フラグなどを先に設計しておくことで、初めてRDBMSの承認情報やVector Storeのチャンクと正しく結び付けられます。
第1回 Data Lakeへデータを配置
↓
第2回 Metadataを設計してData Catalogで管理
↓
第3回 PDF本文をVector化してRAGへ対応
↓
第4回 Data Lake+RDBMS+Vector StoreをLakehouseとして統合
Object StorageにはParquetやPDFを置き、RDBMSには更新される業務ルールを持たせ、Vector Storeには本文のチャンクとEmbeddingを格納する。それぞれが得意な役割を残しながら、Oracle AI Databaseから同じSQLでつなげて利用できるところが、今回とても面白いと感じました。
Oracle Databaseを長く触ってきた人ほど、これまでのTableやView、JOINという考え方の先に、Data Lakeと非構造化データ、Vector Search、生成AIまでつながっていく構成には、グッとくるものがあると思います。
一方で、標準のSelect AIだけでは、構造化検索の結果とRAG検索の結果を1回の質問から自動的に統合できません。今回は人がProfileを切り替え、対象文書を次のRAG質問へ引き継ぎました。
この制約を確認できたことで、次にAI Agentへ任せる処理も明確になりました。
この時点で、AI Agentへ渡すための「データ」と「道具」は揃いました。
次回は、今回作成したLakehouseをAIDP Master Catalogへ登録し、より広いデータ基盤から発見、管理、利用できる形へ発展させてみてみたいです。
これで、AI Agentへ渡すための「道具」と「データ」が揃いました。
■ 次回以降
今後は、今回作成したLakehouseとデータ群をそのまま再利用し、AI Agent系の検証へ進みます。
| 回 | 予定 |
|---|---|
| 第5回 | AIDP Master Catalogへ既存Lakehouseを登録し、AI-readyなデータ基盤へ発展 |
| 第6回 | Private Agent FactoryからLakehouseのSQL検索とRAG検索を使い分け |
| 第7回 | Oracle APEX 26.1、APEX AI Agent、APEX Workflowから業務アプリ化 |
| 以降 | Oracle AI Data CatalogとApache IcebergによるOpen Lakehouseへ発展 |
■ 解説
■ おまけ
■ 参考資料
- OCI Data Catalog
- Query External Data with Data Catalog
- DBMS_DCAT Package
- Manage AI Profiles
- About Select AI
- Use AI Keyword to Enter Prompts
- Examples of Using Select AI
- Select AI with Retrieval Augmented Generation
- DBMS_CLOUD_AI Package
- Use Retrieval Augmented Generation to Complement LLMs
- SQL RAG Example
- Use Lakehouse with Autonomous AI Database
- Oracle AI Data Platform
-
DBMS_CLOUD_AI Package - Profile Attributes
- Select AIのAI Profileで設定できるAttribute一覧。
provider、object_list、comments、constraints、temperature、additional_instructionsなどの役割を確認できます。
- Select AIのAI Profileで設定できるAttribute一覧。
■ 参考資料詳細
今回の第4回では、OCI Data CatalogのLogical EntityとAutonomous AI DatabaseのExternal Table連携、Resource Principal、DBMS_DCAT、Select AIのNL2SQL、AI Profile、Vector Index、Select AI with RAGまで複数の機能を組み合わせています。
実装内容と対応付けて確認しやすいように、Oracle公式ドキュメントを分野ごとに整理します。
● OCI Data Catalog/Data Lake
-
- OCI Data Catalog全体のドキュメントです。
-
Harvesting Object Storage Files as Logical Data Entities
- Object Storage上のファイルをFilename PatternでLogical EntityとしてまとめてHarvestする仕組みを確認できます。
- 今回の
document_inventory.parquetをLogical Entityとして扱う部分の参考資料です。
-
Query External Data with Data Catalog
- OCI Data CatalogのMetadataをAutonomous AI Databaseから利用し、External TableとしてObject Storage上のデータを参照する構成を確認できます。
-
-
SET_DATA_CATALOG_CONN、SET_DATA_CATALOG_CREDENTIAL、SET_OBJECT_STORE_CREDENTIAL、RUN_SYNCなど、Data CatalogとAutonomous AI Databaseを同期するためのDBMS_DCATPackageを確認できます。 - Data Catalog同期によってProtected SchemaとExternal Tableが作成される仕組みや、
grant_read、同期用Dictionary Viewについても確認できます。
-
-
Use Lakehouse with Autonomous AI Database
- Object Storage上のData LakeデータをAutonomous AI DatabaseからSQLで利用するLakehouse機能の概要を確認できます。
-
Parquet to Oracle Data Type Mapping
- Parquetの型がAutonomous AI DatabaseのExternal TableでどのOracle Data Typeへマッピングされるかを確認できます。
- 今回の
rag_enabledで、ParquetのBoolean値をExternal Table側から確認する部分の参考資料です。
● Resource Principal/Object Storage
-
Use Resource Principal to Access Oracle Cloud Infrastructure Resources
- Autonomous AI DatabaseからOCI Resource Principalを使用してOCI Serviceへアクセスする仕組みを確認できます。
- 今回使用している
OCI$RESOURCE_PRINCIPALの参考資料です。
-
- Autonomous AI DatabaseからObject Storageを参照するときに使用できるURI形式を確認できます。
- 今回の文書インベントリで保持している
object_uriの形式を確認するときの参考資料です。
-
Uploading an Object Storage Object to a Bucket
- Object StorageへのObject UploadとUser-defined Metadataの設定方法を確認できます。
- OCI CLIの
oci os object put --metadataについても説明されています。
● Select AI/NL2SQL/AI Profile
-
- Select AIの概要と、自然言語からSQLを生成・実行するNL2SQLの位置付けを確認できます。
-
-
DBMS_CLOUD_AI.CREATE_PROFILE、SET_PROFILEを使用したAI Profileの作成・管理方法を確認できます。 -
SELECT AIを実行するStateful Sessionでは、SessionごとにProfileを設定する必要があることも確認できます。
-
-
- Select AIで使用する
DBMS_CLOUD_AIPackageの詳細です。 - 今回の
OCI_DB_LAKEHOUSE_SQLで設定した次のProfile Attributeを確認できます。
- Select AIで使用する
provider
credential_name
region
oci_compartment_id
model
object_list
object_list_mode
enforce_object_list
comments
constraints
temperature
max_tokens
additional_instructions
-
CREATE_PROFILE、SET_ATTRIBUTE、SET_PROFILE、GET_PROFILE、GENERATEなど、今回使用したProcedure/Functionも確認できます。 -
RAG Profileで使用した
enable_custom_source_uriについても説明されており、trueの場合はObject Storageのopc-meta-customized_url_sourceMetadata HeaderをSource URLとして使用する動作を確認できます。 -
Use AI Keyword to Enter Prompts
-
SELECT AI SHOWSQLやSELECT AI NARRATEなど、AI Keywordを使用した自然言語Promptの実行方法を確認できます。
-
-
- Select AIによるNL2SQL、
SHOWSQL、NARRATEなどの実行例を確認できます。
- Select AIによるNL2SQL、
-
Select your AI Provider and LLMs
- Select AIで利用できるAI Provider、Chat Model、Embedding Modelを確認できます。
- 今回使用している
cohere.command-a-03-2025とcohere.embed-v4.0を確認する際の参考資料です。
-
Regional availability for Generative AI models
- OCI Generative AI ModelのRegion別Availabilityを確認できます。
- Modelの利用可能Regionは変更される可能性があるため、再検証時にはこのページで確認します。
● Vector Store/Select AI with RAG
-
Select AI with Retrieval Augmented Generation
- Object Storage上のPDFなどを取得し、文書をText化、Chunk化、Embedding化してVector Storeへ格納し、Semantic SearchからRAG回答を生成するSelect AI with RAGの処理全体を確認できます。
- 今回参照しているVector Tableの
CONTENT、ATTRIBUTES、EMBEDDINGを理解するための中心的な参考資料です。
-
DBMS_CLOUD_AI Package - Vector Index
-
DBMS_CLOUD_AI.CREATE_VECTOR_INDEXとVector Index Attributeを確認できます。 -
location、chunk_size、chunk_overlap、vector_dimension、refresh_rateなど、Vector Store作成時の設定を確認できます。
-
-
Use Retrieval Augmented Generation to Complement LLMs
- Oracle AI Vector Searchを利用したRAGの基本構成と、Relational DataとVector Dataを組み合わせる考え方を確認できます。
-
- Oracle AI Vector SearchをSQLから利用してRAGを構成する例を確認できます。
- 今回の
V_DOCUMENT_VECTOR_CHUNKSのように、Relational MetadataとVector StoreをSQLで関連付ける場合の参考になります。
● Object StorageのCustom Source URL
今回の第3回/第4回では、PDF Upload時に次のUser-defined Metadataを設定しています。
customized_url_source
Object Storage側では、Metadata Headerとして次の名前で確認できます。
opc-meta-customized_url_source
Select AIのRAG Profileで、
enable_custom_source_uri = true
を設定すると、このMetadata Headerに設定したURLをRAG回答のSourcesとして利用できます。
この動作は次のOracle公式ドキュメントで確認できます。
今回の環境では、Vector Tableの
ATTRIBUTESJSON内にcustom_uriとして同じSource URLが保持されていることを確認しました。ただし、
ATTRIBUTES.custom_uriというJSON Property名そのものを公開仕様として保証するOracle公式ドキュメントは確認できていないため、本稿では「今回の環境で確認できたVector Store内部のMetadata表現」として扱っています。
● 次回以降の発展
-
Oracle AI Data Platform
- 今回作成したData Lake、RDBMS、Vector Storeを、次回以降AIDPのCatalog/AI-ready Dataへ発展させる際の参考資料です。

