Before and after: running the comparison

The cleanest way to see the rewriter working is to hit the same pipeline twice with the same question: once with rewrite_n set to zero and once with rewrite_n set to three. Compare the returned sources. The second call should pull in chunks the first call missed, especially on paraphrased or under-specified questions.

terminal
bash
# Baseline, single query
curl -s -X POST http://localhost:8000/advanced-rag/ask \
  -H "Content-Type: application/json" \
  -d '{ "question": "how do we strip names before the LLM sees them?", "rewrite_n": 0, "anonymize": false }' | jq '.rewrites, .sources | length'

# With rewriter
curl -s -X POST http://localhost:8000/advanced-rag/ask \
  -H "Content-Type: application/json" \
  -d '{ "question": "how do we strip names before the LLM sees them?", "rewrite_n": 3, "anonymize": false }' | jq '.rewrites, .sources | length'

The first call returns an empty rewrites array and whatever sources matched the original phrasing. The second call returns three or four rewrites and a richer source set. A note on naming: the response model maps the chunks the graph state calls retrieved (with their text stored as contexts) to the sources array you are counting here, and the state rewrites list straight to rewrites.

How the rewriter changes the retrieval pattern

Each rewrite becomes a separate retrieval call. The parent graph dedupes and fuses the results.

The retrievals run against a local ChromaDB, so each one is a few milliseconds. The embedding calls can run in parallel since they are independent. The one extra LLM call for rewriting adds about half a second with a fast provider. On a realistic pipeline with a 10-second synthesis call, the rewriter cost is a rounding error. Quality gains are not.