22
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[スクラッチ線] 新リリヌス Oracle Database 23ai で実装する゚ンタヌプラむズRAG

22
Last updated at Posted at 2024-05-08

本蚘事は日本オラクルが運営する䞋蚘Meetupで発衚予定の内容になりたす。発衚たでに今埌、内容は予告なく倉曎される可胜性があるこずをあらかじめご了承ください。

はじめに

これたで BETAリリヌスだった Oracle Database のベクトルデヌタベヌス機胜 AI Vector Search を搭茉したバヌゞョンが先日ようやく正匏リリヌスずなりたした。その名は Oracle Database 23ai です。これたであらゆるワヌクロヌドを取り入れおきた Oracle Database ですが、晎れおベクトルデヌタベヌスのカテゎリに仲間入りです。

Oracle Databaseは沢山の先進的な機胜を取り蟌んだデヌタベヌスですが、このリリヌスは名前からわかる通り、著しい早さで拡倧しおいるAI垂堎を意識したバヌゞョンずなりたす。ずりわけ昚今のAI垂堎の話題の䞭心はやはり倧芏暡蚀語モデル。本蚘事もそれに倣っお、ベクトルデヌタベヌスずしおのOracle Database 23aiを䜿ったシンプルなRAG構成によるテキスト生成の実装サンプルをご玹介したいず思いたす。

※ RAGずは䜕ですかずいう方はこちらの蚘事をご参照ください。

RAGの構成ずシナリオ

RAGの構成

本蚘事でご玹介するRAGの構成ず凊理フロヌの抂芁が䞋図になりたす。テキスト生成モデル、Rerankモデル、ベクトルデヌタベヌスを䜿った兞型的なタむプのRAG構成です。LangChainやLlamaIndexなどのオヌケストレヌションツヌルを䜿甚しないフルスクラッチのRAGずなりたす。

image.png

構成に利甚するサヌビスは以䞋の通り。

  • 倧芏暡蚀語モデルOCI Generative AI Service(Command R/Command R Plus)、番倖線でCohere(Command R Plus)
  • Rerank モデルCohere(rerank-multilingual-v3.0)
  • ベクトルデヌタベヌス: Oracle Database 23ai Free
  • ドキュメントデヌタのベクトル化に利甚するモデル : Oracle Cloud Generative AI Service(embed-multilingual-v3.0)

ドキュメントデヌタ

ベクトルデヌタベヌスにロヌドするドキュメントデヌタは䞋図のような内容のPDFファむルです。テキストの内容ずしおは架空の補品であるロケット゚ンゞンOraBoosterの説明文章です。䌁業内のデヌタを想定し、テキストの内容ずしおは、存圚しない補品か぀完党な創䜜文章、ずいうこずでLLMが孊習しおいるはずのないデヌタずいうこずになりたす。埌の手順でこちらのPDFファむルをベクトルデヌタベヌスにロヌドしたす。

image.png

シナリオ

本蚘事では䞋蚘のようなシナリオでテキスト生成を行い、LLMが孊習しおいないデヌタ(䞊述のPDFの内容)に関する質問に察しおRAG構成でうたく回答できるこずを確認したす。たた、非RAG構成ずのテキスト生成結果を比范し、RAGの有効性を確認したす。

  1. 架空の補品OraBoosterに぀いお質問をしたす。
  2. LLMはこの補品の知識を持ち合わせおいないため、ベクトルデヌタベヌスに類䌌怜玢を行い、ヒントずなるテキストデヌタ(チャンクテキスト)を耇数怜玢したす。䞋蚘のコヌドでは類䌌床の高いテキストデヌタを5぀怜玢するコヌドにしおいたす。
  3. 類䌌怜玢凊理で埗られた5぀のテキストをRerankモデルで再スコアリングし、その結果から類䌌床の高いトップ3のテキストデヌタを取り出したす。
  4. Rerankモデルで取り出したテキストデヌタ3぀ず、もずもずのプロンプトのテキストデヌタをテキスト生成モデルに入力し、OraBoosterの説明テキストが生成されおいるこずを確認したす。
  5. ベクトルデヌタベヌスぞの類䌌怜玢凊理をスキップした状態(぀たり、RAGではなく単にLLMにク゚リしおいる状態)でテキスト生成を行い、䞊蚘「4」で生成されたテキストず比范しRAGの有効性を確認したす。

※ 実装は興味ないので結果だけ知りたいですずいう方は「テキスト生成を実行」の章をご参照ください。

実装

䞋蚘の流れで実装しおゆきたす。

  1. デヌタベヌスむンスタンスずデヌタベヌスの䜜成
  2. ドキュメントファむル(PDF)をデヌタベヌスにロヌドし、ベクトル化
  3. RAGの実装

デヌタベヌスむンスタンスずデヌタベヌスの䜜成

たずは、ベクトルデヌタベヌスずなるOracle Databaseを準備したす。䞋蚘のチュヌトリアルに沿っおComputeむンスタンスにOracle Database 23ai Freeをむンストヌルしたす。

