Week 2Day 11 of 30120 minutes~59 min of reading

Build — retrieve, stuff, generate, cite

RAG: the enterprise pattern

Build enough to be dangerous

Why this matters for a delivery manager

RAG is the pattern behind 80% of 'can we put GPT on our data' asks. It is also how vendors hide a pile of decisions (chunk, retrieve, rerank, prompt, cite). If you can draw it and put a name on each box, you can run the workstream. If you cannot, you are buying a demo.

The generator is the part everyone wants to talk about. The pipeline is the part that actually fails. Ingest without a knowledge owner, retrieve without an eval, generate without a refuse rule, cite without a deep-link — that combination is how you ship a confident intern with a master key and a bibliography of unrelated files.

Today you write the generator contract (prisoner of the packet, allowed to refuse), you demand citations a human can open, and you list the asks that should not be RAG at all. Tomorrow you catalog how this fails in production. Day 14 folds both into a design pack.

You will be able to

  • Draw RAG as a pipeline with owners, not as a product name
  • Write a generation prompt that is not allowed to wander off the retrieved packet
  • Demand citations that a human can click
  • Know when RAG is the wrong pattern (actions, math, live systems of record)

2-hour clock

120:00

Now: Read the pipeline, the prisoner, and the non-goals · 50m

The 2-hour session

Concepts, in full

This block is a slow read — about an hour with the diagrams. After each concept, write one sentence in notes (what you already do vs what is new) and tick annotated. Do not skim the last concept.

01

RAG is a pipeline, not a feature checkbox

Retrieval-Augmented Generation means: find the relevant chunks, then generate an answer conditioned on them. The name is one line. The work is a pipeline. Ingest: load docs, clean junk, split, attach metadata. Index: embed and store. Retrieve: hybrid search + filters + maybe rerank. Generate: model writes using only (or mostly) those chunks. Cite: each claim points at a chunk. UI: the user can open the source. Evaluate: retrieval recall and answer groundedness, separately.

If you cannot draw those boxes with an owner on each, you do not have a RAG program. You have a vendor checkbox. A RACI that says 'AI team' on every box is a failed RACI. Data / knowledge owner on ingest. Engineer on index and client. You on eval questions, generator contract, and go-live. Security on ACL. Product on the UI and the 'not a decision' footer. Sponsor on corpus scope and the no-go.

Ingest is where most timelines actually go. Connectors, permissions, junk, OCR, the argument about which Confluence spaces are in. Treat ingest as a workstream with a sample-chunk review gate, not as 'we'll hook up the loader on Thursday.' Day 10's chunking spec lives here. If ingest is unbounded ('all of Confluence'), the rest of the pipeline is theatre.

Index is operations: which vector store, which embedder, how filters work, how upserts happen when a page changes. You do not need to pick the brand in the first workshop. You do need a re-index SLA and a permission story. 'We'll rebuild nightly' is a lag you must print in the UI. 'We'll rebuild when we remember' is not an SLA.

Retrieve is yesterday. Hybrid, filters, k, eval. The only new point today: retrieve is allowed to return empty. Empty is a success path. It must be passed to generate as empty, not replaced with 'the closest 5 anyway.' Closest-anyway is how you get salary-adjacent answers from a project wiki.

Generate and cite are the product the user sees. They are the smallest part of the code and the largest part of the trust. The next concepts are those boxes in slow motion. Do not skip to them and ignore ingest. Sponsors will try to. Your job is the whole pipe.

Evaluate is two numbers, always: recall@k on retrieval, groundedness / citation correctness on the answer. They fail independently. High recall and a wandering generator still ships lies. A loyal generator on the wrong chunks still ships the wrong SOP. If a vendor reports one blended 'quality' score, ask them to split it. If they cannot, they are selling a demo.

RAG is a pipeline with a name on each box or it is a vendor checkbox. Ingest has a knowledge owner and a sample-chunk gate. Index has a re-index SLA. Retrieve is allowed to return empty. Generate is a prisoner of the packet. Cite deep-links. UI shows the source. Evaluate splits recall from groundedness. A RACI that says 'AI team' on every box is a failed RACI. Draw the boxes until you can staff them. If you cannot, you are not ready to ingest, and you should not be in a workshop pretending you are. The generator is the part everyone wants to talk about. The pipeline is the part that actually fails. Spend your words on ingest and retrieve even when the sponsor is already naming models.

