langchain-embedding_search を使って Supabase を Vector Store として使う

2023/04/28に公開

先日(2023/4/24)の 第 41 回 PostgreSQL アンカンファレンス @ オンライン で話したネタです。

https://pgunconf.connpass.com/event/278329/

PostgreSQL パッケージマネージャー dbdev を使って Supabaselangchain-embedding_search を導入し、Supabase を Vector Store として使ってみます。

dbdev とは?

PostgreSQL の拡張機能や SQL 集を管理するパッケージマネージャーとして Supabase が提供するものです。

https://database.dev/

Supabase のブログ記事 には以下のような記述があります。

  • (2023/4/14 現在)パブリックプレビュー中
  • PostgreSQL において、JavaScript にとってのnpmや Python にとってのpip、Rust にとってのcargoの役割を目指している
  • バージョニング・名前空間の管理機能を持つ

langchain-embedding_search とは?

Supabase の DB(PostgreSQL)を Vector Store として使うためのパッケージです。

https://database.dev/langchain/embedding_search

Vector Store は、

  • ベクトル化した文書を保存し
  • LLM(大規模言語モデル)のプロンプトに文脈を与える際に関連文書を検索・抽出する

目的で使うデータストアです。

langchain-embedding_search では、拡張機能 pgvector を用いて、

  • ベクトル型の列を持つdocumentsテーブル
  • コサイン類似度を使って関連文書を検索するmatch_documentsストアドファンクション

を Supabase プロジェクト上に生成します。

使ってみる

Supabase プロジェクト作成

新規のプロジェクトを作成するか、既存プロジェクトの環境を最新にして、最新の拡張機能が使える状態にします。

dbdev 有効化

「SQL Editor」こちらのページに書かれている SQL 文をそのまま実行します。

pgvector 有効化

同じく 「SQL Editor」 で次の SQL 文を実行します。

pgvector有効化
create extension if not exists vector;

langchain-embedding_search インストール・有効化

さらに 「SQL Editor」 で次の SQL 文を実行します。

langchain-embedding_searchインストール・有効化
select dbdev.install('langchain-embedding_search');
create extension "langchain-embedding_search"
    version '1.0.0';
  • documentsテーブル
  • match_documentsストアドファンクション

が生成されます。

Supabase プロジェクトの URL と匿名(anon)キーを確認

「API Settings」「Project URL」「Project API keys」anonpublicキーを確認しておきます。

OpenAI API キーを発行・確認

OpenAI API keys からキーを発行し確認しておきます。

サンプルコードを取得

こちらの GitHub リポジトリ にサンプルコードを用意しておきました。

https://github.com/hmatsu47/dbdev-langchain-test

手元に clone 後npm installします。

その後、clone したディレクトリ直下に.envファイルを作成し、Supabase のプロジェクト URL / 匿名キーと OpenAI の API キーを記述します。

.env
VITE_SUPABASE_URL=【SupabaseのプロジェクトURL】
VITE_SUPABASE_ANON_KEY=【Supabaseのプロジェクトanon key】
VITE_OPENAI_KEY=【OpenAIのAPI key】

起動

npm run devで起動します。

テストデータ投入

curl -X POST -H 'Content-Type: application/json; charset=UTF-8' http://localhost:【起動ポート番号】 -d '{"contents":【ドキュメント配列】, "metadata":【メタデータ配列】}' で投入できます。 -d @【投入するファイルのパス】 も可能です。

こちらのテストデータcurlで投入します。

https://github.com/hmatsu47/dbdev-langchain-test/blob/master/test-data.json

テストデータ投入
% curl -X POST -H 'Content-Type: application/json; charset=UTF-8' http://localhost:3699 -d @./test-data.json
{"message":"OK"}%

検索

curl http://localhost:【起動ポート番号】/【検索キーワード】/【結果の最大数】 で検索が可能です。

実際に検索してみます。

検索1
% curl http://localhost:3699/初心者/2 | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   966  100   966    0     0    841      0  0:00:01  0:00:01 --:--:--   845
[
  {
    "pageContent": "本書はデータベース初心者およびPostgreSQL初心者向けの入門書です。データベースとは何か?からPostgreSQLのインストール、SQLの実行、トランザクションについて、レプリケーション、バックアップまでを解説しています。",
    "metadata": {
      "title": "データベース初心者のためのPostgreSQL教室",
      "author": [
        "目黒 聖"
      ]
    }
  },
  {
    "pageContent": "本書は,データベース初学者を対象にPostgreSQLを使って,データベース操作の基本から運用までを学ぶための本です。付属DVD収録のファイルを利用することで,自宅のWindowsパソコンやMacで実際にデータの検索や更新などを行いながら,PostgreSQLによるリレーショナルデータベースの操作をマスターすることができます。",
    "metadata": {
      "title": "これからはじめる PostgreSQL入門",
      "author": [
        "高塚 遙",
        "桑村 潤"
      ]
    }
  }
]
検索2
% curl http://localhost:3699/辛い/1 | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   914  100   914    0     0    444      0  0:00:02  0:00:02 --:--:--   445
[
  {
    "pageContent": "「データベースがよく落ちる」「前任者が残したテーブル,SQLが読み解けない」「RDBMSを入れ替えたら予期せぬバグが」――MySQLやPostgreSQLといったRDBMS(リレーショナルデータベース管理システム)を使った業務システム,Webサービスを設計・運用していると,こういった問題によく直面するのではないでしょうか。本書はRDB(リレーショナルデータベース)の間違った使い方(=アンチパターン)を紹介しながら,アンチパターンを生まないためのノウハウを解説します。それぞれの章では,問題解決に必要なRDBやSQLの基礎知識も押さえるので,最近RDBMSを触り始めた新人の方にもお勧めです。",
    "metadata": {
      "title": "失敗から学ぶ RDBの正しい歩き方",
      "author": [
        "曽根壮大"
      ]
    }
  }
]

まあまあそれっぽい検索結果が出ていますね。

注意

  • Node.js v16 では動きません。fetchを(試験的に)サポートする Node.js v18 以降で実行してください。
  • 全体的に入力値チェックなどは実装していません。

参考

LangChain JS/TS Docs Supabase

https://js.langchain.com/docs/modules/indexes/vector_stores/integrations/supabase

LangChain Python Docs SupabaseVectorStore

https://python.langchain.com/en/latest/modules/indexes/vectorstores/examples/supabase.html

サンプルコード(app.ts)全体

https://github.com/hmatsu47/dbdev-langchain-test/blob/master/app.ts

その他

文書ベクトルと全文検索を併用する langchain-hybrid_search もあります。

https://database.dev/langchain/hybrid_search
https://js.langchain.com/docs/modules/indexes/retrievers/supabase-hybrid

GitHubで編集を提案

Discussion