Build an AI Sales Trainer

Build a CLI sales trainer that simulates realistic customer conversations.

Introduction

30 Second Summary

Verkopers oefenen hun pitch het liefst in een veilige omgeving, maar een realistische sparringpartner is niet altijd beschikbaar. Stel je voor dat je 24/7 kunt oefenen met een klant die zich aanpast aan jouw niveau en eerlijke feedback geeft.

In this project, you will build an AI sales trainer that simulates realistic customer conversations using the Claude API. Je oefent verkoopgesprekken met AI-klanten die unieke persona's, bezwaren en moeilijkheidsgraden hebben, en ontvangt gedetailleerde feedback na elk gesprek.

What You'll Build

Een interactieve command-line sales trainer in Python die de Anthropic API aanstuurt om multi-turn verkoopgesprekken te simuleren met realistische klantpersona's.

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

  • Een werkend Python-script met een multi-turn conversation loop die de Claude API aanstuurt voor realistische klantgesprekken.
  • Drie klantscenario's met oplopende moeilijkheidsgraad (friendly, sceptisch, moeilijk) die elk een uniek persona en gedragsprofiel hebben.
  • Een feedback-systeem dat je verkoopgesprek analyseert op sterke punten, verbeterpunten en concrete tips.
  • Secret Mission: een SPIN-scoring systeem dat je gesprek beoordeelt op Situation, Problem, Implication en Need-Payoff vragen.

Are there any prerequisites?

Je hebt basiskennis van Python nodig (variabelen, functies, loops). Je hebt ook een Anthropic Console account met API key nodig. Die maken we samen aan in Step 1.

Before We Start

Om een AI sales trainer te bouwen heb je een werkende ontwikkelomgeving nodig die kan communiceren met de Claude API.

In deze stap installeer je Python en de Anthropic SDK, configureer je je API key, en maak je de projectbestanden aan.

In this step, get ready to:
  • Python en de Anthropic SDK installeren.
  • Je API key instellen en de verbinding testen.
  • De projectbestanden aanmaken.
Installeer Python en de Anthropic SDK

De Anthropic SDK vereist Python 3.9 of hoger. Laten we eerst controleren of Python correct is geinstalleerd.

  • Open je terminal door Cmd+Space (macOS) of de Windows toets (Windows) in te drukken en Terminal (macOS) of cmd (Windows) te typen.
  • Druk op Enter om de terminal te openen.
  • Controleer je Python versie door dit commando uit te voeren:

macOS

python3 --version

Windows

py --version

✔️ Ik zie versie 3.9 of hoger

Python is klaar. Ga door naar de volgende stap hieronder.

ⓧ Ik zie een oudere versie

Je hebt een oudere versie van Python geinstalleerd die niet compatibel is met de Anthropic SDK.

  • Ga naar python.org/downloads en download de nieuwste versie.
  • Voer de installer uit en zorg dat je Add Python to PATH aanvinkt (Windows).
  • Na installatie, sluit je terminal en open een nieuwe.
  • Voer het versie-commando opnieuw uit om te bevestigen dat je 3.9 of hoger ziet.

macOS standaard Python

macOS heeft soms een oudere systeemversie van Python. Na installatie van een nieuwere versie gebruik je altijd python3 in plaats van python om de juiste versie aan te roepen.

ⓧ Command not found

Python is nog niet geinstalleerd op je systeem.

  • Ga naar python.org/downloads en download de nieuwste versie voor jouw besturingssysteem.
  • Voer de installer uit.
  • Op Windows: vink Add Python to PATH aan voordat je op Install Now klikt.
  • Op macOS: dubbelklik op het .pkg bestand en volg de installatie-stappen.
  • Sluit je terminal en open een nieuwe.
  • Voer het versie-commando opnieuw uit om te bevestigen dat Python werkt.

Nu gaan we een projectmap aanmaken en daarin werken.

  • Navigeer naar je Desktop door dit commando uit te voeren:

macOS

cd ~/Desktop

Windows

cd %USERPROFILE%\Desktop
  • Maak de projectmap aan en navigeer erin door deze commando's uit te voeren:
mkdir ai-sales-trainer
cd ai-sales-trainer

Je terminal zou nu in de ai-sales-trainer map moeten staan.

Een virtual environment isoleert de packages van dit project van de rest van je systeem.

  • Maak een virtual environment aan door dit commando uit te voeren:

macOS

python3 -m venv .venv

Windows

py -m venv .venv
  • Activeer de virtual environment:

macOS

source .venv/bin/activate

Windows

.venv\Scripts\activate

Je ziet nu (.venv) aan het begin van je terminal prompt. Dit bevestigt dat de virtual environment actief is.

  • Installeer de Anthropic SDK door dit commando uit te voeren:
pip install anthropic

Wat doet dit commando?

Dit installeert de officiële Anthropic Python SDK in je virtual environment. De SDK bevat alle functies die je nodig hebt om met de Claude API te communiceren.

  • Verifieer dat de installatie gelukt is door dit commando uit te voeren:

macOS

python3 -c "import anthropic; print(anthropic.__version__)"

Windows

py -c "import anthropic; print(anthropic.__version__)"

Je zou een versienummer moeten zien in de output. Dit bevestigt dat de SDK correct is geinstalleerd.

Zie je een foutmelding?

  • Controleer dat je virtual environment actief is. Je zou (.venv) moeten zien in je prompt.
  • Als pip niet gevonden wordt, probeer pip3 in plaats daarvan.
  • help me met het installeren van de Anthropic SDK
Stel je API key in

Om met de Claude API te communiceren heb je een API key nodig. Deze key identificeert jouw account bij elke request.

  • Ga naar console.anthropic.com en log in met je account.
  • Navigeer naar de API Keys pagina.
  • Klik op Create Key om een nieuwe API key aan te maken.
  • Geef de key een naam zoals sales-trainer en kopieer de gegenereerde key.

Bewaar je API key veilig

Je API key wordt maar een keer getoond. Kopieer hem nu en sla hem op een veilige plek op. Deel je key nooit publiek en commit hem nooit naar Git.

  • Stel de environment variable in zodat de SDK je key automatisch kan vinden:

macOS

export ANTHROPIC_API_KEY=your-api-key-here

Windows

set ANTHROPIC_API_KEY=your-api-key-here
  • Vervang your-api-key-here met de key die je zojuist hebt gekopieerd.

Waarom een environment variable?

