44 · Grounded answers from your sources¶
Some turns only ask for information -- how long does a refund take? -- and no tool answers them. With
on_unread: answer, such a question is answered from your own documents: the passages that match it are found
on your machine, the answer is made of what they say, and every sentence carries the passage it came from. A
sentence a passage does not support is removed, and where nothing is left the agent says it has no answer.
Language support
The selector understands turns written in English. Portuguese is its next grammar, and has not shipped yet; until it does, a turn written in Portuguese is not read as Portuguese.
Your documents, indexed on your machine¶
stalwart sources build reads your documents and writes an index, here, with the licensed runtime:
$ stalwart sources build docs/delivery.md docs/refunds.md --out sources.json
Indexed 2 document(s), 3 passage(s), into sources.json (ba9e751e249e).
$ echo $?
0
$ stalwart sources ask "How long does a refund take?" --index sources.json
A refund reaches the card the order was paid with in three to five working days. [refunds.md > How long a refund takes]
$ echo $?
0
- Markdown (
.md) and HTML (.html,.htm) are split at their headings and then at blank lines: each paragraph is a passage, under the heading above it. Plain text is split at blank lines. A PDF's text is read wherepypdfis installed. - Each passage is indexed by its words and its heading's words; a vocabulary file (
--vocabulary) adds the terms and kin your vocabulary declares, so a question in your customers' words finds a passage in yours. - Re-indexing is building again: the index is a file, with its digest printed, and the agent reads the file it is given.
- A file that cannot be read -- missing, empty, not UTF-8, a PDF with no
pypdf-- stops the build with its name and exit status 2.
stalwart sources ask answers a question from the index as the agent would with the extract composer, each
sentence with the document and heading it came from, so you see what your users will be told.
The documents and the index stay on your machine. Stalwart's servers never receive them.
Answering in the agent¶
An agent answers from the index when its on_unread is answer -- the third choice beside refuse and handing
the turn on (chapter 45) -- and answers: names the index:
desk = Agent("desk", tools=[get_order, charge_card], model="anthropic:claude-sonnet-5-5",
on_unread="answer", answers={"index": "sources.json", "composer": "extract"})
for text in ("How long does a refund take?",
"Can a gift card be refunded?",
"charge order 4411 40.00"):
reply = desk.chat(text, user="u-17")
shown = reply.waiting[0].wording if reply.waiting else reply.text
print(f"{text}\n -> {shown}")
How long does a refund take?
-> A refund reaches the card the order was paid with in three to five working days.
Can a gift card be refunded?
-> An order can be refunded within 30 days of delivery. A gift card cannot be refunded.
charge order 4411 40.00
-> Run charge_card?
The two questions were answered from the passages; charge order 4411 40.00 asks for something to be done, so it went to the charge and its confirmation, and never to the documents. An action is never answered with documentation: a passage describing how a refund works is not a refund. A question asked beside an action -- refund order 4411 and tell me how long it takes -- is answered after the action has run.
answers: takes index, k (at most this many passages, 3 by default), floor (no passage scoring below it,
0.3 by default, on a scale of 0 to 1) and composer. Those an agent does not give come from your console's
Settings page, at the conversation's first turn.
The composers¶
extract: the answer is the passages' own sentences that share a term with the question, in rank order. No model is called, and every sentence is supported by construction.compose: your agent's own model writes the answer from the numbered passages, with your key, marking each sentence with the passages it draws on. Each model call is counted as oneanswer_calls. An answer left with no sentence after the check gets one second attempt.
Which plans include each, generated from the plans' rows:
| Composer | Free | Paid | Enterprise |
|---|---|---|---|
extract |
✓ | ✓ | ✓ |
compose |
— | included, 20,000 answer_calls a month |
included, answer_calls with no limit |
Either way, the runtime checks every sentence against the passages it cites: each number, date, amount, name
and negation in it must be in one of them. A sentence that fails is removed. Retrieval and the check run in the
runtime, with no network call; compose calls your model, and nothing else.
Citations¶
Every sentence of an answer is bound to its passages: the document, the heading and, where the document gave
one, its link. stalwart sources ask prints them, as above, and stalwart serve's interface shows them under
the answer (chapter 35). A rule of chapter 43 can add a
sentence whenever a passage with a given tag is cited.
No grounded answer¶
When no passage scores above the floor, or no sentence survives the check, the outcome is
no_grounded_answer, and the agent goes on as if on_unread were refuse: the person is asked once to say it
again, and then told it cannot be done. Here the refunds document is deleted and the index built again:
$ rm docs/refunds.md
$ stalwart sources build docs/delivery.md --out sources.json
Indexed 1 document(s), 1 passage(s), into sources.json (1e1f014fea6f).
$ echo $?
0
$ stalwart sources ask "How long does a refund take?" --index sources.json
No grounded answer: no passage scores above the floor. The agent would refuse or hand the turn off.
$ echo $?
1
The command exits 1 for no grounded answer.
What is kept, and where¶
Nothing of it is kept by us. The documents, the index, the questions and the answers are on your machine and in
your storage. Only the count of answer_calls is reported, with your licence's other meters.
The limits¶
- A supported sentence agrees with its passage. It does not make the passage true, or current: a document that is out of date gives answers that are out of date.
- Retrieval matches words, weighed by how rare they are in your documents. A passage that shares enough of
a question's words to score above the floor is used, whether or not it is about the question; the floor and
kare how strict it is. - The check holds numbers, dates, amounts, names and negations to the passages. A sentence that rewords a passage and changes its meaning in other words can pass it.