Diagram

RAG as a pipeline with a job on each arrow

01

Ingest

Load, clean, split, metadata, ACL. Knowledge owner samples chunks before you fund the rest.

02

Chunk + embed

Structure-aware units, overlap, same embedder you will query with. Upsert on change.

03

Retrieve

Hybrid + filters + k. Empty is allowed. Eval is recall@k.

04

Generate

Prisoner of the packet. Refuse if empty or irrelevant. Temperature 0.

05

Cite + UI

Each claim deep-links. User can open the heading. Footer: this is not a decision.

06

Evaluate

Recall and groundedness, separately. Owner, frozen set, reported as fractions.

Redraw from memory until you can put a role on every box. Cite is not optional decoration. Empty retrieve must still reach generate.

02

The generator is a prisoner of the packet

The system prompt must say: answer only from the provided sources; quote or cite; if sources don't cover it, say you don't know and suggest who to ask. Without that, RAG becomes search plus hallucination with a bibliography of unrelated files. The model is a prisoner. The packet is the cell. If the cell is empty, the prisoner does not get to wander the building.

Stuffing 20 chunks 'to be safe' dilutes the good ones and blows cost. 3–8 good chunks beat 20 mediocre. That is why retrieval eval comes first. If recall@5 is 40%, adding 15 more neighbors will not find a document that was never a neighbor. It will find more junk for the model to quote. k is a product knob you set from the eval, not from anxiety.

The user packet you send is a structured object, not a pile. Typical shape: the question, the retrieved chunks labeled [S1], [S2] with source metadata, the refuse rule, the citation rule, the output contract (short answer, then sources). Labeling matters. If chunks are unlabeled blobs, citations become 'handbook.pdf' and you have decoration. If labels exist, you can demand [S3] on every factual sentence and you can eval it.

Prior knowledge is the leak. Frontier models know a lot of generic HR, law, and vendor folklore. That knowledge will fill gaps unless you forbid it for the classes of claim you care about: policy, prices, owners, dates, SLAs. The prompt should name those classes. 'Do not use prior knowledge for policy, prices, or owners' is a line you paste. 'Be accurate' is not.

Refuse-when-empty is a successful behavior. Write the exact sentence: 'I don't have this in the indexed documents.' Optionally: who to ask (the knowledge owner, a queue). Optionally: what would need to be ingested. Do not let the model improvise a helpful guess. Helpful guesses are how RAG gets banned after one steering meeting.

Refuse-when-irrelevant is harder and still required. Retrieval returned five chunks, none of which answer the question (vector search always returns neighbors). The prompt needs: if the sources are not sufficient, refuse; do not stitch a plausible policy from nearby topics. Groundedness eval is how you test this. The empty-gold rows from yesterday plus 'near-miss' questions (asked the wiki about something in a different space) are your test kit.

Temperature 0, pinned model, prompt version id in the log. The generator is the least of your moving parts and still needs the same client spec as day 9. JSON or a strict markdown contract if you will parse citations. Streaming is fine for the prose if you buffer until the first citation exists, as you already decided for policy copilots.

The prisoner prompt is the product: answer only from SOURCES, cite [Sn], refuse if empty or irrelevant, no prior knowledge for policy, prices, dates, or owners. Label the packet. Use 3 to 8 chunks, not 20. Temperature 0. Prompt version in the log. Exact refuse sentence, not an improvised apology that turns into a guess. Prior knowledge is the tunnel out of the cell; name the claim classes you forbid. If this contract is not versioned, a bad answer has no parent. Paste it. Date it. Put the id on the request. That is how you debug, and that is how you eval. A generator without a cage is search plus hallucination with a bibliography of unrelated files. You already knew that. Write it so the model knows it too.

Diagram

