Skip to main content
Moss embeds text on-device with built-in models (moss-minilm, moss-mediumlm). If you already generate embeddings elsewhere - a proprietary model, a hosted embedding API, or a shared pipeline across services - use model_id="custom" to supply your own vectors. Moss indexes and searches them; it does not load a local model.

How it works

  • At index time, every document must carry its own embedding. With model_id="custom", Moss does not embed for you. (If you omit model_id and every document has an embedding, Moss infers "custom" automatically; mixed documents are rejected.)
  • At query time, you must pass the query vector via QueryOptions.embedding, because there is no local model to embed the query text.
  • All vectors must share the same dimensionality.

Example

import asyncio
from moss import DocumentInfo, MossClient, QueryOptions

def embed(text: str) -> list[float]:
    """Your embedding function - any model, as long as dimensions are consistent."""
    ...

async def main():
    client = MossClient(MOSS_PROJECT_ID, MOSS_PROJECT_KEY)

    # Index with precomputed vectors. model_id="custom" -> Moss does not embed.
    docs = [
        DocumentInfo(id="1", text="Customer asked about billing", embedding=embed("Customer asked about billing")),
        DocumentInfo(id="2", text="Refund requested for duplicate charge", embedding=embed("Refund requested for duplicate charge")),
    ]
    await client.create_index("tickets", docs, model_id="custom")
    await client.load_index("tickets")

    # Query with your own query vector (required for custom embeddings).
    q = embed("billing problem")
    results = await client.query("tickets", "billing problem", QueryOptions(top_k=3, embedding=q))
    for doc in results.docs:
        print(f"{doc.id} score={doc.score:.3f} {doc.text}")

asyncio.run(main())

In a session

Sessions support custom embeddings too: open the session with model_id="custom", set .embedding on every document you add, and pass QueryOptions.embedding on every query.
session = await client.session(index_name="conv-123", model_id="custom")
await session.add_docs([DocumentInfo(id="1", text="...", embedding=embed("..."))])
results = await session.query("...", QueryOptions(top_k=3, embedding=embed("...")))
With model_id="custom", adding a document without .embedding, or querying without QueryOptions.embedding, raises a ValueError. create_index_from_files does not support custom embeddings (it embeds server-side).

Local embeddings

Use the built-in on-device models.

Hybrid search

Blend semantic and keyword scoring.