ラベル United Codes の投稿を表示しています。 すべての投稿を表示
ラベル United Codes の投稿を表示しています。 すべての投稿を表示

2026年4月20日月曜日

United Codes社が提供するパッケージUC_AIのサンプルアプリを動かしてみる

United Codes社は、Oracle DatabaseおよびOracle APEXを中心としたアプリケーション開発・ツール提供を行う、ベルギーを拠点としたエンジニアリング企業です。日本では似たようなポジションの企業はあまりないように感じますが、海外ではUnited Codes社の他に、ドイツのHyland(旧MT GmbH)社、 北米が拠点のTALAN(旧Insum)およびViscocity North Americaなどがあります。

そのUnited Codes社より、OpenAIやAnthropicのAPIを呼び出すPL/SQLパッケージとしてUC_AIが公開されています。ライセンスはLGPL-3.0です。

製品の説明:https://www.united-codes.com/products/uc-ai/docs/

United Codes社ではOracle DatabaseやAPEXを扱う開発者向けに「AI WORKSHOP FOR DATABASE & APEX DEVELOPERS」という、2日間のオンライン・ワークショップを開催しています。言語は英語で有償なので日本からの参加は難しいかもしれませんが、パッケージUC_AIの利用を検討する場合はワークショップを受講するのが近道でしょう。

ワークショップの受講が不要になるような記事は書けませんが、パッケージUC_AIに含まれるサンプルアプリPractical AI Made Easyが、使いたいモデルやプロバイダ(特にOllamaやLM StudioといったローカルLLM)によっては動かないので、サンプルアプリの動かし方を記事にします。

以下より、UC_AIに含まれるサンプルアプリPractical AI Made Easyを動かす手順を紹介します。APEXの実行環境には、同じくUnited Codes社より公開されているUC Local APEX Devを使用します。

APEXのワークスペースとしてAPEXDEV、スキーマとしてAPEXDEVが作成済みとします。また、SQLclの接続としてスキーマAPEXDEVに接続するlocal-26ai-apexdevが作成済みとします。

最初にUC_AIをスキーマAPEXDEVにインストールします。Loggerも一緒にインストールすることにします。

リポジトリUC_AIをクローンし、移動します。安定版のmainブランチを取得します。

git clone -b main https://github.com/United-Codes/uc_ai.git
cd uc_ai

% git clone -b main https://github.com/United-Codes/uc_ai.git

Cloning into 'uc_ai'...

remote: Enumerating objects: 2923, done.

remote: Counting objects: 100% (641/641), done.

remote: Compressing objects: 100% (437/437), done.

remote: Total 2923 (delta 329), reused 339 (delta 185), pack-reused 2282 (from 1)

Receiving objects: 100% (2923/2923), 6.37 MiB | 6.98 MiB/s, done.

Resolving deltas: 100% (1922/1922), done.

% cd uc_ai 

uc_ai % 


Loggerを個別のスキーマにインストールする場合、対象のスキーマにはCREATE ANY CONTEXT権限が必要です。データベースにSYSで接続し、権限を与えます。

sql -name local-26ai-sys
grant create any context to apexdev;

uc_ai % sql -name local-26ai-sys


SQLcl: 月 4月 20 14:21:44 2026のリリース25.4 Production


Copyright (c) 1982, 2026, Oracle.  All rights reserved.


接続先:

Oracle AI Database 26ai Free Release 23.26.1.0.0 - Develop, Learn, and Run for Free

Version 23.26.1.0.0


SQL> grant create any context to apexdev;


Grantが正常に実行されました。


SQL> exit

Oracle AI Database 26ai Free Release 23.26.1.0.0 - Develop, Learn, and Run for Free

Version 23.26.1.0.0から切断されました

uc_ai % 


続いてスキーマAPEXDEVに接続し、パッケージUC_AIと関連オブジェクトをインストールします。

sql -name local-26ai-apexdev
@install_with_logger

uc_ai % sql -name local-26ai-apexdev


SQLcl: 月 4月 20 16:48:18 2026のリリース25.4 Production


Copyright (c) 1982, 2026, Oracle.  All rights reserved.


接続先:

Oracle AI Database 26ai Free Release 23.26.1.0.0 - Develop, Learn, and Run for Free

Version 23.26.1.0.0


SQL> @install_with_logger

Installing UC AI with logger

_____________________________________________________________________________

User has all required privileges, installation will continue.

