以下の記事に続きGenerative AI CDK Constructsネタです。
今回はAgents for Amazon Bedrock(以下Agent)を構築してみます。構成としては以下のような形です。
目次
元ネタ
今回実装するのは以下のWorkshopの内容です。
以下Workshopの画像からの引用です。
保険会社において保険金請求への対応を行うシーンが想定されています。Agentを通して保険金請求に対して申請書類の詳細や提出状況の確認、またリマインダーのセットなどが可能です。
なおAgentのAction Groupから呼ばれるLambda関数において、申請書類の提出状況などはハードコードされています。実際はDBからの参照等になるかと思います。 以下一部抜粋です。Claimにおいてステータスなどがハードコードされています。
def claim_detail(claim_id): if claim_id == 'claim-857': return { "response": { "claimId": claim_id, "createdDate": "21-Jul-2023", "lastActivityDate": "25-Jul-2023", "status": "Open", "policyType": "Vehicle" } }
また各提出書類の要件などが書かれたドキュメントはS3バケットに置かれ、Knowledge Bases経由で取得します。
Agentを実装してみる
実装は以下に格納しています。
プロジェクト構成
以下今回関係あるところのみ抜粋します。実装しているのはConstructsの部分のみで、AgentのAPI SchemaなどはWorkshopのものをそのまま流用しています。
. ├── README.md ├── api-schema │ └── insurance_claims_agent_openapi_schema_with_kb.json # AgentのAPI Schema。Workshopのものをそのまま利用。 ├── bin │ └── workshop_bedrock.ts ├── cdk.json ├── data │ └── for-test-agent # Knowledge Basesで使用するドキュメント。Workshopのものをそのまま利用。 │ ├── AccidentImages_file_requirements.docx │ ├── AccidentReport_file_requirements.docx │ ├── Driverlicense_file_requirements.docx │ └── VehicleRegistration_file_requirements.docx ├── jest.config.js ├── lambda │ └── index.py # AgentのAction Groupから呼び出されるLambda関数。Worokshopのものをそのまま利用。 ├── lib │ ├── constructs │ │ └── 05_0_test-agent.ts # Constructsの実装箇所 │ └── workshop_bedrock-stack.ts ├── package-lock.json ├── package.json └── tsconfig.json
Vector StoreとKnowledge Basesの実装
ここは前回の記事とほぼ同様です。
一点注意点が必要なのが、Knowledge Base
クラスのinstruction
プロパティです。後続のAgent
クラスでaddKnowledgeBase
メソッドで、AgentにKnowledge Basesを追加する際に description
にKnowledgeBase
クラスのinstruction
の値を設定しています(2024/6/11時点)。
ここは違和感がある実装であり、コメントにも問題がある旨が記載されています。実際に動作に影響する項目ではないですが、KnowledgeBase
クラスのinstruction
を未設定にするとAgent
クラスに追加ができないので注意が必要です。
const agentKnowledgeBaseProperty: bedrock.CfnAgent.AgentKnowledgeBaseProperty = { description: knowledgeBase.instruction, // known issue: wrong parameter mapping in Cfn. Workaround: pass instruction through description knowledgeBaseId: knowledgeBase.knowledgeBaseId, knowledgeBaseState: knowledgeBase.knowledgeBaseState, };
const indexName = 'bedrock-knowledge-base-index'; const vectorField = 'bedrock-knowledge-base-vector'; // Vector Store const vectorStore = new opensearchserverless.VectorCollection(this, 'VectorCollectionForAgent', { collectionName: 'bedrock-collection-for-agent', standbyReplicas: opensearchserverless.VectorCollectionStandbyReplicas.DISABLED, }); const vectorIndex = new opensearch_vectorindex.VectorIndex(this, 'VectorIndexForAgent', { collection: vectorStore, indexName, vectorField, vectorDimensions: 1536, mappings: [ { mappingField: 'bedrock-knowledge-base-text', dataType: 'text', filterable: true, }, { mappingField: 'bedrock-knowledge-base-metadata', dataType: 'text', filterable: true, }, ], }); // Knowledge Base const knowledgeBase = new bedrock.KnowledgeBase(this, 'KnowledgeBaseForAgent', { embeddingsModel: bedrock.BedrockFoundationModel.TITAN_EMBED_TEXT_V1, vectorIndex, vectorStore, indexName, vectorField, instruction: 'the property for description ', // 何かしら設定が必要 }); const dataSourceBucket = new s3.Bucket(this, 'BucketForAgent', { autoDeleteObjects: true, removalPolicy: RemovalPolicy.DESTROY, }) new s3deploy.BucketDeployment(this, 'DeployDataForAgent', { sources: [s3deploy.Source.asset('./data/for-test-agent')], destinationBucket: dataSourceBucket, }); new bedrock.S3DataSource(this, 'DataSourceForAgent', { bucket: dataSourceBucket, knowledgeBase, dataSourceName: 'bedrock-sample-knowledge-base-for-agent', chunkingStrategy: bedrock.ChunkingStrategy.FIXED_SIZE, maxTokens: 512, overlapPercentage: 20 })
Agentの実装
まずはAgentを実装していきます。
InstructionはWorkshopのものをそのまま使用しています。またAgentの基盤モデルはClaud 3 Haikuを使用します。
// Agents const instruction = ` You are an agent that can handle various tasks related to insurance claims, including looking up claim details, finding what paperwork is outstanding, and sending reminders. Only send reminders if you have been explicitly requested to do so. If an user asks about your functionality, provide guidance in natural language and do not include function names on the output.`; const agent = new bedrock.Agent(this, 'Agent', { foundationModel: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_HAIKU_V1_0, instruction, idleSessionTTL: Duration.seconds(1800), }); agent.addKnowledgeBase(knowledgeBase); // AgentにKnowledge Basesを追加
追加にAction Groupを実装していきます。
LambdaはPythonFunctionを使用しています。
// Agent Action Group const actionGroupFunction = new PythonFunction(this, 'ActionGroupFunction', { runtime: lambda.Runtime.PYTHON_3_12, entry: 'lambda', // LambdaのコードはWorkshopのものを使用。 handler: 'lambda_handler', timeout: Duration.seconds(60), logRetention: logs.RetentionDays.ONE_DAY, }); const actionGroup = new bedrock.AgentActionGroup(this, 'AgentGroup', { actionGroupExecutor: { lambda: actionGroupFunction, }, actionGroupState: "ENABLED", actionGroupName: 'ClaimManagementActionGroup', apiSchema:bedrock.ApiSchema.fromAsset('api-schema/insurance_claims_agent_openapi_schema_with_kb.json'), // API SchemaをWorkshopのものを使用。 }); agent.addActionGroup(actionGroup); // AgentにAction Groupを追加
動かしてみる
デプロイするとKnowledge BasesとAgentが作成されます。
Knowledge BasesのSyncまでは前回と同様なので省略します。
まずはAgentを選択します。
その上でTest欄のPrepare
を押下します。
あとはプロンプトを打っていきます。Agentを呼び出してClaim-006の詳細を取得ができました。
日本語でも動作確認をしてみます。情報の取得やリマインダーのセットを行うことができました。
また免許証や車両登録書類の要件などはKnowledge Bases経由でS3バケットに格納されたドキュメントから取得できています。問題なさそうです。
まとめ
Generative AI CDK Constructsを使って Agent for Amazon Bedrockも簡単に実装できました。
PythonFunction
を使用するとレイヤー含めLambdaも簡単に作れるため、非常に便利かと思います。