本記事はこちらのブログを参考にしています。
翻訳にはアリババクラウドのModelStudio(Qwen)を使用しております。
Musheng 作成
Spring AI Alibaba RAG サンプルプロジェクトのソースコードアドレス: https://github.com/springaialibaba/spring-ai-alibaba-examples/tree/main/spring-ai-alibaba-rag-example
1. RAG アプリケーションアーキテクチャの概要
1.1 コアコンポーネント
- Spring AI: Springエコシステム向けのJava AI開発フレームワークで、大規模モデルやベクトルデータベース、その他のAIインフラにアクセスするための一元化されたAPIを提供します。
- Ollama: ローカルモデル実行エンジン(Dockerに類似)で、オープンソースモデルの迅速なデプロイをサポートします。
- Spring AI Alibaba: Spring AIの拡張版で、DashScopeモデルプラットフォームを統合しています。
- Elasticsearch: テキストのベクトル化データを保存し、意味検索をサポートするベクトルデータベースです。
1.2 モデル選択
-
Embedding モデル:
nomic-embed-text:latest
(テキストデータのベクトル化に使用) -
Ollama Chat モデル:
deepseek-r1:8b
(最終的な回答を生成)
2. 環境準備
2.1 Ollama サービスの起動
Docker Composeを使用してOllamaを起動します。(同時に、Ollamaモデルと対話するためのフロントエンドシステムも起動します。)yaml
services:
ollama:
container_name: ollama
image: ollama/ollama:latest
ports:
- 11434:11434
open-webui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
ports:
- 3005:8080
environment:
- OLLAMA_BASE_URL=http://host.docker.internal:11434
extra_hosts:
- host.docker.internal:host-gateway
2.2 モデルのダウンロード
以下のコマンドを実行します:bash
docker exec -it ollama ollama pull deepseek-r1:8b
docker exec -it ollama ollama pull nomic-embed-text:latest
open-webuiでdeepseek-r1:8b
モデルを呼び出します:
2.3 Elasticsearch のデプロイyaml
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.16.1
container_name: elasticsearch
privileged: true
environment:
- cluster.name=elasticsearch
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms512m -Xmx1096m
- bootstrap.memory_lock=true
volumes:
- ./config/es.yaml:/usr/share/elasticsearch/config/elasticsearch.yml
ports:
- 9200:9200
- 9300:9300
deploy:
resources:
limits:
cpus: 2
memory: 1000M
reservations:
memory: 200M
esの起動用設定ファイルを準備します:yaml
cluster.name: docker-es
node.name: es-node-1
network.host: 0.0.0.0
network.publish_host: 0.0.0.0
http.port: 9200
http.cors.enabled: true
http.cors.allow-origin: "*"
bootstrap.memory_lock: true
認証を無効化(デフォルトではes 8.xで有効)
xpack.security.enabled: false
これで、シンプルなRAGアプリケーションを構築するための環境準備がすべて完了しました。次に、プロジェクトのセットアップを始めましょう。
3. プロジェクト設定
3.1 依存関係の導入xml
org.springframework.boot spring-boot-starter-web 3.3.4 org.springframework.ai spring-ai-ollama-spring-boot-starter 1.0.0-M5 org.springframework.ai spring-ai-elasticsearch-store 1.0.0-M5 org.springframework.ai spring-ai-pdf-document-reader 1.0.0-M53.2 コア設定yaml
spring:
ai:
# ollama設定
ollama:
base-url: http://127.0.0.1:11434
chat:
model: deepseek-r1:8b
embedding:
model: nomic-embed-text:latest
# ベクトルデータベース設定
vectorstore:
elasticsearch:
index-name: ollama-rag-embedding-index
similarity: cosine
dimensions: 768
elasticsearch:
uris: http://127.0.0.1:9200
ここで:
-
index-name
はesのベクトルインデックス名です。 -
dimensions
はベクトルモデルによって生成されるベクトルの次元数(ベクトルモデルによって生成される次元数と一致する必要があり、デフォルトは1576です)。 -
similarity
はベクトル間の類似度を測定するために使用されるアルゴリズムまたはメトリックを定義します。ここでは高次元疎ベクトルに適したコサイン類似度を使用しています。
カスタマイズされたesのインスタンス化設定を行うには、spring-ai-elasticsearch-store
を導入します:xml
org.springframework.ai
spring-ai-elasticsearch-store
1.0.0-M5
プロジェクト内でカスタム設定ビーンを通じて実装します。
3.3 プロンプトテンプレート
あなたはMacOSの専門家です。次の文脈に基づいて回答してください:
{question_answer_context}
与えられた文脈と提供された履歴情報を組み合わせて中国語Markdown形式で回答してください。文脈に答えがない場合は、それを明確にしてください。
4. コア実装
4.1 テキストのベクトル化
Spring AIおよびSpring AI Alibabaでは、ほぼすべてのデータソースをナレッジベースソースとして使用できます。この例では、PDFをナレッジベースドキュメントとして使用しています。Spring AI Alibabaは、40以上のドキュメントリーダーおよびパーサープラグインを提供しており、RAGアプリケーションにデータをロードすることができます。java
public class KnowledgeInitializer implements ApplicationRunner {
// VectorStoreインスタンスを注入し、ベクトル化データの増加およびクエリ操作を担当
private final VectorStore vectorStore;
// ベクトルデータベースクライアント、ここではesを使用
private final ElasticsearchClient elasticsearchClient;
// .....
@Override
public void run(ApplicationArguments args) {
// 1. pdfリソースをロード
List<Resource> pdfResources = loadPdfResources();
// 2. pdfリソースをDocumentsに解析
List<Document> documents = parsePdfResource(pdfResources);
// 3. ESにインポート
importToES(documents);
}
private List<Document> parsePdfResource(List<Resource> pdfResources) {
// 指定されたポリシーに基づいてテキストを分割し、Documentリ
RAGアプリケーションの構築と最適化
4.3 RAGサービスインターフェース層
ユーザーからのリクエストを処理し、大規模モデルのレスポンスを取得するためのユーザー向けリクエストインターフェースを作成します。java
@RestController
@RequestMapping(/rag/ai)
public class AIRagController {
@Resource
public AIRagService aiRagService;
@GetMapping(/chat/{prompt})
public Flux<String> chat(
@PathVariable(prompt) String prompt,
HttpServletResponse response
) {
// ストリーム応答が文字化けしないようにレスポンスのエンコーディングを設定します。
response.setCharacterEncoding(UTF-8);
if (!StringUtils.hasText(prompt)) {
return Flux.just(prompt is null.);
}
return aiRagService.retrieve(prompt);
}
}
5. リクエストデモンストレーション
以下は例です:私は現在Mac初心者で、Macのトラックパッドをより使いやすく設定したいと考えています。何か提案はありますか?この例からわかるように、モデルからの直接的なレスポンスは比較的公式で、実用的ではありません。
5.1 open-webuiからの直接呼び出し
! 2
5.2 RAGアプリケーションインターフェースの呼び出し
! 3
RAGアプリケーションの出力はより正確であり、ユーザーのニーズに合致していることがわかります。
6. RAGの最適化
6.1 DashScopeプラットフォームモデルの使用
ローカルOllamaを使用してモデルサービスを展開する場合、モデルの実行速度はローカルリソース制約によって制限され、処理時間が長くなることがあります。したがって、クラウドプラットフォーム上にあるモデルを利用することでユーザーエクスペリエンスを向上させることができます。
application.yaml
を次のように修正します:yaml
spring:
application:
name: ollama-rag
ai:
dashscope:
api-key: ${AI_DASHSCOPE_API_KEY}
chat:
options:
model: deepseek-r1
embedding:
enabled: false
ollama:
base-url: http://127.0.0.1:11434
chat:
model: deepseek-r1:8b
enabled: false
embedding:
model: nomic-embed-text:latest
vectorstore:
elasticsearch:
index-name: ollama-rag-embedding-index
similarity: cosine
dimensions: 768
elasticsearch:
uris: http://127.0.0.1:9200
これにより、Ollamaのチャット機能が無効になり、Spring AI Alibaba Starter依存関係を通じてDashScopeプラットフォーム上のDeepSeekR1モデルが使用されます。
依存関係を追加します:xml
com.alibaba.cloud.ai spring-ai-alibaba-starter 1.0.0-M6AIRAGService.java
を編集します:java
public Flux retrieve(String prompt) {
// ベクトルストアプロンプトテンプレートを取得します。
String promptTemplate = getPromptTemplate(systemResource);
// ハイブリッド検索(埋め込みおよび全文検索)を有効にします。
SearchRequest searchRequest = SearchRequest.builder()
.topK(4)
.similarityThresholdAll()
.build();
// 検索結果再ランキングアドバイザー付きのChatClientを構築します:
ChatClient runtimeChatClient = ChatClient.builder(chatModel)
.defaultAdvisors(new RetrievalRerankAdvisor(
vectorStore,
rerankModel,
searchRequest,
promptTemplate,
0.1)
).build();
// Spring AI RetrievalAugmentationAdvisor
Advisor retrievalAugmentationAdvisor = RetrievalAugmentationAdvisor.builder()
.queryTransformers(RewriteQueryTransformer.builder()
.chatClientBuilder(ChatClient.builder(ragChatModel).build().mutate())
.build())
.documentRetriever(VectorStoreDocumentRetriever.builder()
.similarityThreshold(0.50)
.vectorStore(vectorStore)
.build())
.build();
// データの検索とLLM生成
return ragClient.prompt()
.advisors(retrievalAugmentationAdvisor)
.user(prompt)
.stream()
.content();
}
6.2 検索の最適化
Spring AI RAG ドキュメント:https://docs.spring.io/spring-ai/reference/api/retrieval-augmented-generation.html
Spring AI 構造化ドキュメント:https://java2ai.com/docs/1.0.0-M5.1/tutorials/rag/
Spring AIを使用してRAGアプリケーションを構築する際、QuestionAnswerAdvisorを構築する際にパーソナライズされたパラメーターを設定することで、ベクトルデータの検索において最適なパフォーマンスを達成できます。
6.3 データ前処理の最適化
データ前処理フェーズでは、次の操作を行うことができます:
- 関連のない文書を削除する。
- ノイズデータや特殊文字などをテキストデータからクリーンアップする。
- インデックスデータの品質を向上させるためにメタデータを追加する。
- インデックス構造を最適化する。
7. 問題のトラブルシューティング
Q: ベクトル挿入に失敗しました
A: ESインデックスの次元がモデル出力と一致しているか確認してください。
Q: 検索結果が関連性がない
A: 埋め込みモデルがテキストタイプと一致しているか確認してください。
Q: 応答速度が遅い
A: Ollamaの計算リソース設定を調整してください。
Q: spring-ai-alibaba-starter依存関係の取得に失敗しました
A: mvnリポジトリの設定が必要です。xml
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
spring-snapshots
Spring Snapshots
https://repo.spring.io/snapshot
false
8. まとめ
RAGアプリケーションを構築する全体のプロセスは、以下の3つのステップに分けることができます:
- データの読み込みとクリーニング: 外部ナレッジベースからデータを読み込み、ベクトル化後にElasticsearchに保存します。
- モデル呼び出しの最適化: 検索強化技術(RAG)を使用して大規模モデルにコンテキスト情報を提供します。
- インタラクティブサービスの構築: REST APIを構築し、アプリケーションとユーザー間での効率的な対話を実現します。
RAGによる検索強化により、モデルの応答がより文脈的に関連性を持つようになり、最終的にユーザーエクスペリエンスが向上します。