Discourse AI - Sentiment

:bookmark: Questo argomento copre la configurazione della funzionalità Sentiment del plugin Discourse AI.

:person_raising_hand: Livello utente richiesto: Moderatore

Sentiment tiene traccia della tua community analizzando i post e fornendo punteggi di sentiment ed emozione per darti un’idea generale della tua community per qualsiasi periodo di tempo. Queste informazioni possono essere utili per determinare il tipo di utenti che pubblicano all’interno della tua community e interagiscono tra loro.

Funzionalità

  • Sentiment generale: confronta il numero di post classificati come positivi o negativi
  • Grafico a barre che mostra il valore numerico attivabile per i punteggi positivi, negativi e generali
  • Emozione: numero di argomenti e post classificati da più emozioni, raggruppati per lasso di tempo
    • Oggi
    • Ieri
    • Ultimi 7 giorni
    • Ultimi 30 giorni
  • Report per qualsiasi lasso di tempo accessibili tramite le impostazioni
    • Annuali
    • Trimestrali
    • Mensili
    • Settimanali
    • Intervallo personalizzato
  • Accessibile a tutti gli utenti dello staff (amministratori e moderatori)

Abilitazione di Sentiment

Configurazione

Sentiment è abilitato di default per i clienti ospitati. Per i passaggi manuali vedere sotto

  1. Vai alle impostazioni AdminPlugins → cerca o trova discourse-ai e assicurati che sia abilitato
  2. Abilita ai_sentiment_enabled per l’Analisi del Sentiment
  3. Vai su /admin/dashboard/sentiment per vedere i rispettivi report

:information_source: Una volta abilitato, Sentiment classificherà automaticamente tutti i nuovi post e riempirà retroattivamente i post degli ultimi 60 giorni tramite un processo pianificato che viene eseguito ogni 5 minuti. Per riempire i post più vecchi di 60 giorni, aumenta l’impostazione del sito ai_sentiment_backfill_post_max_age_days.

:discourse2: Ospitato da noi?

Contattaci a team@discourse.org se hai bisogno di aiuto per regolare le impostazioni di riempimento retroattivo.

:mechanic: Self-hosted?

Aumenta ai_sentiment_backfill_post_max_age_days nelle impostazioni del tuo sito per coprire l’intervallo di tempo desiderato. Il processo pianificato di riempimento retroattivo elaborerà automaticamente i post più vecchi. Per i dettagli su come impostare gli endpoint del modello richiesti, consulta Self-Hosting Sentiment and Emotion for DiscourseAI.

FAQ Tecniche

Come vengono elaborati i dati di argomenti/post? Come vengono assegnati i punteggi?

  • Sentiment ha una fedeltà “per post”. Per ogni post siamo in grado di determinare il sentiment e quindi suddividere tali dati in molte forme (per tag / categoria / tempo ecc…). Confronta il numero di post classificati come positivi o negativi. Questi vengono calcolati quando i punteggi positivi o negativi superano una soglia fissa di 0,6 (attualmente non configurabile).

Ci sono piani per aggiungere il supporto per altre lingue?

  • In futuro Sì! Sia aggiungendo modelli di apprendimento automatico (ML) semplici multilingue sia utilizzando modelli linguistici di grandi dimensioni (LLM) multilingue per classificare i dati, invece di modelli dedicati.

Quali modelli vengono utilizzati per alimentare Sentiment?

Avvertenze

  • I post classificati come neutri (né positivi né negativi) non vengono mostrati
  • I messaggi privati (PM) sono esclusi dai calcoli
10 Mi Piace

Un post è stato unito a un argomento esistente: Problemi con il backfill del sentiment

Un post è stato unito a un argomento esistente: Problemi con il riempimento retroattivo del sentiment

L’OP è stato aggiornato con un nuovo video che mostra le funzionalità aggiornate di Sentiment, incluse molte più emozioni e la comprensione di quali argomenti/post sono associati a ciascuna emozione.