De Anthropic SDK zoekt automatisch naar de environment variable ANTHROPIC_API_KEY. Door je key hier op te slaan hoef je hem niet in je code te zetten. Dat houdt je credentials veilig.

Laten we de verbinding testen om te bevestigen dat alles werkt.

  • Test de connectie door dit commando uit te voeren:

macOS

python3 -c "import anthropic; client = anthropic.Anthropic(); r = client.messages.create(model='claude-sonnet-4-6', max_tokens=50, messages=[{'role': 'user', 'content': 'Zeg hallo in een zin.'}]); print(r.content[0].text)"

Windows

py -c "import anthropic; client = anthropic.Anthropic(); r = client.messages.create(model='claude-sonnet-4-6', max_tokens=50, messages=[{'role': 'user', 'content': 'Zeg hallo in een zin.'}]); print(r.content[0].text)"

Je zou een kort antwoord van Claude moeten zien in je terminal. Dit bevestigt dat je API key werkt en dat je succesvol met de Claude API kunt communiceren.

Geen antwoord of een foutmelding?

  • Controleer dat je de ANTHROPIC_API_KEY environment variable correct hebt ingesteld in dezelfde terminal sessie.
  • Controleer dat je API key geldig is en niet per ongeluk extra spaties bevat.
  • Zorg dat je een actieve internetverbinding hebt.
  • help me met het verbinden met de Claude API
Maak de projectstructuur aan

Het project bestaat uit drie bestanden die elk een eigen verantwoordelijkheid hebben.

  • Maak de drie projectbestanden aan door deze commando's uit te voeren:

macOS

touch sales_trainer.py scenarios.py feedback.py

Windows

type nul > sales_trainer.py
type nul > scenarios.py
type nul > feedback.py

Wat doet elk bestand?

  • sales_trainer.py is het hoofdbestand met de conversation loop en de main functie.
  • scenarios.py bevat de klantpersona's en de system prompt builder.
  • feedback.py bevat het analyse-systeem dat je gesprek beoordeelt.
  • Bevestig dat de bestanden zijn aangemaakt door dit commando uit te voeren:
ls

Je zou feedback.py, sales_trainer.py en scenarios.py in de output moeten zien.

Bestanden niet zichtbaar?

  • Controleer dat je in de ai-sales-trainer map staat. Typ pwd (macOS) of cd (Windows) om je huidige locatie te zien.
  • Als de bestanden ontbreken, voer de aanmaak-commando's opnieuw uit.
  • help me met het aanmaken van projectbestanden

Je ontwikkelomgeving is helemaal klaar. In de volgende stap ga je de klantscenario's bouwen waarmee de AI realistische verkoopgesprekken kan simuleren.

Build the Customer Scenarios

Your development environment is ready and connected to the Claude API. Now it's time to build the foundation of your sales trainer: the customer scenarios.

A good sales trainer needs realistic customers to practice with. You'll create three distinct personas with increasing difficulty, each with their own personality, budget, objections, and communication style. These personas will later be fed to Claude as a system prompt, instructing the AI to stay in character throughout the conversation.

In this step, get ready to:
  • Define three customer personas with escalating difficulty levels.
  • Build helper functions for scenario selection and display.
  • Create a system prompt builder that transforms persona data into Claude instructions.
Define three customer personas in scenarios.py

Each persona represents a different type of customer a salesperson might encounter. The difficulty progression goes from a friendly buyer to a tough procurement professional.

  • Open scenarios.py in your editor and add the following SCENARIOS list:
SCENARIOS = [
    {
        "id": 1,
        "name": "De Geinteresseerde Starter",
        "difficulty": "Easy",
        "description": "Een ondernemer die actief zoekt naar een oplossing voor zijn groeiende bedrijf.",
        "persona": (
            "Je bent Jasper, 34 jaar, eigenaar van een klein marketingbureau met 8 medewerkers. "
            "Je bedrijf groeit snel en je zoekt actief naar een CRM-oplossing om je klantrelaties "
            "beter te beheren. Je hebt al wat online onderzoek gedaan maar nog geen beslissing genomen. "
            "Je budget is rond de 200 euro per maand. Je bent enthousiast maar wilt wel zeker weten "
            "dat het makkelijk te implementeren is, want je team heeft weinig technische ervaring."
        ),
        "context": (
            "Je hebt vorige week een formulier ingevuld op de website van het CRM-bedrijf. "
            "Je bent nu in gesprek met een verkoper. Je staat open voor het product maar hebt "
            "nog wat vragen over implementatie en gebruiksgemak."
        ),
        "difficulty_guidance": (
            "Wees vriendelijk en geinteresseerd. Stel vragen maar wees niet te moeilijk. "
            "Je bent bereid om te kopen als de verkoper je goed helpt. "
            "Je belangrijkste bezwaar is of je team het snel kan leren."
        ),
    },
    {
        "id": 2,
        "name": "De Sceptische Manager",
        "difficulty": "Medium",
        "description": "Een manager die al een oplossing heeft en overtuigd moet worden om te switchen.",
        "persona": (
            "Je bent Karen, 41 jaar, operations manager bij een middelgroot productiebedrijf met "
            "50 medewerkers. Je gebruikt al 3 jaar een concurrerend CRM-systeem. Het werkt redelijk "
            "maar je team klaagt over de interface en sommige features missen. Je baas heeft je "
            "gevraagd om alternatieven te bekijken, maar je hebt weinig zin in een migratie. "
            "Je budget is maximaal 500 euro per maand maar je wilt een duidelijke ROI zien."
        ),
        "context": (
            "Je bent benaderd door een verkoper na een vakbeurs. Je hebt ingestemd met een gesprek "
            "maar bent sceptisch. Je wilt harde feiten, geen verkooppraatjes. "
            "Je hebt 15 minuten voor dit gesprek."
        ),
        "difficulty_guidance": (
            "Wees beleefd maar sceptisch. Vergelijk constant met je huidige oplossing. "
            "Vraag naar concrete cijfers en case studies. Wees niet makkelijk te overtuigen. "
            "Je belangrijkste bezwaren zijn: migratiekosten, downtime, en of het echt beter is."
        ),
    },
    {
        "id": 3,
        "name": "De Moeilijke Inkoper",
        "difficulty": "Hard",
        "description": "Een ervaren inkoper die focust op prijs en zwaktes zoekt in je aanbod.",
        "persona": (
            "Je bent Marcel, 52 jaar, hoofd inkoop bij een groot retailbedrijf met 200+ medewerkers. "
            "Je hebt 20 jaar ervaring in inkoop en hebt al tientallen software-verkopers gesproken. "
            "Je weet precies welke trucjes verkopers gebruiken en je trapt er niet in. "
            "Je budget is ruim maar je wilt altijd de laagste prijs. Je gebruikt stiltes, "
            "stelt ongemakkelijke vragen, en test of de verkoper onder druk kan presteren."
        ),
        "context": (
            "Je hebt een RFP uitgestuurd en dit bedrijf is een van vijf kandidaten. "
            "Je hebt al gesprekken gehad met twee concurrenten die scherpe prijzen boden. "
            "Je wilt zien of deze verkoper waarde kan toevoegen boven de prijs."
        ),
        "difficulty_guidance": (
            "Wees kort en zakelijk. Onderbreek de verkoper als die te lang praat. "
            "Vraag direct naar prijs en kortingen. Noem lagere prijzen van concurrenten. "
            "Gebruik stiltes om druk te zetten. Test of de verkoper kan omgaan met bezwaren "
            "over prijs, implementatietijd, en referenties. Geef niet makkelijk informatie "
            "over je eigen situatie."
        ),
    },
]