Generator as prisoner — what it is allowed to see, in order

  1. 01

    System contract

    Answer only from SOURCES. Cite [Sn]. Refuse if empty or irrelevant. No prior knowledge for policy, prices, owners.

  2. 02

    Labeled packet

    [S1]…[S8] with source, heading, date. 3–8 chunks, not 20. Empty packet is explicit.

  3. 03

    The question

    User ask, plus any hard filters already applied (space, region, ACL). Do not re-ask the model to filter.

  4. 04

    Output cage

    Short answer + citations. Exact refuse sentence. Footer handled in UI, not improvised.

If a layer is missing, the model walks out of the cell. Prior knowledge is the tunnel.

A generator that is allowed to refuse — paste into the spec, then version it
You answer using ONLY the SOURCES.
Each factual sentence needs a citation like [S3].
If SOURCES are empty or irrelevant, reply exactly:
"I don't have this in the indexed documents."
Do not use prior knowledge for policy, prices, dates, or owners.
Do not invent a source id.

SOURCES:
[S1] {source} | {heading} | {date}
{text}
[S2] ...

QUESTION:
{question}

Write a short answer. Then list the source ids you used.

03

Citations are a product requirement

A citation that says 'Source: handbook.pdf' is decoration. A citation that opens heading 4.2 of the 2024 travel policy is a product. Store enough metadata at ingest to deep-link: path, heading trail, page, paragraph id if you have it. This is how legal, QA, and operators trust the thing. If you cannot highlight, you cannot claim citation. That sentence will return tomorrow as citation theatre. Plant it now.

The UI is the contract with the user. Answer text, inline marks or footnotes, clickable sources, a visible 'this is not a decision / not legal advice / not an HR determination' footer on v1. No write-tools. No 'add this to the wiki' button until you have a human gate and a knowledge owner. v1 is read-with-receipts.

Groundedness eval: given answer + retrieved chunks, did each claim appear in the packet? First version: you, by hand, on 20 rows. Mark claim-level, not whole-answer-level, or one true sentence will launder two invented ones. Later, an LLM-as-judge — with skepticism (day 16). Never let the judge be the only eval, and never let the same model grade its own homework without a frozen human set.

Citation correctness is a separate mark: the cited [S3] actually supports the sentence, not merely appeared in the packet. Models will cite a nearby chunk because it was there. That is theatre. Your eval sheet has two columns: grounded (claim in packet) and cited-right (the id they pointed at is the one that holds the claim).

When the packet supports a partial answer, the product should say so. 'The SOP covers contractors in-country; it does not mention contractors abroad. I don't have the abroad rule in the index.' Partial-plus-refuse is more useful than a confident whole. Teach the prompt that omitting is allowed. Fullness is not a virtue when the corpus is thin.

Operators need a 'see the packet' debug. Not in the customer UI on day one, but in an internal view: the chunks, scores, filters that fired. When someone says 'it cited the wrong SOP,' you must be able to tell retrieve-wrong from generate-wrong in five minutes. request id on the footer, as on day 9.

Do not auto-open the source in a way that bypasses ACL. The citation click goes through the same permission check as retrieve. A deep-link that dumps a document the user could not have retrieved is an ACL leak with extra steps. Tomorrow covers the leak in slow motion. The hook is: citations inherit ACL.

A citation is a deep-link to the heading that supports the claim, clickable, inheriting ACL, with a highlight if you can build it. 'handbook.pdf' in a footer is decoration, and decoration trains auditors to trust a footnote that does not earn it. Groundedness is claim-level: did this sentence appear in the packet. Citation correctness is separate: did they point at the chunk that holds it. Partial answers plus refuse on the rest beat a confident whole. Operators get a 'see the packet' debug with the request id. v1 UI: answer, citations, 'this is not a decision' footer, no writes. If you cannot highlight, you cannot claim citation. Plant that now; tomorrow it returns as theatre.

04

When RAG is the wrong hammer

Need a live number from SAP? That is a tool call, not a PDF index. Need to file a ticket? Structured write with approval. Need yesterday's tickets clustered? Embeddings without a generator. Need a deterministic workflow with 14 systems? That is orchestration, maybe with a model in one step — not a chat over a wiki. RAG shines for 'what does our documentation / prior decisions say.' Keep it in that box and it looks like magic. Stretch it into an agent of record and it looks like a lawsuit.

Math, counts, and 'how many open risks in RAID' are not RAG. The model will approximate from a stale export if you let it. The right pattern is a query tool against the system of record, with an owner of that query. You may still RAG the definition of a risk. You do not RAG the inventory of risks.

