Concepts
Cited answers
POST /v1/answer retrieves the enforced hits, then asks a Workers AI LLM to answer strictly from that cited context — returning a grounded answer where every claim carries a citation that points at the exact sub-unit span, or an honest refusal when the evidence doesn't support one.
The retrieve → synthesize → cite loop#
A cited answer is not a bare LLM completion. SuperChargeDB runs a bounded pipeline over the enforced hybrid search results and refuses to speak past what the evidence supports:
- Retrieve — cheap, high-recall hybrid search across every requested plane (dense + BM25 fused by RRF), scope-clamped and ACL-filtered.
- Localize — narrow to the top hits and pin each candidate to its exact Locator (moment, bbox region, passage, or line).
- Synthesize — a Workers AI LLM answers strictly from the numbered context passages, with a hard instruction to refuse when the context does not contain the answer.
- Cite — the answer carries inline
[n]markers, each resolving to a citation with aunit_id,source_uri, and Locator; a groundedness score reports the share of sentences that are cited.
Model policy & fallback chain#
Grounded synthesis now runs a real LLM — it is no longer always extractive. Providers are tried in a strict order so a single unavailable model can never silently disable answers, and the engine never hallucinates: the worst case is a grounded extractive stitch of the top snippets, never an ungrounded completion.
| Order | Provider | Model | When |
|---|---|---|---|
1 | Cloudflare Workers AI | @cf/meta/llama-3.1-8b-instruct-fp8 | Primary. |
2 | Cloudflare Workers AI | @cf/meta/llama-3.3-70b-instruct-fp8-fast | CF fallback if the primary errors / returns empty. |
3 | OpenAI | gpt-4o-mini | Only when OPENAI_API_KEY is set and every CF model failed. |
4 | Extractive | — | Last resort: stitch the top snippets, each tagged with its citation. |
The OpenAI chat model is configurable via OPENAI_CHAT_MODEL. The winning provider is surfaced in the trace’s synth stage detail (e.g. cloudflare, openai:gpt-4o-mini (cf fallback), or extractive fallback), and the response answer.extractive flag is true only when both model paths were unavailable. Retrieval, RRF fusion, and reranking all use @cf/baai/bge-m3 (1024-d embeddings) and @cf/baai/bge-reranker-base — see Hybrid search.
Honest refusal
Endpoint#
/v1/answerGrounded answers are a Pro / Enterprise feature: a Free-tier principal receives 402 upgrade_required (required_tier: "pro"). See Pricing & billing.
Requires the read permission. The request body is an AegisQuery with answer: true — the same validated query object used by POST /v1/search, so planes, modalities, filters, rerank, and budget all apply. Scope is set via the X-Aegis-Scope header or ?scope=, never the body.
| Field | Type | Default | Notes |
|---|---|---|---|
q | string | — (required) | The natural-language question. |
answer | boolean | true | Must be true on this route; synthesis is always requested. |
planes | Plane[] | ["text"] | Planes to retrieve from — add visual/audio/doc_visual for multimodal evidence. |
modalities | Modality[] | unset | Restrict the evidence to specific modalities. |
budget | Budget | unset | Bounds rounds, MLLM calls, inference units, and latency (see Query). |
Request#
curl -s -X POST "https://superchargedb.krisch1218.workers.dev/v1/answer?scope=acme/alpha/backend" \
-H "Authorization: Bearer aegis_sk_alice" \
-H "Content-Type: application/json" \
-d '{
"q": "Where does the Q3 keynote demo the failover, and how fast was the cutover?",
"answer": true,
"planes": ["text", "audio", "doc_visual"],
"top_k": 8,
"rerank": true
}'The same call with the JavaScript / TypeScript fetch API:
const res = await fetch("https://superchargedb.krisch1218.workers.dev/v1/answer?scope=acme/alpha/backend", {
method: "POST",
headers: {
Authorization: "Bearer aegis_sk_alice",
"Content-Type": "application/json",
},
body: JSON.stringify({
q: "Where does the Q3 keynote demo the failover?",
answer: true,
planes: ["text", "audio", "doc_visual"],
top_k: 8,
}),
});
const { answer, hits, trace, context } = await res.json();
for (const c of answer.citations) {
console.log(`[${c.index}]`, c.source_uri, c.locator);
}
console.log("faithfulness", answer.nli_faithfulness);Response#
The response is a superset of the search response: the same hits, trace, and enforcement context, plus a populated answer object.
{
"answer": {
"text": "The live failover is demonstrated 12:47 into the keynote, where the primary region is drained and traffic re-homes with no dropped requests [1]. The runbook confirms a sub-second cutover [2].",
"citations": [
{
"index": 1,
"unit_id": "u-keynote-shot-19",
"source_uri": "acme/alpha/keynotes/keynote-q3.mp4#t=767",
"locator": { "kind": "time_range", "t_start_ms": 767000, "t_end_ms": 782000, "shot_idx": 19 }
},
{
"index": 2,
"unit_id": "u-runbook-p14",
"source_uri": "acme/alpha/backend/runbooks/failover.pdf#page=14",
"locator": { "kind": "bbox", "box": [72, 512, 540, 611], "page": 14 }
}
],
"nli_faithfulness": 1.0
},
"hits": [ /* SearchHit[] — same shape as POST /v1/search */ ],
"trace": {
"stages": [
{ "stage": "embed", "ms": 40, "neurons": 120 },
{ "stage": "vectorize", "ms": 58, "detail": "text+audio+doc_visual" },
{ "stage": "d1_fts", "ms": 8 },
{ "stage": "rrf", "ms": 1, "detail": "k=60" },
{ "stage": "rerank", "ms": 175, "neurons": 900 },
{ "stage": "synth", "ms": 640, "neurons": 1700, "detail": "@cf/meta/llama-3.1-8b-instruct-fp8; 2 citations" }
],
"total_ms": 1002,
"total_neurons": 2720,
"est_cost_usd": 0.0299,
"cache": "miss"
},
"context": { "effective_scopes": ["acme/alpha/backend"], "perms": ["read", "write", "admin"] }
}Citations resolve to Locators
Each entry in answer.citations carries the inline marker index, the source unit_id and source_uri, and an optional Locator. Because the Locator is the same discriminated union used everywhere else, an audio citation resolves to a timestamp window, a doc-visual citation to a page bbox, and a text citation to a character span — so a UI can deep-link to the exact spot.
The faithfulness score
nli_faithfulness is a 0.0–1.0 groundedness score: the fraction of the answer’s sentences that carry at least one citation marker. It is a cheap, deterministic proxy for full NLI entailment (a dedicated MLLM-judge verification stage is on the roadmap). A score below your threshold is a signal to fall back to raw hits or to widen retrieval rather than trust the prose.
| Field | Meaning |
|---|---|
answer.text | The synthesized answer with inline [n] citation markers. |
answer.citations[] | { index, unit_id, source_uri, locator? } — one per marker. |
answer.nli_faithfulness | 0–1 share of answer sentences that are cited. |
answer.extractive | true only when both LLM providers were unavailable and the answer is a grounded snippet stitch. |
Verify, don't assume
synth stage appears in the trace — with the winning provider/model in its detail — so you can see exactly what each answer cost in latency and inference units. Assert on invariants — every sentence has a citation, citations resolve to visible Units, faithfulness meets your bar — rather than on exact wording, which shifts as models evolve.Response shape
{ answer, hits, trace, context, hidden_by_acl } where answer matches the shared CitedAnswer schema ({ text, citations, nli_faithfulness, extractive }). The response is buffered JSON today; streaming (SSE/WS) is on the roadmap.