In Practice: Ask for the process, not the answer
Before asking an AI agent for an answer, ask it for the best way to get one. On 901 comments that researchers wrote about peer review, the agent interviews you, helpers lay out the options, a reviewer tests them on real comments, you choose, and the method is saved as a skill before anything is coded. Then it runs twice, and a sample coded by hand shows how far it repeats.

Downloads
AI for Research Efficiency, In Practice, with Douglas Hutchings. Narration: an AI-generated voice (ElevenLabs).
One research question, asked two ways. Asked for the answer, three fresh agent sessions read the same 901 survey comments and came back with their own themes, counts and headlines. Asked for the best way to find out what the researchers think, an agent interviewed the researcher, three helpers laid out the options, a reviewer tested them on real comments, the researcher chose, and the method was saved as a skill before anything was coded. Then it ran twice, in two separate sessions, and the studio measured how far the coding repeated. Recorded on 28 October 2026 on the studio's Linux server with Claude Code 2.1.312 and Codex CLI 0.164.0, each run in a folder of its own. Antigravity was not recorded (see "Not confirmed yet"). The same steps work on any task you would otherwise ask an agent to "just analyze".
1. Two ways to ask
The request for an answer (the film's three naive sessions: Claude Code once, Codex twice):
Analyze the comments in peer-review-2016/ comments.csv and tell me what researchers think about open peer review.The request for the process. Switch to plan mode first (section 2), then:
The file peer-review-2016/ comments.csv holds researchers' answers to the last question of a 2016 survey on open peerreview: "Do you have any other comments? ". What is the best way to find out what these researchers think, in a way Icould defend in a methods section and repeat next month? Don't analyze yet. Interview me first using theAskUserQuestion tool: dig into the hard parts I might not have considered.After the interview, the options and the review (in the film it went in as feedback on the agent's first plan):
Before we choose, research the options. Start three subagents, each researching a different approach and writing itscase to options/ . Then start a fourth subagent as a reviewer that tries each option on a sample of the real commentsand lists only the problems that would change the result. Wait for all four, then show me a comparison and ask me tochoose. Don't start the analysis.Then choose, and freeze the choice before anything is coded:
I'll take <the option you chose>. Before coding anything, write the process down as a skill in.agents/ skills/ survey-coding/ : SKILL.md, references/ protocol.md with a decision log, and the codebook, built from aseeded random sample that leaves out the ids in validation/ held-out-ids.txt. Copy the folder to.claude/ skills/ survey-coding/ . Then code the first 50 comments and stop so I can check them.Check the first batch yourself, then let it run. The researcher's check in the film, word for word:
That looks right. Keep the 17 codes and your double-blind rule, and run the random pilot. One change before thefreeze: three runs per comment cost $5.12 for these 50, so code with one run per comment and log it in the decisionlog; a second, separate run in a fresh session will measure how far it repeats. If the random pilot shows no newproblem, freeze the codebook, code the rest in batches following the protocol, and tell me when run 1 is done.Then, in a fresh session with nothing but the saved skill:
Use the survey-coding skill to code every comment in peer-review-2016/ comments.csv into coding/ run-2.csv.Keep it to three helpers and one reviewer: Anthropic measured teams of agents using about 15 times the tokens of a chat (its multi-agent research post, 2025). The tools' built-in team modes (Claude Code's dynamic workflows, Antigravity's /boost and /teamwork-preview) are shortcuts on paid plans, not requirements: every step above works in plain words.
The researcher's answers to the interview were written in advance by the studio from the owner's stated method and the film's brief, and typed by the recorder; where the brief did not cover a question, the researcher took the agent's recommended answer.
2. Plan mode and the interview, in each tool
| Claude Code | Codex CLI | Antigravity CLI | |
|---|---|---|---|
| Plan mode | Shift+Tab until the status bar shows ⏸ plan mode on, or /plan before a prompt | Shift+Tab, or /plan | Shift+Tab to plan, or /plan; agy --mode=plan to start in it |
| The interview | in your prompt: "Interview me in detail using the AskUserQuestion tool" ("For larger features, have Claude interview you first") | in your prompt ("Ask Codex to interview you ... Tell it to challenge your assumptions") | /grill-me: "the agent asks one question at a time and recommends an answer for each"; /plan /grill-me <task> combines the two |
| Approve the plan | choose a "Yes" option, or "Tell Claude what to change" and Shift+Tab to approve with your feedback (what the film did) | ask it to revise the plan in chat, then go on | comment on the plan, then Proceed |
The keys are the same on Windows (Windows Terminal) and on a Mac (Terminal). Read on each vendor's own pages on 24 and 27 October 2026; versions change often.
3. The skill: survey-coding
A skill is a folder with a SKILL.md file that tells an agent how to do one kind of task; all three tools read the same format (the open Agent Skills standard). The one on this page codes open-ended survey answers so the result can be defended and repeated: a codebook built from a seeded random sample and frozen in a written protocol before any coding, every answer coded against it, a second independent run, and agreement measured per code.
survey-coding/ SKILL.md the procedure (steps 0 to 8) references/ protocol.md the protocol template, with a decision log references/ codebook.md the codebook template scripts/ agreement.py percent agreement and Cohen's kappa, per code (Python, standard library only)Download the folder, survey-coding.zip, and put one copy where each tool looks, inside your project folder: .agents/skills/ (Codex and Antigravity) and .claude/skills/ (Claude Code). Use a copy, not a link, on Windows.
Windows
Windows (PowerShell, in your project folder, with survey-coding unzipped beside it):
New-Item -ItemType Directory -Force .agents\ skills, .claude\ skills | Out-NullCopy-Item -Recurse survey-coding .agents\ skills\Copy-Item -Recurse survey-coding .claude\ skills\Mac
Mac (Terminal, in your project folder):
mkdir -p .agents/ skills .claude/ skillscp -R survey-coding .agents/ skills/cp -R survey-coding .claude/ skills/Run it: in Claude Code, /survey-coding, or ask for it ("Use the survey-coding skill..."); in Codex, $survey-coding or /skills; in Antigravity, /survey-coding (it turns each skill into a command). Before you trust it, try it in a fresh session on a few answers you know well.
What the recorded run's own skill did differently. The run wrote its skill from the conversation, and it went further than this page's: it codes each comment with a fresh call to Claude (claude -p, no tools, no settings, no session) so that no comment's coding depends on another's, archives every raw answer as the record, codes a stance for each of the survey's seven parts of open peer review, and refuses to code the held-out comments until the person's hand codes exist. That makes it Claude-specific: Codex followed it step by step in the film's "next month" run, but its coding step calls Claude. This page's version codes in the session itself, in any of the three tools.
The skill's files, in full:
survey-coding/SKILL.md
---name: survey-codingdescription: "Codes open-ended survey answers in a way that can be defended and repeated: a codebook built from a seeded random sample and frozen in a written protocol before any coding, every answer coded against it, then a second independent run and a person's hand-coded sample to measure agreement per code. Use when asked to analyze, code, theme or summarize free-text survey answers or comments, or to repeat an earlier coding on new answers."--- # Survey coding A procedure for turning free-text answers into counts you can defend in a methods section and repeat next month. Themethod is fixed in `references/ protocol.md` before any answer is coded; the codes live in `references/ codebook.md`.`scripts/ agreement.py` measures how far two codings agree (Python 3.8 or later, standard library only). Work only in this project folder. Never send the answers to a website or another service, and never change the datafiles: write everything new under `coding/ `. ## 0. Where you are Read `references/ protocol.md` first. - If its status line says **FROZEN**, the method is settled: follow it exactly and go to step 5. Do not change the codebook, the sample or the rules; anything that cannot follow them goes in the decision log (step 4) and to the person.- If it is the blank template, start at step 1, and do not code any answer until step 4 is done. ## 1. Understand the task and count the answers 1. Ask the person, one question at a time, what they want to learn, who will read the result, and what they must be able to say about the method. Recommend an answer for each question.2. Find the file, the id column, the text column and any grouping column (a discipline, a stance, a language).3. Count the non-empty answers with a reader that keeps every answer as text. Words such as "None", "NA" and "N/ A" are answers, not missing values: in pandas use `keep_default_na= False`; Python's `csv` module keeps them by default.4. Compare your count with any count published for the same data. If they differ, find out why before going on.5. Note what else is in the answers: replies that only say "no" or "none", remarks about the survey itself, other languages, duplicates, web addresses or names. Decide with the person how each is handled, and write it down. ## 2. Lay out the options before choosing one If the person has not chosen a method, research the options before using any. Give each of up to three helpers (onesubagent each) a different approach, for example: a codebook built from a random sample and then applied to everyanswer; a word list or sentiment score; clustering or topic modeling. Each writes `coding/ options/ <approach>.md`:how it works, what it needs, what it costs, what it cannot see, and how its result could be checked. Then ask one morehelper to act as a reviewer: try each option on 20 to 30 real answers and report only the problems that would changethe result. Show the person a comparison and let them choose. Write the choice, the options and the reviewer's findingsin the protocol. ## 3. Build the codebook from a seeded random sample 1. Draw a random sample of answers for building codes (100 by default) with a fixed seed. Leave out the fillers agreed in step 1 and any ids in `validation/ held-out-ids.txt` (those are for the person's check). Write the seed, the size and the exact command in the protocol, so anyone can draw the same sample.2. Read the sample and propose codes in `references/ codebook.md`: a short name, a definition, when to use it, when not to, and an example of at most 15 words from the sample. An answer may take several codes. Keep a code for substantive points no other code covers ("other") and one for answers with nothing to code.3. Show the codebook to the person and revise it with them, until each code is easy to tell apart from the others. ## 4. Freeze the protocol Before coding the full set, fill in `references/ protocol.md` from its template and set its status to FROZEN with thedate. From then on: - No code is added, merged, split or renamed. An answer that fits nothing gets "other" and a note.- Any change of plan is a deviation. Log it in the protocol's decision log (date, what, why, what it affects, who agreed), and if it changes the codebook, start the coding again from the first answer.- Save this skill folder, with the frozen protocol and codebook, where every tool finds it: `.agents/ skills/ ` (Codex, Antigravity) and a copy in `.claude/ skills/ ` (Claude Code). ## 5. Code every answer 1. Code the answers in batches of about 50, in id order. For each answer write one row to `coding/ run-<n>.csv` with the columns `id`, `codes` (code ids separated by `;`), `evidence` (for each code, a phrase of at most 12 words quoted from the answer), `uncertain` (`yes` or empty) and `note`.2. Show the person the first batch and wait for their check before going on. After that, keep going and report progress.3. If you use helpers for batches, give each the frozen codebook and the same rules, and record which helper coded which ids.4. Check the file: one row per answer, every code id from the codebook, no answer missing. ## 6. Code again, independently The second run happens in a fresh session that has not seen the first: start a new session, invoke this skill, and codeevery answer into `coding/ run-<n+1>.csv` from the frozen protocol and codebook alone. Do not open the first run's fileuntil the second is complete. ## 7. Measure agreement Agreement between the two runs, on every answer: ```python scripts/ agreement.py coding/ run-1.csv coding/ run-2.csv --codebook references/ codebook.md --out coding/ agreement-runs.md``` Agreement with the person, on the held-out sample, once the person has coded it (`validation/ person-coding-sheet.csv`,same columns; the person codes without seeing either run): ```python scripts/ agreement.py coding/ run-1.csv validation/ person-coding-sheet.csv --codebook references/ codebook.md --ids validation/ held-out-ids.txt --out coding/ agreement-person.md``` The script reports, for each code, how often each side used it, the percent agreement and Cohen's kappa, and lists theanswers where the two sides differ. Read those answers. Compare each code's kappa with the threshold written in theprotocol before the run, and report the codes below it with a caveat. Tightening a definition after seeing agreement isa deviation: log it, and code again. ## 8. Report Write `coding/ report.md`: - How many answers, how they were read, and what was left out and why.- Counts and shares for each code, from run 1, with the agreement for that code beside it.- Results by group only for groups with at least 30 answers (or the minimum the protocol sets), with the counts shown.- The agreement tables, the threshold, and the codes that fell below it.- Every deviation from the protocol, in the order it happened.- Short quotes only (at most 15 words), none that names a person or holds a web address.- What the method cannot tell you (the sample's make-up, who chose to answer, the year). "The same result" for coding means a measured agreement rate between independent runs, not identical files. Say so inthe report.survey-coding/references/protocol.md
# Protocol: <the study, in a few words> **Status:** DRAFT <!-- set to: FROZEN on YYYY-MM-DD, before any answer is coded --> Fill in every field before the freeze. After it, change nothing above the decision log: record each change of planas a row of the log instead. ## The question - **What we want to learn:** <in the person's words>- **Who will read the result, and what they must be able to check:** <a methods section, a report, a committee>- **Data:** <file>, text column <...>, id column <...>, grouping columns <discipline, stance, language>- **Answers counted:** <n> non-empty answers on <date>, read with <the reader and its settings, e.g. pandas with keep_default_na= False>; published count for comparison: <n, source> <!-- explain any difference -->- **In scope:** <every non-empty answer / the rule for answers that only say "no" or "none">- **Handled separately:** <remarks about the survey itself, other languages, duplicates, answers with names or links> ## The method - **Approach:** <e.g. a codebook built from a random sample, then applied to every answer, then agreement measured>- **Options considered:** <each option, with the reason it was or was not chosen; see coding/ options/ >- **What the reviewer found, and what changed because of it:** <only problems that would change the result>- **Codebook sample:** <n> answers, seed <seed>, drawn with <the exact command>, leaving out the fillers and the ids in `validation/ held-out-ids.txt`- **Codebook:** `references/ codebook.md`, version <n>, <number> codes, frozen on <date>- **Coding unit:** one answer; zero or more codes per answer; a quoted phrase as evidence for each code- **Run 1:** <tool and version, date, who checked the first batch>- **Run 2:** a fresh session, from this protocol and the codebook alone: <tool and version, date>- **The person's check:** <n> held-out answers coded by <who>, before seeing either run, on <date> ## Agreement, decided before the runs - **Measures:** percent agreement and Cohen's kappa for each code (present or absent), between run 1 and run 2 on every answer, and between run 1 and the person on the held-out answers (`scripts/ agreement.py`).- **Threshold:** a code is reported without a caveat if its kappa is at least <value chosen now, before seeing any result>. Below it: <reported with a caveat / merged with <code> by a logged deviation, and both runs coded again>.- **Codes too rare to judge:** fewer than <n> answers with the code on either side; reported as such. ## Reporting - Counts and shares per code, from run 1, with each code's agreement beside it.- Results by <group> only for groups with at least <30> answers; the counts shown.- Quotes of at most <15> words; none that names a person or holds a web address.- Limits to state: <who was asked, who chose to answer, the year, the sample's make-up>. ## Decision log Every decision after the first draft, and every deviation after the freeze, in the order it happened. | Date | Decision or deviation | Why | What it affects | Agreed by ||---|---|---|---|---|| <YYYY-MM-DD> | <e.g. Chose the codebook approach over a sentiment word list> | <the reviewer's test on 25 answers> | <the method> | <the person> || | | | | |survey-coding/references/codebook.md
# Codebook: <the study>, version <n> **Status:** DRAFT <!-- set to: FROZEN on YYYY-MM-DD, with the protocol -->Built on <date> from <n> answers (seed <seed>; see `protocol.md`). After the freeze, codes are only applied: none isadded, merged, split or renamed without a row in the protocol's decision log. Rules for every code: - An answer can take several codes. C99 is always alone.- Code what the answer says, not what its author might think.- The example is quoted from the sample, at most 15 words, and names no person. | Code | Name | Definition | Use when | Do not use when | Example ||---|---|---|---|---|---|| C01 | <short name> | <one sentence> | <the signs that it applies> | <the nearest code it could be confused with, and how to tell them apart> | "<at most 15 words>" || C02 | | | | | || C98 | Other | A substantive point that no code above covers | the answer says something about the question, and no code fits | a code above fits, even partly | || C99 | Nothing to code | The answer says nothing about the question | "no", "none", "thanks", a blank mark | the answer makes any point at all | | `scripts/ agreement.py` reads the code ids from the first column of this table (lines that start with `| C`).survey-coding/scripts/agreement.py
"""agreement.py: how far two codings of the same answers agree, code by code. python scripts/ agreement.py A.csv B.csv [--codebook references/ codebook.md] [--ids held-out-ids.txt] [--out agreement.md] [--disagreements disagreements.csv] A and B are CSV files with an `id` column and a `codes` column (code ids separated by ";"), for example two runs ofthe same coding, or a run and a person's coding sheet. An optional `uncoded` column marks answers a coder could notcode: those answers are left out of the comparison and counted. For each code (from the codebook's table, lines starting with "| C", plus any code found in the files) it reports howmany answers each side gave the code, the percent agreement and Cohen's kappa for "has the code / has not". Kappa isagreement corrected for the agreement two coders would reach by chance with the same rates: 1 is perfect, 0 is nobetter than chance. It is not defined when both sides never (or always) use a code, and it is unstable for rarecodes, so the counts are shown beside it. Overall: the share of answers with exactly the same set of codes, and thepercent agreement over every answer-and-code decision. Python 3.8 or later, standard library only. Reads UTF-8 with or without a byte-order mark (Excel's "CSV UTF-8")."""import argparse, csv, re, sysfrom pathlib import Path def read_codes(path): rows = {} with open(path, encoding= "utf-8-sig", newline= "") as f: reader = csv.DictReader(f) missing = {"id", "codes"} - set(reader.fieldnames or []) if missing: sys.exit(f"{path}: needs the columns id and codes (missing: {', '.join(sorted(missing))})") for r in reader: i = (r.get("id") or "").strip() if not i: continue if i in rows: sys.exit(f"{path}: the id {i} appears twice") codes = {c.strip() for c in re.split(r"[;, ]", r.get("codes") or "") if c.strip()} uncoded = bool((r.get("uncoded") or "").strip()) rows[i] = (codes, uncoded) return rows def codebook_ids(path): ids = [] for line in Path(path).read_text(encoding= "utf-8-sig").splitlines(): m = re.match(r"^\|\s*(C\d+)\s*\|", line) if m and m.group(1) not in ids: ids.append(m.group(1)) return ids def kappa(a, b, c, d): """Cohen's kappa for a 2x2 table: a = both have the code, b = only A, c = only B, d = neither.""" n = a + b + c + d if n == 0: return None, None po = (a + d) / n pa, pb = (a + b) / n, (a + c) / n pe = pa * pb + (1 - pa) * (1 - pb) return po, (None if pe >= 1 else (po - pe) / (1 - pe)) def fmt(x, pct= False): if x is None: return "n/ a" return f"{x * 100:.1f}%" if pct else f"{x:.2f}" def main(argv= None): ap = argparse.ArgumentParser(description= __doc__.split("\n")[0]) ap.add_argument("a"); ap.add_argument("b") ap.add_argument("--codebook", help= "the codebook, to list every code (also the ones neither side used)") ap.add_argument("--ids", help= "compare only these ids (one per line)") ap.add_argument("--out", help= "also write the report (Markdown) here") ap.add_argument("--disagreements", help= "write every answer-and-code disagreement here (CSV)") args = ap.parse_args(argv) A, B = read_codes(args.a), read_codes(args.b) ids = set(A) & set(B) notes = [] if args.ids: wanted = {l.strip() for l in Path(args.ids).read_text(encoding= "utf-8-sig").splitlines() if l.strip()} lacking = sorted(wanted - ids, key= lambda s: (len(s), s)) if lacking: notes.append(f"{len(lacking)} of the {len(wanted)} listed ids {'is' if len(lacking) == 1 else 'are'} missing from one file: {', '.join(lacking[:20])}") ids & = wanted else: only_a, only_b = len(set(A) - set(B)), len(set(B) - set(A)) if only_a or only_b: notes.append(f"{only_a} ids only in {args.a}, {only_b} only in {args.b}: left out") uncoded = {i for i in ids if A[i][1] or B[i][1]} ids = sorted(ids - uncoded, key= lambda s: (len(s), s)) if uncoded: notes.append(f"{len(uncoded)} {'answer' if len(uncoded) == 1 else 'answers'} marked uncoded on either side: left out") if not ids: sys.exit("no answers to compare") codes = codebook_ids(args.codebook) if args.codebook else [] found = sorted(set().union(*(A[i][0] | B[i][0] for i in ids)) - set(codes)) if args.codebook and found: notes.append(f"codes not in the codebook: {', '.join(found)}") codes += found lines = [f"# Agreement: `{Path(args.a).name}` and `{Path(args.b).name}`", "", f"{len(ids)} answers compared." + (" " + " ".join(n + "." for n in notes) if notes else ""), "", f"| Code | Answers with it in {Path(args.a).name} | in {Path(args.b).name} | Agreement | Cohen's kappa |", "|---|---|---|---|---|"] dis, kappas, same_decisions = [], [], 0 for code in codes: a = sum(1 for i in ids if code in A[i][0] and code in B[i][0]) b = sum(1 for i in ids if code in A[i][0] and code not in B[i][0]) c = sum(1 for i in ids if code not in A[i][0] and code in B[i][0]) d = len(ids) - a - b - c po, k = kappa(a, b, c, d) same_decisions += a + d if k is not None: kappas.append(k) lines.append(f"| {code} | {a + b} | {a + c} | {fmt(po, True)} | {fmt(k)} |") dis += [(i, code, "yes" if code in A[i][0] else "", "yes" if code in B[i][0] else "") for i in ids if (code in A[i][0]) != (code in B[i][0])] exact = sum(1 for i in ids if A[i][0] == B[i][0]) / len(ids) pooled = same_decisions / (len(ids) * len(codes)) if codes else None lines += ["", f"- Answers with exactly the same codes: {fmt(exact, True)}", f"- Agreement over every answer-and-code decision: {fmt(pooled, True)}", f"- Mean kappa over the {len(kappas)} codes where it is defined: " f"{fmt(sum(kappas) / len(kappas)) if kappas else 'n/ a'}", f"- Disagreements: {len(dis)} answer-and-code pairs" + (f" (listed in `{Path(args.disagreements).name}`)" if args.disagreements else "")] report = "\n".join(lines) + "\n" print(report) if args.out: Path(args.out).write_text(report, encoding= "utf-8") if args.disagreements: with open(args.disagreements, "w", encoding= "utf-8", newline= "") as f: w = csv.writer(f) w.writerow(["id", "code", Path(args.a).name, Path(args.b).name]) w.writerows(dis) return 0 if __name__ == "__main__": sys.exit(main())4. The protocol and its decision log
The protocol is the method written down before the results exist, as a preregistration is: the question, the data and how it was counted, the method and the options turned down, the codebook's sample and seed, the two runs, the agreement measures and the threshold you accept, decided before you see any figure. After the freeze, nothing above the decision log changes; every change of plan becomes a row of the log, with its date, its reason and who agreed. Plans do change: a review of every preregistered study in one psychology journal found that all of them had departed from their plan (Claesen et al., 2021).
The film's run kept 35 rows in its log, each marked R (the researcher) or C (the agent). Two changes came before the freeze: one coding call per comment instead of three with a majority vote (the researcher's, for cost: the first pilot's three calls a comment cost $5.12 for 50 comments at list prices), and two codes added after a random pilot of 50 comments put 28% of the substantive ones under "other" (EVIDENCE_FIRST, "test open peer review before adopting it", and NO_IMPROVEMENT, "the current system works"). The codebook was then frozen with 19 reason codes and three fixed ones. The template is survey-coding/references/protocol.md.
5. The practice folder
The practice folder, process-practice.zip (about 1.2 MB unzipped). Two surveys of researchers, both under CC BY 4.0:
peer-review-2016/: the 901 answers to "Do you have any other comments?" and the 456 answers to "If you do not agree, why?" from the OpenAIRE Open Peer Review Survey 2016 (Ross-Hellauer, Schmidt and Deppe; Zenodo, doi.org/10.5281/zenodo.439531 (opens in a new tab)), each with the respondent's discipline; the survey's readme and questionnaire.open-data-2023/: 2,409 researchers' reasons for their stance on a national open-data mandate, from the State of Open Data Survey 2023 (Springer Nature, Figshare and Digital Science; figshare, doi.org/10.6084/m9.figshare.24517123.v2 (opens in a new tab)). The published file also holds each respondent's device location and institution name; neither is in the practice folder (itsREMOVED.mdlists everything that was taken out, and why).
To open a CSV in Excel on Windows: Data > From Text/CSV, and choose UTF-8 (the 2023 file has Chinese and Japanese answers). On a Mac, Numbers opens it directly. MANIFEST.csv lists every file with its source, license, checksum and what was changed; README.md gives a credit line to copy if you share them.
What to keep in mind about the 2016 survey: it over-represents the earth and environmental sciences (1,274 of its 3,062 respondents, after one publisher's mailing list brought in almost a third of the responses in a single day), the authors allow for "some self-selection", and it dates from 2016. In the film's run only four fields had 30 or more substantive comments, so results by discipline can compare those four at most.
6. Measuring agreement
Coding a comment is a judgment, so two runs will not give identical files; what you can report is how often they agree. scripts/agreement.py compares two codings of the same answers, code by code:
python scripts\ agreement.py coding\ run-1.csv coding\ run-2.csv --codebook references\ codebook.md(on a Mac, python3 and forward slashes). For each code it gives how many answers each side used it for, the percent agreement, and Cohen's kappa: agreement after discounting what two coders would reach by chance with the same rates (1 is perfect, 0 is no better than chance). Kappa is unstable for rare codes, so read it beside the counts. Choose the kappa you will accept before you see any figure, and write it in the protocol.
In the film's run (computed by the studio from the two runs' files, 28 October 2026): run 1 and run 2 each coded the 821 comments outside the 80 held out for a hand check, one fresh call per comment, in about 15 minutes each ($33.86 and $26.32 at list prices, as claude -p reported them; on a monthly plan these draw on the plan's limits instead). They made the same decision on 99% of 25,451 coding decisions (821 comments, 31 each: the non-answer flag, a stance for each of eight parts, 22 codes). Kappa averaged 0.94 over the 22 codes (lowest 0.84, for "other", the catch-all) and ran from 0.91 to 0.97 for the stances; the non-answer flag agreed every time. Still, 81% of comments were coded identically in every field: about one in five differed somewhere. The run's own report agrees: kappa 0.83 or more for every field, and 81% of comments identical.
What agreement does not show. Two runs of the same model with the same codebook can repeat the same mistakes. Agreement shows the method repeats; whether the codes are right is the next check: a sample you code by hand, before you look at either run, compared with the same script and --ids. The film's held-out 80 comments are drawn for that check; it has not been made yet.
For a sense of scale: in one study of closed categories, two ChatGPT runs agreed on 91% and 97% of labels (at two settings), and trained annotators on 79% (Gilardi, Alizadeh and Kubli, 2023). In another, the same instructions in separate ChatGPT conversations produced open coding schemes with 5 to 13 categories (Bijker et al., 2024).
7. One trap to check
Count your answers with a reader that keeps every answer as text. Read with pandas' default settings, the 2016 comments lose 18 answers ("None" 13 times, "NA" twice, "N/A" twice, "n/a" once), which pandas treats as missing: 901 becomes 883. Use pd.read_csv(..., keep_default_na=False), or Python's csv module, and compare your count with the one the authors published (901 in the paper). None of the film's recorded sessions fell into it: every one counted 901.
8. The line not to cross
- Your own work, and data you may share with these services. Protected data (identifiable participants, health or student records, anything under an agreement) stays out of cloud tools: episode 9 covers your campus's rules and the local options.
- Claim discovery modestly: helpers widen the menu, and you choose. In one study, research ideas from language models were rated more novel than experts' ideas, and the gap closed once the ideas were carried out (Si, Yang and Hashimoto, 2024; Si, Hashimoto and Yang, 2025).
- A reviewer asked to find problems will usually find some: "A reviewer prompted to find gaps will usually report some, even when the work is sound" (Claude Code's best practices). Give it something real to test against, and ask only for problems that would change the result.
- Watch the usage: a skill that makes one model call per answer multiplies quickly. In the film, the plan's weekly limit stopped the run for two hours during a pilot; it carried on by itself when the limit reset.
The run, in numbers
| The three naive answers | Five broad themes shared by all three (matched with the tools' names hidden). One answer (Claude Code's) gave rough counts by keyword, counted 176 empty answers, and made double-blind review a theme of its own; the two Codex sessions gave six themes each and no counts. Headlines: "mixed and mostly conditional"; "divided and depend on the form of openness"; "divided, often conditional" |
| The interview | Eight questions in two rounds; one answer changed the plan: next month's survey is on another topic, so what must repeat is the procedure, not a list of themes |
| The options and the review | Three helpers: an agent coding against a frozen codebook; people coding by hand (about 45 to 58 hours of the researcher's time per survey); a topic model. The reviewer, on 60 comments outside the held-out set: one for-or-against code does not fit; how requests for double-blind review are counted moves "oppose" from 24% to 31%; the comments were analysed and published in 2017 (PLOS ONE); the topic model's clusters barely repeated (agreement 0.02 to 0.12) |
| The codebook | 19 reason codes and three fixed codes, from seeded batches of 200, 100 and 100 comments (seed 20261028), the held-out ids left out; frozen as v1 after two pilots |
| Run 1 and run 2 | 821 comments each, one call per comment, about 15 minutes each |
| Agreement between the runs | 99% of 25,451 decisions; kappa 0.94 on average (lowest: "other", 0.84); 81% of comments identical in every field |
| Next month (2023 survey, Codex) | The same skill: it confirmed the stance target with the researcher, reserved 80 answers for a hand check, drafted 24 reason codes from 400 answers, and stopped for the researcher's review, as the protocol says |
Why this works: the evidence
- The same question gets different answers. Anthropic: "Even with temperature set to 0, the results will not be fully deterministic"; OpenAI: "Determinism is not guaranteed". None of the three tools' settings pages lists a temperature setting (searched 24 October 2026).
- People do it too. Twenty-nine teams given one data set and one question estimated the effect from 0.89 to 2.93 (odds ratios); 20 teams found it significant and 9 did not. The authors: "defensible, yet subjective, analytic choices influence research results" (Silberzahn et al., 2018). A 2026 preprint finds that AI analysts' "independent runs frequently reverse whether the hypothesis is judged supported" (Bertran, Fogliato and Wu; not peer-reviewed when read).
- Fixing the plan first is what researchers already do. Preregistration: to "define the research questions and analysis plan before observing the research outcomes" (Nosek et al., 2018). In psychology, papers accepted before their results were known reported a positive first result 44% of the time, against 96% for standard papers (Scheel, Schijen and Lakens, 2021).
Not confirmed yet
- Antigravity was not recorded. On the studio's server the account's own Antigravity settings skip every approval (the setting the
--dangerously-skip-permissionsflag sets), and a separate installation with approvals on stops at Antigravity's first-run "Terms of Service & Data Use" screen. Both are the owner's to decide, so the third naive session is a second Codex session, and Antigravity's two takes wait for a run by the owner. - A person's hand-coded sample is the next check of the film's coding: the 80 held-out comments are drawn and kept out of everything; nobody has coded them yet.
- Tested on the studio's Linux server only: the PowerShell lines above, Windows' handling of the skill folders, and Excel's reading of the CSVs are not yet confirmed on a Windows PC or a Mac.
- Whether a Windows directory junction works as a skill folder for Claude Code is not documented (hence the copy).
- Whether Codex and Antigravity read
.claude/skills/is not documented; Claude Code does not read.agents/.
Sources
- The data: OpenAIRE Open Peer Review Survey 2016 (opens in a new tab) (CC BY 4.0); State of Open Data Survey 2023 (opens in a new tab) (CC BY 4.0); the license (opens in a new tab).
- The authors' analysis: Ross-Hellauer, Deppe and Schmidt (2017), Survey on open peer review (opens in a new tab), PLOS ONE 12(12): e0189311 (CC BY 4.0).
- The recorded runs (28 October 2026): the studio's recordings and the runs' own files, kept with the film's project; the agreement figures computed by the studio from the runs' coded files.
- The tools (read 27 October 2026): Claude Code best practices (opens in a new tab), permission modes (opens in a new tab), skills (opens in a new tab); Codex best practices (opens in a new tab), slash commands (opens in a new tab), skills (opens in a new tab); Antigravity plan (opens in a new tab), /grill-me (opens in a new tab), modes (opens in a new tab), skills (opens in a new tab); the Agent Skills specification (opens in a new tab).
- The evidence: Anthropic, temperature (opens in a new tab); OpenAI, seed (opens in a new tab); Bijker et al. 2024 (opens in a new tab); Silberzahn et al. 2018 (opens in a new tab); Bertran, Fogliato and Wu 2026 (opens in a new tab) (preprint); Anthropic's multi-agent research system (opens in a new tab); Nosek et al. 2018 (opens in a new tab); Scheel, Schijen and Lakens 2021 (opens in a new tab); Claesen et al. 2021 (opens in a new tab); Gilardi, Alizadeh and Kubli 2023 (opens in a new tab); Si, Yang and Hashimoto 2024 (opens in a new tab); Si, Hashimoto and Yang 2025 (opens in a new tab).
Corrections
None so far. If you find something wrong, email doug,@douglashutchings.com.
Transcript
Every spoken line, by chapter
Three answers, one question
Three agent sessions got the same nine hundred and one survey comments, and the same request: tell me what researchers think.
They agreed on five broad themes. Only one put numbers on them, and only one made double-blind review a theme of its own.
With the method chosen and written down first, two separate runs agreed on ninety-nine percent of their coding decisions.
AI for Research Efficiency, In Practice. Ask for the process, not the answer.
In this film, an agent helps you choose the best way to do a research task, and saves it as a skill for next month.
It builds on episodes three, four, seven and eight.
Why the answers differ
Ask twice and the answers differ. In one study, ChatGPT given the same instructions in separate conversations produced coding schemes with five to thirteen categories.
Anthropic and OpenAI both document this, and none of the three tools lists a setting to stop it.
People vary too. Twenty-nine teams of analysts, given one data set and one question, produced estimates from zero point eight nine to two point nine three: twenty found a significant effect, and nine did not.
A twenty twenty-six preprint finds that A I analysts' independent runs "frequently reverse whether the hypothesis is judged supported."
1. Ask for the process
So begin with a different question, in plan mode: Shift and Tab, or slash plan, in all three tools.
What is the best way to find out what these researchers think, in a way I could defend in a methods section and repeat next month? Don't analyze yet.
Then let it interview you. In Claude Code and Codex you ask for the interview in plain words; Antigravity has a command for it, slash grill me.
Here it asked eight questions. One answer changed the plan: next month's survey is on another topic, so the procedure, not a list of themes, is what must repeat.
2. Lay out the options
Next, three helpers each research one way to do the job, side by side.
One made the case for an agent coding against a fixed codebook, one for people coding by hand, and one for a topic model.
Keep the team small: Anthropic measured teams of agents using about fifteen times the tokens of a chat.
3. Test them on real comments
Then a reviewer tries each option on a sample of the real comments, and reports only the problems that would change the result.
Put that last part in your request: Claude Code's guide warns that a reviewer asked for gaps will usually report some, even when the work is sound.
On sixty real comments, it found that one for-or-against code does not fit, and that how requests for double-blind review are counted moves opposition from twenty-four to thirty-one percent.
It also found that the survey's authors had published an analysis of these same comments, in twenty seventeen.
4. Choose, and write it down
Now you choose. Here, the agent codes against a codebook: coding by hand would take about fifty hours, and the topic model's clusters barely repeated.
Before a single comment is coded, the agent writes the method down: a protocol with a decision log, and a codebook of nineteen reason codes.
Researchers call this preregistration. Plans still change, so each change goes in the log: in one journal, a review found that every preregistered study had departed from its plan.
This run changed two things before the freeze: one call per comment instead of three, to keep the cost down, and two new codes that a random pilot showed were missing.
Then it saves everything as a skill: a folder in dot agents slash skills for Codex and Antigravity, with a copy in dot claude slash skills for Claude Code.
5. Run it, then run it again
Check the first batch yourself, then let it run.
Run one coded eight hundred and twenty-one comments, each in a fresh call, in about fifteen minutes.
Then a fresh session, with nothing but the saved skill, codes every comment again.
6. Check it against something outside the agent
Here, the two runs agreed on ninety-nine percent of their coding decisions, and kappa, which discounts agreement by chance, averaged zero point nine four. Still, about one comment in five was coded differently somewhere.
That shows the method repeats. It does not show the codes are right: for that, compare them with a sample you code by hand.
So for a judgment like this one, the same result means an agreement rate you measure and report.
The paper is a check too: it counts nine hundred and one comments, as the file does, and the view it reports, double-blind review to cut bias, is the run's code for bias about authors, in fifty-five comments.
One trap: open the file with pandas, a popular Python library, on its default settings, and answers like None and N A become blanks. Nine hundred and one turns into eight hundred and eighty-three.
Another field, and next month
By discipline, four fields have thirty or more substantive comments here, and their top reasons differ, often by just a few comments.
Read that with the survey's limits in view: one thousand two hundred and seventy-four of its three thousand and sixty-two respondents are earth and environmental scientists. The authors allow for some self-selection, and the survey dates from twenty sixteen.
And next month looks like this: the same skill, in Codex, on a newer survey of about two thousand four hundred researchers' reasons for their stance on a national open-data mandate. It drafted twenty-four reason codes, and stopped for the researcher's review, as the protocol says.
The line not to cross
Use this on your own work, and on data you may share with these services; episode nine covers protected data.
And claim discovery modestly: helpers widen the menu, and you choose. In one study, ideas from language models were rated more novel than experts' ideas, and lost that edge once carried out.
Try it
Pause here and try it. Before your next analysis, ask your agent: what is the best way to do this? Don't do it yet.
Review and next
So: ask for the way, test the options, choose, write it down, and measure how far it repeats.
The skill and the practice folder are on the companion page.
This shelf of films was planned the same way: helpers researched which films would help researchers most, and a person makes the call.
Next on this shelf: make a slide deck that looks like yours.
