Skip to main content
Embed is a first-party Plot Plugin that turns text into unit-normalized vectors. Use it to prepare Plot data for retrieval, similarity, classification, and clustering workflows.
Embed is currently an internal Plot Plugin. Its SQL and materialization contracts may change before it is included in customer documentation.
Embedding consumes an external model service. Filter invalid input and keep a LIMIT while developing, then set budgets on scheduled Plots.

Embed text

Only input is required. Omitted model coordinates use the platform’s default embedding model, and purpose defaults to document.
Embed issue titles
Named arguments use => and cannot be mixed with positional arguments. The defaults are the platform’s default embedding model in the Workspace’s AI policy. Embedding models are platform-wide: a Workspace sets no default for embed(). The output dimensions come from that model identity and are not a call-site argument. With the platform default, the return type is a nullable, unit-normalized FixedSizeList<Float32, 768>. server => 'vertex' runs on the VERTEX processor, in the Workspace’s own Vertex project when it has one. server => 'openrouter' runs on OPENROUTER_ZDR: every call asks OpenRouter for zero data retention, no data collection, and providers that honour every parameter. The Workspace’s AI policy lists the processors embed() may use; production allows only vertex. A call the policy refuses, and any call while the Workspace’s policy cannot be read, is refused while the query is planned with QL-MP-001 or QL-MP-002, as for Ponder. NULL or empty input returns NULL. If a provider batch fails, the affected cells become NULL and the rest of the query continues. A call that cannot reach its provider at all fails the query with its cause and returns no vectors. This happens, for example, when a vertex call has no Vertex project or an openrouter call has no API key. A scheduled run fails with QR-QU-010 and is charged nothing. A call whose inputs are all NULL or empty sends no request, so it still returns NULL vectors. A scheduled run also fails with QR-QU-010 when the provider answers a request with HTTP 401, 403 or 404: credentials it does not accept, a project without access to the model, or a model it does not serve. No retry changes that answer, so each attempt of the site’s batch stops at its first request instead of retrying every row (PARABLE-5328).

Match the embedding purpose

Use document for stored source text and query for a search phrase.
Embed a search query
Compare each row with one search phrase by giving the phrase its own call. The phrase is a constant input, so it is embedded once, not once per row:
Rank issues by distance from a search phrase
Supported purposes are: Parable maps these values onto each embedding service’s task vocabulary. A service that does not expose task types receives no service-specific value. Any other purpose, an unknown argument name, or a server other than vertex or openrouter is refused while the query is planned. Through Query Layer it returns gRPC INVALID_ARGUMENT with error code QL-PL-013 (INVALID_FUNCTION_ARGUMENT). The message names the argument and what it must be, never the value you gave.

Keep vector identities compatible

Vectors are comparable only when they share provider, name, variant, version, dimensions, and normalization. server controls routing and does not change vector identity. embed() stamps that identity on its output column. A query that compares vectors from two different models fails while it plans, before any input is embedded, with INVALID_ARGUMENT and error code QL-PL-008 (INCOMPARABLE_EMBEDDING_MODELS). The message names both models. Equal dimensions are not enough:
Refused: two model versions
The check covers array_distance. A vector without an identity, such as a literal vector, is compared on its dimensions alone, and Parable logs and counts the comparison. A scheduled Plot keeps its embed() vectors in the Plot table itself; Parable does not create a separate vector table for them. The Plot records the vector type and the model that wrote the column, so a query reads the column back as a FixedSizeList<Float32> of the model’s dimensions, and the check judges it like any embed() output:
Refused: a Plot column and another model version
A Plot last run before Plots recorded the model holds the column as text, and a query that reads that column fails until the Plot runs again.

Execution and limits

Interactive queries and scheduled Plot runs batch inputs, up to EMBED_BATCH_SIZE (32) texts a request, and cap concurrent provider requests. Scheduled Plot runs pin model identity and purpose, account successful embedding work, and persist the vectors and the model identity in the Plot table. embed() is Stable: the same text under the same model and purpose gives the same vector. A query that names the same call twice in one SELECT list sends each text once. The same call in a SELECT and its WHERE is evaluated by two plan operators, so a query sends those texts twice. A scheduled run sends each distinct text once wherever the call sits, because its inference site memoizes every answer. A constant input, such as a search phrase, is one text. A query sends it once for each batch of rows the engine passes to embed(), at most EMBED_BATCH_SIZE × EMBED_MAX_CONCURRENCY rows (128 by default), and every row reads its vector. A scheduled run sends it once. A NULL or empty constant returns NULL on every row without a request. The service rejects calls above its configured row cap. Model and purpose must be constant for the invocation; input can vary by row or be constant. Run embed() with the same SDK query method as any other Parable SQL. See Query with the SDKs.