Actions are not RAG. 'Open a follow-up' is a write. Writes are day 13, with caps and a human gate. A wiki copilot that quietly files Jira tickets because the prompt said 'be helpful' is an incident. Non-goal it in v1 even if the sponsor saw a demo that did it.

Personal data, HR cases, health, payroll, employee performance: usually not this corpus, often not this pattern at all without a much uglier compliance track. If the wiki contains them incidentally, they are out-of-scope and ACL-blocked, not 'we'll prompt it not to answer.' Prompting is not access control.

Conversational search over a corpus the user already has in an enterprise search product may not need a generator. Sometimes the right v1 is hybrid search plus snippets, no LLM. Cheaper, easier to cite (the snippet is the citation), easier to ACL. Add generation when operators ask for synthesis across multiple hits, not because the roadmap said 'AI.'

If the path is known and the input is a form, do not put a model in the loop. 'Submit an access request' is a form with a policy RAG on the side to explain the rules. Mixing them into an agent is how you get a system that sometimes files the request and sometimes writes an essay about the request.

Write the non-goals in the same document as the pipeline. 'We will RAG the policy corpus with citations and a retrieval eval. We will not RAG the ERP. Numbers come from a query tool with an owner.' Say it early. Saying it after the vendor workshop is how you spend a quarter unpicking a demo.

RAG is for 'what does our documentation or prior decisions say.' Live numbers are a query tool. Writes are a form or a gated tool. Clustering is embeddings without a generator. Known 14-step paths are orchestrators. Personal HR data is out. Sometimes v1 should not generate at all — hybrid search plus snippets is cheaper, easier to cite, easier to ACL. Add generation when operators ask for synthesis across hits, not because the roadmap said AI. Write the non-goals in the same document as the pipeline. Repeat them when the demo gets exciting. The sentence that saves a quarter is the one you said early, not the one you drafted after the CEO screenshot.

Pattern choice: RAG is one column, not the whole market
AskRight patternWhy RAG fails here
What did we decide about vendor X?RAG over decision log + SOPsThis is the box RAG is for
Current open PO amount for vendor XQuery tool to ERP / finance SoRIndex is stale; numbers must be live
File a follow-up ticketForm or write-tool with human gateSide effect; not a document lookup
Cluster last month's incidentsEmbeddings + clustering, no generatorGeneration adds fluent fiction
14-step access provisionOrchestrator / BPM; model on messy text onlyKnown path; an agent will improvise
Jane's salary bandRefuse; out of corpus and roleACL + scope; prompting is not enough

Pattern choice: RAG is one column, not the whole market

05

Refuse-when-empty is a product feature, not a failed demo

Sponsors hate refuse. Demos hate refuse. Production requires refuse. Align them in the design: we will measure refuse rate, we will show a useful next step (who to ask, what to ingest), and we will not optimize refuse away by stuffing junk. A refuse rate of zero on a real wiki is a smell. It means you always retrieve something and always talk.

The empty path has a UX. Not a blank bubble (day 9). A sentence, a link to search, a 'request this document be added' if you have a knowledge owner, a request id. That is a successful task outcome when the corpus does not contain the answer. Write it in the one-pager as a screen, not as an afterthought.

Weak retrieval should look closer to empty than to confident. If top score is below a calibrated threshold and hybrid also missed, refuse or ask a clarifying question. Clarifying ('which product: Atlas or Orion?') is allowed. Inventing the product is not. Put two examples in the prompt: empty, and underspecified.

Do not retry generate on empty with a 'try to be helpful' second prompt. That second prompt is how prior knowledge walks in. If you retry, retry retrieve with a rewritten query (hyphenated ID, expanded acronym), then generate once more with the new packet, still allowed to refuse. Query rewrite is a retrieve trick, not a license to ramble.

Eval the refuse path as first-class. Yesterday's empty-gold rows. Today's groundedness on near-misses. Report false-answer rate on those rows separately from recall. Steering should see 'we refused 8/10 out-of-scope asks and we answered 1 we should not have.' That 1 is a go-live blocker if the domain is sensitive.

