Sentiment & Emotions
Hub can classify open-text feedback into a sentiment label and score, and into the emotions it expresses, and store them on the feedback record for analytics and filtering.
Hub can enrich open-text feedback with two related classifications: sentiment — the overall polarity of the text — and emotions — the specific emotions it expresses. Both run asynchronously and are stored on the same feedback record, so you can filter, segment, and aggregate qualitative feedback without reading every response.
They are independent enrichments: a deployment can run either, both, or neither, and each is separately gated per tenant.
The fields
Section titled “The fields”Sentiment and emotions add three read-only fields to every feedback record. All are server-generated — you never set them when creating or updating a record — and are null until the record is enriched.
| Field | Type | Description |
|---|---|---|
sentiment | String | Overall sentiment label of the text (for example positive, neutral, negative). |
sentiment_score | Number | Signed polarity from -1.0 (most negative) to 1.0 (most positive). |
emotions | Array of String | The emotions the text expresses; empty when none clearly apply (stored as null, never []). |
See the API Reference for the exact sentiment and emotions value sets.
Enabling
Section titled “Enabling”Each enrichment runs only where the deployment has a provider configured — an operator sets SENTIMENT_PROVIDER + SENTIMENT_MODEL and/or EMOTIONS_PROVIDER + EMOTIONS_MODEL (plus provider credentials); see Environment Variables. With no provider, that enrichment is off for the whole deployment.
Where a provider is configured, each enrichment is on by default per tenant and can be turned off with the sentiment_enabled / emotions_enabled switches. Setting a switch to false stops Hub producing that enrichment for the tenant going forward; unset (or null) means enabled.
How it works
Section titled “How it works”When a text feedback record is created, or its value_text changes, Hub enqueues the enrichment jobs for whichever of sentiment and emotions are enabled. A background worker calls the provider and writes the result back to the record. The work happens off the ingestion path, so creating feedback is never slowed down or blocked.
- Only open text is classified — records whose
field_typeistextwith a non-emptyvalue_text. Numeric, boolean, date, and categorical answers are left untouched. - Edits re-classify. Changing
value_textclears the stored sentiment/emotions and re-runs the classification; emptyingvalue_textclears them without re-running. During the brief window between the edit and the worker finishing, the fields read back asnull(recomputing) rather than a stale value. - A record can express several emotions, or none.
emotionsis a set (order is not significant); “no clear emotion” isnull, not an empty array.
Backfilling existing records
Section titled “Backfilling existing records”Enrichment runs automatically on new and edited records. To (re)classify an existing backlog — after first enabling an enrichment, or to recover records whose job was lost or finally failed — run the bundled backfill for the type, which enqueues jobs for records missing that classification:
# Run inside the Hub deployment, with the SENTIMENT_*/EMOTIONS_* provider and DATABASE_URL configured./backfill-classify -type sentiment./backfill-classify -type emotionsIt is safe to re-run: records already classified are skipped. Re-enabling a tenant’s switch does not re-classify its backlog on its own — run the backfill to catch records edited while the enrichment was off.
Relationship to translation and embeddings
Section titled “Relationship to translation and embeddings”Sentiment and emotions are independent of translation and of the embeddings used for semantic search. All classify the original, source-language value_text; enabling or disabling one does not affect the others.
Querying
Section titled “Querying”Because the results live on the record, you can filter and aggregate straight from SQL or any connected BI tool:
SELECT sentiment, COUNT(*)FROM feedback_recordsWHERE field_type = 'text' AND tenant_id = 'org-123' AND sentiment IS NOT NULLGROUP BY sentiment;Next Steps
Section titled “Next Steps”- Tenant Settings - Toggle
sentiment_enabled/emotions_enabledper tenant - Data Model - How feedback records are stored, including enrichment fields
- Environment Variables - Configure the sentiment and emotion providers