Building a Serverless ChatGPT Powered Resume Assistant - Basics

project origin

A few weekends ago, I was tempted to build something with the OpenAI API. As a career changer entering the cloud space and someone who has worked in the early career talent space, I am acutely aware of how important and difficult it is for candidates to write a relevant resume for the role they are applying for. So, I decided to make a resume assistant powered by ChatGPT.

There are already a lot of articles written about Large Language Models (LLMs) and ChatGPT in particular, I don't really want to add to them. One thing I would like to address is that criticism of the LLM is just assertive and convincing bullshit. It's not a great trait for writing academic papers, but are there applications where it could be an advantage?

If you think about it, a resume can also be considered confident, convincing bullshit. No, I'm not saying it's acceptable to lie on a resume, but we often find ourselves writing a resume to expand our experience a bit so we can better fit a given job description . Speaking of which..

Job descriptions are a similar kind of aspirational crap. Requirements are based on an old job that no longer really matches the job, or just a description of the previous person's experience (the person who left made 20% more than they gave you). So the CV, job description, and LLM together form what I call the "honest trinity"

So, having determined that LMM is the perfect resume assistant, we will now build a serverless application that, given a "resume" and a job description, can customize a resume for the job through a virtual resume review, namely and your talk.

plan

Since most of this article was written in one article, and it was too long , I decided to split it into 4 articles.

  1. Introduction and some background (this post)
  2. Build a Python function that can be run and tested locally from the command line
  3. Deploy the function to the cloud using the AWS CDK (Python) (but still interact with it through the CLI)
  4. Deploy the frontend so we can allow others to use the service

This should keep things a bit smaller, and allow anyone who wants to build it (or make their own modifications to it) to focus on one file or area generally, instead of jumping around like a maniac.

How conversations with ChatGPT work

Let's talk about the OpenAI library and how ChatGPT conversations work.

First , every conversation has three participants, assistant- the chatbot, user- the person chatting with the chatbot, and system- a hidden but important participant who sets the tone of the conversation.

Second , this system message is your "secret weapon". Something that differentiates your bot from just chatting with ChatGPT. System messages allow you to set rules and constraints that will apply for the duration of a conversation. Here, we can indicate to chatbots that it is a useful assistant in resume review and "uses transferable skills if they lack direct experience". This is probably something you want to keep private, or someone else could copy your million dollar idea!

Third , the OpenAI API doesn't "remember" anything. Every time you pass a request to it, you need to provide all the context needed to generate the relevant completion. This means that the first request might look like this:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">[</span>
  <span style="color:var(--syntax-text-color)">{</span><span style="color:var(--syntax-string-color)">'role'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'system'</span><span style="color:var(--syntax-text-color)">,</span><span style="color:var(--syntax-string-color)">'content'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'You are a resume bot named Resume Bot 3000'</span><span style="color:var(--syntax-text-color)">},</span>
  <span style="color:var(--syntax-text-color)">{</span><span style="color:var(--syntax-string-color)">'role'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'user'</span><span style="color:var(--syntax-text-color)">,</span><span style="color:var(--syntax-string-color)">'content'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'My name is Jimmy and I want a job as a Bank Teller!'</span><span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-text-color)">]</span>
</code></span></span>

