LoginSignup
4
0

こちらのサンプルをウォークスルーします。

注意
AI Functionsはパブリックプレビューです。こちらからパブリックプレビューにサインアップください。

デモのインストール

%pip install dbdemos
import dbdemos
dbdemos.install('sql-ai-functions')

Screenshot 2023-07-18 at 14.52.14.png

上を実行すると、ノートブックとクラスターが作成されます。クラスターが不要であれば停止、削除ください。

概要はこちらで説明されています。

(1) Databricks SQLのAI Functionsを用いた大規模顧客レビューに対するアクション

AI FunctionsはビルトインのDatabricks SQL関数であり、SQLから直接大規模言語モデル(LLM)にアクセスできるようになります。

OpenAI APIによって提供されるような人気のLLMを用いることで、分類、情報抽出、自動回答などテキストに対してあらゆる種類の変換処理を適用することができます。

Databricks SQLのAI functionsであるAI_GENERATE_TEXT()を活用することで、馴染みのあるSQLインタフェースからお使いのデータに対してLLMを用いて、これらの変換処理や実験を適用できるようになります。

適切なLLMプロンプトを作成した後は、Delta Live Tablesやスケジュールジョブのような既存のDatabricksツールを用いて、クイックにプロダクションパイプラインにすることができます。これは、LLMの開発とプロダクション化の両方を非常にシンプルなものにします。

AI FunctionsはLLM呼び出しの技術的な複雑性を抽象化し、アナリストやデータサイエンティストは背後のインフラストラクチャを心配することなしに、これらのモデルを活用し始めることができます。

自動レビュー分析による顧客満足度の向上と、解約率削減

このデモでは、フリーフォームテキスト形式の顧客レビューを受け取り、Azure OpenAIのGPT-3.5 Turboモデルに自然言語の質問をすることで導き出される意味を用いてそれらを補強します。我々のカスタマーサービスチームに対して、ネクストベストアクションとなるレコメンデーションまでも提供します。例えば、顧客にフォローアップが必要かどうかや、フォローアップで用いるサンプルメッセージです。

それぞれのレビューに対して:

  • 感情を特定し、顧客に対するレスポンスが必要かどうかを特定します。
  • 顧客を満足させるであろう代替製品を説明するレスポンスを生成します。

1. セットアップ: Open AI設定を取得し、Databricksシークレットとしてキーを保存

前提条件

このデモをご自身の環境で実行するには、以下の条件を満たす必要があります:

Open AIのセットアップ

AI_GENERATE_TEXT()を用いてご自身でAzure OpenAIモデルを呼び出すためには、お使いのAzure OpenAIリソースエンドポイントに対するキーを提供しなくてはなりません。この情報をどのように取得し、Databricksシークレットにセキュアに格納する方法を見ていきます。

ご自身のOpen AIサービスをどのようにセットアップし、設定を取得するのかに関しては、ノートブック02-Create-OpenAI-model-and-store-secretsを開いてください。

2. AI_GENERATE_TEXT のご紹介: Open AIを用いてデモのためのフェイクデータを生成

デモをスタートするには、我々のデータパイプラインで使用するフェイクのレビューを生成するために AI_GENERATE_TEXT() を活用します。

このサンプルデータは、eコマースウェブサイトに送信された雑貨製品の顧客レビューを真似ており、我々のデータを生成するようにOpen AIのプロンプトを作成します。

最初のSQL AI Functionをスタートするには03-Generate-fake-data-with-AI-functionsを開いてください!

3. レビューの感情を抽出するためのOpen AIを用いたSQLパイプラインの構築

我々の完全なデータパイプラインを構築する準備が整いました:

SQLを用いてテキストを処理し、レビュー回答を自動化するには04-automated-product-review-and-answerを開いてください!

(2) SQL AI Functionのご紹介: Open AI APIからのフェイクデータの生成

ノートブック03-Generate-fake-data-with-AI-functionsを開いてください。

このデモは、AI_GENERATE_TEXT()を用いたフェイクデータの生成からスタートします。

サンプルデータは、eコマースウェブサイトに送信された雑貨製品の顧客レビューを真似ます。

AI_GENERATE_TEXT 関数の操作

この関数のシグネチャは以下の通りです:

SELECT AI_GENERATE_TEXT(<Open AIモデルに送信するプロンプト>,
                        "azure_openai/gpt-35-turbo",
                        "apiKey", <SECRET>,
                        "temperature", <TEMPERATURE>,
                        "deploymentName", <Azureデプロイメント名>,
                        "resourceName", <Azureリソース名>)