What does this data structure do?

Each dictionary in the SCENARIOS list represents one customer persona with six fields.

  • persona contains the character's background, motivations, and budget. This becomes the core of the system prompt.
  • context describes how this sales conversation started. It grounds the AI in a realistic situation.
  • difficulty_guidance tells Claude how hard to make the conversation. Easy means friendly and open. Hard means short, price-focused, and confrontational.

You won't see a change yet. The next functions will use this data to build the selection menu and system prompts.

Create the scenario selection menu

The learner needs a way to browse the available scenarios and pick one. You'll build two helper functions: one to look up a scenario by ID, and one to display all options in a formatted menu.

  • Below the SCENARIOS list in scenarios.py, add the get_scenario function:
def get_scenario(scenario_id):
    """Haal een scenario op basis van ID."""
    for scenario in SCENARIOS:
        if scenario["id"] == scenario_id:
            return scenario
    return None

What does this function do?

get_scenario loops through the SCENARIOS list and returns the dictionary whose id matches the given number. If no match is found, it returns None. This is how the main program will retrieve the selected scenario later.

You won't see a change yet. The next function uses get_scenario to display the full menu.

  • Below get_scenario, add the display_scenarios function:
def display_scenarios():
    """Toon alle beschikbare scenario's."""
    print("\n" + "=" * 60)
    print("  BESCHIKBARE SCENARIO'S")
    print("=" * 60)
    for scenario in SCENARIOS:
        print(f"\n  [{scenario['id']}] {scenario['name']} ({scenario['difficulty']})")
        print(f"      {scenario['description']}")
    print("\n" + "=" * 60)

What does this function do?

display_scenarios prints a formatted menu showing all three scenarios with their ID number, name, difficulty level, and a short description. The user will see this menu before choosing which customer to practice with.

  • Save scenarios.py and test the menu by running:
py -c "from scenarios import display_scenarios; display_scenarios()"

You should see a formatted table with three scenarios listed: De Geinteresseerde Starter (Easy), De Sceptische Manager (Medium), and De Moeilijke Inkoper (Hard).

Seeing an ImportError or SyntaxError?

  • Make sure you saved scenarios.py before running the test command.
  • Check that your terminal is in the ai-sales-trainer folder where scenarios.py lives.
  • Look for missing commas between dictionaries in the SCENARIOS list. Each dictionary must end with }, (comma after the closing brace).

Help me debug my scenarios.py import error

Build the system prompt builder

The system prompt is what tells Claude how to behave during the conversation. In the Claude API, the system parameter is separate from the messages array. This makes it ideal for persistent character instructions that stay active throughout every turn of the conversation.

  • Below display_scenarios in scenarios.py, add the build_system_prompt function:
def build_system_prompt(scenario):
    """Bouw een system prompt voor het geselecteerde scenario."""
    return f"""Je speelt een klant in een sales training simulatie. Je doel is om een realistisch verkoopgesprek te simuleren.

## Jouw Karakter
{scenario['persona']}

## De Situatie
{scenario['context']}

## Jouw Gedrag
{scenario['difficulty_guidance']}

## Belangrijke Regels
- Blijf altijd in karakter als deze specifieke klant
- Reageer natuurlijk en realistisch (2-4 zinnen per antwoord)
- Stel vragen die een echte klant zou stellen
- Breek nooit karakter en vermeld niet dat je AI bent
- Reageer op wat de verkoper daadwerkelijk zegt, niet op wat ze zouden moeten zeggen
- Als de verkoper goed verkoopt, laat dan langzaam meer interesse zien
- Als de verkoper slecht verkoopt, word dan afstandelijker

## Moeilijkheidsgraad: {scenario['difficulty']}"""

What does this system prompt do?

The f-string pulls in the scenario's persona, context, and difficulty guidance to create a complete character brief for Claude. The "Belangrijke Regels" section ensures Claude stays in character, keeps responses short (2-4 sentences), and adapts its warmth based on how well the salesperson performs.

This is the key to realistic roleplay. Without explicit rules, Claude tends to be too helpful and break character. The difficulty instructions override that default behaviour.

  • Save scenarios.py and test the system prompt builder by running:
py -c "from scenarios import build_system_prompt, get_scenario; print(build_system_prompt(get_scenario(1))[:200])"

You should see the first 200 characters of a system prompt starting with "Je speelt een klant in een sales training simulatie" followed by the persona details for Jasper.

Getting None or a TypeError?

  • If you see TypeError: argument of type 'NoneType', it means get_scenario(1) returned None. Check that the first scenario dict has "id": 1 (an integer, not a string).
  • If you see an IndentationError, make sure the return statement in build_system_prompt is indented under the function definition.

Help me debug my build_system_prompt function

Why a separate system parameter instead of a user message?

The Claude API keeps the system parameter separate from the messages array on purpose. System instructions persist across every turn without cluttering the conversation history. The model treats them as a foundational context layer, which means the persona stays consistent even in long conversations.

✔️ Awesome, I've got everything!

Great. Double check you've saved scenarios.py and both test commands produced the expected output.

ⓧ I'd like to double check the full code

Here's the complete scenarios.py file at this point:

