mcpField
S
Spring Boot AI

Spring Boot AI

ローカル
dev.to開発ツール119 週間前に更新

Spring Boot AI について

Spring Boot AIは、MCP、RAG、モデル評価テストを学ぶ開発者向けの、Spring AIによる宿泊予約エージェントの例です。ローカルの天気ツール、リモート予約ツール、ベクトル検索、複数モデルの設定を組み合わせています。

主な機能

  1. 01宿泊予約チャットエージェント
  2. 02ローカル天気・リモート予約ツール
  3. 03PGVectorを使ったRAG
  4. 04チャットメモリとログ用Advisor
  5. 05Ollama、Gemini、Bedrockのプロファイル

活用シーン

  1. 01旅行宿泊予約のチャットアプリ構築
  2. 02ローカルとリモートのMCPツール呼び出しのテスト
  3. 03ベクトル検索による都市情報の追加
  4. 04異なるモデル設定でのアプリ評価

MCP 対応

MCPクライアントでリモートのBooking MCPサーバーに接続し、ローカルのWeatherツールをエージェントに提供します。Bookingツールを実装するMCPサーバーも含まれています。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"spring-boot-ai": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"compose"
]
}
}
}
起動コマンドdocker run -i --rm compose

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
ocicompose

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

mcp-server chat-server Java Kotlin SpringBoot SpringAI

Gemini Bedrock Ollama

Spring Boot AI

Building Agents with AWS: Complete Tutorial に着想を得たこの例では、Spring AI を使用してシンプルな AI エージェントアプリケーションを構築し、次のような主要機能を紹介します。

このプロジェクトは MCP Review によってインデックス化され、認定されています。

