Building a Serverless Resume AI Using Amazon Bedrock: A Step-by-Step Guide
In today’s digital age, automation and artificial intelligence (AI) have revolutionized various industries, including human resources. One innovative application of AI is the creation of a serverless resume AI, which can parse and analyze resumes to extract valuable information. In this comprehensive guide, we’ll walk through the process of building a serverless resume AI using Amazon Web Services (AWS) and AWS Cloud Development Kit (CDK).
Prerequisites:
Before we dive into the project, let’s ensure that we have all the necessary tools set up:
- AWS CLI: Install and configure the AWS Command Line Interface (CLI) to interact with AWS services from the command line.
- CDK: Install the AWS Cloud Development Kit (CDK) to easily define and deploy AWS infrastructure using familiar programming languages.
- Docker: Install Docker to build and run containers for our project.
Preparing the Project:
Create Project Directory: Start by creating a new project folder named resume-ai
in your terminal.
mkdir resume-ai && cd resume-ai
Initialize CDK Project: Initialize a new CDK project with JavaScript as the language.
cdk init app — language javascript
Prepare Resume Data: Create a text or PDF file named resume.txt
in a data
folder within your project directory. Populate it with sample resume content.
Lambda Function Setup:
We’ll create Lambda functions to handle various tasks within our serverless architecture.
Query Knowledge Base Lambda Function:
Create a folder and file structure for our first Lambda function.
mkdir src/queryKnowledgeBase && touch src/queryKnowledgeBase/index.js
const {
BedrockAgentRuntimeClient,
RetrieveAndGenerateCommand,
} = require(“@aws-sdk/client-bedrock-agent-runtime”);
const client = new BedrockAgentRuntimeClient({
region: process.env.AWS_REGION,
});
exports.handler = async (event, context) => {
const { question } = JSON.parse(event.body);
const input = {
// RetrieveAndGenerateRequest
input: {
// RetrieveAndGenerateInput
text: question, // required
},
retrieveAndGenerateConfiguration: {
// RetrieveAndGenerateConfiguration
type: “KNOWLEDGE_BASE”, // required
knowledgeBaseConfiguration: {
// KnowledgeBaseRetrieveAndGenerateConfiguration
knowledgeBaseId: process.env.KNOWLEDGE_BASE_ID, // required
modelArn: `arn:aws:bedrock:${process.env.AWS_REGION}::foundation-model/anthropic.claude-v2`, // required
},
},
};
const command = new RetrieveAndGenerateCommand(input);
const response = await client.send(command);
return JSON.stringify({
response: response.output.text,
});
};
Make the indentation correct
- This function will handle user request queries and return the RAG response from Bedrock model.
- Type the following function code inside
src/queryKnowledgeBase/index.js
Ingest Job Lambda Function:
Create a folder structure for our second Lambda function:
mkdir src/IngestJob && touch src/IngestJob/index.js
Copy and paste the following code into index.js
:
const {
BedrockAgentClient,
StartIngestionJobCommand,
} = require(“@aws-sdk/client-bedrock-agent”); // CommonJS import
const client = new BedrockAgentClient({ region: process.env.AWS_REGION });
exports.handler = async (event, context) => {
const input = {
// StartIngestionJobRequest
knowledgeBaseId: process.env.KNOWLEDGE_BASE_ID, // required
dataSourceId: process.env.DATA_SOURCE_ID, // required
clientToken: context.awsRequestId, // required
};
const command = new StartIngestionJobCommand(input);
const response = await client.send(command);
console.log(response);
return JSON.stringify({
ingestionJob: response.ingestionJob,
});
};
Make the indentation correct
- This function will run Ingest Job in Bedrock Knowledge Base to do pre-processing and will get triggered when we upload our data to S3 Bucket.
- Type the following function code inside
src/IngestJob/index.js
.
Building Services with CDK Constructs:
Now, let’s utilize CDK to define and deploy our AWS infrastructure:
Navigate to lib/resume-ai-stack.js
and define the infrastructure components using CDK constructs. This file orchestrates the creation of S3 buckets, Lambda functions, and other resources necessary for our resume AI.
const { Stack, Duration, CfnOutput, RemovalPolicy } = require(“aws-cdk-lib”);
const s3 = require(“aws-cdk-lib/aws-s3”);
const lambda = require(“aws-cdk-lib/aws-lambda”);
const { bedrock } = require(“@cdklabs/generative-ai-cdk-constructs”);
const { S3EventSource } = require(“aws-cdk-lib/aws-lambda-event-sources”);
const iam = require(“aws-cdk-lib/aws-iam”);
class ResumeAiStack extends Stack {
/**
*
* @param {Construct} scope
* @param {string} id
* @param {StackProps=} props
*/
constructor(scope, id, props) {
super(scope, id, props);
const resumeBucket = new s3.Bucket(this, “resumeBucket”, {
removalPolicy: RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});
const resumeKnowledgeBase = new bedrock.KnowledgeBase(
this,
“resumeKnowledgeBase”,
{
embeddingsModel: bedrock.BedrockFoundationModel.TITAN_EMBED_TEXT_V1,
}
);
const resumeDataSource = new bedrock.S3DataSource(
this,
“resumeDataSource”,
{
bucket: resumeBucket,
knowledgeBase: resumeKnowledgeBase,
dataSourceName: “resume”,
chunkingStrategy: bedrock.ChunkingStrategy.FIXED_SIZE,
maxTokens: 500,
overlapPercentage: 20,
}
);
const s3PutEventSource = new S3EventSource(resumeBucket, {
events: [s3.EventType.OBJECT_CREATED_PUT],
});
const lambdaIngestionJob = new lambda.Function(this, “IngestionJob”, {
runtime: lambda.Runtime.NODEJS_20_X,
handler: “index.handler”,
code: lambda.Code.fromAsset(“./src/IngestJob”),
timeout: Duration.minutes(5),
environment: {
KNOWLEDGE_BASE_ID: resumeKnowledgeBase.knowledgeBaseId,
DATA_SOURCE_ID: resumeDataSource.dataSourceId,
},
});
lambdaIngestionJob.addEventSource(s3PutEventSource);
lambdaIngestionJob.addToRolePolicy(
new iam.PolicyStatement({
actions: [“bedrock:StartIngestionJob”],
resources: [resumeKnowledgeBase.knowledgeBaseArn],
})
);
const lambdaQuery = new lambda.Function(this, “Query”, {
runtime: lambda.Runtime.NODEJS_20_X,
handler: “index.handler”,
code: lambda.Code.fromAsset(“./src/queryKnowledgeBase”),
timeout: Duration.minutes(5),
environment: {
KNOWLEDGE_BASE_ID: resumeKnowledgeBase.knowledgeBaseId,
},
});
const fnUrl = lambdaQuery.addFunctionUrl({
authType: lambda.FunctionUrlAuthType.NONE,
invokeMode: lambda.InvokeMode.BUFFERED,
cors: {
allowedOrigins: [“*”],
allowedMethods: [lambda.HttpMethod.POST],
},
});
lambdaQuery.addToRolePolicy(
new iam.PolicyStatement({
actions: [
“bedrock:RetrieveAndGenerate”,
“bedrock:Retrieve”,
“bedrock:InvokeModel”,
],
resources: [“*”],
})
);
new CfnOutput(this, “KnowledgeBaseId”, {
value: resumeKnowledgeBase.knowledgeBaseId,
});
new CfnOutput(this, “QueryFunctionUrl”, {
value: fnUrl.url,
});
new CfnOutput(this, “ResumeBucketName”, {
value: resumeBucket.bucketName,
});
}
}
module.exports = { ResumeAiStack };
Make the indentation correct
Deployment:
Finally, let’s deploy our serverless resume AI using CDK:
Execute the following command in your terminal:
cdk deploy
With this, our serverless resume AI will be deployed to AWS, ready to parse and analyze resumes seamlessly.
Conclusion:
In this comprehensive guide, we’ve explored the process of building a serverless resume AI using AWS Bedrock and CDK. By leveraging Lambda functions, S3 buckets, and AI models, we’ve created an automated solution for parsing and analyzing resumes, revolutionizing the recruitment process.
Moving forward, you can further enhance this AI application by integrating additional AI models for advanced resume analysis or incorporating natural language processing (NLP) for improved query understanding. The possibilities are endless as we continue to innovate in the realm of serverless and AI technologies.