Skip to content

5.7 keyTransform — rewriting the key into the source's own query language

A source’s query language is a property of the source, not of any question asked of it. Put the knowledge in a lens and every lens re-implements it; declare it on the producer and every surface — lenses, chat, MCP — gets the same translation, with no code shipped by the realm.

ClinicalTrials.gov reads AND / OR / NOT as operators only in UPPERCASE. So parkinsons and anxiety returns 2 trials where Parkinson AND anxiety returns 64, and respiratory diseases other than covid returns 0 where a NOT expression returns 51,961. The danger is the shape of the failure: a plausible number rather than an error, with a confident answer built on top of it.

- name: trialsByDisease
kind: remote
operation: searchByDisease
keyArg: queries
echoKeyAs: matchedFor # REQUIRED with a transform — see "identity" below
keyTransform:
kind: ai
instruction: |
Rewrite a disease phrase as a ClinicalTrials.gov Essie expression.
AND / OR / NOT are operators and MUST be uppercase; quote multi-word phrases.
examples: # few-shot pairs YOU author: the cheapest way to pin a dialect
- input: "parkinsons and anxiety"
output: '(Parkinson Disease OR Parkinsonism) AND (Anxiety OR "Anxiety Disorders")'
cacheSeconds: 604800

Identity is never rewritten. The transform applies to the outgoing argument only; the key’s identity — what the join matches on, and what echoKeyAs stamps onto each record — stays the caller’s phrase. Get this wrong and the failure is silent: if your records echo the sent string, they no longer match the anchor’s keyField, the join edge never forms, and every row vanishes while the query still reports success. A producer that declares keyTransform must also declare echoKeyAs (or otherwise guarantee its records carry the original key).

Three rules keep it honest, and none is optional:

  • Cached per phrase, so the same question searches the same way instead of being re-rolled.
  • Echoed, so the executed expression can be shown and challenged. Surface it — a rewrite a user cannot see is one they cannot argue with.
  • Falls back verbatim on any failure, to the behaviour you had before, never to an empty result that would read as “there is nothing”.

The cost to accept: a model now sits in the key path, so a fetch is no longer purely determined by the query text. The cache and the echo are what make that auditable.