Redisで高速テキストランカーを構築する方法 ― PDF検索アプリ「Alexis」の実装ガイド
スマートフォンなしでは外出できない時代において、Googleは常に私たちのそばにあります。検索クエリを入力すれば、ほぼあらゆる疑問に対する答えが一瞬で手に入るのです。
検索エンジンとその無限の情報へのアクセスは日常生活に深く組み込まれ、多くの人がそれに強く依存しています。そして、検索体験を最適化するには、Googleなどの大手テック企業が設定した高い基準に応えるべく、クエリに対する回答を瞬時に取得できることが求められます。
わずかなラグや遅延もユーザー体験を損なってしまいます。そこで本記事で紹介するLaunchpadアプリ「Alexis」は、この課題を克服するためにRedisをメインデータベースとして採用しました。
開発者のBobby Donchev氏は、RedisAIとRediSearchの力を活かし、コーパスからクエリに対する情報を最大限の効率で取得する仕組みを実現しました。ユーザーはPDFをインデックス化し、シンプルなUIを使ってドキュメントから必要な情報を簡単に抽出できます。
Redisがなければ、検索プロセス全体が遅くなり、Alexisの機能そのものが損なわれてしまうでしょう。ここからは、Bobby氏がどのようにこのアプリケーションを構築したのかを見ていきます。
なお、本題に入る前に、Redis Launchpadには他にも素晴らしいアプリケーションが多数公開されているので、ぜひチェックしてみてください。
目次
- 何を作るのか?
- 必要なもの
- アーキテクチャ
- はじめ方
- データの保存方法
- データのアクセス方法
- 動作の仕組み
1. 何を作るのか?
今回構築するのは、検索クエリを最高速度で処理できる高性能なテキストランカーです。ユーザーはこのアプリケーションを使って、重要なPDFをインデックス化し、ドキュメントから簡単に回答を抽出できるようになります。
以降のセクションでは、時系列に沿って各ステップを解説し、アプリケーション構築に必要なコンポーネントを明確にしていきます。
2. 必要なもの
- RediSearch: インデックス作成、クエリ処理、全文検索エンジン
- RedisAI: 深層学習・機械学習モデルを実行し、データ管理とレイテンシ削減を実現
- Redis Streams: データ消費の管理
- NodeJS: ウェブブラウザ外でJavaScriptコードを実行するオープンソースのクロスプラットフォーム環境
- RedisJSON: ECMA-404(JSONデータ交換標準)をネイティブデータ型として実装
3. アーキテクチャ
検索者のクエリに対して回答を提供する流れは、大きく2つのステップで構成されます。
- まず、回答を含む可能性が高いテキストを選択します。このステップでは、BM25ランキング関数を使用したRediSearchを活用します。
- 次に、RedisAIにロードしたTransformer AIモデルを使って、テキスト内の回答範囲(アンサースパン)を特定します。
最初のステップでRediSearchを使用することで、検索対象の範囲を大幅に絞り込めます。これにより、アプリ全体のレスポンスが高速化されます。その後、バックエンドにはTypeScriptを使用したNodeJS、フロントエンドにはTypeScriptを使用したReactを採用します。
さらに、RedisAIとRediSearchに加えて、ユーザーモデルにはRedisJSONを、非同期ワーカーの実装にはRedis Streamsを活用します。
ウェブサーバーはExpressフレームワークで公開され、以下のようなエンドポイントを持ちます。
アプリに登録してログインすると、インデックス化されたライブラリにドキュメントを追加できるようになります。PDFがアップロードされると、イベントがRedis Streamsに書き込まれます。その後、コンシューマグループのいずれかがイベントを受け取り、非同期処理を行います。
PDFの処理後、クリーニングを適用し、RediSearchでインデックス化されたRedisハッシュに保存します。これにより、「kubernetes deployments」や「DDD root aggregate」のような基本的なキーワード検索にとどまらず、自然言語によるクエリをサーバーに送信できるようになります。
つまり、より関連性の高い検索が可能になるのです。
フローチャート
以下は、Alexisがどのように機能するかの全体像です。
続いて、フローチャートの中でも特に重要な「PDFのアップロード&インデックス化」と「クエリへの回答」の2つの部分がどのように動作するかを詳しく見ていきましょう。
クエリへの回答(Answer Query)
- ユーザーがUI上でクエリを入力すると、その内容がRediSearchに送信されます。
- RediSearchとBM25関数がキーワードをもとに起動し、最も意味のあるコンテンツを特定します。
- そのコンテンツがクエリとともにRedisAIへ送信され、ユーザーの質問に最も関連性の高い回答が比較・選定されます。
PDFのアップロード&インデックス化(Upload PDFs & Index PDF Content)
- ユーザーが検索エンジンに質問を入力します。
- RediSearchがPDFをインデックス化し、クエリに対する回答を検索します。
- RedisAIが推論を実行し、複数の候補回答を抽出します。
- RedisAIが各候補を比較し、クエリに最も関連性の高い回答を決定します。
- 最終的に、その回答がユーザーに表示されます。
4. はじめ方
ステップ1:前提条件のインストール
- Node - v12.x.x
- NPM - v6.x.x
- DockerおよびDocker Compose
ステップ2:リポジトリのクローン
公式リポジトリをローカル環境にクローンしてください。
ステップ3:依存関係のインストール
ディレクトリをalexisに移動し、以下のコマンドを実行します。
npm install
ステップ4:フロントエンドとバックエンドのセットアップ
以下のコマンドでサーバーとクライアントアプリをブートストラップし、同時にRedisサーバーとRedisInsight GUIも初期化されます。
npm run bootstrap
ステップ5:アプリケーションの起動
npm start
ステップ6:アプリケーションへのアクセス
https://localhost:3000 を開くと、アプリケーションにアクセスできます。
ステップ7:RedisInsightへのアクセス
RedisInsightは、GUIベースとCLIベースの両方でRedisデータベースと対話できるビジュアルツールです。Redisアプリケーションの設計、開発、最適化に必要な機能を備えたフル機能のデスクトップGUIクライアントであり、開発作業を大幅に効率化します。詳細については公式ドキュメントをご覧ください。
RedisInsight GUIには、https://localhost:8001 からアクセスできます。
5. データの保存方法
ステップ1: ユーザーデータはRedisJSONに保存されます。
ステップ2: 以下のコードにより、ユーザーごとにRediSearchインデックスが作成されます。
ステップ3: ユーザーがPDFをアップロードすると、RedisJSONによってpdfs配列が更新されます。
ステップ4: ファイルのアップロードは同時にイベントの発生もトリガーとし、その内容がax:stream:pdf-processingストリームに書き込まれます。ストリームのペイロードは以下の通りです。
ステップ5: コンシューマグループ内のコンシューマがストリームからイベントを取り出し、ファイルを処理して、その内容をハッシュに書き込みます。
6. データのアクセス方法
このアプリケーションでは、ユーザーごとにRediSearchインデックスが作成され、前述のハッシュがインデックス化されます。これにより、ユーザーのクエリに関連するコンテンツを照合するルックアップ機能が実現します。コンテンツは以下のコードで分析されます。
RediSearchによって取得されたコンテンツは、その後RedisAIに送信され、分析されます。
7. 動作の仕組み
アカウントの作成
Alexisアプリを開くと、ログイン用のポータル画面に移動します(下図参照)。まだアカウントをお持ちでない場合は、画面下部のリンクから新規アカウントを作成できます。
ログインすると、ポータルの別ページに移動します。初めて利用する場合、ライブラリにはまだドキュメントが存在しないため、次のステップとしてドキュメントをアプリにインポートします。
ドキュメントのライブラリへのインポート
手順を開始するには、画面中央のボックスにドキュメントをドラッグ&ドロップするか、クラウドアイコンをクリックして手動でファイルを選択します。
ドキュメントをアップロードすると、画面左側にタイトルが表示され、保存が完了したことが確認できます(下図参照)。
このとき、PDFはサーバーにアップロードされると同時に、バックグラウンドでクリーニング処理が行われます。Redisの高度な機能のおかげで、このプロセスは非常に効率的です。
クエリの実行
上の画像の通り、アプリに検索させたいクエリを入力するだけです。この例では、ユーザーが「What is the journey about?(この旅について何が書かれていますか?)」と入力し、ファイルの内容について直接質問しています。
クエリを送信すると、関連度に基づいて階層的にランク付けされた複数の回答が即座に表示されます(下記の例参照)。
まとめ:Redisで検索を身近に
結局のところ、誰もが検索クエリに対して一切の遅延なく即座に結果が返されることを期待しています。デジタル時代において、わずかなラグでもユーザーはより快適なサービスへと離れてしまうでしょう。
Redisを活用することで、Alexisはプレミアム品質の動作を実現しました。RediSearchのおかげで、さまざまな場所に散在する最も意味のあるコンテンツを迅速かつ効率的に収集できます。さらに、RedisAIの超高度な分析能力がそのコンテンツを精査し、ユーザーのクエリに対して最も関連性が高く正確な回答を提供します。
このアプリケーションの制作過程について詳しく知りたい方は、Bobby氏のYouTube動画をぜひご覧ください。また、Redis Launchpadにはインスピレーションを得られる多彩なアプリケーションが揃っています。
ヘルシンキでのリアルタイムバス追跡システムから、発展途上国における農作物保険の保護まで、世界中のプログラマーがRedisの可能性を活かして日常に変革をもたらしています。あなたもその一員になれるのです!
このアプリケーションの開発者
Bobby Donchev
Bobby氏は、12年以上にわたりクライアント向けのシステム設計・実装に携わってきた、実績豊富なソフトウェアエンジニアです。
彼のGitHubページをチェックすれば、これまで携わってきたすべてのプロジェクトの最新情報をキャッチできます。
-
JavaFXでポリゴン(多角形)を作成する方法を徹底解説
JavaFXにおけるポリゴンとはポリゴン(多角形)とは、同一平面上に存在する複数の線分によって形成される閉じた図形のことです。JavaFXでは、このポリゴンは javafx.scene.shape.Polygon クラスによって表現されます。JavaFXでポリゴンを作成するには、以下の手順が必要です。Polygonクラスのインスタンスを生成する。ポリゴンを構成する各線分の始点と終点のXY座標を、コンストラクタの引数として渡すか、getPoints() メソッドを使って設定する。polygon.getPoints().addAll(new Double[]{ カンマ区切りのXY座標のリスト })
-
Macでテキストファイルを作成する3つの方法|ターミナル・TextEdit・Automatorの手順を解説
最近、WindowsからmacOSに乗り換えたばかりの方は、操作方法の違いに戸惑うことが多いのではないでしょうか。MacはWindowsパソコンに比べて直感的に使いやすく、動作も安定しているのが魅力ですが、一点だけ大きく異なる部分があります。それが「テキストファイルの新規作成方法」です。本記事では、Macで新しいテキストファイルを作成するためのさまざまな方法を詳しくご紹介します。 Macで新規テキストファイルを作成するには Windowsパソコンであれば、以下のように数ステップで簡単に新しいファイルを作成できます。 デスクトップ画面の任意の場所を右クリックします。 表示されたメニューから[