Faculytics Docs

Embedding Worker Overview

LaBSE embedding contract — request/response schemas, error handling, and deployment.

Source of Truth: src/modules/analysis/dto/analysis-job-message.dto.ts (request) and src/modules/analysis/dto/analysis-result-message.dto.ts (response)

Endpoint

POST {EMBEDDING_WORKER_URL}/embeddings

Request

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "version": "1.0",
  "type": "embedding",
  "text": "The professor explains concepts clearly.",
  "metadata": {
    "submissionId": "660e8400-e29b-41d4-a716-446655440001",
    "facultyId": "faculty-001",
    "versionId": "version-001"
  },
  "publishedAt": "2026-03-14T00:00:00.000Z"
}

Fields

FieldTypeRequiredDescription
jobIdstring (UUID)YesUnique job identifier from BullMQ
versionstringYesContract version
typestringYesAlways "embedding"
textstring (min 1)YesQualitative comment text to embed
metadataobjectYesProvenance metadata
metadata.submissionIdstringYesSource submission ID
metadata.facultyIdstringYesFaculty member being evaluated
metadata.versionIdstringYesQuestionnaire version ID
publishedAtISO datetimeYesWhen the job was published

Response (Success)

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "version": "1.0",
  "status": "completed",
  "result": {
    "embedding": [0.0123, -0.0456, 0.0789, "... (768 floats)"],
    "modelName": "LaBSE"
  },
  "completedAt": "2026-03-14T00:01:00.000Z"
}

Fields

FieldTypeRequiredDescription
jobIdstringYesEchoed from request
versionstringYesEchoed from request
statusenumYes"completed" or "failed"
resultobjectOn successEmbedding output
result.embeddingnumber[768]YesL2-normalized 768-dimensional vector
result.modelNamestringYesModel short name (e.g. "LaBSE")
completedAtISO datetimeYesProcessing completion timestamp

Error Response

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "version": "1.0",
  "status": "failed",
  "error": "Model not loaded. Call load() first.",
  "completedAt": "2026-03-14T00:01:00.000Z"
}

Domain errors (model failure, empty text) return HTTP 200 with status: "failed" to prevent BullMQ retries. Only unexpected infrastructure failures return HTTP 5xx.

Simple Endpoint

A lightweight endpoint is available for direct embedding without job metadata:

POST {EMBEDDING_WORKER_URL}/embed

// Request
{ "text": "Maayo ang pagtudlo sa propesor." }
 
// Response
{
  "embedding": [0.0123, -0.0456, "... (768 floats)"],
  "modelName": "LaBSE",
  "completedAt": "2026-03-14T00:01:00.000Z"
}

This endpoint is used by internal tooling (e.g. topic modeling) and does not follow the job envelope contract.

Health Check

GET {EMBEDDING_WORKER_URL}/health

// Model loaded
{ "status": "ok", "model": "LaBSE" }
 
// Model not yet loaded (HTTP 503)
{ "status": "unavailable", "model": null }

Notes

  • Embeddings are L2-normalized — cosine similarity reduces to dot product
  • The 768-dim vectors are consumed downstream by the topic modeling worker for UMAP + HDBSCAN clustering
  • One embedding per job (single text), unlike sentiment/topic workers which are batch
  • The API's EmbeddingProcessor extracts result.embedding and result.modelName from the response

Deployment

  • Platform: CPU (no GPU required — ONNX backend)
  • Model: sentence-transformers/LaBSE with ONNX runtime
  • Docker: Multi-stage build, PyTorch weights stripped (ONNX-only)
  • Port: 5201

Versioning

The result.modelName field identifies the model used. The API stores this for provenance tracking alongside the embedding vector.