テキスト間テクノロジーは、ユーザーの要求の完全なコンテキストと意味をキャプチャするのに頻繁に苦労しており、意図したものと正確に一致しないクエリをもたらします。開発者はこれらのシステムを強化するために一生懸命働いていますが、より良い方法があるかどうか疑問に思う価値があります。
Rag-to-SQLを入力します。これは、自然言語の理解と強力なデータ取得を組み合わせて正確なSQLクエリを生成する新しいアプローチです。最高の自然言語処理と情報検索をブレンドすることにより、Rag-to-SQLは、日常の言語をデータベースから意味のある洞察に変えるためのより信頼性の高い方法を提供します。
この記事では、特にBigQueryやVertex AIなどのGoogleクラウドサービスを使用して、Rag-to-SQLがデータベースと対話する方法をどのように変換できるかを調べます。
この記事は、データサイエンスブログソンの一部として公開されました。
LLMのSQLモデルへのテキストの背後にある主なアイデアは、SQLについて知らない人がデータベースと対話し、代わりに自然言語を使用して情報を取得できるようにすることでした。既存のテキスト2 SQLフレームワークは、主にLLMの知識に依存して、自然言語クエリをSQLクエリに変換できるようにします。これにより、SQLクエリの間違ったまたは無効な定式化につながる可能性があります。これは、SQLへの新しいアプローチのぼろきれが救助に来る場所であり、次のセクションで説明されています。
テキストの欠点をSQLに克服するために、RAGの革新的なアプローチをSQLに使用できます。データベースに関するドメイン情報の統合は、各テキストからSQLへのソフトウェアが直面する主要な問題です。 RAG2SQLアーキテクチャは、コンテキストデータ(メタデータ、DDL、クエリなど)を追加することにより、この困難に対処します。このデータは「トレーニング」され、使用が可能になります。
さらに、「レトリーバー」は、最も関連性の高いコンテキストを評価および転送して、ユーザークエリに応答します。最終結果は、精度が大幅に改善されています。
詳細なガイドに従って、BigQueryやVertex AIなどのGoogleクラウドサービスを使用してRAG-to-SQLを実装してください。
このコードに従って実行するには、GCP(支払い情報を備えたGoogle Cloudアカウント)をセットアップする必要があります。当初、彼らは90日間無料の300ドルの試用を提供するため、料金は発生しません。アカウントセットアップの詳細:リンク
以下は、コードのさまざまなブロックをより高いレベルで説明するコードフローチャートです。続行すると、それを参照することができます。
コードの実装は、3つの主要なブロックに分けることができます。
Colabノートブックでは、この実装に必要な以下のライブラリをインストールする必要があります。
!ピップインストールlangchain == 0.0.340 -Quiet ! PIPインストールChromadb == 0.4.13 -Quiet ! PIPインストールGoogle-Cloud-BigQuery [Pandas] -Quiet ! PIPインストールGoogle-Cloud-aiplatform-quiet#Import csv
次に、GCPプロジェクトとビッグクエリデータセットを初期化するために、いくつかの変数を宣言する必要があります。この変数を使用して、ノートブックでGCPを使用してビッグクエリのテーブルにアクセスできます。
この詳細は、GCPクラウドコンソールで表示できます。 BigQueryでは、データセットを作成できます。データセット内でテーブルを追加またはアップロードして、詳細については、DataSetand Create Tableの作成を参照してください。
vertex_project = "あなたのGCPプロジェクトID"#@param {type: "string"} vertex_region = "us-central1"#@param {type: "string"} bigquery_dataset = "ビッグクエリデータセット名"#@param {type: "string"} bigquery_project = "vertexプロジェクトID"#@param {type: "string"}
次に、Colabの以下のコードを使用して、ノートブックからGCP Vertex AIに認証してログインします。
Google.Colab Import Authから auth.authenticate_user() Vertexaiをインポートします vertexai.init(project = vertex_project、location = vertex_region)
次に、データセットに存在するさまざまなテーブルのスキーマを含むベクトルDBを作成する必要があり、このベクトルDBの上にレトリバーを作成して、ワークフローにRAGを組み込むことができます。
PythonでBQクライアントを使用してビッグクエリに接続し、テーブルのスキーマを取得します。
Google.CloudからImport BigQueryから JSONをインポートします #テーブルの拡張スキーマ bq_client = bigquery.client(project = vertex_project) bq_tables = bq_client.list_tables(dataset = f "{bigquery_project}。{bigquery_dataset}") スキーマ= [] bq_tablesのbq_tableの場合: t = bq_client.get_table(f "{bigquery_project}。{bigquery_dataset}。{bq_table.table_id}") schema_fields = [f.to_api_repr()t.schemaのfの場合] schema = f "テーブルのスキーマ{bq_table.table_id}は次のとおりです。 schemas.append(スキーマ) print(f "found {len(schemas)} dataset {bigquery_project}:{bigquery_dataset}")#インポートCSV
スキーマをクロマDBなどのベクターDBに保存します。 「データ」と呼ばれるフォルダーを作成する必要があります
langchain.embeddingsからvertexaiembeddingsをインポートします langchain.vectorstoresからchromaをインポートします 埋め込み= vertexaiembedings() 試してください:#複製されたドキュメントを避けてください vector_store.delete_collection() を除外する: 印刷(「ベクターストアを掃除する必要はありません」) vector_store = chroma.from_texts(schemas、embedding = embeddings、persist_directory = '。/data') n_docs = len(vector_store.get()['ids']) retriever = vector_store.as_retriever(search_kwargs = {'k':2}) 印刷(f "ベクターストアには{n_docs}ドキュメントがあります")
3つの異なるチェーンの3つのLLMモデルをインスタンス化します。
最初のモデルは、ユーザー質問と同様のベクトルDBから取得されたユーザーの質問とテーブルスキーマに基づいてSQLクエリを生成する責任があるクエリモデルです。このためには、「CodeChat-Bison」を使用していますモデル 。このモデルは、異なるコーディング言語でコードを生成することを専門とするため、ユースケースに適しています。
他の2つのモデルは、「 Gemini-1.5-Flash-001 」であるChatvertexaiのデフォルトのLLMモデルです。これは、チャットとクイック応答のために最適化された最新のGeminiモデルです。
langchain.chat_modelsからChatvertexaiをインポートします langchain.llmsからVertexaiをインポートします query_model = chatvertexai(model_name = "codechat-bison"、max_output_tokens = 1000) relution_data_model = chatvertexai(max_output_tokens = 1000) agent_model = chatvertexai(max_output_tokens = 1024)
以下は、入力ユーザーの質問のSQLクエリを生成するために使用されるSQLプロンプトです。
SQL_PROMPT = "" "あなたはSQLおよびBigQueryの専門家です。 あなたの仕事は、SQLでBigQueryのクエリを作成することです。 次の段落には、クエリに使用されるテーブルのスキーマが含まれています。 JSON形式でエンコードされています。 {コンテクスト} 上記のテーブルを使用して、次のユーザー入力に対してBigQuery SQLクエリを作成します。 SQLクエリにはスキーマで言及されている列のみを使用します ユーザーとエージェントはこれまでにこの会話をしました: {chat_history} これらの制限に厳密に従ってください: -SQLコードのみを返します。 - バックテックやマークアップを追加しないでください。クエリを出力としてのみ書き込みます。他に何もありません。 - fromで、常にテーブルパスを使用して、 `{project}`をプロジェクトとして使用し、 `{dataset}` as datasetを使用します。 - 常に国の名前を完全な大文字に変換してください。たとえば、国が日本の場合は、クエリで日本を使用する必要があります。 ユーザー入力:{質問} SQLクエリ: "" "
次に、ユーザー質問入力の関連ドキュメントIEスキーマを取得する関数を定義します。
langchain.schema.vectorStoreからVectorStoreretrieverから def get_documents(retriever:vectorStoreretriever、質問:str) - > str: #最初のドキュメントのみを返します output = "" retriever.get_relevant_documents(quuctise)のdの場合: output = D.Page_Content output = "\ n" 返品出力
次に、LANGCHAIN Expression Language Syntaxを使用してLLMチェーンを定義します。注プロンプトを5つのプレースホルダー変数で定義し、後で2つのプレースホルダー変数プロジェクトとデータセットに記入して部分的なプロンプトを定義します。
オペレーターからItemgetterをインポートします from langchain.prompts Import prompttemplate langchain.schemaからインポートStroutputParserから prompt_template = prompttemplate( input_variables = ["context"、 "chat_history"、 "question"、 "project"、 "dataset"]、 テンプレート= sql_prompt) partial_prompt = prompt_template.partial(project = bigquery_project、 データセット= bigquery_dataset) #入力は{"input": "some_question"、 "chat_history": "history"のようになります} docs = {"context":lambda x:get_documents(retriver、x ['input'])} 質問= {"質問":itemgetter( "input")} chat_history = {"chat_history":itemgetter( "chat_history")} query_chain = docs |質問| chat_history | partial_prompt | query_model query = query_chain | stroutputparser()
Langchainのコールバックハンドラーを使用してチェーンをテストしましょう。これにより、チェーン実行の各ステップが詳細に表示されます。
langchain.callbacks.tracersからconsolecallbackhandlerをインポートします # 例 x = {"input": "スタートステーションがアトランティックアベニュー&フォートグリーンPL"からの最高の旅行期間 "、" chat_history ":" "} print(query.invoke(x、config = {'callbacks':[consolecallbackhandler()]}))))
上記のSQLチェーン出力を改良する必要があります。これにより、OUTPに他の変数も含まれるようにする必要があります。
langchain.output_parsersからImport ResponseSchema、structuredOutputParserから langchain.schema.runnable Import runnablelambdaから #チェーンの出力を拒否して、辞書形式の出力に他の変数を含める def _dict_to_json(x:dict) - > str: "` `\ n" json.dumps(x) "\ n```"を返します query_response_schema = [ ResponseSchema(name = "query"、description = "ユーザーの質問を解決するためのsql query。")、 ResponseSchema(name = "question"、description = "ユーザーから質問された質問。")、 ResponseSchema(name = "Context"、description = "Vectorストアから取得されたドキュメント") ] query_output_parser = structuredoutputparser.from_response_schemas(query_response_schema) query_output_json = docs |質問| {"query":query} | runnablelambda(_dict_to_json)| stroutputparser() query_output = query_output_json | query_output_parser
このチェーンを実行してみましょう。
# 例 x = {"input": "トップ2のスタートステーションを教えてください。旅行期間が最高でしたか?"、 "chat_history": ""} output = query_output.invoke(x)#出力は辞書になり、次のチェーンの入力になりました
上記では、洗練されたチェーンの出力がSQLクエリであることがわかります。
次に、上記で定義されたSQLクエリチェーンの出力を取得する次のチェーンを構築する必要があります。このチェーンは、以前のチェーンからSQLクエリを取得し、ビッグクエリで実行し、その結果を使用して適切なプロンプトを使用して応答を生成します。
relution_prompt = "" "あなたは大物の専門家です。また、CSVからデータを抽出する専門家でもあります。 次の段落では、クエリに使用されるテーブルのスキーマについて説明します。 JSON形式でエンコードされています。 {コンテクスト} ユーザーがこの質問をしました: {質問} 答えを見つけるために、次のSQLクエリがBigQueryで実行されました。 `` ` {Query} `` ` そのクエリの結果は、CSV形式の次の表でした。 `` ` {結果} `` ` これらの結果に基づいて、ユーザーの質問に対する簡単な答えを提供します。 これらの制限に厳密に従ってください: - 答えがどのように得られるかについて説明しないでください、答えを書くだけです。 - クエリの結果からのみ、回答に関連する値を抽出します。他のデータソースを使用しないでください。 - 答えを書いて、答えから質問を省略してください。これはチャットです。答えを提供してください。 - 結果で答えが見つからない場合は、データを構成しないでください。「答えが見つかりません」と言ってください。 "" "
Google.CloudからImport BigQueryから def get_bq_csv(bq_client:bigquery.client、query:str) - > str: cleaned_query = clean_query(query) df = bq_client.query(cleaned_query、location = "us")。to_dataframe() df.to_csvを返す(index = false) def clean_query(query:str): query = query.replace( "` `sql"、 "") cleaned_query = query.replace( "` `` "、" ") Cleaned_Queryを返します
2つの関数はClean_Queryです。これにより、アポストロフィやその他の不要な文字のSQLクエリがクリーニングされます。
#前のチェーンの出力を取得します query = {"query":itemgetter( "query")} Context = {"context":itemgetter( "context")} 質問= {"question":itemgetter( "question")} #cleaned_query = {"result":lambda x:clean_query(x ["query"])} query_result = {"result":lambda x:get_bq_csv(bq_client、x ["query"])} prompt = prompttemplate( input_variables = ["question"、 "query"、 "result"、 "context"]、 Template = rettren_prompt) run_bq_chain = context |質問|クエリ| query_result |プロンプト run_bq_result = run_bq_chain | relution_data_model | stroutputparser()
チェーンを実行してテストしましょう。
# 例 x = {"input": "トップ2のスタートステーションを教えてください。旅行期間が最高でしたか?"、 "chat_history": ""} final_response = run_bq_result.invoke(query_output.invoke(x)) print(final_response)
次に、エージェントチェーンである最終チェーンを構築します。ユーザーが質問をすると、SQLクエリツールを使用するか、直接回答するかどうかが決定されます。基本的に、ユーザーの問い合わせに答えるために完了する必要がある作業に応じて、ユーザークエリをさまざまなツールに送信します。
Agent_memory、エージェントプロンプト、ツールFuntionを定義します。
langchain.memoryからImport ConversationBufferWindowMemoryから agent_memory = conversationBufferWindowMemory( memory_key = "chat_history"、 k = 10、 return_messages = true)
agent_prompt = "" "あなたは非常に強力なアシスタントであり、BigQueryを使用して質問に答えることができます。 ツールuser_question_toolを呼び出して、BigQueryを使用して質問に答えることができます。 常にツールを使用して、質問に答えてください。コンテキストにチャット履歴を使用します。他の外部情報を使用しようとしないでください。 ユーザーが間違ったものを書いて、質問を任意のツールに渡す前にユーザーのスペルを修正することができると仮定します。 あなたがあなたの答えで使用したツールについては言及しないでください。 "" "
langchain.toolsインポートツールから langchain.callbacks.tracersからconsolecallbackhandlerをインポートします @道具 def user_question_tool(question) - > str: "" "BigQueryを使用してユーザーからの自然言語の質問に答えるのに役立つ。" "" config = {'callbacks':[consolecallbackhandler()]} config = {} メモリ= agent_memory.buffer_as_str.strip() 質問= {"input":question、 "chat_history":メモリ} query = query_output.invoke(question、config = config) print( "\ n \ n **************** \ n \ n") 印刷(query ['query']) print( "\ n \ n **************** \ n \ n") result = run_bq_result.invoke(query、config = config) return result.strip()
現在、エージェントのすべての主要なコンポーネントをまとめて、エージェントを初期化します。
langchain.agentsからImport AgentType、intiality_agent、agentexecutorから agent_kwgards = {"system_message":agent_prompt} agent_tools = [user_question_tool] agent_memory.clear() agent = initialize_agent( ツール= agent_tools、 llm = agent_model、 agent = agentType.Chat_Conversational_ReaCt_Description、 メモリ= agent_memory、 agent_kwgards = agent_kwgards、 max_iterations = 5、 Early_stopping_method = 'Generate'、 verbose = true)
今すぐエージェントを実行しましょう。
Q = "旅行期間が最も高いトップ2の開始ステーションを教えてください。" agent.invoke(q)
エージェントへのフォローアップの質問。
Q = "これらのステーション名のそれぞれの容量は何ですか?」 agent.invoke(q)
エージェントは、複雑な質問を正確に処理することができ、またチャット履歴に基づいたフォローアップ質問の正しい回答を生成し、別のテーブルを使用してシティバイクの容量情報を取得しました。
Rag-to-SQLアプローチは、コンテキストデータを組み込み、検索技術を活用することにより、従来のテキストからSQLモデルの制限に対処する際の大きな進歩を表しています。この方法論は、ベクトルデータベースから関連するスキーマ情報を取得することにより、クエリの精度を向上させ、より正確なSQL生成を可能にします。 BigQueryやVertex AIなどのGoogleクラウドサービス内でRAG-to-SQLを実装すると、実際のアプリケーションでのスケーラビリティと有効性が示されています。クエリ処理で意思決定プロセスを自動化することにより、Rag-to-SQLは、非技術的なユーザーが高精度を維持しながらデータベースとシームレスに対話するための新しい可能性を開きます。
A.いいえ。ただし、初めて登録している場合は300ドルのクレジットで90日間の試用期間を取得でき、アクセスするためのカードの詳細を提供するだけです。カードから控除されることはありません。300ドルのクレジットを超えて消費しているサービスを使用している場合でも、Googleはサービスを使用できるように支払いアカウントを有効にするように依頼します。したがって、金額の自動控除はありません。
Q2。 ragをSQLに使用することの重要な利点は何ですか?A.これにより、複数のテーブルを使用している場合、LLMに供給されるテーブルスキーマを自動化できます。一度にすべてのテーブルスキーマをフィードする必要はありません。ユーザークエリに基づいて、関連するテーブルスキーマをぼろからフェッチできます。したがって、従来のテキストに対する効率の向上SQLシステムへ。
Q3。 エージェントはこのユースケースにどのように役立つことができますか?A.全体的なチャットボットを構築している場合、SQLクエリツールを除いて他の多くのツールが必要になる場合があります。そのため、エージェントを活用して、Web検索、データベースSQLクエリツール、その他のRAGツール、APIツールを呼び出す機能などの複数のツールを提供できます。これにより、ユーザークエリに応答するために達成する必要があるタスクに基づいて、さまざまな種類のユーザークエリを処理できます。
この記事に示されているメディアは、Analytics Vidhyaが所有しておらず、著者の裁量で使用されています。
以上がGoogleクラウドのrag-to-sqlの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。