_____________________________________________________________________________



PL/SQLプロシージャが正常に完了しました。


tables/logger_logs.sql


PL/SQLプロシージャが正常に完了しました。



PL/SQLプロシージャが正常に完了しました。


tables/logger_prefs.sql


PL/SQLプロシージャが正常に完了しました。



Trigger BIU_LOGGER_PREFSがコンパイルされました


[中略]


Package Body UC_AI_RESPONSES_APIがコンパイルされました


- Installing core UC AI package body...


Package Body UC_AIがコンパイルされました


Running post-installation scripts...

Logger package detected. Setting USE_LOGGER flag to TRUE.

Successfully compiled uc_ai_logger package with USE_LOGGER flag.



PL/SQLプロシージャが正常に完了しました。


===================================================

UC AI installation complete!

Refer to the documentation for usage instructions: https://www.united-codes.com/products/uc-ai/docs/

===================================================

Installation Complete!

SQL> exit

Oracle AI Database 26ai Free Release 23.26.1.0.0 - Develop, Learn, and Run for Free

Version 23.26.1.0.0から切断されました

uc_ai % 


サンプルとなるAPEXアプリPractical AI Made Easyをインストールします。

アプリケーション・ビルダーを開き、インポートを実行します。


インポートするファイルとして、uc_ai/examples/sample-apps/practical-ai-made-easy以下のf135.sqlを選択します。同じディレクトリにpame_pkg.pks、pame_pkg.pkbやtables.sqlといったスクリプトがありますが、これらはAPEXアプリにサポートするオブジェクトとして含まれているため、個別に実行する必要はありません。

f135.sqlを選択し、次へ進みます。


アプリケーションのインストールを実行します。


サポートするオブジェクトのインストールを実行します。


APEXアプリケーションと、その実行に必要なデータベース・オブジェクトがインストールされました。

アプリケーションを実行します。


APEXのワークスペース・ユーザーでサインインします。


パッケージUC_AIのAPIの呼び出し例として、Generate TextStructured OutputAnalyze filesReasoningToolsの5種類のサンプルが含まれています。それらの呼び出しに使用するモデルは、画面右上のボタンをクリックして選択します。


LLMのプロバイダとしてOpenAIAnthropicGoogleOllamaOCIが選択できます。プロバイダごとにAPIの呼び出し形式は異なりますが、UC_AIのAPIでは、これらの違いを吸収して、同じAPIで異なるプロバイダを呼び出せるようになっています。


しかしサンプルアプリでは、選択できるモデルに制限があります。OpenAIを例にとると、gpt-4o、gpt-5、o4-miniです。


今回はローカルLLMを呼び出せるようにします。

OllamaでGoogleのGemma4、LM Studioでgpt-oss-120bを実行します。Ollamaではモデル名はgemma4:31b、LM Studioではmlx-community/gpt-oss-120bです。私のMacはメモリに余裕があるため大きいモデルを使用していますが、ホストしているPCに合わせてモデルを選んでください。

選択可能なモデルを追加します。これは共有コンポーネントLOVとして設定されています。

共有コンポーネントLOVから、MODELSを編集します。


SQL問合せを更新します。

プロバイダがollamaのモデルとしてgemma4:31bを追加します。LM StudioのモデルはOpenAI互換のChat Completions APIから呼び出すため、プロバイダopenaiのモデルとしてmlx-community/gpt-oss-120bを追加します。
select model as r, model as d, provider
from (
    select 'gpt-4o' as model, 'openai' as provider
    union all
    select 'gpt-5' as model, 'openai' as provider
    union all
    select 'o4-mini' as model, 'openai' as provider
    --
    union all
    select 'google/gemmna-4-31b' as model, 'openai' as provider
    union all
    select 'mlx-community/gpt-oss-120b' as model, 'openai' as provider

    union all

    select 'claude-3-5-haiku-latest' as model, 'anthropic' as provider
    union all
    select 'claude-sonnet-4-0' as model, 'anthropic' as provider
    union all
    select 'claude-opus-4-1' as model, 'anthropic' as provider

    union all

    select 'gemini-2.5-pro' as model, 'google' as provider
    union all
    select 'gemini-2.5-flash' as model, 'google' as provider
    union all
    select 'gemini-2.5-flash-lite-preview-06-17' as model, 'google' as provider

    union all

    select 'qwen3:1.7b' as model, 'ollama' as provider
    union all
    select 'gemma3:4b' as model, 'ollama' as provider
    union all
    select 'gpt-oss:20b' as model, 'ollama' as provider
    -- 
    union all
    select 'gemma4:31b' as model, 'ollama' as provider

    union all

    select 'cohere.command-a-03-2025' as model, 'oci' as provider
    union all
    select 'meta.llama-3.3-70b-instruct' as model, 'oci' as provider
)
where provider = :P0_PROVIDER

