ベクトル・データベースPineconeのサービスを提供しているPinecone Systems Inc.が、RAG(Retrieval Augmented Generation)の実装を容易にするCanopyというフレームワークをオープン・ソースで提供しています。
Introducing Canopy: An easy, free, and flexible RAG framework powered by Pinecone
https://www.pinecone.io/blog/canopy-rag-framework/
CanopyはPineconeのベクトル・データベースとOpenAIのサービスを呼び出します。そのため、Canopyの実行にはPineconeのAPIキーとOpenAIのAPIキーの両方が必要です。それぞれの準備方法については、PineconeまたはOpenAIのサイトを参照してください。Pineconeについてはインデックスが1つまでは無料で利用できます。そのため、Canopyを利用するにあたって必ずしも有料アカウントにアップグレードする必要はありません。OpenAIについては、ユーザー登録時に付与される無料クレジットを使い切っている場合は、有料アカウントへのアップグレードが必要です。
Canopyの2023年11月29日時点でのバージョン(v.0.2.0)では、RAGで使用するベクトル埋め込み(embedding)を生成するために、OpenAIのEmbeddings APIを呼び出しています。次元数が1536なので、モデルおそらくはtext-embedding-ada-002でしょう。また、回答を生成するためにOpenAIのCompletions APIを呼び出しています。
Canopy自体はOpenAIのCompletions APIと互換性のあるREST APIを提供しているため、OpenAIのCompletions APIを呼び出すクライアントであれば、Canopyへの問い合わせはエンドポイントを変更するだけで動作するはずです。
CanopyはOracle CloudのAlways Freeのコンピュート・インスタンスに実装します。Canopyを呼び出すアプリケーションは、これもAlways FreeのAutonomous DatabaseのAPEXで作成します。
Oracle CloudのAlways FreeのAutonomous Databaseから外部サービスを呼び出す場合は、HTTPS(SSL)かつDNSで名前解決ができるという制限があるため、作成したコンピュート・インスタンスに付与されているパブリックIPアドレスは、DNSにホスト名とともに設定しておく必要があります。
以下より、Canopyのインストールと構成およびAPEXのアプリケーション作成について紹介します。
Always Freeのコンピュート・インスタンスは、イメージはOracle Linux 9、ShapeはVM.Standard.E2.1 Microで作成しました。Canopy自体はPineconeやOpenAIのAPIを呼び出すだけで重い処理をするわけではないので、計算リソースはそれほど必要ないでしょう。
コンピュート・インスタンスが作成されたら、sshで接続してCanopyの実装を始めます。
Canopyのインストールに必要なPython 3.11とCanopyのSSL対応に使用するnginxをインストールします。作業はユーザーopcで行います。
sudo dnf -y install python3.11 python3.11-pip nginx
[opc@canopy-rag ~]$ sudo dnf -y install python3.11 python3.11-pip nginx
Ksplice for Oracle Linux 9 (x86_64) 385 kB/s | 158 kB 00:00
Oracle Linux 9 OCI Included Packages (x86_64) 24 MB/s | 59 MB 00:02
Oracle Linux 9 BaseOS Latest (x86_64) 14 MB/s | 17 MB 00:01
Oracle Linux 9 Application Stream Packages (x86_64) 19 MB/s | 26 MB 00:01
Oracle Linux 9 Addons (x86_64) 468 kB/s | 335 kB 00:00
Oracle Linux 9 UEK Release 7 (x86_64) 14 MB/s | 24 MB 00:01
Dependencies resolved.
========================================================================================
Package Arch Version Repository Size
========================================================================================
Installing:
nginx x86_64 1:1.20.1-14.0.1.el9_2.1 ol9_appstream 48 k
python3.11 x86_64 3.11.5-1.el9_3 ol9_appstream 30 k
python3.11-pip noarch 22.3.1-4.el9 ol9_appstream 4.3 M
Installing dependencies:
libnsl2 x86_64 2.0.0-1.el9 ol9_appstream 30 k
mpdecimal x86_64 2.5.1-3.el9 ol9_appstream 85 k
nginx-core x86_64 1:1.20.1-14.0.1.el9_2.1 ol9_appstream 587 k
nginx-filesystem noarch 1:1.20.1-14.0.1.el9_2.1 ol9_appstream 8.4 k
oracle-logos-httpd noarch 90.2-1.0.4.el9 ol9_baseos_latest 37 k
python3.11-libs x86_64 3.11.5-1.el9_3 ol9_appstream 12 M
python3.11-pip-wheel noarch 22.3.1-4.el9 ol9_appstream 1.4 M
python3.11-setuptools-wheel noarch 65.5.1-2.el9 ol9_appstream 712 k
Installing weak dependencies:
python3.11-setuptools noarch 65.5.1-2.el9 ol9_appstream 2.3 M
Transaction Summary
========================================================================================
Install 12 Packages
[中略]
Installed:
libnsl2-2.0.0-1.el9.x86_64
mpdecimal-2.5.1-3.el9.x86_64
nginx-1:1.20.1-14.0.1.el9_2.1.x86_64
nginx-core-1:1.20.1-14.0.1.el9_2.1.x86_64
nginx-filesystem-1:1.20.1-14.0.1.el9_2.1.noarch
oracle-logos-httpd-90.2-1.0.4.el9.noarch
python3.11-3.11.5-1.el9_3.x86_64
python3.11-libs-3.11.5-1.el9_3.x86_64
python3.11-pip-22.3.1-4.el9.noarch
python3.11-pip-wheel-22.3.1-4.el9.noarch
python3.11-setuptools-65.5.1-2.el9.noarch
python3.11-setuptools-wheel-65.5.1-2.el9.noarch
Complete!
[opc@canopy-rag ~]$
CanopyにAPEXから接続するにはHTTPS(SSL)が必須であるため、Nginxで一旦HTTPSの接続を受け付けて、HTTPに変換してCanopyにリクエストを転送するようにします。NginxをHTTPSで構成するために、Let's Encryptより証明書を取得します。
証明書の取得に使用する
certbotをインストールします。
sudo dnf --enablerepo=ol9_developer_EPEL -y install certbot[opc@canopy-rag ~]$ sudo dnf --enablerepo=ol9_developer_EPEL -y install certbot
Oracle Linux 9 EPEL Packages for Development (x86_64) 23 MB/s | 47 MB 00:02
Last metadata expiration check: 0:00:34 ago on Wed 29 Nov 2023 01:46:02 AM GMT.
Dependencies resolved.
========================================================================================
Package Arch Version Repository Size
========================================================================================
Installing:
certbot noarch 2.6.0-1.el9 ol9_developer_EPEL 25 k
Installing dependencies:
fontawesome-fonts noarch 1:4.7.0-13.el9 ol9_appstream 205 k
python3-acme noarch 2.6.0-1.el9 ol9_developer_EPEL 268 k
python3-certbot noarch 2.6.0-1.el9 ol9_developer_EPEL 1.0 M
python3-configargparse noarch 1.7-1.el9 ol9_developer_EPEL 56 k
python3-josepy noarch 1.13.0-1.el9 ol9_developer_EPEL 101 k
python3-parsedatetime noarch 2.6-5.el9 ol9_developer_EPEL 133 k
python3-pyrfc3339 noarch 1.1-11.el9 ol9_developer_EPEL 36 k
Transaction Summary
========================================================================================
Install 8 Packages
[中略]
Installed:
certbot-2.6.0-1.el9.noarch fontawesome-fonts-1:4.7.0-13.el9.noarch
python3-acme-2.6.0-1.el9.noarch python3-certbot-2.6.0-1.el9.noarch
python3-configargparse-1.7-1.el9.noarch python3-josepy-1.13.0-1.el9.noarch
python3-parsedatetime-2.6-5.el9.noarch python3-pyrfc3339-1.1-11.el9.noarch
Complete!
[opc@canopy-rag ~]$
サービスhttp、httpsおよびポート8000/tcpでの接続を許可するよう、firewalldを構成します。
sudo firewall-cmd --add-service=http
sudo firewall-cmd --add-service=https
sudo firewall-cmd --add-port=8000/tcp
sudo firewall-cmd --runtime-to-permanent
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
[opc@canopy-rag ~]$ sudo firewall-cmd --add-service=http
success
[opc@canopy-rag ~]$ sudo firewall-cmd --add-service=https
success
[opc@canopy-rag ~]$ sudo firewall-cmd --add-port=8000/tcp
success
[opc@canopy-rag ~]$ sudo firewall-cmd --runtime-to-permanent
success
[opc@canopy-rag ~]$ sudo firewall-cmd --reload
success
[opc@canopy-rag ~]$ sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens3
sources:
services: dhcpv6-client http https ssh
ports: 8000/tcp
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[opc@canopy-rag ~]$
SELinuxの設定で、Nginxによるリバース・プロキシを許可します。
sudo setsebool -P httpd_can_network_connect 1[opc@canopy-rag ~]$ sudo setsebool -P httpd_can_network_connect 1
[opc@canopy-rag ~]$
Canopyをインストールします。Canopyのインストール手順は、GitHubに記載されています。今回はVirutal Environmentの構成はスキップします。
pip3.11 install canopy-sdk[opc@canopy-rag ~]$ pip3.11 install canopy-sdk
Defaulting to user installation because normal site-packages is not writeable
Collecting canopy-sdk
Using cached canopy_sdk-0.2.0-py3-none-any.whl (72 kB)
Collecting fastapi<0.93.0,>=0.92.0
Using cached fastapi-0.92.0-py3-none-any.whl (56 kB)
Collecting gunicorn<22.0.0,>=21.2.0
Using cached gunicorn-21.2.0-py3-none-any.whl (80 kB)
Collecting jsonschema<5.0.0,>=4.2.0
Using cached jsonschema-4.20.0-py3-none-any.whl (84 kB)
Collecting openai<2.0.0,>=1.2.3
Using cached openai-1.3.6-py3-none-any.whl (220 kB)
Collecting pandas-stubs<3.0.0.0,>=2.0.3.230814
Using cached pandas_stubs-2.1.1.230928-py3-none-any.whl (153 kB)
Collecting pinecone-client<3.0.0,>=2.2.2
[中略]
Running setup.py install for wget ... done
Successfully installed aiobotocore-2.7.0 aiohttp-3.9.1 aioitertools-0.11.0 aiosignal-1.3.1 anyio-3.7.1 attrs-23.1.0 botocore-1.31.64 cachetools-5.3.2 canopy-sdk-0.2.0 certifi-2023.11.17 charset-normalizer-3.3.2 click-8.1.7 decorator-5.1.1 distro-1.8.0 dnspython-2.4.2 fastapi-0.92.0 frozenlist-1.4.0 fsspec-2023.10.0 gcsfs-2023.10.0 google-api-core-2.14.0 google-auth-2.23.4 google-auth-oauthlib-1.1.0 google-cloud-core-2.3.3 google-cloud-storage-2.13.0 google-crc32c-1.5.0 google-resumable-media-2.6.0 googleapis-common-protos-1.61.0 gunicorn-21.2.0 h11-0.14.0 httpcore-1.0.2 httpx-0.25.2 idna-3.6 jmespath-1.0.1 joblib-1.3.2 jsonschema-4.20.0 jsonschema-specifications-2023.11.1 loguru-0.7.2 mmh3-3.1.0 multidict-6.0.4 nltk-3.8.1 numpy-1.25.2 oauthlib-3.2.2 openai-1.3.6 packaging-23.2 pandas-2.1.3 pandas-stubs-2.0.3.230814 pinecone-client-2.2.4 pinecone-datasets-0.6.2 pinecone-text-0.7.0 prompt-toolkit-3.0.41 protobuf-4.25.1 pyarrow-11.0.0 pyasn1-0.5.1 pyasn1-modules-0.3.0 pydantic-1.10.13 python-dateutil-2.8.2 python-dotenv-1.0.0 pytz-2023.3.post1 pyyaml-6.0.1 referencing-0.31.0 regex-2023.10.3 requests-2.31.0 requests-oauthlib-1.3.1 rpds-py-0.13.1 rsa-4.9 s3fs-2023.10.0 six-1.16.0 sniffio-1.3.0 sse-starlette-1.8.2 starlette-0.25.0 tenacity-8.2.3 tiktoken-0.3.3 tqdm-4.66.1 types-jsonschema-4.20.0.0 types-pytz-2023.3.1.1 types-pyyaml-6.0.12.12 types-tqdm-4.66.0.5 typing-extensions-4.8.0 tzdata-2023.3 urllib3-2.0.7 uvicorn-0.20.0 wcwidth-0.2.12 wget-3.2 wrapt-1.16.0 yarl-1.9.3
[opc@canopy-rag ~]$
環境変数の設定を行います。
export PINECONE_API_KEY="<PINECONE_API_KEY>"
export PINECONE_ENVIRONMENT="<PINECONE_ENVIRONMENT>"
export OPENAI_API_KEY="<OPENAI_API_KEY>"
export INDEX_NAME="<INDEX_NAME>"
PineconeのAPIキーとEnvironmentの値は、API keysのページより取得します。
INDEX_NAMEは任意ですが、今回は
canopy-101としました。
こちらのCanopyの
セットアップ動画でインデックス名を
canopy-101としているのですが、実際にPineconeに作成されるインデックスの名前は
canopy--が接頭辞として付加されるため、
canopy--canopy-101になります。
以上の環境変数を設定した後に、Pineconeにインデックスを作成します。無料の範囲で利用する場合は、作成済みのインデックスがあれば削除しておく必要があります。
canopy new
[opc@canopy-rag ~]$ canopy new
Canopy is going to create a new index: canopy--canopy-101
Do you want to continue? [y/N]: y
Success!
[opc@canopy-rag ~]$
canopy newが成功するとPineconeのインデックスが作成されています。Pineconeのコンソールより、作成されたインデックスを確認できます。
Githubに記載されているCanopyのインストール手順では、この後より知識として扱われるドキュメントをPineconeのインデックスに登録する作業が続きます。
今回はAPEXのアプリケーションにRAGで使用するドキュメントの登録機能を実装します。そのため、Canopyのインストール作業は以上で完了です。
これより、HTTPSによる接続を受け付けるリバース・プロキシをNginxで構成します。DNSでパブリックIPアドレスの解決ができるようになっていることが前提です。
Oracle Cloudの仮想クラウド・ネットワークのパブリック・ネットワークのイングレス・ルールで、ポート80と443への接続が許可されていることを確認します。
Let's Encryptを使って証明書を発行します。
sudo certbot certonly --standalone
[opc@canopy-rag ~]$ sudo certbot certonly --standalone
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel): <申請者のメール・アドレス>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Account registered.
Please enter the domain name(s) you would like on your certificate (comma and/or
space separated) (Enter 'c' to cancel): <DNSに登録したホスト名>
Requesting a certificate for host-name
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/host-name/fullchain.pem
Key is saved at: /etc/letsencrypt/live/host-name/privkey.pem
This certificate expires on 2024-02-27.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[opc@canopy-rag ~]$
certbotの実行に成功するとディレクトリ
/etc/letsencrypt/live/ホスト名/以下に、秘密キーのファイルとして
privkey.pem、発行された証明書を保存するファイルとして
fullchain.pemが作成されます。
Nginxの構成ディレクトリである/etc/nginx/conf.d/に、server.confとして以下を記述したファイルを作成します。<ホスト名>の部分は実際のホスト名に置き換えます。
以上の設定を行い、nginxを起動します。
sudo systemctl start nginx
[opc@canopy-rag ~]$ sudo systemctl start nginx
[opc@canopy-rag ~]$
Canopyを起動します。Canopyを起動する前に、必ず環境変数を設定しておきます。(以下の例では環境変数の設定をmac.envというファイルに書き込んでいます。)
canopy start
[opc@canopy-rag ~]$ . mac.env
[opc@canopy-rag ~]$ canopy start
🚨 Note 🚨
For debugging only. To run the Canopy server in production run the command:
gunicorn canopy_server.app:app --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 --workers <num_workers>
Starting Canopy server on 0.0.0.0:8000
INFO: Started server process [3900]
INFO: Waiting for application startup.
2023-11-29 03:25:43,526 - MainProcess - canopy_server.app [INFO ]: Did not find config file. Initializing engines with default configuration
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
手元のブラウザより、https://ホスト名/docsにアクセスします。HTTPSのリクエストはNginxが受け付けますがCanopyに転送されているため、CanopyのAPI定義情報が表示されます。
この時点で、Canopyのサーバーが提供するREST APIを、Oracle APEXのアプリケーションから呼び出せる状態になりました。
このCanopyのサーバーに問合せを行う、Oracle APEXのアプリケーションを作成します。
最初に知識となる文章を保存する表CANOPY_DOCUMENTSを作成します。以下のDDLを実行します。
create table canopy_documents (
id number generated by default on null as identity
constraint canopy_documents_id_pk primary key,
source varchar2(80 char) not null,
text clob not null
);
SQLワークショップのSQLコマンドで実行します。
ドキュメントはPineconeのインデックスに登録され検索もPineconeで実施されるため、本来はAPEX側で表を作成してデータを保持する必要はありません。Oracle APEXでは、表があった方が速くアプリケーションを作成できるため、表を作成しています。
続いて以下のコードを実行し、パッケージ
UTL_CANOPY_APIを作成します。CanopyへのRAGを使った問い合わせ(Completions APIの呼び出し)、Pineconeのインデックスの検索(Query API)、RAGの知識となるドキュメントの登録と削除(Upsert/Delete API)を呼び出すプロシージャを作成しています。
アプリケーション作成ウィザードを開始します。アプリケーションの名前はCanopy Appとします。
ホーム・ページを削除し、先ほど作成した表CANOPY_DOCUMENTSのフォーム付き対話モード・レポートのページを追加します。
ページの追加をクリックし、対話モード・レポートを選択します。
ページ名はDocuments、表またはビューにCANOPY_DOCUMENTSを選択し、フォームを含めるをチェックします。
ページの追加をクリックします。
アプリケーションの作成をクリックします。
アプリケーションが作成されます。
最初にアプリケーション定義の置換に、置換文字列としてG_CANOPY_URL、置換値としてCanopyが動作しているサーバーのエンドポイントURLを設定します。URLの末尾は/v1とします。
https://Canopyが動作しているホスト名/v1
ページ番号
1の表
CANOPY_DOCUMENTSの
対話モード・レポートのページを開きます。
RAGのデータとして与えるドキュメントに含まれる改行が適切に表示されるように、列TEXTのタイプをリッチ・テキストに変更します。設定の書式はマークダウンです。
表CANOPY_DOCUMENTSへのドキュメントの挿入、更新、削除は、このままでも実行できます。表CANOPY_DOCUMENTSへのドキュメントの挿入、更新、削除を行うと同時に、同じドキュメントをCanopyに挿入、更新(Upsert APIなので挿入と更新は同じ処理になります)、削除を実行するプロセスを作成します。
ページ番号2のフォームのページを開きます。
プロセス・ビューから作成済みのプロセスプロセス・フォームCanopy Documentを重複させます。このプロセスは、表CANOPY_DOCUMENTSへの操作が実装されています。
新たに作成されたプロセスの識別の名前をManage Canopy Document、設定のターゲット・タイプをPL/SQLコードに変更し、挿入/更新/削除するPL/SQLコードとして以下を記述します。
declare
l_response clob;
begin
utl_canopy_api.manage_document(
p_row_status => :APEX$ROW_STATUS
,p_id => :P2_ID
,p_source => :P2_SOURCE
,p_text => :P2_TEXT
,p_canopy_url => :G_CANOPY_URL
,p_response => l_response
);
end;
失われた更新の防止はオフ、行のロックはいいえを指定します。
以上で、RAGで使用する知識となるドキュメントを登録できるようになりました。
アプリケーションを実行して、ドキュメントを登録してみます。
ナビゲーション・メニューよりDocumentsを開き、作成をクリックします。
Oracle APEX 23.2の新機能のページをコピペして登録してみました。
プロセスの実行が成功していれば、表CANOPY_DOCUMENTSへの書き込みと同時にPineconeのインデックスcanopy--canopy-101への書き込みが行われています。
Pineconeのコンソールよりインデックスcanopy--canopy-101を確認すると、登録したドキュメントは1つですが、チャンク分割が行われて34のベクトルが登録されていることが確認できます。
登録した知識を使った問い合わせを行うページを作成します。
ページの作成を実行します。
空白ページを選択します。
ページ番号は
3、
名前は
Completionsとします。それ以外はデフォルトのまま変更しません。
ページの作成をクリックします。
ページが作成されます。
問い合わせとなる文章を入力するページ・アイテムを作成します。
識別の名前はP3_USER_CONTENT、タイプはテキスト領域、ラベルはUser Contentとします。
送信ボタンを作成します。
識別のボタン名はSUBMIT、ラベルは送信とします。外観のホットをオンにし、テンプレート・オプションのWidthとしてStretchを選択します。
動作のアクションはデフォルトのページの送信です。
問い合わせ結果を表示するページ・アイテムを作成します。
識別の名前はP3_ASSISTANT_CONTENT、タイプはテキスト領域、ラベルはAssistant Contentとします。
送信ボタンを押した時に実行されるプロセスを作成します。左ペインでプロセス・ビューを開き、新規にプロセスを作成します。
作成したプロセスの識別の名前をCall Completionsとします。タイプにAPIの呼出しを選択し、設定のパッケージとしてUTL_CANOPY_API、プロシージャまたはファンクションとしてCOMPLETIONSを選択します。
サーバー側の条件のボタン押下時にSUBMITを指定します。
パラメータの
p_canopy_urlを選択し、
値の
アイテムとして置換文字列
G_CANOPY_URLを指定します。
パラメータ
p_responseを選択し、
パラメータの
出力を無視を
オンにします。
パラメータp_responseには、CanopyのCompletions APIを呼び出した際に受け取った、生のJSONの応答を戻します。デバッグなどのために画面に表示したい場合は、ページ・アイテムを新規に作成して出力先に設定すると良いでしょう。
以上で実装は完了です。ページの保存と実行を行います。
User Contentとして「Oracle APEXの新機能を教えてください。」と入力して、送信をクリックしてみました。
納得いかない回答が返されました。
Pineconeのインデックスの検索結果を確認するページを作成します。
このページもCompletionsと同じく空白のページを作成し、質問文を入力するページ・アイテム、送信ボタン、検索結果を返すページ・アイテムを作成します。送信ボタンのクリックでUTL_CANOPY_API.QUERYを呼び出すプロセスを作成します。
作成するページのページ番号は4、名前はQueryとします。
検索文を入力するページ・アイテムは
名前が
P4_QUERY_TEXT、
タイプは
テキスト領域、
ラベルは
Query Textとします。
送信ボタンは、Completionsのページの送信ボタンと同じです。
検索結果を返すページ・アイテムは、
名前が
P4_QUERY_RESULT、
タイプは
テキスト領域、
ラベルは
Query Resultとします。
Queryには追加でTop Kを指定するページ・アイテムを作成します。
識別の名前はP4_TOP_K、タイプとして数値フィールドを選択します。ラベルはTop Kとします。
検証の必須の値をオンにします。デフォルトのタイプに静的を選択し、静的値として3を設定します。
送信ボタンを押した時に実行されるプロセスを作成します。
作成したプロセスの識別の名前をCall Queryとします。タイプにAPIの呼出しを選択し、設定のパッケージとしてUTL_CANOPY_API、プロシージャまたはファンクションとしてQUERYを選択します。
サーバー側の条件のボタン押下時にSUBMITを指定します。
パラメータのp_canopy_urlとp_responseが赤く表示されます。Completionsのページと同じく、p_canopy_urlにはアイテムとしてG_CANOPY_URLを設定し、p_responseはパラメータの出力を無視します。
以上で実装は完了です。ページの保存と実行を行います。
Query Textとして「Oracle APEXの新機能を教えてください。」と入力して、送信をクリックしてみました。
パラメータのp_max_tokensとして十分に大きい値が設定されている必要があるようですが、Top Kで指定した数だけ、類似したベクトルが返されました。
大きなドキュメントを登録してCanopyにチャンク分割を任せたのが、納得いかない回答が生成される理由ではないかと推測しています。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/canopy-app.zip
Oracle Linux 9上に実装したnginxおよびCanopyの双方ともに、自動起動は実装していないため、作業をする際にはサーバーを毎回起動する必要があります。
以上になります。
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完