feat: orchestrate grounded recommendations

This commit is contained in:
Justin Visser 2026-08-10 13:09:08 +02:00
parent 751391e6a2
commit cead39edbc
8 changed files with 1098 additions and 7 deletions

View file

@ -2,8 +2,8 @@
Bijgehouden tijdens de bouw. Per blok: wat ik deed, waarom, wat ik heb laten
vallen.
## Opzet (avond dag 1)
## Dag 1 - korte sessie in de avond
### Opzet
Wat ik deed:
@ -34,7 +34,8 @@ Wat ik heb laten vallen of uitgesteld:
waar ze horen. Ik probeer op die manier bewust vroeg drift en dode code te voorkomen.
- Geen apart beslisdocument. De motivering staat in de README en hier.
## Spotify-koppeling (ochtend dag 2)
## Dag 2
### Spotify-koppeling
Wat ik deed:
@ -69,3 +70,39 @@ Wat ik heb laten vallen of uitgesteld:
pipeline-stap; daar bestaat het ontwerp pas echt.
- OpenAPI-codegen voor het contract overwogen en afgewezen: de kern van dit
contract is de event-stream en die modelleert OpenAPI niet.
### Pipeline
Wat ik deed:
- Domeinbasis: titel/artiest-matching (normalisatie, met tolerantie voor
Spotify's versie-suffixen zoals "- Remaster 2023"), compressie van het
Spotify-smaakprofiel naar prompttekst plus een set bekende track-ids,
prompts als data in een eigen module, en alle instelbare waarden
gesectioneerd in de config met per waarde het waarom.
- Twee LLM-aanroepen achter een eigen interface: aanroep 1 interpreteert de
vraag (stemming, activiteit, taal, bekendheid) en stelt 30-40 echte
nummers voor als gestructureerde output; aanroep 2 herordent uitsluitend
geverifieerde nummers en streamt per nummer een eerlijke onderbouwing.
Elke output wordt gevalideerd, met hooguit 1 herstelpoging.
- Grounding: begrensde parallelle zoekslag met vroege stop, een deadline,
een naam-naar-id cache en twee aparte metrieken: niet gevonden versus
wel gevonden maar afgekeurd door de controle. Een track-id dat niet in
de geverifieerde pool zit kan nooit bij de gebruiker terechtkomen.
Waarom:
- De LLM is hier de aanbeveler, maar mag alleen creatief zijn tussen twee
deterministische muren: alles wat hij ziet is echte data, alles wat de
gebruiker ziet is geverifieerd op Spotify. Een verzonnen nummer valt
stilletjes af en verschijnt nooit.
- Zoeken geeft maximaal 10 resultaten per aanroep, dus resolutie is per
definitie een fan-out; liever een kandidaat laten vallen dan het
verkeerde nummer aanbevelen.
Wat ik heb laten vallen of uitgesteld:
- Verfijnvragen doen geen nieuwe zoekslag: turn 2 herordent de bestaande
geverifieerde pool. Sneller en consistent, maar een verfijning haalt
geen nieuwe nummers op. Dit is een bewuste afweging, mocht er tijd over
zijn is dit 1 van de uitbreidingen die ik op zou kunnen pakken.