SCENARIOS = [
    {
        "id": 1,
        "name": "De Geinteresseerde Starter",
        "difficulty": "Easy",
        "description": "Een ondernemer die actief zoekt naar een oplossing voor zijn groeiende bedrijf.",
        "persona": (
            "Je bent Jasper, 34 jaar, eigenaar van een klein marketingbureau met 8 medewerkers. "
            "Je bedrijf groeit snel en je zoekt actief naar een CRM-oplossing om je klantrelaties "
            "beter te beheren. Je hebt al wat online onderzoek gedaan maar nog geen beslissing genomen. "
            "Je budget is rond de 200 euro per maand. Je bent enthousiast maar wilt wel zeker weten "
            "dat het makkelijk te implementeren is, want je team heeft weinig technische ervaring."
        ),
        "context": (
            "Je hebt vorige week een formulier ingevuld op de website van het CRM-bedrijf. "
            "Je bent nu in gesprek met een verkoper. Je staat open voor het product maar hebt "
            "nog wat vragen over implementatie en gebruiksgemak."
        ),
        "difficulty_guidance": (
            "Wees vriendelijk en geinteresseerd. Stel vragen maar wees niet te moeilijk. "
            "Je bent bereid om te kopen als de verkoper je goed helpt. "
            "Je belangrijkste bezwaar is of je team het snel kan leren."
        ),
    },
    {
        "id": 2,
        "name": "De Sceptische Manager",
        "difficulty": "Medium",
        "description": "Een manager die al een oplossing heeft en overtuigd moet worden om te switchen.",
        "persona": (
            "Je bent Karen, 41 jaar, operations manager bij een middelgroot productiebedrijf met "
            "50 medewerkers. Je gebruikt al 3 jaar een concurrerend CRM-systeem. Het werkt redelijk "
            "maar je team klaagt over de interface en sommige features missen. Je baas heeft je "
            "gevraagd om alternatieven te bekijken, maar je hebt weinig zin in een migratie. "
            "Je budget is maximaal 500 euro per maand maar je wilt een duidelijke ROI zien."
        ),
        "context": (
            "Je bent benaderd door een verkoper na een vakbeurs. Je hebt ingestemd met een gesprek "
            "maar bent sceptisch. Je wilt harde feiten, geen verkooppraatjes. "
            "Je hebt 15 minuten voor dit gesprek."
        ),
        "difficulty_guidance": (
            "Wees beleefd maar sceptisch. Vergelijk constant met je huidige oplossing. "
            "Vraag naar concrete cijfers en case studies. Wees niet makkelijk te overtuigen. "
            "Je belangrijkste bezwaren zijn: migratiekosten, downtime, en of het echt beter is."
        ),
    },
    {
        "id": 3,
        "name": "De Moeilijke Inkoper",
        "difficulty": "Hard",
        "description": "Een ervaren inkoper die focust op prijs en zwaktes zoekt in je aanbod.",
        "persona": (
            "Je bent Marcel, 52 jaar, hoofd inkoop bij een groot retailbedrijf met 200+ medewerkers. "
            "Je hebt 20 jaar ervaring in inkoop en hebt al tientallen software-verkopers gesproken. "
            "Je weet precies welke trucjes verkopers gebruiken en je trapt er niet in. "
            "Je budget is ruim maar je wilt altijd de laagste prijs. Je gebruikt stiltes, "
            "stelt ongemakkelijke vragen, en test of de verkoper onder druk kan presteren."
        ),
        "context": (
            "Je hebt een RFP uitgestuurd en dit bedrijf is een van vijf kandidaten. "
            "Je hebt al gesprekken gehad met twee concurrenten die scherpe prijzen boden. "
            "Je wilt zien of deze verkoper waarde kan toevoegen boven de prijs."
        ),
        "difficulty_guidance": (
            "Wees kort en zakelijk. Onderbreek de verkoper als die te lang praat. "
            "Vraag direct naar prijs en kortingen. Noem lagere prijzen van concurrenten. "
            "Gebruik stiltes om druk te zetten. Test of de verkoper kan omgaan met bezwaren "
            "over prijs, implementatietijd, en referenties. Geef niet makkelijk informatie "
            "over je eigen situatie."
        ),
    },
]


def get_scenario(scenario_id):
    """Haal een scenario op basis van ID."""
    for scenario in SCENARIOS:
        if scenario["id"] == scenario_id:
            return scenario
    return None


def display_scenarios():
    """Toon alle beschikbare scenario's."""
    print("\n" + "=" * 60)
    print("  BESCHIKBARE SCENARIO'S")
    print("=" * 60)
    for scenario in SCENARIOS:
        print(f"\n  [{scenario['id']}] {scenario['name']} ({scenario['difficulty']})")
        print(f"      {scenario['description']}")
    print("\n" + "=" * 60)


def build_system_prompt(scenario):
    """Bouw een system prompt voor het geselecteerde scenario."""
    return f"""Je speelt een klant in een sales training simulatie. Je doel is om een realistisch verkoopgesprek te simuleren.

## Jouw Karakter
{scenario['persona']}

## De Situatie
{scenario['context']}

## Jouw Gedrag
{scenario['difficulty_guidance']}

## Belangrijke Regels
- Blijf altijd in karakter als deze specifieke klant
- Reageer natuurlijk en realistisch (2-4 zinnen per antwoord)
- Stel vragen die een echte klant zou stellen
- Breek nooit karakter en vermeld niet dat je AI bent
- Reageer op wat de verkoper daadwerkelijk zegt, niet op wat ze zouden moeten zeggen
- Als de verkoper goed verkoopt, laat dan langzaam meer interesse zien
- Als de verkoper slecht verkoopt, word dan afstandelijker

## Moeilijkheidsgraad: {scenario['difficulty']}"""

Your scenarios are ready. Next up, you'll build the conversation loop that sends these system prompts to Claude and manages a multi-turn sales dialogue.

Build the Conversation Loop

In de vorige stap heb je drie klantscenario's ontworpen met unieke persona's en gedragsinstructies. Nu ga je het hart van de applicatie bouwen: de conversation loop die jou als verkoper laat praten met de AI-klant.

De Claude API is stateless. Dat betekent dat Claude geen vorige berichten onthoudt tenzij je ze expliciet meestuurt. Jouw conversation loop moet dus bij elke beurt de volledige gespreksgeschiedenis meeleveren aan de API.

In this step, get ready to:
  • De multi-turn chat implementeren in sales_trainer.py.
  • Gesprekscontrole toevoegen met een stop-commando en beurtenlimiet.
  • Het volledige gesprek testen met een AI-klant.
