Build an AI Resume Tailor with Claude

Build a Python CLI tool that tailors your resume to any job using Claude.

Introduction

30 Second Summary

Applying for jobs means rewriting your resume over and over to match each posting. It is tedious, time-consuming, and easy to get wrong.

In this project, you will build a Python command-line tool that uses Claude's AI to automatically tailor your resume for any job description you paste in.

What You'll Build

A CLI tool that reads your master resume, accepts a job description, and calls the Claude API to produce a customized version optimized for the target role.

By the end of this project, you'll have:

  • A working Python script that integrates with the Claude API to tailor resumes on demand.
  • A reusable system prompt engineered for professional, ATS-friendly resume output.
  • A personal tool you can use immediately for real job applications.
  • Secret Mission: Add a match score feature that rates how well your resume fits a job before and after tailoring.

Are there any prerequisites?

None. This project includes full setup instructions for Python, the Anthropic SDK, and your code editor. You do not need any prior programming experience to follow along.

Before We Start

Before We Start...

Set Up Python and Your Anthropic Account

Before you can build your resume tailor, you need two things in place: Python to run your script and an Anthropic account to access Claude's API.

In this step, you'll install Python, create your Anthropic Console account, and configure your API key so your script can communicate with Claude.

In this step, get ready to:
  • Install and verify Python 3.9+.
  • Create an Anthropic Console account and claim free trial credits.
  • Generate an API key and set it as an environment variable.
Check your Python version

The Anthropic SDK requires Python 3.9 or higher. Let's check whether you already have it installed.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Terminal (macOS) or cmd (Windows) and press Enter to open it.

Check your Python version by running the command for your operating system:

macOS

  • Check your Python version by running:
python3 --version

Windows

  • Check your Python version by running:
py --version

You should see output like Python 3.X.Y where X is 9 or higher.

✔️ I see version 3.9 or higher

You're all set. Move on to the next substep below.

ⓧ I see an older version

You have Python installed, but it's an older version that won't work with the Anthropic SDK.

  • Visit python.org/downloads and download the latest Python 3 installer.
  • Run the installer. On Windows, check the box that says Add Python to PATH before clicking Install Now.
  • Close and reopen your terminal, then run the version check command again to confirm the new version appears.

macOS users with an older default Python

macOS may still point python3 to an older version even after installing a newer one. If that happens, try running the full path (e.g. /Library/Frameworks/Python.framework/Versions/3.12/bin/python3 --version) or install via Homebrew with brew install python.

ⓧ Command not found

Python is not installed on your machine yet.

  • Visit python.org/downloads and download the latest Python 3 installer for your operating system.
  • Run the installer. On Windows, check the box that says Add Python to PATH before clicking Install Now.
  • Close and reopen your terminal after installation.
  • Run the version check command again to confirm Python is now installed.

Still not recognized after installing?

On Windows, make sure you checked Add Python to PATH during installation. If you missed it, rerun the installer and select Modify to add it.

On macOS, the installer from python.org should automatically add Python to your path. If python3 still isn't found, try opening a fresh terminal window.

Help me troubleshoot my Python installation

Create your Anthropic Console account

The Anthropic Console is where you manage your API keys and usage credits. You'll create a free account and claim trial credits to cover the cost of this project.

  • Open your browser and navigate to console.anthropic.com.
  • Click Sign Up and create an account using your email or a Google/GitHub login.
  • Complete the phone verification step when prompted.
  • After verifying, you should see $5 in free trial credits added to your account.

What about the $5 free credits?

New Anthropic accounts typically receive $5 in free trial credits after phone verification. This is more than enough for this project. Each resume tailoring costs less than $0.01 with the model we'll use.

If you don't see free credits, the minimum top-up is $5 and will cover hundreds of resume tailoring operations.

Generate your API key and set it as an environment variable

An API key is a secret credential that lets your Python script authenticate with Claude's servers. You'll store it in an environment variable so your code can access it without hardcoding it.

  • In the Anthropic Console, navigate to the API Keys section.
  • Click Create Key.
  • Give your key a name like resume-tailor and click Create Key.
  • Copy the key immediately. You won't be able to see it again after closing this dialog.

Save your key somewhere safe

Your API key is shown only once at creation time. Paste it into a temporary notes file or password manager before closing the dialog. If you lose it, you'll need to create a new one.

Now set the key as an environment variable in your terminal so the Anthropic SDK can find it automatically.

macOS

  • Set the environment variable by running this command (replace the placeholder with your actual key):
export ANTHROPIC_API_KEY=your-api-key-here

What does this command do?