AI_GENERATE_TEXT は設定されたリモートモデルにプロンプトを送信し、SQLとして結果を取得します。

使い方を見ていきましょう。以下のコマンドを実行する際には、適宜カタログ名とデータベース名を変更してください。

%run ./_resources/00-init $catalog=quickstart_catalog_taka $db=ai_functions

はじめてのSQL AI function

シンプルなSQL AI functionからトライしましょう。Open AIに小売り商品レビューのテキストを生成するに用に頼みます。

現時点ではSQL AI functionsはDatabricks SQL ProあるいはServerless warehouseでのみ動作し、インタラクティブクラスターを用いたノートブックでは動作しないことに注意してください。

このデモをナビゲートしやすくするために、このデモのために作成したSQL PROエンドポイントにSQLクエリーを送信するために、DatabricksのSQL Statement APIを活用します。

(あるいは、実際に動かすために Databricks SQL Editorを用いて新規クエリーにSQLコードをコピー/ペースすることができます。)

# 関連ノートブックをご覧ください
sql_api = SQLStatementAPI(warehouse_name = "Shared Endpoint", catalog = catalog, schema = dbName)

# プロンプト: 赤いドレスに対する短い製品レビューを生成してください。お客様は商品に対して非常にハッピーです。
df = sql_api.execute_sql("""
SELECT AI_GENERATE_TEXT("Generate a short product review for a red dress. The customer is very happy with the article.",
                        "openai/gpt-3.5-turbo",
                        "apiKey", SECRET("demo-token-takaaki.yayoi", "openai_api_key"),
                        "temperature", CAST(0.0 AS DOUBLE)) as product_review""")
display(df)

レビューが生成されました。
Screenshot 2023-07-18 at 14.58.53.png

呼び出しをシンプルにするためのラッパー関数の追加

すべてのパラメーターを指定する必要があると、特にシークレット管理ではなく適切なプロンプトの作成にフォーカスすべきデータアナリストにとっては使いにくいものになります。

デモの次のステップをシンプルにするために、入力パラメーターとしての文字列を持ち、すべてのモデル設定をラッピングするラッパーSQL関数ASK_OPEN_AIを作成します。

SQL管理者がラッパー関数をセットアップ

sql_api.execute_sql(
    """CREATE OR REPLACE FUNCTION ASK_OPEN_AI(prompt STRING)
                                RETURNS STRING
                                RETURN 
                                  AI_GENERATE_TEXT(prompt,
                                                   "openai/gpt-3.5-turbo",
                                                   "apiKey", SECRET("demo-token-takaaki.yayoi", "openai_api_key"),
                                                   "temperature", CAST(0.0 AS DOUBLE))"""
)

SQLアナリストはシンプルにラッパーを活用

display(sql_api.execute_sql("""SELECT ASK_OPEN_AI("Generate a short product review for a red dress. The customer is very happy with the article.") as product_review"""))

Screenshot 2023-07-18 at 15.00.21.png

プロンプトエンジニアリングによるより完全なサンプルデータセットの生成

これで、SQL関数を用いてOpen AIに基本的なクエリーを送信できることを理解したので、より詳細な質問をモデルにしてみましょう。

直接モデルに複数行を生成し、jsonとして直接返却するように依頼します。

こちらが、JSONを生成するプロンプトの例です:

Generate a sample dataset for me of 2 rows that contains the following columns: "date" (random dates in 2022), 
"review_id" (random id), "product_name" (use popular grocery product brands), and "review". Reviews should mimic useful product reviews 
left on an e-commerce marketplace website. 

The reviews should vary in length (shortest: one sentence, longest: 2 paragraphs), sentiment, and complexity. A very complex review 
would talk about multiple topics (entities) about the product with varying sentiment per topic. Provide a mix of positive, negative, 
and neutral reviews

Return JSON ONLY. No other text outside the JSON. JSON format:
[{"review_date":<date>, "review_id":<review_id>, "product_name":<product_name>, "review":<review>}]

翻訳

以下のカラムを持つ2行のサンプルデータセットを生成してください: "date" (2022年のランダムな日付)、"review_id" (ランダムなID)、"product_name" (人気の雑貨商品ブランドを使ってください)、"review"です。レビューでは、eコマースマーケットプレースのウェブサイトに残された有用な製品レビューを真似てください。

レビューでは、長さ(最短: 1文、最長: 2段落)、感情、複雑度に違いを出してください。非常に複雑なレビューでは、トピックごとに感情が異なる製品に関する複数のトピック(エンティティ)について話してください。ポジティブ、ネガティブ、中立なレビューを混ぜて提供してください。

