Sending 'Rewrite This Transcript, NOT a Summary' to the Right Engine

Why an LLM classifier alone misroutes 'rewrite this, NOT a summary', and how deterministic regex guards backstop it.

Here is a request a lawyer actually typed into our product, with a document pinned. "Rewrite the entire transcript in third person, this is not a summary but a complete recitation." Four times in a row, the tool handed back a summary.

That is not a small miss. The user asked for one thing, said in plain words which thing they did not want, and got the thing they did not want anyway. It is the kind of failure that makes a careful buyer decide the tool cannot be trusted with real work, and they are right to.

This post is about the piece of our system that decides what you want to do with a document you have pinned, and how we stop it from hijacking a targeted instruction into the wrong mode. It is a story about reliability through determinism, which is a genuine advantage when the alternative is trusting a language model to get the same question right every time. There are two small code snippets, simplified for readability, because the interesting part is a decision you can see rather than an adjective you have to trust.

The problem: one pinned document, many possible intents

When you pin a document and type a message, there is a hidden fork in the road before anything is answered.

"What is the indemnity cap?" is a targeted question. The right move is to retrieve the handful of passages nearest that question and answer from them. That is ordinary retrieval, and it is fast and cheap.

"Summarize this whole lease" is not that. A summary needs every part of the document processed systematically, not the five or ten chunks nearest a query. If you force a whole-document task through the targeted-retrieval path, it silently answers from a fraction of the document, and the reader never learns that most of the file was never read. This was our single most common document complaint: a majority of document sessions that went wrong went wrong because the answer only saw part of the file.

So there are really two families of intent behind a pinned document. Targeted questions, answered inline from the relevant passages. And whole-document operations, which we route to purpose-built engines: a map-reduce summarizer, a chronology builder, a spreadsheet-style extraction matrix, a section-by-section review pipeline, a version diff. Between those families sits a router, and the router is where an instruction gets honored or betrayed.

Why a language model alone is the wrong foundation for this

The obvious way to build this router is to describe the eleven possible tasks to a language model and ask it to pick one. We do use a model here, and it is good at the hard, ambiguous cases. But making the model the sole authority has two failure modes that matter enormously for legal work.

The first is instability. Ask the same plainly targeted question twice ("quote the survival clause") and a model will sometimes answer it inline and sometimes decide you wanted a structured extraction. Same words, same document, different route, run to run. A coin flip is a terrible foundation for a tool whose whole promise is that it does the thing you asked.

The second is that some misroutes are destructive, not just wrong. Two of the whole-document routes build an asynchronous matrix job, a column per question and a row per document. When a model misfires into that route on a conversational "just give me the numbers," the user does not get a wrong answer, they get an empty five-cell spreadsheet spun up in the background. We have watched a model return exactly that misroute, with high confidence, on a question that carried no hint of wanting a matrix. Confidence, it turns out, is not the same as being right.

The design: a deterministic floor the model cannot fall through

Our router is layered on purpose.

At the bottom is a pure, deterministic classifier: regular expressions and keywords, no model call. It is cheap, it runs in milliseconds, it is unit-testable, and critically it returns the same answer every single time. It is deliberately biased toward "targeted," so a miss just keeps the safe existing behavior, whereas a false alarm would drag a real question into an expensive whole-document engine. It only fires on unambiguous whole-document phrasing.

Above that sits the language model, which acts as the authority on the genuinely ambiguous middle, with the deterministic classifier as a strong hint and as the fallback whenever the model is unavailable or unsure. The model only runs when a document is actually pinned, so this extra step touches a small subset of messages, not every chat.

And then, above even the model, sit a few deterministic guards that the model is not allowed to overrule. This is the part that makes the "rewrite, not a summary" bug impossible rather than merely unlikely.

The whole cascade, from the raw prompt to the engine that runs, looks like this.

Loading diagram...

