本記事はOracle Cloud Infrastructure Advent Calendar 2024の五日目の記事となります。
OCI Generative AI AgentsはAIエージェントのマネージドサービスです。
本サービスを使うとベクトル検索を使ったRAGを効率的に実装できます。
リランクなど精度向上に関わる工夫がサービス内部で自動的に行われる、という特徴を持っています。
OCI Generative AI Agentsはナレッジベース (ベクトル検索のソース) としてObject Storage、OCI Search Service with OpenSearch、Base Database Service (BaseDB)、Autonomous Database (ADB) を選択できます。
今回はADBとの連携を試してみました。
ADBの作成
ADBを23aiで作成します。
具体的な手順は下記をご参照ください。
なおネットワークはプライベート・サブネットに作成してください。
mTLS認証の設定はオフにします。
DBユーザの作成
プライベート・サブネットにADBを作成したため、DBログインするにはBastionを使います。
Bastion経由でADBへアクセスする手順は下記をご参照ください。
※もしホーム・リージョンにADBを作成した場合は、下記手順でCloud ShellからADBに直接アクセス可能です。
https://qiita.com/letian/items/f28aa9ab2a3e5b49b42d
DBログインできたらユーザを作成し、必要な権限を付与します。
今回は agents
という名前のDBユーザを作成しました。
CREATE USER agents IDENTIFIED BY "your password" QUOTA UNLIMITED ON data;
GRANT DWROLE to agents;
GRANT DB_DEVELOPER_ROLE to agents;
GRANT CREATE MINING MODEL TO agents;
GRANT EXECUTE ON DBMS_CLOUD TO agents;
GRANT EXECUTE ON DBMS_VECTOR TO agents;
REST API実行できるように設定します。
BEGIN
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
host => '*',
ace => xs$ace_type(privilege_list => xs$name_list('connect'),
principal_name => 'agents',
principal_type => xs_acl.ptype_db));
END;
/
Object Storageアクセスの設定
本検証ではRAGに使うファイルをOCI Object Storageに配置します。
そのためObject Storageにアクセスするための資格証明を作成します。
まずは下記を参照し、認証トークンを取得します。
資格証明を作成します。
※これ以降は先ほど作成したDBユーザで作業します。
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'OBJ_CRED',
username => 'your user name',
password => 'your auth token'
);
END;
/
Object Storageのバケットを作成します。
今回はObject Storageに最近追加されたプライベート・エンドポイント機能を使ってみます。
作成手順は下記をご参照ください。
Embeddingの設定
Object Storageに配置した非構造化データをベクトル化するために、Embeddingモデル用の資格証明を作ります。
今回はOCI Generative AIで提供されているモデル cohere.embed-multilingual-v3.0
を使います。
そのためOCI向けの資格証明を作成します。
JSONの各項目はご自分の情報を入力してください。
DECLARE
jo json_object_t;
BEGIN
jo := json_object_t();
jo.put('user_ocid','your user ocid');
jo.put('tenancy_ocid','your tenancy ocid');
jo.put('compartment_ocid','your compartment ocid');
jo.put('private_key','your private key');
jo.put('fingerprint','your fingerprint');
DBMS_VECTOR.CREATE_CREDENTIAL(
CREDENTIAL_NAME => 'OCI_GENAI',
PARAMS => json(jo.to_string));
end;
/
private_key
、fingerprint
の箇所に入力するAPIキー情報の取得方法は下記をご参照ください。
なおADBはプライベート・サブネットに配置しているため、OCI Generative AIサービスへアクセスするには事前にサービス・ゲートウェイを作成し、ルート表を更新する必要があります。
表の作成
ベクトルデータを格納する表を作ります。
CREATE TABLE "DOCUMENTS"
( "DOCID" NUMBER GENERATED ALWAYS AS IDENTITY,
"BODY" VARCHAR2(4000),
"VECTOR" VECTOR,
"CHUNKID" NUMBER,
"URL" VARCHAR2(512),
"TITLE" VARCHAR2(512),
CONSTRAINT "DOCUMENTS_PK" PRIMARY KEY ("DOCID") USING INDEX ENABLE
);
なおOCI Generative AI Agentsと連携するためには、下記マニュアル記載の要件を満たす表を作成する必要があります。
データベースの要件 → データベース表 をご参照ください。
Object Storage上のファイルをベクトル化
まずは作成したバケットにRAGで使いたい任意のファイルをアップロードしておきます。
そしてバケット内のオブジェクトをベクトル化するプロシージャを作成します。
※bucket_url
の値はご自分の情報を入力してください。
CREATE OR REPLACE PROCEDURE embed_files
IS
chunk_params clob;
cohere_params clob;
l_blob BLOB := NULL;
bucket_url CLOB := 'https://<your private endpoint prefix>-<your namespace>.private.objectstorage.us-chicago-1.oci.customer-oci.com/n/<your namespace>/b/<your bucket name>/o/';
BEGIN
-- チャンク分割する際のパラメータ
chunk_params := '
{
"max": "200",
"overlap": "40"
}';
-- OCI GenAI のEmbeddingを利用
cohere_params := '
{
"provider": "ocigenai",
"credential_name": "OCI_GENAI",
"url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText",
"model": "cohere.embed-multilingual-v3.0"
}';
-- DOCUMENTS表をリセット
DELETE FROM documents;
-- Object Storage上の各オブジェクトに対してEmbeddingしたデータを保存
FOR rec IN (SELECT OBJECT_NAME FROM DBMS_CLOUD.LIST_OBJECTS('OBJ_CRED', bucket_url))
LOOP
-- オブジェクトを取得
l_blob := DBMS_CLOUD.GET_OBJECT(
credential_name => 'OBJ_CRED',
object_uri => bucket_url || rec.object_name);
-- チャンク分割したテキストをDOCUMENTS表に保存
INSERT INTO documents (body, url, title)
SELECT chunk_t.chunk_data, rec.object_name, rec.object_name
FROM
DBMS_VECTOR_CHAIN.UTL_TO_CHUNKS(REPLACE(DBMS_VECTOR_CHAIN.UTL_TO_TEXT(l_blob), CHR(10)), JSON(chunk_params)) chunk_jt,
JSON_TABLE(chunk_jt.column_value, '$[*]' COLUMNS (chunk_id NUMBER PATH
'$.chunk_id', chunk_data VARCHAR2(4000) PATH '$.chunk_data')) chunk_t;
-- DOCUMENTS表に新規保存された各テキストについて、Cohereの embed-multilingual-v3.0 を使ってEmbeddingし、DOCUMENTS表に保存
FOR rec2 IN (SELECT docid, body FROM documents)
LOOP
UPDATE documents
SET
vector = DBMS_VECTOR.UTL_TO_EMBEDDING(rec2.body, JSON(cohere_params))
WHERE docid = rec2.docid;
END LOOP;
END LOOP;
COMMIT;
END;
/
こちらのプロシージャはバケット内のオブジェクトをすべて読みこんでベクトル化し、DOCUMENTS表に保存します。
プロシージャを作成できましたら実行します。
exec embed_files;
OCI Generative AI Agentsが利用するファンクションの作成
Generative AI AgentsがADB内でベクトル検索を行い、結果を取得するためのファンクションを作成します。
CREATE OR REPLACE FUNCTION retrieval_func (
p_query IN VARCHAR2,
top_k IN NUMBER
)
RETURN SYS_REFCURSOR IS
v_results SYS_REFCURSOR;
cohere_params clob;
query_vec VECTOR;
BEGIN
-- OCI GenAI のEmbeddingを利用
cohere_params := '
{
"provider": "ocigenai",
"credential_name": "OCI_GENAI",
"url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText",
"model": "cohere.embed-multilingual-v3.0"
}';
query_vec := DBMS_VECTOR.UTL_TO_EMBEDDING(p_query, JSON(cohere_params));
OPEN v_results FOR
SELECT docid, body, VECTOR_DISTANCE(vector, query_vec, COSINE) as score, chunkid, title
FROM documents
ORDER BY score
FETCH FIRST top_k ROWS ONLY;
RETURN v_results;
END;
/
なおファンクションが満たすべき要件やサンプルは下記マニュアルをご参照ください。
データベースの要件 → データベース関数
DB接続の設定
Generative AI AgentsとADBが連携するために、いくつかOCIコンソール上で作業する必要があります。
まずはADBにネットワーク・セキュリティ・グループを設定し、下記マニュアルに記載されている要件を満たすようにNW許可設定を入れます。
ネットワークおよびセキュリティー要件 → ネットワーキング要件
次にDBユーザのパスワードを格納するためのボールトを作成します。
以下を参考にボールト、およびキーを作成します。
以下にある「接続」サービスへアクセスします。
開発者サービス → データベース・ツール → 接続
「パスワード・シークレットの作成」を選択します。
先ほど作成したボールトを選択し、冒頭で作成したDBユーザのパスワードを入力します。
元の入力画面に戻りましたら、接続文字列を入力します。
以下は入力例です。
host
と service_name
はご自分の情報を入力します。
(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)
(host=<private-endpoint-URL>)(connect_data=(service_name=xxx_high.adb.oraclecloud.com))
(security=(ssl_server_dn_match=no)))
「プライベート・エンドポイントの作成」を選択します。
ADBのエンドポイントを配置したプライベート・サブネットを入力します。
エージェントの作成
Generative AI Agentsでエージェントを作成します。
以下の通りGenerative AI Agentsのトップ画面へアクセスします。
アナリティクスとAI → AIサービス → 生成AIエージェント
左メニューの「エージェント」を選択し、「エージェントの作成」を押下します。
「ナレッジ・ベースの作成」を選択します。
先ほど作成した接続、ADB内に作成したベクトル検索用のファンクションを入力します。
「接続のテスト」を選択し、成功したら「作成」を押下します。
「このエージェントのエンドポイントの自動作成」をチェックし、「作成」を押下します。
チャットを試す
Generative AI Agentsの左にあるメニューから「チャット」を選択します。
「エージェント」と「エージェント・エンドポイント」をプルダウンから入力します。
あとはアップロードしたファイルの内容と関連する質問を投げかけます。
すると以下のように、ベクトル検索およびリランクした結果がログとして表示され、最終回答が返ってきます。
以上、OCI Generative AI Agentsを使ったRAG対応チャットの実装でした。
LLMとベクトルDBの連携がマネージドサービスとして提供されるため、より効率的にRAGを実装できますね。