Generative AI Use Cases (GenU) で別 AWS アカウントの Bedrock Knowledge Bases / Bedrock Agents を使ってみた
いわさです。
前回、GenU で別アカウントの Bedrock を使って Model Invoke する構成を試しました。
GenU ではオプションで Bedrock Knowledge Bases と Bedrock Agents もサポートしており、これらを使う場合は追加のクロスアカウント設定が必要となります。
今回は Bedrock Knowledge Bases と Bedrock Agents もクロスアカウント構成で使う場合の GenU 設定を行ってみましたので手順などを紹介します。
クロスアカウント構成を行わない場合の Bedrock Knowledge Bases / Bedrock Agents オプションの有効化方法
オプション機能の有効化は前回と同様にparameter.ts
もしくはcdk.json
を編集します。
GenU では通常のチャット機能とは別でオプションの RAG チャット機能を有効化できます。
Amazon Kendra と Bedrock Knowledge Bases を使うことができまして、今回は Bedrock Knowledge Bases を使います。[1]
ragKnowledgeBaseEnabled
をtrue
に設定することで有効化が可能です。
有効化の際にragKnowledgeBaseId
を設定することで既存のナレッジベースを使うことができ、設定しない場合は新しいナレッジベースが新規作成されます。
また、Agents for Amazon Bedrock を使ったアクションを実行できる Agent チャット機能を有効化することもできます。[2]
agentEnabled
やsearchAgentEnabled
を有効化することで新規エージェントの自動作成が可能です。既存エージェントを使いたい場合はagentEnabled
を設定せずにagents
にagentId
とaliasId
を指定します。
上記を設定することで RAG チャットと Agent チャットのユースケースを有効化できます。簡略化した図が次のような感じで Lambda 経由でそれぞれの機能が利用されています。
クロスアカウント構成を行う場合の Bedrock Knowledge Bases / Bedrock Agents オプションの有効化方法
本題のクロスアカウント構成ですが、先程のオプションで既存のナレッジベース、既存のエージェントを設定することが出来ましたが、ここで別アカウントのナレッジベース、エージェントを指定します。
それに加えて前回の記事のようにcrossAccountBedrockRoleArn
を指定すると、あとはそれぞれの Lambda 関数内でクロスアカウントで処理されるように自動で切り替わります。
簡略化した図でいうとこんな感じです。
クロスアカウントで有効化してみる
GenU をデプロイするのがアカウントA、Bedrock の各機能の有効化しているのがアカウントBとします。
デプロイの流れは次のような感じです。
- アカウントBでナレッジベースやエージェントを作成し、クロスアカウント用の IAM ロールを仮作成する
- アカウントAに GenU をデプロイする。デプロイの際にアカウントBの IAM ロール、ナレッジベースとエージェントの ID などを指定する
- アカウントBのクロスアカウント用 IAM ロールでアカウントAの GenU でデプロイされた IAM ロールを信頼する
アカウントBでナレッジベースやエージェントを作成し、クロスアカウント用の IAM ロールを仮作成する
まずはアカウントBで Bedrock Knowledge Bases と Bedrock Agents を有効化します。
自分で作成しても良いですが、今回はアカウントBにも GenU をデプロイし、Bedrock Knowledge Bases と Bedrock Agents を自動デプロイさせました。
{
:
"context": {
"env": "",
"ragEnabled": false,
"kendraIndexArn": null,
"kendraIndexLanguage": "ja",
"kendraDataSourceBucketName": null,
"kendraIndexScheduleEnabled": false,
"kendraIndexScheduleCreateCron": null,
"kendraIndexScheduleDeleteCron": null,
+ "ragKnowledgeBaseEnabled": true,
+ "ragKnowledgeBaseId": null,
"ragKnowledgeBaseStandbyReplicas": false,
"ragKnowledgeBaseAdvancedParsing": false,
"ragKnowledgeBaseAdvancedParsingModelId": "anthropic.claude-3-sonnet-20240229-v1:0",
"ragKnowledgeBaseBinaryVector": false,
"embeddingModelId": "amazon.titan-embed-text-v2:0",
"rerankingModelId": null,
"queryDecompositionEnabled": false,
"selfSignUpEnabled": true,
"allowedSignUpEmailDomains": null,
"samlAuthEnabled": false,
"samlCognitoDomainName": "",
"samlCognitoFederatedIdentityProviderName": "",
"hiddenUseCases": {},
"modelRegion": "us-east-1",
"modelIds": [
"us.anthropic.claude-3-7-sonnet-20250219-v1:0",
"us.anthropic.claude-3-5-haiku-20241022-v1:0",
"us.amazon.nova-premier-v1:0",
"us.amazon.nova-pro-v1:0",
"us.amazon.nova-lite-v1:0",
"us.amazon.nova-micro-v1:0",
"us.deepseek.r1-v1:0"
],
"imageGenerationModelIds": ["amazon.nova-canvas-v1:0"],
"videoGenerationModelIds": ["amazon.nova-reel-v1:0"],
"speechToSpeechModelIds": ["amazon.nova-sonic-v1:0"],
"endpointNames": [],
+ "agentEnabled": true,
+ "searchAgentEnabled": false,
+ "searchApiKey": "",
+ "agents": [],
"inlineAgents": false,
"flows": [],
"allowedIpV4AddressRanges": null,
"allowedIpV6AddressRanges": null,
"allowedCountryCodes": null,
"hostName": null,
"domainName": null,
"hostedZoneId": null,
"dashboard": false,
"anonymousUsageTracking": true,
"guardrailEnabled": false,
+ "crossAccountBedrockRoleArn": "",
"useCaseBuilderEnabled": true,
:
}
}
そうするとデフォルトでバージニア北部リージョンに追加のスタックが作成されると思います。
Bedrock コンソールからナレッジベースの ID と、エージェントの ID とエイリアス ID を確認しておきましょう。
なお、ナレッジベースのベクトルデータストアは OpenSearch Serverless コレクションが自動デプロイされ使われています。
そして、前回と同様にクロスアカウント用の IAM ロールを作成します。
この時点ではまだ信頼すべきアカウントAの情報がわからないので、信頼ポリシーは適当な仮のもので良いです。
許可ポリシーはドキュメントに従って次のように設定します。
前回の記事に加えて対象のナレッジベースと、ナレッジベースのデータソースへのアクセスを追加しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowBedrockInvokeModel",
"Effect": "Allow",
"Action": [
"bedrock:Invoke*",
"bedrock:Rerank",
"bedrock:GetInferenceProfile",
"bedrock:GetAsyncInvoke",
"bedrock:ListAsyncInvokes",
"bedrock:GetAgent*",
"bedrock:ListAgent*"
],
"Resource": ["*"]
},
{
"Sid": "AllowS3PutObjectToVideoTempBucket",
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": ["arn:aws:s3:::videotmpbucketstackus-east-1-bucket83908e77-fjfjii5g5lyh/*"]
},
{
"Sid": "AllowBedrockRetrieveFromKnowledgeBase",
"Effect": "Allow",
"Action": ["bedrock:RetrieveAndGenerate*", "bedrock:Retrieve*"],
"Resource": [
"arn:aws:bedrock:us-east-1:222222222222:knowledge-base/YQNZGGCUVF"
]
},
{
"Sid": "AllowS3GetPresignedUrl",
"Effect": "Allow",
"Action": ["s3:GetObject*"],
"Resource": ["arn:aws:s3:::ragknowledgebasestack-datasourcebucket9fa93e04-4ubgpbbpwyzu/*"]
}
]
}
アカウントAに GenU をデプロイする。デプロイの際にアカウントBの IAM ロール、ナレッジベースとエージェントの ID などを指定する
アカウントBの準備が出来たので、アカウントAに GenU をデプロイします。
デプロイオプションは次のように指定します。
{
:
"context": {
"env": "",
"ragEnabled": false,
"kendraIndexArn": null,
"kendraIndexLanguage": "ja",
"kendraDataSourceBucketName": null,
"kendraIndexScheduleEnabled": false,
"kendraIndexScheduleCreateCron": null,
"kendraIndexScheduleDeleteCron": null,
+ "ragKnowledgeBaseEnabled": true,
+ "ragKnowledgeBaseId": "YQNZGGCUVF",
"ragKnowledgeBaseStandbyReplicas": false,
"ragKnowledgeBaseAdvancedParsing": false,
"ragKnowledgeBaseAdvancedParsingModelId": "anthropic.claude-3-sonnet-20240229-v1:0",
"ragKnowledgeBaseBinaryVector": false,
"embeddingModelId": "amazon.titan-embed-text-v2:0",
"rerankingModelId": null,
"queryDecompositionEnabled": false,
"selfSignUpEnabled": true,
"allowedSignUpEmailDomains": null,
"samlAuthEnabled": false,
"samlCognitoDomainName": "",
"samlCognitoFederatedIdentityProviderName": "",
"hiddenUseCases": {},
"modelRegion": "us-east-1",
"modelIds": [
"us.anthropic.claude-3-7-sonnet-20250219-v1:0",
"us.anthropic.claude-3-5-haiku-20241022-v1:0",
"us.amazon.nova-premier-v1:0",
"us.amazon.nova-pro-v1:0",
"us.amazon.nova-lite-v1:0",
"us.amazon.nova-micro-v1:0",
"us.deepseek.r1-v1:0"
],
"imageGenerationModelIds": ["amazon.nova-canvas-v1:0"],
"videoGenerationModelIds": ["amazon.nova-reel-v1:0"],
"speechToSpeechModelIds": ["amazon.nova-sonic-v1:0"],
"endpointNames": [],
+ "agentEnabled": false,
+ "searchAgentEnabled": false,
+ "searchApiKey": "",
+ "agents": [
+ {
+ "displayName": "CodeInterpreterAgent-WebSearchAgentStackAgent49BCEDE6",
+ "agentId": "KFXJODLSWG",
+ "aliasId": "TBBIXYVSZP"
+ }
+ ],
"inlineAgents": false,
"flows": [],
"allowedIpV4AddressRanges": null,
"allowedIpV6AddressRanges": null,
"allowedCountryCodes": null,
"hostName": null,
"domainName": null,
"hostedZoneId": null,
"dashboard": false,
"anonymousUsageTracking": true,
"guardrailEnabled": false,
+ "crossAccountBedrockRoleArn": "arn:aws:iam::222222222222:role/hoge0525crossaccount",
"useCaseBuilderEnabled": true,
:
}
}
ちなみに、crossAccountBedrockRoleArn
を指定した場合、アカウントA上でナレッジベースやエージェントの自動作成は出来ません。既存のIDを必ず指定する必要があって、指定しない場合はデプロイに失敗するようになっています。
ナレッジベースのデプロイ失敗の様子
% npm run cdk:deploy -- --profile hoge
> generative-ai-use-cases@4.2.3 cdk:deploy
> npm -w packages/cdk run cdk deploy -- --all --profile hoge
> cdk
> cdk deploy --all --profile hoge
/Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/packages/cdk/lib/rag-knowledge-base-stack.ts:162
throw new Error(
^
Error: With `crossAccountBedrockRoleArn` specified, you must use an existing knowledge base. Create a knowledge base in your Bedrock account and provide its `knowledgeBaseId`.
at new RagKnowledgeBaseStack (/Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/packages/cdk/lib/rag-knowledge-base-stack.ts:162:13)
at createStacks (/Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/packages/cdk/lib/create-stacks.ts:44:9)
at Object.<anonymous> (/Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/packages/cdk/bin/generative-ai-use-cases.ts:9:13)
at Module._compile (node:internal/modules/cjs/loader:1546:14)
at Module.m._compile (/Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/node_modules/ts-node/src/index.ts:1618:23)
at node:internal/modules/cjs/loader:1689:10
at Object.require.extensions.<computed> [as .ts] (/Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/node_modules/ts-node/src/index.ts:1621:12)
at Module.load (node:internal/modules/cjs/loader:1318:32)
at Function._load (node:internal/modules/cjs/loader:1128:12)
at TracingChannel.traceSync (node:diagnostics_channel:315:14)
npx ts-node --prefer-ts-exts bin/generative-ai-use-cases.ts: Subprocess exited with error 1
npm error Lifecycle script `cdk` failed with error:
npm error code 1
npm error path /Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/packages/cdk
npm error workspace cdk
npm error location /Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/packages/cdk
npm error command failed
npm error command sh -c cdk deploy --all --profile hoge
エージェントのデプロイ失敗の様子
% npm run cdk:deploy -- --profile hoge
> generative-ai-use-cases@4.2.3 cdk:deploy
> npm -w packages/cdk run cdk deploy -- --all --profile hoge
> cdk
> cdk deploy --all --profile hoge
/Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/packages/cdk/lib/create-stacks.ts:57
throw new Error(
^
Error: When `crossAccountBedrockRoleArn` is specified, the `agentEnabled` and `searchApiKey` parameters are not supported. Please create agents in the other account and specify them in the `agents` parameter.
at createStacks (/Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/packages/cdk/lib/create-stacks.ts:57:13)
at Object.<anonymous> (/Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/packages/cdk/bin/generative-ai-use-cases.ts:9:13)
at Module._compile (node:internal/modules/cjs/loader:1546:14)
at Module.m._compile (/Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/node_modules/ts-node/src/index.ts:1618:23)
at node:internal/modules/cjs/loader:1689:10
at Object.require.extensions.<computed> [as .ts] (/Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/node_modules/ts-node/src/index.ts:1621:12)
at Module.load (node:internal/modules/cjs/loader:1318:32)
at Function._load (node:internal/modules/cjs/loader:1128:12)
at TracingChannel.traceSync (node:diagnostics_channel:315:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:218:24)
npx ts-node --prefer-ts-exts bin/generative-ai-use-cases.ts: Subprocess exited with error 1
npm error Lifecycle script `cdk` failed with error:
npm error code 1
npm error path /Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/packages/cdk
npm error workspace cdk
npm error location /Users/iwasa.takahito/work/hoge0525genu/generative-ai-use-cases/packages/cdk
npm error command failed
npm error command sh -c cdk deploy --all --profile hoge
デプロイ後に GenU にアクセスしてみると、RAG チャットと Agent チャットユースケースが有効化されていることが確認できます。
ただし、アカウントA上には Bedrock Knowledge Bases も Bedrock Agents もデプロイされていません。
アカウントBのクロスアカウント用 IAM ロールでアカウントAの GenU でデプロイされた IAM ロールを信頼する
で、このままだとまだアカウントAの GenU がアカウントBにアクセスする権限がないので、最後に GenU でデプロイされた各 IAM ロールから、アカウントBのクロスアカウント用 IAM ロールに Assume できるように信頼してやります。[3]
実際の IAM ロール名には CloudFormation によって自動生成されたランダムな文字列が追加されているので、対象 IAM ロールをもとにアカウントA上で実際の IAM ロール名を探します。
対象IAMロール | 実際のIAMロール名 |
---|---|
GenerativeAiUseCasesStack-APIPredictTitleService | GenerativeAiUseCasesStack-APIPredictTitleServiceRol-KCogLtsITlVx |
GenerativeAiUseCasesStack-APIPredictService | GenerativeAiUseCasesStack-APIPredictServiceRole6B8A-63OZMHLPel2H |
GenerativeAiUseCasesStack-APIPredictStreamService | GenerativeAiUseCasesStack-APIPredictStreamServiceRo-Lffng0T8GlEg |
GenerativeAiUseCasesStack-APIGenerateImageService | GenerativeAiUseCasesStack-APIGenerateImageServiceRo-0ktKYg1PlapO |
GenerativeAiUseCasesStack-APIGenerateVideoService | GenerativeAiUseCasesStack-APIGenerateVideoServiceRo-NNDcJ7Vn3cwq |
GenerativeAiUseCasesStack-APIListVideoJobsService | GenerativeAiUseCasesStack-APIListVideoJobsServiceRo-byMmv45ug1GY |
GenerativeAiUseCasesStack-SpeechToSpeechTaskService | GenerativeAiUseCasesStack-SpeechToSpeechTaskService-jVsmd9geYRRl |
GenerativeAiUseCasesStack-RagKnowledgeBaseRetrieve | GenerativeAiUseCasesStack-RagKnowledgeBaseRetrieveS-x1SBpReYqYhn |
GenerativeAiUseCasesStack-APIGetFileDownloadSigned | GenerativeAiUseCasesStack-APIGetFileDownloadSignedU-XhZblnNpYxLc |
実際の IAM ロール名が確認できたらアカウントBのクロスアカウント用 IAM ロールで、信頼ポリシーに指定してやります。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111111111111:role/GenerativeAiUseCasesStack-APIPredictTitleServiceRol-KCogLtsITlVx",
"arn:aws:iam::111111111111:role/GenerativeAiUseCasesStack-APIPredictServiceRole6B8A-63OZMHLPel2H",
"arn:aws:iam::111111111111:role/GenerativeAiUseCasesStack-APIPredictStreamServiceRo-Lffng0T8GlEg",
"arn:aws:iam::111111111111:role/GenerativeAiUseCasesStack-APIGenerateImageServiceRo-0ktKYg1PlapO",
"arn:aws:iam::111111111111:role/GenerativeAiUseCasesStack-APIGenerateVideoServiceRo-NNDcJ7Vn3cwq",
"arn:aws:iam::111111111111:role/GenerativeAiUseCasesStack-APIListVideoJobsServiceRo-byMmv45ug1GY",
"arn:aws:iam::111111111111:role/GenerativeAiUseCasesStack-SpeechToSpeechTaskService-jVsmd9geYRRl",
"arn:aws:iam::111111111111:role/GenerativeAiUseCasesStack-RagKnowledgeBaseRetrieveS-x1SBpReYqYhn",
"arn:aws:iam::111111111111:role/GenerativeAiUseCasesStack-APIGetFileDownloadSignedU-XhZblnNpYxLc"
]
},
"Action": "sts:AssumeRole"
}
]
}
つかう
これで準備が整いました。アカウントB上でのモデルアクセスの有効化や、ナレッジベースデータソースの同期が済んでいれば、アカウントAの GenU から利用できるはずです。
Agent チャットを使っている様子。
RAG チャットを使っている様子。
GenU デフォルトでデプロイされるデータソースでは Bedrock ユーザーガイド PDF などが同期されています。
さいごに
本日は Generative AI Use Cases (GenU) で別 AWS アカウントの Bedrock Knowledge Bases / Bedrock Agents を使ってみました。
ナレッジベースとエージェントがすでに用意できていれば、こちらも設定は非常に簡単ですね。