こんにちは、エキサイト株式会社の平石です。
エキサイトホールディングス Advent Calendar 2024のシリーズ2, 16日目を担当いたします。
今回は、Spring AIを利用してECS環境からAmazon Bedrockに接続する方法をご紹介します。
はじめに
Spring AIとは
Spring AIはSpringからAIモデルを利用するためのフレームワークです。
SpringがAIモデルを提供しているわけではなく、SpringアプリケーションからAIプロバイダーにリクエストを送り、レスポンスを受け取る部分をAPIとして提供してくれます。
今回紹介するAmazon Bedrock以外にも、OpenAIやStabilityAIなど多くのプロバイダーに対応しています。
Amazon Bedrockとは
Amazon Bedrockは、AWS上で生成AIを利用できるようにするフルマネージドサービスです。
既存のモデルを容易に利用することもできますし、用途やデータに合わせてカスタマイズすることも可能です。
環境
この記事のソースコードは以下の環境で動作確認をしています。
- Java 21
- SpringBoot 3.2.1
- Gradle 8.5
依存関係
Spring AIを利用するためのGradleの依存関係は以下のとおりです。
allprojects { repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } maven { url 'https://repo.spring.io/snapshot' } } } 〜〜 略 〜〜 project(':project1:controller') { dependencies { 〜〜 略 〜〜 implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-SNAPSHOT") implementation 'org.springframework.ai:spring-ai-bedrock-ai-spring-boot-starter' } }
Spring AIのライブラリは2024年9月30日時点でMaven Centralにはないため、個別にrepositoryを指定する必要があります。
AWS認証情報の設定
まずは、Bedrockに接続するためのAWS認証情報の設定を行います。
@Configuration public class BedrockApiConfig { @Bean @Profile("local") public AwsCredentialsProvider awsDefaultCredentialsProvider() { return DefaultCredentialsProvider.builder() .profileName("sample-profile-name") .build(); } @Bean @Profile("!local") public AwsCredentialsProvider awsContainerCredentialsProvider() { return ContainerCredentialsProvider.builder().build(); } }
Spring AIに対してAWSの認証情報を渡すためにはAwsCredentialsProvider
を実装したクラスのインスタンスを用意する必要があります。
ローカル環境で実行するときには、DefaultCredentialsProvider
を用いてprofileName
で指定したプロファイル名で設定したアクセスキーやAWS SSOを用いてBedrockにアクセスできます。
当然、ECS環境内でもローカル環境と同じようにアクセスキーを発行してアクセスすることも可能ですが、より簡単な方法があります。
それは、AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
またはAWS_CONTAINER_CREDENTIALS_FULL_URI
という環境変数を用いる方法です。(基本的にはAWS_CONTAINER_CREDENTIALS_RELATIVE_URI
がセットされているはず)
コンテナが起動するとAWS_CONTAINER_CREDENTIALS_RELATIVE_URI
という環境変数に自動的に値がセットされます。この環境変数にセットされたURIにアクセスするとAWSの各サービスにアクセスするための認証情報を取得できます。
ContainerCredentialsProvider
を使うと環境変数を参照し、認証情報を取得する一連の処理を自動でやってくれます。*1
今回は、ECS環境からBedrockにアクセスすることが目的ですが、ローカル環境での動作確認も開発上必要になることも考えられます。
そのため、@Profile
を用いてローカル環境かどうかで使うAwsCredentialsProvider
を切り替えています。*2
Bedrockに接続するための設定
実際にBedrockに接続するためには、利用するモデルに対応するクラスを利用します。
以下から、ご自身が利用したいモデルに対応するクラスをご確認ください。
Chat Model API :: Spring AI Reference
今回はAnthropic3のClaude 3.5というモデルを利用します。
Claude 3.5に対応するクラスはAnthropic3ChatBedrockApi
とBedrockAnthropic3ChatModel
です。
@Configuration public class BedrockApiConfig { // 略 @Bean public Anthropic3ChatBedrockApi anthropic3ChatBedrockApi(final AwsCredentialsProvider awsCredentialsProvider) { return new Anthropic3ChatBedrockApi( Anthropic3ChatBedrockApi.AnthropicChatModel.CLAUDE_V3_5_SONNET.id(), awsCredentialsProvider, Region.AP_NORTHEAST_1.id(), new ObjectMapper() ); } @Bean public BedrockAnthropic3ChatModel bedrockAnthropic3ChatModel(final Anthropic3ChatBedrockApi anthropic3ChatBedrockApi) { return new BedrockAnthropic3ChatModel( anthropic3ChatBedrockApi, Anthropic3ChatOptions.builder() .withMaxTokens(4000) .withAnthropicVersion(Anthropic3ChatBedrockApi.DEFAULT_ANTHROPIC_VERSION) .build()); } }
Anthropic3ChatBedrockApi
で東京リージョン(Region.AP_NORTHEAST_1.id()
)でClaude 3.5(Anthropic3ChatBedrockApi.AnthropicChatModel.CLAUDE_V3_5_SONNET.id()
)を指定した認証情報で利用するように設定しています。
また、BedrockAnthropic3ChatModel
ではAnthropic3ChatOptions
を用いて、Claudeモデルに関する設定を行っています。
上のソースコードで設定した以外にも設定項目はありますので、詳細は以下をご確認ください。
実際に、Bedrockにリクエストを送信するには以下のように記述します。
@RestController @RequiredArgsConstructor @RequestMapping("bedrock/sample") public class BedrockTestController { private final BedrockAnthropic3ChatModel bedrockAnthropic3ChatModel; @GetMapping public String callBedrockApi() { final String prompt = "Hello!" return bedrockAnthropic3ChatModel.call(prompt); } }
SpringBoot アプリケーションを起動しhttp://localhost:{ポート番号}/bedrock/sample
にアクセスすると、以下のようなレスポンスが得られます。
Hello! How can I assist you today? Feel free to ask me any questions or let me know if you need help with anything.
おわりに
今回は、Spring AIを利用してECS環境からAmazon Bedrockに接続する方法をご紹介しました。
次回は、ECSコンテナとAmazon Bedrockの間でのPrivateLinkを確立する方法をご紹介します。
では、また次回。