以上で、選択できるモデルが追加できました。

プロバイダとしてOllama、モデルとしてgemma4:31bを選択します。


モデルを選択した上でSystem PromptUser Promptを入力し、Generateボタンをクリックすると以下のエラーが発生します。

「Ajax call returned server error ORA-29273: HTTP request failed for Execute Server-Side Code.」


OllamaやLM StudioはローカルLLMなのでAPIキーは不要ですが、呼び出し先となるエンドポイントURLはそれぞれ設定が必要です。デフォルトはlocalhostですが、APEX(を実行しているデータベース)がコンテナで実行されているため、呼び出し先はコンテナ外となるhost.docker.internal(またはhost.containers.internal)になります。また、OpenAIやAnthropicなどの、エンドポイントが固定で呼び出し先のURLを変更する必要がない場合でも、APIキーは設定する必要があります。

APIキーの設定方法はいくつかありますが、今回はAPEXのWeb資格証明を使用します。

ワークスペース・ユーティリティWeb資格証明を開きます。


OpenAIのAPIキーを新規に登録します。作成をクリックします。


Web資格証明の名前OpenAI API Key静的IDOPENAI_API_KEYとします。静的IDは、UC_AIへWeb資格証明を設定する際に使用します。

認証タイプHTTPヘッダーを選択し、資格証明名にHTTPヘッダー名であるAuthorization資格証明シークレットとしてBearerで始めて、空白で区切り、OpenAIのAPIキーを繋げた文字列を設定します。

APIキーの送信先がOpenAIに限定されるように、URLに対して有効https://api.openai.com/を設定します。

以上でWeb資格証明を作成します。


Generate Textのページに戻り、ボタンGenerateをクリックしたときに実行されるコードを更新します。

プロバイダがollamaのときは、ベースURLをhost.docker.internal:11434/apiとします。プロバイダがopenaiでモデルがmlx-community/gpt-oss-120bのときは、LM Studioの呼び出しなので、ベースURLをhttp://host.docker.internal:1234/v1にします。それ以外のopenaiのときは、Web資格証明としてOPENAI_API_KEYを設定します。

UC_AIでプロバイダがOpenAIの場合、デフォルトでResponses APIが使用されるようです。LM StudioについてはChat Completions APIを使用させるため、uc_ai_openai.g_use_responses_apifalseを設定します。
declare
  l_result json_object_t;
begin
  pame_pkg.reset_global_variables;
  --
  if :P0_PROVIDER = 'ollama' then
    uc_ai.g_base_url := 'host.docker.internal:11434/api';
  elsif :P0_PROVIDER = 'openai' and :P0_MODEL in ('google/gemma-4-31b','mlx-community/gpt-oss-120b') then
    uc_ai.g_base_url := 'http://host.docker.internal:1234/v1';
    uc_ai_openai.g_use_responses_api := false;
  elsif :P0_PROVIDER = 'openai' then
    uc_ai_openai.g_apex_web_credential := 'OPENAI_API_KEY';
  end if;

  l_result := uc_ai.generate_text(
    p_user_prompt => :P1_USER_PROMPT,
    p_system_prompt => :P1_SYSTEM_PROMPT,
    p_provider => :P0_PROVIDER,
    p_model => :P0_MODEL
  );

  :P1_OUTPUT := l_result.get_clob('final_message');
  :P1_FULL_RESPONSE := l_result.to_clob;
end;
ファンクションuc_ai.generate_textがLLMを呼び出すファンクションです。


プロバイダをOllama、モデルとしてgemma4:31bを選択して、Generateを実行します。Outputが返されることが確認できます。


LM Studioで動作しているmlx-community/gpt-oss-120bや、OpenAIが提供しているモデルgpt-4oやgpt-5をモデルとして選択しても、Outputが得られます。

