Build a Cited Evidence Table From 10 User Interviews in an Afternoon — No Dovetail
A four-step workflow that produces a participant-ID-tagged, verbatim-quoted evidence table with every citation confirmed against your…
Build a Cited Evidence Table From 10 User Interviews in an Afternoon — No Dovetail
A four-step workflow that produces a participant-ID-tagged, verbatim-quoted evidence table with every citation confirmed against your source transcript. No Dovetail or research-repo tool required.

~9 min read. For product designers who ran 5–15 user interviews, have the raw transcripts, and need a themed insight readout with traceable quotes they can defend to a PM. No Dovetail, Looppanel, or ProductBoard budget required. By the end you’ll have a participant-ID-tagged, verbatim-quoted evidence table where every citation has been confirmed to exist in the source transcript.
You paste five interview transcripts into ChatGPT. A few seconds later: five clean themes, each with a neat supporting quote. It looks exactly like what you’d spend an afternoon building manually. You drop it into the readout, send the deck, and feel genuinely good about the work.
Then in the review, a PM points at the quote under “frustration with notification timing” and asks: “Who said that?” You check your transcripts. The phrase isn’t there. Not verbatim. Participant 3 said something close; Participant 5 said something adjacent. The model took two related complaints, smoothed them into one sentence, and attributed it to neither.
This is not a rare failure. It is the normal output of ChatGPT applied to interview transcripts without a structural constraint on what it’s allowed to return.
The invisible failure modes are three and they compound: the model merges quotes across participants and smooths the wording so the composite sounds real; it paraphrases correctly-attributed content so the “quote” is a plausible summary, not a verbatim extract; and the themes themselves shift when you rephrase the prompt slightly, meaning the readout you sent is one of several equally plausible readouts the same transcripts would have produced. Linardon et al. at Deakin University, writing in JMIR Mental Health in November 2025, found that only 43.8% of GPT-4o citations were both genuine and accurate. Of the fabricated ones, 64% of those that included a DOI linked to a real but unrelated source. They looked legitimate until you checked.
The fix is a structural output contract followed by a verification pass, not a better prompt. This article gives you both: a four-step tag, cluster, cite and verify workflow that produces a PM-ready evidence table where every quote is confirmed to appear verbatim in the transcript it cites.
The deliverable is specific: a table with columns for theme, participant ID, verbatim quote, and a verified flag (confirmed or flagged). You can build it this afternoon from transcripts you already have.
Why “the model gave me a quote” doesn’t mean the quote is real
The failure is worth understanding precisely, because the naive fix (“just ask ChatGPT for better citations”) doesn’t address the root cause.
When you ask ChatGPT to synthesize qualitative data, each response is built on continuing context. The model isn’t retrieving passages; it is generating text that is consistent with the themes it has already named. A 2023 PMC study, “Harnessing ChatGPT for Thematic Analysis: Are We Ready?” (arXiv 2310.14545), named three specific failure modes for thematic analysis with ChatGPT: hallucination (responses not grounded in the data); prompt-dependence (different theme sets from the same transcripts depending on how the request is phrased); and missed codes that a human analyst would flag. The study recommends human review of every ChatGPT-generated theme against the research question. That is correct as far as it goes, but it doesn’t give you a mechanism.
Morgan (2023), in the International Journal of Qualitative Methods, documented the specific qualitative-synthesis failure: ChatGPT synthesizes plausible-sounding quotes from fragments or invents them, with a theme like “frustration with mobile app performance” supported by quotes that don’t appear verbatim in any transcript. The root cause is the same as above: the model is continuing its own generated context, not retrieving text.
The Deakin/JMIR data makes the practitioner stakes concrete. Of 176 citations GPT-4o generated for literature reviews, 19.9% were completely fabricated. Of the authentic citations, 45.4% contained errors. Only 43.8% were both genuine and accurate (Linardon et al., JMIR Mental Health, November 2025). Those numbers apply to a task structurally similar to interview synthesis: the model produces citations that look right without the underlying source supporting them.
The relevant distinction for interview synthesis is between obvious hallucination and quote-merging. An obvious hallucination (a participant reference that doesn’t exist) you might catch on review. A merged quote, where the model composites two real participant statements into a single plausible sentence, you probably won’t catch, because you remember the general sentiment from your notes. Quote-merging is worse than obvious hallucination because it looks right until the PM asks.
Both the failure and the fix are mechanical.
How to stop ChatGPT from making up quotes: the output contract
Emily Campbell, in her “The Shape of AI” talk, points to ProductBoard’s citation pattern as an example of a UI affordance worth admiring: research synthesis that traces every insight back to its source. She’s right that the pattern is valuable. What she doesn’t address is how to build it from raw transcripts without a research repository tool, or what happens when the “citations” the model produces were never in the source.
The answer is an output contract: a structural constraint on what ChatGPT is allowed to return, built into the prompt. You do not ask for themes; you ask for themes plus a participant ID plus a verbatim extract, and you specify the format so the model cannot satisfy the prompt with a paraphrase.
This is a two-prompt chain.
Step 1: Tag each transcript (run once per transcript)
Transcript ID: [P3]
Participant: [name or role label]
Below is the full transcript. For every moment where the participant expresses a pain, a workaround, a preference, or a behaviour pattern, extract the exact verbatim text. Do not paraphrase. Do not summarise.
Return a JSON array. Each element:
{
"transcript_id": "P3",
"excerpt": "[verbatim quote, unaltered]",
"line_range": "[approximate line numbers or timestamp if available]",
"signal_type": "pain | workaround | preference | behaviour"
}
Only return excerpts where the text is verbatim from the transcript. If you are not certain the text appears verbatim, omit it.
[paste transcript here]
Run this once for each transcript. You’ll get a JSON array of tagged excerpts per participant. The line_range field is borrowed from the tagging convention in GoTranscript's evidence-table approach: timestamp or line number as a locator, so you can find the excerpt in the original in seconds.
Step 2: Cluster into themes with citations
Below are tagged excerpts from [N] user interviews. Each excerpt includes a transcript_id and verbatim text.
Cluster these into 4–7 themes. For each theme:
- Name the theme (a specific behaviour or problem, not a category label)
- List 2–4 supporting excerpts
- For each excerpt: include the transcript_id, the verbatim text exactly as given, and the signal_type
Return a markdown evidence table with columns:
| Theme | Participant ID | Verbatim quote | Signal type |
Do not rephrase the excerpts. Use only the verbatim text from the input. If no verbatim support exists for a theme, do not include the theme.
[paste all JSON arrays from Step 1]
This is the output contract. The model is forced to carry a participant ID and verbatim quote for every row. A theme without attached evidence cannot be returned. The format makes it structurally impossible to satisfy the prompt with a paraphrase.
The insider term for what you’ve built here is an evidence table: structured, source-tagged, with explicit support strength implied by how many participants appear in each theme row.
Why the contract isn’t enough: the verification pass that closes it
Most articles on ChatGPT interview synthesis stop at the output contract. You have a table, it has participant IDs, the quotes look specific. That feels like the finish line.
The problem is that a quote in the right format can still be invented. The model will satisfy the contract with plausible text that fits the participant ID and the theme, even if that text was never in the transcript. It has been told what format to return, not instructed to refrain from generating content. The contract reduces fabrication but does not eliminate it. And a fabricated quote that passes format-checking is the one a PM catches in the meeting.
Treat synthesis like code with a test suite. The tagging and clustering prompts are the build; the verification pass confirms the output. Nobody ships code without running tests, and a research readout deserves the same treatment.
The verification pass has two forms depending on what you have available.
Verify prompt (paste into ChatGPT with your transcripts and the evidence table)

