Skip to main content
Kestrel is an inbound claims line for a motor insurer. Sam answers, finds the caller’s policy, takes the report of what happened one question at a time, reads the whole claim back and files it on the caller’s yes. The code is in examples/kestrel.

The group

One group, claim, runs two steps. The group’s arguments carry what the caller said before the group started, so a caller who gives everything at once hears the read-back at once.
kestrel/agent.py
find_policy opens with lookup_policy on those two values. The lookup has a confirm line, so code asks before it runs:
kestrel/agent.py

Code asks every question

take_report holds two tools. The model calls note_facts with whatever the caller just said, as typed arguments. Code saves the facts, picks the next missing one, and says its question.
kestrel/agent.py
  1. The step opens on note_facts with nothing noted. Its result’s next_question is the first question. No model request.
  2. The caller answers. The model calls note_facts(incident_day=..., place=...) with only what they said. A caller who tells it all in one breath fills several facts in one call.
  3. When the report is complete, the model calls file_claim. Code says the whole claim, from read_back in the State, and files it only on the caller’s yes.
The questions come in a fixed order: when, where, what happened, anyone hurt, police, another driver, which car, can it be driven. A car is picked only from the cars on the policy.

Why it works this way

The model only fills typed fields. incident_day is a date. injuries is a bool. incident_time is a time or one of four parts of the day. Code decides, and code says it. A day in the future is the tool’s rule, not the argument’s. note_facts keeps it out of the report and returns status: "future_day". A reply on the tool turns that into “That day hasn’t happened yet. On which day did it happen?” The model makes one request for the turn, the call, and says nothing. Every read-back is code’s. The caller hears the same claim read-back on every call. The model never paraphrases the report it is about to file. Nothing the caller did not hear is filed. file_claim locks the report, the policy number and the call’s id, and takes nothing from the model. A yes runs it only while its locked values are the ones read back. A correction after the read-back changes the report, so code reads the claim back again. Each answer is saved as it comes. note_facts merges the new facts into the report and returns it. Its assign rows on the registry save the report and the read-back as soon as it returns, inside the step:
kestrel/agent.py
The model reads complete and next_question only. The report and the read-back are hidden: a model that sees the read-back says it in its own words, before code reads it back. Codes and birthdays are typed for speech. The policy and claim numbers are Spelled, so code says them a character at a time: “K C, 1 0 0, 2 3 1”. The date of birth is a BirthDate, said with its year: “5 June 1979”.

What a call costs

A whole 13 turn claim costs 15 model requests, on both frameworks.

The parts

Best practice.
  1. When a step asks many questions, keep the order in code and give the model one tool that takes them all as optional typed fields.
  2. Say codes letter by letter in code, like “K P, four eight two, nine one three”. A model reading “KP482913” may say it as a word.
  3. Save a long read-back to the State and use it as the confirm line, {{read_back}}.

Try it

The demo desk has two policies. KP482913 is Daniel, born 5 June 1979, with a blue Toyota Corolla. KP731508 is Priya, born 23 January 1992, with two cars.
  1. “It’s KP482913, and I was born on the fifth of June 1979.” Code reads both back.
  2. “Yes.” Code says “Thank you, Daniel” and asks when it happened.
  3. Answer each question. Try “Yesterday afternoon on the high street, someone reversed into me.”
  4. After the read-back, say “Actually it was the morning.” Code reads the changed claim back.

Troubleshooting

The step asks the first question twice

The prompt also tells the model to ask. Fix: tell the model the application asks the next question itself, in the step prompt and in the tool’s docstring.

Where to go next

Wasla: an outbound reminder

Verify a person before saying anything about their account.

Groups

Group fields, arguments and what follows a group.