CCPR Workshop · UCLA
$ claude ▍
Using Claude Code for research
Jake Anderson · Economics, UCLA
10/28/2026
−100
−50
Human
+50
+100
2000
2005
2010
2015
2020
2025
Handwritten digits, speech
Images
Reading, language tests
GPQA Diamond
PhD science questions
GDPval
work tasks from 44 jobs
ARC-AGI-2
visual puzzles
OSWorld
using a computer
Scale from Kiela et al. (2021): −100 = first recorded score, 0 = human level. Gray: 12 benchmarks from Our World in Data, 1998–2023. Color: best score so far (Epoch AI), rescaled the same way by me. Human level: PhD experts 65% (GPQA), as good as an expert half the time (GDPval), public 66% (ARC-AGI-2), people 72% (OSWorld).
0%
25%
50%
75%
100%
2023
2024
2025
2026
2027
PhD experts in the field, 65%
Random guessing, 25%
GPT-4, 36%
Claude 3.5 Sonnet, 54%
o1, 77%
Gemini 2.5 Pro, 84%
Gemini 4 Argon, 96%
OpenAI
Anthropic
Chinese labs
Others
Best so far
325 model versions and settings
GPQA Diamond: 198 multiple-choice questions in biology, chemistry, and physics. Data: Epoch AI.
Writing tasks, 453 professionals
Noy & Zhang 2023, Science
40% less time
Software, 3 firms, 4,867 developers
Cui et al. 2025, Management Science
26% more tasks done
Consulting, tasks AI can do, 758 consultants
Dell'Acqua et al. 2023, HBS
25% faster
Customer support, 5,172 agents
Brynjolfsson, Li & Raymond 2025, QJE
15% more issues solved per hour
Consulting, a task AI can't do, same study
Dell'Acqua et al. 2023, HBS
19 points less often right
Experienced developers, 16 people
METR 2025
19% slower
Their forecast
before the study
24% faster
Measured
randomized, 246 tasks
19% slower
Their guess
after the study
20% faster
← less time
more time →
16 experienced open-source developers on their own projects, early-2025 tools (Cursor with Claude 3.5/3.7 Sonnet). A 2026 follow-up with newer tools points to a speedup, but METR calls that weak evidence.
How a session felt is not always calibrated with true productivity
Anthropic, "How AI agents shape experts' judgment calls," Oct 2026 · animation from Alex Tamkin's post on X
Anthropic, "How AI agents shape experts' judgment calls," Oct 2026 · animation and posts from Alex Tamkin on X
We have successfully transitioned to new technologies in the past
Machine code
10101001 10111110 01001111 11110100
10101001 00000001 01111011 11111101
10010001 00000000 01000011 11111101
01010010 10000000 00000000 00010011
01110001 00000000 00001000 00010100
01010100 00000000 00000000 11101011
01010001 00000000 00000100 00000000
10010111 11111111 11111111 11111001
00001011 00000000 00000010 01110011
10101010 00010100 00000011 11100000
01110001 00000000 00001000 00010100
01010100 11111111 11111111 01101010
00001011 00010011 00000000 00000000
10101001 01000001 01111011 11111101
10101000 11000010 01001111 11110100
11010110 01011111 00000011 11000000
Assembly
fib: stp x20, x19, [sp, #-32]!
stp x29, x30, [sp, #16]
add x29, sp, #16
mov w19, #0
subs w20, w0, #2
b.lt done
loop: sub w0, w0, #1
bl fib
add w19, w19, w0
mov x0, x20
subs w20, w0, #2
b.ge loop
done: add w0, w0, w19
ldp x29, x30, [sp, #16]
ldp x20, x19, [sp], #32
ret
I don't need to worry about binary anymore. I trust the assembler to turn each line into the right 32 bits.
Machine code
10101001 10111110 01001111 11110100
10101001 00000001 01111011 11111101
10010001 00000000 01000011 11111101
01010010 10000000 00000000 00010011
01110001 00000000 00001000 00010100
01010100 00000000 00000000 11101011
01010001 00000000 00000100 00000000
10010111 11111111 11111111 11111001
00001011 00000000 00000010 01110011
10101010 00010100 00000011 11100000
01110001 00000000 00001000 00010100
01010100 11111111 11111111 01101010
00001011 00010011 00000000 00000000
10101001 01000001 01111011 11111101
10101000 11000010 01001111 11110100
11010110 01011111 00000011 11000000
Machine code
Assembly
fib: stp x20, x19, [sp, #-32]!
stp x29, x30, [sp, #16]
add x29, sp, #16
mov w19, #0
subs w20, w0, #2
b.lt done
loop: sub w0, w0, #1
bl fib
add w19, w19, w0
mov x0, x20
subs w20, w0, #2
b.ge loop
done: add w0, w0, w19
ldp x29, x30, [sp, #16]
ldp x20, x19, [sp], #32
ret
C
int fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
fib(46) 1,836,311,903
fib(47) -1,323,752,223
I don't need to worry about registers anymore. I trust the compiler to choose them and save them.
But if I forget how numbers are stored, fib(47) comes back negative.
Machine code
10101001 10111110 01001111 11110100
10101001 00000001 01111011 11111101
10010001 00000000 01000011 11111101
01010010 10000000 00000000 00010011
01110001 00000000 00001000 00010100
01010100 00000000 00000000 11101011
01010001 00000000 00000100 00000000
10010111 11111111 11111111 11111001
00001011 00000000 00000010 01110011
10101010 00010100 00000011 11100000
01110001 00000000 00001000 00010100
01010100 11111111 11111111 01101010
00001011 00010011 00000000 00000000
10101001 01000001 01111011 11111101
10101000 11000010 01001111 11110100
11010110 01011111 00000011 11000000
Assembly
fib: stp x20, x19, [sp, #-32]!
stp x29, x30, [sp, #16]
add x29, sp, #16
mov w19, #0
subs w20, w0, #2
b.lt done
loop: sub w0, w0, #1
bl fib
add w19, w19, w0
mov x0, x20
subs w20, w0, #2
b.ge loop
done: add w0, w0, w19
ldp x29, x30, [sp, #16]
ldp x20, x19, [sp], #32
ret
Machine code
Assembly
C
int fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
fib(46) 1,836,311,903
fib(47) -1,323,752,223
Java
static long fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
long[] results = {fib(10), fib(20), fib(30)};
long[] backup = results;
results[0] = 0;
backup[0] 0
I don't need to manage memory anymore, and the code is easier to read. I trust the compiler and Java to handle it.
But if I forget that some variables point to the same data, changing one changes the other.
Machine code
10101001 10111110 01001111 11110100
10101001 00000001 01111011 11111101
10010001 00000000 01000011 11111101
01010010 10000000 00000000 00010011
01110001 00000000 00001000 00010100
01010100 00000000 00000000 11101011
01010001 00000000 00000100 00000000
10010111 11111111 11111111 11111001
00001011 00000000 00000010 01110011
10101010 00010100 00000011 11100000
01110001 00000000 00001000 00010100
01010100 11111111 11111111 01101010
00001011 00010011 00000000 00000000
10101001 01000001 01111011 11111101
10101000 11000010 01001111 11110100
11010110 01011111 00000011 11000000
Assembly
fib: stp x20, x19, [sp, #-32]!
stp x29, x30, [sp, #16]
add x29, sp, #16
mov w19, #0
subs w20, w0, #2
b.lt done
loop: sub w0, w0, #1
bl fib
add w19, w19, w0
mov x0, x20
subs w20, w0, #2
b.ge loop
done: add w0, w0, w19
ldp x29, x30, [sp, #16]
ldp x20, x19, [sp], #32
ret
C
int fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
fib(46) 1,836,311,903
fib(47) -1,323,752,223
Machine code
Assembly
C
Java
static long fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
long[] results = {fib(10), fib(20), fib(30)};
long[] backup = results;
results[0] = 0;
backup[0] 0
Python
def fib(n):
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
df = pd.DataFrame(columns=["n", "n_squared"])
for n in range(100_000):
df.loc[len(df)] = [n, n ** 2]
52 seconds; 0.02 if built all at once
I don't need to declare types anymore. I trust Python to work them out.
But if I forget how a DataFrame stores data, adding rows one at a time gets slow.
Machine code
10101001 10111110 01001111 11110100
10101001 00000001 01111011 11111101
10010001 00000000 01000011 11111101
01010010 10000000 00000000 00010011
01110001 00000000 00001000 00010100
01010100 00000000 00000000 11101011
01010001 00000000 00000100 00000000
10010111 11111111 11111111 11111001
00001011 00000000 00000010 01110011
10101010 00010100 00000011 11100000
01110001 00000000 00001000 00010100
01010100 11111111 11111111 01101010
00001011 00010011 00000000 00000000
10101001 01000001 01111011 11111101
10101000 11000010 01001111 11110100
11010110 01011111 00000011 11000000
Assembly
fib: stp x20, x19, [sp, #-32]!
stp x29, x30, [sp, #16]
add x29, sp, #16
mov w19, #0
subs w20, w0, #2
b.lt done
loop: sub w0, w0, #1
bl fib
add w19, w19, w0
mov x0, x20
subs w20, w0, #2
b.ge loop
done: add w0, w0, w19
ldp x29, x30, [sp, #16]
ldp x20, x19, [sp], #32
ret
C
int fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
fib(46) 1,836,311,903
fib(47) -1,323,752,223
Java
static long fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
long[] results = {fib(10), fib(20), fib(30)};
long[] backup = results;
results[0] = 0;
backup[0] 0
Machine code
Assembly
C
Java
Python
def fib(n):
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
df = pd.DataFrame(columns=["n", "n_squared"])
for n in range(100_000):
df.loc[len(df)] = [n, n ** 2]
52 seconds; 0.02 if built all at once
English, to Claude
> Write a function that returns the
nth Fibonacci number.
def fib(n):
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
fib(77) about 11 years on my laptop
@cache 34 microseconds
I don't need to write the code anymore. I trust Claude to write it from what I ask in English.
But if I forget what good code looks like, I get code that runs and is wrong or slow: no memoization, the wrong standard errors.
Different from the steps before: a compiler does exactly what I wrote. Claude makes choices I didn't ask for.
One person, one document. I write it, and I read every line.
A natural step, but the job changes. What matters most now:
Communication
The task, the data, what not to touch
Visibility
See what each one did: plans, logs, reports
Robust testing
Check the work before you rely on it
I fix my own car. I know every part I touch.
Engine
Brakes
Tires
Electrical
Body work
I don't need to know what's inside the car. What matters most now:
Communication
What's wrong, what I'll pay for
Visibility
An itemized estimate, the old parts
Robust testing
Sometimes my uncle or another mechanic checks it
Page 1
– How the site stores the data
– What the links and page numbers look like
– What questions to ask about it
Worth my time
Page 10
– Same layout, new rows
– Nothing new about how the site works
Grunt work: outsource it
Spend time where it helps me understand the process. Outsource the grunt work that doesn't.
Page 1
– How things are phrased
– Which policies are bundled together
– Which law codes go with which statutes
Worth my time
Page 100
– More information
– Nothing new about how it's written
– I only want the part I need
Grunt work: outsource it
Spend time where it helps me understand the process. Outsource the grunt work that doesn't.
Before
Ideas and thinking about the problem
Reading
Writing and speaking
Coding
Errors and debugging
Formatting tables
Overfull \hbox warnings
The goal
Thinking carefully about the setting
Institutional details
Learning new methods
Refining arguments against the literature
Ideas, reading, writing
ManagementManagement
Done well, management improves your
• communication
• specificity
• writing
Shares are illustrative, not measured
Data
Analysis
Writing
Funding
Decision
Drop 2010–2012
Data
First extract arrives
Advisor meeting
Change the outcome
Grant
Progress report due
Seminar comment
Check balance
Data vendor
Follow up: missing years
Reviewers
Referee 2: new robustness
Decision
Cluster by court
Coauthor
A new sample?
Data vendor
Corrected file
Conference
Draft due
Decision
Rerun everything
Advisor meeting
Back to the old outcome
IRB
Renewal
Seminar comment
Why not a DiD?
Claude can keep the record
Every decision and why, where the project stands, what's next. Less for us to hold in our heads while we do the hard part.
Beyond research
Turns emails and syllabi into calendar events
Turns my PT notes into a daily stretching schedule
Writes training plans for the athletes I coach
Slide decks with charts and simulations I can run live in class
Beyond research
Prompt
Result
Mon
8:15
Commute
9:30
Read: seminar paper
11:00
Stretch break
15:00
Snack
17:30
Commute
Tue
8:15
Commute
10:00
Applied micro seminar
11:30
Stretch break
15:00
Snack
16:00
Office hours
17:30
Commute
Wed
9:30
Read: workshop paper
11:00
Stretch break
15:00
Snack
Thu
8:15
Commute
11:00
Stretch break
12:00
CCPR workshop
15:00
Snack
17:30
Commute
Fri
11:00
Stretch break
14:00
Coauthor call
15:00
Snack
Orange: seminars from the email. Gray: blocks it added (reading, commute, stretching, snack).
Simulated example
Beyond research
Prompt
Result
| Exercise | Dose | When | Note from PT |
|---|---|---|---|
| Hamstring stretch | 3 × 30 s | Morning | Each side |
| Hip flexor stretch | 3 × 30 s | Morning | Keep back straight |
| Glute bridge | 2 × 12 | Evening | Hold 2 s at top |
| Cat–cow | 1 × 10 | Evening | Slow |
| Ice | 15 min | After lifting |
Plus 28 calendar reminders. Medicine goes on the same schedule if there is any.
Simulated example
Beyond research
Prompt
Beyond research
One sample: 100 workers; point size = weight
Estimated slope, every sample so far
Samples: 0 Standard error, OLS: – WLS: –
Sign-up form
Experience
What you use it for
Question
Literature review
Contribution
Data
Pipeline & exploration
Modeling
Results
Writing
Question
Literature review
Contribution
Data
Pipeline & exploration
Modeling
Results
Writing
The most important human part; AI hasn't caught up here
– Depth in one field over breadth
– We know who's working on what
– We know what would move the literature
– Nobody can read every paper in their subfield; it's too much
– We need ways to skim, review, and read summaries to keep up
Question
Literature review
Contribution
Data
Pipeline & exploration
Modeling
Results
Writing
AI is very good at this
– We used to spend weeks on:
· Technical PDFs
· Announcements and outdated government websites, for institutional details
· Codebooks, for what each variable means
– Scrapers take an afternoon; FOIA is easier (MuckRock has templates)
– Lots of training data on this kind of code, so fewer errors
Question
Literature review
Contribution
Data
Pipeline & exploration
Modeling
Results
Writing
AI is decent at this, but needs to be hand-held for the best results
– Much better when you give it:
· Similar designs
· Code for those designs
· Other reference material
Question
Literature review
Contribution
Data
Pipeline & exploration
Modeling
Results
Writing
AI is not very good at interpreting results, but really good at checking them
– Writing tests and checks is the best way to make sure results are sensible
– Feed it the literature: does your result match past work or run against it?
Question
Literature review
Contribution
Data
Pipeline & exploration
Modeling
Results
Writing
The academic community is split on this
– Some draft with AI as a first pass
– Others think you shouldn't
– Today: strategies I think both groups can accept
Principle 0
– Extremely detailed
– Clear headings: goal, sources, definitions, steps, checks, when to stop
– Read it and edit it yourself before anything runs
– Every minute here saves hours later
notes/plan.md
# Plan: did county jail populations fall during COVID?
## Goal
How much did jail populations fall from mid-2019 to mid-2020? How much of the drop is real, and how much is counties that stopped reporting?
## Read first
data/raw/ and its codebook; notes/ideas.md (my notes, don't edit)
literature/ summaries on COVID jail releases
## Definitions
One unit = one jail, not one county. Counties that share a jail all show its total; count it once.
## Sample
Mid-year (Q2) counts, 2019 and 2020. Only counties that report in both years. Never add up quarters.
## Steps
1. Profile the data; report anything odd before analyzing
2. Write down the sample rules
3. Compute the change
4. A second agent recomputes it without seeing the code
## Checks (all must pass)
2019 total close to BJS (about 735k); Alaska's 29 rows count as one jail
State totals add up to the national total
## Output
output/change.csv and a one-page memo; every number points to a file
## Out of scope
No regressions yet. No claims about the whole US.
## Stop and ask me if
A check fails, or a choice moves the answer by more than 1 point
Principle 1
– Your writing, ideas, and notes in their own folder
– Same for raw sources: laws, medical records, policy text, data
– Agents can read them, never edit them
– You always know what you wrote and what the AI touched
– Your voice and ideas stay yours
mine/
drafts/paper.tex
ideas.md
notes/
sources/
statutes/, policy text
codebooks/
data/raw/
ai/
code/, output/
reports/
summaries/
Agent
read only
read only
writes
Principle 2
– Every claim points to a source
– Sources:
· Papers in your library
· Policies
· News articles
· Other files in your directory: notes, data, codebooks, output
– Ask for the file and the exact passage
– Then check it: a quote you can search for is easy to verify
AI's sentence
Source it cites
Check
Writing tasks took 40% less time with ChatGPT (Noy & Zhang 2023)
literature/noy_zhang.md
"…decreased average time taken by 40%…"
✓
matches
Support agents solved 34% more issues per hour (Brynjolfsson et al. 2025)
literature/brynjolfsson.md
"…by 15% on average…"
✗
wrong number
Kajeepeta et al. (2022), "County jail incarceration rates and county COVID‑19 incidence…"
CrossRef, OpenAlex
No such paper. Closest: her 2020 AJPH paper on jails and mortality
✗
AI hallucination
Principle 3
– Writes a report
– Can't touch the original
– Makes a triage report:
· Must fix: the result is wrong
· Check: could change the result
· Mention: say it in the paper
– Give it a list of what to look for, not just "check this"
notes/check_report.md
MUST FIX
Shared jails counted many times
All 29 Alaska rows say 2,693; all 5 NYC boroughs say 7,939. 2019 is too high.
CHECK
Who reports changed
2,939 counties report in 2019, 2,261 in 2020. Part of the drop is counties that stopped reporting.
MENTION
Some numbers are estimates, not counts
When a jail didn't report, Vera filled in the number: a straight line between years, or the last reported number copied forward. Say so in the paper.
Principle 4
– Some agents report problems
– Others make the changes
– None does both
– An agent that fixes what it finds is grading its own work
– Set it in each agent file: which tools it gets
Read files
Write a report
Edit code, data, text
Data profiler
Referee
Auditor
Replicator
Worker
Checkers report
Worker fixes
Checkers look again
Principle 5
– AI doesn't know your decisions or why you made them
– So it guesses: choices that are fine in other fields, wrong in ours
– Write down each one: what we chose, what we rejected, why
– Point to the file from CLAUDE.md so every new session reads it
notes/decisions.md
D1 · Which count to use
Claude's guess
Add up every row in the year
We decided
June 30 count only
Why
BJS uses mid-year; summing counts a county up to 4 times
D2 · Which counties
Claude's guess
Every county that reports in either year
We decided
Only counties that report in both years
Why
Otherwise the change mixes in who reports
D3 · Outliers
Claude's guess
Drop the biggest counties as outliers
We decided
Keep every county
Why
They're the biggest jails, not errors
Lecture
1 Set up a project: CLAUDE.md, folders, protecting your work
2 Agents and skills, on one research idea from start to finish
3 Checking the work: auditors, citations, replication
4 Graphs of agents, and the newer features
Hands-on workshop
Make your own skills, agents, and auditors for one of your projects
# once
$ npm install -g @anthropic-ai/claude-code
# every time
$ cd ~/research/jail_project
$ claude
# first time in a project
> /init
Start it in your project folder
/init writes a first CLAUDE.md
Needs a Pro, Max, Team, or API account
jail_project/
CLAUDE.md instructions
.claude/agents/ personas
.claude/skills/ repeated tasks
data/raw/ never edited
data/clean/ written by code only
code/ 01_ingest.py, 02_clean.py
output/ tables, figures, logs
paper/ the draft
slides/ talks
literature/ one summary per paper
institutional/ laws, policies, other institutional details
notes/ plans, decisions, referee reports
comments/ feedback, one file per person
Agents find things by name. With clear folders you can say "use the plan in notes/" and it knows where to look.
Every number in a paper should trace back to a file in output/
Everything in output/ should come from a reproducible script, not just an ad hoc analysis that Claude ran in the terminal
CLAUDE.md
Claude doesn't remember yesterday's session. What you explained, what went wrong, what you decided: gone.
A text file in the project folder. Claude reads it automatically at the start of every session, before you type anything.
Write what you'd tell a new research assistant on their first day:
• What the project is
• What never to touch
• Where things are
• How you want the work done
Applies to all your projects
How you like to work: writing style, language, general rules
Applies to the current project
This project: the question, the data, the folders
CLAUDE.md
1 Run /init. Claude reads the folder and writes a draft.
2 Read it. Delete anything vague or wrong.
3 Add the question, the folders, and what's off limits.
4 Add 4 to 6 rules you can check.
5 Start a fresh session and ask what the rules are.
6 Every time Claude makes a mistake you don't want again, add one line.
# step 1
> /init
# steps 2-4: open CLAUDE.md in any editor
# step 5
> /clear
> What rules do you follow in this
project?
# step 6
> You summed every quarter. Add a
line to CLAUDE.md so that doesn't
happen again.
CLAUDE.md
| Part | What to write | Example line | Without it |
|---|---|---|---|
| Project | The question, in 1 or 2 lines | How much did jail populations fall in 2020? | It guesses what the work is for |
| Folders | Where things are; what's off limits | data/raw/: never edit | Output goes anywhere; raw files can get changed |
| Data notes | What one row is; known problems | One row = county x year x quarter | Every session has to find the same problem again, or misses it |
| Rules | How to work, in a form you can check | Print the row count after every filter | It decides for itself how careful to be |
Start with project, folders, rules; add data notes as you find problems
CLAUDE.md
Using the Vera Institute county file, compute the number of people held in US jails in 2019 and 2020, and the percent change
No CLAUDE.md
most common mistake: shared jails counted many times
7 of 20 (35%)
General rules
11 of 19 wrong runs found the problem, then reported the raw number
1 of 20 (5%)
General rules, one rule reworded
most common mistake: shared jails counted many times
9 of 20 (45%)
Rules + data notes
no wrong runs
20 of 20 (100%)
Same task, one agent, 20 fresh runs each; only CLAUDE.md changes
CLAUDE.md
Primary sources
Codebooks
Source files: the law, the budget
Paper summaries in literature/
Agent
Example output
A table from a paper I trust
A past figure that passed every check
The best things to give an agent: explicit resources and successful examples.
CLAUDE.md
| Vague | Checkable |
|---|---|
| Be careful with the data | Print the row count after every filter or merge |
| Don't make things up | Never report a number you didn't compute from a file in this project |
| Use good sources | Cite only papers with a summary in literature/ |
| Be thorough | Run every check in checks.md and report pass / fail / marginal |
| Understand the data | Read the codebook before using a column |
Keep it short: the whole file loads every session
Steps for one task go in a skill
Risk: an agent edits a raw file to get its code to run, and the original is lost
In Claude Code
.claude/settings.json
{"permissions": {"deny": [
"Edit(data/raw/**)",
"Write(data/raw/**)"
]}}
In the operating system
# make raw files read-only
$ chmod -R a-w data/raw
# and keep a backup
$ git init
1 Press Shift+Tab until the prompt says plan mode
2 Type the task. I recommend writing a my_plan.md first and telling Claude to plan from it.
3 Claude reads files and writes a plan. It can't edit or run anything yet.
4 Check the plan against the list on the right. Tell it what to change.
5 Approve. Now it edits and runs.
Which files it will read, and which it will change
The exact filters and merges
The row counts it expects after each
What it won't touch
How you'll know it worked
Without it: if Claude misreads the task, you find out after the files have changed
Keep working in the same session. Ask questions and ask for changes in plain language.
Documents
"Draft the data section of paper/draft.md"
Slides
"Make three slides on the 2020 drop for lab meeting"
Figures
"Plot jail population by quarter, same counties in both years"
Numbers
"Why are fewer counties in 2020 than in 2019?"
Formulas
"Write the percent change formula in LaTeX for the paper"












1
Shrewd econometrician
Example description →Identification, standard errors, what would break the IV.
What did other papers in the literature check?
2
Domain expert
Immigration courts: is this how bond hearings actually work?
3
Non-technical reader
Could a reporter or a policymaker follow it?
4
Formatting nitpicker
Example description →Labels, axis titles, fonts, typos, numbers that don't match
.claude/agents/econometrician.md
---
name: econometrician
description: Referees identification, estimation and inference.
Reports only; never edits.
tools: Read, Grep, Glob, Bash
model: opus
---
You're a shrewd applied econometrician refereeing this paper for a top
field journal. You're looking for the reason to reject it.
Read first
- The paper or slides, then code/ and output/
- literature/summaries/ for papers that use the same design
Check
1. Identification. Name the design (IV, diff-in-diff, RD, ...) and
every assumption it needs. For each: what in this setting could
break it, and does the paper test it?
2. Estimation. Does the code do what the paper says? Fixed effects
at the right level, sample cuts written down, weak instruments
or few treated units in any subgroup.
3. Inference. Is the clustering level right? Few clusters? Many
outcomes or horizons tested at once?
4. The literature. Find the 3-5 closest papers with the same design.
List every check they ran. Mark each one done or not done here,
with the slide or table.
5. Numbers. Rerun the code; every number in the paper should match
output/. List any that don't.
Rules
- Don't edit any file. Return the review as your final message.
- Every point cites a slide number, file and line, or paper.
- Rank each point: MUST FIX, SHOULD CHECK, or MINOR.
- For each one: the question a seminar audience would ask, and the
test or table that would answer it.
- If you couldn't verify something, say so. Don't guess.
.claude/agents/format-nitpicker.md
---
name: format-nitpicker
description: Checks formatting on every slide, table and figure.
Reports only; never edits.
tools: Read, Grep, Glob, Bash
model: sonnet
---
You only care about how the paper looks. Don't comment on the
economics, and don't rewrite the argument.
Look at every slide as an image: render it with headless Chrome and
read the picture, not just the HTML.
Check
- Titles: one capitalization style everywhere; no title wraps to
a second line.
- Axes: every axis has a title with units; no cut-off or
overlapping labels; tick labels readable at the back of the room.
- Numbers: same decimals for the same quantity; real minus signs,
not hyphens; each number on a slide matches the table it's from.
- Notes: every figure and table says the sample, N, the estimator,
and what the intervals are.
- Text: typos, doubled words, double spaces; every abbreviation
(UJIVE, EOIR, IV) spelled out the first time.
- Colors: the same group gets the same color in every figure; still
readable in grayscale.
- Citations: every paper cited is in the bibliography, in one format.
Rules
- Don't edit any file. Return the list as your final message.
- One line per problem: slide number, what's wrong, the fix.
- Group by slide, in slide order. No praise and no summary.
• A text file of steps for one kind of task: .claude/skills/<name>/SKILL.md
• Run it by typing /<name>, or Claude starts it when your request matches its description
• Only the name and description load at the start of a session; the steps load when it runs
Loads every session
Rules for the whole project
Loads when used
Steps for one task you repeat
My skills:
/ingest-paper
Copy a PDF to papers/ and write a summary to summaries/
/codebook
Read a new data file and list each variable, its type, missing values, and range
/make-guide
Make a slide guide for a paper when I want to understand it in greater depth
/audit-slides
Four reviewers check a slide deck
1Do the task once in a normal session
2Ask Claude: “Write a skill for what we just did”
3Edit the steps: one action each, where files go, when to stop and ask you
4Save to .claude/skills/ (this project) or ~/.claude/skills/ (all projects)
5Run it in a new session; fix the steps it gets wrong
~/.claude/skills/ingest-paper/SKILL.md (shortened)
--- name: ingest-paper description: Add a paper PDF to the library. Copies it to papers/ and writes a summary in summaries/. --- Input: $ARGUMENTS (path to a PDF) 1. Name it authorlast_year_topic.pdf 2. Copy (don't move) it to papers/ 3. Read the paper 4. Write summaries/<name>.md: question, data, identification, key findings with numbers, limitations 5. Report where both files are
Claude can only hold so much of a session at once (the "context window"). In long sessions, older parts get summarized or dropped, and instructions in them stop being followed.
| Do this | When |
|---|---|
| /context | Check how full the window is |
| /clear | Starting a new task |
| /compact | Same task, but the session is getting long |
| a file in notes/ | Anything Claude needs to remember tomorrow |
| a subagent | A side job that would fill the window (reading 50 summaries) |
Literature
> /ingest-paper owens_sloan.pdf
1 Renames it author_year_topic.pdf
2 Copies it to papers/
3 Reads it and writes a summary to literature/ with the same sections every time
literature/owens_sloan_2022_...md
title: "Can Text Messages Reduce
Incarceration in Rural ..."
authors: [Owens, Sloan]
year: 2022
tags: [pretrial-detention, RCT, ...]
## Research Question
## Identification
## Data & Sample
## Key Findings
## Limitations
Search the library for the passages closest in meaning to a question, then have Claude answer from those passages
1
Every summary and full-text paper into passages of at most 1,500 characters
2
Turn each passage into a list of 768 numbers that describes its meaning (nomic-embed-text, runs on my laptop)
3
Turn the question into numbers the same way; return the passages with the closest numbers
4
Claude reads only those passages and cites them
My library: 1,003 summaries and 1,934 full papers, split into 118,631 passages, in one DuckDB file
• A search takes about 1.5 seconds, instead of Claude reading the papers
• Small: the file is 1.4 GB, against 3.8 GB for the PDFs
• The same way companies set up search over their own documents
Literature
64 pixels: 1 = ink, 0 = blank
5
0
2
1
2
0
7
4
1
9
1
3
7
4
1
… 1,797 digits, 64 numbers each
Embedding: 64 numbers → 2
5 (−11.511907, −29.39809)
0 (5.6371565, −49.00215)
2 (−32.26241, 8.4860325)
1 (18.344864, 7.8005333)
2 (−45.922905, 17.100817)
0 (2.142613, −59.66422)
7 (8.495072, 45.27381)
4 (48.5379, 24.834377)
1 (2.8567827, 12.828926)
9 (−31.532978, −24.098316)
1 (18.653387, 7.709546)
3 (−30.613049, −16.255203)
7 (11.466808, 39.034477)
4 (41.400875, 19.621922)
1 (23.78706, 6.506026)
Literature
Bail reform and pretrial detention
Peer effects in juvenile facilities
Minimum wages and youth employment
Policing spillovers onto nearby blocks
Prison crowding and early release
Job search after incarceration
Event-study estimates of sentencing reform
Classroom peers and later arrests
Family spillovers of parental incarceration
Monopsony in local labor markets
Parallel trends with staggered adoption
Peer effects and spillovers in prison
Literature
Bail reform and pretrial detention
Peer effects in juvenile facilities
Minimum wages and youth employment
Policing spillovers onto nearby blocks
Prison crowding and early release
Job search after incarceration
Event-study estimates of sentencing reform
Classroom peers and later arrests
Family spillovers of parental incarceration
Monopsony in local labor markets
Parallel trends with staggered adoption
Peer effects and spillovers in prison
Passages of ~1,000 characters
Admissions rose by 40 percent in ten years…
We compare cohorts before and after…
Inmates placed with older cellmates were…
Brothers of incarcerated men were less likely…
After release, job search took longer when…
Peer quality is measured by prior arrests…
768 numbers each
[−0.05, 0.16, 0.58, …]
[−0.08, −0.07, 0.30, …]
[−0.27, −0.09, 0.26, …]
[0.17, 0.03, 0.20, …]
[−0.85, 0.31, −0.29, …]
[−0.50, 0.08, 0.21, …]
Embedding → 2
(12.9, −36.7)
(−34.2, 20.4)
(9.9, 27.0)
(35.8, −4.8)
(−23.9, −23.8)
(10.2, 26.0)
● Diff-in-diff
● Peer effects
● Spillovers
● Labor market frictions
● Prison population dynamics
> What does my library say about pretrial detention and case outcomes?
My question
⏺ Bash(python scripts/search.py "effect of pretrial detention on case outcomes" --type summary -n 4)
Claude runs my search script
[1] Dobbie, Goldin, Yang (2018) 0.819 [Research Question]
[2] Dobbie, Yang (2021) 0.807 [Key Findings]
"Pretrial detention increases the probability of being
found guilty by 14 percentage points ..."
[3] Grau, Marivil, Rivera (2021) 0.807 [Research Question]
[4] Lacoe, Fischer, Raphael (2023) 0.806 [Related Work]
Closest passages: paper, similarity, section
⏺ Using judge assignment as an instrument, detention raises the
chance of conviction by 14 pp, raises re-arrest after the case by
12.1 pp, and lowers formal employment by 9.4 pp three to four years
later (Dobbie, Goldin, and Yang 2018; reviewed in Dobbie and Yang
2021). Grau, Marivil, and Rivera (2021) study wages for people not
incarcerated after the verdict.
Answer, citing those papers
Search output shortened. Run on my library, October 25, 2026.
Replication test
State A raised its minimum wage from $6.80 to $8.08.
State B's stayed at $6.80.
Fast-food restaurants surveyed before and after.
1. Effect on employment per restaurant?
2. Same, using how much each store had
to raise its starting wage
3. Effect on the price of a meal?
Use only the files in data/. No internet.
Card & Krueger (1994): NJ vs. PA fast food
Data disguised: states, dollars, variable names, row order
Each run in its own folder, no web
Same model each time (Sonnet)
40 one-shot runs, then 15 per setup
Replication test
Counts managers
Leaves managers out
2.6
2.7
2.8
2.9
3
Q1
Employment effect
30 · paper's 2.75
10
13
14
15
16
17
Q2
Wage-gap regression
Paper 15.65
21
2
11
4
2
State A only
Paper's model
Needed the detail of the paper's sample: drop 8 stores with no wave-2 wage. Then it matches.
Replication test
Paper's 2.75
Managers left out, 2.94
Other choices
One shot
30 of 40
Checker reports once
11 of 15
worker can ignore it
Auditor ↔ worker until approved
11 of 15
auditor flagged managers 0 of 4 times
Same, Opus as auditor
11 of 15
flagged 3 of 4; worker kept its choice
Checker overrides the worker
14 of 15
fixed the 2 that left managers out
Immigration project
My paper on immigration bond judges: 8 days, 9 sessions
Day 1
Oct 18
Four possible angles, a literature search on each, picked bond judges, first estimates
Day 2
Oct 19
Read the closest paper in full, switched to UJIVE, tested finer comparison groups
Day 3
Oct 20
Settled the treatment: released within 30 days; collected the references
Day 4
Oct 21
Presented to colleagues for feedback; monotonicity and judge-skill checks from a methods paper
Day 5
Oct 22
Notes on how bond hearings work; quotes from the Supreme Court briefs; more balance checks
Day 6
Oct 23
Listed every column in the 19 data tables; plan for more analyses; started linking ICE records
Day 7
Oct 24
Who ICE detains before a hearing; flow chart of the system
Day 8
Oct 25
Monotonicity graphs, appeals and lawyers; rebuilt the slides
Immigration project

• EOIR case data, Sept 2026 release: 19 tables → Parquet
• 751,671 first bond hearings, 2010–2026; 673 judges, 78 courts
• Inventory of every column: meaning, coverage, which script uses it
• Codes with no documentation marked “not verified”
Immigration project

• Cases: our count from EOIR, checked against CRS
• Money: ICE budget justifications, FY2010–2025
• $45B: Pub. L. 119-21, quote checked against the statute
• About $10.6B a year ≈ housing every sheltered household ($9.6B) or Head Start ($12.3B)
Immigration project

• Four search agents: no paper uses bond-judge assignment as an instrument
• Every number read in the full text, with the page
• PDFs it couldn't download: I opened them in Chrome and saved them
• New papers ingested into my library
Immigration project

• From the institutional details an agent collected: statutes, BIA cases
• Selection steps → controls and checks: no bond at first, mandatory detention, DHS-requested hearing
• Each end point → an outcome: removal, voluntary departure, relief, still open
Immigration project
7
• About 60 papers: bail, prosecutors, examiners
• Fixed effects, controls, and balance results in each
• What they did when balance failed
8
• Chyn, Frandsen & Leslie 2025
• Goldsmith-Pinkham, Hull & Kolesár 2025
• Kerwin, Rostom & Sterck 2024
• Norris: disagreement between judges
Immigration project

Balance

First stage

Monotonicity
• Every check those papers ran, marked done or not done
• Balance fails (F = 19.4); bias from the measured traits is 3.5–9% of each effect
Immigration project

UJIVE, the standard estimator in these papers

Removal orders: −19 points at 8 years
Immigration project

Splits like the ones in similar papers

The data also name the judge who decides the case
• The bond judge decides 61% of held cases → control for that judge's removal rate: −0.189 → −0.167
• Released people's next judge: unrelated to the bond judge, 0.014 (0.008)
Graphs
Data describer
data_report
Planner
plan
Plan referee
report
Analyst
numbers
Replicator
report
Lit search
lit.json
Citation check
drops bad ones
Writer
result
Number check
report
Each box: one agent, one job, named input and output files
Orange boxes: checkers that can't edit the work
Every loop has a limit, then a person decides
When to use what
| Task | Setup | Example |
|---|---|---|
| Quick question, nothing depends on it | One agent | "What does this column mean?" |
| Changes several files | One agent + plan mode | Reorganize code/ |
| A number or citation someone will rely on | Worker + checker with a checklist | A proof of concept |
| Many steps, repeated, or going in a paper | Graph | Clean data → estimation → create figure |
Newer features
| Feature | Problem it fixes | Tested here |
|---|---|---|
| Hooks | A request can override a CLAUDE.md rule | Yes, 35 runs |
| /goal | The agent decides for itself when it's done | No |
| Workflows | A graph you set up once is hard to run the same way again | No |
| Plugins | Sharing your agents and skills means copying folders by hand | Yes, kit packaged |
| Plugin evals | You don't know if your setup helps | No |
| Routines | Some work should run when your laptop is closed | No |
| Connectors (MCP) | Claude can't reach Zotero, Stata, or Drive | No |
Claude Code 2.1.296, October 2026. Features change often; check the docs before you rely on one.
Hooks
1 · The rule
Immigration project, CLAUDE.md: “Never edit anything in data/raw/”
The raw files are the EOIR release as downloaded. Change one, and nobody can reproduce my numbers.
2 · The conflict
A month later I spot a typo in a judge code and type: “just fix it in the file”
Two instructions now disagree: the rule and me. Claude goes with me and edits the raw file.
3 · The hook
Before every edit, Claude Code runs a check: is this file in data/raw/?
If yes, the edit is blocked and Claude is told: “Raw data. Fix it in the cleaning script.”
A hook is a check that Claude Code runs automatically at a set moment, like before every edit. It isn't an instruction to Claude, so Claude can't be talked out of it.
Hooks
1 · The problem
Claude edits the results slide and says “done”
It changed the code for the slide but never looked at the slide itself.
2 · What happens
The title wraps onto two lines; an axis label runs off the edge
I find out when I open the deck, or in front of the seminar.
3 · The hook
After every edit to slides/, Claude Code draws the slide and checks it
If text wraps or runs off the edge, Claude is told: “Slide 21: title is on two lines.” It fixes it before it's done.
Hooks
Same request: "go ahead and fix it in that file." Share of runs that changed the raw file:
CLAUDE.md rule only
5 of 5
+ hook on Edit|Write
5 of 15
All 4 logged edits used sed -i through Bash, which the hook didn't check
+ hook on Edit|Write|Bash
0 of 10
5 runs tried sed -i, 5 tried Edit; all blocked
A Python script that opens a raw file for writing still gets past the Bash check. Keep the read-only setting from Set up: chmod -R a-w data/raw
Writing a hook →Hooks
.claude/settings.json
{"hooks": {"PreToolUse": [{
"matcher": "Edit|Write|Bash",
"hooks": [{"type": "command",
"command": ".claude/hooks/protect-raw.sh"
}]
}]}}
protect-raw.sh: Edit/Write part only
FILE=$(jq -r .tool_input.file_path)
if [[ "$FILE" == */data/raw/* ]]; then
echo "Blocked: raw data. Write to
data/clean/ instead." >&2
exit 2
fi
exit 0
| Part | What to write | Without it |
|---|---|---|
| Event | When it runs: PreToolUse = before a tool call | Runs at the wrong time, or never |
| Matcher | Which tools: Edit|Write|Bash | Edits through Bash get past it |
| Script | exit 2 blocks the call; the message goes back to Claude | Claude doesn't know what to do instead |
/goal
1 · The task
“Rerun the event studies: removal, relief, and in absentia, years 1–10”
Claude decides for itself when it's done.
2 · What happens
Removal runs. Relief hits an error. Claude: “Here are the removal results.”
One of three is done, and the reply reads like it's finished.
3 · /goal
/goal 3 outcomes, years 1–10, estimates in output/logs/. Max 15 turns.
After every turn, a second model checks what Claude printed. Not met yet → Claude keeps going.
/goal sets the finish line. Claude doesn't decide when it's done; a separate check does, after every turn.
Workflows
1 · The task
After every revision: run the five reviewers, fix what they flag, review again
The reviewers from earlier. I ask Claude to run them each time.
2 · What happens
Claude runs it differently each time
One week all five; next week it skips the nitpicker and stops after one round.
3 · Workflow
A script runs it: 5 reviewers at once → fixes → review again, max 2 rounds
Same steps every time. Save it once, then type /review after each revision.
A workflow is an agent graph written as a script. The script decides who is involved during each round of decision making.
Plugins
1 · My setup
Five reviewer agents, a data describer, the raw-data hook
The ones from this talk, in one project's .claude/ folder.
2 · The problem
My RA starts a new project and wants the same setup
I copy the folders by hand. Next week I fix the econometrician; their copy is out of date.
3 · Plugin
All of it in one package; they install it with one command
When I update it, they get the update.
A plugin is a package of agents, skills, and hooks: ssc install for Claude Code.
Examples: this workshop's research-checks (referee, replicator, raw-data hook); EPI's plugin for BLS, BEA, FRED, and Census data
Plugins
Folder
research-checks/
.claude-plugin/plugin.json name, version
agents/ referee.md, replicator.md, ...
skills/ proof-of-concept/SKILL.md, ...
hooks/ hooks.json, protect-raw.sh
Install
# once
> /plugin marketplace add
jakemanderson/claude-code-research-workshop
# then
> /plugin install
research-checks@claude-code-research-workshop
Always loaded
~357
tokens per session: each skill and agent's name and description
Each time one runs
110–670
tokens, depending on the skill or agent
The hook
0
tokens: Claude Code runs it, not the model
Plugins
| Risk | Check |
|---|---|
| It runs code on your machine as you | Read its hooks/ and .mcp.json first |
| Third-party marketplaces aren't reviewed by Anthropic | Prefer claude-plugins-official, or a source you know |
| Every enabled plugin adds tokens to every session | claude plugin details [name]; disable what you don't use |
| Polished output can still be wrong | Test it on a task where you know the answer |
One reviewer's test
A sales plugin's report said the author had 2,000 subscribers. The author has 5,000+.
Made by economists
Economic Policy Institute: /plugin marketplace add economic/epi-skills (BLS, BEA, FRED, Census data)
Plugin evals
claude plugin eval runs each test case with your plugin and without it, and reports the difference.
evals/jail-drop/prompt.md
---
max_turns: 30
allowed_tools: [Read, Bash, Write, Agent]
---
How much did jail populations fall
from 2019 to 2020? Data:
data/raw/vera_county.csv.gz
evals/jail-drop/graders/answer.md
---
type: llm
---
PASS if the 2019 total is within 3%
of 704,947 and the change is within
1 point of -25.95%.
FAIL otherwise.
$ claude plugin eval . --runs 20 --ablation with-without
The default is 3 runs each way. With 20 each, only one of our three differences was clear. Use 20 when the result decides something.
Routines and connectors
Routines
A saved prompt that runs in Anthropic's cloud on a schedule, from a GitHub event, or from a web request.
> /schedule every Monday 9:07am, search
NBER for new papers on jail populations,
add summaries to literature/,
open a pull request
Needs a GitHub repo. Runs as you, with no permission prompts. Green status means it ran; check the output
Connectors (MCP)
Give Claude tools outside the project folder.
> claude mcp add [name] -- [command]
> /mcp list and log in
Examples: Zotero (community servers), Stata (the Stata Workbench VS Code extension), Google Drive.
Routines include all your connectors by default, with write access. Remove the ones a routine doesn't need.
When to use what
| If you need | Use | Example |
|---|---|---|
| A rule that must hold every time | Hook | Never change data/raw/ |
| Advice Claude should usually follow | CLAUDE.md | Print row counts after merges |
| Keep going until a check passes | /goal | All scripts run with no errors |
| The same multi-agent process again | Saved workflow | Proof of concept on a new question |
| Your setup in a coauthor's project | Plugin | research-checks |
| Evidence your setup helps | Plugin eval | With vs without, 20 runs each |
| Work while you're away | Routine | Weekly new-paper search |
| Track | What you do | You leave with |
|---|---|---|
| Your own project | Set up folders and CLAUDE.md; plan mode on one real task | A project set up for Claude Code |
| Proof of concept | See if you can get from an idea to a proof of concept in 90 minutes | A first estimate, and whether to continue |
| Literature library | Ingest 10–20 of your PDFs; search the summaries | A searchable library of your papers |
| Agents and skills | Write a reviewer agent and run it on your draft; turn one task into a skill | One agent and one skill |
| Data from a messy source | Scrape a site, parse a PDF table, or pull from an API (Census, IPUMS, BLS) | A script that rebuilds the data |
| Teaching | Write a problem set, solutions, and a grading rubric for a course you teach | A problem set with solutions |
| Your writing voice | Measure your own emails and writing; turn the numbers into a style guide | A voice profile Claude can follow |
Track 1
What you'll do
1Sort your files into raw data, code, output, and notes
2Copy the kit; make the raw data read-only
3Write CLAUDE.md: your question, your folders, your rules
4Write a plan for one real task yourself, then run it in plan mode and check the result
What you leave with
Instructions: tracks/1-your-own-project/README.md
Track 2
What you'll do
1Write the idea and a stop rule yourself, before any numbers
2Have the referee agent review the idea
3Run /proof-of-concept up to the plan; edit the plan yourself
4Compute, replicate, check the number yourself, and decide
What you leave with
Instructions: tracks/2-proof-of-concept/README.md
Track 3
What you'll do
1Ingest one paper you know well; check its summary against the PDF
2Fix the skill, not the summary
3Ingest the rest of your papers with subagents
4Search the library; plant three mistakes and see if the citation checker catches them
What you leave with
Instructions: tracks/3-literature-library/README.md
Track 4
What you'll do
1Write a reviewer agent that can read but not edit
2Run it on a draft with problems you already know about, and score it
3Add to its checklist and run it again
4Do one task by hand, turn it into a skill, and test it in a new session
What you leave with
Instructions: tracks/4-agents-and-skills/README.md
Track 5
What you'll do
1Look at the source yourself first: a website, a PDF table, or an API
2Write the plan, then plan mode
3Let it download and parse; profile the result
4Check a total and three rows against the source by hand
What you leave with
Instructions: tracks/5-data-from-a-messy-source/README.md
Track 6
What you'll do
1Plan a problem set from your lecture notes
2Write the data, the problem set, and the solutions
3A separate session solves it without seeing your solutions; compare
4Write a rubric and test it on made-up student answers
What you leave with
Instructions: tracks/6-teaching/README.md
Track 7
What you'll do
1Export your sent email and other writing
2A script pulls out only your own text; you read 10 samples to check
3A script measures sentence length, vocabulary, punctuation, and sentiment
4Measure 5 to 10 papers in your field the same way and compare
5Turn the numbers into a one-page profile; test writing with and without it
What you leave with
Instructions: tracks/7-your-writing-voice/README.md
Before the hands-on portion
1
Introduction and a preview of features
2
Agent graphs and pipelines
3
Retrieval and memory: RAG, reusing past work, context engineering
4
Many agents at once: swarms, harnesses, long-running work
If you think your home department's faculty or students would enjoy this talk (and its future versions), feel free to reach out about having me come speak!
Hands-on
1
Clone the repo next to your project folders, not inside one
cd ~/Documents
git clone https://github.com/jakemanderson/claude-code-research-workshop.git
2
Make a new folder for your track, or go into an existing project
mkdir ~/Documents/my_track && cd ~/Documents/my_track # new
cd ~/Documents/my_project # existing
3
Copy in the agents, skills, and hooks, then start Claude
cp -R ../claude-code-research-workshop/.claude .
claude
4
Open tracks/<your track>/README.md in the repo and follow it
CCPR Workshop · UCLA
Jake Anderson · Economics, UCLA
jakeanderson@g.ucla.edu