元の例では AWS Bedrock を使用していますが、Spring AI の大きな利点の一つは、設定を少し変更するだけで、同じコードを他の対応モデルでも利用できることです。このプロジェクトでは、Ollama(ローカル)、[Google Gemini](https://ai.google.dev/)、[AWS Bedrock](https://aws.amazon.com/bedrock/) の3つのプロファイルをサポートしています。

このアプリケーションには、観光地での宿泊先予約をユーザーに案内する AI エージェントが備わっています。

MCP を通じて、エージェントは次のツールを使用できます。

  • Weather Tool:指定された都市と日付の天気情報を取得します。
  • Booking Tool:指定された日付に都市での宿泊先を予約します。

Weather ツールは MCP を使用してローカルに実装され、Booking ツールはリモートの MCP サーバー によって提供されます。現在の日付はシステムプロンプトで指定されます。都市に関する追加情報は、RAG を使用してベクトルストアから取得されます。

図

実装

MCP サーバー

Spring Boot ではよくあることですが、MCP サーバーの実装は非常に簡単です。MCP Server Boot Starterのガイドに従い、次のことを行うだけです。

  1. spring-ai-starter-mcp-server-webflux または spring-ai-starter-mcp-server-webmvc の依存関係を追加します。

  2. インスタンスを作成し、@Tool と @ToolParam を付与します。

@Service // or @Bean / @Component
class BookingTool(private val bookingService: BookingService) {
  @Tool(
    description = "make a reservation for accommodation for a given city and date",
  )
  fun book(
    @ToolParam(description = "the city to make the reservation for")
    city: String,
    @ToolParam(description = "the check-in date, when the reservation begins")
    checkinDate: LocalDate,
    @ToolParam(description = "the check-out date, when the reservation ends")
    checkoutDate: LocalDate
  ): String = bookingService.book(city, checkinDate, checkoutDate) // Delegate to a service
}
  1. MethodToolCallbackProvider として登録します。
@Configuration
class BookingToolConfiguration {
  @Bean
  fun bookingToolCallbackProvider(bookingTool: BookingTool) = 
    MethodToolCallbackProvider.builder()
      .toolObjects(bookingTool)
      .build()
}
チャットサーバー

チャットサーバーは、次の依存関係を使用して構築された Spring Boot アプリケーションです。

  • spring-boot-starter-web または -webflux - チャットインターフェース用の REST API を公開します
  • spring-ai-starter-mcp-client - MCP を使用します
  • spring-ai-starter-vector-store-pgvector と spring-ai-advisors-vector-store - PGVector で RAG を有効にします
  • spring-ai-starter-model-ollama - Ollama モデルを使用します
  • spring-ai-starter-model-google-genai と spring-ai-starter-model-google-genai-embedding - Google Gemini モデルを使用します
  • spring-ai-starter-model-bedrock と spring-ai-starter-model-bedrock-converse - AWS Bedrock モデルを使用します
コンポーネント
  • MCP ツール
    • Weather Tool - 指定した日付の指定した都市の天気を WeatherService に問い合わせる、ローカルの MCP ツールです
    • Booking Tool - Booking MCP Server に接続して宿泊施設を予約する、リモートの MCP ツールです
  • チャット
    • Chat Client - 次の設定を行った Spring AI の ChatClient です。
      • AI エージェントの役割と現在の日付を定義するシステムプロンプト
      • 有効なプロファイルを介して Spring Boot が自動構成する AI モデル
      • AI エージェントのツールセットに含まれる上記の MCP ツール
    • Chat Service - Chat Client をラップし、次の3つのアドバイザーを追加します。
      • QuestionAnswerAdvisor - ベクトルストアからコンテキストを取得し、ユーザー入力を拡張します(RAG)
      • MessageChatMemoryAdvisor - ユーザー入力に会話履歴を追加します(チャットメモリ)
      • SimpleLoggerAdvisor - デバッグ用にチャット履歴をコンソールに記録します
    • Chat Controller - ユーザー入力を受け取り、Chat Service を呼び出して、AI エージェントの応答を返すシンプルな REST POST エンドポイントを公開します
  • Vector Store Initializer - 起動時にサンプルデータをベクトルストアに読み込みます

順を追って実装していきましょう。

Weather Tool

Weather Tool は次のように実装します。

  1. インスタンスを作成し、@Tool と @ToolParam を付与します。
@Service // or @Bean / @Component
class WeatherTool(private val weatherService: WeatherService) {
  @Tool(description = "get the weather for a given city and date")
  fun getWeather(
    @ToolParam(description = "the city to get the weather for")
    city: String,
    @ToolParam(description = "the date to get the weather for") 
    date: LocalDate
  ): String = weatherService.getWeather(city, date) // Delegate to a service
}
  1. MethodToolCallbackProvider として登録します。
@Configuration
class WeatherToolConfiguration {
  @Bean
  fun weatherToolCallbackProvider(weatherTool: WeatherTool) =
    MethodToolCallbackProvider.builder()
      .toolObjects(weatherTool)
      .build()
}
Booking Tool

Booking Tool をリモート MCP ツールとして設定するには、application.propertiesで MCP クライアントの SSE 接続を構成するだけです。

spring.ai.mcp.client.toolcallback.enabled=true
spring.ai.mcp.client.sse.connections.booking-tool.url=http://localhost:8081

その他の設定方法は、MCP Client Boot Starterのドキュメントをご覧ください。

Chat Client

Chat Client は Spring AI の ChatClient.Builder を使用して作成します。これは spring.ai の設定プロパティによってすでに自動構成されています(詳しくは後述の設定で説明します)。カスタムのシステムプロンプトと利用可能な MCP ツールを指定して初期化します。

@Configuration
class ChatClientConfiguration {
  @Bean
  fun chatClient(
    builder: ChatClient.Builder,
    toolCallbackProviders: List<ToolCallbackProvider>
  ): ChatClient {
    return chatClientBuilder(builder, toolCallbackProviders).build()
  }

  private fun chatClientBuilder(
    builder: ChatClient.Builder,
    toolCallbackProviders: List<ToolCallbackProvider>
  ): ChatClient.Builder {
    val system = """
      You are an AI powered assistant to help people book accommodation in touristic cities around the world.
      If there is no information, then return a polite response suggesting you don't know.
      If the response involves a timestamp, be sure to convert it to something human-readable.
      Do not include any indication of what you're thinking.
      Use the tools available to you to answer the questions.
      Just give the answer.
      When booking accommodation for a weekend, assume check-in on Saturday and check-out on Monday.
      Current date: {currentDate}
      """.trimIndent()
    return builder
      .defaultSystem(system)
      .defaultToolCallbacks(*toolCallbackProviders.toTypedArray())
  }
}
チャットサービス

チャットサービスは、チャット ID とユーザーの質問を受け取る単一の chat メソッドを公開します。ユーザーの質問と一連のアドバイザーを チャットクライアントに渡し、やり取りを充実させます。

  • QuestionAnswerAdvisor - ベクトルストアから関連するコンテキストを取得し、コンテキストに追加します(RAG)
  • MessageChatMemoryAdvisor - 指定されたチャット ID の会話履歴をユーザー入力に追加します(チャットメモリ)
  • SimpleLoggerAdvisor - 内部アドバイザーのトレースをコンソールに記録します(logging.level.org.springframework.ai.chat.client.advisor が DEBUG に設定されている場合)

また、質問と回答もコンソールに記録されます。

実装は次のとおりです。

@Service // or @Bean / @Component
class ChatService(
  vectorStore: VectorStore,
  private val clock: Clock,
  private val chatClient: ChatClient
) {
  private val logger = LoggerFactory.getLogger(ChatService::class.java)
  private val questionAnswerAdvisor = QuestionAnswerAdvisor.builder(vectorStore).build()
  private val simpleLoggerAdvisor = SimpleLoggerAdvisor()
  private val chatMemoryAdvisor = MessageChatMemoryAdvisor.builder(
    MessageWindowChatMemory.builder()
      .chatMemoryRepository(InMemoryChatMemoryRepository())
      .build()
  ).build()

  fun chat(chatId: String, question: String): String {
    return chatClient
      .prompt()
      .system { it.param("currentDate", LocalDate.now(clock)) }
      .user(question)
      .advisors(questionAnswerAdvisor, chatMemoryAdvisor, simpleLoggerAdvisor)
      .advisors { a -> a.param(ChatMemory.CONVERSATION_ID, chatId) }
      .call()
      .content().apply {
        logger.info("Chat #$chatId question: $question")
        logger.info("Chat #$chatId answer: $this")
      }!!
  }
}
チャットコントローラー

チャットコントローラーは、ユーザー入力を受け取り、チャットサービスを呼び出して、AI エージェントの応答を返すシンプルな REST POST エンドポイントを公開します。

@RestController
class ChatController(private val chatService: ChatService) {
  @PostMapping("/{chatId}/chat")
  fun chat(
    @PathVariable chatId: String, 
    @RequestParam question: String
  ): String? {
    return chatService.chat(chatId, question)
  }
}
ベクトルストアの初期化

Spring AIの自動構成済み VectorStore を使用して、ドキュメントを追加するだけです。これにより、埋め込みモデルが自動的に呼び出され、埋め込みが生成されてベクトルストアに保存されます。

@Bean
fun vectorStoreInitializer(vectorStore: VectorStore) = 
  ApplicationRunner {
    // TODO check if the vector store is empty ...
    // TODO load cities from a JSON file or any other source ...
    cities.forEach { city ->
      val document = Document(
        "name: ${city.name} " +
        "country: ${city.country} " +
        "description: ${city.description}"
      )
      vectorStore.add(listOf(document))
    }
  }

vectorStoreInitializer の完全版は、ChatServerApplication.kt にあります。

設定

spring.ai.model.embedding(スカラー値で、Bedrock と Ollama で使用)と spring.ai.model.embedding.text(ネストされた値で、Gemini で使用)を同時に指定できないため、application.yml の代わりに application.properties を使用します。いつか解決されるかもしれませんが、いずれにしても、これは複数のモデルをサポートする概念実証(PoC)です。実運用アプリケーションでは、おそらく 1 つだけを使用するため、問題にはなりません。

このファイルでは、次のグローバル設定値を定義します。

  • すべてのモデルの自動構成をデフォルトで無効にします。
  • PostgreSQL データベースに接続するようデータソースを設定し、PGVector をサポートします。
  • サーバーのポートを 8080 に設定します。
  • リモート Booking Tool MCP サーバーの URL を設定します。
  • チャットアドバイザーのデバッグトレースのログレベルを設定します。
spring.application.name=chat-server

spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=password
spring.datasource.driver-class-name=org.postgresql.Driver

spring.ai.model.chat=none
spring.ai.model.embedding=none
spring.ai.model.embedding.text=none

spring.ai.mcp.client.toolcallback.enabled=true
spring.ai.mcp.client.sse.connections.booking-tool.url=http://localhost:8081

server.port=8080

logging.level.org.springframework.ai.chat.client.advisor=INFO

AI モデルは Spring プロファイルで設定します。各プロファイルでは、チャットモデル、埋め込みモデル、ベクトルストアの次元数を設定します。実行時に SPRING_PROFILES_ACTIVE を使用して、アクティブなプロファイルを指定する必要があります。

Ollama プロファイル

application-ollama.yml では、Ollama モデルを使用するよう Spring AI を設定します。

  • Ollama サーバーのベース URL を http://localhost:11434 に設定します。
  • チャットモデルを llama3.1:8b に設定します(tools 対応モデルである必要があります)。
  • 埋め込みモデルを nomic-embed-text に設定します。
  • pull-model-strategy: when_missing を使用して、モデルがローカルにない場合にのみプルします。
  • PGVector をベクトルストアとして設定し、次元数を 768 にします(埋め込みモデルのサイズに合わせます)。
spring:
  ai:
    model:
      embedding: "ollama"
      chat: "ollama"
    ollama:
      base-url: "http://localhost:11434"
      init:
        pull-model-strategy: "when_missing"
      chat:
        options:
          model: "llama3.1:8b"
      embedding:
        options:
          model: "nomic-embed-text"
    vectorstore:
      pgvector:
        table-name: "vector_store_ollama"
        dimensions: 768
        initialize-schema: true
Gemini プロファイル

application-gemini.yml では、Google Gemini モデルを使用するよう Spring AI を設定します。

  • GOOGLE_API_KEY 環境変数から Google API キーを設定します。
  • チャットモデルを gemini-2.5-flash に設定します。
  • 埋め込みモデルを gemini-embedding-001 に設定し、次元数を 768 にします。
  • PGVector をベクトルストアとして設定し、次元数を 768 にします。
spring:
  ai:
    model:
      chat: "google-genai"
      embedding:
        text: "google-genai"
    google:
      genai:
        api-key: "${GOOGLE_API_KEY}"
        chat:
          options:
            model: "gemini-2.5-flash"
            temperature: 0.7
        embedding:
          api-key: "${GOOGLE_API_KEY}"
          text:
            options:
              model: "gemini-embedding-001"
              dimensions: 768
    vectorstore:
      pgvector:
        table-name: "vector_store_gemini"
        dimensions: 768
        initialize-schema: true
Bedrock プロファイル

application-bedrock.yml では、AWS Bedrock モデルを使用するよう Spring AI を設定します。

  • 環境変数から AWS 認証情報とリージョンを設定します。
  • Bedrock Converse API を使用してチャットモデルを設定します。
  • Bedrock Cohere を使用して埋め込みモデルを設定します。
  • PGVector をベクトルストアとして設定し、次元数を 1024 にします(Cohere 埋め込みモデルのサイズに合わせます)。
spring:
  ai:
    model:
      embedding: "bedrock-cohere"
      chat: "bedrock-converse"
    bedrock:
      aws:
        access-key: "${AWS_ACCESS_KEY_ID}"
        secret-key: "${AWS_SECRET_ACCESS_KEY}"
        region: "${AWS_REGION:eu-central-1}"
      converse:
        chat:
          options:
            model: "${AWS_BEDROCK_CHAT_MODEL}"
            max-tokens: 2048
      cohere:
        embedding:
          model: "${AWS_BEDROCK_EMBEDDING_MODEL}"
    vectorstore:
      pgvector:
        table-name: "vector_store_bedrock"
        dimensions: 1024
        initialize-schema: true

テスト

MCP サーバーのテスト

MCP サーバーをテストするために、McpClient を使用して、下流の BookingService をモックしながら、Booking Tool の book メソッドを呼び出します。

MCP サーバーのテスト

以下に簡略化したテストの実装を示します。利用可能なツールの一覧を検証するテストを含む完全な実装については、McpServerApplicationTest.kt を参照してください。

@SpringBootTest(webEnvironment = RANDOM_PORT)
class McpServerApplicationTest {

  // 1. Inject the server port (it is random)
  @LocalServerPort
  val port: Int = 0

  // 2. Mock the BookingService instance
  @MockitoBean
  lateinit var bookingService: BookingService

  @Test
  fun `should book`() {
    // 3. Create a McpClient connected to the server
    val client = McpClient.sync(
      HttpClientSseClientTransport("http://localhost:$port")
    ).build()
    client.initialize()
    client.ping()

    // 4. Mock the bookingService using argument captors
    val bookResult = "Booking is done!"
    val cityCaptor = argumentCaptor<String>()
    val checkinDateCaptor = argumentCaptor<LocalDate>()
    val checkoutDateCaptor = argumentCaptor<LocalDate>()
    doReturn(bookResult)
      .whenever(bookingService)
      .book(
        cityCaptor.capture(),
        checkinDateCaptor.capture(),
        checkoutDateCaptor.capture()
      )

    // 5. Call the tool
    val city = "Barcelona"
    val checkinDate = LocalDate.parse("2025-04-15")
    val checkoutDate = LocalDate.parse("2025-04-18")
    val result = client.callTool(CallToolRequest(
      "book",
      mapOf(
        "city" to city,
        "checkinDate" to checkinDate.toEpochDay(),
        "checkoutDate" to checkoutDate.toEpochDay()
      )
    ))

    // 6. Verify the result
    assertThat(result.isError).isFalse()
    assertThat(result.content).singleElement()
      .isInstanceOfSatisfying(TextContent::class.java) {
        // TODO why is text double quoted?
        assertThat(it.text).isEqualTo("\"$bookResult\"")
      }

    // 7. Verify that the bookingService was called with
    // the correct parameters
    assertThat(cityCaptor.allValues).singleElement()
      .isEqualTo(city)
    assertThat(checkinDateCaptor.allValues).singleElement()
      .isEqualTo(checkinDate)
    assertThat(checkoutDateCaptor.allValues).singleElement()
      .isEqualTo(checkoutDate)

    // 8. Close the client
    client.close()
  }
}

MCP サーバーのテストを実行するには:

cd mcp-server
./gradlew test
チャットサーバーのテスト

チャットサーバーをテストするために、以下を行います。

  • application-test.yml でデフォルトのプロファイルを gemini に上書きし、MCP クライアントを無効にします(SPRING_PROFILES_ACTIVE で上書きできます)。
  • リモートの 予約ツール を、同じシグネチャを持つローカルの 予約テストツール に置き換えます。
  • 下流サービスの 天気サービス と 予約サービス を MockitoBean でモックします。
  • ClockTestToolConfiguration.kt で、現在の日付を制御する固定の Clock を作成します。
    • デフォルトの Clock Bean を上書きするため、@Primary @Bean として宣言します。
  • Testcontainers を使用して、PGVector を含む Docker Compose を起動します。

チャットサーバーのテスト

お気づきかもしれませんが、MCP クライアントが無効になっているため、このテストでは実際には MCP クライアントの SSE 接続を確認していません。McpServerAutoConfiguration を使って McpServer を起動しようとしたところ、ほぼうまくいきました。問題は、サーバーの起動前にクライアントが接続しようとし、その結果、アプリケーション全体の起動に失敗することです。単なる順序の問題かもしれませんし、今後修正されることを願っています 🤞

では、興味深い部分です。AI エージェントの応答はどのようにテストすればよいのでしょうか。ここで 評価テスト の出番です。

応答を評価する方法の 1 つは、AI モデル自体を使って評価することです。評価には最適な AI モデルを選びます。応答の生成に使用したモデルと同じである必要はありません。

これは、Martin Fowler の GenAI パターン Evals で説明されている評価手法と一致します。

  • 自己評価:LLM が自身の応答を評価しますが、自身の誤りや偏見を強化してしまう可能性があります。
  • LLM を判定役として使う:別のモデルが出力を採点し、セカンドオピニオンを取り入れることで偏見を抑えます。
  • 人による評価:人が応答を手作業でレビューし、語調や意図が適切に感じられるかを確認します。

シンプルにするため、自己評価を採用します 🤓

各テストは、次の構成に従います。

@Test
fun `should do something`() {
  // 1. Mock downstream service(s)
  // Optionally use argument captors depending on how you plan
  // to verify parameters in step 5
  // Example for BookingService:
  doReturn("Your booking is done!")
    .whenever(bookingTestService).book(any(), any(), any())

  // 2. Call the chat service
  val chatId = UUID.randomUUID().toString()
  val chatResponse = chatService.chat(
    chatId, 
    "Can you book accommodation for Barcelona from 2025-04-15 to 2025-04-18?"
  )
  
  // 3. Evaluate the response using the AI model
  val evaluationResult = TestEvaluator(chatClientBuilder) { evaluationRequest, userSpec ->
    userSpec.text(
      """
      Your task is to evaluate if the answer given by an AI agent to a human user matches the claim.
      Return YES if the answer matches the claim and NO if it does not.
      After returning YES or NO, explain why.
      Assume that today is ${LocalDate.now(clock)}.
      Answer: {answer}
      Claim: {claim}
      """.trimIndent()
    )
      .param("answer", evaluationRequest.responseContent)
      .param("claim", evaluationRequest.userText)
  }.evaluate(EvaluationRequest(
    "Accommodation has been booked Barcelona from 2025-04-15 to 2025-04-18", 
    chatResponse
  ))
  
  // 4. Assert the evaluation result is successful, show feedback if not
  assertThat(evaluationResult.isPass).isTrue
    .withFailMessage { evaluationResult.feedback }
  
  // 5. If applicable, verify the parameters passed to the service
  // You can verify with argument captors or use the `verify` method as in the example below:
  verify(bookingTestService).book(
    eq("Barcelona"), 
    eq(LocalDate.parse("2025-04-15")), 
    eq(LocalDate.parse("2025-04-18"))
  )
}

完全なテスト実装は ChatServerApplicationTest.kt を参照してください。

各評価では、テスト対象の応答に合わせたカスタムプロンプトを使用します。試してみると、驚くほど風変わりな動作に気づくでしょう。そのため、Spring AI の RelevancyEvaluator と FactCheckingEvaluator をベースにしたカスタム TestEvaluator を作成しましたが、まだ必要なレベルのカスタマイズには対応できていないかもしれません。

予想外の結果に遭遇するたびに、プロンプトを調整する必要がありました。たとえば、評価モデルがまだ 2023 年だと思い込み、AI エージェントが 2025 年の天気を予測できることを信じようとしなかったり、回答中の「あなた」をユーザーではなく自分自身のことだと勘違いしたりしました。最も奇妙だったのは、ある評価が「NO」とだけ答えたのに、説明では「うーん、YES と言うべきだったかもしれません」と述べていたことです 🤣

本番システムでは、システムと評価モデルの両方について、期待どおりに動作させるために、プロンプトの調整とテストを十分に行う必要があるでしょう。GenAI を扱う「楽しさ」の一部なのだと思います。

デフォルトでは、ローカルと CI の両方でテストに Gemini プロファイルを使用します(GOOGLE_API_KEY が必要です)。

cd chat-server
./gradlew test

Ollama を使ってローカルでテストするには(Ollama をローカルで実行する が起動している必要があります。十分な GPU ハードウェアがないと、結果が不安定になる場合があります)。

cd chat-server
SPRING_PROFILES_ACTIVE=ollama ./gradlew test

Bedrock を使ってローカルでテストするには(AWS 認証情報が必要です)。

cd chat-server
SPRING_PROFILES_ACTIVE=bedrock ./gradlew test

実行

環境変数またはルートディレクトリにある system.properties ファイルを使用して、アプリケーションを設定できます。このファイルは Git の対象外であり、./gradlew bootRun とテストの両方で読み込まれます。

system.properties の例:

# AWS Bedrock
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=eu-central-1
AWS_BEDROCK_CHAT_MODEL=...
AWS_BEDROCK_EMBEDDING_MODEL=...

# Google Gemini
GOOGLE_API_KEY=...
ベクトルデータベースの起動

すべてのプロファイルで、RAG ベクトルデータベースに PGVector が必要です。

cd chat-server
docker compose -f docker-compose-vectordb.yml up -d

停止するには:

cd chat-server
docker compose -f docker-compose-vectordb.yml down

停止してすべてのボリュームを削除するには(ベクトルデータベースのデータがすべて削除されます):

cd chat-server
docker compose -f docker-compose-vectordb.yml down -v
Ollama をローカルで実行する

ローカルの LLM を使用する場合は、Docker Compose またはネイティブアプリケーションとして Ollama を実行できます(詳しくは ollama.com をご覧ください)。

cd chat-server
docker compose -f docker-compose-ollama.yml up -d

停止するには:

cd chat-server
docker compose -f docker-compose-ollama.yml down
アプリケーションの起動
  1. MCP サーバーを起動します
cd mcp-server
./gradlew bootRun
  1. 次のいずれかのプロファイルでチャットサーバーを起動します:

Ollama(Ollama と ベクトルデータベース が必要です):

cd chat-server
SPRING_PROFILES_ACTIVE=ollama ./gradlew bootRun

Gemini(ベクトルデータベース と GOOGLE_API_KEY が必要です):

cd chat-server
SPRING_PROFILES_ACTIVE=gemini ./gradlew bootRun

Bedrock(ベクトルデータベース と AWS 認証情報が必要です):

cd chat-server
SPRING_PROFILES_ACTIVE=bedrock ./gradlew bootRun
  1. チャットを開始します

シンプルなチャット UI を http://localhost:8080/chat.html で利用できます(注:この UI は完全に AI によって生成されました。この PoC の目的はフロントエンドではありません)。

http://localhost:8080/swagger-ui.html で API エンドポイントを確認することもできます。

その他の AI モデルの使用方法

Spring AI がサポートする他の AI モデルを使用するには、次の手順に従ってください:

  • 必要な依存関係を追加します
  • モデルを専用の application-<model>.yml ファイルで設定します
  • SPRING_PROFILES_ACTIVE=<model> を使用してプロファイルを有効にします

ドキュメント

GenAI のコーディングをお楽しみください! 💙

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。