Elasticsearchは、業界をリードする生成AIツールやプロバイダーとネイティブに統合されています。RAG応用編やElasticベクトルデータベースで本番環境対応のアプリを構築する方法についてのウェビナーをご覧ください。
ユースケースに最適な検索ソリューションを構築するには、無料のクラウドトライアルを始めるか、ローカルマシンでElasticを試してみてください。
Spring AIは現在一般公開されており、最初の安定版リリース 1.0がMaven Centralからダウンロードできます。早速、お気に入りのLLMとお気に入りのベクター データベースを使用して、完全な AI アプリケーションを構築してみましょう。または、最終的なアプリケーションを使用してリポジトリに直接アクセスします。
Spring AI とは何ですか?
AI 分野の急速な進歩の影響を受けたかなりの開発期間を経て、Java での AI エンジニアリングのための包括的なソリューションであるSpring AI 1.0 がリリースされました。このリリースには、AI エンジニアにとって重要な新機能が多数含まれています。
Java と Spring は、この AI の波に乗るのに最適な位置にあります。数多くの企業が Spring Boot 上で業務を遂行しており、既存の業務に AI を組み込むのが非常に簡単になります。基本的に、あまり手間をかけずにビジネス ロジックとデータを AI モデルに直接リンクできます。

Spring AI は、次のようなさまざまな AI モデルとテクノロジーのサポートを提供します。
- 画像モデル: テキストプロンプトに基づいて画像を生成します。
- 転写モデル: オーディオ ソースを取得してテキストに変換します。
- 埋め込みモデル:任意のデータを、意味的類似性検索に最適化されたデータ型であるベクトルに変換します。
- チャットモデル:これら 馴染みがあるはずです!あなたもきっとどこかで簡単な会話をしたことがあるはずです。
チャット モデルは AI 分野で最も注目を集めているようですが、その通り、素晴らしいものです。文書の修正や詩の作成を手伝ってもらうこともできます。(ただ、まだジョークを言うように頼まないでください。)素晴らしいですが、いくつか問題もあります。
AIの課題に対するSpring AIソリューション