JSONのみを返却してください。JSON以外のテキストは不要です。JSONのフォーマット:
[{"review_date":<date>, "review_id":<review_id>, "product_name":<product_name>, "review":<review>}]
fake_reviews = sql_api.execute_sql("""
SELECT ASK_OPEN_AI(
      'Generate a sample dataset of 2 rows that contains the following columns: "date" (random dates in 2022), 
      "review_id" (random id), "customer_id" (random long from 1 to 100)  and "review". Reviews should mimic useful product reviews 
      left on an e-commerce marketplace website. 
      
      The reviews should be about a popular grocery brands product

      The reviews should vary in length (shortest: one sentence, longest: 2 paragraphs), sentiment, and complexity. A very complex review 
      would talk about multiple topics (entities) about the product with varying sentiment per topic. Provide a mix of positive, negative, 
      and neutral reviews.

      Give me JSON only. No text outside JSON. No explanations or notes
      [{"review_date":<date>, "review_id":<long>, "customer_id":<long>, "review":<string>}]') as reviews""")
display(fake_reviews)

JSONが返ってきます。
Screenshot 2023-07-18 at 15.01.05.png

結果をjsonとして変換

結果は良さそうです。次にやるべきことの全ては、JSONとしてのテキストから結果を変換し、N行に渡って結果をexplodeすることです。

これを行う新たな関数を作成しましょう:

fake_reviews = sql_api.execute_sql("""
CREATE OR REPLACE FUNCTION GENERATE_FAKE_REVIEWS(num_reviews INT DEFAULT 5)
RETURNS array<struct<review_date:date, review_id:long, customer_id:long, review:string>>
RETURN 
SELECT FROM_JSON(
    ASK_OPEN_AI(
      CONCAT('Generate a sample dataset of ', num_reviews, ' rows that contains the following columns: "date" (random dates in 2022), 
      "review_id" (random long), "customer_id" (random long from 1 to 100) and "review". 
      Reviews should mimic useful product reviews from popular grocery brands product left on an e-commerce marketplace website. The review must include the product name.

      The reviews should vary in length (shortest: 5 sentence, longest: 10 sentences).
      Provide a mix of positive, negative, and neutral reviews but mostly negative.

      Give me JSON only. No text outside JSON. No explanations or notes
      [{"review_date":<date>, "review_id":<long>, "customer_id":<long>, "review":<string>}]')), 
      "array<struct<review_date:date, review_id:long, customer_id:long, review:string>>")""")

jsonの結果をテーブルとしてexplode

display(sql_api.execute_sql("""SELECT review.* FROM (
                                SELECT explode(reviews) as review FROM (
                                  SELECT GENERATE_FAKE_REVIEWS(10) as reviews))"""))

テーブルになりました。
Screenshot 2023-07-18 at 15.02.14.png

デモで直接使用できるテーブルとしてデータセットを保存

より多くの行を作成したい場合には、最初にテーブルを作成して、カテゴリーや期待される顧客満足度のようなプロンプトに追加できる追加情報を用いて複数行を追加します。テーブルを作成したら、より多くのパラメーターを受け取り、より高度なプロンプトを作成する新たなカスタムのGENERATE関数を作成することに注意してください。

新規テーブルとして作成したレビューを保存

sql_api.execute_sql("""
CREATE OR REPLACE TABLE quickstart_catalog_taka.ai_functions.fake_reviews
COMMENT "Raw Review Data"
AS
SELECT review.* FROM (
  SELECT explode(reviews) as review FROM (
    SELECT GENERATE_FAKE_REVIEWS(10) as reviews))""")

さらに、同じアイデアを用いて複数のユーザーを作成しましょう

fake_reviews = sql_api.execute_sql("""
CREATE OR REPLACE FUNCTION GENERATE_FAKE_CUSTOMERS(num_reviews INT DEFAULT 10)
RETURNS array<struct<customer_id:long, firstname:string, lastname:string, order_count:int>>
RETURN 
SELECT FROM_JSON(
    ASK_OPEN_AI(
      CONCAT('Generate a sample dataset of ', num_reviews, ' customers containing the following columns: 
      "customer_id" (long from 1 to ', num_reviews, '), "firstname", "lastname" and order_count (random positive number, smaller than 200)

      Give me JSON only. No text outside JSON. No explanations or notes
      [{"customer_id":<long>, "firstname":<string>, "lastname":<string>, "order_count":<int>}]')), 
      "array<struct<customer_id:long, firstname:string, lastname:string, order_count:int>>")""")