Ho configurato il sentiment model config con un model_name, endpoint e api_key copiati dalle impostazioni LLM, dove passa il test, ma ottengo l’errore sottostante nei /logs.

(Ma forse non capisco correttamente, perché il sentiment non usa uno degli LLM configurati?)

Utilizzo claude-3-5-sonnet.


{"type":"error","error":{"type":"invalid_request_error","message":"anthropic-version: header is required"}} (Net::HTTPBadResponse)
/var/www/discourse/plugins/discourse-ai/lib/inference/hugging_face_text_embeddings.rb:71:in `classify'
/var/www/discourse/plugins/discourse-ai/lib/sentiment/post_classification.rb:142:in `request_with'
/var/www/discourse/plugins/discourse-ai/lib/sentiment/post_classification.rb:78:in `block (4 levels) in bulk_classify!'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:1593:in `evaluate_to'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:1776:in `block in on_resolvable'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:359:in `run_task'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:350:in `block (3 levels) in create_worker'
internal:kernel:187:in `loop'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:341:in `block (2 levels) in create_worker'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:340:in `catch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:340:in `block in create_worker'
Status: 400

{"type":"error","error":{"type":"invalid_request_error","message":"anthropic-version: header is required"}} (Net::HTTPBadResponse)
/var/www/discourse/plugins/discourse-ai/lib/inference/hugging_face_text_embeddings.rb:71:in `classify'
/var/www/discourse/plugins/discourse-ai/lib/sentiment/post_classification.rb:142:in `request_wit...

Il modulo di sentiment non utilizza LLM generici, ma modelli specificamente ottimizzati per la classificazione del sentiment. Se desideri eseguire tali modelli autonomamente, la documentazione è disponibile su Self-Hosting Sentiment and Emotion for DiscourseAI

3 Mi Piace

@Falco Ho appena notato che il sentiment ha smesso di funzionare a partire da gennaio 2025. La mia ipotesi è che ci sia questa nuova impostazione ai_sentiment_model che, come spiega il link sopra, serve per far funzionare un proprio modello di sentiment/dizione. Ho notato che dopo aver aggiornato discourse ora ai_sentiment_model_configs è tutto vuoto (dovrebbe esserlo?).

Quando provo a eseguire un rake di backfill, ricevo un errore:

rake ai:sentiment:backfill
rake aborted!
ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR:  errore di sintassi vicino a ")" (ActiveRecord::StatementInvalid)
LINE 1: ...e_upload_id", "posts"."outbound_message_id" FROM () as posts..

Il plugin utilizzava per impostazione predefinita un server situato in DigitalOcean che avevo allestito per facilitare i test.

Da allora ho modificato le impostazioni predefinite del plugin su una base pulita e coloro che desiderano la classificazione AI devono eseguire server seguendo la documentazione qui su Meta.

In effetti, ma stavamo pagando quel costo per scopi di test. Non è sostenibile offrire questo per ogni self-hoster.

Vale la pena menzionare che offriamo questo servizio di classificazione su server con accelerazione GPU come parte del nostro servizio di hosting.

2 Mi Piace

Problemi di analisi del sentiment con Discourse AI: formato del modello Hugging Face e fallimento dell’endpoint Azure


Ciao Community e sviluppatori di Discourse,

Sto riscontrando problemi significativi nel tentativo di configurare e utilizzare la funzionalità di analisi del sentiment all’interno del plugin Discourse AI sul mio forum. Sembra che ci siano due problemi distinti che impediscono il suo corretto funzionamento.


Problema 1: Discrepanza nel formato della risposta del modello Hugging Face

Ho configurato il modello cardiffnlp/twitter-roberta-base-sentiment di Hugging Face per l’analisi del sentiment. Sebbene la mia chiave API sia valida e io possa chiamare con successo l’API dalla mia istanza Discourse utilizzando curl, il plugin Discourse AI sembra analizzare la risposta in modo errato a causa di una modifica nel formato di output del modello Hugging Face.