Verification workflow: Claude confirming quote existence against transcript corpus ⬇
Below is an evidence table of themes and verbatim quotes from user interviews.
Below the table are the source transcripts, labeled by Participant ID.
For each row in the table:
1. Search the relevant transcript for the exact verbatim quote in the "Verbatim quote" column.
2. If the quote appears verbatim (or within 3 characters, accounting for punctuation): mark it CONFIRMED.
3. If the quote does not appear verbatim: mark it FLAGGED and note the closest passage you found, if any.
Return the same evidence table with an additional "Verified" column.
[paste evidence table]
[paste all transcripts, labeled with participant IDs]
This prompt is the featured-snippet target: paste it, run it, get a table where every quote is CONFIRMED or FLAGGED. Any FLAGGED row needs your attention: the model merged quotes, paraphrased, or invented. Replace it with a genuine verbatim extract or remove the row.
Verification script (optional, for larger datasets or repeatable runs)
If you have more than eight transcripts or you’re running this process across multiple projects, a 15-line Python script does the same character-level existence check without re-pasting everything into a chat:
import json, re
def verify_quotes(evidence_table_path, transcripts_dir):
with open(evidence_table_path) as f:
rows = json.load(f) # list of {participant_id, verbatim_quote, theme}
results = []
for row in rows:
pid = row["participant_id"]
quote = row["verbatim_quote"].strip()
transcript_path = f"{transcripts_dir}/{pid}.txt"
try:
with open(transcript_path) as t:
text = t.read()
# Normalize whitespace, check substring presence
normalized_text = re.sub(r'\s+', ' ', text)
normalized_quote = re.sub(r'\s+', ' ', quote)
status = "CONFIRMED" if normalized_quote in normalized_text else "FLAGGED"
except FileNotFoundError:
status = "TRANSCRIPT_MISSING"
results.append({**row, "verified": status})
return results
The script normalizes whitespace (the most common reason a real quote fails a naive string match) and returns a verified flag per row. FLAGGED rows get replaced or dropped before the readout goes to the PM.
The smart-skeptic objection here is predictable: “Verifying every quote by hand defeats the point of automating.” The verification pass is not hand-verification. A second prompt or a 15-line script confirms the existence of every quote in minutes, not the afternoon of review you were already facing. What used to be an afternoon of manual cross-checking is now a two-minute prompt run plus replacing the FLAGGED rows, which you’d have had to do anyway once a PM asked. The automation changes which hours you spend, not whether you do the work.
The PM-ready evidence table you end up with
The final table has four columns, drawn from the GoTranscript evidence-table structure extended with a verification column:
- Notification timing disrupts focused work — Participant ID: P2, P5; Verbatim quote: “I turn them all off during the day now, every single one” (P2, line 47); Verified: CONFIRMED
- Onboarding skips the use case that matters most — Participant ID: P1, P4, P7; Verbatim quote: “I had no idea it could do that until three months in, a colleague showed me” (P4, line 23); Verified: CONFIRMED
- Search is a workaround, not a workflow — Participant ID: P3; Verbatim quote: “Basically I just search for everything because the nav doesn’t make sense to me” (P3, line 91); Verified: CONFIRMED
Each row carries a support strength signal implicitly: a theme with five participant IDs across the quote column is strong evidence; a theme with one participant is an exception worth noting but not generalising from. You can add a “Support” column (strong / mixed / exception) following the GoTranscript tagging convention if your PM expects that level of structure.
Two smart-skeptic counters to pre-empt before you present this:
The first: “Dedicated tools like Dovetail or Looppanel already do this.” They do, and they are excellent. They are also paid SaaS products that require procurement and institutional access. This workflow is for the designer running one round of research this week, with five transcripts and no tool budget, who needs a defensible readout by Friday.
The second: “Human analysis should come first; AI should not drive interpretation.” Correct, and nothing in this workflow contradicts it. The thinking (which themes matter, what the patterns mean, how to present the implications) stays with you. What the chain automates is mechanical retrieval (which participant said what), format normalization (tagging to a consistent schema), and verification (confirming the quote exists). That’s where the hours were going, not in the interpretation itself.
Thinking exercise: run the verify prompt on a readout you already shipped. Count the FLAGGED rows. That number tells you whether the unverified synthesis you’ve been doing has been holding up.
An unverified citation is worse than no citation
Return to the PM’s question: “Who said that?”
With the verify pass, the answer is a one-click reference to participant ID, line number, and exact transcript text. The quote survived the check. The theme is defensible.
Without it, the answer is silence while you open a transcript and search for a phrase you know the model generated from two different people’s adjacent complaints. If you find something close, you qualify. If you don’t, you walk back a theme that shaped the readout.
The danger of a verified-looking citation that was never verified is that it manufactures confidence. A CONFIRMED label you earned is evidence. A quote that looks sourced because it’s formatted correctly is a liability that passed format-checking.
That’s why an unverified citation is worse than none. A missing citation signals incompleteness: a PM asks for the source, you find it, you fill the gap. An invented or merged citation signals false certainty. The PM finds the problem when the readout already shaped a product decision.
Synthesis isn’t done until the quotes are verified. The verification rep is what converts ChatGPT output from “plausible” to “defensible.” Run it before you ship.
I’m packaging this into an Interview Synthesis Pack: the four prompts plus the verification step and the evidence-table template, ready to paste. Join the list and I’ll send it when it’s ready.
메타데이터
- post_id
- 93c4b3e2611b
- slug
- build-a-cited-evidence-table-from-10-user-interviews-in-an-afternoon-no-dovetail-93c4b3e2611b
- url
- https://medium.com/@sumeeeet/build-a-cited-evidence-table-from-10-user-interviews-in-an-afternoon-no-dovetail-93c4b3e2611b
- canonical_url
- https://medium.com/@sumeeeet/build-a-cited-evidence-table-from-10-user-interviews-in-an-afternoon-no-dovetail-93c4b3e2611b
- author_url
- https://medium.com/@sumeeeet
- status
- ok
- fetched_at
- 2026-07-10 06:10:56