sql_api.execute_sql("""
CREATE OR REPLACE TABLE quickstart_catalog_taka.ai_functions.fake_customers
COMMENT "Raw customers"
AS
SELECT customer.* FROM (
  SELECT explode(customers) as customer FROM (
    SELECT GENERATE_FAKE_CUSTOMERS(10) as customers))""")

display(sql_api.execute_sql("""SELECT * FROM quickstart_catalog_taka.ai_functions.fake_customers"""))

ユーザーも作成されました。

Screenshot 2023-07-18 at 15.03.23.png

(3) SQL functionsを用いた自動製品レビューと分類

04-automated-product-review-and-answerをオープンします。

このデモでは、製品レビュー情報を抽出するパイプラインを作成するために、SQL AI関数AI_GENERATE_TEXTを活用します。

SQLユーザーのAI関数へのアクセスをシンプルに

振り返りですが、AI_GENERATE_TEXTのシグネチャは以下の通りです:

SELECT AI_GENERATE_TEXT(<Open AIモデルに送信するプロンプト>,
                        "azure_openai/gpt-35-turbo",
                        "apiKey", <SECRET>,
                        "temperature", <TEMPERATURE>,
                        "deploymentName", <Azureデプロイメント名>,
                        "resourceName", <Azureリソース名>)

前回のノートブックで、エンドユーザーのSQLオペレーションをシンプルにし、設定詳細を隠蔽するために、ラッパーのASK_OPEN_AI関数を作成しました。このパイプラインでもこの関数を再利用します。

我々のアナリストのユーザー体験をシンプルにするために、データに対する自然言語の質問を尋ね、構造化データとしてレスポンスを返却するSQL関数を処方します。

以下のコマンドを実行する前に、適宜カタログ名とデータベース名を変更してください。

%run ./_resources/00-init $catalog=quickstart_catalog_taka $db=ai_functions

生データの確認

# 添付ノートブックをご覧ください
sql_api = SQLStatementAPI(warehouse_name = "Shared Endpoint", catalog = catalog, schema = dbName)

display(sql_api.execute_sql("""SELECT * FROM quickstart_catalog_taka.ai_functions.fake_reviews INNER JOIN quickstart_catalog_taka.ai_functions.fake_customers using (customer_id)"""))

Screenshot 2023-07-18 at 15.05.23.png

Open AIプロンプトエンジニアリングによるレビュー分析

GPTモデルから有用な結果を得る際に鍵となるのは:

  • 適切な形式の質問で尋ねる
  • 期待する回答のタイプに対して具体的になる

テーブルに容易に格納できる形式で結果を受け取るために、JSON表現を反映する文字列で結果を返却するようにモデルに依頼し、期待するスキーマに対して非常に具体的になります。

我々が落ち着いたプロンプトは以下の通りです:

A customer left a review on a product. We want to follow up with anyone who appears unhappy.
Extract all entities mentioned. For each entity:
- classify sentiment as ["POSITIVE","NEUTRAL","NEGATIVE"]
- whether customer requires a follow-up: Y or N
- reason for requiring followup

Return JSON ONLY. No other text outside the JSON. JSON format:
[{
    "product_name": <product name>,
    "category": <product category>,
    "sentiment": <review sentiment, one of ["POSITIVE","NEUTRAL","NEGATIVE"]>,
    "followup": <Y or N for follow up>,
    "followup_reason": <reason for followup>
}]

Review:
<insert review text here>

翻訳

お客様は製品のレビューを残しました。ハッピーではないように見える皆様をフォローアップしたいと考えています。
言及されたすべてのエンティティを抽出してください。それぞれのエンティティについて:
- 感情を ["POSITIVE","NEUTRAL","NEGATIVE"] として文流してください。
- お客様にフォローアップが必要か: Y or N
- フォローアップが必要な理由

JSONのみを返してください。JSON以外のテキストは不要です。JSONフォーマット:
[{
    "product_name": <product name>,
    "category": <product category>,
    "sentiment": <review sentiment, one of ["POSITIVE","NEUTRAL","NEGATIVE"]>,
    "followup": <Y or N for follow up>,
    "followup_reason": <reason for followup>
}]

Review:
<insert review text here>

ANNOTATE関数の作成

