こちらのサンプルをウォークスルーします。
注意
AI Functionsはパブリックプレビューです。こちらからパブリックプレビューにサインアップください。
デモのインストール
%pip install dbdemos
import dbdemos
dbdemos.install('sql-ai-functions')
上を実行すると、ノートブックとクラスターが作成されます。クラスターが不要であれば停止、削除ください。
概要はこちらで説明されています。
(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シークレットとしてキーを保存
前提条件
このデモをご自身の環境で実行するには、以下の条件を満たす必要があります:
- パブリックプレビューへの参加。こちらから参加登録してください。
- Databricks SQLのProあるいはServerlessウェアハウスへのアクセス
- Azure OpenAI key
- Databricks SecretsにAPIキーを格納 (documentation: AWS, Azure, GCP).
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)
呼び出しをシンプルにするためのラッパー関数の追加
すべてのパラメーターを指定する必要があると、特にシークレット管理ではなく適切なプロンプトの作成にフォーカスすべきデータアナリストにとっては使いにくいものになります。
デモの次のステップをシンプルにするために、入力パラメーターとしての文字列を持ち、すべてのモデル設定をラッピングするラッパー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"""))
プロンプトエンジニアリングによるより完全なサンプルデータセットの生成
これで、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として変換
結果は良さそうです。次にやるべきことの全ては、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))"""))
デモで直接使用できるテーブルとしてデータセットを保存
より多くの行を作成したい場合には、最初にテーブルを作成して、カテゴリーや期待される顧客満足度のようなプロンプトに追加できる追加情報を用いて複数行を追加します。テーブルを作成したら、より多くのパラメーターを受け取り、より高度なプロンプトを作成する新たなカスタムの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"""))
ユーザーも作成されました。
(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)"""))
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"""))
# お客様の不平に基づいたお客様へのレスポンスを生成
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'])
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"""))
レビューの感情、フォローアップの要否、レスポンスのドラフトまで生成されています。
エクストラ: アドホッククエリー
アナリストは、データに自信のプロンプトを適用するために、常に以前作成した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"""))
Unity Catalogでの関数のサポート
先日のアップデートで、データエクスプローラから関数も確認できるようになっています。これも嬉しい。
まとめ
AI Functionsを活用することで、SQLの中に簡単にLLMの能力を埋め込むことでき、アプリケーション構築が捗ると思います。是非こちらからパブリックプレビューにサインアップください!