(掲載されている写真は、Spring AI チームリーダーの Mark Pollack 博士の許可を得て使用しています)
これらの問題のいくつかと Spring AI での解決策を見てみましょう。
| 問題 | ソリューション | |
|---|---|---|
| 一貫性 | チャットモデルはオープンマインドで、気が散りやすい | 全体的な形状と構造を制御するためのシステムプロンプトを与えることができます |
| メモリ | AIモデルには記憶がないので、特定のユーザーからのメッセージを別のユーザーと関連付けることはできない。 | 会話の関連部分を保存するメモリシステムを与えることができます |
| 分離 | AIモデルは隔離された小さなサンドボックス内に存在しますが、ツール(必要だと判断したときに呼び出せる機能)へのアクセスを与えると、本当に素晴らしいことが可能になります。 | Spring AI はツール呼び出しをサポートしており、これにより AI モデルに環境内のツールを通知し、そのツールを呼び出すように要求できます。この複数ターンのインタラクションはすべて透過的に処理されます |
| 個人データ | AI モデルはスマートですが、全知ではありません。彼らはあなたの独自のデータベースに何が入っているか知りませんし、あなたもそれを知りたいとは思わないでしょう。 | 基本的には、モデルが質問を確認する前に、強力な文字列連結演算子を使用してリクエストにテキストを挿入することで、プロンプトを詰め込んで応答を通知する必要があります。背景情報です。何を送信して何を送信しないかをどのように決定しますか?ベクター ストアを使用して、関連するデータのみを選択し、それを送信します。これは検索拡張生成、またはRAGと呼ばれます。 |
| 幻覚 | AI チャット モデルは、チャットするのが大好きです。そして時には、自信過剰になり、嘘をつくこともある。 | 妥当な結果を確認するには、評価(あるモデルを使用して別のモデルの出力を検証する)を使用する必要があります。 |
そしてもちろん、AI アプリケーションは孤立したものではありません。今日、最新の AI システムとサービスは、他のシステムやサービスと統合すると最も効果的に機能します。モデルコンテキストプロトコル (MCP) を使用すると、記述言語に関係なく、AI アプリケーションを他の MCP ベースのサービスに接続できるようになります。これらすべてを、より大きな目標に向かって進むエージェントワークフローに組み込むことができます。
一番良かった点は?Spring Boot 開発者なら誰もが期待する使い慣れたイディオムと抽象化を基盤として、これらすべてを実現できます。基本的にすべてに対する便利なスターター依存関係がSpring Initializrで利用できます。
Spring AI は、既知の期待通りの、設定よりも規約を重視するセットアップを実現する便利な Spring Boot 自動設定を提供します。また、Spring AI は、Spring Boot の Actuator と Micrometer プロジェクトによって可観測性をサポートしています。GraalVM や仮想スレッドとも連携し、スケーラブルな超高速かつ効率的な AI アプリケーションを構築できます。
Elasticsearchを選ぶ理由
Elasticsearch は全文検索エンジンです。おそらくご存知でしょう。では、なぜこのプロジェクトでそれを使用するのでしょうか?まあ、ベクターストアでもあります!データが全文の隣に保存されるので、非常に便利です。その他の注目すべき利点:
- セットアップは超簡単
- オープンソース
- 水平方向に拡張可能
- 組織の自由形式のデータのほとんどは、すでにElasticsearchクラスターに保存されているでしょう。
- 完全な検索エンジン機能を搭載
- Spring AI に完全に統合されています!
すべてを考慮すると、Elasticsearch は優れたベクター ストアに必要なすべての条件を満たしているので、セットアップしてアプリケーションの構築を開始しましょう。
Elasticsearchを使い始める
Elasticsearch と Kibana (データベースにホストされているデータを操作するために使用する UI コンソール) の両方が必要になります。
Docker イメージとElastic.co ホームページのおかげで、ローカル マシンですべてを試すことができます。そこに移動して、下にスクロールしてcurlコマンドを見つけ、それを実行してシェルに直接パイプします。
これにより、Elasticsearch と Kibana の Docker イメージがプルされて構成され、数分後には接続資格情報も揃ってローカル マシン上で稼働するようになります。
Elasticsearch インスタンスと対話するために使用できる 2 つの異なる URL もあります。プロンプトの指示に従って、ブラウザでhttp://localhost:5601にアクセスします。
コンソールに出力されるユーザー名elasticとパスワードにも注意してください。これらはログイン時に必要になります (上記の出力例では、それぞれelasticとw1GB15uQです)。
アプリをまとめる
Spring Initializrページに移動し、次の依存関係を持つ新しい Spring AI プロジェクトを生成します。
Elasticsearch Vector StoreSpring Boot ActuatorGraalVMOpenAIWeb
必ず最新の Java バージョン (理想的には、この記事の執筆時点では Java 24 以降) と好みのビルド ツールを選択してください。この例では Apache Maven を使用しています。
Generateをクリックし、プロジェクトを解凍して、選択した IDE にインポートします。(IntelliJ IDEA を使用しています。)
まず最初に、Spring Boot アプリケーションの接続詳細を指定しましょう。application.properties,に次のように記述します。
また、データ構造に関して Elasticsearch 側で必要なものをすべて初期化するための Spring AI のベクトル ストア機能も使用するので、次のように指定します。
このデモではOpenAI 、具体的には埋め込みモデルとチャット モデルを使用します ( Spring AI がサポートしている限り、お好みのサービスを自由に使用してください)。
埋め込みモデルは、データを Elasticsearch に格納する前にデータの埋め込みを作成するために必要です。OpenAI が動作するには、 API keyを指定する必要があります。
ソース コード内に資格情報を保存することを避けるために、 SPRING_AI_OPENAI_API_KEYのような環境変数として定義することができます。
ファイルをアップロードするので、サーブレット コンテナにアップロードできるデータの量を必ずカスタマイズしてください。
もうすぐ到着です!コードの記述に進む前に、これがどのように機能するかをプレビューしてみましょう。
私たちのマシンでは、次のファイル(ボードゲームのルールのリスト) をダウンロードし、名前をtest.pdfに変更して~/Downloads/test.pdfに配置しました。
ファイルは/rag/ingestエンドポイントに送信されます (パスをローカル設定に応じて置き換えてください)。
数秒かかる場合があります…
舞台裏では、データが OpenAI に送信され、データの埋め込みが作成されます。その後、そのデータはベクトルと元のテキストの両方で Elasticsearch に書き込まれます。
そのデータと、そこに含まれるすべての埋め込みによって、魔法が起こるのです。その後、 VectorStoreインターフェースを使用して Elasticsearch をクエリできます。
完全なフローは次のようになります。
- HTTP クライアントは、選択した PDF を Spring アプリケーションにアップロードします。
- Spring AI は PDF からテキストを抽出し、各ページを 800 文字のチャンクに分割します。
- OpenAI は各チャンクのベクトル表現を生成します。
- チャンク化されたテキストと埋め込みの両方が Elasticsearch に保存されます。

最後に、クエリを発行します。
そして、適切な答えが得られます。
いいですね!これはどうやって動くんですか?
- HTTP クライアントは Spring アプリケーションに質問を送信します。
- Spring AI は OpenAI から質問のベクトル表現を取得します。
- この埋め込みにより、保存された Elasticsearch チャンク内で類似のドキュメントが検索され、最も類似したドキュメントが取得されます。
- 次に、Spring AI は質問と取得したコンテキストを OpenAI に送信し、LLM 回答を生成します。
- 最後に、生成された回答と取得されたコンテキストへの参照を返します。