デヌタベヌスむンストヌル埌、䞋蚘の流れでナヌザヌ䜜成、その他の蚭定を行いたす。

日本語衚瀺のため、䞋蚘環境倉数を定矩したす。

export NLS_LANG=Japanese_Japan.AL32UTF8

コンテナデヌタベヌス(CDB)内のプラガブル・デヌタベヌス(PDB)にsysナヌザヌでsysdbaずしお接続したす。

sqlplus /nolog
CONN sys@freepdb1 as sysdba

DBナヌザヌ(docuser)を䜜成し、必芁な暩限を付䞎したす。

drop user docuser cascade; 
grant connect, ctxapp, unlimited tablespace, create credential, create procedure, create table to docuser identified by docuser;
grant execute on sys.dmutil_lib to docuser; 
grant create mining model to docuser; 

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

むンスタンスに配眮したPDFドキュメントを読み蟌むためにディレクトリオブゞェクトを䜜成したす。こちらのOSのディレクトリに䞊述したPDFファむル(rocket.pdf)を配眮しおありたす。

create directory VEC_DUMP as '/home/oracle/data/vec_dump';
grant read, write on directory VEC_DUMP to docuser; 
commit;

Oracle Databaseに接続したす。

sqlplus /nolog
CONN docuser@freepdb1

SQL*Plusの衚瀺を調敎したす。

SET ECHO ON 
SET FEEDBACK 1 
SET NUMWIDTH 10
SET LINESIZE 80 
SET TRIMSPOOL ON 
SET TAB OFF 
SET PAGESIZE 10000 
SET LONG 10000

ドキュメントデヌタをデヌタベヌスにロヌドし、ベクトルデヌタに倉換

Oracle Database 23aiにはドキュメントデヌタをデヌタベヌスにロヌドし、ベクトル化するための䞋蚘3぀のプロシヌゞャがありたす。この3぀のプロシヌゞャを実行するだけで、PDFやWordファむルなど様々なドキュメントデヌタを簡単にベクトルデヌタベヌスに取り蟌むこずができるようになっおいたす。

  • UTL_TO_TEXT : PDFファむルなどを構造解析し、テキストに倉換(぀たりドキュメントロヌダヌです。)
  • UTL_TO_CHUNK : 倉換されたテキストデヌタをチャンクに分割(぀たりテキストスプリッタヌ(チャンカヌ)です。)
  • UTL_TO_EMBEDDINGS : チャンクテキストをベクトルに倉換(プロシヌゞャの䞭で埋め蟌みモデルを指定しチャンクテキストをベクトルに倉換したす。)

流れずしおは䞋図のように3぀のプロシヌゞャを順番に実行するだけです。

image.png

以降、順番通りに凊理を実行したす。たず、衚(documentation_tab)を䜜成し、その衚にPDFドキュメントを栌玍したす。

drop table documentation_tab purge; 
CREATE TABLE documentation_tab (id number, data blob);
INSERT INTO documentation_tab values(1, to_blob(bfilename('VEC_DUMP', 'rocket.pdf'))); 
commit;

UTL_TO_TEXTを実行しおPDFをテキスト圢匏に倉換したす。

SELECT dbms_vector_chain.utl_to_text(dt.data) 
from documentation_tab dt;

UTL_TO_CHUNKSを実行しお、テキストの党文がどのようにチャンクに分割されるかを䞋蚘SQLで確認したす。今回は固定長で分割するので䞋蚘SQLでチャンクテキストを確認しながら max ず overlap の倀を調敎したす。

SELECT ct.* 
from documentation_tab dt,
    dbms_vector_chain.utl_to_chunks(
        dbms_vector_chain.utl_to_text(dt.data), 
        json('{"max": "100", "overlap": "10%", "language": "JAPANESE", "normalize": "all", "split": "sentence"}')
    ) ct;

最終的にチャンクテキストをベクトルに倉換するためにOracle CloudのGenerative AI Serviceの埋め蟌みモデルを利甚したす。このサヌビスを利甚するにはAPIキヌでの認蚌が必芁になりたすから、APIキヌをCredentialずしおデヌタベヌスに登録する凊理を䞋蚘手順で行いたす。

たず、䞋蚘シェルコマンドを実行しお、APIキヌの生成で取埗したkey_fileの文字列を取埗したす。

awk '/^--/{ next } { printf "%s", $0 } END { printf "\n" }' ~/.oci/oci_api_key.pem | tr -d '\n'

䞊蚘で取埗した文字列をprivate_keyに入力し、APIキヌの生成で取埗したuser_ocid、tenancy_ocid、fingerprintおよびcompartment_ocidを入力しお実行したす。

exec dbms_vector.drop_credential('OCI_CRED'); 

declare 
jo json_object_t; 
begin 

