rag-asic
Technicals

How rag-asic works

rag-asic answers questions over ASIC's regulatory guides and Chapter 7 of the Corporations Act by retrieving the actual text first, then asking a language model to write an answer grounded in — and citing — only what it was shown. Nothing here is trained into a model; every citation traces back to an extract you can inspect. Two things happen: documents get ingested into a retrievable index, and each question runs through retrieval to assemble the extracts the answer is built from.

Ingestion

Three sources in, one indexed chunk out.

The Corporations Act arrives as a DOCX compilation with real Word heading styles; regulatory guides and other ASIC PDFs don't, so their parsers key off the margin paragraph labels (e.g. "RG 175.30") and font-size-detected headings instead. All three converge on the same chunk record, which gets a breadcrumb — its full structural path — prepended before embedding. That's the single highest-leverage step in the pipeline: it disambiguates terse statutory text and gives the generator citation context for free. Each register then gets its own index table with its own keyword-search statistics — Act, RG, and misc chunks are never scored against each other.

Ingestion graph

Three sources in, one indexed chunk out.

source
Act · DOCX
source
RG · PDF
source
Misc · PDF
Act parser
Word styles → §
RG parser
labels + font
Misc parser
font headings
Chunk record
id · ref · text · as_at
Breadcrumb
highest leverage
Ch7 > s912A + text
Embed
nomic-embed-text
chunks_act
+ BM25
chunks_rg
+ BM25
chunks_misc
+ BM25
LanceDB · stats never mix across registers
Plain English · nomic-embed-text

Turns each chunk of text into a list of numbers — a fingerprint of its meaning. Chunks about the same idea end up with similar fingerprints even when they share no words in common. That's how a question like "what if my company can't pay its debts" can still find the section on insolvency.

Plain English · BM25

A classic keyword scorer: it counts how often your exact words show up, weighting rare, specific terms (like "s912A" or "AFSL") far more than common ones. It won't find a match unless the wording lines up — but that literalism is exactly what makes it reliable for citations and defined terms.

Retrieval

One question, resolved per register — then reranked, budgeted, and topped up.

A question is encoded once, then searched independently in each register — dense vector similarity and BM25 keyword search, fused by reciprocal rank fusion, within that register's own pool only. The Act pool's top candidates then go through a listwise LLM rerank — the single change that closed retrieval recall@8 from 0.93 to a perfect 1.00 on the eval set. Results are merged by a doc-aware seat budget, and a deterministic pass scans the seated guidance text for its own statute citations, pulling in the most-cited Act section that budget allocation missed — no extra model call. Only then does generation see any text.

Retrieval layer · query → answer

One question, resolved per register — then reranked, budgeted, and topped up.

input
User question
Query encode
dense vector + BM25 terms
Per-register search
Actdense+BM25→RRF
RGdense+BM25→RRF
Miscdense+BM25→RRF
pools never mix stats
LLM rerank
1.00 win
Act pool top-10 · listwise
Seat budget
doc-aware alloc + open-slot fill
Citation-graph seat
deterministic
pulls most-cited missing Act §
output
Generate
seated context → LLM
Only the Act pool is reranked (v6, →1.00). Registers stay independent until the seat budget merges them by doc-aware allocation.
Plain English · LLM rerank

Reads the top candidates side by side and re-orders them by which one actually answers the question — not just which is on-topic. Adjacent statute sections can be nearly identical to both keyword matching and semantic similarity; only reading them jointly, in context of the question, tells "about this topic" apart from "answers this."

Plain English · Seat budget

Merges each register's ranked list by fixed quotas rather than one shared score, since scores from different registers aren't comparable. Within a register it also hedges: instead of betting the whole allocation on the top-ranked document's guess, it spreads seats across other documents that are genuinely still in contention.

Plain English · Citation-graph seat

Guidance documents cite the statute sections they interpret. If the guidance that got seated repeatedly cites an Act section that didn't otherwise make the cut, that section is pulled in for free — no extra model call, just reading the citations already sitting in the text.

Evolution

The shape changed more than the number did.

Retrieval recall@8 climbed from 0.50 to a perfect 1.00 across seven versions — but the number alone hides what actually happened. Step through them: some jumps are new pipeline stages, one is a straight bug fix, and one is mostly the measuring stick getting harder, not the architecture getting better.

Pipeline morphology · recall@8

The shape changed more than the number did.

Experimental RAG demo over public regulatory material. Output is machine-generated general information, not legal or financial advice, and may be wrong or out of date. Source material © Commonwealth of Australia / ASIC.