Two details in that picture carry most of the weight. The order of the guard matters: the rewrite and negation check runs before the model is ever called, so a keyword sitting in the sentence can never be claimed by a whole-document route first. And the two confidence floors are not the same number: an ordinary inline whole-document route clears a moderate bar, while a matrix route, the one that spawns a background job, has to clear a distinctly higher one. The resolver also decodes deterministically and caches its answer per prompt and per document count, so the same message routes the same way every time within a process rather than drifting run to run.

The guards that override the model

The transcript incident taught us something specific. A certain family of requests is content generation over a document, not a whole-document operation. Rewrite it in third person. Reformat it as a numbered list. Recite it word for word. Fill in the blank fields. Redact the names. Continue drafting from where it stops.

These all operate on the whole document, which is exactly why a model keeps mislabeling them as "summarize." But the user does not want the document condensed. They want its content reproduced in a new form, and that has to be answered inline, obeying the instruction literally.

So we wrote a deterministic guard that recognizes this family by its verbs and phrasing, plus explicit negations like "not a summary" and "do not summarize." It runs before any whole-document route can claim a keyword sitting in the sentence, and short-circuits straight to the targeted path.

Simplified, the top of the router looks like this:

# Simplified from classify_document_task() and resolve_document_task().
def route(query, document_count):
    # Deterministic guard the model is not allowed to beat: a rewrite / reformat /
    # recite request, or an explicit negation ("don't review", "not a summary"),
    # is content generation -> answer inline.
    if is_rewrite_or_transform(query) or is_negated_task(query):
        return TARGETED

    regex_task = regex_classify(query)          # deterministic prior + fallback
    llm_task, confidence = ask_the_model(query, document_count)
    ...

In plain English: before we consult the model at all, if the request is a rewrite, a reformat, a verbatim recitation, or carries an explicit "do not summarize / not a review" negation, we route it to the inline answer and stop. The model never gets the chance to turn "rewrite this, not a summary" into a summary, because the decision was already made by a rule that cannot waver.

A second guard covers the negation of any task directly. "Don't review the whole brief, only answer about the payment term" used to grab the word "review" and route to a full-document review, ignoring the "don't." Now an explicit negation of a task, review, compare, redline, diff, extract, is recognized and honored, and the underlying targeted question is answered instead.

The general principle is the one worth taking to any tool you evaluate. A confirmed misroute should not be fixed by nudging a prompt and hoping. It should be converted into a deterministic rule so the same input can never regress, no matter how the model's mood shifts between releases.

The extra bar for the destructive routes

Because a matrix job is destructive when it misfires, the two matrix routes have to clear a higher bar than an ordinary inline whole-document route.

Three things have to agree before we will spawn one. At least two documents must actually be pinned, since a single-document request can never be a per-document tabulation across many. The model has to clear a higher confidence floor than a plain route needs. And a deterministic signal has to corroborate the intent: either the regex classifier already saw an extraction, or the text carries an explicit "same fields across multiple documents" cue, which requires an actual document noun so "each clause in this agreement" (one document) does not match while "the cap from each of these contracts" does.

If the model wants a matrix but nothing deterministic agrees, we refuse the destructive route and answer inline instead.

# Simplified: a matrix (async spreadsheet) route needs the model AND the world to agree.
if llm_task in MATRIX_TASKS:
    corroborated = document_count >= 2 and matrix_cue_present(query, regex_task)
    if not (corroborated and confidence >= MATRIX_FLOOR):
        return TARGETED        # refuse the destructive route, answer inline

In plain English: the single most damaging misroute, a conversational question turned into an empty background spreadsheet, requires the model to be confident and the document count and the wording to independently back it up. Any one of those missing, and we quietly do the safe thing.

This whole subsystem only engages when a document is pinned in the first place, so nothing here touches an ordinary chat with no attachment.

How we prove it, for free

A router is only as trustworthy as the evidence that it behaves, and the useful thing about a deterministic core is that you can test it exhaustively without spending a cent.

