Snowflake Cortex AIのCortex AnalystのREST APIにSnowflake外のサービスからリクエストしてみる

Snowflake Cortex AIのCortex AnalystのREST APIにSnowflake外のサービスからリクエストしてみる

Cortex AnalystのREST APIは外部システムからでも利用でき、簡単にSnowflakeのデータをに対する質問機能を実装することができます。
Clock Icon2025.05.04

データ事業本部の鈴木です。

Snowflake Cortex AIのCortex AnalystはSnowflakeの構造化データに基づいたビジネス上の質問に確実に回答できるアプリケーションの作成を実現する機能です。

REST APIで外部から呼び出しもできるため、サンプルを参考に試してみました。

Cortex Analystの外部システムからの利用

Cortex Analystのウリとして、REST APIの提供により、さまざまなシステムでSnowflakeのデータを使って「ビジネス上の質問に確実に回答できるアプリケーションの作成」を支援できる点があると思っています。
例えば、データベース内のテーブルに対する質問とSQLの生成は、現在プレビュー提供中のCopilotである程度できてしまいます。Copilotのユースケースとしてマルチターンの会話もサポートしており、その点も一緒です。

サポートされているユースケース

  • 提案された SQL クエリを洗練させ、分析をより深く掘り下げるためのフォローアップの質問をすることにより、 Snowflake Copilot との会話を介して 複雑なクエリを構築 します。

https://docs.snowflake.com/ja/user-guide/snowflake-copilot#supported-use-cases

差別化の一つのポイントとしては、Copilotと異なって、REST APIを利用できるさまざまなシステムから利用でき、そのシステムにSnowflakeのデータを使った回答機能を実装できる点があると考えています。

サンプルとしては以下のガイドに『Create a standalone Streamlit app』として紹介されており、

https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst#create-a-standalone-streamlit-app

GitHub上でも記事執筆時点では以下のパスにサンプルが記載されています。

https://github.com/Snowflake-Labs/sfguide-getting-started-with-cortex-analyst/blob/main/cortex_analyst_streaming_demo.py

やってみた

1. 検証の前提

Cortex Analyst向けの準備

今回はCortex Analyst向けのセマンティックファイルはあらかじめ準備してあることとします。具体的には以下のようなアプリをStreamlit in Snowflakeで用意して、アプリ上でCortex Analystと会話できる状態になっているとします。

https://dev.classmethod.jp/articles/snowflake-try-cortex-analytst/

Cortex Analystに問い合わせをする外部のシステムの準備

Cortex Analystに問い合わせをする外部のシステムは、Snowpark Pythonがインストールされているなにかしらの環境を想定しています。今回はSageMaker StudioのJupyterLab環境を使いました。
以下のようにJupyterLabスペースを作成し、サーバーを起動してノートブックから実装を行いました。SageMaker Studioに詳しくない方は、とりあえずSnowpark Pythonが使えてインターネットにアクセスできる環境から試したとご理解ください。

JupyterLabスペース

最近試したところ、SageMaker DistributionにSnowpark Pythonがインストールされていたので、そのまま使用しました。

Cortex Analystに問い合わせをするSnowflakeユーザーの準備

Snowflakeのユーザーも必要ですので作成方法について記載します。
以下のようにユーザーを作成しました。

-- ROLEの作成
CREATE ROLE SNOWPARK_ROLE;

-- ウェアハウスへのUSAGEアクセス権の付与
GRANT USAGE ON warehouse ウェアハウス名 TO ROLE SNOWPARK_ROLE;

-- データベースへのUSAGEアクセス権の付与
GRANT USAGE ON DATABASE データベース名 TO ROLE SNOWPARK_ROLE;

-- スキーマへのUSAGEアクセス権の付与
GRANT USAGE ON SCHEMA データベース名.スキーマ名 TO ROLE SNOWPARK_ROLE;

-- テーブルへのSELECT権限の付与
GRANT SELECT ON ALL TABLES IN SCHEMA データベース名.スキーマ名 TO ROLE SNOWPARK_ROLE;

-- セマンティックモデルの読み取り権限の付与
GRANT READ ON データベース名.スキーマ名.ステージ名  TO ROLE SNOWPARK_ROLE;

-- ユーザーの作成
CREATE USER SNOWPARK_OPERATOR
    PASSWORD = 'パスワード'
    DEFAULT_ROLE = 'SNOWPARK_ROLE'

-- ユーザーへのロールの付与
GRANT ROLE SNOWPARK_ROLE TO USER SNOWPARK_OPERATOR;

以下のブログでも過去に紹介しています。

https://dev.classmethod.jp/articles/create-local-develop-python-environment-snowpark/

今回のポイントは、ステージ上に作成してあるセマンティックモデルも読み取りできるようにしておく点です。

2. Cortex Analystへの問い合わせの実装

JupyterLabのノートブックに以下を記載して実行しました。

import requests
import snowflake.connector

# 接続の作成
session = snowflake.connector.connect(
    user="SNOWPARK_OPERATOR",
    password="パスワード",
    account="アカウント識別子",
    warehouse="ウェアハウス名",
    role="SNOWPARK_ROLE",
    )

# Cortex Analyst向けの設定変数
DATABASE = "データベース名"
SCHEMA = "スキーマ名"
STAGE = "ステージ名"
FILE = "セマンティックモデルファイル名"
API_ENDPOINT = "/api/v2/cortex/analyst/message"

# Cortex Analystへの問い合わせ
def send_message(message, session):
    request_body = {
        "messages": [message],
        "semantic_model_file": f"@{DATABASE}.{SCHEMA}.{STAGE}/{FILE}",
    }
    resp = requests.post(
        url=f"https://{session.host}/api/v2/cortex/analyst/message",
        json=request_body,
        headers={
            "Authorization": f'Snowflake Token="{session.rest.token}"',
            "Content-Type": "application/json",
        },
        stream=True,
    )
    if resp.status_code < 400:
        return resp  # type: ignore
    else:
        raise Exception(f"Failed request with status {resp.status_code}: {resp.text}")

# 質問例
query = "総取引額トップ3の顧客を教えてください。"
message = {"role": "user",
           "content": [
                {
                    "type": "text",
                    "text": query
                }]}

# 質問の実行
resp = send_message(message, session)
resp.json()

ちなみに、Streamlit in Snowflakeでは以下のような、_snowflake.send_snow_api_requestを使った問い合わせ実装例がよく紹介されています。

    resp = _snowflake.send_snow_api_request(
        "POST",
        f"/api/v2/cortex/analyst/message",
        {},
        {},
        request_body,
        {},
        30000,
    )

_snowflakeはPython UDFの実装などで出てくる、Snowflakeのランタイム上で利用できる内部向けのライブラリですが、今回は別システム上からREST APIを叩きたいため、別途Snowflakeとの接続を作成し、そのセッションオブジェクトを使ってREST APIへアクセスしています。

https://docs.snowflake.com/en/developer-guide/external-network-access/secret-api-reference#python-api-for-secret-access

3. 回答結果の確認

上記コードを実行し、以下のようにCortex Analystの回答が得られることを確認しました。

Cortex Analystの回答例

最後に

Cortex AnalystのREST APIをSnowflake外から呼び出す例をご紹介しました。今回は単発の質問の例ですが、マルチターンの質問については以下の実装例も参考にしてください。

https://dev.classmethod.jp/articles/snowflake-cortex-analyst-try-multi-turn-conversation/

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.