Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added sample code for a custom SQL Agent #457

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

135 changes: 135 additions & 0 deletions agents-and-function-calling/custom-sql-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
### ConverseSQLAgent: Building an intelligent text-to-SQL agent using Amazon Bedrock and Converse API. This is a Sample Code for a quick POC and the infrastructure can be adapted based on final implementation.

Authors: Ross Alas, Pavan Kumar, Parag Srivastava and Abdullah Siddiqui

ConverseSQLAgent is a simple and powerful text-to-sql solution that can connect to
different databases and queries them all through natural language. It is built using
Amazon Bedrock, Converse API, and a custom agent implementation that enables it to
plan, execute, and learn as you use it.


### Manual Installation steps

1. You will need to deploy the Lambda using the deployment/lambda.zip
2. Configure Lambda to connect to the VPC where your RDS database is
3. Configure the following VPC endpoints in the same VPC:
- Bedrock Runtime (com.amazonaws.<region>.bedrock-runtime)
- DynamoDB (com.amazonaws.<region>.dynamodb)
- Secrets Manager (com.amazonaws.<region>.secretsmanager)
4. Ensure the Lambda execution role has permissions:
- Bedrock Converse and the Claude 3 Sonnet
- DynamoDB table for use with the agent
- Secrets Manager key to store the RDS credentials
5. Ensure Lambda has the following enviroment variables:
- DynamoDbMemoryTable (advtext2sql_memory_tb)
- BedrockModelId (anthropic.claude-3-sonnet-20240229-v1:0)
6. Ensure that Lambda/VPC endpoints/RDS security groups allow communication


### This section contains details on how to run the setup using CDK code written in Python.

### Prerequisites

1. Ensure CDK is installed and [bootstrap](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping-env.html) the environment as required to connect it to your AWS account.
```
$ npm install -g aws-cdk
```

2. Check for existence of Python 3.11.

```
python 3.11 --version
```

3. If the response is "python: command not found". Install Python 3.11 and pip for Python 3.11
```
sudo dnf install python3.11 -y
sudo dnf install python3.11-pip -y
```

### To run example

Clone the code to your working environment. Follow the steps as mentioned.

1. Change your working directory to the downloaded folder.
```
$ cd ConverseSqlAgent
```

2. Run the following Script to download the dependencies recuired by the lambda layer and creating a zip file to be utilized as a layer for the lambda code.
```
cd ./src/layers
python3.11 -m venv create_layer
source create_layer/bin/activate
pip install -r requirements.txt
mkdir python
cp -r create_layer/lib python/
zip -r layer_content.zip python
deactivate
cd ../../
```

3. Once bak in the working directory of your code. Create a Python virtual environment
```
python3.11 -m venv .venv
```

4. Activate virtual environment

_On MacOS or Linux_
```
source .venv/bin/activate
```

_On Windows_
```
.venv\Scripts\activate.bat
```

5. Install the required dependencies.

```
pip install -r requirements.txt
```

6. Synthesize (`cdk synth`) or deploy (`cdk deploy`) the example

```
cdk deploy
```

### To dispose of the stack afterwards:

```
cdk destroy
```

7. Once the resources are built. Connect to the MySQL RDS instance and run the sample HR schema using the file "hr-schema-mysql.sql" from "sql" folder.

Ensure that you have the mysql agent installed and that the RDS MySQL instance security group allows inbound traffic on port 3306.

8. First, create the database schema. Retrieve the username, password and databse hostname values from Secrets Manager.

```
mysql -u <username> -p -h <database hostname> -P 3306 < ./sql/hr-schema-mysql.sql
```

9. Connect to database and check if the new HR database is created.

```
mysql -u <username> –p -h <database hostname> -P 3306
```

10. After connecting check the databases and the tables in the HR database.
```
show databases;
show tables;
```

11. You can test the lambda using the simple prompt. as given below.

```
{
"input_text": "Connect to the database hr using the secrets manager key <Database key> and get me how many employees are there in each department in each region?"
}
```
28 changes: 28 additions & 0 deletions agents-and-function-calling/custom-sql-agent/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from converse_sql_agent.converse_sql_agent_stack import ConverseSqlAgentStack


app = cdk.App()
ConverseSqlAgentStack(app, "ConverseSqlAgentStack",
# 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=cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')),

# Uncomment the next line if you know exactly what Account and Region you
# want to deploy the stack to. */

#env=cdk.Environment(account='123456789012', region='us-east-1'),

# For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html
)

app.synth()
71 changes: 71 additions & 0 deletions agents-and-function-calling/custom-sql-agent/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"app": "python3 app.py",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"requirements*.txt",
"source.bat",
"**/__init__.py",
"**/__pycache__",
"tests"
]
},
"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
}
}
Empty file.
Binary file not shown.
Binary file not shown.
Loading