実際にどのように動作するかを確認するために、Java コードを調べてみましょう。
まず、 Mainクラス: これは、あらゆる Spring Boot アプリケーションの標準的なメイン クラスです。
そこには何も見るものはありません。次に進みましょう…
次は、基本的な HTTP コントローラーです。
コントローラーは、ファイルの取り込みと Elasticsearch ベクター ストアへの書き込みを処理するために構築したサービスを呼び出し、同じベクター ストアに対するクエリを容易にするだけです。
サービスを見てみましょう:
このコードはすべての取り込みを処理します。バイトを囲むコンテナーである Spring Framework Resourceが指定されると、Spring AI のPagePdfDocumentReaderを使用して PDF データ ( .PDFファイルであると想定されます。任意の入力を受け入れる前に必ず検証してください) を読み取り、次に Spring AI のTokenTextSplitterを使用してトークン化し、最後に結果のList<Document>をVectorStore実装ElasticsearchVectorStoreに追加します。
Kibana を使用してこれを確認できます。ファイルを/rag/ingestエンドポイントに送信した後、ブラウザでlocalhost:5601を開き、左側のサイド メニューでDev Toolsに移動します。ここでクエリを発行して、Elasticsearch インスタンス内のデータと対話できます。

次のようなクエリを発行します。

さて、ここからが面白いところです。ユーザーのクエリに応じて、そのデータをどうやって再び取り出すのでしょうか?
以下は、 directRagと呼ばれるメソッドでのクエリの実装の最初の例です。
コードは非常に単純ですが、複数のステップに分解してみましょう。
- 類似検索を実行するには、
VectorStoreを使用します。 - すべての結果が与えられたら、基礎となる Spring AI
Documentを取得し、そのテキストを抽出して、すべてを 1 つの結果に連結します。 VectorStoreからの結果を、その結果の処理方法をモデルに指示するプロンプトとユーザーからの質問とともにモデルに送信します。応答を待って返します。
これはRAG (検索拡張生成) です。これは、ベクトル ストアのデータを使用して、モデルによって実行される処理と分析に情報を提供するという考え方です。やり方がわかったので、もうそんなことをしなくて済むことを祈ります!とにかく、これは違います。Spring AI のアドバイザーは、このプロセスをさらに簡素化するために存在します。
アドバイザーを使用すると、アプリケーションとベクター ストアの間に抽象化レイヤーを提供するだけでなく、特定のモデルへのリクエストを前処理および後処理できます。ビルドに次の依存関係を追加します。
クラスにadvisedRag(String question)という別のメソッドを追加します。
すべての RAG パターン ロジックはQuestionAnswerAdvisorにカプセル化されます。その他は、 ChatModelへのリクエストと同じです。ニース!
完全なコードは GitHub から入手できます。
まとめ
このデモでは、Docker イメージを使用してすべてをローカル マシン上で実行しましたが、ここでの目標は、本番環境に適した AI システムとサービスを構築することです。それを実現するためにできることはいくつかあります。
まず、トークンの消費を監視するためにSpring Boot Actuator を追加できます。トークンは、モデルに対する特定のリクエストの複雑さ (場合によってはドルとセント) のコストを表す代理です。
クラスパスにはすでに Spring Boot Actuator があるので、次のプロパティを指定するだけで、すべてのメトリック (素晴らしいMicrometer.ioプロジェクトによってキャプチャされたもの) が表示されます。
アプリケーションを再起動してください。クエリを作成して、 http://localhost:8080/actuator/metricsにアクセスします。「 token 」を検索すると、アプリケーションで使用されているトークンに関する情報が表示されます。これに注意してください。もちろん、Micrometer のElasticsearch 統合を使用してこれらのメトリックをプッシュし、Elasticsearch を好みの時系列データベースとして機能させることもできます。
次に、Elasticsearch などのデータストア、OpenAI、またはその他のネットワーク サービスにリクエストを送信するたびに IO が実行され、多くの場合、その IO によって実行中のスレッドがブロックされることを考慮する必要があります。Java 21 以降には、スケーラビリティを大幅に向上させる非ブロッキング仮想スレッドが搭載されています。有効にするには以下を実行します:
そして最後に、アプリケーションとデータを、それが繁栄し、拡張できる場所でホストすることが必要になります。アプリケーションをどこで実行するかについてはおそらくすでにお考えだと思いますが、データはどこにホストするのでしょうか?Elastic Cloudをお勧めしますか?安全、プライベート、スケーラブル、そして機能が満載です。私たちのお気に入りの部分は?ご希望の場合は、Elastic がポケベルを装着し、お客様がポケベルを装着する Serverless エディションを入手できます。




