mazyu36の日記

某SIer所属のクラウドエンジニアのブログ

Generative AI CDK ConstructsのL2 Constructを使って Agents for Amazon Bedrockを構築してみる

以下の記事に続きGenerative AI CDK Constructsネタです。

mazyu36.hatenablog.com

今回はAgents for Amazon Bedrock(以下Agent)を構築してみます。構成としては以下のような形です。

目次

元ネタ

今回実装するのは以下のWorkshopの内容です。

github.com

以下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を実装してみる

実装は以下に格納しています。

github.com

プロジェクト構成

以下今回関係あるところのみ抜粋します。実装しているのは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を追加する際に descriptionKnowledgeBaseクラスの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,
    };

github.com

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も簡単に作れるため、非常に便利かと思います。