Semantic Kernel / Spring AI & Azure Cosmos DB VectorStore 登壇内容補足
Java on Azure Day 2025 My Presentation Supplement
この記事は、先日開催された Java on Azure Day 2025 における私の登壇内容の補足記事です。
こちらの Session 5 にて、Java で作る RAG を活用した Q&A アプリケーション
と題し、以下の 2 点をデモアプリを交えて紹介しました。
当日のスライドについては、当日参加者向けのダウンロードリンクに加えて、以下でも公開しています。
この記事では、スライドには載せていない詳細や、実際のデモアプリについて深く紹介したいと思います。
当日紹介したデモ内容
当日紹介した内容としては、下記の 2 点です。
- Semantic Kernel for Java を使用した Chat Completion アプリの実装方法
- Spring AI と Azure Cosmos DB VectorStore を利用した RAG アプリの実装方法
1 つ目は、Semantic Kernel for Java の ChatCompletionService
を利用して LLM (Large Language Model) とやり取りを行うアプリについて紹介しました。当日は時間や説明の都合上、コンソール形式でのアプリデモをお見せしました。
2 つ目は、Spring AI と Azure Cosmos DB VectorStore を利用した RAG (Retrieval-Augmented Generation) アプリのデモを行いました。こちらは Azure Cosmos DB 公式が公開している Azure Cosmos DB Samples Gallery に良いサンプルが公開されているので、そちらを利用してデモを行いました。
サンプルアプリ
1 つ目の Chat Completion アプリについては、Spring Boot として RestController の Web API ベースで実行できる形にした内容を下記に公開しています。
2 つ目の Spring AI & Azure Cosmos DB VectorStore の RAG アプリについては、公式が提供しているサンプルアプリをそのまま流用したので、詳しくは以下を見てください。
Semantic Kernel for Java
Semantic Kernel そのものについてはこの記事では解説しませんので、学習したい方は以下を参照することをお勧めします。
Semantic Kernel for Java については、以前は上記の GitHub リポジトリの java ディレクトリ配下で開発されていましたが、現在はリポジトリが分離することになりました。
これは、従来のリポジトリは Java に加えて C# や Python のコードも含まれる巨大なリポジトリになっており、OSS として Java コミュニティからのコミットメントに支障が出たりしていたことから、開発の円滑化を目的に分離されたことが背景にあります。
(Semantic Kernel 自体の方向性などについては、分離前のリポジトリのプロジェクトボード側で継続して議論されます)
Components
Semantic Kernel の主要なコンポーネントとして、5 つ紹介しました。
- AI Service Connectors
- Functions and Plugins
- Vector Store (Memory) Connectors
- Prompt Templates
- Filters
当日は時間の都合上、AI Service Connectors と Function and Plugins に焦点を当てて説明しました。
Vector Store (Memory) Connectors については、現在プレビュー扱いのため、今後破壊的変更が行われる可能性もあります。現時点での詳細を知りたい方は、以下を参照すると良いです。
Azure AI Search との接続についてのサンプルなども公開されています。
Prompt Templates については、こちらを参照すると良いです。ざっくり言うと、プロンプトに変数を組み込める感じです。
詳細は以下を参照すると良いと思います。
Filter については、下記を参照です。簡単に言えば、Azure OpenAI Service などで提供されているコンテンツフィルターのように、ユーザープロンプトの事前チェックや LLM が出力した内容のチェックなどを独自に定義できるようなものです。
ChatCompletionAgent
Semantic Kernel for Java については、直近のプレビューバージョン 1.4.4-RC1
で Agent Framework の対応がされるようになったと解説しました。まだ RC1 のため、今後、破壊的変更が行われる可能性がありますが、現時点での内容を確認するなら以下を参照すると良いです。
ChatCompletion アプリ解説
Spring Boot なので、基本的な RestController や Bean による DI コンテナの解説はしません。
Semantic Kernel for Java における基本的なクラスの生成や実行についてはスライドに記載の通りですが、サンプルアプリにおいての挙動は下記を見れば Spring Boot 触ったことがある人はそこそこわかると思います。
ちなみに config の Bean で ChatCompletionAgent の Bean を作成しているのを見た方もいるかもですが、そのうち ChatCompletionAgent 対応はする予定です。
アプリの実行方法としては、config に書いてある通り必要な情報を application.properties に載せたあと、実行すれば localhost:8080 で通信ができます。(Dev Container 実行時は、ポート番号はポート転送の内容に適宜読み替えてください)
アプリを起動したら、Postman などを使って Post を実行すれば良いです。
Body は DTO である ChatMessageRequest
を参考に作れば良いです。最初のユーザープロンプト送信の時は context や lastMessage は不要です。
会話を継続したい場合は、Response で返ってきている context や lastMessage をそのまま突っ込めばいいです。
DateTimePlugin
Kernel への登録は、withPlugin にて KernelPlugin として KernelPluginFactory に登録したものを組み込んでます。
@Bean
public Kernel kernel(ChatCompletionService chatCompletionService) {
return Kernel.builder()
.withAIService(ChatCompletionService.class, chatCompletionService)
.withPlugin(dateTimePlugin())
.build();
}
@Bean
public KernelPlugin dateTimePlugin() {
return KernelPluginFactory.createFromObject(new DateTimePlugin(), "DateTimePlugin");
}
実際のプラグインのコードについては、下記にあります。DefineKernelFunction
アノテーションでプラグインの説明を書いてます。登壇時も紹介した通り、ここの説明は英語で書くのが良いとされています。
実際にプラグインの実行を検証したい場合は、先述の Postman 実行の際、プロンプト (content) として日時を聞くプロンプトを実行してみれば良いです。
Spring AI & Azure Cosmos DB VectorStore アプリ解説
前述の通り、公式のサンプルアプリをそのまま実行しているので、特に解説はないですが、流れとしては
- ベクトル化する情報を準備
-
CliApplication
を実行して、チャンク化したテキストをベクトル化して Azure CosmosDB VectorStore に保存 -
SpringChatgptSampleApplication
を実行してチャットアプリを起動
この流れで実行すれば良いです。
CliApplication でテキストをチャンク化する際のサイズは下記で定数定義されているので、いじりたい場合はここを変更すればいいです。
実際に Azure Cosmos DB VectorStore へアクセスする部分は Spring AI 側でマネジメントされているので、application.properties にて正しい情報を指定し、ChatService
と VectorStore
を生成すれば良いだけです。
実際に RAG して結果を受け取っている部分は下記なので、そんなに難しくないと思います。
String response = this.chatClient.prompt(prompt)
.user(messages.get(0).getContent())
.messages(messages)
.advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.query(messages.get(0).getContent()).withTopK(5)))
.call()
.content();
実際に本番利用する際の注意
今回のアプリはどれもサンプルなので、本番運用を想定したセキュリティ対応は無視しています。
API エンドポイントの認証/認可などは、Spring Security の導入や Azure API Management やネットワークレベルでの制限など、各種必要な対応を講じてください。
Discussion