Implementeer de multi-turn chat in sales_trainer.py

De conversation loop bestaat uit meerdere lagen: imports, configuratie, scenarioselectie, en de daadwerkelijke chat-loop. Je begint met de basis: imports en constanten die het model en de limieten definiëren.

  • Open sales_trainer.py in je editor.
  • Voeg de imports en constanten toe door deze code te plakken:
import anthropic
from scenarios import get_scenario, display_scenarios, build_system_prompt
from feedback import format_conversation_for_feedback, get_feedback_prompt, display_feedback

# Model configuratie
MODEL = "claude-sonnet-4-6"
MAX_TOKENS = 1024
MAX_TURNS = 10

What does this code do?

De eerste import laadt de officiële Anthropic SDK. De tweede haalt je scenario-functies op uit het bestand dat je eerder schreef.

De drie constanten bepalen het gedrag van je trainer. MODEL definieert welk Claude-model je aanstuurt. MAX_TOKENS beperkt de lengte van elk AI-antwoord. MAX_TURNS voorkomt eindeloze gesprekken.

Why import from feedback already?

De import van feedback staat er alvast omdat je in substep 3 de feedbackfunctie aanroept vanuit sales_trainer.py. Het bestand is nu nog leeg, dus je voegt straks tijdelijke placeholders toe om te kunnen testen.

Nu bouw je de functie waarmee de gebruiker een scenario kiest.

  • Voeg de select_scenario() functie toe onder de constanten:
def select_scenario():
    """Laat de gebruiker een scenario kiezen."""
    display_scenarios()
    while True:
        choice = input("\nKies een scenario (1-3): ").strip()
        if choice in ["1", "2", "3"]:
            scenario = get_scenario(int(choice))
            print(f"\n--- Briefing ---")
            print(f"Je gaat in gesprek met: {scenario['name']}")
            print(f"Moeilijkheidsgraad: {scenario['difficulty']}")
            print(f"Context: {scenario['context']}")
            print(f"\nJij bent de verkoper van een CRM-oplossing.")
            print(f"Typ 'stop' om het gesprek te beeindigen.")
            print(f"--- Start gesprek ---\n")
            return scenario
        print("Ongeldige keuze. Kies 1, 2 of 3.")

What does this code do?

Deze functie roept display_scenarios() aan om de drie opties te tonen. Daarna wacht een while True loop tot de gebruiker een geldig nummer invoert.

Na de keuze krijgt de gebruiker een briefing met de naam van de klant, de moeilijkheidsgraad, en de context. Dit bereidt ze voor op het gesprek.

  • Sla sales_trainer.py op.

Foutmelding bij het opslaan?

Controleer of je geen tikfouten hebt in de functienamen display_scenarios en get_scenario. Deze moeten exact overeenkomen met de functies in scenarios.py.

Help me debug my sales_trainer.py imports

Voeg gesprekscontrole toe

Nu bouw je de kernfunctie: de conversation loop die berichten heen en weer stuurt tussen jou en de AI-klant. Deze functie bevat alle controles voor een realistisch gesprek.

  • Voeg de run_conversation() functie toe onder select_scenario():
def run_conversation(client, scenario):
    """Voer het verkoopgesprek met de AI-klant."""
    system_prompt = build_system_prompt(scenario)
    messages = []
    turn_count = 0

    while turn_count < MAX_TURNS:
        user_input = input("Jij (verkoper): ").strip()

        if user_input.lower() == "stop":
            print("\n[Gesprek beeindigd door verkoper]")
            break

        if not user_input:
            print("(Typ iets om het gesprek voort te zetten, of 'stop' om te stoppen)")
            continue

        messages.append({"role": "user", "content": user_input})

        response = client.messages.create(
            model=MODEL,
            max_tokens=MAX_TOKENS,
            system=system_prompt,
            messages=messages,
        )

        assistant_message = response.content[0].text
        messages.append({"role": "assistant", "content": assistant_message})

        print(f"\nKlant ({scenario['name']}): {assistant_message}\n")
        turn_count += 1

    if turn_count >= MAX_TURNS:
        print("\n[Maximaal aantal beurten bereikt]")

    return messages

What does this code do?

Dit is het hart van je applicatie. De functie werkt als volgt:

  • build_system_prompt(scenario) genereert de persona-instructies. De system parameter staat los van de messages array, zodat Claude de persona-instructies bij elke beurt meekrijgt zonder de history te vervuilen.
  • messages is een lege lijst die bij elke beurt groeit. Omdat de Claude API stateless is, stuur je de volledige lijst bij elke request mee.
  • Het stop commando laat de verkoper het gesprek beeindigen. Lege input wordt genegeerd met een hint.
  • client.messages.create() stuurt de volledige conversation history naar Claude en krijgt het antwoord van de AI-klant terug via response.content[0].text.
  • turn_count begrenst het gesprek tot 10 beurten. Een realistisch verkoopgesprek duurt niet eindeloos.

Why is the API stateless?

Claude onthoudt niets tussen API-calls. Elke keer dat je messages.create() aanroept, stuur je de hele gespreksgeschiedenis opnieuw mee. Dit geeft jou volledige controle over wat Claude "ziet" en "herinnert".

  • Sla sales_trainer.py op.

Twijfel over de structuur?

Controleer dat messages.append() twee keer wordt aangeroepen per beurt: eenmaal voor de user input, eenmaal voor het assistant antwoord. Zonder beide kanten verliest Claude de context.

Help me understand the conversation loop structure

Test het volledige gesprek

Om alles samen te brengen heb je nog twee functies nodig: get_ai_feedback() (die de feedback aanstuurt) en main() (die het hele programma start).

  • Voeg de get_ai_feedback() functie toe onder run_conversation():
def get_ai_feedback(client, messages, scenario):
    """Vraag feedback aan Claude over het gesprek."""
    conversation_text = format_conversation_for_feedback(messages, scenario)
    feedback_prompt = get_feedback_prompt(conversation_text)

    response = client.messages.create(
        model=MODEL,
        max_tokens=2048,
        messages=[{"role": "user", "content": feedback_prompt}],
    )

    feedback_text = response.content[0].text
    display_feedback(feedback_text)

What does this code do?

Deze functie formatteert het hele gesprek tot een leesbare tekst, bouwt een analyse-prompt, en stuurt die naar Claude. Let op dat hier max_tokens=2048 wordt gebruikt in plaats van 1024, omdat de feedback-analyse langer mag zijn dan een klantantwoord.

