16
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OCI Generative AI AgentsとADBを使ってRAG対応チャットを実装してみた

Last updated at Posted at 2024-12-05

本記事は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_keyfingerprint の箇所に入力する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ユーザのパスワードを格納するためのボールトを作成します。
以下を参考にボールト、およびキーを作成します。

以下にある「接続」サービスへアクセスします。
開発者サービス → データベース・ツール → 接続

「接続の作成」を選択します。
WS000006.JPG

以下を参考に入力します。
WS000007.JPG

「パスワード・シークレットの作成」を選択します。
先ほど作成したボールトを選択し、冒頭で作成したDBユーザのパスワードを入力します。
WS000008.JPG

元の入力画面に戻りましたら、接続文字列を入力します。
以下は入力例です。
hostservice_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)))

その他は以下を参考に入力します。
WS000009.JPG

「プライベート・エンドポイントの作成」を選択します。
ADBのエンドポイントを配置したプライベート・サブネットを入力します。
WS000010.JPG

最後に「作成」を選択します。
WS000011.JPG

エージェントの作成

Generative AI Agentsでエージェントを作成します。
以下の通りGenerative AI Agentsのトップ画面へアクセスします。
アナリティクスとAI → AIサービス → 生成AIエージェント
WS000001.JPG

左メニューの「エージェント」を選択し、「エージェントの作成」を押下します。
WS000002.JPG

以下を参考に入力します。
WS000003.JPG

「ナレッジ・ベースの作成」を選択します。
先ほど作成した接続、ADB内に作成したベクトル検索用のファンクションを入力します。
「接続のテスト」を選択し、成功したら「作成」を押下します。
WS000004.JPG

「このエージェントのエンドポイントの自動作成」をチェックし、「作成」を押下します。
WS000005.JPG

チャットを試す

Generative AI Agentsの左にあるメニューから「チャット」を選択します。
「エージェント」と「エージェント・エンドポイント」をプルダウンから入力します。
あとはアップロードしたファイルの内容と関連する質問を投げかけます。
すると以下のように、ベクトル検索およびリランクした結果がログとして表示され、最終回答が返ってきます。
WS000000.JPG

ログの内容を展開するとベクトル検索の結果を確認できます。
WS000000-2.JPG

以上、OCI Generative AI Agentsを使ったRAG対応チャットの実装でした。
LLMとベクトルDBの連携がマネージドサービスとして提供されるため、より効率的にRAGを実装できますね。

16
3
0

Register as a new user and use Qiita more conveniently

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?