Spaces:
Running
Running
import * as kendra from 'aws-cdk-lib/aws-kendra'; | |
import * as iam from 'aws-cdk-lib/aws-iam'; | |
import { Construct } from 'constructs'; | |
import { Duration, Token, Arn } from 'aws-cdk-lib'; | |
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; | |
import { Runtime } from 'aws-cdk-lib/aws-lambda'; | |
export interface RagProps { | |
} | |
/** | |
* RAG を実行するためのリソースを作成する | |
*/ | |
export class Rag extends Construct { | |
constructor(scope: Construct, id: string, props: RagProps) { | |
super(scope, id); | |
const kendraIndexArnInCdkContext = | |
this.node.tryGetContext('kendraIndexArn'); | |
let kendraIndexArn: string; | |
let kendraIndexId: string; | |
if (kendraIndexArnInCdkContext) { | |
// 既存の Kendra Index を利用する場合 | |
kendraIndexArn = kendraIndexArnInCdkContext!; | |
kendraIndexId = Arn.extractResourceName( | |
kendraIndexArnInCdkContext, | |
'index' | |
); | |
} else { | |
// 新規に Kendra Index を作成する場合 | |
const indexRole = new iam.Role(this, 'KendraIndexRole', { | |
assumedBy: new iam.ServicePrincipal('kendra.amazonaws.com'), | |
}); | |
indexRole.addToPolicy( | |
new iam.PolicyStatement({ | |
effect: iam.Effect.ALLOW, | |
resources: ['*'], | |
actions: ['s3:GetObject'], | |
}) | |
); | |
indexRole.addManagedPolicy( | |
iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLogsFullAccess') | |
); | |
const index = new kendra.CfnIndex(this, 'KendraIndex', { | |
name: 'langflow-index', | |
edition: 'DEVELOPER_EDITION', | |
roleArn: indexRole.roleArn, | |
}); | |
kendraIndexArn = Token.asString(index.getAtt('Arn')); | |
kendraIndexId = index.ref; | |
// WebCrawler を作成 | |
const webCrawlerRole = new iam.Role(this, 'KendraWebCrawlerRole', { | |
assumedBy: new iam.ServicePrincipal('kendra.amazonaws.com'), | |
}); | |
webCrawlerRole.addToPolicy( | |
new iam.PolicyStatement({ | |
effect: iam.Effect.ALLOW, | |
resources: [kendraIndexArn], | |
actions: ['kendra:BatchPutDocument', 'kendra:BatchDeleteDocument'], | |
}) | |
); | |
new kendra.CfnDataSource(this, 'WebCrawler', { | |
indexId: kendraIndexId, | |
name: 'WebCrawler', | |
type: 'WEBCRAWLER', | |
roleArn: webCrawlerRole.roleArn, | |
languageCode: 'ja', | |
dataSourceConfiguration: { | |
webCrawlerConfiguration: { | |
urls: { | |
seedUrlConfiguration: { | |
webCrawlerMode: 'HOST_ONLY', | |
// デモ用に AWS の GenAI 関連のページを取り込む | |
seedUrls: [ | |
'https://aws.amazon.com/jp/what-is/generative-ai/', | |
'https://aws.amazon.com/jp/generative-ai/', | |
'https://aws.amazon.com/jp/generative-ai/use-cases/', | |
'https://aws.amazon.com/jp/bedrock/', | |
'https://aws.amazon.com/jp/bedrock/features/', | |
'https://aws.amazon.com/jp/bedrock/testimonials/', | |
], | |
}, | |
}, | |
crawlDepth: 1, | |
urlInclusionPatterns: ['https://aws.amazon.com/jp/.*'], | |
}, | |
}, | |
}); | |
} | |
// RAG 関連の API を追加する | |
// Lambda | |
const queryFunction = new NodejsFunction(this, 'Query', { | |
runtime: Runtime.NODEJS_18_X, | |
entry: './lambda/queryKendra.ts', | |
timeout: Duration.minutes(15), | |
bundling: { | |
// 新しい Kendra の機能を使うため、AWS SDK を明示的にバンドルする | |
externalModules: [], | |
}, | |
environment: { | |
INDEX_ID: kendraIndexId, | |
}, | |
}); | |
queryFunction.role?.addToPrincipalPolicy( | |
new iam.PolicyStatement({ | |
effect: iam.Effect.ALLOW, | |
resources: [kendraIndexArn], | |
actions: ['kendra:Query'], | |
}) | |
); | |
const retrieveFunction = new NodejsFunction(this, 'Retrieve', { | |
runtime: Runtime.NODEJS_18_X, | |
entry: './lambda/retrieveKendra.ts', | |
timeout: Duration.minutes(15), | |
bundling: { | |
// 新しい Kendra の機能を使うため、AWS SDK を明示的にバンドルする | |
externalModules: [], | |
}, | |
environment: { | |
INDEX_ID: kendraIndexId, | |
}, | |
}); | |
retrieveFunction.role?.addToPrincipalPolicy( | |
new iam.PolicyStatement({ | |
effect: iam.Effect.ALLOW, | |
resources: [kendraIndexArn], | |
actions: ['kendra:Retrieve'], | |
}) | |
); | |
} | |
} |