Operators will try to 'fix' refuse by adding more spaces to the index. Sometimes that is right (the document exists and is in-scope). Sometimes that is how HR folders get ingested on a Friday. Every corpus expansion is a change request with ACL, owner, and eval rows. Refuse is the pressure valve that makes those expansions visible.

Your generator contract from c2 is incomplete if it does not include the exact refuse sentence and the ban on prior knowledge. Paste it. Version it. Put the version id in the log. When a bad answer ships, you need to know which contract produced it.

Refuse-when-empty is a successful task outcome. Give it UX: a sentence, a next step, a request id — not a blank bubble, not a second prompt that says 'try to be helpful.' Query rewrite is a retrieve trick you may retry once. It is not a license to ramble. Measure refuse rate; zero on a real wiki is a smell. Eval the path with empty-gold rows and near-misses. The one false answer on an out-of-scope ask is a go-live blocker if the domain is sensitive. Operators will try to 'fix' refuse by adding spaces. Sometimes that is right. Sometimes that is how HR folders get ingested on a Friday. Every expansion is a change request with ACL, owner, and eval rows. Refuse is the pressure valve that makes those expansions visible instead of silent.

06

Owners, first-release UI, and the one-pager you will reuse

The practice is a one-pager for 'ChatGPT on Confluence for the program' — a sentence you will not accept as a spec. You replace it with: users, job, corpus in/out, pipeline boxes with owners, generator contract, two evals, first-release UI, non-goals. You will fold this into day 14. Write it so a skeptical engineer and a skeptical sponsor both survive the read.

Users and job: 'PMs on Program Atlas can ask what we decided about vendor X and get a cited answer from the decision log and SOPs in the Atlas space.' Not 'employees can chat with knowledge.' If you cannot name the job, you cannot name the eval questions, and you will RAG everything.

Corpus in/out: named spaces, named types (SOP, decision log, RAID). Out: HR personal data, vendor pricing folders, personal drives, archive unless dated and flagged. If out-of-scope material lives inside an in-scope space, that is an ingest filter, not a prompt. Name the knowledge owner who will keep the boundary.

First-release UI: answer, citations that open the heading, refuse sentence, 'this is not a decision' footer, request id, no writes, no agents. Search-like, not intern-like. If the sponsor needs a chat personality, they can have a one-line tone instruction. They cannot have tools that mutate Jira in v1.

Two evals, named: recall@5 on the day-10 table (at least 10 questions, mix including empty), and groundedness on 20 answers including the refuse cases. Owners of each. Cadence for re-run (every corpus change, every prompt change, every model bump).

Cost envelope at expected volume and 10×, using day 5 math and day 9 usage logs. If you cannot estimate, you do not have a v1, you have a credit card. Put the number next to the non-goals so the sponsor sees what they are buying.

The eight-minute talk track starts to form here: problem (PMs cannot find decisions), slice (Atlas space, read-only), how it works (the six boxes), how we'll know (two evals), what we will not do (ERP, writes, all-of-Confluence). Day 14 is that talk with RAID and ACL added. Draft the bones now so lab day is assembly, not invention.

The one-pager replaces 'ChatGPT on Confluence' with users, job, corpus in and out, boxes with owners, generator contract, two evals, first-release UI, non-goals, cost envelope. That is the object you fold into day 14. Write it so a skeptical engineer and a skeptical sponsor both survive the read. If either would bounce, you wrote a mood board. The eight-minute talk track starts here: problem, slice, how it works, how we'll know, what we will not do. Lab day is assembly of objects you already have. If this page is thin, thicken it tonight. Do not invent a new architecture under the clock.

Worked case · stay here ~20 minutes

RAG versus fine-tune in the architecture review

Monday architecture review. Atlas wiki copilot. In the room: you, Priya, Dev (platform architect), Marcus, and a vendor SE who has a fine-tuning slide. The ask on the agenda is ChatGPT on Confluence for the program. Dev wants to fine-tune a small model on the wiki so it just knows our SOPs. You have a one-pager that says RAG. You have forty minutes.

