Asset List
Filters
動画をフレームに分割してLLMで解析する with Claude3 Opus
動画をLLMへ入力し、プロンプトで指示した条件に応じてコールバック関数を実行できるアプリのデモです。 紹介動画 概要 想定ユーザー 動画をLLMで解析するアプリケーションをStudioで実現したい利用者 テンプレート動作 Input 解析したい動画ファイル .mp4形式 サンプルファイルはWebアプリからダウンロード可能 環境変数 環境変数 内容 備考 AWS_ACCESS_KEY_ID Bedrock Claude3 Opusのアクセスキー AWS_SECRET_ACCESS_KEY Bedrock Claude3 Opusが利用可能のシークレットキー Output LLMにより解析された動画 利用方法 単体での動作確認 デプロイ方法 下記のシークレットをCanvasに設定する。 AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY デプロイボタンを押す。 実行方法 Webアプリにアクセスする。 WebアプリURLは下記 https://studio.internal.studio.exabase.ai/92b41f91d8085d62/ws/ui/ 動画のフレーム化 画面左のDownload the hand example videoをクリックし、サンプル動画ファイルを取得する。 StreamlitのUI上からサンプル動画をアップロードし、Subsample amountを任意の値に設定し、Parase framesをクリックする。 Subsample amountは、LLMによる処理をいくつのフレームごとに行うかを表しています。値が小さいほど小刻みに解析を行うことができますが、API利用コストは高くなります。サンプル動画を用いる場合、3〜5で程よく解析が行われます。 LLMへ入力する準備 (オプション)変換したフレーム群のクロッピングを行う。 LLMへ処理させたい部分にだけ各フレームを切り取ることができます。 (オプション)コールバック関数を指定する。 本アプリではTrigger(boolean)とCounter(integer)の指定ができます。 Trigger: プロンプトで指示した条件を満たしたときにtrue/falseを出力させる Counter: 上げられている指の本数や車の数をカウントする 各フレーム画像の処理について、LLMに指示を出すプロンプトの編集を行う。 デフォルトで入力されているプロンプトをそのまま使用することも可能です。 処理の開始と結果の確認 準備ができたらProcessを クリックして処理を開始する。 各フレーム画像は並列処理されます。 処理が終わると、LLMからの回答とコールバック関数の出力がJSON形式で一覧表示される。 字幕付き動画の生成 (オプション) Generate outputをクリックすると動画が生成される。 LLMからの回答とコールバック関数の実行結果が表示された字幕付き動画を再生できます。動画プレイヤーの︙から字幕の切り替えや再生速度の変更ができます。 他のアセットとの連携 本アセットは、単体での実行を想定しております。 関連情報 プロンプトで判定ロジックを変えられる動画像認識エンジン
Entity APIクライアント
GUIからCanvas上のEntityに対してデータの入出力をテストするツールです。Entityに値を入力し、APIリクエストを送信することで、結果を確認できます。 想定ユーザー Entityの使い方をマスターしたい、または使用したいStudio利用者。このtemplateを用いることで、entityにGUIからデータやファイルをアップロードすることができます。※ Studio入門編 紹介動画 概要 テンプレート動作 入力 環境変数で用意された、以下 環境変数 内容 備考 DATA_ENTITY_ID_LIST データのEntity ID ex) data-ent FILE_ENTITY_ID_LIST ファイルのEntity ID ex) file-ent LAYER_DATA_ENTITY_ID_LIST レイヤー化されたデータのEntity ID ex) layer-data LAYER_FILE_ENTITY_ID_LIST レイヤー化されたファイルのEntity ID ex) layer-file ALL_ENTITY_ID_LIST CanvasにあるすべてのEntity ID ex) data-ent,file-ent,layer-data,layer-file LAYER_ALL_ENTITY_ID_LIST レイヤー化されたすべてのEntity ID ex) layer-data,layer-file Injection機能による初期設定 Injectionに追加している各jsonファイルの中身を編集することで対応する各ページの表示を変更することができる。 Output Entityにデータやファイルへの参照を保持させたり、保持しているデータやファイルを確認することができる。これにより、functionへの入出力や、特定の条件が満たされたときに自動的に動作する仕組み(trigger)を設定できる。 利用方法 単体での動作確認 テンプレート動作に従い、環境変数を設定。 デプロイボタンを押す。 /streamlit-apiのエンドポイントにアクセスする。 POST Request (エンティティにWriteを行う。) 左側のサイドバーからpost requestを選択。 Data Data uploadを選択。 "Write data to post to an entity"にpostしたいデータを入力。 "Upload Data"をクリックする。 File File uploadを選択。 "Browse files"をクリックし、postしたいファイルを選択。 "Upload File"をクリックする。 複数のData(レイヤー化されたデータ) Data upload (layered)を選択。 "Insert layer ID"に任意のlayer-idを設定。 "Write data to post to an entity"にpostしたいデータを入力。 "Upload Data"をクリックする。 複数のFile(レイヤー化されたデータ) File upload (layered)を選択。 "Insert layer ID"に任意のlayer-idを設定。 "Browse files"をクリックし、postしたいファイルを選択。 "Upload File"をクリックする。 subscription subscriptionタブを選択 過去にpostしたリクエストのentity IDとlayer IDを設定。 "Subscribe to Entity"をクリックする。 指定したリクエストの情報を取得することができる。 GET Request (エンティティにReadを行う。) 左側のサイドバーからget requestを選択。 Data Get Dataを選択。 "Get Data"をクリックすると過去にpostしたdataが取得できる。 File Get Fileを選択。 "Get File data"をクリックする。 "Download File"をクリックするとファイルがダウンロードされる。 複数のData(レイヤー化されたデータ) Get Data (layered)を選択。 "Layer ID"に過去にデータをpostした際のlayer IDを設定。 "Get Data"をクリックすると指定したlayer IDのdataが取得できる。 複数のFile(レイヤー化されたデータ) Get File (layered)を選択。 "Entity ID"はlayer-fileを選択。 "Layer ID"に過去にファイルをpostした際のlayer IDを設定。 "Retrieve file data"をクリックする。 "Download File"をクリックすると指定したlayer IDのファイルがダウンロードされる。 すべてのレイヤー化されたエンティティのLayer IDを確認する。 Get all layer id in entityを選択。 "Entity ID"にDataのLayer IDを確認したい場合はlayer-dataを、FileのLayer IDを確認したい場合はlayer-fileを設定。 "Get Layer ID"をクリックすると、過去にlayeredにpostした、すべてのデータやファイルのLayer IDが表示される。 DELETE Request あるentityのすべてのデータまたはファイルを削除する。 Delete all layer in an entityを選択。 "Delete all layer"に削除したいentity IDを選択する。 "Delete all layer"をクリックすると指定したentity IDのすべてのデータが削除される。 特定のレイヤーのデータまたはファイルを削除する。 Delete specific layerを選択。 "Entity ID"にデータを削除したい場合はlayer-dataを、Fileを削除したい場合はlayer-fileを設定。 "Layer ID"に削除したいデータまたはファイルのlayer IDを設定。 "Delete specific layer"をクリックすると指定したデータまたはファイルが削除される。 他のアセットとの連携 このtemplateを用いることで、entityを用いるアプリケーションを開発する際に、entityへのデータやファイルのアップロードをGUIから行うことが可能になります。 方法は以下の通りです。 こちらのtemplateをコピー&ペーストをして配置する。 使用したいentityにtriggerやfunctionを繋げる。 上記の手順により、GUIからアップロードしたデータやファイルを用いて、functionの入力やtriggerの設定に利用できます。 関連情報 Entity ref) https://docs.<cluster_name>.studio.exabase.ai/docs/references/components/entity <cluster_name>は、お使いの環境を指定する文字列が入ります。担当者に確認してください。
RAGシステム with ハイブリッド検索
LLMを使ったアプリケーション開発のフレームワークであるLangChainを使って、RAGシステムを構築できます。リトリーバーにBM25アルゴリズムを利用でき、ベクトル検索とのハイブリッド検索に対応しています。 Azure OpenAI Service か OpenAI API のAPIキーが必要です。 紹介動画 概要 想定ユーザー RAGシステムを実装したいユーザー。 PDFやWebページのドキュメントをベクトルデータと合わせてOpenSearchに保存したいユーザー。 検索に、ベクトル検索・BM25・ハイブリッド検索を使用したいユーザー。 テンプレート動作 入力 シークレット AZURE_AI_API_KEY Azure OpenAI Serviceを使用する場合、そのAPIキーを入力する。 OpenAI APIを使用するでも、OpenAIのAPIキーを入力すると、他の変数の設定を変更することなく利用できる。OpenAIのAPIキーを設定するためのシークレットを別に設ける場合は、 chatknowledge for admin SideAppのEnvironment variables OPENAI_API_KEY の値の ${{SECRET.AZURE_AI_API_KEY}} の AZURE_AI_API_KEY の部分を、対応するシークレットのキーに変更する。 OPENSEARCH_PASSWORD OpenSearchで使用するためのパスワードを設定する。値は任意。 chatknowledge for admin SideAppのEnvironment variables STREAMLIT_SERVER_PORT Streamlitが起動するポート 8080 を指定する。 OPENAI_API_TYPE Azure OpenAI Serviceの場合は値を azure 、OpenAI APIの場合は値を openai とする。 OPENAI_API_VERSION Azure OpenAI Serviceの場合のみ使用するAzure OpenAI APIバージョン。値は 2023-10-01-preview など。OpenAI APIを使用する場合は設定しない。 OPENAI_API_BASE Azure OpenAI Serviceの場合のみ使用するAzure OpenAI APIのベースURL。値は基本的に https://{replace-me}.openai.azure.com/ の形式。OpenAI APIを使用する場合は設定しない。 OPENAI_API_KEY Azure OpenAI ServiceまたはOpenAI APIのAPIキー。この値は ${{SECRET.AZURE_AI_API_KEY}} のように設定し、APIキーの値は対応するシークレットに格納する。 OPENSEARCH_URL OpenSearchサーバーのURL。 http://{opensearch SideAppが存在するWorkspace名}-{opensearch SideAppのID}:8080 の形式で指定する。 VECTOR_STORE ベクターストアの種類。値は Opensearch。 OPENSEARCH_INDEX DBにドキュメントを登録する際のindex名。 OPENAI_CHUNK_SIZE ドキュメントロード時の最大チャンクサイズ。 CHAT_MODEL_LIST 使用するモデルのリスト。 gpt-35-turbo-16k,gpt-4,gpt-3.5-turbo のように、カンマ区切りで指定する。 ALLOW_UPLOAD ドキュメントのアップローダーを表示する場合は値を true とする。 LOG_ENTITY 会話履歴を保存するために使用するEntity名。他のアセットと組み合わせて使う場合に利用する。このアセット単体で使用する場合は設定不要。 OPENSEARCH_INITIAL_ADMIN_PASSWORD OpenSearchで設定するパスワード。この値は ${{SECRET.OPENSEARCH_PASSWORD}} のように指定し、実際のパスワードは対応するシークレットに格納する。 PAST_CONTEXT チャットでAPIにリクエストを投げる際に含める過去の会話(Q&A)の数。 Injection機能による初期設定 opensearch SideAppのInjectionファイル /usr/share/opensearch/config/opensearch.yml の cluster.name の値を、各環境のクラスター名 (URLの app.{env-id}.studio.exabase.ai の {env-id} の部分) に置き換える。 Opensearch Dashboard SideAppのInjectionファイル /usr/share/opensearch/config/opensearch.yml の {namespace-id} をCanvasのネームスペースIDに置き換える。 ドキュメントの登録 デプロイした後、 chatknowledge for admin SideAppに接続されたエンドポイントのURLからRAGシステムの管理画面を開き、RAGシステムで用いるためのPDFまたはWebページのドキュメントを登録する。 チャット入力 ドキュメントを登録した後、RAGシステム管理画面下部のチャット欄からテキストを入力する。 Output チャット入力に対して、ドキュメントを踏まえた回答が得られる。 Function 検索にベクトル検索、BM25、ハイブリッド検索を用い、登録されたドキュメントに基づいてチャットボットが回答する。 PDFやWebページのドキュメントをベクトルデータと合わせてOpenSearchに保存する。 登録したドキュメントをOpenSearchダッシュボードで確認する。 利用方法 単体での動作確認 Canvasでシークレットとして下記を設定する。 AZURE_AI_API_KEY Azure OpenAI Serviceを使用する場合、そのAPIキーを入力する。 OpenAI APIを使用するでも、OpenAIのAPIキーを入力すると、他の変数の設定を変更することなく利用できる。OpenAIのAPIキーを設定するためのシークレットを別に設ける場合は、 chatknowledge for admin SideAppのEnvironment variables OPENAI_API_KEY の値の ${{SECRET.AZURE_AI_API_KEY}} の AZURE_AI_API_KEY の部分を、対応するシークレットのキーに変更する。 OPENSEARCH_PASSWORD OpenSearchで使用するためのパスワードを設定する。値は任意。 Canvasで chatknowledge for admin SideAppのEnvironment variablesとして下記を設定する。 STREAMLIT_SERVER_PORT Streamlitが起動するポート 8080 を指定する。 OPENAI_API_TYPE Azure OpenAI Serviceの場合は値を azure 、OpenAI APIの場合は値を openai とする。 OPENAI_API_VERSION Azure OpenAI Serviceの場合のみ使用するAzure OpenAI APIバージョン。値は 2023-10-01-preview など。OpenAI APIを使用する場合は設定しない。 OPENAI_API_BASE Azure OpenAI Serviceの場合のみ使用するAzure OpenAI APIのベースURL。値は基本的に https://{replace-me}.openai.azure.com/ の形式。OpenAI APIを使用する場合は設定しない。 OPENAI_API_KEY Azure OpenAI ServiceまたはOpenAI APIのAPIキー。この値は ${{SECRET.AZURE_AI_API_KEY}} のように設定し、APIキーの値は対応するシークレットに格納する。 OPENSEARCH_URL OpenSearchサーバーのURL。 http://{opensearch SideAppが存在するWorkspace名}-{opensearch SideAppのID}:8080 の形式で指定する。 VECTOR_STORE ベクターストアの種類。値は Opensearch。 OPENSEARCH_INDEX DBにドキュメントを登録する際のindex名。 OPENAI_CHUNK_SIZE ドキュメントロード時の最大チャンクサイズ。 CHAT_MODEL_LIST 使用するモデルのリスト。 gpt-35-turbo-16k,gpt-4,gpt-3.5-turbo のように、カンマ区切りで指定する。 ALLOW_UPLOAD ドキュメントのアップローダーを表示する場合は値を true とする。 LOG_ENTITY 会話履歴を保存するために使用するEntity名。他のアセットと組み合わせて使う場合に利用する。このアセット単体で使用する場合は設定不要。 OPENSEARCH_INITIAL_ADMIN_PASSWORD OpenSearchで設定するパスワード。この値は ${{SECRET.OPENSEARCH_PASSWORD}} のように指定し、実際のパスワードは対応するシークレットに格納する。 PAST_CONTEXT チャットでAPIにリクエストを投げる際に含める過去の会話(Q&A)の数。 Canvasで opensearch SideAppのInjectionファイル /usr/share/opensearch/config/opensearch.yml の cluster.name の値を、各環境のクラスター名 (URLの app.{env-id}.studio.exabase.ai の {env-id} の部分) に置き換える。 Canvasで Opensearch Dashboard SideAppのInjectionファイル /usr/share/opensearch/config/opensearch.yml の {namespace-id} をCanvasのネームスペースIDに置き換える。 デプロイボタンを押し、デプロイの完了を待つ。 chatknowledge for admin SideAppに接続されたEndpointのURL ( https://studio.{env-id}.studio.exabase.ai/{namespace-id}/ws/chatknowledge-admin/ ) から、管理画面にアクセスする。 管理画面左側の設定項目を入力する。 "Chat Settings" と "Text Embedding Settings" の "Model" では、使用するモデル名を選択する。 "Deployment" には、Azure OpenAI Serviceの場合、使用するデプロイメント名を入力する。OpenAI APIの場合は入力不要。 "Search Method" では、使用する検索アルゴリズムを選択する。 管理画面から、ドキュメントを登録する。 PDFファイルの内容を登録する場合、 "Choose a pdf file" のフォームから使用するPDFファイルをアップロードする。 Webページの内容を登録する場合、 "input urls" のフォームにURLをカンマ区切りで入力する。 PDFファイルアップロードまたはURL入力の後、 "Create & Update Vector DB" のボタンを押し、登録が完了するのを待つ。 管理画面下部の "ask a question" のフォームからテキストを入力して "Go" ボタンを押すと、登録したドキュメントを踏まえた回答が得られる。 登録したドキュメントデータをOpenSearchダッシュボードで確認する場合、以下の操作を行う。 Opensearch Dashboard SideAppに接続されたEndpointのURL ( https://studio.{env-id}.studio.exabase.ai/{namespace-id}/ws/opensearch-dashboard/ ) から、OpenSearchダッシュボードにアクセスする。 OpenSearchダッシュボードのメニューから "Discover" を開き、 "Create index pattern" から、 chatknowledge for admin SideAppのEnvironment variablesの OPENSEARCH_INDEX で設定した名称 (デフォルト値は chatknowledge) のインデックスパターンを作成する。 再度OpenSearchダッシュボードのメニューの "Discover" を開くと、登録したドキュメントデータを確認できる。 他のアセットとの連携 会話履歴を保存する場合、Entityを経由して保存できる。DB等に保存する場合は、Entityに接続するTriggerやPipelineを組み合わせて実装すると良い。Entityの配置や会話内容のデータについては下記。 chatknowledge for admin SideAppのEnvironment variablesの LOG_ENTITY の値と一致するIDのData Entityを、同じWorkspace内に配置すると、チャット時Entityに会話内容が送られる。 Data Entityの /data APIエンドポイント (上記画像のように設定してEntityに接続したEndpointにリクエストを投げる場合のURLは https://studio.{env-id}.studio.exabase.ai/{namespace-id}/ws/check-chat/data ) にGETリクエストを送ると、 {"data": "<JSON文字列>"} のようなJSONを得る。 <JSON文字列> をパースすると、JavaScriptの場合、下記キーを有するオブジェクトが得られる。 apitype: chatknowledge for admin SideAppのEnvironment variablesの OPENAI_API_TYPE に設定した値。 appid: 本アセットの場合、値は "chatknowledge" となる。 convid: 会話のIDの文字列。 messages: チャットメッセージに関するオブジェクトの配列。そのオブジェクトは下記キーを有する。 role: メッセージ送信者のロールの文字列。基本的に配列の先頭のものの値が "user" (チャット入力側) で、次のものの値が "assistant" (チャットボットの出力側)。 content: メッセージ内容の文字列。ただし、 role が "user" の場合、チャット入力欄以外の命令文も含む。 model: チャットで用いるために選択したモデル名の文字列。例えば "gpt-3.5-turbo" のような値となる。 timestamp: タイムスタンプの文字列(JST)。例えば "2024-08-15 11:41:16" のような値となる。 tokensize: 対応するOpenAIのAPIコールで使用された総トークン数。 userid: 本アセットの場合、値は "chatknowledge" となる。 関連情報 RAG RAG (Retrieval-Augmented Generation, 検索による拡張生成) は、LLMを使う際に業務で扱うデータなどの関連情報をデータベースから検索して生成プロセスに取り込む手法です。 https://exawizards.com/exabase/studio/blog/27871/ ベクトル検索 ベクトル検索とは、データを数値ベクトル(数値の配列)をして表現し、ベクトル間の距離(類似度)を計算する検索手法です。 BM25 BM25は、キーワード検索で用いられるもので、単語の出現頻度や文書全体での重要性に基づき検索クエリとの関連度を順位付けするアルゴリズムです。 ハイブリッド検索 ハイブリッド検索とは、複数の検索方法を組み合わせた検索手法です。主に、ベクトル検索とキーワード検索を組み合わせます。 LangChain LangChainは、大規模言語モデルを用いたアプリケーションを構築するためのフレームワークです。 langchain.com LangChain GitHub リポジトリ OpenSearch OpenSearchは、ベクトル検索などの機能を有する検索エンジンです。 opensearch.org OpenSearch GitHub リポジトリ OpenSearch-Dashboards GitHub リポジトリ
エンドポイントのJWT認証モジュール
エンドポイントにJWT (JSON Web Token) 認証を追加することで、認証されたユーザーのみにアクセスを許可します。 これにより、APIのセキュリティが強化され、権限のないユーザーからのアクセスを防ぐことができます。 想定ユーザー 既存のWebAPIのセキュリティを強化したいStudio利用者。※ Studio入門編 紹介動画 概要 テンプレート動作 入力 環境変数 環境変数 内容 備考 API_HOST_ID 保護対象のWebAPIサーバのName EXPIRES_IN WTトークンの有効期間(分) PSWD_HASH_ALGO ユーザのパスワードの暗号化方式 sha256, sha512が選択可能 Injection機能による初期設定 Injection の /app/config/login-user.json に、IDとパスワードを設定してデプロイします。 パスワードは以下の手順に従って、Hash化したものを設定します。 パスワードのHash化 以下のどちらかの方法でHash化したパスワードを取得できます。 Windows/PowerShellコマンド PowerShellで以下を実行する。 SHA-256 $ms = [System.IO.MemoryStream]::new() $sw = [System.IO.StreamWriter]::new($ms) $sw.write("user1") $sw.Flush() $ms.Position = 0 Get-FileHash -InputStream $ms -Algorithm sha256 | Select-Object Hash $sw.close SHA-512 $ms = [System.IO.MemoryStream]::new() $sw = [System.IO.StreamWriter]::new($ms) $sw.write("user1") $sw.Flush() $ms.Position = 0 Get-FileHash -InputStream $ms -Algorithm sha512 | Select-Object Hash $sw.close Python 以下のPythonコードを実行する。 SHA-256 import hashlib raw_password = "xxxxxxx" digest256 = hashlib.sha256(password.encode("utf-8")).hexdigest() print(digest256) SHA-512 digest512 = hashlib.sha512(password.encode("utf-8")).hexdigest() print(digest512) Output 認証されたユーザーのみがAPIにアクセスできるようになる。 利用方法 単体での動作確認 テンプレート動作に従い、環境変数・ID・パスワードを設定。 デプロイボタンを押す。 JWT認証の確認。 JWT認証 jwt-proxyのエンドポイント+"/login"に設定したユーザ名とパスワードを送信。curl -X 'POST' https://studio.{env-name}.studio.exabase.ai/{namespace_id}/ws/login \ -H 'Content-Type: application/json' \ -d '{"userid": "user1", "password": "user1"}' => ログインに成功すると、{"token":"xxxxxx....."}のようにトークンが返却。以後このBearerトークンをAPI利用時に設定することで、認証がされる仕組みです。 トークンをBearerにセット。 WebAPIの/api/v1/health呼出。curl -H GET 'https://studio.{env-name}.studio.exabase.ai/{namespace_id}/ws/api/v1/health' \ -H 'Authorization: Bearer ここに取得したトークン内容を貼り付け' => {"health":"ok"}と返る。 WebAPIにアクセス。 WebAPIの/api/v1/estimate呼出。curl -X 'POST' 'https://studio.{env-name}.studio.exabase.ai/{namespace_id}/ws/api/v1/estimate' \ -H 'Authorization: Bearer ここに取得したトークン内容を貼り付け' \ -H 'Content-Type: application/json' \ -d '{"text": "sample text"}' => {"response":"sample text"}と返る。 他のアセットとの連携 本認証モジュールでは、他のStudioアセットで特に認証機能を持っていないSideApp等との接続を想定しています。 方法は以下の通りです。 既存のSideAppを含むStudioキャンバスを開く。 jwt-proxyのSideAppをendpointと既存のSideAppの間に配置する。 矢印で接続する。 上記の手順により、個々のWebAPI側に認証機能を付与することなく、JWTプロキシを手前に置くことでWebAPI保護を行うことができます。 関連情報 JWT (JSON Web Token) 認証 JSONデータを安全に送受信するためのオープンスタンダード(RFC 7519)。
アプリの死活監視テンプレート
exaBase StudioのSideAppの動作ログを、外部のロギングシステムにEndpoint経由で送付する機能です。StreamlitによるSideAppから使われることを前提としています。 LOGを安定して取得すること、外部システムでロギングし死活監視や障害切り分けのためのシーケンスログを保管することを想定しています。 概要 想定ユーザー Studioで構築するアプリケーションの死活監視を行いたいユーザー。 Studioで構築するアプリケーションのシーケンスログを外部からモニタリングしたいユーザー。 テンプレート動作 入力 Environment variables sa1 SideAppのEnvironment variablesとして、 LOG_ENDPOINTID を設定し、値に "死活監視Entity" のIDを設定する。本アセット単体で動作確認する場合は変更不要。 ログの送信 sa1 SideAppのInjectionファイル /app/src/app.py で、 LifeDeathLogger インスタンスの start_worker メソッドを呼び出し、ログをEntityに送信され続けるようにする。ログのメッセージを更新するには、 start_worker の返り値のメソッド set_message を実行する。本アセット単体で動作確認する場合は変更不要。 Output /sequence EndpointにGETリクエストを送るとログを取得できる。レスポンスのJSONは、例えば下記のような形式。{ "data": { "life_and_death_log": "2024/08/23 13:41:04, logging_counter:12548, last_message_from_app:app_log:2024/08/23 12:08:00, 223" } } Function シーケンスログをEntityに送り、Endpointからログを取得できるようにする。 利用方法 単体での動作確認 sa1 SideAppのEnvironment variablesとして、キーに LOG_ENDPOINTID、値に sequence ("死活監視Entity" のID) が設定されていることを確認する。 デプロイボタンを押し、デプロイの完了を待つ。 "死活監視SideApp" に接続されたEndpointのURL (https://studio.{env-id}.studio.exabase.ai/{namespace-id}/ws1/app/) を開くと、Streamlit死活監視のデモページを確認することができる。 "死活監視Entity" に接続されたEndpointの /data (https://studio.{env-id}.studio.exabase.ai/{namespace-id}/ws1/sequence/data) にGETリクエストを送ると、ログを取得できる。具体例は下記。 curlコマンドにより死活監視情報を取得する場合curl --max-time 5 -X GET https://studio.{env-id}.studio.exabase.ai/{namespace-id}/ws1/sequence/data watchとcurlコマンドにより1秒ごとに定期的に死活監視する場合watch -n 1 'curl --max-time 5 -X GET https://studio.{env-id}.studio.exabase.ai/{namespace-id}/ws1/sequence/data' watchとcurlコマンドにより1秒ごとに定期的に死活監視してログファイルに残す場合watch -n 1 'curl -w"¥n" --max-time 5 -X GET https://studio.{env-id}.studio.exabase.ai/{namespace-id}/ws1/sequence/data 1>>templog.txt' 上記と組み合わせて異なるコマンドラインでログファイルの最新状態を閲覧し続ける場合tail -f templog.txt 他のアセットとの連携 本アセットは、 sa1 SideAppのInjectionファイルを書き換えて、ログ出力と死活監視機能を備えたStreamlitのSideAppを構築するために活用されることを想定されています。 方法は以下の通りです。 本アセットの "死活監視Entity" とそれに接続されたEndpointのように、Canvasでログ送信先のEntityとそれを取得するためのEndpointを配置する。 本アセットの sa1 SideAppを、Injection機能などを利用して構築したいアプリケーションの動作になるように実装する。 sa1 SideAppのInjectionファイル /app/src/app.py を参考に、死活監視やシーケンスログ送信のためのコードを記載する。具体的には下記の通り。 モジュールをimportする。 import os from utils.lifedeath_logger import LifeDeathLogger Studioの環境変数を読み込む。 # --------------------------------------------- # 環境変数の取得 / get the environmental variables # ローカル環境でdockerを動かす場合は同様に環境変数をDockerfile等で定義してください # / be aware if to local docker test, all variables also set, such on Dockerfile or else # --------------------------------------------- NAMESPACEID = os.getenv("EBS_NAMESPACEID") WORKSPACEID = os.getenv("EBS_WORKSPACEID") LOG_ENDPOINTID = os.getenv("LOG_ENDPOINTID") 死活監視ログを管理する LifeDeathLogger クラスのインスタンスを作成し、スレッドをスタートさせる。 life_death_logger = LifeDeathLogger(NAMESPACEID, WORKSPACEID, LOG_ENDPOINTID) # スレッドを1度だけスタートさせます / start the thread for the first time # ページreloadでもlifedeath_workerが生き続けるようにしています / lifedeath_worker will continue when page loaded again lifedeath_worker = None if not life_death_logger.is_running(): lifedeath_worker = life_death_logger.start_worker() else: lifedeath_worker = life_death_logger.get_worker() :::tip アプリケーションとは別スレッドで動作させることで、Coding時に意識すること無く、死活監視ログを送信し続けられる。 Streamlitの特性に合わせて、SideAppのページの開き直し、リロード等に影響を受けることなく、死活監視スレッドは動作し続けるよう、 LifeDeathLogger クラスが定義されている。Streamlitアプリケーションの本体のコーディングの前に、上記ブロックを記載する。 ::: 死活監視ログにアプリケーションからのメッセージをセットしたい場合、以下のようにする。 lifedeath_worker.set_message(message_from_app) :::note message_from_app の部分に、任意の文字列(str)をセットする。 LifeDeathLogger の動作について: 死活監視ログは約1秒毎にEntityを更新する。以下の順に動作する。 set_message(message_from_app) によりStreamlitアプリケーションの最新ログを受け取る。 message_from_app を受け取ったタイミングでタイムスタンプ(JST)を自動付与する。 次のEntity更新タイミング(1秒毎)に、死活監視ログとして message_from_app を含んだ形で、Entityへメッセージをセットする。 セットしたタイミングでタイムスタンプが追加で付与される。 この動作はStreamlitアプリケーションとは非同期。 ::: Canvasでの実装完了後、デプロイボタンを押し、デプロイの完了を待つ。 単体での動作確認 と同様に、ログ送信先のEntityに接続されたEndpointから、ログを取得できる。 関連情報 ツール Streamlit Streamlitは、WebアプリケーションをPythonで簡単に素早く構築できるフレームワークです。 streamlit.io ご利用に際して留意事項 本アセットは、ロングランテストを1週間程度行ったものであり、長期運用の品質が担保されたものではないことにご留意ください。
アプリのロギングエージェント with rsyslog
SideAppで稼働するアプリにロギングエージェントをインストールすることでログをFluentdで収集し、Opensearchに格納、Opensearch Dashboardでログを閲覧することができます。 また、OpensearchのスナップショットをAmazon S3へバックアップし、リストアすることも可能です(Amazon S3のアクセスキーが必要)。 紹介動画 概要 想定ユーザー ロギングを実装したいユーザー。 ロギングエージェント(特にrsyslog)を使用し、Fluentdを経由してOpenSearchにログを保存したいユーザー。 OpenSearchに保存したログをOpenSearchダッシュボードで確認したいユーザー。 テンプレート動作 入力 シークレット (スナップショットをAmazon S3に保存する場合に設定する) AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN (任意。一時的な認証情報を使用する場合に設定する。) Injection機能による初期設定 Dashboard のSideAppにInjectionファイル /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml の server.basePath の {namespace-id} をCanvasのネームスペースIDに置き換える。 ログの保存 app ワークスペースの Log generation app with agent SideAppのInjectionファイル /etc/rsyslog.d/60-rsyslog.conf は、Fluentdへのログ転送の設定を含む、rsyslogの設定ファイル。本アセット単体で動作確認する場合は変更不要。 Output 保存されたログをOpenSearchダッシュボードから確認できる。 Function ロギングエージェント(特にrsyslog)を使用し、Fluentd経由でOpenSearchにログを保存する。 OpenSearchダッシュボードでログを表示する。 利用方法 単体での動作確認 スナップショットをAmazon S3に保存する場合、Canvasでシークレットとして下記を設定する。 AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN (任意。一時的な認証情報を使用する場合に設定する。) Canvasで Dashboard のSideAppにInjectionファイル /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml の server.basePath の {namespace-id} をCanvasのネームスペースIDに置き換える。 デプロイボタンを押し、デプロイの完了を待つ。完了すると、 app ワークスペースの Log generation app with agent SideAppが、30秒おきにログを出力する。 Dashboard のSideAppに接続されたEndpointのURL ( https://studio.{env-id}.studio.exabase.ai/{namespace-id}/log/dashboard/ ) から、OpenSearchダッシュボードにアクセスする。 OpenSearchダッシュボードのメニューから "Discover" を開き、 "Create index pattern" から system-logs-* というインデックスパターンを作成する。 Time field としては、基本的には @timestamp を用いる。 再度OpenSearchダッシュボードのメニューの "Discover" を開くと、ログを確認できる。 スナップショットをAmazon S3に保存する場合は、OpenSearchダッシュボードから以下の設定を行う。 メニューの "Snapshot Management" -> "Repositories" を開き、 "Create repository" から、下記のように入力してスナップショットリポジトリを登録する。 Repository name: {任意の名称} Repository type: Custom configuration Custom configuration:{ "type": "s3", "settings": { "bucket": "{bucket_name}", "base_path": "{bucket_base_path}" } } 自動的なスナップショット保存の設定をするために、 "Snapshot Management" -> "Snapshot policies" を開き、 "Create policy" から、表示されるフォームに入力する。 スナップショットからログをリストアする場合、OpenSearchダッシュボードから以下のように操作する。 "Snapshot Management" -> "Repositories" を開き、スナップショット設定時に設定したリポジトリがなければ、設定時と同様にスナップショットリポジトリを登録する。 "Snapshot Management" -> "Snapshots" を開くと、保存していたスナップショットが表示される。リストアしたいスナップショットのチェックボックスをチェックし、 "Restore" を押す。表示に従ってリストアの設定を行い、 "Restore snapshot" を押す。 メニューから "Discover" を開き、インデックスパターンがなければ、にリストアしたログのインデックスにマッチするインデックスパターンを "Index pattern name" に入力し、インデックスパターンを作成する。 再度メニューの "Discover" を開くと、リストアしたログを確認できる。 他のアセットとの連携 本アセットは、ロギングエージェントを使用したOpenSearchとOpenSearch Dashboardsによるロギング関連機能を、Studioで構築するアプリケーションに導入するために活用されることを想定されています。 方法は以下の通りです。 ロギング関連機能を導入したいCanvasに本アセットの log ワークスペースと同様のものを配置する。 本アセットの app ワークスペースの Log generation app with agent SideAppで使用しているDockerイメージの実装を含む こちらのzipファイル や、Injectionされた /etc/rsyslog.d/60-rsyslog.conf を参考に、ロギングエージェントからFluentdにログを転送するための設定を行う。 該当のDockerイメージを基にしたアプリケーションは、Ubuntuベースのアプリで、rsyslogをエージェントとして使用し、システムログをFluentdに転送する。zipファイル内には例として、Fluentdサーバーにシステムログを転送するための、rsyslogdの設定方法が示されている。rsyslogのデーモンは rsyslogd コマンドで開始する必要があり、これは、ダミーシステムログの生成コマンドと共に entrypoint.sh ファイルに記載されている。ログ転送対象のFluentdサーバーとポートは /etc/rsyslog.conf で定義する必要がある。詳細はzipファイル内をご確認ください。 Injectionされた /etc/rsyslog.d/60-rsyslog.conf の target の値としてデフォルトで log-fluentd が指定されているがこれは {Fluentd SideAppが存在するワークスペース名}-{Fluentd SideAppのID} である。 デプロイ後、 単体での動作確認 と同様に、OpenSearchダッシュボードからインデックスパターンやスナップショットの設定を行う。 再度OpenSearchダッシュボードのメニューのDiscoverを開くと、ログを確認できる。 関連情報 OpenSearch OpenSearchは、ログ分析などの機能を有する検索エンジンです。 opensearch.org OpenSearch GitHub リポジトリ OpenSearch-Dashboards GitHub リポジトリ Fluentd Fluentdは、データ収集ツールです。データ収集を一元化することができます。 fluentd.org rsyslog rsyslogは、高速なログ処理システムです。 rsyslog.com
アプリのロギングスクリプトのサンプル with Opensearch
Studio上で動作するアプリケーションのログを収集する仕組みとして、OpenSearchとOpenSearch Dashboardsのセットをデプロイするサンプルです。 また、このログ収集サーバに対して、ログを送信するサンプルのアプリ(Python)も付属しています。 OpensearchのスナップショットをAmazon S3へバックアップし、リストアすることも可能です(Amazon S3のアクセスキーが必要)。 紹介動画 概要 想定ユーザー ロギングを実装したいユーザー。 PythonアプリケーションのログをOpenSearchに保存したいユーザー。 OpenSearchに保存したログをOpenSearchダッシュボードで確認したいユーザー。 テンプレート動作 入力 シークレット (スナップショットをAmazon S3に保存する場合に設定する) AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN (任意。一時的な認証情報を使用する場合に設定する。) Injection機能による初期設定 Dashboard のSideAppにInjectionファイル /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml の server.basePath の {namespace-id} をCanvasのネームスペースIDに置き換える。 ログの保存 app ワークスペースの Dummy log generation app SideAppのInjectionファイル /app/src/app.py に、ログを送信するためのコードが記載されている。本アセット単体で動作確認する場合は変更不要。 Output 保存されたログをOpenSearchダッシュボードから確認できる。 Function PythonアプリケーションのログをOpenSearchに保存する。 OpenSearchダッシュボードでログを表示する。 利用方法 単体での動作確認 スナップショットをAmazon S3に保存する場合、Canvasでシークレットとして下記を設定する。 AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN (任意。一時的な認証情報を使用する場合に設定する。) Canvasで Dashboard のSideAppにInjectionファイル /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml の server.basePath の {namespace-id} をCanvasのネームスペースIDに置き換える。 デプロイボタンを押し、デプロイの完了を待つ。完了すると、 app ワークスペースの Dummy log generation app SideAppが、30秒おきにログを出力する。 Dashboard のSideAppに接続されたEndpointのURL ( https://studio.{env-id}.studio.exabase.ai/{namespace-id}/log/dashboard/ ) から、OpenSearchダッシュボードにアクセスする。 OpenSearchダッシュボードのメニューから "Discover" を開き、 "Create index pattern" から python-logs-* というインデックスパターンを作成する。 Time field としては、基本的には @timestamp を用いる。 再度OpenSearchダッシュボードのメニューの "Discover" を開くと、ログを確認できる。 スナップショットをAmazon S3に保存する場合は、OpenSearchダッシュボードから以下の設定を行う。 メニューの "Snapshot Management" -> "Repositories" を開き、 "Create repository" から、下記のように入力してスナップショットリポジトリを登録する。 Repository name: {任意の名称} Repository type: Custom configuration Custom configuration:{ "type": "s3", "settings": { "bucket": "{bucket_name}", "base_path": "{bucket_base_path}" } } 自動的なスナップショット保存の設定をするために、 "Snapshot Management" -> "Snapshot policies" を開き、 "Create policy" から、表示されるフォームに入力する。 スナップショットからログをリストアする場合、OpenSearchダッシュボードから以下のように操作する。 "Snapshot Management" -> "Repositories" を開き、スナップショット設定時に設定したリポジトリがなければ、設定時と同様にスナップショットリポジトリを登録する。 "Snapshot Management" -> "Snapshots" を開くと、保存していたスナップショットが表示される。リストアしたいスナップショットのチェックボックスをチェックし、 "Restore" を押す。表示に従ってリストアの設定を行い、 "Restore snapshot" を押す。 メニューから "Discover" を開き、インデックスパターンがなければ、リストアしたログのインデックスにマッチするインデックスパターンを "Index pattern name" に入力し、インデックスパターンを作成する。 再度メニューの "Discover" を開くと、リストアしたログを確認できる。 他のアセットとの連携 本アセットは、PythonアプリケーションのログをOpenSearchとOpenSearch Dashboardsにより扱うための機能を、Studioで構築するアプリケーションに導入するために活用されることを想定されています。 方法は以下の通りです。 ロギング関連機能を導入したいCanvasに本アセットの log ワークスペースと同様のものを配置する。 アプリケーションのコードのログを取りたい箇所に、ロギングのコードを記述する。例えば、下記のように記述する。 import os import logging from opensearch_logger import OpenSearchHandler logger = logging.getLogger(__name__) logger.setLevel(level=logging.DEBUG) openSearchHandler = OpenSearchHandler( index_name="python-logs", hosts=[f"{os.environ['LOG_ADDRESS']}:{os.environ['LOG_PORT']}"], use_ssl=False, raise_on_index_exc=True, ) logger.addHandler(openSearchHandler) logger.info("log message") なお、 opensearch-logger を、 pip install opensearch-logger 等により使用できるようにする必要がある。 また、 上記コード中の LOG_ADDRESSと LOG_PORT を、該当のSideApp等でEnvironment variablesとして設定する必要がある。それぞれの内容は下記。 LOG_ADDRESS : {OpenSearch SideAppが存在するワークスペース名}-{OpenSearch SideAppのID}。 log ワークスペースの内容を変更していない場合は、値を log-opensearch とする。 LOG_PORT : OpenSearchのSideAppで該当プロセスが待ち受けているポート。 log ワークスペースの内容を変更していない場合は、値を 8080 とする。 その他、必要に応じて app ワークスペースの Dummy log generation app SideAppに設定されたEnvironment variablesとInjectionされた /app/src/app.py を参考にする。 デプロイ後、 単体での動作確認 と同様に、OpenSearchダッシュボードからインデックスパターンやスナップショットの設定を行う。 再度OpenSearchダッシュボードのメニューのDiscoverを開くと、ログを確認できる。 関連情報 OpenSearch OpenSearchは、ログ分析などの機能を有する検索エンジンです。 OpenSearchにログを送信するPythonスクリプト中では、 opensearch-logger を使用しています。 opensearch.org OpenSearch GitHub リポジトリ OpenSearch-Dashboards GitHub リポジトリ
LLMを用いたニュース記事の見出しとサマリー生成
ニュースサイト等のURLを入力すると、スクレイピングして、LLMを用いて記事の見出しとサマリーを自動生成するアプリケーションです。 想定ユーザー 記事の見出しとサマリーを生成させたいStudio利用者。※ Studio入門編 紹介動画 概要 テンプレート動作 入力 シークレットシークレットにOpenAI APIにアクセスするための情報を下記のkey名で登録する。 OPENAI_API_ORG OPENAI_API_KEY 環境変数SideApp「ユーザーインターフェース」に以下の5つの環境変数を設定する。 環境変数 内容 備考 OPENAI_API_KEY OpenAI APIのアクセスキー1 OPENAI_API_ORG OpenAI APIのアクセスキー2 QD_PORT Qdrantのポート設定 QD_COLLECTION_NAME Qdrantのコレクション名 QD_SIDEAPPID QdrantのSideAppノードのID Output 入力した記事の内容の見出しと要約 (GUIに直接表示される。) Function 記事の内容を受け取り、見出しと要約を生成する。 利用方法 単体での動作確認 テンプレート動作に従い、シークレットと環境変数を設定。 デプロイボタンを押す。 エンドポイントにアクセスする。 ニュース記事のURLを入力欄に記入し、記事を抽出する。 「ベクトルdbに登録」ボタンを押して、抽出した記事をDBに登録する。 見出しや要約を作成したい記事の内容を入力する。(URLではなく、記事の内容をコピー&ペーストして直接入力する。登録した記事に同じテーマの記事が含まれていると、より良い見出しが作成できる。) 条件を設定し、「見出しと要約を生成」ボタンを押すと見出しと要約が表示される。 関連情報 Webスクレイピングとは Webスクレイピングとは、インターネット上にある情報の中から特定の情報を抽出・収集する技術・行為のこと。 ご利用に際して留意事項 Webスクレイピング Webサイトの中には、利用規約でWebスクレイピングを行うことが禁止されているものも少なくないため、事前にご確認ください。 Webスクレイピングは対象のWebサイトに負荷をかけることがあるため、利用規約やマナーにご注意ください。 Webスクレイピングを行うと、収集したデータの加工の方法や利用用途よっては著作権侵害の可能性があります。 参考:文化庁|著作者の権利の制限(許諾を得ずに利用できる場合)
OpenSearch Dashboardテンプレート
OpenSearch Dashboardのモジュールです。OpenSearchクラスタに保存されたデータを可視化し視索するOSSダッシュボードです。データを活用して、様々なチャートを作成し、クラスタを管理できます。 想定ユーザー データの可視化を通じて分析やモニタリングを行いたいビジネスやITの専門家。 紹介動画 概要 テンプレート動作 入力 環境変数 環境変数 内容 SiedeApp名 備考 ES_JAVA_OPTS JVMオプションの設定 opensearch メモリ割り当て、ガベージコレクション、その他のJVMパラメータを調整可能。例: -Xms500m -Xmx500m OPENSEARCH_INITIAL_ADMIN_PASSWORD 初期パスワード opensearch クラスターの初期セットアップ時に、この環境変数で指定されたパスワードが管理者ユーザーに割り当てられる。 OPENSEARCH_HOSTS クラスターのノードのホスト名 Opensearch Dashboard DISABLE_SECURITY_DASHBOARDS_PLUGIN セキュリティプラグインの無効化 Opensearch Dashboard 開発やテストのためにデフォルトでtrueとなっている。本番利用する場合にはfalseとして適切な設定が必要。 詳細はhttps://opensearch.org/docs/latest/ を参照してください。 Injection機能による初期設定 SideApp「Opensearch Dashboard」の/usr/share/opensearch-dashboards/config/opensearch_dashboards.ymlの{namespace-id}をご自身のCanvasのネームスペースIDに書き換えます。(IDはノードを何を選択していないときに表示されます。) SideApp「opensearch」の/usr/share/opensearch/config/opensearch.ymlの{cluster-name}を利用している環境のクラスタ名に書き換えます。(クラスタ名はStudioのURLから取得できますs:app.{cluster-name}.studio.exabase.ai/) Output OpenSearch Dashboardが使えるようになり、データの可視化や分析ができるようになる。 利用方法 単体での動作確認 テンプレート動作に従い、環境変数とInjectionファイルを設定。 デプロイボタンを押す。 サンプルデータをOpensearchクラスタにPostする。 エンドポイント「/opensearch-dashboard」からアプリを開き、画面右側のDev Toolを選択する。 画面からOpensearchに下記のクエリを実行し、サンプルデータを送信する(index_nameは任意)。POST /{index_name}/_doc { "title": "Opensearch dashboard test", "content": "This is the content from opensearch dashboard", "timestamp": "2024-04-09T15:00:00" } サンプルデータをOpensearch Dashboardから表示する。 エンドポイント「/opensearch-dashboard」にアクセスし、サイドバーから"Discover" を選択する。 "Create index pattern"を選択し、3-iiで設定したindex_nameを入力して、該当するものを選択する。 Discoverページに戻るとサンプルデータが表示される。 関連情報 OpenSearch OpenSearch:検索エンジンおよび分析プラットフォームで、大量のデータの収集、検索、分析を高速に行うことができる。 OpenSearch Dashboards:OpenSearchに収集されたデータを視覚化するためのツールで、データの可視化、インタラクティブなダッシュボードの作成、およびデータの分析結果のプレゼンテーションといった機能がある。 公式ドキュメント
Amazon S3のアップローダー/ダウンローダー
Amazon S3にファイルをアップロードしたり、ダウンロードしたりするためのテンプレートです。 AWSのアクセスキーとシークレットが必要です。 紹介動画 概要 想定ユーザー Amazon S3にファイルをアップロードしたり、ダウンロードしたりしたいユーザー。 テンプレート動作 入力 シークレット AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY s3-upload FunctionのEnvironment variables TARGET_S3_URI アップロード先のS3 URI。下記のような値。 s3://{bucket-name}/{prefix(folder-name)}/{object-name} s3://{bucket-name}/{object-name} SOURCE_PATH s3-upload FunctionのInputのPathと同一の値。 AWS_ACCESS_KEY_ID AWSアクセスキーID。ここでは ${{SECRET.AWS_ACCESS_KEY_ID}} のように指定し、実際の値は対応するシークレットに設定する。 AWS_SECRET_ACCESS_KEY AWSシークレットアクセスキー。ここでは ${{SECRET.AWS_SECRET_ACCESS_KEY}} のように指定し、実際の値は対応するシークレットに設定する。 AWS_DEFAULT_REGION AWSリージョン。設定は任意。 s3-download FunctionのEnvironment variables SOURCE_S3_URI ダウンロード元のS3 URI。下記のような値。 s3://{bucket-name}/{prefix(folder-name)}/{object-name} s3://{bucket-name}/{object-name} TARGET_PATH s3-download FunctionのOutputのPathと同一の値。 AWS_ACCESS_KEY_ID AWSアクセスキーID。ここでは ${{SECRET.AWS_ACCESS_KEY_ID}} のように指定し、実際の値は対応するシークレットに設定する。 AWS_SECRET_ACCESS_KEY AWSシークレットアクセスキー。ここでは ${{SECRET.AWS_SECRET_ACCESS_KEY}} のように指定し、実際の値は対応するシークレットに設定する。 AWS_DEFAULT_REGION AWSリージョン。設定は任意。 アップロード対象のファイル ファイルをS3にアップロードする場合、POSTリクエストで設定したEndpointにファイルを送信する。 Output ダウンロード対象のファイル ファイルをS3からダウンロードする場合、設定したEndpointからGETリクエストでファイルをダウンロードする。 Function Amazon S3にファイルをアップロードする。 Amazon S3からファイルをダウンロードする。 利用方法 単体での動作確認 Canvasでシークレットとして下記を設定する。 AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY ファイルをS3にアップロードする場合、Canvasで s3-upload FunctionのEnvironment variablesとして下記を設定する。 TARGET_S3_URI アップロード先のS3 URI。下記のような値。 s3://{bucket-name}/{prefix(folder-name)}/{object-name} s3://{bucket-name}/{object-name} SOURCE_PATH s3-upload FunctionのInputのPathと同一の値。 AWS_ACCESS_KEY_ID AWSアクセスキーID。ここでは ${{SECRET.AWS_ACCESS_KEY_ID}} のように指定し、実際の値は対応するシークレットに設定する。 AWS_SECRET_ACCESS_KEY AWSシークレットアクセスキー。ここでは ${{SECRET.AWS_SECRET_ACCESS_KEY}} のように指定し、実際の値は対応するシークレットに設定する。 AWS_DEFAULT_REGION AWSリージョン。設定は任意。 ファイルをS3からダウンロードする場合、Canvasで s3-download FunctionのEnvironment variablesとして下記を設定する。 SOURCE_S3_URI ダウンロード元のS3 URI。下記のような値。 s3://{bucket-name}/{prefix(folder-name)}/{object-name} s3://{bucket-name}/{object-name} TARGET_PATH s3-download FunctionのOutputのPathと同一の値。 AWS_ACCESS_KEY_ID AWSアクセスキーID。ここでは ${{SECRET.AWS_ACCESS_KEY_ID}} のように指定し、実際の値は対応するシークレットに設定する。 AWS_SECRET_ACCESS_KEY AWSシークレットアクセスキー。ここでは ${{SECRET.AWS_SECRET_ACCESS_KEY}} のように指定し、実際の値は対応するシークレットに設定する。 AWS_DEFAULT_REGION AWSリージョン。設定は任意。 デプロイボタンを押し、デプロイの完了を待つ。 ファイルをS3にアップロードする場合、下記操作を行う。 /upload Endpointの /file にPOSTリクエストでファイルを送信する。例えば、curlコマンドの場合、下記を実行する。curl -X POST https://studio.{env-id}.studio.exabase.ai/{namespace-id}/s3-upload/upload/file \ -H "Content-Type: multipart/form-data" \ -F "file=@/path/to/your/file" Pipelineが実行されると、S3にファイルがアップロードされる。 ファイルをS3からダウンロードする場合、下記操作を行う。 /run-ai Endpointに空のJSONをPOSTするリクエストを送り、Pipelineをキックする。例えば、curlコマンドの場合、下記を実行する。curl -X POST https://studio.{env-id}.studio.exabase.ai/{namespace-id}/s3-download/run-dl/ \ -H "Content-Type: application/json" \ -d "{}" Pipelineの処理が完了すると、 output Entityにファイルが送信される。 /download Endpointの /data にGETリクエストを送り、file IDを取得する。例えば、curlコマンドの場合、下記を実行する。curl -X GET https://studio.{env-id}.studio.exabase.ai/{namespace-id}/s3-download/download/data \ -H "Content-Type: multipart/form-data" 得られるJSONは下記のようになる。{ "data": { "fileId":"{your-file-id}", "layerId":"", "filename":"output", "encoding":"7bit", "mimeType":"application/octet-stream" } } /download Endpointの /file/{file-id} にGETリクエストを送り、ファイルをダウンロードする。例えば、curlコマンドの場合、下記を実行する。curl https://studio.{env-id}.studio.exabase.ai/{namespace-id}/s3-download/download/file/{file-id} \ > {output-file-path} 他のアセットとの連携 ファイルをS3にアップロードする場合、 単体での動作確認 と同様に "s3-upload" Workspace のような設定を行い、それを活用して他アセットからアップロードする。 ファイルをS3からダウンロードする場合、 単体での動作確認 と同様に "s3-download" Workspace のような設定を行い、それを活用して他アセットからダウンロードする。 関連情報 Amazon S3 Amazon S3 (Simple Storage Service) は、AWS のオブジェクトストレージサービスです。 https://aws.amazon.com/jp/s3/
LLMを用いたWebスクレイパー
LLMを活用してWebスクレイピングを行えます。対象のWebページから抽出したい情報・出力フォーマットを指定できます。 想定ユーザー 複数のWebサイトから決まった情報を抽出し、表にリストアップしたいユーザ SideAppとPipelineを組み合わせることで、疎結合なアプリケーションを作成したいユーザ 紹介動画 概要 テンプレート動作 Input Webスクレイピングを行いたいURL (.json, 形式は利用方法を参照) Webアプリの画面にて入力 LLMプロンプト (.txt) Injection機能を用いてFunction内に記載 configファイル (.json) Injection機能を用いてFunction内に記載 環境変数 環境変数 内容 備考 OPEN_AI_ORGID OpenAIの組織ID シークレットに設定 OPEN_AI_API_KEY OpenAIのAPI Key シークレットに設定 CHAT_MODEL_NAME ChatGPTのモデル名 gpt-4o-mini推奨 Output 抽出済みの情報一覧 Webアプリの画面から確認 Function 下記の処理を順番に実行 Webスクレイピング コンテンツから情報を抽出(表示内容・更新日 etc..) コンテンツのカテゴリ化(Energy, Materials, Industrials etc..) コンテンツの日本語訳、要約 利用方法 単体での動作確認 デプロイ方法 下記のシークレットをCanvasに設定する。 OPEN_AI_ORGID OPEN_AI_API_KEY デプロイボタンを押す。 実行方法 Webアプリにアクセスし、左側のサイドバーから「app」を選択する。 WebアプリURLは下記 https://studio.{環境名}.studio.exabase.ai/{ネームスペース名}/ws/ui/ 情報を抽出したいサイトのURLを、入力欄にJSON形式で記載する。 フォーマットは下記 { "urllist": [ { "url": "xxxx1", "target": "yyyy1" }, { "url": "xxxx2", "target": "yyyy2" } ] } もしくは、「サンプルデータを挿入」ボタンを押すことで、入力欄にサンプルのJSONが記載される。 「実行ボタン」を押す。 実行結果確認方法 Webアプリの左側のサイドバーから「result」を選択する。 「解析結果を取得ボタン」を押す。 必ず実行中のパイプライン動作が完了してから押してください。 もしくは、「サンプルの結果を読み込む」ボタンを押すことでも、結果画面にサンプルの結果が表示されます。 表示された結果のテーブルのセルをダブルクリックすると、隠れている長いテキストが表示される。 テーブル左側のチェックボックスにて詳細表示したい情報を選択し、「詳細表示」ボタンを押す。 各タイトルをクリックし展開すると原文と日本語訳をそれぞれ表示されます。 抽出内容の変更方法 抽出・表示する内容を変えたい場合、下記のファイルの値をそれぞれ変える必要があります。 Function /app/config/config.json 注) 各Functionで全く同じ記述になるようにしてください。 変更する可能性が高いのは「input_list_keyname」〜「summary_text」あたりです。 /app/config/prompt.txt 出力されるフォーマットをプロンプト内で定義しています。 SideApp /app/src/pages/result.py 下記定数内の値を必要に応じて変更(20行目〜40行目 あたりに記載) COLUMN_NAME_LIST COLUMN_NAME_DISPLAY_LIST COLUMN_TITLE COLUMN_CONTENT_JA COLUMN_CONTENT_EN 例えば、入力・出力をそれぞれ以下のように変えたい場合を考える。 入力 { "urls": [ <- キーの名前を変更 { "url": "xxxx1", <- 「target」を削除 }, { "url": "xxxx2", } ] } 出力 { "urls": [ <- キーの名前を変更 { "url": "<https://ofsi.blog.gov.uk/2023/08/31/ofsi-uses-disclosure-power-for-first-time/>", "title": "OFSI uses disclosure power for first time", <- 「target」を削除 "main_content_english": "The critical role that financial ....", <- キーの名前を変更 "article_update_date": "2023/08/31", "regulation_released_date": "2022/08/31", "category": "Financials", "main_content_japanese": "金融制裁がロシアのウクライナアクション...", <- キーの名前を変更 "summary_content_japanese": "- 英国は金融制裁を使って国家安全保障と金..." <- キーの名前を変更 }, { "url": "<https://www.gov.uk/government/collections/enforcement-of-financial-sanctions>", "title": "Enforcement of financial sanctions", "main_content_english": "OFSI is responsible for...", "article_update_date": "2023/08/31", "regulation_released_date": "2019/02/25", "category": "Financials", "main_content_japanese": "OFSI(英国資産執行部)は、金融制裁のトラベレックスU...", "summary_content_japanese": "- OFSIは金融制裁の遵守を監視し、疑わしい違反を..." } ] } このとき、それぞれのfunctionに記載されているconfig.jsonと、function「構造化」のプロンプトは、以下のように書き換える必要がある。 /app/config/config.json { "input_list_keyname": "urls", <- valueを変更 "target_url": "url", "scraped_text": "page_text", "target_text": "main_content_english", <- valueを変更 "translate_text": "main_content_japanese", <- valueを変更 "summary_text": "summary_content_japanese", <- valueを変更 "retry_count": 3, "timeout_sec": 600, "paths": { "input": "/app/data/input/input.json", "output": "/app/data/output/output.json", "prompts": {"structuralize": "/app/config/prompt.txt", "categorize": "/app/config/prompt.txt", "translate": "/app/config/translate_prompt.txt", "summarize": "/app/config/summary_prompt.txt"} } } /app/config/prompt.txt Please extract the corresponding info from the following texts, and ouput it based on the provided output format. # Texts (extracted from a specific Web site) {scraped_text} # Output Format {{ "title" : "<Title of the article>", "main_content_english" : "<The text information related to Compliance, Financial Sanctions and Implementation.>", <- キーの名前を変更 "article_update_date" : "<The date when the article was released or updated. YYYY/MM/DD>", "regulation_released_date" : "<The date when the Compliance, Financial Sanctions and Implementation described in the article was notified. YYYY/MM/DD>" }} SideApp内の/app/src/pages/result.pyは以下のように書き換える。 ## テーブルに表示する項目 COLUMN_NAME_LIST = ["title", "category", <- 「target」を削除 "article_update_date", "regulation_released_date", "summary_content_japanese", <- 値を変更 "url", "changelog", ] ## テーブルに表示する項目(日本語) COLUMN_NAME_DISPLAY_LIST = ["表題", "情報カテゴリ", <- 「対象HP」(targetに対応)を削除 "情報更新日", "規制発行日", "要約(日本語)", "対象URL", "従来からの変更点", ] COLUMN_TITLE = "title" COLUMN_CONTENT_JA = "main_content_japanese" <- 値を変更 COLUMN_CONTENT_EN = "main_content_english" <- 値を変更 他のアセットとの連携 本アセットは、単体での実行を想定しております。
Triggerサンプルコード集
Triggerのサンプル集です。時刻指定やEntityの状態に応じてPipelineを実行することができます。 他のアセットと異なり、本アセット単体では動作しません。 想定ユーザー Triggerを利用し、独自のアプリケーションを構築したいユーザー。 Entityの状態に応じてPipelineを実行したいユーザー。 Pipelineを定期実行したいユーザー。 Triggerサンプル一覧 ワークスペース名 機能 ws1 Entityに新しい値が格納されたらPipelineを実行する ws2 2つのEntityに値が格納されたら数値かどうかを判断して、両方とも数値だったらPipelineを実行する ws3 1時間ごとにTrigger内でイベントを発生させる。イベントのタイミングで「平日かつ時刻部が10時(GMT標準時)」に一致する場合、Pipelineを実行する。 ws4 5分おきにPipelineを実行する ws5 毎日定時でPipeline実行する ws6 1時間ごとにTrigger内でイベントを発生させる。イベントのタイミングで「日付が1日かつ時刻部が10時(JST)」に一致する場合、Pipelineを実行する。 ws7 Pipelineの処理中に新たなタスクを開始させない 各Triggerサンプル詳細 ws1 Entityに新しい値が格納されたらPipelineを実行する 利用方法 デプロイ前のCanvasの設定 ws1内をコピーし、使用したいCanvasに貼り付ける。 Endpointの許可IPアドレスを必要に応じて設定する。 Pipeline内の "+" ボタンを押し、使用したいFunctionを設定する。少なくとも、FunctionのIDとimage (image URI) を入力する。 デプロイ後の動作 Entityに登録したいデータを送る。 Dataエンティティの場合curl -X POST "https://studio.{env-name}.studio.exabase.ai/{namespace-id}/{workspace-id}/data" \ -H 'Content-Type: application/json' \ -d '{"data": {"name": "John"}}' Fileエンティティの場合curl -X POST "https://studio.internal.studio.exabase.ai/3576a86c7aa9c128/ws1/file" \ -F file=@{filename} Pipelineが実行される。 ws2 2つのEntityに値が格納されたら数値かどうかを判断して、両方とも数値だったらPipelineを実行する 利用方法 デプロイ前のCanvasの設定 ws2内をコピーし、使用したいCanvasに貼り付ける。 Endpointの許可IPアドレスを必要に応じて設定する。 数値判定の条件を調整する必要があれば、Triggerのコードの isNumeric 関数の実装を変更する。 Pipeline内の "+" ボタンを押し、使用したいFunctionを設定する。少なくとも、FunctionのIDとimage (image URI) を入力する。 デプロイ後の動作 該当のエンドポイントURL+"data"にEntityに登録したいデータを送る。curl -X POST "https://studio.{env-name}.studio.exabase.ai/{namespace-id}/{workspace-id}/data" \ -H 'Content-Type: application/json' \ -d '{"data": 2}' 各Entityに格納された値が数値であれば、Pipelineが実行される。 ws3 1時間ごとにTrigger内でイベントを発生させる。イベントのタイミングで「平日かつ時刻部が10時(GMT標準時)」に一致する場合、Pipelineを実行する。 利用方法 デプロイ前のCanvasの設定 ws3内をコピーし、使用したいCanvasに貼り付ける。 実行時刻を変更したい場合は、Triggerのコードの return dayOfWeek >= 1 && dayOfWeek <= 5 && hour === 10; の箇所を変更する。 Pipeline内の "+" ボタンを押し、使用したいFunctionを設定する。少なくとも、FunctionのIDとimage (image URI) を入力する。 デプロイ後の動作 1時間ごとに発生するイベントのタイミングが、平日で、時刻部が指定の数値に合致する際に、Pipelineが実行される。 ws4 5分おきにPipelineを実行する 利用方法 デプロイ前のCanvasの設定 ws4内をコピーし、使用したいCanvasに貼り付ける。 実行間隔を変更したい場合は、Triggerのコードの IntervalMilliSeconds の値を変更する。 Pipeline内の "+" ボタンを押し、使用したいFunctionを設定する。少なくとも、FunctionのIDとimage (image URI) を入力する。 デプロイ後の動作 指定した実行間隔の時間ごとにPipelineが実行される。 ws5 毎日定時でPipeline実行する 利用方法 デプロイ前のCanvasの設定 ws5内をコピーし、使用したいCanvasに貼り付ける。 実行時刻を変更したい場合は、Triggerのコードの return hour === '2' && min === '05'; の箇所を変更する。 Pipeline内の "+" ボタンを押し、使用したいFunctionを設定する。少なくとも、FunctionのIDとimage (image URI) を入力する。 デプロイ後の動作 毎日指定時刻にPipelineが実行される。 ws6 1時間ごとにTrigger内でイベントを発生させる。イベントのタイミングで「日付が1日かつ時刻部が10時(JST)」に一致する場合、Pipelineを実行する。 利用方法 デプロイ前のCanvasの設定 ws6内をコピーし、使用したいCanvasに貼り付ける。 実行日時を変更したい場合は、Triggerのコードの return jstTime.getDate() === 1 && jstTime.getHours() === 10; の箇所を変更する。 Pipeline内の "+" ボタンを押し、使用したいFunctionを設定する。少なくとも、FunctionのIDとimage (image URI) を入力する。 デプロイ後の動作 1時間ごとに発生するイベントのタイミングが、指定日で、時刻部が指定の数値に合致する際に、Pipelineが実行される。 ws7 Pipelineの処理中に新たなタスクを開始させない 利用方法 デプロイ前のCanvasの設定 ws7内をコピーし、使用したいCanvasに貼り付ける。 Endpointの許可IPアドレスを必要に応じて設定する。 使用したいFunctionのimage (image URI) を入力する。また、Entity e2に接続したFunctionのOutputを、Pipeline処理中でないことを表す false などの値に更新するように実装する。 デプロイ後の動作 Entity e1の値を更新した際、Pipelineが処理中でなければ、Pipelineの処理を開始する。
プロンプトで判定ロジックを変えられる動画像認識エンジン
ユーザーが指定したプロンプトに従って、動画内のオブジェクトを認識し、特定の条件が満たされた場合においてコールバック関数によるトリガーを発出します。 概要 想定ユーザー プロンプトを書き換えるだけで、任意の動画解析を行いたいStudio利用者 解析結果に応じてアクションのトリガーを実現したいStudio利用者 テンプレート動作 Input 解析したい動画ファイル サンプル 環境変数 video-frame-parser 環境変数 内容 備考 FILENAME 入力ビデオファイルのパス OUTPUT 出力イメージtarファイルのパス WIDTH 出力フレームイメージの幅 HEIGHT 出力フレームイメージの高さ agentization-llm-function 環境変数 内容 備考 PATH_INSTRUCTIONS 入力命令ファイルのパス PATH_IMAGES 入力画像ファイルまたはそれらを含むtarファイルのパス PATH_OUTPUT 出力ファイルのパス MODE すべてのフレームを一度に分析(multi)または1つずつ分析(single) Singleモードでは動画から取り出されたフレーム1つに対して1つの回答を返しますが、Multiモードでは複数のフレームに対して1つの回答を返します。これによりアップロードされた動画から取り出される複数のフレームを入力として回答を返すことができます。 SUBSAMPLE nフレームごとに1フレームを取得 AI 使用するLLMプロバイダ:openaiまたはanthropic OpenAIのGPT4-visionとAnthropicのClaude3 Opusが利用できます。 MODEL_ANALYZE OpenAIによる画像検出に使用するモデル openai選択時にのみ使用 MAX_TOKENS_ANALYZE OpenAIによる画像検出に使用する最大トークン数 openai選択時にのみ使用 MODEL_INTERPRET OpenAIの分析と関数呼び出しに使用されるモデル openai選択時にのみ使用 MAX_TOKENS_INTERPRET OpenAIの画像分析に使用する最大トークン数 openai選択時にのみ使用 MODEL Anthropicで使用されるモデル anthropic選択時にのみ使用 MAX_TOKENS Anthropicで使用する最大トークン数 anthropic選択時にのみ使用 OPENAI_API_KEY OpenAI APIキー openai, anthropicのうち片方のみ使用の場合は、シークレット登録していない方のキーを環境変数から削除すること ANTHROPIC_API_KEY Anthropic APIキー openai, anthropicのうち片方のみ使用の場合は、シークレット登録していない方のキーを環境変数から削除すること Output 動画解析の結果 JSON形式 動作の流れ Endpoint /video に動画ファイルが送られると、Entity video に格納されます。 Triggerが発動し、Pipelineが実行されます。 TriggerのスクリプトはEntity video に変更があった場合にPipelineを実行するように設定されています。 Pipelineからの出力は、Entity output に解析結果が格納されます。接続されているEndpoint /outputより解析結果をダウンロードすることができます。 Pipelineは2つのFunctionから構成されています。 video-frame-parser 動画ファイルをフレームに分割し、そのフレームを圧縮ファイル(frames.tar)として出力します。これにより、動画の各フレームが次のFunctionで分析可能な形式に変換されます。 agentization-llm-function 先に生成されたフレームセット(frames.tar)を入力として受け取り、指定されたプロンプトに基づいてフレームの内容を分析します。プロンプトは、例えば「画像内のすべてのオブジェクトを列挙する」といった内容で、特定の条件(例:画像にリンゴが含まれているかどうか)に基づいてコールバック関数からをトリガーを発動するように設定されています。分析結果は接続されているEntityに保存されます。 利用方法 単体での動作確認 デプロイ方法 下記のシークレットをCanvasに設定します。 OPENAI_API_KEY ANTHROPIC_API_KEY :::note 片方だけ使う場合は、シークレットとして登録していない環境変数をFunction agentization-llm-funcitonから削除してください(現行仕様では、存在していないシークレットが環境変数に設定されていると、デプロイがうまくいかない場合があります) ::: デプロイボタンを押します。 実行方法 Endpoint /videoにローカルディレクトリから動画ファイルをアップロードします。 下記はTerminalからの実行例です。<env-name>、<namespace-id>、<動画のファイルパス>はご自身のものに書き換えてください。 curl -X POST https://studio.<env-name>.studio.exabase.ai/<namespace-id>/ws/video/file \ -H "Content-Type: multipart/form-data" \ -F "file=@<動画のファイルパス>" Pipelineによる処理が完了したら、Endpoint /outputから解析結果を取得します。 下記はTerminalからの実行例です。<env-name>、<namespace-id>、はご自身のものに書き換えてください。 curl -X GET https://studio.<env-name>.studio.exabase.ai/<namespace-id>/ws/upload/data -H "Content-Type: application/json" 下記は出力例です。今回の例では、画像にリンゴが含まれているかどうかに基づいてコールバック関数からをトリガーを発動するように設定されています。リンゴが映っている画像に対してはTrueを返し、リンゴが映らなくなるとFalseを返すようになります。 { "data": { "ai": "openai", "mode": "single", "subsample": 50, "frames": [ "000.jpg", "050.jpg", "100.jpg", "150.jpg", "200.jpg", "250.jpg", "300.jpg", "350.jpg" ], "prompt": [ "Enumerate all the visible objects on the image.", "Set the trigger state value to true, using the callback function, if there is an apple on the image description." ], "responses": [ { "analysis": "In the image, I see:\n\n1. Two apples with a predominantly red and yellow color, displaying some natural blemishes.\n2. A wooden surface, likely a table or countertop, with a visible wood grain pattern.\n3. Shadows cast on the wooden surface, indicating a light source on the upper left side, outside of the frame.\n\nThat covers all the visible objects in the image.", "message": null, "functions": [ { "trigger": true } ] }, { "analysis": "In the image, there are two apples on a wooden surface. The wood appears to have a fine grain, typical of a wooden table or countertop. The lighting casts a soft shadow for each apple on the surface.", "message": null, "functions": [ { "trigger": true } ] }, { "analysis": "The image shows two apples on a wooden surface. The surface appears to be a table or countertop with light shining on it, possibly from a nearby window, as indicated by the shadows cast by the apples. The apples have a reddish hue with some yellow and green spots, indicating they might be of a variety that isn't uniformly red.", "message": null, "functions": [ { "trigger": true } ] }, { "analysis": "The image shows a red apple with some yellowish hues on a wooden surface. The surface appears smooth, with the grain of the wood running horizontally from the perspective of the photo. There are also patterns of light and shadow, likely created by sunlight, casting over the apple and wooden surface, suggesting that the photo may have been taken near a window or under a light source that creates a similar effect.", "message": null, "functions": [ { "trigger": true } ] }, { "analysis": "In the image, I see a single red apple resting on a wood-grained surface where the light is creating a pattern of shadows and highlights across the surface, suggesting a light source above or to one side of the scene.", "message": null, "functions": [ { "trigger": true } ] }, { "analysis": "In the image, I can see the following objects:\n\n1. A human hand reaching for or holding an object.\n2. A red apple with part of it hidden by the hand.\n3. A flat surface with a wood grain pattern that appears to be a table or countertop.", "message": null, "functions": [ { "trigger": true } ] }, { "analysis": "The image shows a wooden surface with a visible wood grain pattern. There are no distinct objects other than the wood itself. The wood has variations in color, with lighter and darker brown tones. The grain patterns suggest it might be a floor or a table, but without additional context, it's not possible to determine its exact use or the presence of any other objects.", "message": null, "functions": [ { "trigger": false } ] }, { "analysis": "I'm sorry, but you haven't provided an image for me to analyze. Please upload an image, and I'll help you identify the visible objects.", "message": null, "functions": [ { "trigger": false } ] } ] } } Injection機能によるカスタマイズ方法 Canvas上から、Function agentization-llm-funciton の/app/data/instructions.json を編集します。 このファイルには、LLMが画像を分析して関数を呼び出すためのプロンプトが書かれています。プロンプトは {"prompt": [...]} 形式である必要があります。OpenAIとAnthropicではプロンプトがわずかに異なるため、デフォルトでサンプルのプロンプトがそれぞれに対して提供されています。 /app/data/instructions.json の設定例 { "prompt": [ "Enumerate all the visible objects on the image.", "Set the trigger state value to true, using the callback function, if there is an apple on the image description." ], "prompt_anthopic": "Enumerate all the visible objects on the image. Set the callback trigger state value to true if there is an apple on the image." } 編集が完了したら、Circuitを再度デプロイし、前述と同様に動画をEndpointにアップロードしてください。 他アセットとの連携 本アセットは他アセットとの連携が可能です。以下に実装例を紹介します。 Function agentization-llm-funciton の後ろに別のFunctionを繋げることで、更なる機能拡張が期待できます。例えば、JSON形式の解析結果と元々の動画を入力として、トリガーの値やLLMによる画像の解説を字幕化した動画の出力する機能をもったFunctionが考えられます。前述のSideAppによる実装と合わせることも可能です。 SideAppを用いたWebApp(別途作成の必要があります)にFrontendとBackendで責務を分けた互いに疎結合なサービスの開発が可能です。例えば、先ほどのFunction追加と併せて以下の機能を実装することが可能です。 ローカルから動画ファイルをアップロードする 動画をEntity videoに送信する Pipelineによる解析結果をEntity outputから取得する 解析結果(JSON形式)と解析結果の字幕付き動画をローカルにダウンロードする 関連情報 動画をフレームに分割してLLMで解析する with Claude3 Opus