De drie helperfuncties (format_conversation_for_feedback, get_feedback_prompt, display_feedback) bouw je in de volgende stap in feedback.py.

  • Voeg de main() functie en het startblok toe onderaan het bestand:
def main():
    """Hoofdprogramma van de AI Sales Trainer."""
    client = anthropic.Anthropic()

    print("\n" + "=" * 60)
    print("  AI SALES TRAINER")
    print("  Oefen je verkoopgesprekken met AI-klanten")
    print("=" * 60)

    while True:
        scenario = select_scenario()
        messages = run_conversation(client, scenario)

        if messages:
            print("\nFeedback wordt gegenereerd...")
            get_ai_feedback(client, messages, scenario)

        again = input("\nNog een gesprek oefenen? (ja/nee): ").strip().lower()
        if again != "ja":
            print("\nBedankt voor het oefenen! Succes met je volgende verkoopgesprek.")
            break


if __name__ == "__main__":
    main()

What does this code do?

anthropic.Anthropic() maakt de client aan. De SDK leest automatisch je ANTHROPIC_API_KEY environment variable.

De while True loop laat de gebruiker meerdere gesprekken oefenen. Na elk gesprek wordt feedback gegenereerd (als er berichten zijn uitgewisseld) en kan de gebruiker kiezen om door te gaan of te stoppen.

Voordat je kunt testen moet je tijdelijke placeholders toevoegen aan feedback.py. De echte implementatie bouw je in de volgende stap.

  • Open feedback.py en voeg deze tijdelijke placeholders toe:
# Tijdelijke placeholders - worden vervangen in de volgende stap

def format_conversation_for_feedback(messages, scenario):
    return "Placeholder"

def get_feedback_prompt(conversation_text):
    return conversation_text

def display_feedback(feedback_text):
    print(feedback_text)

Why placeholders?

sales_trainer.py importeert drie functies uit feedback.py. Zonder deze placeholders krijg je een ImportError bij het opstarten. In de volgende stap vervang je deze met de echte feedback-logica.

  • Sla beide bestanden op.
  • Voer een testgesprek door het script te starten:
py sales_trainer.py
  • Kies scenario 1 (De Geinteresseerde Starter) om te beginnen met de makkelijkste klant.
  • Voer een paar beurten in als verkoper. Probeer het CRM-product te pitchen.
  • Typ stop om het gesprek te beeindigen.

Je ziet het scenariomenu, de briefing, en daarna reageert de AI-klant op je verkooppogingen. Na het typen van stop verschijnt de placeholder-feedback (nog niet de echte analyse).

Script start niet op?

  • Controleer dat je virtual environment actief is (je ziet (.venv) in je terminal).
  • Controleer dat je ANTHROPIC_API_KEY environment variable is ingesteld.
  • Als je een ImportError ziet, controleer dat alle drie de bestanden (sales_trainer.py, scenarios.py, feedback.py) in dezelfde map staan.

Help me fix my sales trainer script startup error

✔️ Awesome, I've got everything!

Mooi. Controleer dat je het bestand hebt opgeslagen en ga door naar de volgende stap.

ⓧ I'd like to double check the full code

Hier is de volledige sales_trainer.py tot nu toe:

import anthropic
from scenarios import get_scenario, display_scenarios, build_system_prompt
from feedback import format_conversation_for_feedback, get_feedback_prompt, display_feedback

MODEL = "claude-sonnet-4-6"
MAX_TOKENS = 1024
MAX_TURNS = 10


def select_scenario():
    """Laat de gebruiker een scenario kiezen."""
    display_scenarios()
    while True:
        choice = input("\nKies een scenario (1-3): ").strip()
        if choice in ["1", "2", "3"]:
            scenario = get_scenario(int(choice))
            print(f"\n--- Briefing ---")
            print(f"Je gaat in gesprek met: {scenario['name']}")
            print(f"Moeilijkheidsgraad: {scenario['difficulty']}")
            print(f"Context: {scenario['context']}")
            print(f"\nJij bent de verkoper van een CRM-oplossing.")
            print(f"Typ 'stop' om het gesprek te beeindigen.")
            print(f"--- Start gesprek ---\n")
            return scenario
        print("Ongeldige keuze. Kies 1, 2 of 3.")


def run_conversation(client, scenario):
    """Voer het verkoopgesprek met de AI-klant."""
    system_prompt = build_system_prompt(scenario)
    messages = []
    turn_count = 0

    while turn_count < MAX_TURNS:
        user_input = input("Jij (verkoper): ").strip()

        if user_input.lower() == "stop":
            print("\n[Gesprek beeindigd door verkoper]")
            break

        if not user_input:
            print("(Typ iets om het gesprek voort te zetten, of 'stop' om te stoppen)")
            continue

        messages.append({"role": "user", "content": user_input})

        response = client.messages.create(
            model=MODEL,
            max_tokens=MAX_TOKENS,
            system=system_prompt,
            messages=messages,
        )

        assistant_message = response.content[0].text
        messages.append({"role": "assistant", "content": assistant_message})

        print(f"\nKlant ({scenario['name']}): {assistant_message}\n")
        turn_count += 1

    if turn_count >= MAX_TURNS:
        print("\n[Maximaal aantal beurten bereikt]")

    return messages


def get_ai_feedback(client, messages, scenario):
    """Vraag feedback aan Claude over het gesprek."""
    conversation_text = format_conversation_for_feedback(messages, scenario)
    feedback_prompt = get_feedback_prompt(conversation_text)

    response = client.messages.create(
        model=MODEL,
        max_tokens=2048,
        messages=[{"role": "user", "content": feedback_prompt}],
    )

    feedback_text = response.content[0].text
    display_feedback(feedback_text)


def main():
    """Hoofdprogramma van de AI Sales Trainer."""
    client = anthropic.Anthropic()

    print("\n" + "=" * 60)
    print("  AI SALES TRAINER")
    print("  Oefen je verkoopgesprekken met AI-klanten")
    print("=" * 60)

    while True:
        scenario = select_scenario()
        messages = run_conversation(client, scenario)

        if messages:
            print("\nFeedback wordt gegenereerd...")
            get_ai_feedback(client, messages, scenario)

        again = input("\nNog een gesprek oefenen? (ja/nee): ").strip().lower()
        if again != "ja":
            print("\nBedankt voor het oefenen! Succes met je volgende verkoopgesprek.")
            break