We fan roughly twenty-five labeled prompt categories into more than a thousand concrete prompts by combining templates ("Rewrite this {doc} in third person") with a long list of legal document types (transcript, lease, NDA, deposition, motion, and so on). Every prompt runs through the pure regex classifier in milliseconds, with no model calls, so the whole sweep is free and deterministic and can run on every change.

The headline metric is not overall accuracy. It is the count of severe false-whole-document misroutes: a targeted-intent prompt that got hijacked into summarize, extract, matrix, or review. That is the rewrite-bug family, the class of failure that enrages users, and we hold it to the floor. A whole-document request that falls back to a plain answer is tracked too, but it is minor, because the worst case there is a slightly less complete answer rather than an ignored instruction.

There is a second, tiny probe that costs a few model calls. It takes a curated set of content-generation prompts, translate this, draft a reply, fill in the fields, redact the names, continue writing, and runs them through the full model-backed resolver to catch any case where the model tries to override the deterministic prior. Every confirmed override there becomes a new deterministic guard, which means it is fixed for free from that point on and can never quietly come back.

That is the loop that matters. A misroute is not a bug we patch once and forget. It is a permanent, deterministic guard plus a free regression test, so the same betrayal cannot happen twice.

What this does and does not promise

Being honest about a router means naming its limits.

It does not read your mind on a genuinely ambiguous sentence. "Go through this" could be a review or a summary, and there the model's judgment is doing the work, backed by the safe default of answering inline when confidence is low.

It leans conservative by design. When it is unsure, it keeps you in an ordinary answer rather than launching an expensive engine, which occasionally means a whole-document request gets a normal answer and you rephrase. We would rather under-route to the safe path than over-route into a matrix you did not ask for.

And the deterministic guards are only as complete as the misroutes we have seen. A brand-new phrasing that no pattern yet covers can still slip through to the model, which is exactly why the free stress sweep runs against a thousand-plus variants and why every confirmed miss becomes a new rule.

Test any tool yourself: prompts that expose a bad router

You do not need our code to find out whether a tool honors your instruction or overrides it. You need a pinned document and a few pointed prompts. Run these in any legal-AI product, including ours, and watch what it does, not what its label says.

  1. The rewrite-not-summary test. Pin a transcript or a long document and ask: "Rewrite the entire thing in third person. This is a complete recitation, not a summary. Do not shorten it." A strong tool reproduces the full content in the new form. The tell of a weak one: a tidy summary, or an answer that is visibly half the length of the original.

  2. The negation test. Pin a multi-clause contract and ask: "Do not review the whole document. Only tell me who is responsible for the notice period." A strong tool answers the one narrow question. The tell: a full clause-by-clause review you never requested, because the tool grabbed the word "review" and ignored the "do not."

  3. The format-is-not-a-task test. Ask a perfectly ordinary question and add "put it in a table," for example "What is the termination right? Give it to me as a table." A strong tool answers normally and formats the answer as a table. The tell: it treats "table" as a command to build a spreadsheet-style extraction and stalls, or spins up an empty grid.

  4. The single-document extraction trap. With exactly one document pinned, ask "pull every defined term into a matrix." A strong tool recognizes that a per-document matrix across one document is just a normal list and answers inline. The tell: it launches a background job that never really had a second row to fill.

  5. The repeat-it test. Ask the same targeted question twice, in two separate messages: "Quote the survival clause." A strong tool answers it the same way both times. The tell: once you get the quote, and once you get a summary or a table, which means routing in that tool is a coin flip and you just watched it land on both sides.

If a tool passes these, its router is doing real work. If it fails, you have learned something no feature list will tell you: that the tool will sometimes do a different job than the one you asked for, and you will not always catch it in time.

New legal AI guides, weekly.

Priyansh Khodiyar

Priyansh Khodiyar

Co-Founder & CTO

Priyansh leads engineering and AI at Vaquill, from the matter workbench to drafting, document comparison, document matrix, and citation-verified research.

Research, review, and draft, with a source on every answer.

Vaquill AI reads your documents and knows the law. Every answer shows where it came from. 7-day free trial.