The export command creates an environment variable in your current terminal session. The Anthropic SDK automatically reads the ANTHROPIC_API_KEY variable, so you never need to paste your key directly into code.

Windows

  • Set the environment variable by running this command in PowerShell (replace the placeholder with your actual key):
$env:ANTHROPIC_API_KEY="your-api-key-here"

What does this command do?

The $env: prefix sets an environment variable in your current PowerShell session. The Anthropic SDK automatically reads the ANTHROPIC_API_KEY variable, so you never need to paste your key directly into code.

This variable lasts for your terminal session only

When you close your terminal, the variable disappears. You'll need to re-run this command each time you open a new terminal to work on this project.

  • Verify the variable is set by running:

macOS

echo $ANTHROPIC_API_KEY

Windows

echo $env:ANTHROPIC_API_KEY

You should see your API key printed in the terminal output.

Seeing a blank output?

Make sure you ran the export (macOS) or $env: (Windows) command in the same terminal window where you're checking. If you opened a new terminal, you need to set the variable again.

Help me set up my ANTHROPIC_API_KEY environment variable

Your environment is ready to go. Next up, you'll create your project folder and start writing the resume tailoring script.

Set Up Your Project

Your Python environment is ready and your API key is configured. Now it's time to create the actual project files that will power your resume tailor.

In this step, you'll set up a project folder, install the Anthropic Python SDK, and create two files: a resume file and a Python script that reads it.

In this step, get ready to:
  • Create a project folder and install the Anthropic Python SDK.
  • Create a master resume file for Claude to tailor.
  • Write the basic Python script structure with file-reading logic.
Create your project folder and install the SDK

Before writing any code, you need a dedicated folder for this project and the Anthropic SDK installed so Python can talk to Claude's API.

  • Open your terminal by pressing Cmd+Space (macOS) or the Windows key (Windows), then typing Terminal (macOS) or PowerShell (Windows) and pressing Enter.
  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your project folder and move into it by running these commands:
mkdir resume-tailor
cd resume-tailor
  • Confirm the folder exists by running:
ls

You should see an empty output since the folder is brand new.

  • Install the Anthropic Python SDK by running:
pip install anthropic

You should see output ending with Successfully installed anthropic-... along with its dependencies.

Seeing a pip error?

If you see a "command not found" error for pip, try using pip3 install anthropic instead.

If you see a permissions error, try adding --user at the end of the command.

help me fix my pip install error for the anthropic package

Create your master resume file

