Cheat sheets

Chatbots and Dialogue State Tracking

Route turns, run the agent loop, track slots across turns and budget the context window. Python from the lessons.

  • Concepts and terms
  • Tasks and commands
  • Annotated code
  • Diagrams
  • Defaults and numbers
  • Troubleshooting
  • Questions and tips

Source

Hybrid routing#

destructiveelsematchNonetool_callclientUser inputprocessDestructivecheckdanger wordsprocessStructuredflowconfirm firststoreFAQ retrievalthreshold 0.6modelLLM agent loopRAG and toolcallsprocessToolscallablefunctionsclientReplydestructiveelsematchNonetool_callclientUser inputprocessDestructive checkdanger wordsprocessStructured flowconfirm firststoreFAQ retrievalthreshold 0.6modelLLM agent loopRAG and tool callsprocessToolscallable functionsclientReply

The agent loop#

1Starthistory holds one user message. The loop runsmax_steps times at most.2LLMllm(history, tools=tools) returns content or atool_call.3Checkunknown tool name or non-dict arguments add anerror message. The loop continues.4Toolfn(**args) runs. The call and its result go intohistory.5Stopa reply without a tool_call is the final answer.6Budgetafter max_steps, return "I could not completethe task in the step budget."

Tasks in code#

TaskCode
FAQ answer or Nonefaq_respond(user_input, threshold=0.5)
Detect a destructive requestis_destructive_action(text)
Agent with a step budgetagent_loop(user_message, tools, llm, max_steps=5)
Score a trackerjoint_goal_accuracy(predicted_states, gold_states)
Budget the windowContextBudget(max_tokens=128000, generation_reserve=4000)
Add a component with a capbudget.allocate("tools", tool_text, max_tokens=2000)
Prune tools by intentselect_tools(query, token_budget=2000)
Best docs at start and endreorder_lost_in_middle(items, scores)

Rule-based state update#

SLOT_EXTRACTORS = {"cuisine": extract_cuisine, "area": extract_area,
"price": extract_price, "people": extract_people}
def update_state(state, utterance):
new_state = dict(state)never reset untouched slots
for slot, extractor in SLOT_EXTRACTORS.items():
value = extractor(utterance)
if value is not None:
new_state[slot] = valuea correction overwrites
continue
if is_negation(utterance, slot):
new_state[slot] = None"never mind the cuisine"
return new_state

LLM tracker with a schema#

class RestaurantState(BaseModel):
cuisine: Optional[Literal["italian", "chinese", "indian", "thai", "any"]] = None
area: Optional[Literal["north", "south", "east", "west", "center"]] = None
price: Optional[Literal["cheap", "moderate", "expensive"]] = None
people: Optional[int] = None
day: Optional[str] = Nonefree-form slot
def llm_dst(history, llm):
prompt = f"""...{render(history)}...Output only the JSON state."""
return llm(prompt, response_model=RestaurantState)whole state each turn

Assemble context per query#

1System promptgoes first. Cap max_tokens=1000.2Toolsclassify_intent then select_tools. Cap 2000.3Retrievalscore_relevance drops docs below the threshold.Cap 3000.4Reorderreorder_lost_in_middle puts the best docs at thestart and the end.5Historysummaries plus recent turns. Cap 5000.6Querygoes last. Cap 500. The rest is the generationreserve.

Paradigms and DST terms#

Rule-based
patterns, intents and slot filling. Fails outside its scope.
Retrieval-based
nearest stored response. No generation, so no hallucination.
Neural seq2seq
fluent, but generic replies and factual drift.
LLM agent
plan, call tool, observe result, decide next step.
Slot
a named parameter the backend needs, such as cuisine or date.
Classification DST
yes or no for each slot and candidate value. Closed vocabulary.
Generation DST
generate slot values as text. Open vocabulary. The modern default.
JGA
fraction of turns where every slot is correct. All or nothing.

Defaults and numbers#

SettingDefaultNote
max_tokens128000Window size of ContextBudget
generation_reserve4000Reserve 2,000-4,000 for the answer
max_history_tokens5000Above it, summarize the 2 oldest turns
token_budget2000Tool definitions for one query
Relevance threshold0.05The lesson text uses 0.1
Token estimate1.3Tokens for each whitespace word
max_steps5Agent step budget
FAQ threshold0.5Hybrid route uses 0.6

Troubleshooting#

SymptomCauseFix
Agent claims an action it did not doConfident fabricationTrust only a successful tool return
Input overrides the system promptPrompt injectionUntrusted input, PVE, confirm destructive
Same tool called again and againInfinite loopStep budget, dedupe tool calls
Earliest turns lostContext window fullSummarize or retrieve old turns
Fact in the middle ignoredLost in the middleKey facts first or last
Correction clears other slotsReset of untouched slotsOverwrite only the corrected slot
"Italian" and "italian" differCaseNormalize everywhere
Old training data breaksNew slots added laterVersion the schema

Abbreviations#

DST
Dialogue State Tracking. Keeps the slot-value dict across turns.
JGA
Joint Goal Accuracy. MultiWOZ 2.4 top systems reach 80-83%.
MultiWOZ
Multi-domain WOZ dataset. The standard DST benchmark.
LDST
LLaMA plus LoRA, instruction-tuned with domain-slot prompts.
TripPy
copy-based DST with BERT encoding. Pre-LLM standard.
PVE
Plan-Verify-Execute. Check each action against the plan first.
RAG
retrieve relevant docs, then ground the reply in them.
Lost-in-the-middle
85-90% accuracy at the ends, 60-70% in the middle.

Questions#

Why route instead of one model?
No single architecture handles every request well.
Why rules for payments?
Destructive actions need deterministic, confirmed flows.
Incremental update or regenerate?
Regenerate the whole state from history. It handles corrections.
What does regeneration cost?
O(n^2) total tokens. Cap or summarize old turns.
Is a bigger window enough?
No. A curated 10K context often beats a dumped 100K.

Tips#

  • Below the FAQ threshold, return None and escalate.
  • Log every agent step. Measure off-task rate.
  • Mix free-form slots (names, times) with closed slots (cuisine, area).
  • Always pass the full history so earlier slots stay set.
  • Tool pruning cuts tool tokens by 60-80%.
  • Two or three good few-shot examples often beat long instructions.