Discourse AI + Data Explorer?

Ho deciso che volevo una query particolare oggi. Non volendo disturbare troppo i miei ingegneri, ho deciso di chiedere a ChatGPT di scrivermi una query per l’esploratore di dati basandomi su ciò che sapevo e su ciò che sapevo di volere. Sono rimasto piuttosto colpito dal fatto che abbia fatto tutto correttamente (a parte l’aggiunta di un punto e virgola alla fine che non avrebbe dovuto esserci).

Ecco la query che ha creato per me quando le ho fornito alcuni parametri e le ho chiesto di crearmi una query che mi desse un totale progressivo di tutti gli utenti per mese:

SELECT 
    timeframe "Mese, Anno",
    user_count as "Utenti Iscritti Questo Mese",
    SUM(user_count) OVER (ORDER BY TO_DATE(timeframe, 'Month, YYYY'))::integer as "Utenti (Totale Progressivo)"
FROM (
    SELECT 
        TO_CHAR(u.created_at, 'Month, YYYY') as "timeframe",
        count(u.id) as "user_count"
    FROM 
        users u
    GROUP BY 
        timeframe
    ORDER BY
        timeframe
) subquery
ORDER BY 
    TO_DATE(timeframe, 'Month, YYYY')

È stata presa in considerazione l’integrazione dell’IA nell’area dell’esploratore di dati? :slight_smile:

12 Mi Piace

Un post è stato diviso in un nuovo argomento: Potremmo riaprire l’argomento per condividere le query di Explorer?

Ti dispiace condividere il prompt, la versione di ChatGPT e il modello utilizzato con ChatGPT. :slightly_smiling_face:

Ad esempio


ChatGPT August 3 Version
Modello: GPT-3.5
Prompt

Cos’è Discourse Data Explorer?

Completamento

Dal mio ultimo aggiornamento nel settembre 2021, non sono a conoscenza di alcuno strumento o prodotto specifico chiamato “Discourse Data Explorer”. Tuttavia, posso fornire una spiegazione generale basata sulle informazioni disponibili fino a quel momento.

Discourse è un software per forum open-source e moderno che consente alle comunità online di avere discussioni e interazioni. È ampiamente utilizzato per ospitare discussioni, forum di domande e risposte e comunità di supporto. Discourse offre un ricco set di funzionalità per la gestione delle discussioni, il coinvolgimento degli utenti e la moderazione.

Un “Data Explorer” si riferisce tipicamente a uno strumento o una funzionalità che consente agli utenti di interrogare ed esplorare i dati all’interno di un sistema o di una piattaforma. Viene spesso utilizzato nel contesto di database o piattaforme di analisi dei dati.

Dati i due componenti, “Discourse Data Explorer” potrebbe potenzialmente essere uno strumento o un plugin ipotetico che fornisce agli utenti la capacità di esplorare e interrogare i dati all’interno di un forum Discourse. Ciò potrebbe essere utile per gli amministratori della community o per gli analisti di dati che desiderano ottenere informazioni sul comportamento degli utenti, sulle tendenze dei contenuti o su altre metriche relative alle discussioni in corso sul forum.

È importante notare che le mie informazioni potrebbero essere obsolete e potrebbero essersi verificati nuovi sviluppi dopo il mio ultimo aggiornamento. Se “Discourse Data Explorer” è effettivamente un prodotto o una funzionalità reale, ti consiglio di cercare le informazioni più recenti per ottenere dettagli accurati sulle sue capacità e sul suo utilizzo.


Il motivo della richiesta è che hai un’ottima idea ed è stato bello vederla condivisa, ma in futuro altri potrebbero provare a fare un’altra richiesta e la condivisione del prompt, del completamento e dei dettagli di ChatGPT sono necessari se è necessario aiuto per comprendere eventuali problemi.

Nota: sono un moderatore di categoria sul forum OpenAI Discourse, quindi ho molta esperienza con coloro che cercano aiuto con i prompt di ChatGPT. (ref)


La versione di ChatGPT si trova in basso a destra sotto dove viene inserito un prompt

Il modello si trova in alto nella pagina, al centro

image

1 Mi Piace

Non…mi piace questo bot.

1 Mi Piace