Your resume tailor needs a source resume to work from. You'll create a text file containing your resume content that the script will read every time it runs.

  • Open your code editor by pressing Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Cursor (or VS Code if you're using that) and press Enter to open it.
  • Click File in the top menu bar.
  • Click Open Folder.
  • Navigate to your Desktop, select the resume-tailor folder, and click Open.
  • Create a new file by pressing Cmd+N (macOS) or Ctrl+N (Windows).
  • Save it immediately with Cmd+S (macOS) or Ctrl+S (Windows), and name it my_resume.txt.
  • Paste the following sample resume into the file:
ALEX JOHNSON
Software Developer
alex.johnson@email.com | (555) 123-4567 | linkedin.com/in/alexjohnson | github.com/alexjohnson

SUMMARY
Software developer with 3 years of experience building web applications. Skilled in Python, JavaScript, and cloud technologies. Passionate about writing clean, maintainable code and solving complex problems.

EXPERIENCE

Software Developer | TechCorp Inc. | June 2022 - Present
- Developed and maintained RESTful APIs using Python and Flask, serving 50,000+ daily requests
- Built responsive front-end interfaces using React and TypeScript
- Implemented CI/CD pipelines with GitHub Actions, reducing deployment time by 40%
- Collaborated with cross-functional teams in an Agile environment using Jira and Confluence
- Optimized database queries in PostgreSQL, improving response times by 30%

Junior Developer | StartupXYZ | January 2021 - May 2022
- Built internal tools using Python and Django to automate manual processes
- Created data visualization dashboards using JavaScript and D3.js
- Participated in code reviews and contributed to team coding standards
- Wrote unit and integration tests, achieving 85% code coverage

EDUCATION
Bachelor of Science in Computer Science | State University | 2020
- GPA: 3.7/4.0
- Relevant coursework: Data Structures, Algorithms, Database Systems, Web Development

SKILLS
Languages: Python, JavaScript, TypeScript, SQL, HTML/CSS
Frameworks: React, Flask, Django, Express.js
Tools: Git, Docker, AWS (EC2, S3, Lambda), PostgreSQL, MongoDB
Practices: Agile/Scrum, CI/CD, Test-Driven Development, RESTful API Design

Use your own resume

If you have a real resume ready, replace the sample content with your own. The script works with any plain-text resume format. You can always update this file later.

  • Save my_resume.txt with Cmd+S (macOS) or Ctrl+S (Windows).
  • Confirm the file appears in the Explorer sidebar on the left. You should see my_resume.txt listed under your resume-tailor folder.

Don't see the file in the sidebar?

Make sure you saved the file inside the resume-tailor folder on your Desktop. If you accidentally saved it elsewhere, drag it into the correct folder using your file manager.

help me find where my file was saved and move it to the right folder

Create the resume_tailor.py script

Now you'll create the Python script that will eventually call Claude to tailor your resume. You'll start with the basic structure: importing the SDK, writing a function to load your resume file, and initializing the Anthropic client.

  • Create another new file with Cmd+N (macOS) or Ctrl+N (Windows).
  • Save it as resume_tailor.py.
  • Add the following imports at the top of the file:
import anthropic
import os
from datetime import datetime

What do these imports do?

  • anthropic is the official SDK that lets your script communicate with Claude's API.
  • os provides access to operating system features like reading environment variables.
  • datetime will be used later to timestamp your tailored resume output files.
  • Below the imports, add the resume-loading function and client initialization:

def load_resume(filepath="my_resume.txt"):
    # Open the resume file and return its contents as a string
    with open(filepath, "r", encoding="utf-8") as f:
        return f.read()


# Initialize the Anthropic client (reads ANTHROPIC_API_KEY from your environment)
client = anthropic.Anthropic()

What does this code do?

load_resume() opens your my_resume.txt file and reads its entire contents into a string. The default filepath parameter means you can call it without arguments and it will find your resume automatically.

anthropic.Anthropic() creates a client that connects to Claude's API. It automatically reads the ANTHROPIC_API_KEY environment variable you set in Step 1, so you never need to paste your key into the code.

  • Save resume_tailor.py with Cmd+S (macOS) or Ctrl+S (Windows).
  • Open the terminal inside your editor by pressing Ctrl+` (backtick key, same on both platforms).
  • Verify the script runs without errors:
python resume_tailor.py

You should see no output and no errors. The script loads your resume and initializes the client, then exits silently because there are no print statements yet.

Seeing an error when you run the script?

If you see ModuleNotFoundError: No module named 'anthropic', the SDK is not installed in the Python version you're running. Try python3 resume_tailor.py or reinstall with pip3 install anthropic.

If you see FileNotFoundError, make sure my_resume.txt is saved in the same folder as resume_tailor.py.

If you see an authentication error mentioning your API key, double-check that ANTHROPIC_API_KEY is set in your environment. You may need to restart your terminal for it to take effect.

help me fix the error I'm seeing when running resume_tailor.py

✔️ Awesome, I've got everything!

Great. Double check you've saved both files, then move on to the next step.

ⓧ I'd like to double check the full code

Here is the complete resume_tailor.py so far:

import anthropic
import os
from datetime import datetime


def load_resume(filepath="my_resume.txt"):
    with open(filepath, "r", encoding="utf-8") as f:
        return f.read()


client = anthropic.Anthropic()

Your project structure is in place. Next up, you'll write the prompt that tells Claude exactly how to tailor your resume for a specific job.

Engineer Your Resume Tailoring Prompt

Your resume file is loaded and ready. Now you need to tell Claude exactly how to tailor it.

The quality of AI output depends almost entirely on the quality of your instructions. In this step, you will write a detailed system prompt that turns Claude into a professional resume writer, then wire it up with an API call.

In this step, get ready to:
  • Write a system prompt with 8 rules for professional resume tailoring.
  • Build a user message that combines your resume and a job description.
  • Make your first API call to Claude using the Anthropic SDK.
Write your resume tailoring function

A system prompt is a set of instructions that tells an AI model how to behave for an entire conversation. It shapes the model's personality, constraints, and output format before the user ever sends a message.

You will wrap everything (the system prompt, the user message, and the API call) inside one function called tailor_resume.

  • In resume_tailor.py, find this line at the bottom of your file:
client = anthropic.Anthropic()
  • Delete that line entirely. You will move it into a main() function in the next step.
  • Below the load_resume() function, add the following tailor_resume function:
def tailor_resume(client, resume, job_description):
    system_prompt = """You are a professional resume writer and career coach. Your job is to tailor a resume to match a specific job description.

Rules:
1. NEVER fabricate experience, skills, or qualifications the candidate does not have.
2. Reorder bullet points to prioritize the most relevant experience for this role.
3. Rewrite bullet points to incorporate keywords and phrases from the job description where truthful.
4. Adjust the summary/objective to align with the target role.
5. Emphasize transferable skills that match the job requirements.
6. Keep the format clean and ATS-friendly (no tables, columns, or graphics).
7. If the candidate lacks a required skill, do NOT add it. Instead, highlight the closest related experience.
8. Output ONLY the tailored resume text. No explanations, no commentary."""

    message = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=4096,
        system=system_prompt,
        messages=[
            {
                "role": "user",
                "content": f"Here is my current resume:\n\n{resume}\n\n---\n\nHere is the job description I am applying for:\n\n{job_description}\n\n---\n\nPlease tailor my resume for this specific job.",
            }
        ],
    )

    return message.content[0].text

What does this code do?

This function takes three inputs: the API client, your resume text, and a job description. It sends both to Claude along with detailed instructions on how to tailor the resume.

  • system_prompt defines 8 rules that constrain Claude's behavior. The most important rule is #1: never fabricate anything.
  • client.messages.create() sends the request to Claude's Messages API.
  • message.content[0].text extracts the plain text response from Claude's reply.
  • Save resume_tailor.py.

Seeing a syntax error?

The system prompt uses triple quotes ("""). Make sure you have exactly three double-quote characters at both the start and end of the string.

If you see unterminated triple-quoted string literal, check that the closing """ is on its own line directly after rule 8.

Help me fix a syntax error in my tailor_resume function's triple-quoted system prompt string.

Understand the user message format

The user message is the second key piece of your prompt. It packages your resume and the job description into a single structured message that Claude can parse.

Why separate the resume and job description with dashes?

The --- dividers act as clear section boundaries. Without them, Claude might confuse where your resume ends and the job description begins.

The final line ("Please tailor my resume for this specific job.") gives Claude an explicit instruction to act. Without a clear ask, the model might just summarize or analyze instead of rewriting.

Understand the API call parameters

The client.messages.create() call is where your prompt reaches Claude. Each parameter controls a different aspect of the request.

What do the API parameters mean?

  • model="claude-haiku-4-5" selects Claude Haiku 4.5. It costs $1 per million input tokens and $5 per million output tokens. A typical resume tailoring costs less than one cent.
  • max_tokens=4096 sets the maximum length of Claude's response. A full resume fits comfortably within this limit.
  • system=system_prompt passes your 8 rules as the system-level instructions.
  • messages=[...] contains the conversation history. Here it is a single user message with your resume and job description.

Why Haiku 4.5 instead of a larger model?

Resume tailoring is a structured text rewriting task. Haiku 4.5 handles it well at a fraction of the cost. Each call costs roughly $0.009, meaning your $5 in credits covers hundreds of tailoring operations.

Sonnet costs 3x more per call. For this use case, the quality difference is minimal.

✔️ Awesome, I've got everything!

Great. Double check you have saved resume_tailor.py.

ⓧ I'd like to double check the full code

Here is the full resume_tailor.py so far:

import anthropic
import os
from datetime import datetime


def load_resume(filepath="my_resume.txt"):
    with open(filepath, "r", encoding="utf-8") as f:
        return f.read()


def tailor_resume(client, resume, job_description):
    system_prompt = """You are a professional resume writer and career coach. Your job is to tailor a resume to match a specific job description.

Rules:
1. NEVER fabricate experience, skills, or qualifications the candidate does not have.
2. Reorder bullet points to prioritize the most relevant experience for this role.
3. Rewrite bullet points to incorporate keywords and phrases from the job description where truthful.
4. Adjust the summary/objective to align with the target role.
5. Emphasize transferable skills that match the job requirements.
6. Keep the format clean and ATS-friendly (no tables, columns, or graphics).
7. If the candidate lacks a required skill, do NOT add it. Instead, highlight the closest related experience.
8. Output ONLY the tailored resume text. No explanations, no commentary."""

    message = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=4096,
        system=system_prompt,
        messages=[
            {
                "role": "user",
                "content": f"Here is my current resume:\n\n{resume}\n\n---\n\nHere is the job description I am applying for:\n\n{job_description}\n\n---\n\nPlease tailor my resume for this specific job.",
            }
        ],
    )

    return message.content[0].text

Your tailoring function is ready to go. In the next step, you will build an interactive loop so you can paste job descriptions straight into the terminal and get tailored resumes back instantly.

Build the Interactive Loop

You have two core functions ready: one to load your resume and one to send it to Claude for tailoring. But right now, there's no way to actually run the tool.

In this step, you'll wire everything together into an interactive command-line interface. You'll be able to paste any job description into the terminal, get a tailored resume back, and have it automatically saved to a file.

In this step, get ready to:
  • Add a function to save tailored resumes as timestamped files.
  • Build an interactive loop that accepts multi-line job descriptions.
  • Add error handling for API failures and empty inputs.
Add a function to save tailored resumes

Each time Claude tailors your resume, you want a permanent copy saved to disk. A timestamp in the filename ensures you never accidentally overwrite a previous version.

  • In resume_tailor.py, add this function below your existing tailor_resume() function:
def save_output(tailored_resume, job_title="job"):
    # Create a unique filename using the current date and time
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"tailored_resume_{timestamp}.txt"
    with open(filename, "w", encoding="utf-8") as f:
        f.write(tailored_resume)
    return filename

What does this code do?

  • datetime.now().strftime("%Y%m%d_%H%M%S") generates a timestamp like 20260607_143052, giving each output file a unique name.
  • The function writes the tailored resume to a .txt file and returns the filename so you can tell the user where it was saved.
Build the main function with the input loop

The main() function is where the tool comes to life. It initializes the Anthropic client, loads your resume once, then enters a loop where you can paste job descriptions one after another.

  • Below your save_output() function, add the main() function and entry point:
def main():
    # Initialize the Anthropic client (reads ANTHROPIC_API_KEY from env)
    client = anthropic.Anthropic()

    print("=" * 50)
    print("   AI Resume Tailor - Powered by Claude")
    print("=" * 50)

    # Load your resume once at startup
    resume = load_resume()
    print(f"\nResume loaded ({len(resume)} characters)")

    while True:
        print("\n" + "-" * 50)
        print("Paste the job description below.")
        print("(Type 'END' on a new line when done, or 'quit' to exit)")
        print("-" * 50)

        # Collect multi-line input until user types END or quit
        lines = []
        while True:
            line = input()
            if line.strip().upper() == "END":
                break
            if line.strip().lower() == "quit":
                print("\nGoodbye! Good luck with your applications!")
                return
            lines.append(line)

        job_description = "\n".join(lines)

        # Skip empty submissions
        if not job_description.strip():
            print("No job description entered. Try again.")
            continue

        print("\nTailoring your resume... (this takes a few seconds)")

        try:
            tailored = tailor_resume(client, resume, job_description)
            filename = save_output(tailored)

            print(f"\nDone! Tailored resume saved to: {filename}")
            print("\n" + "=" * 50)
            print("TAILORED RESUME PREVIEW:")
            print("=" * 50)
            print(tailored)

        except anthropic.APIError as e:
            print(f"\nAPI Error: {e.message}")
            print("Check your API key and account credits.")


if __name__ == "__main__":
    main()

What does this code do?

  • anthropic.Anthropic() creates the API client. It automatically reads your ANTHROPIC_API_KEY environment variable.
  • The while True loop keeps the tool running so you can tailor multiple resumes in one session. Type quit to exit or END to submit each job description.
  • The inner while True loop collects lines one at a time, allowing you to paste multi-line job descriptions without them being cut off.
  • The try/except block catches anthropic.APIError so the tool prints a helpful message instead of crashing if something goes wrong with the API call.

Why catch anthropic.APIError?

anthropic.APIError is the base exception for all API-specific errors from the Anthropic SDK. It covers authentication failures, rate limits, and server issues in a single catch.

Without it, a network hiccup or expired credit balance would crash your entire script. The error handler keeps the loop alive so you can fix the issue and try again.

  • Save resume_tailor.py.

Seeing a syntax error when you save?

  • Make sure the save_output() function is placed after tailor_resume() and before main(). Order matters in Python.
  • Check that if __name__ == "__main__": is at the very bottom of the file, outside any function.
  • Verify your indentation is consistent. Every line inside main() should be indented one level (4 spaces).

help me fix a syntax error in my resume_tailor.py file

✔️ Awesome, I've got everything!

Great. Make sure you have saved resume_tailor.py with both new functions and the entry point at the bottom.

ⓧ I'd like to double check the full code

Here is the complete resume_tailor.py file at this point:

import anthropic
import os
from datetime import datetime


def load_resume(filepath="my_resume.txt"):
    with open(filepath, "r", encoding="utf-8") as f:
        return f.read()


def tailor_resume(client, resume, job_description):
    system_prompt = """You are a professional resume writer and career coach. Your job is to tailor a resume to match a specific job description.

Rules:
1. NEVER fabricate experience, skills, or qualifications the candidate does not have.
2. Reorder bullet points to prioritize the most relevant experience for this role.
3. Rewrite bullet points to incorporate keywords and phrases from the job description where truthful.
4. Adjust the summary/objective to align with the target role.
5. Emphasize transferable skills that match the job requirements.
6. Keep the format clean and ATS-friendly (no tables, columns, or graphics).
7. If the candidate lacks a required skill, do NOT add it. Instead, highlight the closest related experience.
8. Output ONLY the tailored resume text. No explanations, no commentary."""

    message = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=4096,
        system=system_prompt,
        messages=[
            {
                "role": "user",
                "content": f"Here is my current resume:\n\n{resume}\n\n---\n\nHere is the job description I am applying for:\n\n{job_description}\n\n---\n\nPlease tailor my resume for this specific job.",
            }
        ],
    )

    return message.content[0].text


def save_output(tailored_resume, job_title="job"):
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"tailored_resume_{timestamp}.txt"
    with open(filename, "w", encoding="utf-8") as f:
        f.write(tailored_resume)
    return filename


def main():
    client = anthropic.Anthropic()

    print("=" * 50)
    print("   AI Resume Tailor - Powered by Claude")
    print("=" * 50)

    resume = load_resume()
    print(f"\nResume loaded ({len(resume)} characters)")

    while True:
        print("\n" + "-" * 50)
        print("Paste the job description below.")
        print("(Type 'END' on a new line when done, or 'quit' to exit)")
        print("-" * 50)

        lines = []
        while True:
            line = input()
            if line.strip().upper() == "END":
                break
            if line.strip().lower() == "quit":
                print("\nGoodbye! Good luck with your applications!")
                return
            lines.append(line)

        job_description = "\n".join(lines)

        if not job_description.strip():
            print("No job description entered. Try again.")
            continue

        print("\nTailoring your resume... (this takes a few seconds)")

        try:
            tailored = tailor_resume(client, resume, job_description)
            filename = save_output(tailored)

            print(f"\nDone! Tailored resume saved to: {filename}")
            print("\n" + "=" * 50)
            print("TAILORED RESUME PREVIEW:")
            print("=" * 50)
            print(tailored)

        except anthropic.APIError as e:
            print(f"\nAPI Error: {e.message}")
            print("Check your API key and account credits.")


if __name__ == "__main__":
    main()

Your resume tailor is now fully functional. In the next step, you'll take it for a real test drive with an actual job description and see Claude in action.

Test with a Real Job Description

Your resume tailor is fully built. It can read your resume, accept a job description, call Claude, and save the result to a file.

Now it is time to put it to the test with a real job posting. You will run the script, paste in a job description, and review how well Claude tailors your resume to match the role.

In this step, get ready to:
  • Run the script and paste in a real job description.
  • Review the tailored output for keyword matching and truthfulness.
  • Iterate on your system prompt if needed to improve results.
Run the script with a real job description

Before you run the script, find a real job description to use. Open a job board (LinkedIn, Indeed, or your company's career page) and copy the full text of a posting that interests you.

Pick a role that overlaps with your resume

For the best first test, choose a job description that has some overlap with your experience. This lets you clearly see how Claude reorders and rewords your bullet points to match the role's requirements.

  • Run the resume tailor script by entering this command in your terminal:

macOS

python3 resume_tailor.py

Windows

py resume_tailor.py

You should see the header banner and a confirmation that your resume was loaded:

==================================================
   AI Resume Tailor - Powered by Claude
==================================================

Resume loaded (1234 characters)

--------------------------------------------------
Paste the job description below.
(Type 'END' on a new line when done, or 'quit' to exit)
--------------------------------------------------
  • Paste the full job description text into the terminal.
  • After pasting, type END on a new line and press Enter to submit.

Why type END on a new line?

Job descriptions are multi-line text. The script collects every line you paste until it sees the word END by itself. This lets you paste as much text as needed without accidentally submitting early.

The script prints "Tailoring your resume..." while it waits for Claude's response. After a few seconds, you should see the tailored resume printed in your terminal.

Seeing an API error?

If you see an authentication error, your ANTHROPIC_API_KEY environment variable is not set correctly. Close and reopen your terminal, then set the variable again before running the script.

If you see a credit-related error, check your balance at console.anthropic.com. Each tailoring operation costs less than $0.01 with Claude Haiku 4.5, so $5 in credits covers hundreds of runs.

Help me debug my API error

Review the tailored output

A good tailored resume passes two checks. It incorporates keywords from the job description, and it stays truthful to your actual experience.

  • Read through the tailored resume printed in your terminal.
  • Compare the summary section to the job description. Check that Claude aligned your summary with the target role's language.
  • Look at your bullet points. Confirm that Claude reordered them to prioritize the most relevant experience for this role.
  • Verify that no new skills or experiences were fabricated. Everything in the tailored resume should trace back to your original.

What should I look for?

Keywords from the job description should now appear naturally in your bullet points. For example, if the job mentions "microservices," Claude might rewrite "Developed and maintained RESTful APIs" to emphasize the distributed nature of those APIs.

The order of your bullet points may change so the most relevant experience appears first. Your skills section might also be reordered to lead with the technologies the job requires.

  • Confirm the output file was saved by running:
ls tailored_resume_*.txt

You should see a file named something like tailored_resume_20260607_143022.txt (with your own timestamp).

Don't see the output file?

Make sure you are running the ls command from the same folder where you ran the script. The output file is saved in the current working directory.

If the script exited with an error before printing "Done!", the file was never created. Check the error message and try running the script again.

Help me find my tailored resume output file

Iterate on your system prompt to improve results

Prompt engineering is iterative. If the output is not quite right, you can adjust the system prompt in your script and re-run to see different results.

  • Open resume_tailor.py and scroll to the system_prompt variable inside the tailor_resume() function.
  • Review the output you just received and identify what you would like Claude to do differently.

What can I tweak in the system prompt?

Here are common adjustments that improve results:

  • If the output is too generic, add a rule like "Use specific metrics and numbers from the original resume."
  • If bullet points are too long, add "Keep each bullet point to one line, under 20 words."
  • If the format drifts, add "Maintain the exact section headings from the original resume."
  • If you want stronger keyword matching, add "Mirror exact phrases from the job description wherever truthful."
  • After editing the system prompt, save resume_tailor.py and run the script again with the same job description.
  • Compare the new output to your previous tailored resume. Note what improved and what still needs work.
  • Type quit when you are satisfied with the results.

Test with different job descriptions

Try pasting two or three different job descriptions to see how the same resume gets tailored in different ways. Each output file is saved with a unique timestamp, so you can compare them side by side.

Output looks wrong after editing the prompt?

Make sure you saved the file before re-running the script. Also check that your new rule does not conflict with an existing rule (for example, asking Claude to add skills while rule #1 says never fabricate).

Help me improve my system prompt for better tailoring results

✔️ Awesome, I've got everything!

Great. Make sure you have saved resume_tailor.py with any prompt iterations you made.

ⓧ I'd like to double check the full code

Here is the full resume_tailor.py for reference:

import anthropic
import os
from datetime import datetime


def load_resume(filepath="my_resume.txt"):
    with open(filepath, "r", encoding="utf-8") as f:
        return f.read()


def tailor_resume(client, resume, job_description):
    system_prompt = """You are a professional resume writer and career coach. Your job is to tailor a resume to match a specific job description.

Rules:
1. NEVER fabricate experience, skills, or qualifications the candidate does not have.
2. Reorder bullet points to prioritize the most relevant experience for this role.
3. Rewrite bullet points to incorporate keywords and phrases from the job description where truthful.
4. Adjust the summary/objective to align with the target role.
5. Emphasize transferable skills that match the job requirements.
6. Keep the format clean and ATS-friendly (no tables, columns, or graphics).
7. If the candidate lacks a required skill, do NOT add it. Instead, highlight the closest related experience.
8. Output ONLY the tailored resume text. No explanations, no commentary."""

    message = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=4096,
        system=system_prompt,
        messages=[
            {
                "role": "user",
                "content": f"Here is my current resume:\n\n{resume}\n\n---\n\nHere is the job description I am applying for:\n\n{job_description}\n\n---\n\nPlease tailor my resume for this specific job.",
            }
        ],
    )

    return message.content[0].text


def save_output(tailored_resume, job_title="job"):
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"tailored_resume_{timestamp}.txt"
    with open(filename, "w", encoding="utf-8") as f:
        f.write(tailored_resume)
    return filename


def main():
    client = anthropic.Anthropic()

    print("=" * 50)
    print("   AI Resume Tailor - Powered by Claude")
    print("=" * 50)

    resume = load_resume()
    print(f"\nResume loaded ({len(resume)} characters)")

    while True:
        print("\n" + "-" * 50)
        print("Paste the job description below.")
        print("(Type 'END' on a new line when done, or 'quit' to exit)")
        print("-" * 50)

        lines = []
        while True:
            line = input()
            if line.strip().upper() == "END":
                break
            if line.strip().lower() == "quit":
                print("\nGoodbye! Good luck with your applications!")
                return
            lines.append(line)

        job_description = "\n".join(lines)

        if not job_description.strip():
            print("No job description entered. Try again.")
            continue

        print("\nTailoring your resume... (this takes a few seconds)")

        try:
            tailored = tailor_resume(client, resume, job_description)
            filename = save_output(tailored)

            print(f"\nDone! Tailored resume saved to: {filename}")
            print("\n" + "=" * 50)
            print("TAILORED RESUME PREVIEW:")
            print("=" * 50)
            print(tailored)

        except anthropic.APIError as e:
            print(f"\nAPI Error: {e.message}")
            print("Check your API key and account credits.")


if __name__ == "__main__":
    main()

Your AI resume tailor is working end-to-end. Next up, you will take this tool further with a Secret Mission that adds match scoring to quantify how much your resume improves.

Secret mission

Add a Match Score Feature

Your resume tailor works great, but how do you know if the tailored version is actually better? In this secret mission, you'll add an AI-powered scoring system that rates your resume's match to the job description on a 0-100 scale, both before and after tailoring, so you can see exactly how much Claude improved your fit.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally, so there are no servers or cloud resources incurring ongoing costs. The Anthropic API is pay-per-use and only charges when you actively run the script.

Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • Project folder containing resume_tailor.py, my_resume.txt, and any tailored_resume_<timestamp>.txt output files.
  • anthropic Python package installed via pip.
  • ANTHROPIC_API_KEY environment variable.
  • Anthropic Console account at console.anthropic.com.

Keep everything running

No action needed. Choose this if you plan to use the resume tailor again for future job applications.

  • Your project files stay on your Desktop and are ready to run anytime.
  • Your ANTHROPIC_API_KEY environment variable remains set so the script works immediately next time.
  • Your Anthropic Console account stays active. You are only charged when you run the script.

Pause - I'll come back to this later

Remove your API key from the environment to prevent accidental usage, but keep your project files for later.

  • Remove the environment variable for the current terminal session.

On macOS or Linux, run:

unset ANTHROPIC_API_KEY

On Windows (Command Prompt), run:

set ANTHROPIC_API_KEY=

On Windows (PowerShell), run:

Remove-Item Env:ANTHROPIC_API_KEY

What about permanent removal?

The commands above only clear the variable for the current terminal session. If you added the key to a shell config file (like .bashrc or .zshrc), remove the line from that file too.

On Windows, if you used setx to set the variable permanently, open System Properties then Environment Variables and delete the ANTHROPIC_API_KEY entry.

  • Your project files and Anthropic Console account remain intact. When you are ready to resume, set the environment variable again and run your script.

Delete - I don't want to use this again

Remove all project resources and clean up completely.

  • Delete your project folder from the Desktop.

On macOS or Linux, run:

cd ~/Desktop
rm -rf resume-tailor

On Windows (Command Prompt), run:

cd %USERPROFILE%\Desktop
rmdir /s /q resume-tailor

Different folder name?

Replace resume-tailor with whatever you named your project folder when you created it.

  • Uninstall the anthropic package by running:
pip uninstall anthropic
  • Remove the ANTHROPIC_API_KEY environment variable using the same steps described in the Pause tab above.
  • Delete your API key from the Anthropic Console.

To delete the API key:

  • Go to console.anthropic.com and sign in.
  • Navigate to Settings then Workspaces.
  • Find your API key in the list, click the ellipsis next to it, and select Delete API Key.
  • Confirm the deletion.
  • (Optional) Delete your Anthropic Console organization entirely.

To delete your Console organization:

  • Navigate to Settings then Organization.
  • Click the red Delete organization button.
  • Follow the confirmation prompts to complete the deletion.

Console deletion is permanent

Deleting your Console organization removes all API keys and usage history. Only do this if you are sure you will not use the Anthropic API again. Anthropic Support can restore your data within seven days if you change your mind.

Nice Work!

Nice Work!

Nice work! You have built your own AI-powered resume tailoring assistant using Python and the Claude API.

Every time you find a job posting that excites you, just run your script, paste the description, and get back a customized resume in seconds.

You've learned how to:

  • Built a Python CLI tool that integrates with the Claude API to generate tailored resumes on demand.
  • Engineered a system prompt for professional resume tailoring that preserves truthfulness while optimizing for ATS keywords.
  • Learned how to read files, manage environment variables, and handle API responses in Python.
  • Added an AI-powered match scoring system to quantify resume fit before and after tailoring.

Ready to quiz yourself?