Dev's pitch is clean and it will sound cheaper if you let the slide run. Fine-tune a small model on Atlas SOPs, ship it in our VPC, no retrieval latency, no index to keep fresh, the model just knows POL-1044. The vendor SE nods: they have a tuning API and a case study on a policy bot. Marcus hears just knows and in our VPC and puts down his pen. You have to get the pen back without calling Dev a fool. You ask two questions before you talk pattern. One: how often does SOP-14 change. Marcus: monthly, and at 4 p.m. when a regulator writes. Two: who owns the gold answers if we train. Silence. There is no labeled set. There is a wiki. Fine-tuning on a wiki without a labeled job is next-token on junk, plus a retraining loop every time a heading moves. RAG is the pattern for what does our documentation say when the documents move. You say that sentence. You do not say fine-tune is wrong. You say fine-tune is a different job, and we have not named that job.

You draw the pipeline on the board, six boxes, owners, because a checkbox named RAG is what Dev thinks you are selling. Ingest, chunk, embed, retrieve, generate, cite. Knowledge owner on ingest. Engineer on index and client. You on eval and generator contract. Security on ACL. Empty retrieve is allowed and must reach generate as empty. Evaluate two numbers: recall at k and groundedness, separately. Dev says that is a lot of boxes for a chatbot. It is a lot of boxes for a product that will be quoted in a ticket as if it were policy. Fine-tune does not delete the boxes. It hides them. You still need ingest (training data), a split (what is a document), an eval (did it memorize the right SOP), an ACL story (the weights will not forget the CEO folder you accidentally trained on), and a refresh SLA (retrain when SOP-14 moves). The boxes come back, with a GPU bill and a lag measured in days. RAG's lag can be hours or event-driven. For a wiki that changes at 4 p.m., lag is the architecture. Name the lag.

The generator is the part everyone wants to talk about. You talk about the prisoner instead. Answer only from SOURCES. Cite source ids. Refuse if empty or irrelevant. No prior knowledge for policy, prices, dates, or owners. Temperature 0. Prompt version in the log. Exact refuse sentence. Dev says if we fine-tune, we will not need to cage the model. That is the opposite of the truth. A fine-tuned model is prior knowledge with a house accent. It will still invent a clause when the question is in a hole. It will invent with more confidence because the hole sounds like Atlas. RAG's cage is visible: the packet is on the screen, the citation opens H2, empty is a sentence. Fine-tune's cage is we hope the weights learned to shut up. Hope is not a control. You paste the prisoner prompt into the one-pager in the meeting, version id and all. If this contract is not versioned, a bad answer has no parent. That is true whether the weights are frontier or house-trained. The cage is the product. The model is the inmate.

Citations are the kill shot for the fine-tune slide, and you use them without theatre. A citation that says handbook.pdf is decoration. A citation that opens heading 4.2 of the 2024 travel policy is a product. Fine-tuned weights do not deep-link. They can emit a document name they memorized, which is citation theatre with extra steps. Legal, QA, and operators will ask to click. If you cannot highlight, you cannot claim citation. Dev says we can store a side index for citations and still generate from the fine-tune. At that point he has reinvented RAG, plus a training loop. Thank him. Put retrieval back in the middle. Use the frontier model as the generator, prisoner of the packet, until an eval says a smaller model, prompted, holds groundedness. Distillation and small models are work for classification at volume, not for a 200-page wiki in week two of a POC. The vendor case study was 40,000 labeled tickets. You have ten harvested questions and a knowledge owner named last Friday. Do not buy a training pipeline with that inventory. Buy retrieve.

When RAG is the wrong hammer is the honesty that makes the rest land. Live number from SAP: tool call, not a PDF index. File a ticket: structured write with approval. Cluster last month's incidents: embeddings without a generator. Fourteen-system deterministic path: orchestrator. Jane's salary: refuse, out of corpus and role. Dev's fine-tune does not fix any of those. It makes the salary question worse if HR text was in the dump. You write the non-goals on the same board as the pipeline: we will RAG the Atlas policy corpus with citations and a retrieval eval; we will not RAG the ERP; numbers come from a query tool with an owner; we will not fine-tune until we have a labeled job the wiki is not. Marcus repeats the ERP sentence. Good. The vendor SE tries to save the slide by offering RAG plus optional tuning. Optional is how the tuning job gets staffed and the retrieval eval does not. You put optional in appendix v2, gated on recall holding for two weeks and on a named labeled task. Dates only on RAG v1.