sql_api.execute_sql("""
    CREATE OR REPLACE FUNCTION ANNOTATE_REVIEW(review STRING)
    RETURNS STRUCT<product_name: STRING, entity_sentiment: STRING, followup: STRING, followup_reason: STRING>
    RETURN FROM_JSON(
      ASK_OPEN_AI(CONCAT(
        'A customer left a review. We follow up with anyone who appears unhappy.
         extract the following information:
          - classify sentiment as ["POSITIVE","NEUTRAL","NEGATIVE"]
          - returns whether customer requires a follow-up: Y or N
          - if followup is required, explain what is the main reason

        Return JSON ONLY. No other text outside the JSON. JSON format:
        {
            "product_name": <entity name>,
            "entity_sentiment": <entity sentiment>,
            "followup": <Y or N for follow up>,
            "followup_reason": <reason for followup>
        }
        
        Review:', review)),
      "STRUCT<product_name: STRING, entity_sentiment: STRING, followup: STRING, followup_reason: STRING>")""")

すべてのレビュアーの情報を抽出

sql_api.execute_sql("""
  CREATE OR REPLACE TABLE quickstart_catalog_taka.ai_functions.reviews_annotated as 
    SELECT * EXCEPT (review_annotated), review_annotated.* FROM (
      SELECT *, ANNOTATE_REVIEW(review) AS review_annotated
        FROM quickstart_catalog_taka.ai_functions.fake_reviews LIMIT 10)
    INNER JOIN quickstart_catalog_taka.ai_functions.fake_customers using (customer_id)
    """)
display(sql_api.execute_sql("""SELECT * FROM quickstart_catalog_taka.ai_functions.reviews_annotated"""))

Screenshot 2023-07-18 at 15.06.33.png

# お客様の不平に基づいたお客様へのレスポンスを生成
sql_api.execute_sql("""
  CREATE OR REPLACE FUNCTION GENERATE_RESPONSE(firstname STRING, lastname STRING, article_this_year INT, product STRING, reason STRING)
  RETURNS STRING
  RETURN ASK_OPEN_AI(
    CONCAT("Our customer named ", firstname, " ", lastname, " who ordered ", article_this_year, " articles this year was unhappy about ", product, 
    "specifically due to ", reason, ". Provide an empathetic message I can send to my customer 
    including the offer to have a call with the relevant product manager to leave feedback. I want to win back their 
    favour and I do not want the customer to churn")
  )""")

# レスポンスをテストしましょう
r = sql_api.execute_sql("""SELECT GENERATE_RESPONSE("Quentin", "Ambard", 235, "Country Choice Snacking Cookies", "Quality issue") AS customer_response""")
display_answer(r.iloc[0]['customer_response'])

レスポンスが生成されました!
Screenshot 2023-07-18 at 15.06.58.png

sql_api.execute_sql("""
  CREATE OR REPLACE TABLE quickstart_catalog_taka.ai_functions.reviews_answer as 
    SELECT *,
      GENERATE_RESPONSE(firstname, lastname, order_count, product_name, followup_reason) AS response_draft
    FROM quickstart_catalog_taka.ai_functions.reviews_annotated where followup='Y'
    LIMIT 10""")
display(sql_api.execute_sql("""SELECT * FROM quickstart_catalog_taka.ai_functions.reviews_answer"""))

レビューの感情、フォローアップの要否、レスポンスのドラフトまで生成されています。
Screenshot 2023-07-18 at 15.08.04.png

エクストラ: アドホッククエリー

アナリストは、データに自信のプロンプトを適用するために、常に以前作成したASK_OPEN_AI()関数を活用できることを思い出してください。

短い例として、飲み物に関するすべてのレビューを抽出するクエリーを書いてみましょう:

# プロンプト: このレビューでは飲み物を論じていますか?ブール値で答えてください: 'true' or 'false' のみ、小文字、説明文、注記、最後のドットは不要です。レビュー: 
display(sql_api.execute_sql("""
  SELECT review_id,
    BOOLEAN(ASK_OPEN_AI(
      CONCAT("Does this review discuss beverages? Answer boolean: 'true' or 'false' only, lowercase, no explanations or notes nor final dot. Review: ", review)
    )) AS is_beverage_review,
    review
  FROM quickstart_catalog_taka.ai_functions.fake_reviews LIMIT 10"""))

Screenshot 2023-07-18 at 15.08.59.png

Unity Catalogでの関数のサポート

先日のアップデートで、データエクスプローラから関数も確認できるようになっています。これも嬉しい。
Screenshot 2023-07-18 at 15.10.22.png
Screenshot 2023-07-18 at 15.10.41.png

まとめ

AI Functionsを活用することで、SQLの中に簡単にLLMの能力を埋め込むことでき、アプリケーション構築が捗ると思います。是非こちらからパブリックプレビューにサインアップください!

Databricksクイックスタートガイド

Databricksクイックスタートガイド

Databricks無料トライアル

Databricks無料トライアル

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0