if __name__ == "__main__":
    main()

Je conversation loop werkt. In de volgende stap bouw je het echte feedback-systeem dat je verkoopgesprek analyseert en concrete verbeterpunten geeft.

Build the Feedback System

Je hebt nu een werkende conversation loop waarmee je volledige verkoopgesprekken kunt voeren met AI-klanten. Maar oefenen zonder feedback is als sporten zonder spiegel.

In deze stap bouw je het feedback-systeem dat je gesprek analyseert en concrete verbeterpunten geeft. Je stuurt de volledige conversation history naar Claude met een analyse-prompt, en Claude beoordeelt je verkooptechniek als een ervaren sales coach.

In this step, get ready to:
  • Bouw een feedback prompt die Claude instrueert om je gesprek te analyseren.
  • Maak helper-functies die het gesprek formatteren en de feedback tonen.
  • Test de volledige applicatie-flow van begin tot eind.
Schrijf de feedback prompt template

De kracht van je feedback-systeem zit in de prompt. Je geeft Claude een gestructureerd format om het gesprek te analyseren op sterke punten, verbeterpunten, en concrete tips.

  • Open feedback.py in je editor. Dit bestand is nu nog leeg.
  • Voeg de feedback prompt template toe door de volgende code te kopieren:
FEEDBACK_PROMPT = """Je bent een ervaren sales coach. Analyseer het volgende verkoopgesprek en geef gedetailleerde feedback aan de verkoper.

## Het Gesprek
{conversation}

## Geef je analyse in het volgende format:

SCORE: [getal van 1-10]

STERKE PUNTEN:
- [punt 1]
- [punt 2]
- [punt 3]

VERBETERPUNTEN:
- [punt 1]
- [punt 2]
- [punt 3]

CONCRETE TIPS:
- [tip 1 met voorbeeld van wat ze hadden kunnen zeggen]
- [tip 2 met voorbeeld van wat ze hadden kunnen zeggen]
- [tip 3 met voorbeeld van wat ze hadden kunnen zeggen]

SAMENVATTING:
[2-3 zinnen over de algehele prestatie en het belangrijkste om aan te werken]"""

What does this code do?

FEEDBACK_PROMPT is een multi-line string met een gestructureerd format dat Claude als output moet volgen. De {conversation} placeholder wordt later ingevuld met de daadwerkelijke gesprekshistorie.

Door Claude een exact format te geven (score, sterke punten, verbeterpunten, tips, samenvatting) krijg je gestructureerde output die makkelijk te lezen is. Dit is een veelgebruikt prompt engineering patroon.

  • Sla feedback.py op.
Bouw de format-functie voor het gesprek

De conversation history in je applicatie is een lijst van dictionaries met role en content keys. Claude heeft context nodig over wie wat zei, dus je formatteert dit naar leesbare tekst.

  • Voeg de format_conversation_for_feedback functie toe onder de FEEDBACK_PROMPT template:

def format_conversation_for_feedback(messages, scenario):
    """Formatteer de conversation history voor de feedback-analyse."""
    formatted = f"Scenario: {scenario['name']} ({scenario['difficulty']})\n"
    formatted += f"Klant: {scenario['persona'][:100]}...\n\n"
    formatted += "--- Gesprek ---\n\n"

    for msg in messages:
        if msg["role"] == "user":
            formatted += f"Verkoper: {msg['content']}\n\n"
        elif msg["role"] == "assistant":
            formatted += f"Klant: {msg['content']}\n\n"

    return formatted

What does this code do?

Deze functie zet de ruwe messages-lijst om naar leesbare tekst voor Claude. Het voegt scenario-context toe (naam, moeilijkheidsgraad, de eerste 100 karakters van het persona) zodat Claude weet welk type klant het gesprek simuleerde.

De loop labelt elke beurt als "Verkoper" of "Klant" zodat Claude precies weet wie wat zei. Dit maakt gerichte feedback mogelijk.

  • Sla feedback.py op.
Voeg de prompt- en display-functies toe

Je hebt nog twee kleine helper-functies nodig. Een om de prompt samen te stellen, en een om de feedback netjes weer te geven in de terminal.

  • Voeg deze twee functies toe onderaan feedback.py:

def get_feedback_prompt(conversation_text):
    """Genereer de volledige feedback prompt."""
    return FEEDBACK_PROMPT.format(conversation=conversation_text)


def display_feedback(feedback_text):
    """Toon de feedback geformateerd in de terminal."""
    print("\n" + "=" * 60)
    print("  FEEDBACK VAN JE SALES COACH")
    print("=" * 60)
    print(f"\n{feedback_text}")
    print("\n" + "=" * 60)

What does this code do?

get_feedback_prompt() vult de {conversation} placeholder in de template met de geformatteerde gesprekshistorie. Dit levert de complete prompt op die naar Claude gestuurd wordt.

display_feedback() print de feedback met een duidelijke header zodat het visueel gescheiden is van het gesprek zelf.

  • Sla feedback.py op.

Seeing a syntax error?

