mazyu36の日記

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

Generative AI CDK ConstructsのL2 Constructを使って Bedrock Knowledge Basesを構築してみる

Generative AI CDK Constructsに用意されているL2 Constructを使用し、Knowledge bases for Amazon Bedrock (以降Knowledge Bases) を構築してみました。

re:Invent 2023で発表されていたアレです。

引用元の動画

目次

Generative AI CDK Constructsとは

名前の通り生成AI系に関するCDKのConstructs ライブラリです。

当初はL3 Construct(Pattern)しかありませんでしたが、現在はL2 Constructも存在しています。2024/6/10時点だとリポジトリREADMEには以下が記載されています。

※Aurora Vector StoreやPineconeもライブラリ上は存在していますが、なぜか記載されていない。

Construct Description
Lambda layer langchainなどが入ったLambda(python)のレイヤー
Amazon Bedrock Knowledge Bases, GuardrailなどBedrock関連のリソース
Amazon OpenSearch Serverless Vector Collection OpenSearch ServerlessのVector Store
Amazon OpenSearch Vector Index Vector StoreのIndex(カスタムリソースで作られている)

BedrockやOpenSearch Severlessなど生成AI絡みでよく使うものがL2 Construct化されています。

Bedrockは以前カスタムリソースで作られていましたが、CloudFormation対応によりL1 ConstructをベースにL2 Constructが実装されています。

OpenSearch ServerlessのIndex作成はカスタムリソースですが、面倒なところであり抽象化されているのはありがたいですね。

使い方

非常に簡単です。まずはいつも通りcdk init を行います。

cdk init app --language=typescript    

そしてGenerative AI CDK Constructsをnpm installします。

npm install @cdklabs/generative-ai-cdk-constructs

あとはimportして使うのみです。

import { bedrock, opensearchserverless, opensearch_vectorindex } from '@cdklabs/generative-ai-cdk-constructs';

const vectorStore = new opensearchserverless.VectorCollection(this, 'VectorCollection', {
  // omit
});

APIのドキュメントは以下から確認できます。

github.com

Bedrock Knowledge Bases を実装してみる

題材としてBedrock WorkshopのKnowledge Baseのコンテンツを実装してみます。

Amazonの株主向けドキュメントをインプットとして使います。

github.com

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

github.com

Vector StoreとVector indexの実装

Vector StoreとIndexを実装します。CloudFormationで実装する際は特にIndexが面倒ですが、L2 Constructを使用すると簡単に実装できます。

const indexName = 'bedrock-sample-rag';
const vectorField = 'vector';

// Vector Store
const vectorStore = new opensearchserverless.VectorCollection(this, 'VectorCollection', {
  collectionName: 'bedrock-sample-rag',
  standbyReplicas: opensearchserverless.VectorCollectionStandbyReplicas.ENABLED,  // スタンバイレプリカを使用するかどうか。enumじゃなくてbooleanの方がいい気が...
});

// Vector Index
const vectorIndex = new opensearch_vectorindex.VectorIndex(this, 'VectorIndex', {
  collection: vectorStore,
  indexName,
  vectorField,
  vectorDimensions: 1536,
  mappings: [
    {
      mappingField: 'text',
      dataType: 'text',
      filterable: true,
    },
    {
      mappingField: 'text-metadata',
      dataType: 'text',
      filterable: true,
    },
  ],
});

IndexはWorkshopの以下の部分の設定を踏襲しています。

body_json = {
   "settings": {
      "index.knn": "true",
       "number_of_shards": 1,
       "knn.algo_param.ef_search": 512,
       "number_of_replicas": 0,
   },
   "mappings": {
      "properties": {
         "vector": {
            "type": "knn_vector",
            "dimension": 1536,
             "method": {
                 "name": "hnsw",
                 "engine": "faiss",
                 "space_type": "l2"
             },
         },
         "text": {
            "type": "text"
         },
         "text-metadata": {
            "type": "text"         }
      }
   }
}

mappingsに関して、L2 Constructで使用されているカスタムリソースの実装を見ていただくとわかりますが、共通的なところはあらかじめ定義されています。

そのためdimensionに相当する項目など最低限の設定で済むようになっています。

github.com

Knowledge Basesの実装

本題のBedrock Knowledge Bases関連の実装です。

// Knowledge Base
const knowledgeBase = new bedrock.KnowledgeBase(this, 'KnowledgeBase', {
  embeddingsModel: bedrock.BedrockFoundationModel.TITAN_EMBED_TEXT_V1,
  vectorStore, // 作成したVector Storeを指定
  vectorIndex, // 作成したIndexを指定
  indexName,  // index名はVector Indexのものと揃える。バリデーションエラーじゃなくて自動で同じもの設定してくれてもいい気がするが...
  vectorField,  // 同上
});

// ドキュメントを入れるバケットを作成
const dataSourceBucket = new s3.Bucket(this, 'Bucket', {
  autoDeleteObjects: true,
  removalPolicy: RemovalPolicy.DESTROY,
})

// cdk deploy時にドキュメントをS3バケットに自動アップロード
new s3deploy.BucketDeployment(this, 'DeployData', {
  sources: [s3deploy.Source.asset('./data')],
  destinationBucket: dataSourceBucket,
});

// Knowledge BasesにData Sourceを追加
new bedrock.S3DataSource(this, 'DataSource', {
  bucket: dataSourceBucket,  // 作成したバケットを指定。
  knowledgeBase, // Knowledge Basesを指定
  dataSourceName: 'bedrock-sample-knowledge-base',
  chunkingStrategy: bedrock.ChunkingStrategy.FIXED_SIZE,
  maxTokens: 512,
  overlapPercentage: 20
})

動かしてみる

実装後デプロイすると Knowledge Basesが作成されます。

設定値を確認してみるとVector databaseは想定通りOpenSearch Serverlessで作成されています。またIndexなども設定通りです。

ではまずはData sourceSyncを行います。

今回はTest knowledge baseを使用しマネコン上で動作確認をします。Select modelを押下します。

モデルを選択します。今回は Claude 3 Haiku を使ってみます。

事前準備が整いました。元ネタWorkshopと同様のプロンプトを投げてみます。

結果が返ってきました。問題なく動作しています。Show source detailsで詳細を確認してみます。

導出元としてS3に格納されたドキュメントが示されています。問題なさそうです。

まとめ

Generative AI CDK Constructsを使うことで、簡単にBedrock Knowledge Basesを実装できました。

CloudFormationで同じことをやろうとするとかなり大変なので、IaC派の方はぜひ使ってみてはいかがでしょうか。

Agents for Amazon Bedrock もそのうち試してみたいと思います。