2023年6月26日月曜日

CohereのCo.EmbedをOracle APEXから呼び出してみる

 CohereのAPIのCo.Classify、Co.Generateを呼び出すAPEXアプリケーションに、Co.Embedを呼び出すページを追加しました。Co.EmbedのAPIリファレンスはこちらになります。

作成したページで、ExamplesのRestaurant Customer Inquiries(の一部)を呼び出してみます。

以下、作り方になります。

Co.Embedを呼び出すページを作成します。

ページの作成を実行します。


空白ページを選択します。


ページ番号名前Embedとします。

ページの作成をクリックします。

Co.Embedはテキストの配列を入力としているため、対話グリッドを使ってテキストの配列を作成します。テキストの配列はAPEXコレクションEMBED_TEXTSに保持します。

レンダリング前ヘッダーの前にプロセスを作成し、APEXコレクションEMBED_TEXTSを初期化します。

識別名前APEXコレクションの初期化とします。タイプコードを実行ソースPL/SQLコードとして以下を記述します。

begin
apex_collection.create_or_truncate_collection('EMBED_TEXTS');
end;

対話グリッドを作成します。

識別名前Textsタイプとして対話グリッドを選択します。ソースタイプとしてSQL問合せSQL問合せとして以下を記述します。

select seq_id, c001 from apex_collections where collection_name = 'EMBED_TEXTS'


APEXコレクションでは列SEQ_IDが一意列です。そのため、対話グリッドが列SEQ_IDを主キーとして扱うように設定します。

SEQ_IDを選択し、識別タイプ非表示に変更します。ソース主キーオンにします。


C001を選択し、識別タイプテキスト・フィールドに変更します。ヘッダーtextにします。


対話グリッドTexts属性を開き、編集有効オンに変更します。


プロセス・ビューを開き、プロセスTexts - 対話グリッド・データの保存を選択します。

設定ターゲット・タイプPL/SQL Codeに変更し、挿入/更新/削除するPL/SQLコードに以下を記述します。

declare
C_COLLECTION_NAME constant varchar2(20) := 'EMBED_TEXTS';
begin
case :APEX$ROW_STATUS
when 'C' then
:SEQ_ID := apex_collection.add_member(
p_collection_name => C_COLLECTION_NAME
,p_c001 => :C001
);
when 'U' then
apex_collection.update_member(
p_collection_name => C_COLLECTION_NAME
,p_c001 => :C001
,p_seq => :SEQ_ID
);
when 'D' then
apex_collection.delete_member(
p_collection_name => C_COLLECTION_NAME
,p_seq => :SEQ_ID
);
end case;
end;
view raw embed-texts.sql hosted with ❤ by GitHub
失われた更新の防止オフ行のロックNoにします。


対話グリッドの設定は以上で完了です。

Co.EmbedのAPIの入力のひとつであるmodelを指定するページ・アイテムを作成します。

識別名前P4_MODELタイプテキスト・フィールドラベルModelとします。

デフォルトタイプ静的を選択し、静的値としてembed-multilingual-v2.0を設定します。


APIのもうひとつの入力truncateを指定するページ・アイテムを作成します。

識別名前P4_TRUNCATEタイプテキスト・フィールドラベルTruncateとします。レイアウト新規行の開始オフにし、P4_MODELの右に配置します。

デフォルトタイプ静的を選択し、静的値としてNONEを設定します。


CohereのCo.Embedを呼び出すボタンを作成します。

識別ボタン名SUBMITラベルSubmitとします。動作アクションとして動的アクションで定義を選択します。

動的アクションは、Co.Embedを呼び出すリージョンを作成した後に定義します。


Co.Embedを呼び出し、受け取ったレスポンスを表示するリージョンを作成します。

識別タイトルResponseタイプとして動的コンテンツを選択します。ソースCLOBを返すPL/SQLファンクション本体として、以下を記述します。

declare
l_request clob;
l_response clob;
l_count number;
begin
select count(*) into l_count from apex_collections where collection_name = 'EMBED_TEXTS';
if l_count = 0 then
l_response := 'no input exists.';
return l_response;
end if;
-- Co.Embedへのリクエストを生成する。
select json_object(
key 'texts' value
(
select json_arrayagg(c001 order by seq_id) from apex_collections
where collection_name = 'EMBED_TEXTS'
)
-- モデルを指定する。
,key 'model' value :P4_MODEL
-- トランケートを指定する。
,key 'truncate' value :P4_TRUNCATE
returning clob)
into l_request
from dual;
-- Cohere Co.Embedを呼び出す。
-- https://docs.cohere.com/reference/embed
apex_debug.info(l_request);
apex_web_service.clear_request_headers;
apex_web_service.set_request_headers('Accept','application/json', p_reset => false);
apex_web_service.set_request_headers('Content-Type','application/json', p_reset => false);
l_response := apex_web_service.make_rest_request(
p_url => 'https://api.cohere.ai/v1/embed'
,p_http_method => 'POST'
,p_body => l_request
,p_credential_static_id => 'COHERE_API'
);
return l_response;
end;
送信するページ・アイテムとしてP4_MODEL,P4_TRUNCATEを指定します。


ボタンSUBMITの動的アクションを作成します。

識別名前onClick Refreshとします。タイミングイベントは、ボタンのデフォルトであるクリックです。


TRUEアクションリフレッシュ影響を受ける要素選択タイプリージョンリージョンとしてResponseを選択します。


以上でCo.Embedを呼び出すページは完成です。

作成したアプリケーションを実行すると、本記事の先頭のGIF動画のように動作します。

作成したアプリケーションのエクスポートとして、以前のエクスポートを更新しています。
https://github.com/ujnak/apexapps/blob/master/exports/sample-cohere-api.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。

オラクル・データベースでpgvectorが提供するような、embeddingを保存してvector similarity searchを実行する方法を見つけることはできませんでした。