Investigating with AI

Course project template

First run

uv sync                      # Python env (uv fetches Python 3.12 itself)
uv sync --group ml           # add scikit-learn, xgboost, shap  (~2-3 GB)
uv sync --group llm          # add the Claude API client
claude                       # start Claude Code in this folder

Inside Claude Code: /permissions shows what it may touch here, /usage shows your remaining weekly allowance.

Layout

data/raw/         original files, never edited
data/restricted/  confidential microdata — Claude cannot read this folder
data/processed/   cleaned, de-identified files your scripts produce
src/analysis/     reusable cleaning, modelling and LLM-coding functions
scripts/          numbered runnable steps (01_clean.py, 02_model.py, ...)
notebooks/        exploration; import from src/, don't redefine logic there
report/           the HTML/JS report — index.html + data.json
outputs/          figures and tables, regenerated by scripts

The report

report/index.html is a self-contained animated chart: no build step, no CDN, no framework. It reads report/data.json, which scripts/03_export_report_data.py writes from your analysis. That one-way flow is the point — the figure cannot drift from the numbers, because it has no other source for them.

Preview it (HTML needs a server; opening the file directly blocks fetch):

npm run dev            # serves report/ on port 8080

Working on the course server? Forward the port from your own machine:

ssh -L 8080:localhost:8080 yourlogin@investigatingwithai.com

then open http://localhost:8080.

The chart already does the things that are easy to get wrong: a zero-based axis, a legend plus direct labels so identity is never colour alone, a hover tooltip, a data-table toggle, a colourblind-safe palette, dark mode, and animation that respects prefers-reduced-motion. Change the data, keep the structure.

Machine learning

uv sync --group ml. Two rules that matter more here than the code:

LLM calls in your own code

src/analysis/llm.py shows the standard pattern: coding open-ended survey answers into categories with a versioned codebook and a validated output schema.

This is billed separately from your Claude Code seat. It needs an ANTHROPIC_API_KEY from platform.claude.com. Ask your instructor before running anything at scale.

Treat the model as a coder, not an oracle: hand-code a sample first, compare, report the agreement rate in the write-up.

Git and GitHub

git init && git add -A && git commit -m "first commit"
gh auth login                      # once per account, on the server
gh repo create my-analysis --private --source=. --push

.gitignore already excludes data/ and outputs/. Keep it that way — survey microdata in a git history is very hard to remove, and a private repo is one setting away from being public.

Custom commands

Rules

Read CLAUDE.md. The same rules apply to you and to Claude.