A/B Testing Framework for LLM Code Generation with Knowledge Base Context
Measure how project-specific context improves LLM code generation accuracy
Aspect Bench is a lightweight A/B testing harness that measures how project-specific context ("knowledge bases") changes LLM code generation outcomes.
Itβs designed to benchmark prompts with and without KB context (including KBs generated by the Aspect Code VS Code extension), and compare outcomes using tests as the objective signal.
Aspect Bench compares LLM performance across two modes:
| Mode | Description |
|---|---|
| Baseline | Standard prompts without additional context |
| Aspect KB | Prompts enhanced with project knowledge base files (optional) |
This A/B testing approach measures how much project-specific context improves:
- β Code generation accuracy
- β Test pass rates
- β Regression prevention
Real benchmark results from Claude 4 Sonnet on 15 FastAPI tasks:
| Metric | Baseline | With KB | Ξ |
|---|---|---|---|
| Tasks Passed | 5 | 9 | +80% |
| Tests Fixed | 24 | 41 | +71% |
| Regressions | 8 | 3 | -63% |
The KB-enhanced prompts consistently outperform baseline, especially on complex refactoring tasks where project architecture knowledge is critical.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ASPECT BENCH WORKFLOW β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. SETUP 2. GENERATE KB 3. GENERATE PROMPTS
ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
β Clone target repoβ β β (Optional) add β β β Run generate_ β
β into repos/ β β KB text files β β prompts.py β
β β β into example_kb/ β β β
ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββ
β Provide KB files |
β (optional): |
β example_kb/kb_*. |
β txt |
ββββββββββββββββββββ
4. RUN BENCHMARK 5. GENERATE REPORT
ββββββββββββββββββββ ββββββββββββββββββββ
β run_benchmark.py β β β generate_report. β β π Results!
β --repo <name> β β py --experiment β
β --provider ... β β -id <id> β
ββββββββββββββββββββ ββββββββββββββββββββ
TL;DR β Clone, install, set API key, run:
git clone https://github.com/asashepard/aspect-bench.git && cd aspect-bench pip install -e . && cp .env.example .env # Add your ANTHROPIC_API_KEY python src/scripts/run_benchmark.py --repo fastapi-template --provider anthropic
git clone https://github.com/asashepard/aspect-bench.git
cd aspect-benchpip install -e .cp .env.example .env
# Edit .env and add your API keysClone the target repositories into the repos/ folder:
# Create repos folder
mkdir repos
cd repos
# Clone fastapi-template
git clone https://github.com/fastapi/full-stack-fastapi-template.git fastapi-template
# Clone djangopackages
git clone https://github.com/djangopackages/djangopackages.git djangopackages
cd ..Tasks are defined as one YAML file per task:
# View task definition files
ls src/repos/fastapi-template/tasks/
ls src/repos/djangopackages/tasks/Each task has an id field (e.g., missing-item-404, api-package-404) that you use when running benchmarks.
Task file location pattern:
src/repos/<repo-name>/tasks/*.yaml
Before running benchmarks, generate the prompts from task definitions:
python src/scripts/generate_prompts.pyThis creates both baseline and aspect prompt files in each repo's prompts/ directory.
# Run all tasks for a repository
python src/scripts/run_benchmark.py --repo fastapi-template --provider anthropic
# Run a specific task by ID
python src/scripts/run_benchmark.py --repo djangopackages --tasks api-package-404 --provider anthropic
# Run all repositories
python src/scripts/run_benchmark.py --all-repos --provider anthropicpython src/scripts/generate_report.py --experiment-id <experiment_id>Before running benchmarks, ensure:
-
.envfile exists with validANTHROPIC_API_KEY(and/orOPENAI_API_KEY) - Target repository is cloned in
repos/<repo-name>/ - (Optional) KB files placed in
example_kb/ - Prompts generated by running
python src/scripts/generate_prompts.py - Tests are configured and runnable for the target repo
KB files are plain text inputs that provide project context to the model.
- Put KB files in
example_kb/(e.g.,example_kb/kb_fastapi.txt). - If you donβt have KB files, you can still run baseline benchmarks.
aspect-bench/
βββ .env.example # Environment template
βββ .gitignore
βββ README.md
βββ CONTRIBUTING.md
βββ LICENSE.md
β
βββ example_kb/ # Optional knowledge base text files
β βββ AGENTS.md # Agent instructions template
β βββ kb_djangopackages.txt # KB for djangopackages repo
β βββ kb_fastapi.txt # KB for fastapi-template repo
β
βββ repos/ # Cloned target repositories (gitignored)
β βββ fastapi-template/ # β Cloned target repo
β β βββ backend/...
β βββ djangopackages/ # β Cloned target repo
β βββ djangopackages/...
β
βββ src/
βββ repos/ # Benchmark harness files (prompts, tasks, tests)
β βββ djangopackages/
β β βββ prompts/ # Generated prompts (*_baseline.txt, *_aspect.txt)
β β βββ tasks/
β β β βββ *.yaml # β One task definition per file
β β βββ tests/
β β
β βββ fastapi-template/
β βββ prompts/
β βββ tasks/
β β βββ *.yaml # β One task definition per file
β βββ tests/
β
βββ scripts/ # Main scripts
β βββ run_benchmark.py # Main benchmark runner
β βββ generate_prompts.py # Generate prompt files from tasks
β βββ generate_report.py # Generate markdown reports
β βββ run_tests_for_task.py # Test runner utility
β βββ load_task_defs.py # Task/repo registry
β
βββ results/ # Benchmark results (gitignored)
βββ responses/ # LLM responses (gitignored)
βββ reports/ # Generated reports (gitignored)
Main entry point for running benchmarks.
# Full benchmark for a repo
python src/scripts/run_benchmark.py --repo fastapi-template --provider anthropic
# Single task test (use task ID from the task YAML file)
python src/scripts/run_benchmark.py --repo fastapi-template --tasks missing-item-404 --provider anthropic
# Multiple specific tasks
python src/scripts/run_benchmark.py --repo fastapi-template --tasks missing-item-404 add-csv-export --provider anthropic
# All repos
python src/scripts/run_benchmark.py --all-repos --provider anthropicArguments:
--repo: Repository name (from REPO_REGISTRY)--tasks: Space-separated task IDs (optional, defaults to all)--provider:anthropicoropenai--all-repos: Run all registered repositories
Generate prompt files from task definitions. Must run before benchmarking.
python src/scripts/generate_prompts.pyGenerate human-readable markdown reports from benchmark results.
python src/scripts/generate_report.py --experiment-id 20241201_143022Task IDs are defined in the task_defs.yaml file for each repository:
# Example from src/repos/fastapi-template/tasks/task_defs.yaml
tasks:
- id: missing-item-404 # β This is the task ID
name: "Return 404 for missing items"
description: |
Modify the items endpoint to return 404 when item not found...
- id: add-csv-export # β Another task ID
name: "Add CSV export endpoint"
...To list all task IDs for a repo:
# Using grep
grep "^ - id:" src/repos/fastapi-template/tasks/task_defs.yaml
# Or view the full file
cat src/repos/fastapi-template/tasks/task_defs.yamlEach benchmark run creates:
results/
βββ aspect_ab_experiment_<experiment_id>.json
responses/
βββ <repo>_<task_id>_<mode>_<experiment_id>.txt
reports/
βββ <experiment_id>/
βββ report.md
Generated reports include:
- Side-by-side comparison of baseline vs aspect KB results
- Test pass/fail counts before and after changes
- Regression analysis (did existing tests break?)
- Code diffs for both approaches
- Winner determination with analysis
| Provider | Environment Variable | Models |
|---|---|---|
| Anthropic | ANTHROPIC_API_KEY |
Claude 4 Sonnet, Claude 4.5 Opus |
| OpenAI | OPENAI_API_KEY |
GPT-4o, o1, o3 |
MIT License - see LICENSE.md
Contributions welcome! Please read CONTRIBUTING.md before submitting PRs.