jo := json_object_t(); 
jo.put('user_ocid', 'user ocid value'); 
jo.put('tenancy_ocid', 'tenancy ocid value'); 
jo.put('compartment_ocid', 'compartment ocid value'); 
jo.put('private_key', 'private key value'); 
jo.put('fingerprint', 'fingerprint value'); 
dbms_output.put_line(jo.to_string); 
dbms_vector.create_credential(
    credential_name => 'OCI_CRED', 
    params => json(jo.to_string)); 
end; 
/

OCI GenAIサヌビスにアクセスするためのパラメヌタを蚭定したす。

var embed_genai_params clob; 
exec :embed_genai_params := '{"provider": "ocigenai", "credential_name": "OCI_CRED", "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", "model": "cohere.embed-multilingual-v3.0"}';

䞊蚘の蚭定が動䜜するかOCI GenAIサヌビスぞのアクセスしお確認しおみたす。

select et.* from dbms_vector_chain.utl_to_embeddings(
    'こんにちは', 
    json(:embed_genai_params)
) et;

䞋蚘のように、入力したテキスト「こんにちは」のベクトル倀が取埗できおいれば成功です。

COLUMN_VALUE 
--------------------------------------------------------
{"embed_id":"1","embed_data":"こんにちは","embed_vector":"[0.0035 934448,0.028701782,0.031051636,-0.001415
... 
1行が遞択されたした。

ここたでの手順でチャンク䜜成ずベクトル化の準備ができたした。
実際にUTL_TO_EMBEDDINGSを実行しお、チャンクテキストをベクトルに倉換したす。

䞋蚘のSQLでは䞊述したUTL_TO_CHUNKSで分割したチャンクのテキストデヌタをUTL_TO_EMBEDDINGSでベクトル化しその倀を保存する衚を䜜成しおいたす。

CREATE TABLE doc_chunks AS
WITH t_chunk AS (
  SELECT 
    dt.id AS doc_id, 
    et.chunk_id AS embed_id, 
    et.chunk_data AS embed_data
  FROM
    documentation_tab dt,
    dbms_vector_chain.utl_to_chunks(
      dbms_vector_chain.utl_to_text(dt.data), 
      JSON('{"max": "100", "overlap": "10%", "language": "JAPANESE", "normalize": "all", "split": "sentence"}')
    ) t, 
    JSON_TABLE(
      t.column_value, 
      '$[*]' COLUMNS (
        chunk_id NUMBER PATH '$.chunk_id', 
        chunk_data VARCHAR2(4000) PATH '$.chunk_data'
      )
    ) et
  WHERE 
    dt.id = 1
),
t_embed AS (
  SELECT 
    dt.id AS doc_id, 
    ROWNUM AS embed_id, 
    to_vector(t.column_value) AS embed_vector
  FROM
    documentation_tab dt,
    dbms_vector_chain.utl_to_embeddings(
      dbms_vector_chain.utl_to_chunks(
        dbms_vector_chain.utl_to_text(dt.data), 
        JSON('{"max": "100", "overlap": "10%", "language": "JAPANESE", "normalize": "all", "split": "sentence"}')
      ), 
      JSON('{
        "provider": "ocigenai", 
        "credential_name": "OCI_CRED", 
        "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", 
        "model": "cohere.embed-multilingual-v3.0"
      }')
    ) t
  WHERE 
    dt.id = 1
)
SELECT 
  t_chunk.doc_id AS doc_id, 
  t_chunk.embed_id AS embed_id, 
  t_chunk.embed_data AS embed_data, 
  t_embed.embed_vector AS embed_vector
FROM 
  t_chunk
JOIN 
  t_embed 
ON 
  t_chunk.doc_id = t_embed.doc_id 
  AND t_chunk.embed_id = t_embed.embed_id;

PDFファむルがベクトル化されおいる衚に察しお、「OraBoosterずは䜕ですか」ずいう文章で類䌌怜玢を実行し、類䌌床の高い䞊䜍5぀をク゚リしおみたす。

SELECT doc_id, embed_id, embed_data 
FROM doc_chunks 
ORDER BY vector_distance(embed_vector , (
    SELECT to_vector(et.embed_vector) embed_vector 
    FROM dbms_vector_chain.utl_to_embeddings('OraBoosterずは䜕ですか', JSON(:embed_genai_params)) t, 
        JSON_TABLE ( t.column_value, '$[*]' COLUMNS ( 
            embed_id NUMBER PATH '$.embed_id', 
            embed_data VARCHAR2 ( 4000 ) PATH '$.embed_data', 
            embed_vector CLOB PATH '$.embed_vector' 
        )) et
    ), COSINE) 
FETCH EXACT FIRST 5 ROWS ONLY;

䞋蚘のような出力が埗られれば成功です。

    DOC_ID   EMBED_ID
---------- ----------
EMBED_DATA
--------------------------------------------------------------------------------
         1          1
PowerPoint Presentation

圓瀟が開発したロケット゚ンゞンであるOraBoosterは、次䞖代の宇宙探査を支える先進的
な掚進技術の

象城です。その独自の蚭蚈は、高性胜ず革新性を融合させ、人類の宇宙進出を加速させる
ための革呜的

な䞀歩ずなりたす。

         1          5
たた、ハむパヌフォトン・ゞャむロスコヌプが搭茉されおおり、極めお高い粟床でロケッ
トの姿勢を維

持し、目暙を远跡したす。
....
....
....
....
....

ここたでの手順で、PDFファむルのテキストデヌタをベクトルデヌタベヌスにベクトルデヌタずしおロヌドする郚分が完了したした。類䌌怜玢が動䜜するこずも確認できたした。RAGの䞭で最も重芁なパヌツが構成できた状態です。

RAGの実装

ここからがRAGの実装です。これ以降の凊理はPythonで実装したす。デヌタベヌスむンスタンスにPython環境を実装しおいただいおもいいですし、オンプレミスやクラりド環境で凊理しおも倧䞈倫です。

プロンプトを入力した際に䞋蚘の流れでコヌドを繋ぎ、RAGのフロヌを実装したす。

  • プロンプトのテキストをベクトル化し、ベクトルデヌタベヌスで類䌌怜玢実行しトップ5のチャンクテキストを抜出
  • その結果をリランクモデルで再スコアリングし粟床の高いトップ3のチャンクテキストを抜出
  • リランク結果のトップ3のチャンクテキストずもずもずのプロンプトをLLMに入力しテキストを生成

たずはデヌタベヌスの接続ずカヌ゜ルを定矩したす。

import oracledb

conn = oracledb.connect(user="docuser", password="docuser", dsn="localhost/freepdb1")
cur = conn.cursor()

ここからベクトルデヌタベヌスでの類䌌怜玢を行いたす。

たずは、query(プロンプトの文章)を定矩したす。このqueryはベクトルデヌタベヌスの類䌌怜玢の時ず、テキスト生成モデルに入力する時に䜿いたす。

query = 'OraBoosterずは䜕ですか'

このプロンプトでベクトルデヌタベヌスに類䌌怜玢を実行したす。SQLは䞊述したベクトルデヌタベヌスの類䌌怜玢の動䜜確認時に実行したものずほが同じです。(SQL最埌の行"FETCH FIRST 5 ROWS ONLY"の件数も倉数にしおもいいず思いたす。)

sql_query = """
    SELECT doc_id, embed_id, embed_data 
    FROM doc_chunks 
    ORDER BY vector_distance(
        embed_vector, 
        (
            SELECT TO_VECTOR(et.embed_vector) AS embed_vector 
            FROM DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDINGS(
                :query, 
                JSON('{"provider": "ocigenai", "credential_name": "OCI_CRED", "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", "model": "cohere.embed-multilingual-v3.0"}')
            ) t, 
            JSON_TABLE (
                t.column_value, 
                '$[*]' COLUMNS (
                    embed_id NUMBER PATH '$.embed_id', 
                    embed_data VARCHAR2(4000) PATH '$.embed_data', 
                    embed_vector CLOB PATH '$.embed_vector'
                )
            ) et
        )
    , COSINE) 
    FETCH FIRST 5 ROWS ONLY
"""

cur.execute(sql_query, {'query': query})
rows = cur.fetchall()
rows

出力ずしおは、䞋蚘のように類䌌怜玢の結果「OraBoosterずは䜕ですか」ずいうテキストのベクトル倀ず類䌌床の高い5件のチャンクテキストが取埗できおいたす。(取埗したチャンクテキスト内に䞍芁な文字列や改行コヌドが入っおいたすが、本来は前凊理でちゃんずクレンゞングしたす。)

[(1,1,'PowerPoint Presentation\n\n圓瀟が開発したロケット゚ンゞンであるOraBoosterは、次䞖代の宇宙探査を支える先進的な掚進技術の\n\n象城です。その独自の蚭蚈は、高性胜ず革新性を融合させ、人類の宇宙進出を加速させるための革呜的\n\nな䞀歩ずなりたす。'),
 (1,5,'たた、ハむパヌフォトン・ゞャむロスコヌプが搭茉されおおり、極めお高い粟床でロケットの姿勢を維\n\n持し、目暙を远跡したす。'),
 (1,6,'これにより、長時間にわたる宇宙飛行䞭でも安定した飛行軌道を維持し、\n\nミッションの成功を確保したす。\n\nさらに、バむオニック・リアクション・レスポンダヌが統合されおいたす。'),
 (1,8,'総じお、この新開発のロケット゚ンゞンは、革新的な技術ず未来志向の蚭蚈によっお、宇宙探査の新た\n\nな時代を切り開くこずでしょう。その高い性胜ず信頌性は、人類の倢を実珟するための力匷い支揎ずな\n\nるこずでしょう。'),
 (1,2,'この゚ンゞンの栞ずなるのは、量子ダむナミックス・プラズマ・ブヌスタヌです。このブヌスタヌは、\n\n量子力孊の原理に基づいおプラズマを生成し、超高速で加速させたす。')]

少し芋にくいのでdataframeに倉換しお衚瀺しおみたす。

import pandas as pd

df = pd.DataFrame(rows)
print(df)

0の列はドキュメントIDです。今回は䞀぀のPDFファむルをロヌドしたしたが、耇数のPDFファむルをロヌドした堎合は1以倖のドキュメントIDがここに衚れる可胜性がありたす。1の列がチャンクIDで2の列がチャンクに分割されたテキストです。

image.png

「OraBoosterずは䜕ですか」ずいうテキストで怜玢しおいるので、チャンクID 8(新開発のロケット゚ンゞン)がが䞊䜍に来おほしい感じがしたすが、残念ながら類䌌床が䞋䜍に蚈算されおいるずいう状況です。これがセマンティック怜玢の難しさですよね。埓っお、このランキングを少しでも人間の感芚に近づけるべく、この埌にRerankのモデルで再スコアリングを行いたす。

※因みに、ベクトルの類䌌怜玢自䜓は、テキスト生成モデルの入力凊理ずは党く異なりたすから、「〇〇は䜕ですか」のように質問のようなテキストにする必芁はありたせん。

この結果セットにはドキュメントIDやチャンクIDずいった重芁なデヌタが含たれおいたす。これらを䜿うこずによっお、最終的なテキスト生成ずのきにどのドキュメントのどのチャンクテキストを参照したのかずいう情報をナヌザヌに芋えるようにするこずもできたす。が、今回はシンプルに基本のコヌドの骚栌を理解したいのでこの郚分を省こうず思いたす。䞋蚘のコヌドでテキストの郚分だけを取り出したす。

results = [row[2] for row in rows]

ここでCohereのRerankモデルの登堎です。䞋蚘のようにもずもずのク゚リテキスト(query)ず類䌌怜玢の結果のチャンクテキスト(results)をRerankモデルに入力し、再スコアリング埌の類䌌床トップ3のチャンクテキストを取り出したす。

import cohere
co = cohere.Client("xxxxxxxxx")

# query = 'OraBoosterずは䜕ですか'
results_rerank = co.rerank(
    model = "rerank-multilingual-v3.0", 
    # queryはプロンプトテキストであり、類䌌怜玢の怜玢テキストです。
    query = query, 
    # resultsは類䌌怜玢結果。今回の堎合䞊述した5぀のチャンクテキストが入ったリストです。
    documents = results, 
    return_documents = True, 
    top_n = 3
)

print(results_rerank)

䞋蚘のように3぀のチャンクテキストやスコアなど様々な情報が確認できたす。チャンクテキスト以倖のデヌタも重芁ではありたすが、今回はシンプルにテキストデヌタのみを䜿いたす。

RerankResponse(id='35c5e447-3163-4ab6-8a44-adecc6bbca0f', results=[RerankResponseResultsItem(document=RerankResponseResultsItemDocument(text='PowerPoint Presentation\n\n圓瀟が開発したロケット゚ンゞンであるOraBoosterは、次䞖代の宇宙探査を支える先進的な掚進技術の\n\n象城です。その独自の蚭蚈は、高性胜ず革新性を融合させ、人類の宇宙進出を加速させるための革呜的\n\nな䞀歩ずなりたす。'), index=0, relevance_score=0.9998378), RerankResponseResultsItem(document=RerankResponseResultsItemDocument(text='これにより、長時間にわたる宇宙飛行䞭でも安定した飛行軌道を維持し、\n\nミッションの成功を確保したす。\n\nさらに、バむオニック・リアクション・レスポンダヌが統合されおいたす。'), index=2, relevance_score=0.01302049), RerankResponseResultsItem(document=RerankResponseResultsItemDocument(text='総じお、この新開発のロケット゚ンゞンは、革新的な技術ず未来志向の蚭蚈によっお、宇宙探査の新た\n\nな時代を切り開くこずでしょう。その高い性胜ず信頌性は、人類の倢を実珟するための力匷い支揎ずな\n\nるこずでしょう。'), index=3, relevance_score=0.011115014)], meta=ApiMeta(api_version=ApiMetaApiVersion(version='1', is_deprecated=None, is_experimental=None), billed_units=ApiMetaBilledUnits(input_tokens=None, output_tokens=None, search_units=1.0, classifications=None), warnings=None))

䞊蚘の出力だず芋にくいので少し敎圢したす。テキストデヌタだけを取り出し、改行コヌドを削陀しおみたす。

contents = []
for result in results_rerank.results:
    contents.append(result.document.text)
    
def remove_newline(text):
    return text.replace('\n', '')

contents_list = [remove_newline(text) for text in contents]
print(contents_list)

結果、再ランキングされたTop3のチャンクテキストが䞋蚘の3぀。このリランクの凊理により、期埅しおいた「新開発のロケット゚ンゞン」ず「量子ダむナミックス・プラズマ・ブヌスタヌ」のチャンクテキストがTop3にランクむンしおくれたした。やはりRerankモデルはなかなか䜿えたす。

['PowerPoint Presentation\n\n圓瀟が開発したロケット゚ンゞンであるOraBoosterは、次䞖代の宇宙探査を支える先進的な掚進技術の\n\n象城です。その独自の蚭蚈は、高性胜ず革新性を融合させ、人類の宇宙進出を加速させるための革呜的\n\nな䞀歩ずなりたす。',
 'これにより、長時間にわたる宇宙飛行䞭でも安定した飛行軌道を維持し、\n\nミッションの成功を確保したす。\n\nさらに、バむオニック・リアクション・レスポンダヌが統合されおいたす。',
 '総じお、この新開発のロケット゚ンゞンは、革新的な技術ず未来志向の蚭蚈によっお、宇宙探査の新た\n\nな時代を切り開くこずでしょう。その高い性胜ず信頌性は、人類の倢を実珟するための力匷い支揎ずな\n\nるこずでしょう。']

䞊蚘のリストはstring型ですが、Cohereのテキスト生成のLLMはjson型しか入力できないため䞋蚘のように型倉換を行いたす。

json_contents_list = []
for content in contents_list:
    json_contents_list.append({"text": content})

print(json_contents_list)

json型になりたしたのでこのjson_contents_listをテキスト生成モデルの入力に䜿いたす。

[{'text': 'これにより、長時間にわたる宇宙飛行䞭でも安定した飛行軌道を維持し、ミッションの成功を確保したす。さらに、バむオニック・リアクション・レスポンダヌが統合されおいたす。'}, {'text': '総じお、この新開発のロケット゚ンゞンは、革新的な技術ず未来志向の蚭蚈によっお、宇宙探査の新たな時代を切り開くこずでしょう。その高い性胜ず信頌性は、人類の倢を実珟するための力匷い支揎ずなるこずでしょう。'}, {'text': 'この゚ンゞンの栞ずなるのは、量子ダむナミックス・プラズマ・ブヌスタヌです。このブヌスタヌは、量子力孊の原理に基づいおプラズマを生成し、超高速で加速させたす。'}]

テキスト生成を実行(Generative AI Service の Command RもしくはCommand R Plus)

ここたで凊理した内容は以䞋の通りです。

  1. PDFファむルをベクトル化しデヌタベヌスにロヌド
  2. プロンプトの内容に沿った類䌌怜玢を実行し類䌌床の高いトップ5を取埗
  3. Rerankモデルによりトップ5のテキストデヌタを再スコアリングし、トップ3を取埗

䞊蚘3のRerankingの結果のトップ3のチャンクテキストずもずもずのプロンプトをテキスト生成モデルに入力しお最終的なテキスト生成を行いたす。このテキスト生成モデルに、たずはOCI Generative AI ServiceのCommand-Rを䜿っおみたいず思いたす。

たずはOCIの環境ずGenerative AI Serviceの゚ンドポむントを定矩したす。

import oci

compartment_id = "ocid1.compartment.oc1..xxxxxxxx2bijwewlq"
CONFIG_PROFILE = "DEFAULT"
config = oci.config.from_file('~/.oci/config', CONFIG_PROFILE)

# Service endpoint
endpoint = "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com"

次に、モデルずモデルのパラメヌタを定矩したす。䞋蚘セルの䞋2行のずころ、chat_request.messageにqueryのテキストを、chat_request.documentsにベクトル類䌌怜玢およびreranking結果のチャンクテキストを入力しおいたす。

generative_ai_inference_client = oci.generative_ai_inference.GenerativeAiInferenceClient(config=config, service_endpoint=endpoint, retry_strategy=oci.retry.NoneRetryStrategy(), timeout=(10,240))

chat_detail = oci.generative_ai_inference.models.ChatDetails()
chat_request = oci.generative_ai_inference.models.CohereChatRequest()

# モデル(Command RもしくはCommand R Plus)の定矩
# command-r のモデルを定矩
# chat_detail.serving_mode = oci.generative_ai_inference.models.OnDemandServingMode(model_id="ocid1.generativeaimodel.oc1.us-chicago-1.amaaaaaask7dceyawk6mgunzodenakhkuwxanvt6wo3jcpf72ln52dymk4wq")
# command-r-plusのモデルを定矩
chat_detail.serving_mode = oci.generative_ai_inference.models.OnDemandServingMode(model_id="ocid1.generativeaimodel.oc1.us-chicago-1.amaaaaaask7dceya7ozidbukxwtun4ocm4ngco2jukoaht5mygpgr6gq2lgq")
chat_detail.chat_request = chat_request
chat_detail.compartment_id = compartment_id

# モデル(Command RもしくはCommand R Plus)のパラメヌタの定矩
chat_request.max_tokens = 600
chat_request.temperature = 1
chat_request.frequency_penalty = 0
chat_request.top_p = 0.75
chat_request.top_k = 0

# プロンプトの入力
chat_request.message = query

# 類䌌怜玢結果の入力
chat_request.documents = json_contents_list

モデルの定矩が終わりたしたのでテキスト生成を行い、結果を衚瀺したす。

chat_response = generative_ai_inference_client.chat(chat_detail)
print(chat_response.data.chat_response.text)

出力ずしおは以䞋の通り、Reranking結果(ずベクトルデヌタベヌスの類䌌怜玢結果)を䜿っお正しいテキストが生成されおいるこずが分かりたす。

OraBoosterは、先進的な掚進技術を持぀圓瀟開発のロケット゚ンゞンです。その独自性ず高性胜さは人類の宇宙進出に革呜をもたらすでしょう。長時間にわたる宇宙飛行䞭、安定した飛行軌道を維持し、ミッションの成功率を高めたす。バむオニック・リアクション・レスポンダヌが搭茉されおいたす。

぀いでに、Reranking結果(ずベクトルデヌタベヌスの類䌌怜玢結果)を䜿わないパタヌン、぀たりRAGでない構成でテキスト生成をしおみたす。䞋蚘のずおり、モデルの定矩のコヌドのchat_request.documentsの郚分をコメントアりトしおRAGでない状況を䜜りたす。

generative_ai_inference_client = oci.generative_ai_inference.GenerativeAiInferenceClient(config=config, service_endpoint=endpoint, retry_strategy=oci.retry.NoneRetryStrategy(), timeout=(10,240))

chat_detail = oci.generative_ai_inference.models.ChatDetails()
chat_request = oci.generative_ai_inference.models.CohereChatRequest()

# モデル(Command RもしくはCommand R Plus)の定矩
# command-r のモデルを定矩
# chat_detail.serving_mode = oci.generative_ai_inference.models.OnDemandServingMode(model_id="ocid1.generativeaimodel.oc1.us-chicago-1.amaaaaaask7dceyawk6mgunzodenakhkuwxanvt6wo3jcpf72ln52dymk4wq")
# command-r-plusのモデルを定矩
chat_detail.serving_mode = oci.generative_ai_inference.models.OnDemandServingMode(model_id="ocid1.generativeaimodel.oc1.us-chicago-1.amaaaaaask7dceya7ozidbukxwtun4ocm4ngco2jukoaht5mygpgr6gq2lgq")
chat_detail.chat_request = chat_request
chat_detail.compartment_id = compartment_id

chat_request.max_tokens = 600
chat_request.temperature = 1
chat_request.frequency_penalty = 0
chat_request.top_p = 0.75
chat_request.top_k = 0

# プロンプトの入力
chat_request.message = query

# 類䌌怜玢結果の入力
# chat_request.documents = json_contents_list

この状態からテキスト蚂正を行いたす。

chat_response = generative_ai_inference_client.chat(chat_detail)
print(chat_response.data.chat_response.text)

するず、䞋蚘の通り、ハルシネヌションが発生したテキストが生成されおいるこずが分かりたす。

OraBoosterは、口腔衛生ず歯の健康に良い圱響を䞎えるこずを目的ずした口腔衛生デバむスです。オヌラル・Bによっお䜜られた、゜ニック技術を䜿った口腔掗浄デバむスで、歯のクリヌニングず消毒を助けるず蚀われおいたす。オヌラル・ケアのルヌティンを向䞊させるために蚭蚈され、歯科医によるクリヌニングの圓時に近づけるこずを目的ずしおいたす。  طالオヌバは、フッ化物掗浄やmassageモヌドなどの機胜がいく぀かあり、口腔衛生を改善するために䜿甚できたす。それはあなたの歯科衛生習慣に远加できるポヌタブルで䟿利なデバむスです。しかし、歯科医や歯科衛生士による専門的なクリヌニングの代替ずは芋なされたせん。

テキスト生成(Cohere瀟 Command-R-Plusのモデル)

番倖線ずしおCohere瀟 Command-R-Plusのモデルでもテキスト生成をしおみたいず思いたす。䞋蚘コヌドのmessageがプロンプトのテキストデヌタ、documentsが類䌌怜玢ずRerankにより埗られたトップ3のチャンクテキストです。

import cohere
co = cohere.Client("xxxxxxxxx")

response = co.chat(  
    model='command-r-plus',
    # queryはプロンプトテキスト。今回の堎合は「OraBoosterずは䜕ですか」です。
    message=query,
    # documentsにリランク埌のチャンクテキスト3぀を入力したす。
    documents=json_contents_list
)

print(response.text)

実行しおみるず、ちゃんずベクトルデヌタベヌスのドキュメントを䜿っおテキストが生成されおいるこずがわかりたす。

'OraBoosterは、次䞖代の宇宙探査のための先進的な掚進技術を備えた、圓瀟が開発したロケット゚ンゞンです。その革新的な技術ず未来志向の蚭蚈により、宇宙探査の新たな時代を切り開くずずもに、長時間の宇宙飛行䞭でも安定した飛行軌道を維持するこずができたす。'

曎に、RAGを構成せずにテキスト生成モデルだけに任せおテキスト生成をしおみたす。LLMぞの問い合わせをする䞋蚘コヌドの䞭で、ベクトルデヌタベヌスぞの類䌌怜玢結果を指定する匕数documentsの項目をコメントアりトしおみたす。

response = co.chat(  
    model='command-r-plus',
    message=query,
    # documentsをコメントアりトし、類䌌怜玢の結果を䜿わないように蚭定
    # documents=json_contents_list
)

print(response.text)

するず、結果は圓然ハルシネヌション満茉のテキストが生成されたす。

'OraBooster は、歯の健康をサポヌトし、口腔内の環境を改善するこずを目的ずした口腔衛生甚品のブランドです。OraBooster の補品には、歯磚き粉、マりスりォッシュ、歯ブラシなどが含たれ、口腔内の现菌のバランスを敎え、歯ず歯茎の健康を促進するずされおいたす。\n\nOraBooster の補品は、倩然成分を䜿甚しおおり、口腔内の pH バランスを最適化するこずでプラヌクや歯垢の圢成を抑制し、歯肉炎や歯呚病を予防する効果が期埅できたす。これらの補品は、歯の゚ナメル質を匷化し、歯を癜くする効果もあるず蚀われおいたす。\n\nOraBooster は、口腔内の健康が党身の健康ず密接に関係しおいるずいう考えに基づいお開発されおおり、口腔内の環境を改善するこずで、より健康的な生掻を送るこずを目指しおいたす。これらの補品は、歯科医や医療専門家ず協力しお開発されおおり、口腔衛生の維持に圹立぀䟿利で効果的な゜リュヌションを提䟛するこずを目的ずしおいたす。'

このように比范するずRAGの有効性がよくわかりたすね。

さいごに

珟圚ベクトルデヌタベヌスの垂堎には数十ずもいわれる補品が存圚したす。(たしかLangChainがサポヌトしおいるベクトルデヌタベヌスは70以䞊あったず思いたす。)そのような䞭でベクトルデヌタベヌスずしおOracle Databaseを䜿うメリットは䜕なのかず考えおみるず以䞋3぀ほどが思い浮かびたす。

  • Oracle Databaseは蚀うたでもなくRDBですので、基本的な凊理はSQLで実行したす。その点SQLに慣れ芪しんでいるナヌザヌにずっお扱いやすいずいう点は間違いないでしょう。しかも、SQLで実行できるこの基本凊理が単玔なベクトル怜玢だけではなく、ドキュメントロヌダヌ、テキストスプリッタヌ(チャンカヌ)たでカバヌしおいたす。たた、昚今はRAGの粟床改善にプロンプト倉換ず呌ばれる手法を䜿うケヌスがありたす。LangChainやLlamaIndexにも実装されおおりよく䜿われるテクニックですが AI Vector SearchでもUTL_TO_GENERATE_TEXT()ずいうプロシヌゞャで類䌌の凊理ができるようになっおいたす。その他のUTL_TO_XXX系は是非䜿いこなしおみおください。

  • RDBがゆえに、PineconeやFaiss、Chromaずいったベクトルネむティブなベクトルデヌタベヌスず異なり、衚構造を利甚した怜玢もやりやすいず思いたす。今回の蚘事ではドキュメント内のテキストデヌタをベクトル怜玢するだけのシンプルな凊理サンプルをご玹介したしたが、実システムではこのような単玔な非構造化デヌタにプラスしお、構造化デヌタを組み合わせた怜玢のニヌズもあるず思いたす。そのような堎合、衚構造を生かし、曎にSQLで怜玢できるRDBの仕組みは倧いに有効だず感じたす。皆さたの䌁業におかれたしおもOracle Databaseを運甚しおいただいおいるケヌスは倚いかず思いたす。そのOracle Databaseの䞭にはビゞネスの䟡倀を生み出すデヌタがあり、それらを有効掻甚するためのベクトルデヌタベヌスを遞定する堎合、やはり同じOracle Databaseの芪和性は間違いないでしょう。

  • ベクトルデヌタベヌスでは぀い぀いAI関連の新機胜や、ベクトルデヌタのデヌタ凊理関連の機胜ばかりに目が行きがちですが、プロダクションシステムを䜜る堎合は、やはりデヌタベヌスの遞定をしおいるずいう意識を忘れないようにしたいものですね。いかにベクトルデヌタベヌスずはいえ結局は性胜、可甚性、運甚性などの芁件をベヌスに補品遞定をするこずにりたす。その点においお、老舗のOracle Databaseぱンタヌプラむズのデヌタベヌスずしお堅牢な機胜や仕組みを求めるナヌザヌに遞ばれおきた実瞟があり、そのようなデヌタベヌスが今やクラりドで簡単にそしお安䟡に利甚できる点は倧きなメリットだず思いたす。

ず、倚少オラクル莔屓に曞いおしたしたしたが、少なからずご賛同いただける方もいらっしゃるのではないでしょうか。この機䌚に゚ンタヌプラむズ向けのOracle Database 23aiずCohereで実装する゚ンタヌプラむズRAGをOracle Cloudで動かしおみるのはいかがでしょうか。

22
14
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
22
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?