Your second request might look like this (we'll talk about parsing responses in a minute):

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">[</span>
  <span style="color:var(--syntax-text-color)">{</span><span style="color:var(--syntax-string-color)">'role'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'system'</span><span style="color:var(--syntax-text-color)">,</span><span style="color:var(--syntax-string-color)">'content'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'You are a resume bot named Resume Bot 3000'</span><span style="color:var(--syntax-text-color)">},</span>
  <span style="color:var(--syntax-text-color)">{</span><span style="color:var(--syntax-string-color)">'role'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'user'</span><span style="color:var(--syntax-text-color)">,</span><span style="color:var(--syntax-string-color)">'content'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'My name is Jimmy and I want a job as a Bank Teller!'</span><span style="color:var(--syntax-text-color)">},</span>
  <span style="color:var(--syntax-text-color)">{</span><span style="color:var(--syntax-string-color)">'role'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'assistant'</span><span style="color:var(--syntax-text-color)">,</span><span style="color:var(--syntax-string-color)">'content'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'Hi Jimmy, A bank teller is a job that typically requires money handling experience. Have you ever had a job or other experience where you had to handle cash or facilitate transactions?'</span><span style="color:var(--syntax-text-color)">},</span>
  <span style="color:var(--syntax-text-color)">{</span><span style="color:var(--syntax-string-color)">'role'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'user'</span><span style="color:var(--syntax-text-color)">,</span><span style="color:var(--syntax-string-color)">'content'</span><span style="color:var(--syntax-text-color)">:</span><span style="color:var(--syntax-string-color)">'Well, maybe not a job but I volunteered at school basketball games selling tickets for admission and also working at the concession stand. Does that count?'</span><span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-text-color)">]</span>
</code></span></span>

In order for ChatGPT to understand what's going on, it basically needs the entire conversation every time. Everything is new to it. This means that the longer the conversation lasts, the more context is built and the more expensive your requests become.

The context price of gpt-3.5-turbo is $0.0015/1k tokens (according to the openAI pricing page, about 750 words), and the response price is $0.003/1k tokens. This can be fairly cheap, but it can also easily get out of hand if there are a lot of people having long conversations. Be sure to set your account limits in the billing section.

While the ultimate goal of this project is to deploy it on AWS and open it up to the world, we will first create a python function that can be run locally. We can modify it later to run in AWS Lambda. So even though this code ends up needing to be placed in a directory of the CDK project, we'll skip that part and refactor it later if needed. We hope to get some glorious feedback on working code soon!

Setup files and virtual environments

So let's create a directory called chat_app, which we will first use to run our chatbot locally and then communicate with our deployed AWS Lambda function. Once we've created the directory, we can add the files we need to a small python project:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">mkdir </span>chat_app
<span style="color:var(--syntax-text-color)">cd </span>chat_app
<span style="color:var(--syntax-text-color)">touch </span>app.py requirements.txt
</code></span></span>

Now add the OpenAI library to yours requirements.txt. I'll be pinning the latest version available at the time of writing, but you can check out the latest version while reading this.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code># chat_app/requirements.txt

openai==0.27.8
</code></span></span>

Note that I'm trying to be as clear as possible which file I'm working on by adding a comment to all my code blocks telling you where I am. When I use an external library or module, I also do my best to show its imports at the top of the file. You can skip this part of the code if it was already imported in the previous step.

requirements.txtWe have now declared our first external dependency in our create virtual environment and installed that dependency in the virtual environment. If you plan to commit any of these to a git repository, be sure to add this .venv/to your .gitignore.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>python3 <span style="color:var(--syntax-error-color)">-m</span> venv .venv
<span style="color:var(--syntax-text-color)">source</span> .venv/bin/activate   
pip <span style="color:var(--syntax-text-color)">install</span> <span style="color:var(--syntax-error-color)">-r</span> requirements.txt
</code></span></span>

Now let's move into our python file. We'll import our module, setting the OpenAPI key we got from our OpenAI account. (Are you doing it right? If you aren't, please do it!)

Add your key to a local environment variable like this, but use your own:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">export </span><span style="color:var(--syntax-text-color)">OPENAI_API_KEY</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"sk-Th1si5n0tmyactua1k3y"</span>
</code></span></span>

Let's test your key with a simple request and see what happens:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-comment-color)"># chat_app/app.py
</span>
<span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">openai</span>
<span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">os</span>

<span style="color:var(--syntax-text-color)">openai</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">api_key</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">os</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">environ</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">get</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">'OPENAI_API_KEY'</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-text-color)">messages</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">[</span>
    <span style="color:var(--syntax-text-color)">{</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"system"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"You are a Cat named Mr. Boots"</span><span style="color:var(--syntax-text-color)">},</span>
    <span style="color:var(--syntax-text-color)">{</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"user"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"What is your name?"</span><span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-text-color)">]</span>

<span style="color:var(--syntax-text-color)">completion</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">openai</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">ChatCompletion</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">create</span><span style="color:var(--syntax-text-color)">(</span>
    <span style="color:var(--syntax-text-color)">model</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"gpt-3.5-turbo"</span><span style="color:var(--syntax-text-color)">,</span>
    <span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-declaration-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">completion</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">choices</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">].</span><span style="color:var(--syntax-text-color)">message</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">content</span><span style="color:var(--syntax-text-color)">)</span>

</code></span></span>

So we're creating a messaging dialog that is triggered by that system message and sending the user a question about the assistant's name.

The test response is accessible .choices[0].message.content, so we print it out.

This is the response I get when I run:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code> ⚡  python app.py                                                             
I am a language model AI and my name is OpenAI. But for the purpose of this conversation, you can refer to me as Mr. Boots, the cat. Meow!
</code></span></span>

You may end up with something slightly different. Language models are just that. But guess what! We're done chatting! Now let's turn this into an infinite loop (with some escaping) so we can have a real conversation with Mr. Boots.

We'll take some input from the user, assume it's not one of our escape commands, and enter our loop. We add that input to the message list and request completion. We'll then print that response and append it to the message list, and wait for another user to respond. User input will determine whether to enter the loop again, or to exit the loop.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-comment-color)"># chat_app/app.py
</span>
<span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">openai</span>
<span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">os</span>

<span style="color:var(--syntax-text-color)">openai</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">api_key</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">os</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">environ</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">get</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">'OPENAI_API_KEY'</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-text-color)">messages</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">[</span>
    <span style="color:var(--syntax-text-color)">{</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"system"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"You are a Cat named Mr. Boots"</span><span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-text-color)">]</span>

<span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">input</span><span style="color:var(--syntax-text-color)">()</span>

<span style="color:var(--syntax-declaration-color)">while</span> <span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-error-color)">not</span> <span style="color:var(--syntax-error-color)">in</span> <span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-string-color)">"exit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"Exit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"quit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"Quit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"stop"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"Stop"</span><span style="color:var(--syntax-text-color)">]:</span>
    <span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">append</span><span style="color:var(--syntax-text-color)">({</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"user"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-text-color)">})</span>
    <span style="color:var(--syntax-text-color)">completion</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">openai</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">ChatCompletion</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">create</span><span style="color:var(--syntax-text-color)">(</span>
        <span style="color:var(--syntax-text-color)">model</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"gpt-3.5-turbo"</span><span style="color:var(--syntax-text-color)">,</span>
        <span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">)</span>

    <span style="color:var(--syntax-text-color)">assistant_response</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">completion</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">choices</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">].</span><span style="color:var(--syntax-text-color)">message</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">content</span>
    <span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">append</span><span style="color:var(--syntax-text-color)">({</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"assistant"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">assistant_response</span> <span style="color:var(--syntax-text-color)">})</span>
    <span style="color:var(--syntax-declaration-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">f</span><span style="color:var(--syntax-string-color)">"Mr. Boots: </span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-text-color)">assistant_response</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span>
    <span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">input</span><span style="color:var(--syntax-text-color)">()</span>