Estendendo un po’ questa idea, permettere agli utenti di interagire con le applicazioni utilizzando il linguaggio naturale è praticamente il mio sogno per quanto riguarda l’IA. Con Discourse e il plugin Data Explorer, potrebbe essere possibile ottenere risultati da prompt come “restituisci un elenco di utenti che hanno espresso interesse per la moderazione”. O ancora meglio, “invia un invito al gruppo community_moderation a tutti gli utenti che hanno espresso interesse per la moderazione”.

Tornando a ciò che è possibile ora:

Testando con ChatGPT 3.0 e 3.5, ho ottenuto buoni risultati quando gli ho chiesto di restituire una query PostgreSQL e ho copiato la struttura delle tabelle che mi interessano nel prompt. Ad esempio:

Riassunto

Io: Restituisci una query postgresql che elenchi tutti gli username degli utenti che fanno parte del gruppo “community_moderators” per la seguente struttura del database:

# == Schema Information
#
# Table name: groups
#
#  id                                 :integer          not null, primary key
#  name                               :string           not null

# == Schema Information
#
# Table name: group_users
#
#  id                 :integer          not null, primary key
#  group_id           :integer          not null

# == Schema Information
#
# Table name: users
#
#  id                        :integer          not null, primary key
#  username                  :string(60)       not null

ChatGPT 3.5: Certo, ecco una query PostgreSQL che elenca tutti gli username degli utenti che fanno parte del gruppo “community_moderators” in base alla struttura del database fornita:

SELECT u.username
FROM users u
JOIN group_users gu ON u.id = gu.user_id
JOIN groups g ON gu.group_id = g.id
WHERE g.name = 'community_moderators';

Questa query recupera gli username dalla tabella users unendola alla tabella group_users tramite l’ID utente e quindi unendola alla tabella groups tramite l’ID del gruppo. Filtra i risultati per includere solo gli username degli utenti che fanno parte del gruppo “community_moderators”.

Io: Ecco la struttura delle tabelle topics e posts dell’applicazione:

# == Schema Information
#
# Table name: topics
#
#  id                        :integer          not null, primary key
#  title                     :string           not null

# == Schema Information
#
# Table name: posts
#
#  id                      :integer          not null, primary key
#  user_id                 :integer
#  topic_id                :integer          not null
#  post_number             :integer          not null
#  raw                     :text             not null

Restituisci una query che elenchi tutti gli ID di topic, gli ID di post e gli username per tutti i post creati da membri del gruppo “community_moderators” che indicano un qualche interesse su come moderare discussioni polarizzanti.

ChatGPT 3.5: Per ottenere questo risultato, dovresti unire le tabelle posts, topics, users e group_users in base allo schema fornito. Ecco una query PostgreSQL che recupera le informazioni richieste:

SELECT t.id AS topic_id, p.id AS post_id, u.username
FROM posts p
JOIN topics t ON p.topic_id = t.id
JOIN users u ON p.user_id = u.id
JOIN group_users gu ON u.id = gu.user_id
JOIN groups g ON gu.group_id = g.id
WHERE g.name = 'community_moderators'
  AND (p.raw ILIKE '%moderate%' OR p.raw ILIKE '%polarizing%' OR p.raw ILIKE '%discussion%');

Questa query recupera topic_id, post_id e username per tutti i post creati da membri del gruppo “community_moderators” che contengono determinate parole chiave che indicano un interesse per la moderazione di discussioni polarizzanti. L’operatore ILIKE viene utilizzato per la corrispondenza di pattern case-insensitive nella colonna raw della tabella posts.

Si prega di notare che questa query presuppone che le parole chiave fornite siano indicative dei post desiderati. Potrebbe essere necessario regolare o espandere le parole chiave in base ai criteri specifici.

Io: Scrivi una query che restituisca un conteggio dei post creati in ogni periodo settimanale da settembre 2022, creati da membri del gruppo community_moderators che indicano un qualche interesse su come moderare discussioni polarizzanti.

ChatGPT 3.5: Per ottenere questo risultato, puoi utilizzare la seguente query PostgreSQL per restituire un conteggio dei post creati in ogni periodo settimanale da settembre 2022, creati da membri del gruppo “community_moderators” che indicano un interesse su come moderare discussioni polarizzanti:

