Fix unasked pleasantries + callback re-asks (live call 2026-07-04 #3)
- PLEASANTRIES: the 8B parroted the verbatim example ("I'm doing well, thank
you for asking") when the caller never asked how she was, then burned two
more turns "starting fresh". Rule is now strictly conditional with no canned
example: answer+ask-back only if the caller literally asks; never answer a
question that wasn't asked.
- callstate: extraction now captures the CALLBACK request note ("are my
glasses ready" -> "status of an order"), so the checklist stops the "what's
the reason for your call?" re-ask; callback wrap-up wording now says STATE
the caller-ID number, never ask for one (she asked "what's the best phone
number" despite having it); first-name-only callbacks still ask the last name.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
9
bot.py
9
bot.py
@@ -170,10 +170,11 @@ SYSTEM_PROMPT = (
|
||||
"talk like a helpful human being: natural, relaxed, and genuinely conversational. Keep every "
|
||||
"reply to ONE short sentence — two at the very most, never a paragraph. Speak in English. Say "
|
||||
"numbers, dates, and times as words a person would say.\n\n"
|
||||
"PLEASANTRIES: mind normal phone courtesy. If the caller greets you or asks how you are, warmly "
|
||||
"answer and ask them back in the same breath before moving on — e.g. 'I'm doing well, thank you "
|
||||
"for asking — how are you?' — and never ignore a greeting or a 'how are you?'. Then continue to "
|
||||
"how you can help.\n\n"
|
||||
"PLEASANTRIES: mind normal phone courtesy, but ONLY respond to what the caller actually said. "
|
||||
"If — and only if — the caller literally asks how you are, answer warmly and ask them back in "
|
||||
"the same breath, then continue helping. If they just greet you or give their name WITHOUT "
|
||||
"asking how you are, do NOT say how you're doing and do NOT ask how they are — greet them back "
|
||||
"by name and go straight to their request. NEVER answer a question the caller did not ask.\n\n"
|
||||
"Your job is to answer questions and take appointment requests. Be warm but DIRECT and "
|
||||
"efficient: when the caller greets you, get to the point and lead the call by asking "
|
||||
"questions. Never re-ask for something they already told you, and keep each turn to one "
|
||||
|
||||
22
callstate.py
22
callstate.py
@@ -37,9 +37,11 @@ _STATE_INSTRUCTIONS = (
|
||||
' "call_type": "booking" (wants to schedule a visit), "callback" (wants something staff '
|
||||
"must check off-phone: order/frames/lens/prescription status, billing, account lookup, "
|
||||
'reach a person), "question" (just asking something), or "unknown"\n'
|
||||
' "reason": string or null — for booking, why they want to be seen (visit type or eye '
|
||||
"problem); for callback, a one-line note of what they need. 'an appointment' alone is NOT "
|
||||
"a reason — use null.\n"
|
||||
' "reason": string or null — WHAT the caller wants. For booking: the visit type or eye '
|
||||
'problem (e.g. "annual exam", "eye pain"). For callback: what they want checked or done, '
|
||||
'even if phrased as a question (e.g. "are my glasses ready", "status of an order", '
|
||||
'"billing question"). Only \'an appointment\' with no visit reason is NOT a reason — '
|
||||
"use null then.\n"
|
||||
' "location": string or null — the office/city the caller wants\n'
|
||||
' "patient_name": string or null — the caller\'s name as given (full or first-only)\n'
|
||||
' "name_is_full": boolean — true only if it clearly has first AND last name\n'
|
||||
@@ -112,17 +114,27 @@ def build_state_block(state) -> str:
|
||||
needed.append(label)
|
||||
|
||||
if ctype == "callback":
|
||||
reason = (state.get("reason") or "").strip() if isinstance(state.get("reason"), str) else ""
|
||||
lines = [
|
||||
"CALL STATE (auto-tracked from this conversation — trust it over your memory):",
|
||||
"- This is a NON-BOOKING call: the caller needs staff to handle something off the "
|
||||
"phone. Do NOT ask about insurance, office, or a preferred day/time.",
|
||||
]
|
||||
if reason:
|
||||
lines.append(f"- Their request (already known — NEVER ask what they're calling "
|
||||
f"about again): {reason}")
|
||||
got = [g for g in got if not g.startswith("reason for the visit")] # shown above
|
||||
if got:
|
||||
lines.append("- ALREADY COLLECTED — NEVER ask for these again: " + "; ".join(got))
|
||||
wrap = ("STATE the number on file back to them (it's in CALLER ID above) and invite a "
|
||||
"correction only — NEVER ask them for a phone number — then say staff will call "
|
||||
"them back, and close.")
|
||||
if state.get("patient_name") is None:
|
||||
lines.append("- Still needed: their name. Then confirm the callback number and close.")
|
||||
lines.append(f"- Still needed: their name. Then {wrap}")
|
||||
elif not state.get("name_is_full"):
|
||||
lines.append(f"- Still needed: their LAST name (you have the first). Then {wrap}")
|
||||
else:
|
||||
lines.append("- You have what you need: confirm the callback number and close.")
|
||||
lines.append(f"- You have what you need: {wrap}")
|
||||
return "\n".join(lines)
|
||||
|
||||
if ctype == "booking" and (got or needed):
|
||||
|
||||
Reference in New Issue
Block a user