
Graph & raw embeddings
Sentence embeddings aren't the only vectors. Curiosity ships three embedding indexes — they differ only in where the vector comes from, and all expose the same ISimilarityIndex surface, so a similar-items lookup looks identical regardless of which you query.
| Index | Vector source | Use when |
|---|---|---|
| Sentence Embeddings | A transformer encodes a text field | Recommend by meaning — names, summaries, bodies |
| Graph Embeddings (PageSpace) | Self-supervised over graph topology | Recommend by behaviour — "customers who behave like this one" |
| Raw Embeddings | You supply the vectors | You already have embeddings or a model we don't ship |
Sentence vs. graph is the key recommendation choice:
- "Products with similar descriptions" → Sentence. Text drives it.
- "Products bought by similar customers" → Graph (PageSpace). Topology drives it; text is irrelevant.
PageSpace trains on random walks through edges you choose, so you define what "similar" means:
var index = await Graph.Indexes.AddPageSpaceEmbeddingsIndexAsync(
nodeType: N.Customer.Type, setting: settings);
index.SetNodesAndEdges(
edgesToFollow: new[] { E.Placed, E.Contains, E.OpenedCase },
nodesToFollow: new[] { N.Customer.Type, N.Order.Type, N.Product.Type, N.SupportCase.Type });
await index.TrainAsync(progressLogger: msg => Logger.LogInformation(msg));
PageSpace is not auto-trained on commit — call TrainAsync once you have data, then refresh periodically from a scheduled task. New nodes get vectors predicted in real time as they're committed.