- Je laat met kleine inproductscores zien hoe een vreemde kaart een gewone top-k-taak verdringt.
- Je begrenst de zoekruimte vooraf en onderscheidt lokale vergelijkingssporen van echte autorisatie.
Twee bedrijven gebruiken dezelfde zoektoepassing. Jij werkt voor bedrijf a en zoekt een eigen kaart, maar een kaart van bedrijf b lijkt nog beter op je vraag. Die vreemde kaart mag niet bepalen welke eigen informatie je te zien krijgt.
Een tenant is hier één afgeschermde klantomgeving. De toepassing kent jouw tenant al vanuit een afzonderlijk vertrouwde context. Een tenantnaam in je zoektekst of in een opgehaald document verleent geen toegang.
1. Kies eerst in welke kast je zoekt
Stel je twee archiefkasten voor. Eerst in beide kasten de beste kaart pakken en daarna de vreemde kaart weggooien, is iets anders dan meteen in de juiste kast zoeken. In de eerste route kan je eindigen met lege handen, terwijl je eigen kast een bruikbaar antwoord bevat.
We gebruiken kleine tweedimensionale vectoren. De score s is het inproduct van vraagvector q en documentvector v. q₁ en q₂ zijn de twee vraagcoördinaten; v₁ en v₂ horen bij de kaart.
Voor vraag [1,0] krijgt je eigen kaart [2,0] score 2; de vreemde kaart [8,0] krijgt score 8. Dit zijn zelfgekozen oefencoördinaten, geen echte tekstembeddings. Een hogere score betekent hier alleen hoger in onze rangschikking.
def item(name, tenant, vector):
return dict(id=name, tenant=tenant,
source="manual", revision="r1",
text="color=blue",
vector=vector)
records = [
item("eigen", "a", [2, 0]),
item("vreemd", "b", [8, 0]),
]
query = [1, 0]
print(2 * 1 + 0 * 0)
print(8 * 1 + 0 * 0)
# 2
# 8
2. Achteraf verwijderen vult geen plaats aan
De naïeve route rangschikt alle kaarten en bewaart de beste k. Pas daarna verwijdert zij kaarten van andere tenants. Met k=1 wint de vreemde kaart; na verwijderen blijft geen resultaat over.
late = postfiltered_search(
records, query, "a", 1)
print(late["hits"])
print(late["compared_ids"])
# []
# ['eigen', 'vreemd']
Het vergelijkingsspoor laat zien welke kaarten een numerieke score kregen. Dit spoor is uitsluitend instrumentatie van onze lokale oefening. Het is geen advies om vreemde document-id’s of scores aan bezoekers te tonen.
013. Autorisatie bepaalt de zoekruimte
Noem de volledige oefentabel D en de vertrouwde tenant t. Dₜ bevat uitsluitend de records uit die tenant. R is de resultatenlijst; top-k rangschikt haar invoer en neemt hoogstens k kaarten.
De verdedigde route kiest Dₜ vóór het berekenen van scores. Zij vergelijkt de vreemde kaart dus niet. De eigen kaart blijft beschikbaar, ook wanneer een andere tenant een nog hoger scorende kaart toevoegt.
early = scoped_search(
records, query, "a", 1)
print(early["hits"])
print(early["compared_ids"])
# [{'id': 'eigen', 'score': 2}]
# ['eigen']
Beide functies leveren nieuwe resultaten en laten de invoer intact. De gegeven helpers controleren eerst de volledige oefentabel. Dat onderscheid is belangrijk: het numerieke spoor bewijst onze zoekvolgorde, geen afwezigheid van timing- of validatielekken in een echte gedeelde index.
02Vergelijk dezelfde vraag en dezelfde vertrouwde tenant. Links wordt pas na top-k gefilterd; rechts mogen alleen toegestane kaarten meedoen.
Vraag [1, 0] · vertrouwde tenant a · k=1.
Kaarten en de late scoreberekening
| Kaart | Tenant | Vector | Score |
|---|---|---|---|
a-2 | a | [0, 2] | 0 |
b-1 | b | [8, 8] | 8 |
a-1 | a | [2, 0] | 2 |
De score is ons eigen inproduct. Bij k=0 wordt geen kaart gescoord. Het spoor toont alleen de numerieke zoekvolgorde in deze lokale oefening.
1. Alle kaarten → top-k → tenantfilter
Gescoorde ids
a-2, b-1, a-1Resultaten op volgorde
Geen hits
2. Tenantfilter → scoren → top-k
Gescoorde ids
a-2, a-1Resultaten op volgorde
a-1score 2
Na laat filteren blijft geen hit over, terwijl vooraf begrenzen wel een eigen kaart behoudt.
Een tenantnaam in een document of zoektekst verleent geen rechten. De gekozen tenant is hier apart vertrouwde oefencontext; deze tabel bouwt geen echte authenticatie of gedeelde index.
Alle kaarten, tenants, receipts, meetrijen en claims zijn eigen oefengegevens. Deze vergelijking doet geen echte zoek- of netwerkopdracht.
4. Bewaar ook de gewone taak
Alles weigeren voorkomt de verkeerde kaart, maar helpt de leerling niet zoeken. Toegestane kaarten moeten op hun eigen score blijven verschijnen. Bij gelijke scores kiezen we alfabetisch op id, zodat een andere invoervolgorde geen willekeurige winnaar maakt.
records.append(item(
"ander", "a", [2, 0]))
reply = scoped_search(
records, query, "a", 2)
print([r["id"] for r in reply["hits"]])
# ['ander', 'eigen']
Een ontbrekende tenant heeft terecht geen hits. Met k=0 wordt nog steeds de invoervorm gecontroleerd, maar er worden geen scores berekend. Onze bovengrenzen zijn twaalf records, twee gehele coördinaten tussen -8 en 8 en k tussen 0 en 6.
Samenvatting
- Een vertrouwde tenantscope bepaalt welke kaarten mogen meedoen vóór de rangschikking.
- Achteraf filteren kan een gewone taak verdringen, ook zonder vreemde tekst terug te geven.
- Controleer zowel de begrenzing als het behouden van toegestane resultaten.
In de volgende les onderzoek je welke inhoud überhaupt in de beoordeelde verzameling thuishoort.