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ò

With ChatCPT 3.5 I’m getting unexpected results when I provide the full schema. For example, it keeps trying to find the topic author in the topic_users table.

I get successful results by limiting the information in the prompt to the tables and columns that are required to write the query. Also by adding some additional information about how the columns are used. For example:

# Table name: 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 (the user who is to be credited with the action)
#  target_topic_id :integer
#  acting_user_id  :integer (the user who performed the action, for example, a staff user can perform an action on behalf of a regular user)
#  created_at      :datetime         not null

Another way to look at getting this to work with the Data Explorer plugin would be to have users fill out a dynamically generate form that lists the data they are looking for, and what conditions they want to apply to the data. The prompt could be generated programmatically by Discourse, then sent to the LLM to have the query written.

Edit: @jordan-violet, this might be a useful starting point. Here’s an annotated partial schema that’s working for me. It works well as long as I limit my queries so that they can be answered by the provided schema. I’ve added additional details to the schema to clarify details that seem to confuse ChatGPT. The obvious downside of this approach is that a fully annotated schema will exceed ChatGPT 3.5’s token limit. I’ve included some information in the schema that could be omitted to reduce the number of tokens that are used.

Summary
# == Schema Information
#
# Table name: 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
#
# Table name: users
#
#  id                        :integer          not null, primary key
#  username                  :string(60)       not null
#  created_at                :datetime         not null
#  updated_at                :datetime         not null
#  name                      :string           (the user's real name)
#  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
#
# Table name: 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          (the id of the user who created the topic)
#  last_post_user_id         :integer          not null (the id of the user who created the last post in the topic)
#  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 (can be set to either "regular" or "private_message")
#  slug                      :string
#  deleted_by_id             :integer          (the id of the user who deleted the topic)
#  participant_count         :integer          default(1)
#  word_count                :integer
#  excerpt                   :string
#  highest_staff_post_number :integer          default(0), not null
#
# Table name: posts
#
#  id                      :integer          not null, primary key
#  user_id                 :integer          (the id of the user who created the post)
#  topic_id                :integer          not null
#  post_number             :integer          not null (indicates the post's order in its topic)
#  raw                     :text             not null (the post's content)
#  created_at              :datetime         not null
#  updated_at              :datetime         not null
#  reply_to_post_number    :integer          (the post_number that the post is a reply to)
#  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 (the number of times the post has been read)
#  post_type               :integer          default(1), not null (:regular=>1, :moderator_action=>2, :small_action=>3, :whisper=>4)
#  last_editor_id          :integer          (the id of the user who last edited the 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
#
# Table name: categories
#
#  id                                        :integer          not null, primary key
#  name                                      :string(50)       not null
#  topic_id                                  :integer          (the id of the topic that is used for the category's description)
#  topic_count                               :integer          default(0), not null
#  created_at                                :datetime         not null
#  updated_at                                :datetime         not null
#  user_id                                   :integer          not null (the id of the user who created the topic)
#  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)
#
# Table name: 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             (the group's description)
#  allow_membership_requests          :boolean          default(FALSE), not null
#  full_name                          :string
#  visibility_level                   :integer          default(0), not null (who can see the group :public=>0, :logged_on_users=>1, :members=>2, :staff=>3, :owners=>4)
#  messageable_level                  :integer          default(0) (who can message the group :public=>0, :logged_on_users=>1, :members=>2, :staff=>3, :owners=>4)
#  mentionable_level                  :integer          default(0) (who can mention the group :public=>0, :logged_on_users=>1, :members=>2, :staff=>3, :owners=>4)
#  members_visibility_level           :integer          default(0), not null (who see the group's members :public=>0, :logged_on_users=>1, :members=>2, :staff=>3, :owners=>4)
#
# Table name: group_users
#
#  id                 :integer          not null, primary key
#  group_id           :integer          not null
#  user_id            :integer          not null
#  created_at         :datetime         not null
#
# Table name: 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 (the user who is to be credited with the action)
#  target_topic_id :integer
#  target_post_id  :integer
#  target_user_id  :integer          (for example, the id of the user whose post was liked)
#  acting_user_id  :integer          (the user who performed the action, for example, a staff user can perform an action on behalf of a regular user)
#  created_at      :datetime         not null
#  updated_at      :datetime         not null
#
# Table name: topic_views
#
#  topic_id   :integer          not null
#  viewed_at  :date             not null
#  user_id    :integer         (will be set if the topic was viewed by a logged in user)
#  ip_address :inet            (will be set if the topic was viewed by an anonymous user)
#
# Table name: 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) (will be set to TRUE if the user visited on a mobile device)
#  time_read  :integer          default(0), not null (the value returned is the number of seconds of the visit)

Here’s a link to a chat session where I tried it out: https://chat.openai.com/share/d108c104-3aa3-45d9-9161-6da21d5b3a77

If you want to try expanding on this list, the easiest way to do it is to copy the schema from the bottom of the model you’re interested in, directly from the Discourse code: 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