Structured Outputについても、ボタンGenerateで呼ばれるコードに以下を組み込み、環境に合わせたモデルの呼び出しが行われるようにします。Structured Outputに対応するように、ファンクションuc_ai.generate_textの呼び出し時に引数p_response_json_schemaが追加されています。
  --
  if :P0_PROVIDER = 'ollama' then
    uc_ai.g_base_url := 'host.docker.internal:11434/api';
  elsif :P0_PROVIDER = 'openai' and :P0_MODEL in ('google/gemma-4-31b','mlx-community/gpt-oss-120b') then
    uc_ai.g_base_url := 'http://host.docker.internal:1234/v1';
    uc_ai_openai.g_use_responses_api := false;
  elsif :P0_PROVIDER = 'openai' then
    uc_ai_openai.g_apex_web_credential := 'OPENAI_API_KEY';
  end if;

User Promptに「日本の首都はどこですか?responseには首都の名前を返してください。」と入力し、Structured OutputのJSONスキーマとしてConfidenceを選択します。

モデルとしてgpt-oss-120bを選択しました。Outputは以下です。

{ "response": "東京", "confidence": 0.99 }

モデルによっては構造化出力を返さないものもあります。


Analyze filesについても今までと同様に、ボタンGenerateで呼び出されるコードを変更します。

Analyze filesではファイルを処理できますが、表PAME_FILESに登録済みのファイルに限定されています。


自分で選んだファイルを処理するために、表PAME_FILESにファイルを登録するアプリを作成しました。

https://github.com/ujnak/apexapps/blob/master/exports/manage_pame_files.sql

このAPEXアプリをダウンロードし、ワークスペースにインポートします。

インポートしたアプリケーションを実行すると、以下のような画面が開きます。表PAME_FILESを対象に、ローカルPCにあるファイルをアップロードするだけの簡単なアプリケーションです。


使用したいファイルを登録して、UC_AIのサンプルアプリに戻ります。

新たに登録したファイルを選択して、ボタンGenerateをクリックします。画像やPDFといったファイルを処理したOutputを確認できます。画像を処理したり、さらに構造化出力を返すには、それらに対応したモデルを選択する必要があります。


Reasoningについても同様に、ボタンGenerateで呼び出されるコードを変更します。

Enable Reasoningオンにして、ボタンGenerateをクリックします。Reasoningが行われるかどうかも、選択したモデルに依存します。


Toolsについても同様に、ボタンGenerateで呼び出されるコードを変更します。

呼び出されるツールを登録するのは大変なので、サンプルに含まれているツールPAME_GET_USER_INFOを呼び出してみます。

System Promptは「あなたは保険の外交員です。」とします。User Promptは「alice.smith@example.comの情報を教えて。」とします。

以上でボタンGenerateをクリックすると、表PAME_USERSから取得した情報がOutputに表示されます。


UC_AIに含まれるサンプルアプリPractical AI Made Easyの紹介は以上です。

サンプルアプリPractical AI Made Easyを削除しても、関連オブジェクトはそのまま残ります。完全に削除するには以下のスクリプトを実行します。
drop table pame_settlement_demo;
drop table pame_files;
drop table pame_users;
delete from uc_ai_tools where code in ('PAME_CREATE_SETTLEMENT', 'PAME_GET_USER_INFO');
Oracle APEXのアプリケーション開発の参考になれば幸いです。

2023年10月23日月曜日

United Codesが提供しているプラグインEnhanced Grid Proを日本語化する

 ベルギーのUnited Codesが提供しているOracle APEXの有償プラグインEnhanced Grid Proを日本語化する手順を紹介します。Enhanced Grid ProはUnited Codesが開発しているOracle APEXのプラグインPlug-ins Proに含まれています。

日本語化した結果は、Enhanced Grid Proのサンプル・アプリケーションのBasic Exampleのページで確認します。


Enhanced Grid Proは共有コンポーネントプラグインUnited Codes - Enhanced Grid Proとしてインストールされています。


プラグインを開き、United Codesが開発したJavaScriptのファイルを確認します。ucGrid.min.jsを開きます。


JavaScriptのファイルを確認すると、メッセージはUC_GRID.TOOLTIP_NOT_POSSIBLEといった形で、Oracle APEXのテキスト・メッセージで定義されていることが確認できます。


以下のスクリプトを実行し、APEXアプリケーションのグローバリゼーションテキスト・メッセージを作成します。先頭のC_APP_IDは、テキスト・メッセージを作成するアプリケーションのアプリケーションIDに変更します。



グローバリゼーションテキスト・メッセージを開き、日本語のテキスト・メッセージが作成されていることを確認します。


