Skip to content
All projects

Shipped · Mar 2026

SynthDrive

You describe a driving scenario in plain English, and it generates a 3D world, runs object detection on it, and scores how hard that scene is to perceive.

The problem

Testing how an autonomous vehicle perceives edge cases usually means capturing those situations in the real world, which is expensive, slow, and in some cases dangerous. The scenarios you most need to test, like a pedestrian at night or heavy glare or an occluded object, are exactly the ones you cannot arrange whenever you want.

What I built

I built a pipeline that chains four AI systems together. GPT-4o takes a one line prompt and expands it into three scenario variants that each target a different perception challenge. World Labs Marble turns those into navigable 3D worlds. YOLOv8 runs object detection on the generated scenes. Then GPT-4o reads the detection results and produces a Perception Difficulty Score from 0 to 100, along with a risk level and recommendations.

Why generate the world instead of filming it

The perception failures worth testing are the rare ones. If you want footage of a pedestrian stepping out in low light with glare on the windshield, you have to wait a long time for it and accept some real risk to get it. Generating the scene instead means the hard case is available whenever you want it and it is reproducible, which is what a test suite actually needs.

Four models, one contract between each

Each stage hands the next one a narrow artifact that I can check on its own. First text scenarios, then world assets, then bounding boxes with confidence values, then a score. Keeping those handoffs small is what makes a four model chain debuggable. When a run looks wrong, it is usually obvious which stage produced the bad output.

Detection as a separate service

YOLOv8 runs in its own FastAPI microservice instead of inside the Next.js app, so the computer vision runtime and the web runtime can scale and deploy separately. The detection server URL is configurable, which is what allowed me to move it onto Render without changing any app code.

Making the output a decision, not a dump

Raw bounding boxes do not tell an engineer whether a scenario is actually dangerous. The final GPT-4o pass turns the detections into one Perception Difficulty Score with a risk level and specific findings, so the result of a test run is something you can act on rather than a pile of output.

Outcome

  • Built at BigThink (UMD) x World Labs in March 2026 and deployed live
  • Generates three 3D worlds in parallel in roughly 45 seconds
  • Returns a 0 to 100 perception score with low, medium, high, or critical risk levels
  • Saves full test history per user, enforced by Supabase row level security

Stack

Next.js 14TypeScriptTailwind CSSFastAPIYOLOv8OpenAI GPT-4oWorld Labs Marble APISupabasePostgreSQLRender

Data flow

Four AI systems chained into one test run

  1. 1

    Prompt

    Natural-language scenario, or a preset

  2. 2

    Scenario generation

    GPT-4o expands it into 3 variants targeting different perception challenges

  3. 3

    3D world generation

    World Labs Marble API produces panoramic imagery and Gaussian splat assets, 3 worlds in parallel

  4. 4

    Detection

    YOLOv8 via a FastAPI microservice on Render, bounding boxes + confidence

  5. 5

    Safety analysis

    GPT-4o turns detections into a 0-100 score, risk level, findings

  6. 6

    Persistence

    Supabase Auth + Postgres with row-level security per user

Next.js 14TypeScriptTailwind CSSFastAPIYOLOv8OpenAI GPT-4oWorld Labs Marble APISupabasePostgreSQLRender

This diagram is generated from portfolio.ts. Edit the `architecture` field to change it.

Want the deeper version of this?

I am happy to walk through the tradeoffs, the failure modes, and what I would do differently.

Email me