SELECT
    DATE_TRUNC('week', p.created_at) AS week_start,
    COUNT(p.id) AS post_count
FROM
    posts p
JOIN
    users u ON p.user_id = u.id
JOIN
    group_users gu ON u.id = gu.user_id
JOIN
    groups g ON gu.group_id = g.id
WHERE
    g.name = 'community_moderators'
    AND (p.raw ILIKE '%moderate%'
         OR p.raw ILIKE '%polarizing%'
         OR p.raw ILIKE '%political%'
         OR p.raw ILIKE '%contentious%'
         OR p.raw ILIKE '%debate%'
         OR p.raw ILIKE '%controversial%'
         OR p.raw ILIKE '%discussion%')
    AND p.created_at >= '2022-09-01' -- Data di inizio: settembre 2022
GROUP BY
    week_start
ORDER BY
    week_start;

Questa query calcola il conteggio dei post creati da membri del gruppo “community_moderators” che contengono le parole chiave specificate in ogni periodo settimanale da settembre 2022. Raggruppa i risultati per settimana e li ordina cronologicamente. Assicurati di regolare i nomi delle colonne e le relazioni tra le tabelle in base allo schema effettivo del tuo database.


I risultati mi sembrano buoni e rappresentano i tipi di query che in passato mi richiedevano molto tempo per scrivere. Presumo che sarebbe possibile addestrare un modello sulla struttura del database di Discourse in modo che i dettagli sulla struttura possano essere omessi dai prompt.

4 Mi Piace

oh questo è fantastico, ho avuto risultati contrastanti con le query SQL di chatGPT data explorer ma farlo in questo modo ha molto senso. non avevo nemmeno pensato di fornire la struttura della tabella e chiedere query PostgreSQL. :woman_facepalming:t2: grazie per il suggerimento @simon :slight_smile:

1 Mi Piace

È possibile visualizzare uno schema completo dei database di discourse?

1 Mi Piace

Ciao @so-jordan-violet, uso semplicemente lo strumento della tabella collassabile (non so come si chiami! lol) sul lato destro nell’interfaccia di modifica delle query di Esplora dati:

2 Mi Piace

Se potessimo ottenere un documento di testo (specialmente se è in formato sql create table) potremmo fornirlo come istruzioni e probabilmente ottenere risultati abbastanza affidabili.

1 Mi Piace

Sì, abbiamo questo elemento nel backlog del team AI dall’inizio di quest’anno. L’idea è quella di ingerire l’intero (o la parte importante) dello schema Discourse nel prompt per consentirgli di creare qualsiasi query.

Abbiamo creato GitHub - discourse/data-explorer-examples: Examples for Discourse Data Explorer per fornire esempi al modello, in modo che possa essere meglio contestualizzato.

7 Mi Piace

Vorrei avere più tempo per esaminare il codebase, ma avete l’SQL memorizzato da qualche parte (pubblicamente) per gli schemi delle tabelle crest?

Sto lavorando su LLM con il mio prodotto/azienda in questo momento e mi piacerebbe giocarci.

1 Mi Piace

oh questo è fantastico. grazie per il link Falco! :slight_smile:

3 Mi Piace

Genero questo direttamente dallo schema

Qualcosa di simile dovrebbe darti un punto di partenza:


Ho esplorato tutti i tipi di approcci per far funzionare questo. Un problema, però, è che GPT 3.5 è così difficile da guidare che si confonde.

Fornirgli lo schema certamente aiuta, ma sto scoprendo che devo essere ultra strategico con gli esempi.

Diregli semplicemente una storia su “come contare gli argomenti archiviati per un utente” finisce per guidare una query come “quanti post ha avuto un utente” verso argomenti archiviati.

Stavo pensando:

graph TD
A[Aggiungi informazioni generiche utili] --> B[Genera embedding per la domanda]
B --> C[Esegui una ricerca di similarità tra gli esempi]
C --> D[Aggiungi 3 esempi al prompt]
D --> E[Aggiungi lo schema al prompt]
E --> F[Poni la domanda]
F --> G[Ottieni SQL]

Ma si scopre che a meno che gli esempi non siano spettacolari e tu non includa controesempi… le cose vanno male.