<span style="color:var(--syntax-declaration-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Mr. Boots: GoodBye"</span><span style="color:var(--syntax-text-color)">)</span>
</code></span></span>

Here's what happens when I run:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code> ⚡  python app.py
Hello My name is Mr. Dog. What is your name?
Mr. Boots: My name is Mr. Boots. Nice to meet you, Mr. Dog.
Do you like laying in the sun?
Mr. Boots: Yes, I love to bask in the warmth of the sun. It makes me feel cozy and relaxed. How about you, Mr. Dog? Do you enjoy sunbathing?
exit
Mr. Boots: GoodBye
</code></span></span>

Our first conversation!

Goodbye Mr. Boots! We have a resume to work on!

So let's think about what our resume assistant needs to do.

  1. ready system message
  2. Get a resume or description of a job seeker (candidate)
  3. get some kind of job description
  4. Talk to candidates to get more information about their experiences
  5. Prepare a Better Resume

Once we store it in the cloud, we'll need to add some other stuff, but we'll deal with that in the next article.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-comment-color)"># chat_app/app.py
</span>
<span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">openai</span>
<span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">os</span>

<span style="color:var(--syntax-text-color)">openai</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">api_key</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">os</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">environ</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">get</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">'OPENAI_API_KEY'</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-text-color)">messages</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">[</span>
    <span style="color:var(--syntax-text-color)">{</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"system"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"You are a resume review assistant. You will be provided information about a job candidate. that information might be in the form of a formatted resume, or just a sentence about themselves. You also may also receive a description of a job or position sought by the candidate. Your task as the assistant is to prompt the candidate for additional information they could add to their resume to make it better generally, and more well suited for the job they are seeking specifically. Don't shy away from asking and promoting transferable and soft skills."</span><span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-text-color)">]</span>
