Qualitative analysis
Using GenAI in qualitative analysis without breaking your method
The model is a reading partner. You stay the analyst.
You paste your interviews into a chatbot, ask for a thematic analysis, and six tidy themes come back, each with participant quotes underneath. It looks like a week of work done in a minute. Then you open a transcript to find one of the quotes. Nobody said it.
The problemYou did not code badly. You asked for the wrong thing.
Many qualitative researchers have had this moment in the last two years, and it is part of why more than 400 of them, across more than thirty countries, signed an open letter rejecting generative AI in reflexive qualitative research. The themes came back as topic buckets. The quotes came back invented.
The chatbot was never built to do what you asked. Thematic analysis is roughly twenty small tasks in sequence: read everything, code a segment, hold that code in mind, meet a new idea in interview ten, go back and recode interview three. A chatbot has no memory of your dataset between prompts and no stable place to keep a code. Ask it to run the whole thing in one go and it does the only thing it can, which is to recognise the shape of a thematic-analysis report and write something with that shape. The fabricated quotes follow directly: a text predictor was asked to retrieve evidence it never stored.
That makes the failure structural. It also means the useful response is neither to swear off the tool nor to hand it the whole job.
The shiftInterlocutor, not coder
Coding was always a workaround for a human limit. You cannot hold twenty hours of interviews in your head at once, so you break the data into labelled pieces you can retrieve. A language model does not share that limit. It can hold the whole set in view and surface passages that speak to each other. Forcing it to imitate line-by-line human coding wastes the one thing it does well.
So the model works as a reading partner rather than a decider. It suggests candidate codes, groupings that might belong together, a contrasting reading you had not considered. You interrogate each suggestion against the transcript, keep what holds, drop what does not. The interpretation stays yours, because meaning in non-positivist work is made by a situated human.
Three moves make this work, whatever tool you use:
- Divide the work. One small task per prompt, reviewed before the next. Never one prompt for the whole study.
- Review every suggestion against the data. A code counts only after you have accepted or edited it. The model's confidence is a self-report, not evidence.
- Keep themes as questions until you can sign them. "Could these codes describe how waiting reshapes daily life?" is a grouping. A theme exists when you can state it in one sentence, show what supports it, show what complicates it, and put your name on it.
Do this and you are still doing qualitative research. Be honest about which kind: this structured, reviewed approach fits framework, matrix, template and codebook thematic analysis best. It supports reflexive work through your own reading and memos, and it does not turn reflexive analysis into a button.
The toolWhat QualiVahti Local does for you
QualiVahti Local is an Obsidian vault plus open Python and R scripts that run this method on your own computer. The pipeline is one reviewable step at a time, and every step names its tool, so you can see exactly what the model touched.
- Transcription.
faster-whisperruns locally,large-v3by default, so audio never leaves the machine. Drop a recording into01_Audio/and a watcher script transcribes it. Finnish, Swedish and around a hundred other languages are auto-detected, or forced with--language fi. - Code suggestions. A local model served by Ollama (
qwen3:14bby default,qwen3:4bon an 8 GB laptop) suggests one to three first-cycle codes per excerpt, each with a rationale and its own marked uncertainty. Suggestions land insuggested_<id>.csv; your decisions live in a separatereviewed_<id>.csv, onereview_statusper row:accepted,edited,rejectedorunclear. A code counts once you have marked it, and the model name and version id are written into every row. - A second opinion.
build_vault_index.pyvectorises your notes with a local embedding model (nomic-embed-text);chat_with_vault.pythen answers questions over the whole vault with cited, clickable sources, using a different model (hermes3:8b) from the one that suggested your codes. It reports contradictions first and never decides meaning. Every chat session is logged under11_Audit_Trail/chat_sessions/. - The reviewer paragraph, written from your records.
Rscript _scripts/r/draft_ai_disclosure.Rreads your reviewed coding and drafts the AI-use disclosure into09_Methods_Draft/: your real accept, edit and reject counts, the coding model and version, the boundary sentence, and[MISSING:]tags for the facts only you can supply. - A pre-flight check.
Rscript _scripts/r/preflight_check.Rreports, before you export, whether the analysis loop hangs together: every row reviewed, every theme signed and grounded in a real quote with what complicates it, a saturation verdict logged as a three-way call (saturated, not saturated, or not resolvable at this n).
Everything is plain files you keep: Markdown notes, CSV coding, a .canvas evidence map where every node is a live note, and R tables and co-occurrence networks in 12_Exports/. Each run appends one line to 11_Audit_Trail/audit_log.md with the date, script, inputs, model and version, and outputs, so your AI use stays legible to a supervisor or journal. The only network address anywhere in the scripts is localhost, so the whole workflow runs with the internet switched off.
The scripts are open source under Apache-2.0 with a Zenodo DOI, which lets a reviewer inspect exactly what the model was allowed to do. The R side installs straight from an R session:
install.packages("qualivahti", repos = "https://heidihelena.r-universe.dev")
QualiVahti Local will not do your analysis. It surfaces material, you make the meaning, and the audit trail records what you decided rather than whether it is true. That is the line the method literature draws, and it is what lets you explain your work to a committee. See it on the demo study, then your own: QualiVahti Local.
The criteriaHow this maps to a congruence framework
Nguyen-Trung and colleagues (2026) set out what methodologically congruent GenAI use looks like. QualiVahti is built to make each of their tenets the easy path.
- A relational epistemology. The model offers candidate codes, groupings and a contrasting reading. It never names a theme or makes a decision. The second-opinion chat is an explicit dialogue partner, deliberately a different model from your coder, and the reflexivity memo has a section to declare that stance in your own words.
- Ethical, responsible and rigorous use. Everything runs on your machine, since the only network address in the scripts is
localhost, so no research data leaves it. Pseudonymisation happens in the cleaning step and the key stays outside the vault. Every run is logged with its model and version, and one command drafts the AI-use disclosure reviewers ask for. - The researcher leads, GenAI assists. The split is enforced in the files rather than the guidance: the model writes
suggested_*.csv, you writereviewed_*.csv, and only rows you markedacceptedoreditedreach any table or figure. Scripts never overwrite a human-reviewed file. - From mechanical extraction to abductive discovery. Theme suggestions arrive as questions. A theme exists only when you can state it, show what supports it, show what complicates it, and sign it. The chat lets you interrogate a pattern and check a quote against the source, and the negative-case and saturation templates keep the back-and-forth honest.
Underneath all four sits the technical point: a chatbot has no memory of your dataset and cannot run twenty analytic steps in sequence. The vault sidesteps that by dividing the work into small, reviewed tasks with persistent files, so the model is only ever asked to do what it can do.
None of this makes a study congruent on its own. Congruence is the researcher's achievement, and no tool confers it. What the vault removes is the technical excuse: the reflexive memos, the audit trail, the human-first data contract and the disclosure paragraph are already in place, so what is left to supply is the interpretive work that was always yours.
Try it todayA prompt that keeps the model in its place
If you already work with a local model, this starting instruction keeps it in the interlocutor role. It mirrors the rules built into QualiVahti's own prompts.
System prompt · first-cycle coding
You are helping me with first-cycle qualitative coding. You suggest; I decide. Work only from the excerpt and codebook I give you, nothing else. For each excerpt, offer one to three short candidate codes (1 to 4 words, close to the participant's own words). For each, quote the words that triggered it, and say plainly what makes you unsure or what I need to judge. Do not invent participant details or guess demographics. Do not name themes; a theme is a claim only I can make. If an excerpt contradicts an obvious pattern, say so. End by stating what needs my judgement.
Give it one excerpt at a time, and review every suggestion against the transcript before you keep it.
Related guidesRead next
Further readingSources worth your time
- Nguyen-Trung and colleagues (2026), Towards a methodologically congruent framework for GenAI use in nonpositivist qualitative research. International Journal of Social Research Methodology.
- Jowsey, Braun, Clarke, Lupton and Fine (2025), We reject the use of generative artificial intelligence for reflexive qualitative research. Qualitative Inquiry.