Il mio comando curl (che conferma la chiave API valida e il nuovo formato):

Bashcurl -X POST https://api-inference.huggingface.co/models/cardiffnlp/twitter-roberta-base-sentiment \ -H "Authorization: Bearer hf_xxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d "{\"inputs\": \"I love Discourse!\"}"

Output da curl (che mostra il nuovo formato di array nidificato):

[[{\"label\":\"LABEL_2\",\"score\":0.9891520738601685},{\"label\":\"LABEL_1\",\"score\":0.009014752693474293},{\"label\":\"LABEL_0\",\"score\":0.0018332178005948663}]]

Problema: Il modello twitter-roberta-base-sentiment restituiva un singolo array di hash label-score: [{\"label\": \"LABEL_2\", \"score\": 0.98}, ...]. Ora restituisce un array nidificato: [[{\"label\": \"LABEL_2\", \"score\": 0.98}, ...]].
La logica di analisi hardcoded del plugin Discourse AI (in particolare, classification[\"label\"][/\\d+/].to_i come indicato dal backtrace) non tiene conto di questo livello di array esterno. Ciò causa un TypeError quando tenta di accedere a un Simbolo come Intero.

Messaggio di errore (dall’eccezione del job):

nessuna conversione implicita di Simbolo in Intero (TypeError)
/var/www/discourse/plugins/discourse-ai/lib/sentiment/post_classification.rb:163:in block in transform_result' /var/www/discourse/plugins/discourse-ai/lib/sentiment/post_classification.rb:163:in each’
/var/www/discourse/plugin…`

Backtrace completo per il problema Hugging Face:

/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:1268:in `raise'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:1268:in `wait_until_resolved!'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:998:in `value!'
/var/www/discourse/plugins/discourse-ai/lib/sentiment/post_classification.rb:93:in `bulk_classify!'
/var/www/discourse/plugins/discourse-ai/app/jobs/scheduled/sentiment_backfill.rb:27:in `execute'
/var/www/discourse/app/jobs/base.rb:316:in `block (2 levels) in perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in `with_connection'
/var/www/discourse/app/jobs/base.rb:303:in `block in perform'
/var/www/discourse/app/jobs/base.rb:299:in `each'
/var/www/discourse/app/jobs/base.rb:299:in `perform'
/var/www/discourse/app/jobs/base.rb:379:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_scheduler-0.18.0/lib/mini_scheduler/manager.rb:137:in `process_queue'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_scheduler-0.18.0/lib/mini_scheduler/manager.rb:77:in `worker_loop'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mini_scheduler-0.18.0/lib/mini_scheduler/manager.rb:63:in `block (2 levels) in ensure_worker_threads'
internal:kernel:187:in `loop'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:341:in `block (2 levels) in create_worker'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:340:in `catch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:340:in `block in create_worker'
nessuna conversione implicita di Simbolo in Intero (TypeError)
/var/www/discourse/plugins/discourse-ai/lib/sentiment/post_classification.rb:163:in `block in transform_result'
/var/www/discourse/plugins/discourse-ai/lib/sentiment/post_classification.rb:163:in `each'
/var/www/discourse/plugin...

Problema 2: La configurazione del modello Microsoft Azure porta a un errore Hugging Face

Quando ho tentato di passare al modello Microsoft Text Analytics nelle impostazioni di Discourse AI, ho riscontrato un errore 404 Resource not found e, sorprendentemente, il backtrace punta ancora a hugging_face_text_embeddings.rb.

Messaggio di errore (dall’eccezione del job):

Job exception: 416 errors
{"error":{"code":"404","message": "Resource not found"}} (Net::HTTPBadResponse)

Frammento di backtrace pertinente (che punta a Hugging Face nonostante il modello Microsoft selezionato):

/var/www/discourse/plugins/discourse-ai/lib/inference/hugging_face_text_embeddings.rb:76:in `do_request!'
/var/www/discourse/plugins/discourse-ai/lib/inference/hugging_face_text_embeddings.rb:51:in `classify_by_sentiment!'
/var/www/discourse/plugins/discourse-ai/lib/sentiment/post_classification.rb:156:in `request_with'

Osservazione: Questo indica che anche quando seleziono e configuro l’endpoint e la chiave API del modello Microsoft, il plugin Discourse AI sembra essere hardcoded o instradare in modo errato le richieste di analisi del sentiment attraverso la logica o gli endpoint specifici di Hugging Face. Ciò impedisce l’utilizzo del modello Microsoft.


Screenshot della configurazione:

Ho allegato uno screenshot delle mie impostazioni di Discourse AI per mostrare la configurazione:

  • Configurazione dettagliata per i modelli AI di sentiment (che mostra sia i modelli Hugging Face che Microsoft) - Ho testato solo con la configurazione del modello Hugging Face o solo con quella del modello Microsoft con lo stesso risultato

Questi problemi rendono la funzionalità di analisi del sentiment di fatto inutilizzabile. Sembra che il plugin richieda un aggiornamento per gestire il nuovo formato di risposta di Hugging Face e per instradare correttamente le richieste quando vengono configurati diversi provider di sentiment.

Qualsiasi assistenza o guida su questi problemi sarebbe molto apprezzata.

Grazie!

2 Mi Piace

Sono curioso di sapere se il reporting del sentiment funziona per altri, o se ho configurato qualcosa in modo errato. Vorrei sapere cos’altro devo controllare o configurare per abilitare il reporting del sentiment, poiché sto ancora riscontrando lo stesso problema.

1 Mi Piace

Stiamo cercando di utilizzare questa funzionalità con Azure AI Language (dalla nostra istanza Discourse self-hosted), poiché stiamo già utilizzando il nostro abbonamento Azure per integrare GPT-4.5 con Discourse (per funzionalità di riepilogo e chatbot):

…ma non stiamo ottenendo dati nella dashboard del sentiment e vediamo questi errori nei log:

Discourse AI: Errors during bulk classification: Failed to classify 208 posts (example ids: 2256, 909, 2270, 2260, 2797) : JSON::ParserError : An empty string is not a valid JSON string.

Il backtrace mostra che Discourse potrebbe tentare di utilizzare HuggingFace - questi sono gli unici modelli supportati al momento?

Grazie,

N

1 Mi Piace

Quindi, l’unico modo per usare questa funzionalità è configurare le proprie istanze dei modelli (che necessitano di istanze GPU ad alta intensità di risorse che sarebbero costose)? Questa funzionalità sembra molto utile, ma sembra che mi costerebbe di più impostarla rispetto al mio attuale hosting di Discourse.

Sì, i modelli supportati sono quelli elencati nell’OP.

Alla fine aggiungeremo il supporto per la classificazione utilizzando LLM per le persone per cui il costo non è un problema.

Bene, l’intera funzionalità è costruita attorno alla classificazione dei post utilizzando modelli ML, quindi sì, hai bisogno di un posto dove eseguirli.

E poiché Discourse può essere eseguito sul VPS più economico in circolazione, l’esecuzione di modelli ML è effettivamente più costosa. Se vuoi avere la funzionalità nel modo più economico possibile, è fattibile eseguirla su un server con solo una manciata di core CPU, purché tu abbia abbastanza RAM per caricare i modelli.

1 Mi Piace

Mi scuso se questa domanda è già stata posta, ma non sono riuscito a trovare un riferimento a dove sia configurabile esattamente il punteggio soglia :sweat_smile:

1 Mi Piace

Sfortunatamente, il punteggio di soglia non è qualcosa che può essere configurato dagli utenti o dagli amministratori. È un valore specifico impostato nella codebase.

1 Mi Piace