Sto iniziando a pensare che il meglio che abbiamo per ora sia semplicemente fornirgli lo schema e un preambolo. Forse aggiungere un altro passaggio alla fine per la validazione e il nuovo tentativo della query.

5 Mi Piace

Avresti uno schema completo che mostra i tipi di dati?

Non sono sicuro che rientri nel budget dei token, ci proverò

Con ChatGPT 3.5 ottengo risultati inaspettati quando fornisco lo schema completo. Ad esempio, continua a cercare l’autore dell’argomento nella tabella topic_users.

Ottengo risultati positivi limitando le informazioni nel prompt alle tabelle e alle colonne necessarie per scrivere la query. Inoltre, aggiungendo alcune informazioni aggiuntive su come vengono utilizzate le colonne. Ad esempio:

# Nome tabella: user_actions
#
#  id              :integer          not null, primary key
#  action_type     :integer          not null (:like=1,:was_liked=2,:new_topic=4,:reply=5,:response=6,:mention=7,:quote=9,:edit=11,:new_private_message=12,:got_private_message=13,:solved=15,:assigned=16)
#  user_id         :integer          not null (l'utente a cui attribuire l'azione)
#  target_topic_id :integer
#  acting_user_id  :integer (l'utente che ha eseguito l'azione, ad esempio un utente staff può eseguire un'azione per conto di un utente regolare)
#  created_at      :datetime         not null

Un altro modo per far funzionare questo approccio con il plugin Data Explorer sarebbe far compilare agli utenti un modulo generato dinamicamente che elenca i dati che stanno cercando e le condizioni che vogliono applicare ai dati. Il prompt potrebbe essere generato programmaticamente da Discourse, quindi inviato all’LLM per scrivere la query.

Modifica: @jordan-violet, questo potrebbe essere un punto di partenza utile. Ecco uno schema parziale annotato che funziona per me. Funziona bene finché limito le mie query in modo che possano essere risposte dallo schema fornito. Ho aggiunto dettagli aggiuntivi allo schema per chiarire aspetti che sembrano confondere ChatGPT. Lo svantaggio ovvio di questo approccio è che uno schema completamente annotato supererà il limite di token di ChatGPT 3.5. Ho incluso alcune informazioni nello schema che potrebbero essere omesse per ridurre il numero di token utilizzati.

