What this recipe does
Apple's "Memories" decides what was a memory. This recipe lets you teach the model what counts as an album by feeding it 80 albums you already curated. It groups by EXIF time + GPS + on-device CLIP embedding similarity, then names the album in the style you used for the gold corpus ("brunch with the cousins" not "Sunday morning at 30°N").
Photos never leave your device. EXIF stripping happens after grouping — the artifact only sees the EXIF, not raw pixels, except through CLIP embeddings computed locally.
The spec
{
"output_kind": "json",
"schema": {
"required": ["albums"],
"properties": {
"albums": { "type": "array", "items": {
"required": ["name", "event_type", "photo_ids", "suggested_cover"],
"properties": {
"name": { "type": "string", "maxLength": 60 },
"event_type": { "enum": ["meal", "trip", "work", "home", "event", "misc"] },
"photo_ids": { "type": "array", "items": {"type":"string"} },
"who": { "type": "array", "items": {"type":"string"} },
"suggested_cover": { "type": "string" }
}
} }
}
},
"verifier": {
"album_must_share_time_window": true,
"max_window_hours": 8,
"album_must_share_place_or_subject": true,
"name_style_corpus": "prior-albums.jsonl"
}
}
Compile
kolm compile "camera roll grouper in my naming style" \ --base phi-3-mini-vision \ --pairs ~/.kolm/album-pairs.jsonl \ --style-corpus ~/.kolm/prior-albums.jsonl \ --verifier exif-grounded-clusters,style-faithful-names \ --k-floor 0.80 \ --output photo-grouper.kolm ok wrote photo-grouper.kolm k_score=0.84 signature=hmac-sha256
K-score gate
Run-time profile
Deploy
# iOS shortcut — run on every "Photos batch import" event: const photos = await Photos.getRecent({ since: lastRun }); const out = kolm.run('photo-grouper.kolm', photos.map(p => p.exif)); for (const a of out.albums) { await Photos.createAlbum(a.name, a.photo_ids, a.suggested_cover); }