Refuse-when-empty is where Dev and the vendor will try to win on demo feel. Fine-tuned models always talk. Demos love that. Production on a real wiki requires refuse. A refuse rate of zero is a smell: you always retrieve something and always talk. You show the empty path as a screen, not as an apology: sentence, who to ask, request id. Query rewrite once is allowed. A second prompt that says try to be helpful is how prior knowledge walks in, whether or not you trained. The salary question from Friday's eval mix is the test. RAG with a cage refuses. A fine-tune will answer from whatever HR-adjacent text leaked into the dump, or from the base model's folklore. Marcus has now seen a blank bubble last week and a guess in a hallway demo. He does not want a third way to be wrong. He wants a sentence that is allowed to be I do not have this. You make him say that in the review. Once the sponsor has blessed refuse, the fine-tune slide has to explain how weights refuse. They will not. Move on.

Eval is two numbers and Dev has one blended quality score from the vendor. Ask them to split it. If they cannot, they are selling a demo. Retrieval recall at 5 on the day-10 table, including empty-gold. Groundedness on 20 answers, claim-level, cited-right as a second column. They fail independently. High recall and a wandering generator still ships lies. A loyal generator on the wrong chunks still ships the wrong SOP. Fine-tune eval is a third animal: did the weights memorize answers that are now stale, did they leak train-set PII, do they still refuse. You do not have that set. You will not by Thursday. RAG's sets you already started. That is the schedule argument, which is a delivery argument, which is why you are in this review. Priya can have hybrid retrieve on Atlas this week. A tuning job cannot. If Dev's concern is cost at 10x, you put the envelope next to the non-goals: expected questions, tokens in, tokens out, embed of 200 pages, a cheaper model for classification later. Fine-tune does not erase token cost. It adds a training invoice and a refresh invoice.

ACL is the career-class reason you do not train on the dump. If the export was pulled with a service account that can see everything, the weights will see everything. You cannot query-time filter a weight. You can query-time filter a chunk. Permission-aware retrieval is a go-live gate for RAG. For fine-tune it is a go-live impossibility unless the training set was already ACL-sliced per audience, which this dump is not. Dev says they will strip sensitive pages first. Who will? The knowledge owner named Friday has not seen the dump. Security is not in the RACI yet. You add them before ingest, not after an intern's screenshot. The vendor SE says they can unlearn. Unlearning is a research slide. Query-time ACL is an enterprise search pattern your company already has. Invite that team. Do not invent a worse permission universe because a tuning API does not mention users. This is not v2. This is why the architecture is RAG on a permissioned index, or it is not an architecture you will put your name under. Write that in the minutes before the recap email.

You offer Dev a landing zone so he does not have to lose in front of Marcus. v1: RAG, prisoner generator, citations, two evals, ACLs on, no training. v1.5: smaller generator if groundedness holds, still RAG. v2: a labeled classification or extraction job — ticket routing, field extraction — where fine-tune or a small model actually earns its keep, with a gold set and a refresh owner. Wiki Q&A is not that job. He can own v2's labeled path. He cannot own a stealth training loop on Atlas in parallel with v1. Parallel is how the dump becomes the corpus and the index becomes a side project. Marcus likes the landing zone. The vendor SE asks to come back for v2. Fine. Get them off the v1 critical path. Write the RACI on the six boxes before you leave the room. If a box still says AI team, you have not staffed a pipeline, you have staffed a slogan. Put names. Yours is on eval and go-live. Priya's is on index and client. Knowledge owner on ingest. Security on ACL.

The one-pager you came with is now the minutes. Users: PMs on Atlas. Job: find-and-cite decisions and SOPs. Corpus in: Atlas space, SOP, decision log, RAID, about 200 pages. Out: HR, finance, personal drives, archive unless flagged. Pipeline boxes with owners. Generator contract pasted. Two evals named. First-release UI: answer, citations that open H2, refuse sentence, not-a-decision footer, request id, no writes, no agents. Non-goals: ERP, Jira writes, all-of-Confluence, fine-tune on the dump. Cost envelope at 1x and 10x, even if ugly. You read the users-and-job sentence out loud. If it needs a slide to be understood, it is not specific yet. It does not. Marcus repeats it. That is the review outcome. Fine-tune is in the appendix as a gated maybe on a different job. RAG is the architecture. Anyone who still wants the model to just know can have that sentence in a keynote. They cannot have it in the pack. You send the page within an hour, before the vendor SE's recap email rewrites the decision into hybrid approach, TBD. Speed is the control.

