Phase 5: Turn-Taking & Conversation Management · 50 min · Python · Cekura · Hamming.ai
The Concept
Conversation Flow Patterns
| Pattern | Structure | Use Case |
|---|
| Linear | Step 1 → Step 2 → Step 3 | Booking, registration |
| Branching | If X → Path A, else → Path B | Support, troubleshooting |
| Mixed-initiative | Agent leads, caller can redirect | General support |
| Open-ended | Caller drives, agent follows | Information lookup |
| Escalation | Agent tries → fails → human | Complex issues |
The Pacing Principle
One question at a time. One piece of information at a time.
# BAD: Overwhelming
"I can help you book a flight. What's your destination, date, preferred time, number of passengers, and seating preference?"
# GOOD: Paced
"I can help you book a flight. Where would you like to go?"
# Wait for answer
"Great, Tokyo. What date would you like to travel?"
# Wait for answer
"Got it, next Tuesday. Would you prefer morning or evening?"
A caller says "I need to change my flight." What's the right first response?
"I can help you change your flight. What's your reservation number?"
Slot Filling Strategy
When the agent needs multiple pieces of information, use slot filling — collect one slot at a time:
SLOTS = {
"destination": {"question": "Where would you like to go?", "required": True},
"date": {"question": "What date would you like to travel?", "required": True},
"time_preference": {"question": "Morning or evening?", "required": False, "default": "morning"},
"passengers": {"question": "How many passengers?", "required": False, "default": 1},
}
class SlotFiller:
def __init__(self, slots):
self.slots = slots
self.filled = {}
def get_next_question(self):
"""Get the next unfilled required slot."""
for slot_name, slot_config in self.slots.items():
if slot_name not in self.filled and slot_config["required"]:
return slot_config["question"]
return None # All required slots filled
def fill_slot(self, name, value):
"""Fill a slot with a value."""
self.filled[name] = value
def is_complete(self):
"""Check if all required slots are filled."""
return all(
name in self.filled for name, config in self.slots.items()
if config["required"]
)
Conversation States
class ConversationState:
GREETING = "greeting"
INTENT_DETECTION = "intent_detection"
SLOT_FILLING = "slot_filling"
CONFIRMATION = "confirmation"
EXECUTION = "execution"
CLOSING = "closing"
ESCALATION = "escalation"
State Machine Flow
Pacing Guidelines
| Guideline | Rule | Why |
|---|
| One question per turn | Never ask 2+ questions | Caller can't remember in voice |
| Acknowledge before asking | "Got it. What's next?" | Shows listening |
| Don't repeat the caller | Don't echo their words | Wastes time, feels robotic |
| Confirm before executing | "Book Tokyo on Tuesday, morning?" | Prevents errors |
| Offer help, don't demand | "Would you like me to..." | Feels like service, not interrogation |
| Keep responses <30 words | Short and natural | Voice is ephemeral |
Handling Topic Changes
Callers often change direction mid-conversation:
# Caller: "I want to book a flight to Tokyo"
# Agent: "What date?"
# Caller: "Actually, can I check my balance first?"
async def handle_topic_change(self, new_intent, current_state):
"""Handle caller changing the topic."""
# Save current state for potential return
self.saved_states.append(current_state)
# Acknowledge and pivot
return f"Of course, let me check your balance first. We can come back to the flight after."
# After balance check:
# "Your balance is $1,247. Would you like to continue booking your flight to Tokyo?"
Unlock the full lesson
You've read the first 2 sections. The rest of this lesson covers Build It, Use It, Ship It, Evaluation, Key Terms, Common Pitfalls, Interview Framing — plus a hands-on lab, quiz, and project artifact.
Create a free account to unlock Phase 0 and Phase 1 of every course — no credit card.