翻訳者 |李睿 レビュー | Chonglou 今日では、 ChatGPTのような生成AI技術のおかげで、簡単な文章でデータセットをクエリすることが非常に簡単になりました。 ほとんどの生成 AI と同様に、 OpenAIによって開発されたAPI の結果はまだ不完全であり、ユーザーはそれを完全に信頼することはできません。幸いなことに、ユーザーはGPT に応答の計算方法を問い合わせるコードを記述できるようになり、このアプローチを採用すれば、ユーザー自身でコードを実行できます。つまり、ユーザーは自然言語を使用してChatGPT に質問することができ、 「昨年の地域別の製品の総売上高はいくらでしたか?」など、 ChatGPT の回答が正確であると確信できます。 GPT を使用してデータベースの自然言語クエリを設定するための簡単で簡単な方法を次に示します。 - データの構造、複数のサンプル行、またはその両方を 1 つのテキスト文字列にまとめます。
- この情報は、自然言語で提示された質問とともに、 GPTの「ヒント」を作成するために使用されます。
- プロンプトはOpenAIのGPT-3.5-turbo APIに送信され、質問に答えるためにSQLクエリが要求されます。
- データセットに返された SQL を実行して答えを計算します。
- (オプション) データセットを簡単にクエリできる対話型アプリケーションを作成します。
このアプローチには、実際のデータを扱うときにいくつかの利点があります。データ構造といくつかのサンプル行(偽のデータが含まれる場合があります)のみを送信すると、実際の機密データを GPT に送信する必要はありません。データサイズが大きすぎて GPT のサイズ制限を超える場合でも、心配する必要はありません。また、最終的な回答ではなく SQL を要求することで、GPT がどのように回答を生成したかを検査する機能がプロセスに組み込まれます。 エンタープライズクエリのための生成AI生成 AI を使用してエンタープライズ グレードのクエリを開発したい場合は、OpenAIのGPT だけでなく、さまざまな大規模言語モデル ( LLM )を操作するためのフレームワークである LangChain などのツールを検討することをお勧めします。 OpenAI は最近、クエリや同様のタスクをより簡単に、より信頼性の高いものにすることを目的として、API リクエストに関数呼び出しを含める可能性も発表しました。しかし、迅速なプロトタイピングや独自の使用の場合は、ここで説明するプロセスを使用すると簡単に始めることができます。ここでのデモンストレーションはRで行われていますが、この手法はどのプログラミング言語でも使用できます。 ステップ1 :サンプルデータを1文字の文字列に変換するこのステップのサンプル データには、データベース スキーマまたは数行のデータを含めることができます。これは GPT 3.5 に送信されるより大きなテキスト文字列クエリの一部となるため、すべてを 1 つの文字列に変換することが重要です。 データがすでに SQL データベース内にある場合、この手順は非常に簡単です。そうでない場合は、SQL クエリ可能な形式に変換することをお勧めします。なぜでしょうか? RおよびSQL コードの結果をテストした後、ユーザーはRコードよりも GPT によって生成された SQL コードに信頼を寄せました。 Rコードでは、sqldf パッケージを使用すると、R データ フレームに対して SQL クエリを実行できます。この例では、これが使用されています。 Python には sqldf と呼ばれる同様のライブラリもあります。パフォーマンスが重要な大規模データの場合は、duckdb プロジェクトを検討してください。 このデモでは、states.csv にある米国国勢調査の州人口データを含む CSV ファイルが使用されることに注意してください。 次のコードは、データ ファイルを R にインポートし、データ フレームが SQL データベース テーブルである場合に sqldf を使用して SQL スキーマを表示し、dplyr の filter() 関数を使用して 3 つのサンプル行を抽出し、スキーマとサンプル行の両方を文字列に変換します。免責事項: ChatGPT は、データを単一の文字列に変換するためのコードの基本 R apply() 部分を作成しました (通常、これらのタスクには purrr が使用されます)。 library(rio) library(dplyr) library(sqldf) library(glue) states <- rio::import("https://raw.githubusercontent.com/smach/SampleData/main/states.csv") |> filter(!is.na(Region)) states_schema <- sqldf("PRAGMA table_info(states)") states_schema_string <- paste(apply(states_schema, 1, paste, collapse = "\t"), collapse = "\n") states_sample <- dplyr::sample_n(states, 3) states_sample_string <- paste(apply(states_sample, 1, paste, collapse = "\t"), collapse = "\n") ステップ2 :大規模言語モデル(LM)のプロンプトを作成する形式は、「データ サイエンティストのように行動します。次のスキーマを持つ {table_name} という名前の SQLite テーブルがあります: ```{schema}``。最初の行は次のようになります: ```{rows_sample}``。このデータに基づいて、次の質問に回答する SQL クエリを作成します: {query}。説明ではなく、SQL のみを返します。」のようになります。 以下の関数は、この形式でクエリを作成し、データ スキーマ、サンプル行、ユーザー クエリ、およびテーブル名のパラメータを受け入れます。 create_prompt <- function(schema, rows_sample, query, table_name) { glue::glue("Act as if you're a data scientist. You have a SQLite table named {table_name} with the following schema: ``` {schema} ``` The first rows look like this: ```{rows_sample}``` Based on this data, write a SQL query to answer the following question: {query}. Return the SQL query ONLY. Do not include any additional explanation.") } ステップ3: OpenAIのAPIにデータを送信するユーザーはまずデータを切り取って OpenAI のWebインターフェースに貼り付け、その後 ChatGPT または OpenAI API で結果を表示できます。 ChatGPT は使用料はかかりませんが、ユーザーはその結果を調整することはできません。これにより、ユーザーは温度などのパラメータを設定できます。温度とは、応答がどの程度「ランダム」または創造的であるべきか、またサービスがどのようなモデルを使用するかを意味します。 SQL コードでは、温度を 0 に設定します。 次に、自然言語の質問を変数 my_query に保存し、create_prompt() 関数を使用してプロンプトを作成し、そのプロンプトを API プレイグラウンドに貼り付けると何が起こるかを確認します。 > my_query <- "What were the highest and lowest Population changes in 2020 by Division?" > my_prompt <- get_query(states_schema_string, states_sample_string, my_query, "states") > cat(my_prompt) Act as if you're a data scientist. You have a SQLite table named states with the following schema: ``` 0 State TEXT 0 NA 0 1 Pop_2000 INTEGER 0 NA 0 2 Pop_2010 INTEGER 0 NA 0 3 Pop_2020 INTEGER 0 NA 0 4 PctChange_2000 REAL 0 NA 0 5 PctChange_2010 REAL 0 NA 0 6 PctChange_2020 REAL 0 NA 0 7 State Code TEXT 0 NA 0 8 Region TEXT 0 NA 0 9 Division TEXT 0 NA 0 ``` The first rows look like this: ```Delaware 783600 897934 989948 17.6 14.6 10.2 DE South South Atlantic Montana 902195 989415 1084225 12.9 9.7 9.6 MT West Mountain Arizona 5130632 6392017 7151502 40.0 24.6 11.9 AZ West Mountain``` Based on this data, write a SQL query to answer the following question: What were the highest and lowest Population changes in 2020 by Division?. Return the SQL query ONLY. Do not include any additional explanation. OpenAI API プレイグラウンドと生成された SQL コードのプロンプト 提案された SQL を実行した結果は次のとおりです。 sqldf("SELECT Division, MAX(PctChange_2020) AS Highest_PctChange_2020, MIN(PctChange_2020) AS Lowest_PctChange_2020 FROM states GROUP BY Division;") Division Highest_PctChange_2020 Lowest_PctChange_2020 1 East North Central 4.7 -0.1 2 East South Central 8.9 -0.2 3 Middle Atlantic 5.7 2.4 4 Mountain 18.4 2.3 5 New England 7.4 0.9 6 Pacific 14.6 3.3 7 South Atlantic 14.6 -3.2 8 West North Central 15.8 2.8 9 West South Central 15.9 2.7 ChatGPT は正確な SQL を生成しただけでなく、「2020 年の人口変化」が Pop_2020 列にあることを GPT に伝える必要もありませんでした。 ステップ4: GPTから返されたSQLコードを実行するデータをWebインターフェースに切り取って貼り付けるよりも、プログラムで OpenAI に送信して返す方がはるかに便利です。 OpenAI API を使用できる R パッケージはいくつかあります。次のコード ブロックは、OpenAI パッケージを使用して API にプロンプトを送信し、API 応答を保存し、要求された SQL コードを含むテキストを含む応答の部分を抽出し、そのコードを出力し、データに対して SQL を実行します。 library(openai) my_results <- openai::create_chat_completion(model = "gpt-3.5-turbo", temperature = 0, messages = list( list(role = "user", content = my_prompt) )) the_answer <- my_results$choices$message.content cat(the_answer) SELECT Division, MAX(PctChange_2020) AS Highest_Population_Change, MIN(PctChange_2020) AS Lowest_Population_Change FROM states GROUP BY Division; sqldf(the_answer) Division Highest_Population_Change Lowest_Population_Change 1 East North Central 4.7 -0.1 2 East South Central 8.9 -0.2 3 Middle Atlantic 5.7 2.4 4 Mountain 18.4 2.3 5 New England 7.4 0.9 6 Pacific 14.6 3.3 7 South Atlantic 14.6 -3.2 8 West North Central 15.8 2.8 9 West South Central 15.9 ユーザーが OpenAI API を使用する場合は、OpenAI API キーが必要です。このパッケージの場合、キーは OPENAI_API_KEY などのシステム環境変数に保存する必要があります。この API は無料では使用できないことに注意してください。ただし、エディターにする前に、このプロジェクトを 1 日に 12 回実行し、アカウントの合計使用料は 1 セントでした。 ステップ5(オプション) :インタラクティブアプリケーションを作成するこれで、スクリプトまたはターミナルのいずれかで、R ワークフローでクエリを実行するために必要なすべてのコードが揃いました。ただし、簡単な言語でデータを照会するインタラクティブなアプリを作成したい場合は、使用できる基本的な Shiny アプリのコードが含まれています。 他のユーザーが使用できるようにアプリケーションを公開する予定の場合は、悪意のあるクエリを防ぐためにコードを強化し、より適切なエラー処理と説明ラベルを追加し、スタイルを改善し、エンタープライズでの使用向けに拡張する必要があります。 並行して、このコードは自然言語を使用してデータセットをクエリするインタラクティブなアプリケーションの作成を開始する必要があります。 library(shiny) library(openai) library(dplyr) library(sqldf) # Load hard-coded dataset states <- read.csv("states.csv") |> dplyr::filter(!is.na(Region) & Region != "") states_schema <- sqldf::sqldf("PRAGMA table_info(states)") states_schema_string <- paste(apply(states_schema, 1, paste, collapse = "\t"), collapse = "\n") states_sample <- dplyr::sample_n(states, 3) states_sample_string <- paste(apply(states_sample, 1, paste, collapse = "\t"), collapse = "\n") # Function to process user input get_prompt <- function(query, schema = states_schema_string, rows_sample = states_sample_string, table_name = "states") { my_prompt <- glue::glue("Act as if you're a data scientist. You have a SQLite table named {table_name} with the following schema: ``` {schema} ``` The first rows look like this: ```{rows_sample}``` Based on this data, write a SQL query to answer the following question: {query} Return the SQL query ONLY. Do not include any additional explanation.") print(my_prompt) return(my_prompt) } ui <- fluidPage( titlePanel("Query state database"), sidebarLayout( sidebarPanel( textInput("query", "Enter your query", placeholder = "eg, What is the total 2020 population by Region?"), actionButton("submit_btn", "Submit") ), mainPanel( uiOutput("the_sql"), br(), br(), verbatimTextOutput("results") ) ) ) server <- function(input, output) { # Create the prompt from the user query to send to GPT the_prompt <- eventReactive(input$submit_btn, { req(input$query, states_schema_string, states_sample_string) my_prompt <- get_prompt(query = input$query) }) # send prompt to GPT, get SQL, run SQL, print results observeEvent(input$submit_btn, { req(the_prompt()) # text to send to GPT # Send results to GPT and get response # withProgress adds a Shiny progress bar. Commas now needed after each statement withProgress(message = 'Getting results from GPT', value = 0, { # Add Shiny progress message my_results <- openai::create_chat_completion(model = "gpt-3.5-turbo", temperature = 0, messages = list( list(role = "user", content = the_prompt()) )) the_gpt_sql <- my_results$choices$message.content # print the SQL sql_html <- gsub("\n", "<br />", the_gpt_sql) sql_html <- paste0("<p>", sql_html, "</p>") # Run SQL on data to get results gpt_answer <- sqldf(the_gpt_sql) setProgress(value = 1, message = 'GPT results received') # Send msg to user that }) # Print SQL and results output$the_sql <- renderUI(HTML(sql_html)) if (is.vector(gpt_answer) ) { output$results <- renderPrint(gpt_answer) } else { output$results <- renderPrint({ print(gpt_answer) }) } }) } shinyApp(ui = ui, server = server) 原題: GPT を自然言語の SQL クエリ エンジンとして使用する方法、著者: Sharon Machlis |