What you do not do after: run a bake-off between RAG and fine-tune on five demo questions to be fair. Fair is the mixed eval, and fine-tune does not have a training set that matches it. A bake-off now is a demo-off. Demo-offs hire the vendor. You also do not agree to pre-train on the wiki in the background while we RAG. Background training on an ACL-stripped dump is the leak with a longer fuse. Kill it in the same mail as the one-pager. Priya gets a sequence: sample chunks, hybrid retrieve, prisoner prompt, UI with citations, evals. Dev gets a parking lot with a named gate. You get a review that did not become a science project. That is a win. It will not feel like a win if you like Dev. Like him. Do not give him the dump. The dump is how architecture reviews turn into incidents with a delay of six weeks. You have seen delayed incidents. You prefer the argument today. Have it. Then write. Then stop explaining RAG as a brand. It is a pipeline with a name on each box.

The interview probe is this meeting, compressed. Architect wanted to fine-tune the wiki so the model would just know. We asked how often the SOP changes and who owned the labels. Monthly, and nobody. We staffed a RAG pipeline with a prisoner generator, clickable citations, two evals, and query-time ACL. Fine-tune parked on a labeled classification job with a gate. We did not run a bake-off on demo questions. If you cannot say the ACL sentence, you will sound like you picked the trendy pattern. RAG is not trendy here. RAG is the pattern that can refuse, cite, and forget a page when the page is out of scope. Weights cannot. That is the architecture. The vendor slide will still exist in the next loop. Your one-pager is how you do not work for the slide. Steal the two questions — change rate, label owner — for every fine-tune pitch you will hear this year. They end most of them in four minutes. The rest of the forty is staffing the boxes so the win survives the recap email. Send the page. Then stop arguing with the slide.

Diagram

Wiki Q&A: RAG v1 vs fine-tune-now

A

RAG (Atlas v1)

  • Documents move; index upserts
  • Query-time ACL on chunks
  • Citations deep-link to H2
  • Refuse-when-empty is a screen
  • Evals: recall at k and groundedness
B

Fine-tune on the dump

  • Lag in days; 4 p.m. SOP is stale
  • Weights cannot filter by user
  • Emitted doc names are theatre
  • Always-talk is a demo feature
  • Needs labels you do not have

Fine-tune is a different job. If you cannot name the labeled task and the refresh owner, you are not ready to train. You are ready to retrieve.

Practice

RAG one-pager for a project wiki

45 minutes

Sponsor request: 'ChatGPT on Confluence for the program.' You will not accept that sentence as a spec.

  1. Draw the boxes with owners.
  2. Write the generator contract (refuse allowed).
  3. List in-scope corpora and out-of-scope (HR personal data, vendor pricing folders, etc.).
  4. Name two evals: recall@5 and groundedness on 20 questions.
  5. Write the first-release UI: answer + citations + 'this is not a decision' footer — no write-tools.

Done looks like: A one-pager that could go to steering. You will fold this into the day 14 artifact.

Check yourself

Attempt in your notes first. Reveal is for after, not during.

  • What are the two evals RAG always needs?

  • What should the model do when retrieval is empty?

  • When do you refuse RAG entirely?

  • Why is stuffing 20 chunks 'to be safe' usually wrong?

  • What makes a citation real rather than theatre?

  • Who owns ingest vs index vs eval?

Terms from this day

RAG
Retrieval-Augmented Generation: find relevant chunks, then generate an answer conditioned on them.
Groundedness
Whether the answer's claims are supported by the retrieved sources.
Ingest
The pipeline that turns raw documents into clean, chunked, metadata-tagged index records.
ACL on chunks
Access control so retrieval cannot return documents the user is not allowed to see.

Your notes for day 11

Saved on this device. Use this as the start of the artifact.