<span style="color:var(--syntax-declaration-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Please provide your resume or tell me about yourself"</span><span style="color:var(--syntax-text-color)">)</span>
<span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">input</span><span style="color:var(--syntax-text-color)">()</span>
<span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">append</span><span style="color:var(--syntax-text-color)">({</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"user"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">f</span><span style="color:var(--syntax-string-color)">"Candidate information: </span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-text-color)">user_input</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">})</span>

<span style="color:var(--syntax-declaration-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"What job do you want?"</span><span style="color:var(--syntax-text-color)">)</span>
<span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">input</span><span style="color:var(--syntax-text-color)">()</span>
<span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-string-color)">f</span><span style="color:var(--syntax-string-color)">"Description of the job they want: </span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-text-color)">user_input</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-string-color)">"</span>
<span style="color:var(--syntax-declaration-color)">while</span> <span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-error-color)">not</span> <span style="color:var(--syntax-error-color)">in</span> <span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-string-color)">"exit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"Exit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"quit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"Quit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"stop"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"Stop"</span><span style="color:var(--syntax-text-color)">]:</span>
    <span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">append</span><span style="color:var(--syntax-text-color)">({</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"user"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-text-color)">})</span>
    <span style="color:var(--syntax-text-color)">completion</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">openai</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">ChatCompletion</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">create</span><span style="color:var(--syntax-text-color)">(</span>
        <span style="color:var(--syntax-text-color)">model</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"gpt-3.5-turbo"</span><span style="color:var(--syntax-text-color)">,</span>
        <span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">)</span>

    <span style="color:var(--syntax-text-color)">assistant_response</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">completion</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">choices</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">].</span><span style="color:var(--syntax-text-color)">message</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">content</span>
    <span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">append</span><span style="color:var(--syntax-text-color)">({</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"assistant"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">assistant_response</span> <span style="color:var(--syntax-text-color)">})</span>
    <span style="color:var(--syntax-declaration-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">f</span><span style="color:var(--syntax-string-color)">"Mr. Boots: </span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-text-color)">assistant_response</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span>
    <span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">input</span><span style="color:var(--syntax-text-color)">()</span>

<span style="color:var(--syntax-declaration-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Mr. Boots: GoodBye"</span><span style="color:var(--syntax-text-color)">)</span>
</code></span></span>

A simple start:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code> ⚡  python app.py              
Please provide your resume or tell me about yourself
My name is Jimmy Jimbert and I worked at McDonalds as a team member from Jan 10 2022 to now. I did all of the jobs there. 
What job do you want?
I would like to be a bank teller. 
Mr. Boots: Great, Jimmy! It sounds like you have experience working in a customer service-oriented role, which is helpful when working as a bank teller. Can you please provide more information about your responsibilities at McDonald's, especially those that could be transferable to a bank teller role, such as handling financial transactions, upholding high levels of accuracy and attention to detail, and working as a team with colleagues and customers? Additionally, do you have any experience handling cash efficiently and accurately? Finally, do you have any additional education or certification related to banking or finance that may be relevant for a bank teller role?
exit
Mr. Boots: GoodBye
</code></span></span>

At first, this seemed like a good start to me. AI assistants have already mastered some activities related to both positions, such as cash handling and accuracy. That's the core thing we want it to do.

We also need to make some changes, such as we keep the format of the assistant response as coming from "Mr. Boots" hahaha.

Second, it became clear that we needed a better way to provide assistants with our resumes. Pasting blocks of multi-line text is more work than it's worth, so it's best to just let it load a resume.txtjob description called jd.txt. Nor will this work go to waste as we move on to further steps.

Let's make these files for testing. I'll keep trying to get Jimmy a job at the bank, but if you're doing it yourself, you might as well use your info and the job you're looking for!

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code># chat_app/resume.txt

Jimmy Jimbert

Experience:

Old Navy 3/15/2022 - present
Team member

McDonalds 5/20/2020 - 3/1/2022
Crew member
</code></span></span>

