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:
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