Riepilogo
# == Schema Information
#
# Nome tabella: application_requests
#
#  id       :integer          not null, primary key
#  date     :date             not null
#  req_type :integer          not null ("http_total"=0,"http_2xx"=1,"http_background"=2,"http_3xx"=3,"http_4xx"=4,"http_5xx"=5,"page_view_crawler"=6,"page_view_logged_in"=7,"page_view_anon"=8,"page_view_logged_in_mobile"=9,"page_view_anon_mobile"=10,"api"=11,"user_api"=12)
#  count    :integer          default(0), not null
#
# Nome tabella: users
#
#  id                        :integer          not null, primary key
#  username                  :string(60)       not null
#  created_at                :datetime         not null
#  updated_at                :datetime         not null
#  name                      :string           (il nome reale dell'utente)
#  last_posted_at            :datetime
#  active                    :boolean          default(FALSE), not null
#  username_lower            :string(60)       not null
#  last_seen_at              :datetime
#  admin                     :boolean          default(FALSE), not null
#  trust_level               :integer          not null
#  approved                  :boolean          default(FALSE), not null
#  approved_by_id            :integer
#  approved_at               :datetime
#  previous_visit_at         :datetime
#  suspended_at              :datetime
#  suspended_till            :datetime
#  date_of_birth             :date
#  ip_address                :inet
#  moderator                 :boolean          default(FALSE)
#  title                     :string
#  locale                    :string(10)
#  primary_group_id          :integer
#  registration_ip_address   :inet
#  staged                    :boolean          default(FALSE), not null
#  first_seen_at             :datetime
#  silenced_till             :datetime
#
# Nome tabella: topics
#
#  id                        :integer          not null, primary key
#  title                     :string           not null
#  last_posted_at            :datetime
#  created_at                :datetime         not null
#  updated_at                :datetime         not null
#  views                     :integer          default(0), not null
#  posts_count               :integer          default(0), not null
#  user_id                   :integer          (l'id dell'utente che ha creato l'argomento)
#  last_post_user_id         :integer          not null (l'id dell'utente che ha creato l'ultimo post nell'argomento)
#  reply_count               :integer          default(0), not null
#  deleted_at                :datetime
#  highest_post_number       :integer          default(0), not null
#  like_count                :integer          default(0), not null
#  category_id               :integer
#  visible                   :boolean          default(TRUE), not null
#  moderator_posts_count     :integer          default(0), not null
#  closed                    :boolean          default(FALSE), not null
#  archived                  :boolean          default(FALSE), not null
#  bumped_at                 :datetime         not null
#  archetype                 :string           default("regular"), not null (può essere impostato su "regular" o "private_message")
#  slug                      :string
#  deleted_by_id             :integer          (l'id dell'utente che ha eliminato l'argomento)
#  participant_count         :integer          default(1)
#  word_count                :integer
#  excerpt                   :string
#  highest_staff_post_number :integer          default(0), not null
#
# Nome tabella: posts
#
#  id                      :integer          not null, primary key
#  user_id                 :integer          (l'id dell'utente che ha creato il post)
#  topic_id                :integer          not null
#  post_number             :integer          not null (indica l'ordine del post nel suo argomento)
#  raw                     :text             not null (il contenuto del post)
#  created_at              :datetime         not null
#  updated_at              :datetime         not null
#  reply_to_post_number    :integer          (il post_number a cui il post è una risposta)
#  reply_count             :integer          default(0), not null
#  deleted_at              :datetime
#  like_count              :integer          default(0), not null
#  bookmark_count          :integer          default(0), not null
#  reads                   :integer          default(0), not null (il numero di volte che il post è stato letto)
#  post_type               :integer          default(1), not null (:regular=1, :moderator_action=2, :small_action=3, :whisper=4)
#  last_editor_id          :integer          (l'id dell'utente che ha modificato per ultimo il post)
#  hidden                  :boolean          default(FALSE), not null
#  hidden_reason_id        :integer          (:flag_threshold_reached=1,:flag_threshold_reached_again=2,:new_user_spam_threshold_reached=3,:flagged_by_tl3_user=4,:email_spam_header_found=5,:flagged_by_tl4_user=6,:email_authentication_result_header=7,:imported_as_unlisted=8)
#  edit_reason             :string
#  word_count              :integer
#  wiki                    :boolean          default(FALSE), not null
#
# Nome tabella: categories
#
#  id                                        :integer          not null, primary key
#  name                                      :string(50)       not null
#  topic_id                                  :integer          (l'id dell'argomento utilizzato per la descrizione della categoria)
#  topic_count                               :integer          default(0), not null
#  created_at                                :datetime         not null
#  updated_at                                :datetime         not null
#  user_id                                   :integer          not null (l'id dell'utente che ha creato l'argomento)
#  topics_year                               :integer          default(0)
#  topics_month                              :integer          default(0)
#  topics_week                               :integer          default(0)
#  slug                                      :string           not null
#  description                               :text
#  text_color                                :string(6)        default("FFFFFF"), not null
#  read_restricted                           :boolean          default(FALSE), not null
#  auto_close_hours                          :float
#  post_count                                :integer          default(0), not null
#  latest_post_id                            :integer
#  latest_topic_id                           :integer
#  position                                  :integer
#  parent_category_id                        :integer
#  posts_year                                :integer          default(0)
#  posts_month                               :integer          default(0)
#  posts_week                                :integer          default(0)
#  topics_day                                :integer          default(0)
#  posts_day                                 :integer          default(0)
#
# Nome tabella: groups
#
#  id                                 :integer          not null, primary key
#  name                               :string           not null
#  created_at                         :datetime         not null
#  automatic                          :boolean          default(FALSE), not null
#  user_count                         :integer          default(0), not null
#  title                              :string
#  bio_raw                            :text             (la descrizione del gruppo)
#  allow_membership_requests          :boolean          default(FALSE), not null
#  full_name                          :string
#  visibility_level                   :integer          default(0), not null (chi può vedere il gruppo :public=0, :logged_on_users=1, :members=2, :staff=3, :owners=4)
#  messageable_level                  :integer          default(0) (chi può inviare messaggi al gruppo :public=0, :logged_on_users=1, :members=2, :staff=3, :owners=4)
#  mentionable_level                  :integer          default(0) (chi può menzionare il gruppo :public=0, :logged_on_users=1, :members=2, :staff=3, :owners=4)
#  members_visibility_level           :integer          default(0), not null (chi vede i membri del gruppo :public=0, :logged_on_users=1, :members=2, :staff=3, :owners=4)
#
# Nome tabella: group_users
#
#  id                 :integer          not null, primary key
#  group_id           :integer          not null
#  user_id            :integer          not null
#  created_at         :datetime         not null
#
# Nome tabella: user_actions
#
#  id              :integer          not null, primary key
#  action_type     :integer          not null (:like=1,:was_liked=2,:new_topic=4,:reply=5,:response=6,:mention=7,:quote=9,:edit=11,:new_private_message=12,:got_private_message=13,:solved=15,:assigned=16)
#  user_id         :integer          not null (l'utente a cui attribuire l'azione)
#  target_topic_id :integer
#  target_post_id  :integer
#  target_user_id  :integer          (ad esempio, l'id dell'utente il cui post è stato messo mi piace)
#  acting_user_id  :integer          (l'utente che ha eseguito l'azione, ad esempio un utente staff può eseguire un'azione per conto di un utente regolare)
#  created_at      :datetime         not null
#  updated_at      :datetime         not null
#
# Nome tabella: topic_views
#
#  topic_id   :integer          not null
#  viewed_at  :date             not null
#  user_id    :integer         (verrà impostato se l'argomento è stato visualizzato da un utente connesso)
#  ip_address :inet            (verrà impostato se l'argomento è stato visualizzato da un utente anonimo)
#
# Nome tabella: user_visits
#
#  id         :integer          not null, primary key
#  user_id    :integer          not null
#  visited_at :date             not null
#  posts_read :integer          default(0)
#  mobile     :boolean          default(FALSE) (verrà impostato su TRUE se l'utente ha visitato da un dispositivo mobile)
#  time_read  :integer          default(0), not null (il valore restituito è il numero di secondi della visita)

