-
Notifications
You must be signed in to change notification settings - Fork 946
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2553 from kaustavbecs/kaustavbecs-feature-appsync…
…-lambda-bedrock-async-stream-subscription-cdk New serverless pattern - AppSync Async Bedrock Streaming with Lambda Event Mode
- Loading branch information
Showing
15 changed files
with
989 additions
and
0 deletions.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
appsync-lambda-bedrock-async-stream-subscription-cdk/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
*.js | ||
!jest.config.js | ||
*.d.ts | ||
node_modules | ||
|
||
# CDK asset staging directory | ||
.cdk.staging | ||
cdk.out |
6 changes: 6 additions & 0 deletions
6
appsync-lambda-bedrock-async-stream-subscription-cdk/.npmignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
*.ts | ||
!*.d.ts | ||
|
||
# CDK asset staging directory | ||
.cdk.staging | ||
cdk.out |
131 changes: 131 additions & 0 deletions
131
appsync-lambda-bedrock-async-stream-subscription-cdk/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
# Long running invocations of Amazon Bedrock using Amazon AppSync and AWS Lambda streaming | ||
|
||
This pattern demonstrates how to implement [long-running invocations](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html#long-running-invocations) with Amazon Bedrock using AWS AppSync subscriptions and AWS Lambda in Event Mode, following the official AWS AppSync documentation pattern. | ||
|
||
Learn more about this pattern at [Serverless Land Patterns](https://serverlessland.com/patterns/appsync-lambda-bedrock-async-stream-subscription-cdk). | ||
|
||
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. | ||
|
||
## Requirements | ||
|
||
* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. | ||
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured | ||
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) | ||
* [Node and NPM](https://nodejs.org/en/download/) installed | ||
* [AWS Cloud Development Kit](https://docs.aws.amazon.com/cdk/v2/guide/cli.html) (AWS CDK) installed | ||
* Enable the **Anthropic - Claude Sonnet 3.5 V2** model in **us-east-1** region through the [Bedrock console](https://console.aws.amazon.com/bedrock/home#/modelaccess). This implementation uses the [cross-region inference profile](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html#inference-profiles-support-system) from us-east-1. | ||
|
||
## How it works | ||
|
||
The pattern implements an asynchronous [streaming architecture](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html#long-running-invocations) where: | ||
|
||
1. Client initiates a WebSocket subscription and makes a request to AppSync | ||
2. AppSync invokes Lambda function in Event mode, enabling asynchronous processing | ||
3. Lambda function streams responses from Bedrock using ConverseStream | ||
4. Lambda sends updates via mutations to AppSync | ||
5. Updates are delivered to client through WebSocket subscription | ||
|
||
![alt text](image.png) | ||
|
||
**Key Benefits** | ||
- **Asynchronous Processing**: AppSync immediately returns a response while Lambda processes the request asynchronously, preventing timeouts for long-running operations | ||
- **Real-time Updates**: Clients receive progressive updates through WebSocket subscriptions as the model generates responses | ||
- **Scalable Architecture**: Event-driven design allows handling multiple concurrent requests without blocking | ||
- **Enhanced User Experience**: Progressive updates enable responsive interfaces even during lengthy AI model invocations | ||
|
||
## Deployment Instructions | ||
|
||
1. Clone the repository: | ||
```sh | ||
git clone https://github.com/aws-samples/serverless-patterns | ||
``` | ||
2. Navigate to pattern directory: | ||
```sh | ||
cd appsync-lambda-bedrock-async-stream-subscription-cdk | ||
``` | ||
|
||
3. Install dependencies: | ||
```sh | ||
npm install | ||
``` | ||
|
||
4. Bootstrap CDK (if needed): | ||
```sh | ||
cdk bootstrap | ||
``` | ||
|
||
5. Deploy stack: | ||
```sh | ||
npm run deploy | ||
``` | ||
|
||
### Important: | ||
Note the GraphQL API URL and API Key from the stack outputs - you'll need these for testing. | ||
|
||
## Testing | ||
|
||
After deployment, you can test the Bedrock streaming integration using the provided test script. The script demonstrates: | ||
- WebSocket subscription initialization | ||
- Conversation start with Bedrock | ||
- Real-time streaming chunks display | ||
- Graceful cleanup on exit | ||
|
||
1. Configure test credentials: | ||
```sh | ||
Open test/test.ts | ||
Replace APPSYNC_API_URL with the API URL from stack outputs | ||
Replace APPSYNC_API_KEY with the API Key from stack outputs | ||
``` | ||
|
||
2. Run the test: | ||
```sh | ||
npx tsx test/test.ts | ||
``` | ||
|
||
3. Expected Output: | ||
```sh | ||
Starting subscription... | ||
Starting conversation... | ||
StartConversation response: { | ||
data: { | ||
startConversation: { | ||
conversationId: '123e4567-e89b-12d3-a456-426614174000', | ||
status: 'STARTED' | ||
} | ||
} | ||
} | ||
Received chunk: { | ||
conversationId: '123e4567-e89b-12d3-a456-426614174000', | ||
chunk: "Here's a joke for you: Why don't scientists trust atoms? Because they make" | ||
} | ||
Received chunk: { | ||
conversationId: '123e4567-e89b-12d3-a456-426614174000', | ||
chunk: 'up everything!' | ||
} | ||
``` | ||
|
||
If you do not receive any response, please check your Bedrock Model access for Claude Sonnet 3.5 V2 in us-east-1 region. | ||
|
||
4. Stop the test: | ||
```sh | ||
Press Ctrl+C to terminate the process | ||
``` | ||
|
||
|
||
## Cleanup | ||
|
||
1. Delete the stack | ||
```sh | ||
cdk destroy --all | ||
``` | ||
|
||
## Author bio | ||
Kaustav Dey, | ||
https://www.linkedin.com/in/kaustavbecs/ | ||
Solution Architect | ||
|
||
---- | ||
Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
|
||
SPDX-License-Identifier: MIT-0 | ||
|
81 changes: 81 additions & 0 deletions
81
...k-async-stream-subscription-cdk/appsync-lambda-bedrock-async-stream-subscription-cdk.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
{ | ||
"title": "Amazon Bedrock calls via AppSync & Lambda streaming for long tasks", | ||
"language": "TypeScript", | ||
"level": "300", | ||
"framework": "CDK", | ||
"introBox": { | ||
"headline": "How it works", | ||
"text": [ | ||
"The pattern implements an asynchronous streaming architecture.", | ||
"Client initiates a WebSocket subscription and makes a request to AWS AppSync. AppSync invokes Lambda function in event mode, enabling asynchronous processing.", | ||
"Lambda function streams responses from Amazon Bedrock using ConverseStream. Lambda function sends updates via mutations to AppSync. Updates are delivered to client through WebSocket subscription." | ||
] | ||
}, | ||
"gitHub": { | ||
"template": { | ||
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/appsync-lambda-bedrock-async-stream-subscription-cdk", | ||
"templateURL": "serverless-patterns/appsync-lambda-bedrock-async-stream-subscription-cdk", | ||
"projectFolder": "appsync-lambda-bedrock-async-stream-subscription-cdk", | ||
"templateFile": "/lib/appsync-lambda-bedrock-async-stream-subscription-cdk-stack.ts" | ||
} | ||
}, | ||
"resources": { | ||
"bullets": [ | ||
{ | ||
"text": "AWS AppSync JavaScript resolver and function reference for Amazon Bedrock runtime", | ||
"link": "https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html#long-running-invocations" | ||
}, | ||
{ | ||
"text": "Bedrock ConverseStream API", | ||
"link": "https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ConverseStream.html" | ||
} | ||
] | ||
}, | ||
"deploy": { | ||
"text": ["cdk deploy"] | ||
}, | ||
"testing": { | ||
"text": ["See the GitHub repo for detailed testing instructions."] | ||
}, | ||
"cleanup": { | ||
"text": ["Delete the stack: <code>cdk destroy --all</code>."] | ||
}, | ||
"authors": [ | ||
{ | ||
"name": "Kaustav Dey", | ||
"image": "https://avatars.githubusercontent.com/u/13236519", | ||
"bio": "Solution Architect at AWS", | ||
"linkedin": "kaustavbecs" | ||
} | ||
], | ||
"patternArch": { | ||
"icon1": { | ||
"x": 20, | ||
"y": 50, | ||
"service": "appsync", | ||
"label": "AWS AppSync" | ||
}, | ||
"icon2": { | ||
"x": 50, | ||
"y": 50, | ||
"service": "lambda", | ||
"label": "AWS Lambda" | ||
}, | ||
"icon3": { | ||
"x": 80, | ||
"y": 50, | ||
"service": "bedrock", | ||
"label": "Amazon Bedrock" | ||
}, | ||
"line1": { | ||
"from": "icon1", | ||
"to": "icon2", | ||
"label": "" | ||
}, | ||
"line2": { | ||
"from": "icon2", | ||
"to": "icon3", | ||
"label": "" | ||
} | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
...async-stream-subscription-cdk/bin/appsync-lambda-bedrock-async-stream-subscription-cdk.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/usr/bin/env node | ||
import * as cdk from 'aws-cdk-lib'; | ||
import { AppsyncLambdaBedrockAsyncStreamSubscriptionCdkStack } from '../lib/appsync-lambda-bedrock-async-stream-subscription-cdk-stack'; | ||
|
||
const app = new cdk.App(); | ||
new AppsyncLambdaBedrockAsyncStreamSubscriptionCdkStack(app, 'AppsyncLambdaBedrockAsyncStreamSubscriptionCdkStack', { | ||
/* If you don't specify 'env', this stack will be environment-agnostic. | ||
* Account/Region-dependent features and context lookups will not work, | ||
* but a single synthesized template can be deployed anywhere. */ | ||
|
||
/* Uncomment the next line to specialize this stack for the AWS Account | ||
* and Region that are implied by the current CLI configuration. */ | ||
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION }, | ||
|
||
/* Uncomment the next line if you know exactly what Account and Region you | ||
* want to deploy the stack to. */ | ||
// env: { account: '123456789012', region: 'us-east-1' }, | ||
|
||
/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */ | ||
}); |
81 changes: 81 additions & 0 deletions
81
appsync-lambda-bedrock-async-stream-subscription-cdk/cdk.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
{ | ||
"app": "npx ts-node --prefer-ts-exts bin/appsync-lambda-bedrock-async-stream-subscription-cdk.ts", | ||
"watch": { | ||
"include": [ | ||
"**" | ||
], | ||
"exclude": [ | ||
"README.md", | ||
"cdk*.json", | ||
"**/*.d.ts", | ||
"**/*.js", | ||
"tsconfig.json", | ||
"package*.json", | ||
"yarn.lock", | ||
"node_modules", | ||
"test" | ||
] | ||
}, | ||
"context": { | ||
"@aws-cdk/aws-lambda:recognizeLayerVersion": true, | ||
"@aws-cdk/core:checkSecretUsage": true, | ||
"@aws-cdk/core:target-partitions": [ | ||
"aws", | ||
"aws-cn" | ||
], | ||
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, | ||
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, | ||
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, | ||
"@aws-cdk/aws-iam:minimizePolicies": true, | ||
"@aws-cdk/core:validateSnapshotRemovalPolicy": true, | ||
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, | ||
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, | ||
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, | ||
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true, | ||
"@aws-cdk/core:enablePartitionLiterals": true, | ||
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, | ||
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, | ||
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, | ||
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, | ||
"@aws-cdk/aws-route53-patters:useCertificate": true, | ||
"@aws-cdk/customresources:installLatestAwsSdkDefault": false, | ||
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, | ||
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, | ||
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, | ||
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, | ||
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, | ||
"@aws-cdk/aws-redshift:columnId": true, | ||
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, | ||
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, | ||
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, | ||
"@aws-cdk/aws-kms:aliasNameRef": true, | ||
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, | ||
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true, | ||
"@aws-cdk/aws-efs:denyAnonymousAccess": true, | ||
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, | ||
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, | ||
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, | ||
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, | ||
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, | ||
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, | ||
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, | ||
"@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, | ||
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, | ||
"@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, | ||
"@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, | ||
"@aws-cdk/aws-eks:nodegroupNameAttribute": true, | ||
"@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, | ||
"@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, | ||
"@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, | ||
"@aws-cdk/aws-s3:keepNotificationInImportedBucket": false, | ||
"@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true, | ||
"@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true, | ||
"@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true, | ||
"@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true, | ||
"@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true, | ||
"@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true, | ||
"@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true, | ||
"@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true, | ||
"@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": true | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
appsync-lambda-bedrock-async-stream-subscription-cdk/example.pattern.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{ | ||
"title": "Long running invocations of Amazon Bedrock using Amazon AppSync and AWS Lambda streaming", | ||
"language": "Typescript", | ||
"level": "300", | ||
"framework": "CDK", | ||
"introBox": { | ||
"headline": "How it works", | ||
"text": [ | ||
"The pattern implements an asynchronous streaming architecture.", | ||
"Client initiates a WebSocket subscription and makes a request to AppSync. AppSync invokes Lambda function in Event mode, enabling asynchronous processing.", | ||
"Lambda function streams responses from Bedrock using ConverseStream. Lambda sends updates via mutations to AppSync. Updates are delivered to client through WebSocket subscription" | ||
] | ||
}, | ||
"gitHub": { | ||
"template": { | ||
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/appsync-lambda-bedrock-async-stream-subscription-cdk", | ||
"templateURL": "serverless-patterns/appsync-lambda-bedrock-async-stream-subscription-cdk", | ||
"projectFolder": "appsync-lambda-bedrock-async-stream-subscription-cdk", | ||
"templateFile": "lib/appsync-lambda-bedrock-async-stream-subscription-cdk-stack.ts" | ||
} | ||
}, | ||
"resources": { | ||
"bullets": [ | ||
{ | ||
"text": "AWS AppSync JavaScript resolver and function reference for Amazon Bedrock runtime", | ||
"link": "https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html#long-running-invocations" | ||
}, | ||
{ | ||
"text": "Bedrock ConverseStream API", | ||
"link": "https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ConverseStream.html" | ||
} | ||
] | ||
}, | ||
"deploy": { | ||
"text": [ | ||
"cdk deploy" | ||
] | ||
}, | ||
"testing": { | ||
"text": [ | ||
"See the GitHub repo for detailed testing instructions." | ||
] | ||
}, | ||
"cleanup": { | ||
"text": [ | ||
"Delete the stack: <code>cdk destroy --all</code>." | ||
] | ||
}, | ||
"authors": [ | ||
{ | ||
"name": "Kaustav Dey", | ||
"image": "https://avatars.githubusercontent.com/u/13236519", | ||
"bio": "Solution Architect at AWS", | ||
"linkedin": "https://www.linkedin.com/in/kaustavbecs/" | ||
} | ||
] | ||
} | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.