This is a bank teller job I found on Linkedin.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code># chat_app/jd.txt

Bank Teller


PARKWAY BANK

Location: 4106 N Milwaukee Ave.
Chicago, IL. 60641

Hours: Tuesday through Friday 9:00 a.m. – 6:00 p.m.
Saturday 7:45 a.m. - 1:00 p.m.
Hours may change based on the needs of the bank, one day off during the week.

Parkway Bank is looking for a Full-Time Teller at our Six-Corners Branch in Chicago, IL. We are a locally owned and operated financial institution committed to offering the best in customer service, financial products, and services. We maintain a strong presence in our communities through donations, volunteer work, and education. Come be a part of our growing team!

Job Duties:
Responsible for receiving deposits for credit to customer’s deposit and loan accounts (personal and commercial); verifying cash withdrawals and signature endorsements within established limits and securing required approval as necessary; scanning daily work; balancing daily transactions. In addition, tellers are responsible for ensuring quality customer service; maintaining acceptable teller difference records; and referring sales opportunities to the appropriate banking staff. Tellers are required to meet and/or exceed appropriate referral goals and perform other job functions as assigned by supervisor/manager.

Requirements:


    High school diploma, GED or currently pursuing.
    Three months cash handling
    Effective customer service and sales skills
    Good math and clerical skills
    Ability to effectively communicate (oral and written) with fellow employees and customers.
    Must be accurate and detail oriented.
    Ability to work varied hours/days as needed.
    Proficient using a PC, keyboard, and computer mouse.
    Basic knowledge of Outlook, Microsoft Word and Excel preferred.
    Ability to walk, sit, stoop, and stand for long periods of time.
    Ability to lift, move, push, or pull up to 25 pounds.


Parkway Bank is an Equal Opportunity Employer
Minority/Female/Disability/Veteran
</code></span></span>

Now let's modify our python code to import these files, get rid of Mr. Boots (you're a good cat), and add some spaces and some newlines () to the output to make things more readable \n.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-comment-color)"># chat_app/app.py
</span>
<span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">openai</span>
<span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">os</span>

<span style="color:var(--syntax-text-color)">openai</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">api_key</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">os</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">environ</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">get</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">'OPENAI_API_KEY'</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-text-color)">messages</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">[</span>
    <span style="color:var(--syntax-text-color)">{</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"system"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"You are a resume review assistant. You will be provided information about a job candidate. that information might be in the form of a formatted resume, or just a sentence about themselves. You also may also receive a description of a job or position sought by the candidate. Your task as the assistant is to prompt the candidate for additional information they could add to their resume to make it better generally, and more well suited for the job they are seeking specifically. Don't shy away from asking and promoting transferable and soft skills."</span><span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-text-color)">]</span>

<span style="color:var(--syntax-declaration-color)">with</span> <span style="color:var(--syntax-text-color)">open</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"resume.txt"</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">as</span> <span style="color:var(--syntax-text-color)">f</span><span style="color:var(--syntax-text-color)">:</span>
    <span style="color:var(--syntax-text-color)">resume</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">f</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">readlines</span><span style="color:var(--syntax-text-color)">()</span>
<span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">append</span><span style="color:var(--syntax-text-color)">({</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"user"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">f</span><span style="color:var(--syntax-string-color)">"Candidate information: </span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-string-color)">''</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">join</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">resume</span><span style="color:var(--syntax-text-color)">)</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">})</span>

<span style="color:var(--syntax-declaration-color)">with</span> <span style="color:var(--syntax-text-color)">open</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"jd.txt"</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">as</span> <span style="color:var(--syntax-text-color)">f</span><span style="color:var(--syntax-text-color)">:</span>
    <span style="color:var(--syntax-text-color)">jd</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">f</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">readlines</span><span style="color:var(--syntax-text-color)">()</span>

