Skip to content

Add semantic search over your records

Rank records by meaning, not keywords: embed a text field into a vector, then search by cosine similarity. The platform ships the pieces — a vector field type, the embed_field action to populate it from an embeddings service, and a similarity-search endpoint.

An OpenAI-compatible embeddings endpoint, allow-listed like any outbound service:

{
"name": "Embeddings",
"service_type": "rest",
"base_url": "https://api.openai.com",
"auth_type": "bearer",
"auth_config": {"token": "<api-key>"},
"headers": {"Content-Type": "application/json"}
}

Declare a vector field whose dimension matches the embedding model’s output (for example 1536 for text-embedding-3-small). Cosine is the only supported metric, and the dimension cap is 8192:

{"name": "notes_vec", "type": "vector", "settings": {"dimension": 1536, "metric": "cosine"}}

Publish the model after adding the field.

3. Embed on write with the embed_field action

Section titled “3. Embed on write with the embed_field action”

A rule on record_create / record_update (phase post_save) turns the source text into a vector and writes it to the target field. The action posts to the service and reads the float array at response_path:

{
"type": "embed_field",
"params": {
"service_config_id": "<embeddings-service-uuid>",
"source_field": "notes",
"target_field": "notes_vec",
"path": "/v1/embeddings",
"model": "text-embedding-3-small",
"response_path": "data.0.embedding"
}
}

The source text is sent as the request body’s input (or prompt, if that key is present). A _{target_field}_embed_meta companion field records a hash of the source so unchanged text is not re-embedded.

Embed the query with the same service, then rank records by cosine distance:

POST /api/v1/applications/{application_id}/models/{model_id}/records/search
{"field": "notes_vec", "vector": [0.0123, -0.0456, 0.0789], "top_k": 10}

The vector is the query text embedded by the same service (shortened above); its length must equal the field’s dimension.

Results come back ordered by similarity with a _score per record. The query vector’s length must equal the field’s dimension.

Similarity is computed in application memory over the JSON-stored vectors (there is no ANN index), which is fine at demo and moderate scale; size accordingly for large collections. And embedding quality is the model’s, not the platform’s: a general chat model makes a poor embedder (scores cluster and ranking blurs), so use a dedicated embeddings model in production.