VCC-experiments

April 3, 2026 · View on GitHub

Official experiment code for "View-oriented Conversation Compiler for Agent Trace Analysis" (Paper)

This repo reproduces the academic experiments in the paper. For daily use of VCC, see VCC.

This repo now supports a context learning platform on AppWorld. It trains a memory (MEMORY.md) by running tasks with a student agent, analyzing each execution with a teacher agent, and iteratively refining rules across epochs. The learned memory is then evaluated on test splits.

Install

Requirements: Python 3.10+, Claude Code.

AppWorld is automatically installed and set up on first run (pinned to commit a072b7a). No manual setup needed.

This project runs Claude Code as a subprocess with claude -p --bare. The --bare flag disables OAuth/keychain and requires explicit API credentials. You must set up one of:

  • Anthropic API: set ANTHROPIC_API_KEY environment variable
  • Vertex AI: set CLAUDE_CODE_USE_VERTEX=1, ANTHROPIC_VERTEX_PROJECT_ID, CLOUD_ML_REGION environment variables

You can also put these in an env.json file in this directory (gitignored, won't be committed):

{
  "CLAUDE_CODE_USE_VERTEX": "1",
  "ANTHROPIC_VERTEX_PROJECT_ID": "your-project-id",
  "CLOUD_ML_REGION": "us-east5"
}

Important:

  • Do not run experiments on a Claude Pro/Max subscription — it will get your account banned or burn through your quota instantly.
  • Do not remove the --bare flag from the code — it prevents Claude Code's auto-memory and CLAUDE.md from contaminating experiment data.
  • These scripts are thread-safe but not process-safe. Use --workers to parallelize, but do not run multiple script instances simultaneously — this will corrupt AppWorld's internal state.

Running all experiments costs roughly $6,500+ USD. You can reproduce the key Sonnet result for under $200 (see below).

Quick Sanity Check

The debug split has only 4 tasks. Use these to verify your setup works.

python train.py --split debug --workers 2 --epochs 1 --model haiku --effort low --teacher-model haiku --teacher-effort low
python evaluate.py --split debug --workers 4 --model haiku --effort low

If both complete without errors, your environment is ready.

How It Works

Train (train.py): epoch-based context learning. Each epoch runs every task once with a student agent, then a teacher agent analyzes the execution trace and edits MEMORY.md. Multiple parallel workers sync via LLM-based memory merging after each batch.

Evaluate (evaluate.py): single-pass execution. Runs tasks with a fixed MEMORY.md (from training or default), measures pass rate.

All outputs go to artifacts/:

artifacts/
├── train/{session}/
│   ├── config.json              # config + progress (for resume)
│   ├── MEMORY.md                # learned rules
│   └── {epoch}/
│       ├── t000_{task_id}/      # per-task: run.jsonl, run.txt, analyse.jsonl, ...
│       └── merge_{batch}/       # memory merge artifacts
└── eval/{session}/
    ├── config.json
    ├── MEMORY.md                # memory used
    ├── results.json             # aggregated pass rate
    └── t000_{task_id}/          # per-task: run.jsonl, run.txt, result.json

Train

python train.py [options]
ArgDefaultDescription
--task_id ID [ID ...]Specific task(s). Mutually exclusive with --split
--split SPLIT [...]Load tasks from split(s): train, dev, test_normal, test_challenge, debug
--difficulty NallFilter by difficulty (1/2/3). Only with --split
--limit NallTake first N tasks. Only with --split
--workers N1Parallel sessions
--epochs N2Training epochs
--method MvccpTeacher trace format: vccp, vcc, vccpf, naive
--model MCC defaultStudent model: opus, sonnet, haiku
--effort ECC defaultStudent effort: low, medium, high
--teacher-model Msame as --modelTeacher model
--teacher-effort Esame as --effortTeacher effort
--memory PATHbuilt-in seedInitial MEMORY.md file
--session NAMEtimestampOutput dir name (artifacts/train/{name}/). Errors if exists
--shuffle MODErndTask order: rnd, no, or integer seed
--resume NAMEResume or inherit from existing run. last for most recent

Evaluate

python evaluate.py [options]
ArgDefaultDescription
--task_id ID [ID ...]Specific task(s). Mutually exclusive with --split
--split SPLIT [...]Load tasks from split(s)
--difficulty NallFilter by difficulty. Only with --split
--limit NallTake first N tasks. Only with --split
--workers N1Parallel sessions
--model MCC defaultModel: opus, sonnet, haiku
--effort ECC defaultEffort: low, medium, high
--memory PATHbuilt-in seedMEMORY.md to use
--session NAMEtimestampOutput dir name (artifacts/eval/{name}/). Errors if exists
--resume NAMEResume or inherit from existing run. last for most recent
--manualfalsePrint command and wait for manual execution (single task only)

Resume: --resume NAME with same mode resumes (skips completed tasks). Cross-mode (e.g. --resume a train session from evaluate) inherits config + memory. Add --session NEW to clone instead of resuming in-place.

Run Sonnet Experiments (Recommended)

The most cost-effective way to reproduce the key results. Commands are grouped by cost so you can stop at any point.

Each step is independently resumable. If a run crashes, rerun the same command with --resume {session} to continue from where it left off.

Step 1: Train VCC (~$60)

python train.py --split train --workers 8 --model sonnet --teacher-model sonnet --method vccp --session son_son_vccp

Step 2: Evaluate on test_normal (~$100)

python evaluate.py --resume son_son_vccp --split test_normal --workers 8 --session son_son_vccp_tn

You can stop here for under $200 — this reproduces the core VCC result on test_normal.

Step 3: Train naive for comparison (~$130)

python train.py --split train --workers 8 --model sonnet --teacher-model sonnet --method naive --session son_son_naive

Step 4: Evaluate naive on test_normal (~$100)

python evaluate.py --resume son_son_naive --split test_normal --workers 8 --session son_son_naive_tn

Step 5: Evaluate on test_challenge (~$500)

python evaluate.py --resume son_son_vccp --split test_challenge --workers 8 --session son_son_vccp_tc
python evaluate.py --resume son_son_naive --split test_challenge --workers 8 --session son_son_naive_tc

Step 6: Baselines (~$100 for test_normal, ~$500 for test_challenge)

python evaluate.py --split test_normal --workers 8 --model sonnet --session baseline_son_tn
python evaluate.py --split test_challenge --workers 8 --model sonnet --session baseline_son_tc

Full Sonnet reproduction (all 6 steps) costs roughly $1,000.

Run All Experiments (~$6,500+ USD)

Full reproduction across three model tiers. Each command is independent and resumable. Includes the Sonnet commands above.

# ── Opus + Opus ──
python train.py --split train --workers 8 --model opus --teacher-model opus --method vccp --session opus_opus_vccp
python train.py --split train --workers 8 --model opus --teacher-model opus --method naive --session opus_opus_naive
python evaluate.py --resume opus_opus_vccp --split test_normal --workers 8 --session opus_opus_vccp_tn
python evaluate.py --resume opus_opus_vccp --split test_challenge --workers 8 --session opus_opus_vccp_tc
python evaluate.py --resume opus_opus_naive --split test_normal --workers 8 --session opus_opus_naive_tn
python evaluate.py --resume opus_opus_naive --split test_challenge --workers 8 --session opus_opus_naive_tc

# ── Sonnet + Sonnet ──
python train.py --split train --workers 8 --model sonnet --teacher-model sonnet --method vccp --session son_son_vccp
python train.py --split train --workers 8 --model sonnet --teacher-model sonnet --method naive --session son_son_naive
python evaluate.py --resume son_son_vccp --split test_normal --workers 8 --session son_son_vccp_tn
python evaluate.py --resume son_son_vccp --split test_challenge --workers 8 --session son_son_vccp_tc
python evaluate.py --resume son_son_naive --split test_normal --workers 8 --session son_son_naive_tn
python evaluate.py --resume son_son_naive --split test_challenge --workers 8 --session son_son_naive_tc

# ── Haiku + Sonnet ──
python train.py --split train --workers 8 --model haiku --teacher-model sonnet --method vccp --session haiku_son_vccp
python train.py --split train --workers 8 --model haiku --teacher-model sonnet --method naive --session haiku_son_naive
python evaluate.py --resume haiku_son_vccp --split test_normal --workers 8 --session haiku_son_vccp_tn
python evaluate.py --resume haiku_son_vccp --split test_challenge --workers 8 --session haiku_son_vccp_tc
python evaluate.py --resume haiku_son_naive --split test_normal --workers 8 --session haiku_son_naive_tn
python evaluate.py --resume haiku_son_naive --split test_challenge --workers 8 --session haiku_son_naive_tc

# ── Baselines (no training) ──
python evaluate.py --split test_normal --workers 8 --model opus --session baseline_opus_tn
python evaluate.py --split test_challenge --workers 8 --model opus --session baseline_opus_tc
python evaluate.py --split test_normal --workers 8 --model sonnet --session baseline_son_tn
python evaluate.py --split test_challenge --workers 8 --model sonnet --session baseline_son_tc
python evaluate.py --split test_normal --workers 8 --model haiku --session baseline_haiku_tn
python evaluate.py --split test_challenge --workers 8 --model haiku --session baseline_haiku_tc

Note: Haiku uses Sonnet as teacher because Haiku alone cannot effectively reflect on its own traces.

Results

All numbers are AppWorld official metrics (%). T tok = total reflector tokens during training, T/a = reflector tokens per analysis. Mem = trained MEMORY.md size in characters.

Paper-to-code mapping: VCC = vccp (VCC-preprocessed trace format), JSON = naive (raw JSONL).

Opus generator + Opus reflector

Methodtest_normal task_goaltest_normal scenario_goaltest_challenge task_goaltest_challenge scenario_goalT tokT/aMem
alld1d2d3alld1d2d3alld1d2d3alld1d2d3
Baseline79.277.275.084.167.968.456.276.275.869.476.777.464.054.266.066.1
JSON92.996.593.888.987.589.587.585.784.791.784.782.070.583.374.063.122.1M124K12.6K
VCC94.098.295.888.991.194.793.885.786.393.184.785.174.187.570.072.37.6M43K12.0K

Sonnet generator + Sonnet reflector

Methodtest_normal task_goaltest_normal scenario_goaltest_challenge task_goaltest_challenge scenario_goalT tokT/aMem
alld1d2d3alld1d2d3alld1d2d3alld1d2d3
Baseline73.277.258.381.067.973.750.076.261.461.159.363.150.445.850.052.3
JSON90.598.291.782.582.194.781.271.471.086.166.768.760.475.054.060.020.5M115K23.4K
VCC92.996.595.887.389.394.793.881.074.388.968.773.363.379.256.063.18.8M49K15.5K

Haiku generator + Sonnet reflector

Methodtest_normal task_goaltest_normal scenario_goaltest_challenge task_goaltest_challenge scenario_goalT tokT/aMem
alld1d2d3alld1d2d3alld1d2d3alld1d2d3
Baseline39.949.127.141.325.036.812.523.833.831.934.034.417.316.722.013.9
JSON71.486.079.252.462.579.075.038.153.569.445.353.836.045.830.036.923.3M131K43.3K
VCC75.687.775.065.162.568.456.261.954.781.947.350.339.666.738.030.812.6M71K37.9K

Cite

@article{zhang2026vcc,
  title={View-oriented Conversation Compiler for Agent Trace Analysis},
  author={Lvmin Zhang and Maneesh Agrawala},
  year={2026},
  url={https://github.com/lllyasviel/VCC}
}