<span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-string-color)">f</span><span style="color:var(--syntax-string-color)">"Description of the job they want: </span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-string-color)">''</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">join</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">jd</span><span style="color:var(--syntax-text-color)">)</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-string-color)">"</span>
<span style="color:var(--syntax-declaration-color)">while</span> <span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-error-color)">not</span> <span style="color:var(--syntax-error-color)">in</span> <span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-string-color)">"exit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"Exit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"quit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"Quit"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"stop"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"Stop"</span><span style="color:var(--syntax-text-color)">]:</span>
    <span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">append</span><span style="color:var(--syntax-text-color)">({</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"user"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-text-color)">})</span>

    <span style="color:var(--syntax-text-color)">completion</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">openai</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">ChatCompletion</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">create</span><span style="color:var(--syntax-text-color)">(</span>
        <span style="color:var(--syntax-text-color)">model</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"gpt-3.5-turbo"</span><span style="color:var(--syntax-text-color)">,</span>
        <span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">)</span>

    <span style="color:var(--syntax-text-color)">assistant_response</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">completion</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">choices</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">].</span><span style="color:var(--syntax-text-color)">message</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">content</span>
    <span style="color:var(--syntax-text-color)">messages</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">append</span><span style="color:var(--syntax-text-color)">({</span><span style="color:var(--syntax-string-color)">"role"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"assistant"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"content"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">assistant_response</span> <span style="color:var(--syntax-text-color)">})</span>
    <span style="color:var(--syntax-declaration-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">f</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-literal-color)">\n</span><span style="color:var(--syntax-string-color)">Assistant:</span><span style="color:var(--syntax-literal-color)">\n</span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-text-color)">assistant_response</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-literal-color)">\n</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span>

    <span style="color:var(--syntax-text-color)">user_input</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">input</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"User:</span><span style="color:var(--syntax-literal-color)">\n</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-declaration-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Assistant: GoodBye"</span><span style="color:var(--syntax-text-color)">)</span>
</code></span></span>

When we try it out:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>⚡  python app.py

Assistant:
Thank you for sharing your experience, Jimmy. Based on the requirements listed for the Bank Teller position at Parkway Bank, here are some potential areas you could add to your resume to make it more relevant to the job:

- Highlight your experience with cash handling, as it is an important requirement for the job.
- Include any instances where you excelled in customer service, as providing quality customer service is one of the main responsibilities of a bank teller.
- Be sure to mention your proficiency with basic computer programs such as Microsoft Word and Excel, as well as your ability to learn new systems quickly.
- Detail how you have been able to work varied hours or extended shifts in the past, as this is a requirement for the position.
- Are there any sales or referral goals you have met in previous jobs? If so, including that information on your resume would be helpful since tellers are expected to refer sales opportunities to the appropriate staff at Parkway Bank.

Additionally, Parkway Bank seeks individuals who are detail oriented and possess good math and clerical skills. Can you think of any instances where you have been especially detail-oriented or when you have had to use your math skills on the job? These could be good examples to include on your resume.

User:
Im really great and really qualified in all of those things.  add them to my resume and show me what that resume would look like. 

Assistant:
Certainly, Jimmy! Here's a revised version of your resume that incorporates your qualifications, experience, and the requirements from the job description:

**Jimmy Jimbert**

**Experience**

Old Navy | Team Member | 3/15/2022 - Present

- Assisted customers with product inquiries, fitting room requests, and checkout procedures.
- Maintained store appearance by restocking merchandise and organizing displays.

McDonald's | Crew Member | 5/20/2020 - 3/1/2022

- Prepared food and drinks, operated cash register, maintained cleanliness of the restaurant.
- Provided exceptional customer service and resolved customer concerns.

**Education**

High School Diploma | XYZ High School | Graduated June 2020

**Skills**

- Cash handling: Proficient in accurately counting, verifying, and processing cash transactions.
- Customer service: Able to provide friendly, efficient service and resolve customer concerns.
- Sales and referral: Consistently met or exceeded sales goals and referred opportunities to appropriate staff.
- Math and clerical skills: Possess strong skills in performing basic math calculations and maintaining accurate records.
- Computer proficiency: Proficient in using Microsoft Word, Excel, and Outlook.
- Detail-oriented: Meticulous when handling customer transactions and maintaining records.
- Flexible: Able to work varied hours and days as needed.

I hope this helps! Let me know if there's anything else I can do for you.

User:
exit
Assistant: GoodBye
</code></span></span>

Well, this is neat. It manages to fill Jimmy's typical experience and touches all the boxes in a way that I think most people can claim without feeling like they're lying.

Next we will deploy this application to the cloud!

 

Guess you like

Origin blog.csdn.net/jascl/article/details/131325510