LoginSignup
2
0

More than 1 year has passed since last update.

Databricksのデータに SQLDatabaseChainを使ってSlackからアクセスしてみた

Last updated at Posted at 2023-06-27

はじめに

こちらの@taka_yayoi さんの記事にもありますが、LangchainのSQLDatabaseChainを使ってDatabricksの特定のデータに自然言語でアクセス出来るようになりました。

今回、こちらの仕組みをSlackから簡単にアクセスできるようにまとめましたので、皆様も是非トライしてみてください。

必要な環境

  • Databricks SQLWarehouse  
  • OpenAI API (Secret Keyが必要です)
  • Slack App
  • EC2 or Lamdaなど pythonコードが動作する環境。デモの場合はPCでも可能です。

コードやSlackAppのデプロイファイルなど

今回必要なコード類やこちらのgitに公開しております。まずはお手元にクローンしてください。
https://github.com/maroon-spec/slack_sqldb

設定手順

1. SlackAppの作成

今回はレポジトリの中にSlackAppのデプロイファイルを用意してありますので、そちらを利用します。

slack_app.yaml
display_information:
  name: Databricks-sql-bot
features:
  bot_user:
    display_name: databricks-sql
    always_online: true
oauth_config:
  scopes:
    bot:
      - chat:write
      - channels:history
      - groups:history
      - mpim:history
      - im:history
      - app_mentions:read
      - reactions:write
      - users:read
settings:
  event_subscriptions:
    bot_events:
      - app_mention
      - message.channels
      - message.groups
  org_deploy_enabled: false
  socket_mode_enabled: true
  token_rotation_enabled: false

[SlackApp]に移動して、Create New Appにて、From an app manifestを選択し、上記のyamlをコピーして貼り付けます。

Install Appに移動して、対象のワークスペースとAppを紐付けます。(以下はイメージ)

App Tokenを作成します。このTokenは後ほど利用します。
Basic information -> App-Levels Token. Scope: connections:write

最後にBot Tokenを取得します。
Install App -> Bot User OAuth Token取得

2. Slack上でAppが追加されているので、対象のChannelにBotを追加する.

チャンネル詳細 -> インテグレーション -> App追加

3. Pythonコード実行

最後に Pythonコードを実行します。今回はシンプルにPC上で実行します。
(他にLambda とAPI Gatewayを組み合わせたり、Publicアクセス可能なEC2上などで動作させると本番でも利用できます)

まずはvenvを作成し、いくつかのライブラリーをインストールします。

$ python -m venv .venv
$ source .venv/bin/activate
$ pip install -r requirements.txt

次にOS上に環境変数として以下をセットします。

OS環境変数
export DATABRICKS_HOST=""    # Databricks Workspace URL(https://は除く)
export DATABRICKS_TOKEN=""   # Personal Access Token
export DATABRICKS_WAREHOUSE=""   # SQL Warehouse ID (最後のID部分のみ)
export OPENAI_API_KEY=""     # OpenAI APIのSecret Key
export SLACK_BOT_TOKEN=""    # 先ほどのSlack BOT Token
export SLACK_APP_TOKEN=""    # 先ほどのSlack App Token 

実行するコードはこちらです。
コード内のカタログやスキーマ、テーブルを変更すると、対象となるテーブルを変更することができます。

app.py
import os
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from langchain import OpenAI, SQLDatabase, SQLDatabaseChain

#######################################################
## 今回検索対象とするカタログとスキーマを選択します。   #######
#######################################################

catalog = "samples"
schema = "nyctaxi" 
tables  = ["trips"] 
host = os.environ.get("DATABRICKS_HOST") 
warehouse_id = os.environ.get("DATABRICKS_WAREHOUSE") 
api_token = os.environ.get("DATABRICKS_TOKEN")

# LLM
llm = OpenAI(temperature=0, verbose=True)

## Langchain SQLDatabaseChain
db = SQLDatabase.from_databricks(catalog=catalog, 
                                 schema=schema, 
                                 include_tables=tables, 
                                 host = host, 
                                 warehouse_id=warehouse_id, 
                                 api_token=api_token)

db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)

#######################################################
# ここから Slack 設定
# トークンとソケットモードハンドラーを使ってアプリを初期化します
#######################################################

app = App(token=os.environ.get("SLACK_BOT_TOKEN")) 

# mentionされた場合メッセージを読み取ります
@app.event("app_mention")
def respond_to_mention(body, say):
    channel_id = body["event"]["channel"]
    user_id = body["event"]["user"]
    question = body["event"]["text"]

    response = db_chain.run(question)

    # Craft your response message
    message = f"Answer: {response}"

    # Send the response message
    say(message, channel=channel_id)

# アプリを起動します
if __name__ == "__main__":
    SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start()

実行します。

$ python app.py

設定は以上です。

試してみる

今回は、MentionでBotに問い合わせると、指定したテーブルに対して、自然言語で問い合わせできます。

例えば、どんなデータがあるか聞いてみます。(英語で帰ってきたので言語を指定しました)
image.png

次に、fare_amountというカラムがあったので、「運賃の平均金額は?」 と聞いてみると自動的に fare_amount と認識して平均値を出してくれます。
image.png

もう少し難しい、2つのカラムの時間差の平均時間を聞いてみました。
image.png

実行しているシェルを見てみると、裏ではSQLに変換して正しい問い合わせをしてくれてます。
image.png

Slack以外にも色々なインターフェースと組み合わせて利用できます。
対象となるテーブルはUnity CatalogのACLでRead権限のみを許可した方がいいです。MergeやDropもできてしまいます。DatabricksのService PrincipalなどでRead権限などを許可されたトークンを発行すると良いと思います。

2
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
2
0