Ecco un link a una sessione di chat in cui l’ho provato: ChatGPT

Se vuoi provare ad espandere questa lista, il modo più semplice è copiare lo schema dalla parte inferiore del modello che ti interessa, direttamente dal codice di Discourse: discourse/app/models at main · discourse/discourse · GitHub.

3 Mi Piace

Sarebbe fantastico ottenere esattamente questo, ma un elenco completo di ogni tabella. Da dove l’hai preso?

MODIFICA: Ah, vedo il tuo link in fondo, scusa. Probabilmente non avrò il tempo di metterli tutti insieme. Speravo ci fosse uno schema SQL master da qualche parte :confused:

Il problema è che fornire solo lo schema non è sufficiente per ChatGPT. Devi fornirgli dettagli su cose come:

  • cosa significano i codici interi di req_type di application_requests
  • a cosa serve la colonna user_id di topics
  • cosa significano i codici di action_type della tabella user_actions e qual è la differenza tra le colonne user_id, target_user_id e acting_user_id di quella tabella

Con questi tipi di dettagli, GPT 3.5 sembra fare un buon lavoro senza ulteriore addestramento. Il problema diventa quindi che fornire questo livello di dettaglio sull’intero database comporterà il superamento del limite di token di ChatGPT (4096 token, inclusi sia il testo del prompt che l’output generato). Se questo tipo di approccio venisse utilizzato, ci dovrebbe essere un modo per limitare ciò che viene inserito nel prompt in base alle informazioni che l’utente voleva ottenere dalla query di Data Explorer.

1 Mi Piace

Non è stata affatto la mia esperienza. L’ho trovata piuttosto piacevole stasera. Condividerò alcuni risultati più tardi.

Mi dà la sensazione di un ruolo competente, ma molto entry-level/junior. Fa avvicinare le cose, gli dico cosa ha fatto di sbagliato e lo corregge. Ripeti.

Mi sto davvero divertendo con quello che mi sta dando, e il tempo che mi fa risparmiare in base al mio utilizzo di stasera.

1 Mi Piace

GPT 3.5 gestisce 16k senza problemi oggi

Il problema inizia a verificarsi quando le richieste sono complicate, tenendo conto dei casi limite e così via

1 Mi Piace