Controleer dat de drie aanhalingstekens (""") van FEEDBACK_PROMPT correct geopend en gesloten zijn. Multi-line strings in Python moeten exact drie aanhalingstekens aan beide kanten hebben.

Help me debug a syntax error in my feedback.py file

✔️ Awesome, I've got everything!

Great. Double check that je feedback.py bestand is opgeslagen.

ⓧ I'd like to double check the full code

FEEDBACK_PROMPT = """Je bent een ervaren sales coach. Analyseer het volgende verkoopgesprek en geef gedetailleerde feedback aan de verkoper.

## Het Gesprek
{conversation}

## Geef je analyse in het volgende format:

SCORE: [getal van 1-10]

STERKE PUNTEN:
- [punt 1]
- [punt 2]
- [punt 3]

VERBETERPUNTEN:
- [punt 1]
- [punt 2]
- [punt 3]

CONCRETE TIPS:
- [tip 1 met voorbeeld van wat ze hadden kunnen zeggen]
- [tip 2 met voorbeeld van wat ze hadden kunnen zeggen]
- [tip 3 met voorbeeld van wat ze hadden kunnen zeggen]

SAMENVATTING:
[2-3 zinnen over de algehele prestatie en het belangrijkste om aan te werken]"""


def format_conversation_for_feedback(messages, scenario):
    """Formatteer de conversation history voor de feedback-analyse."""
    formatted = f"Scenario: {scenario['name']} ({scenario['difficulty']})\n"
    formatted += f"Klant: {scenario['persona'][:100]}...\n\n"
    formatted += "--- Gesprek ---\n\n"

    for msg in messages:
        if msg["role"] == "user":
            formatted += f"Verkoper: {msg['content']}\n\n"
        elif msg["role"] == "assistant":
            formatted += f"Klant: {msg['content']}\n\n"

    return formatted


def get_feedback_prompt(conversation_text):
    """Genereer de volledige feedback prompt."""
    return FEEDBACK_PROMPT.format(conversation=conversation_text)


def display_feedback(feedback_text):
    """Toon de feedback geformateerd in de terminal."""
    print("\n" + "=" * 60)
    print("  FEEDBACK VAN JE SALES COACH")
    print("=" * 60)
    print(f"\n{feedback_text}")
    print("\n" + "=" * 60)
Bekijk hoe de feedback geintegreerd is in de main loop

Je sales_trainer.py importeert en gebruikt deze functies al. De get_ai_feedback() functie stuurt de conversation history naar Claude voor analyse nadat het gesprek eindigt.

  • Open sales_trainer.py en bekijk de get_ai_feedback() functie. Deze roept de drie functies aan die je zojuist in feedback.py hebt geschreven.
  • Bekijk ook de main() functie. Na elk gesprek wordt automatisch feedback aangevraagd, en de gebruiker krijgt de optie om nog een gesprek te starten of te stoppen.

Why separate files?

Door de feedback-logica in een apart bestand te houden, blijft je code modulair. Als je later een ander type analyse wilt toevoegen (zoals de SPIN-scoring in de Secret Mission), hoef je alleen feedback.py aan te passen zonder sales_trainer.py te wijzigen.

Test de volledige flow

Nu alle drie de bestanden compleet zijn, kun je de volledige applicatie testen. De flow is: scenario selectie, briefing, gesprek, en dan automatische feedback.

  • Start de applicatie door dit commando uit te voeren in je terminal:
py sales_trainer.py
  • Kies scenario 1 (De Geinteresseerde Starter) voor je eerste test.
  • Voer 2-3 beurten in als verkoper. Probeer vragen te stellen over de situatie van de klant.
  • Typ stop om het gesprek te beeindigen.

Na het gesprek genereert Claude automatisch je feedback. Je ziet een score, sterke punten, verbeterpunten, en concrete tips in je terminal.

What should I see?

Na het typen van stop zie je "Feedback wordt gegenereerd..." gevolgd door een geformateerd feedbackblok met header "FEEDBACK VAN JE SALES COACH". De output bevat een score, sterke punten, verbeterpunten, concrete tips, en een samenvatting.

Getting an ImportError?

Als je een foutmelding ziet over het importeren van functies uit feedback, controleer dat de functienamen in feedback.py exact overeenkomen: format_conversation_for_feedback, get_feedback_prompt, en display_feedback.

Controleer ook dat alle drie de bestanden (sales_trainer.py, scenarios.py, feedback.py) in dezelfde map staan.

Help me fix an ImportError in my sales trainer project

Je AI Sales Trainer is nu volledig werkend. Je kunt scenario's selecteren, gesprekken voeren, en gedetailleerde feedback ontvangen. Klaar voor een extra uitdaging? In de Secret Mission voeg je een SPIN-scoring systeem toe dat je gesprekken beoordeelt op een bewezen verkoopframework.

Secret mission

Voeg een SPIN Scoring Systeem Toe

Je hebt nu een werkende sales trainer met basisfeedback. Maar hoe weet je of je de juiste vragen stelt? Het SPIN-framework (Situation, Problem, Implication, Need-Payoff) is een bewezen verkooptechniek die je gesprekken structureel verbetert. Voeg een SPIN-scoring systeem toe dat je gesprek beoordeelt op vier dimensies en concrete suggesties geeft.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally, so there are no ongoing costs unless you actively run the script again. Decide whether to keep your files for future practice or clean everything up.

Resources you used:

  • ai-sales-trainer project folder on your Desktop (includes all Python files and the .venv virtual environment).
  • ANTHROPIC_API_KEY environment variable (session-scoped, resets when your terminal closes).
  • Anthropic API key on console.anthropic.com.

Keep everything running

No action needed. Choose this if you want to keep practising sales conversations with different scenarios.

  • Your project files stay on your Desktop in the ai-sales-trainer folder.
  • Re-activate your virtual environment next time by running .venv\Scripts\activate (Windows) or source .venv/bin/activate (macOS/Linux) from inside the project folder.
  • You will need to set ANTHROPIC_API_KEY again in each new terminal session.

Pause - I'll come back to this later

Close your terminal to clear the environment variable from memory. Your project files remain on the Desktop for next time.

  • Close your terminal window. The ANTHROPIC_API_KEY variable is session-scoped and disappears automatically.
  • Your ai-sales-trainer folder and virtual environment stay intact on your Desktop.
  • When you return, open a new terminal, navigate to the project folder, re-activate the virtual environment, and set ANTHROPIC_API_KEY again.

Delete - I don't want to use this again

Remove all project files and revoke your API key so nothing remains from this project.

  • Deactivate your virtual environment by running:
deactivate
  • Delete the project folder. On macOS/Linux, run:
cd ~/Desktop
rm -rf ai-sales-trainer
  • On Windows, run:
cd ~/Desktop
rmdir /s /q ai-sales-trainer
  • Clear the environment variable from your current session. On macOS/Linux:
unset ANTHROPIC_API_KEY
  • On Windows:
set ANTHROPIC_API_KEY=
  • Revoke your API key. Log in to console.anthropic.com, navigate to the API Keys section, and delete the key you created for this project.

Nice Work!

Nice Work!

Nice work! You've just built a fully functional AI sales trainer powered by the Claude API. You can now practice sales conversations with realistic AI customers, get scored feedback, and sharpen your technique on demand.

You've learned how to:

  • Integrate the Anthropic Python SDK to build a multi-turn conversation loop with persistent conversation history.
  • Design persona-driven system prompts that keep an AI character consistent across difficulty levels.
  • Build an LLM-powered feedback system that analyzes conversations and delivers structured coaching with scores and improvement tips.
  • Secret Mission: Built a SPIN scoring system that evaluates sales conversations on Situation, Problem, Implication, and Need-Payoff dimensions with concrete suggestions.

Ready to quiz yourself?