Responding to recruiter emails with GPT-3

If you’re just interested in the code, here it is.

Like many software engineers, each week I receive multiple emails from recruiters.

I’m grateful to work in a field with such opportunities, and I know that receiving a lot offers to interview is a good problem to have. But, practically, most of the time I’m not looking for a new job, and so handling all these emails is a recurring administrative task.

Here’s an example thread that I neglected to respond to:

screenshot of emails from a recruiter

I do try to respond to all recruiter emails with a short message that pretty much always follows a format like:

Hi <recruiter name>,

Thanks for reaching out! I’m not interested at this time, but I’ll keep <your company> in mind.

- Matt

There are a few reasons that I respond to these emails (rather than merely ignore them):

  1. It’s polite
  2. If I don’t respond, the recruiter will often send multiple follow-up emails
  3. Maintaining a cordial relationship with the recruiters is in my best interest for future job searches

I use some rough email filtering rules to funnel recruiter emails to an email folder. Then, when I have time, I go through the list of unreads and send my little response.

It would be ideal if I could automate sending these responses. Assuming I get four such emails per week and that it takes two minutes to read and respond to each one, automating this would save me about seven hours of administrative work per year.

A trivial approach would be to send a canned response. But a touch of personalization would aid in my goal of maintaining a good relationship with the recruiter.

Extracting the name of the recruiter and their company from the email using a rule-based approach / trying to parse the text would be really tricky and error prone. Luckily, OpenAI’s GPT-3 language model is quite good at processing this email.

Using the GPT-3 API, we can provide the recruiter’s email along with an example, and extract the required information. It can even format the output as JSON.

    def get_recruiter_name_and_company(email_text: str):
        """Uses OpenAI text models to automatically parse the recruiter's name
        and company from their email."""
    
        prompt = f"""
        Given an email from a recruiter, return the recruiter's first name and the recruiter's company's name formatted as valid JSON.
    
        Example: ***
        Email:
        '''
        Hi Matt! This is Steve Jobs with Apple Computer Company! I'm interested in having you join our team here.
        '''
    
        Response:
        {{"name": "Steve", "company": "Apple Computer Company"}}
        ***
    
        Email:
        '''
        {email_text}
        '''
    
        Response:
        """
    
        # don't make expensive OpenAI API calls unless operating in production
        if not IS_PROD:
            return json.loads('{"name": "Steve", "company": "Apple Computer Company"}')
    
        completion = openai.Completion.create(
            model="text-davinci-002",
            prompt=textwrap.dedent(prompt),
            max_tokens=20,
            temperature=0,
        )
    
        return json.loads(completion.choices[0].text)

Here’s an example from the OpenAI Playground.

screenshot of the OpenAI playground

With the recruiter’s name and company in hand, responding is just a matter of interpolating those variables into the body of my standard response template:

response = f"""\
Hi {recruiter_name or ""},
Thanks for reaching out! I'm not interested in new opportunities at this time, but I'll keep {recruiter_company or "your company"} in mind for the future.
Thanks again,
{SIGNATURE}
"""

IMAP and SMTP are used to interface with the mailbox. The rest of the code can be found in this repo.

This solution worked well for the handful of emails I tried it on. I’m planning to run this on a cron to save myself some time and automatically maintain recruiter relationships.