アプリケーション定義のプライマリ言語日本語(ja)に変更します。


これまでの作業でボタンやコンテキスト・メニューが日本語化されています。


コンテキスト・メニューの一部およびフィルタの文字列については、Enhanced Grid Proが採用しているWebコンポーネントHandsontableを日本語化する必要があります。

Handsontableのローカライズの方法について、以下を参考にしました。


Enhanced Grid Proの日本語化では、この中の3. Universal Module Definition (UMD)の手法が使えそうです。

DemoEditを開いて、手法について確認します。jsFiddleが起動します。


HTMLの記述はそのままでも良いのですが、日本語に限定するため、all.jsをja-JP.jsに変更します。

JavaScriptについては、言語に関する記述(deDEが現れる行)をコメントアウトします。それに加えて、Handsontableを生成する(new)するときのlanguageの指定をde-DEからja-JPに変更します。

上記の変更を行ったあと、左上でのRunをクリックします。

コンテキスト・メニューが日本語で表示されることが確認できます。


以上の操作で確認できた実装を、United CodesのEnhanced Grid Proに適用します。

プラグインに含まれていてるHandsontableが実装されているファイルhandsontable_12_3_0.full.min.jsより、バージョンが12.3.0であることが分かります。


HandsontableのソースコードはGitHub上でホストされています。GitHubからHandsontable 12.3.0の各国語対応を含んだ完全なコードをダウンロードします。


12.3.0AssetsからSource codeをダウンロードします。


ダウンロードされたファイルhandsontable-12.3.0.zipを展開します。この中にja_JP.jsというファイルが含まれます。

handsontable/dist/languages/ja-JP.js

プラグインUnited Codes - Enhanced Grid Proファイルファイルの作成をクリックし、このファイルja_JP.jsをプラグインを構成するファイルとして追加します。


ファイルをドラッグ・アンド・ドロップをクリックして、ja-JP.jsを選択します。

作成をクリックします。


ファイルのアップロードが行われ、ja-JP.jsがスクリプト・エディタで開かれます。スクリプト自体の変更は行わず、変更の保存をクリックします。ja-JP.jsがミニファイされ、ja-JP.min.jsが作成されます。

ファイルが保存され、縮小されました、というメッセージを確認し、ブレッドクラムのUnited Codes - Enhanced Grid Proをクリックして、プラグインの設定画面に戻ります。


ファイルja-JP.min.jsが作成されていることを確認し、ロードするファイルURLのセクションに移ります。


ロードするファイルURLのJavaScriptに、以下のファイルを追加します。handsontable_12_3_0.full.min.jsより後に配置します。

#PLUGIN_FILES#ja-JP.min.js


Enhanced Grid Proをタイプとして選択しているリージョンの属性初期化JavaScriptファンクションに以下のコードを記述し、languageja-JPに指定します。
function (pOptions) {
    pOptions.language = 'ja-JP';
    return pOptions;
}


本来であれば、これでHandsontableのlanguageがja-JPとなり、jsFiddleで確認したようにコンテキスト・メニューが日本語化されるはずですが、現行のバージョンではそうなりません。

ワークアラウンドとして、ucGrid.min.jsに含まれるlanguage指定を直接更新します。

プラグインのファイルに含まれるucGrid.min.jsを開きます。


以下のように続くコードを見つけます。

this.hot=new Handsontable(document.getElementById(this.regionID),{language:"en-US",licenseKey:

"en-US"の部分を、初期化JavaScriptファンクションで設定するlanguageを参照するように変更します。

this.hot=new Handsontable(document.getElementById(this.regionID),{language:o.options.language,licenseKey:


以上の変更により、Handsontableが提供するフィルタが日本語で表示されます。


まだ、コンテキスト・メニューの一部が日本語化されていません。


Handsontableのローカライズは、本体の機能追加の後に、各国の有志によってローカライズのためのリソースが提供されているようです。Copy with headersの機能の日本語訳は12.3.1で追加されています。


12.3.1のSource codeをダウンロードし、Enhanced Grid Proに追加したja-JP.jsを12.3.1のものに入れ替えます。

アップロード済みのja-JP.jsを一旦削除し、12.3.1のja-JP.jsをアップロードします。


以上で、コンテキスト・メニューのCopy with headersなども日本語表記になります。


以上が、United Codesが提供しているEnhanced Grid Proの日本語手順の紹介になります。