Можете ли вы привести несколько примеров пограничных случаев?
Конечно, я планирую провести ещё один раунд на следующей неделе. Вы можете попробовать ruby-скрипт в репозитории, который я поделился.
@simon Я считаю, что главная ценность заключается в понимании того, что, по крайней мере в обозримом будущем, этот инструмент никогда не будет давать идеальный результат с первого раза. Но если вы знаете, чего хотите, вы можете направлять его, как неутомимого стажёра, способного выполнять рутинную работу.
Итак, не обладая какими-либо актуальными знаниями SQL, кроме того, что помню конструкцию select from where, и чётко представляя желаемый итоговый результат, я смог заставить его сгенерировать нужный мне запрос, просто ведя с ним разговор в фоновом режиме, не отвлекаясь от своих основных рабочих задач. Это действительно похоже на наличие бесплатного личного помощника или стажёра, которого нужно лишь постоянно направлять в нужном направлении.
Прежде всего, вот мой финальный запрос. Мне нужен был запрос, который возвращал бы топ-100 пользователей с наибольшим общим количеством лайков, а также предоставлял бы информацию о пользователе, его имени, общем количестве ссылок и ссылку на его пост, получивший наибольшее число лайков. Я совершенно не знал, как это сделать, и честно говоря, даже не представлял, с чего начать. Обычно, когда мне нужно что-то подобное, я обращаюсь к одному из наших инженеров. На этот раз мне удалось не беспокоить их, не замедлять свою работу и при этом успешно направить/инструктировать ChatGPT для выполнения необходимой задачи.
Финальный запрос:
WITH Most_Liked_Posts AS (
SELECT
p.user_id,
p.topic_id,
p.post_number,
ROW_NUMBER() OVER (PARTITION BY p.user_id ORDER BY likes_count DESC) AS row_number
FROM (
SELECT
p.user_id,
p.topic_id,
p.post_number,
COUNT(l.id) AS likes_count
FROM
posts p
LEFT JOIN post_actions l ON p.id = l.post_id AND l.post_action_type_id = 2
WHERE
p.user_id NOT IN (SELECT id FROM users WHERE username = 'codey')
GROUP BY
p.user_id,
p.topic_id,
p.post_number
) p
),
User_Likes AS (
SELECT
u.id AS user_id,
COUNT(pa.id) AS total_likes
FROM
users u
LEFT JOIN posts p ON u.id = p.user_id
LEFT JOIN post_actions pa ON p.id = pa.post_id AND pa.post_action_type_id = 2
WHERE
u.username != 'codey'
GROUP BY
u.id
)
SELECT
ul.user_id,
u.username AS username,
ul.total_likes,
'<a href="/discuss/t/' || mlp.topic_id || '/' || mlp.post_number || '">' || 'Ссылка на пост с наибольшим количеством лайков' || '</a>' AS html$post
FROM
User_Likes ul
JOIN users u ON ul.user_id = u.id
LEFT JOIN Most_Liked_Posts mlp ON ul.user_id = mlp.user_id AND mlp.row_number = 1
ORDER BY
ul.total_likes DESC
LIMIT 100
Инструкции в моём аккаунте ChatGPT перед началом промпта:
Я буду задавать вам только вопросы, связанные с PostgreSQL, и прошу отвечать только релевантными SQL-запросами.
Все эти запросы относятся к базам данных моей платформы сообщества Discourse.
Отвечайте SQL-запросами и пояснениями к ним. Не используйте точки с запятой для завершения SQL-операторов, так как они не требуются.
Следуйте всей моей переписке в ChatGPT по построению этого запроса здесь:
@sam с полной схемой, как выше (ещё раз извините, я не знаю, где именно её получить и/или получить в таком формате), используя langchain и векторную базу данных для правильной обработки документов перед отправкой в ChatGPT, плюс любые документы, которые у вас есть по использованию Data Explorer… Я вполне уверен, что этот процесс будет почти волшебным.
Я пробовал использовать векторную базу данных и подавать ей похожие примеры, но это слишком сильно влияет на результат. Вероятно, нам понадобится около 1000 очень близких примеров, чтобы получить магический эффект.
Мой инженер тоже попробует, так как мы создали своего рода «фабрику» для быстрого производства таких данных.
Есть ли где-то полный и исчерпывающий документ со всеми схемами БД в таком формате?
# == 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 (настоящее имя пользователя)
# 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
Этот формат крайне неэффективен с точки зрения использования токенов, но вы можете просто запросить его из таблиц схемы pg в Data Explorer ![]()
Ха-ха, хорошо, я попросу его посмотреть. Как я уже говорил, это не моя тема, чтобы развивать её дальше. Если бы это было так, я бы, наверное, не задавал бы эти вопросы!
Я очень хочу, чтобы что-то заработало, но это очень сложная задача
Это лишь идея, я её ещё не пробовал.
По моему мнению, необходимые запросы можно разделить по ролям:
- модератор
- администратор
- разработчик
Соответственно, требуемые таблицы можно сгруппировать в расширяющиеся наборы, где наименьший набор будет включать таблицы, нужные модератору.
При этом большая часть данных, необходимых модератору, будет основана на стандартных соединениях таблиц с использованием конкретных столбцов, поэтому целесообразно использовать представления.
Если вместо всей схемы использовать стандартные представления, то, вероятно, во многих случаях промптам потребуется передавать только эти представления, а не полную схему, что значительно упростит задачу для LLM при генерации возможного решения.
Надеюсь, это поможет.
Что касается более сложных запросов, то, скорее всего, если вы знаете достаточно для их необходимости, вы знаете достаточно и для их построения.
Я пробовал это. Результаты получаются крайне нестабильными. Интересный эксперимент — предоставить GPT-3.5 минимальную аннотированную версию схемы базы данных Discourse, чтобы просто проверить его способности в SQL. Я понимаю, что это неэффективно с точки зрения токенов, зато это читаемо:
Минимальная схема
# == Информация о схеме
#
# Имя таблицы: users
#
# id :integer не null, первичный ключ
# username :string(60) не null
# created_at :datetime не null
#
# Имя таблицы: groups
#
# id :integer не null, первичный ключ
# name :string не null
# created_at :datetime не null
#
# Имя таблицы: group_users
#
# id :integer не null, первичный ключ
# group_id :integer не null
# user_id :integer не null
#
# Имя таблицы: posts
#
# id :integer не null, первичный ключ
# user_id :integer
# topic_id :integer не null
# deleted_at :datetime (Приложение выполняет «мягкое удаление» постов. Когда пост удаляется, его свойство `deleted_at` устанавливается в значение :datetime. Если явно не требуется возвращать удалённые посты, при написании запросов, касающихся данных о постах, убедитесь, что столбец `deleted_at` имеет ограничение `NOT NULL`.)
#
# Имя таблицы: topics
#
# id :integer не null, первичный ключ
# title :string не null
# category_id :integer
# created_at :datetime не null
# user_id :integer (id пользователя, создавшего тему)
# deleted_at :datetime (Приложение выполняет «мягкое удаление» тем. Когда тема удаляется, её свойство `deleted_at` устанавливается в значение :datetime. Если явно не требуется возвращать удалённые темы, при написании запросов, касающихся данных о темах, убедитесь, что столбец `deleted_at` имеет ограничение `NOT NULL`.)
#
# Имя таблицы: categories
#
# id :integer не null, первичный ключ
# name :string(50) не null
На данный момент результаты, которые я получаю, впечатляют. Это заставляет меня задуматься, что проблему можно решить, просто предоставив аннотированную схему в промпте.
Для интереса я спросил его, с какими типами запросов он, вероятно, столкнётся с трудностями:
Ограничения GPT-3.5
- Иерархические запросы: Запросы, работающие с иерархическими структурами данных, такими как рекурсивные связи, могут быть сложными. Например, запросы для поиска отношений «родитель–потомок» внутри иерархии категорий.
- Временные запросы: Запросы, связанные с данными, зависящими от времени, например, расчёт исторических тенденций или анализ данных за определённые интервалы времени, могут требовать более сложных конструкций SQL.
- Оконные функции: Хотя я использовал оконные функции в предыдущих запросах, более продвинутое их применение для сложных аналитических задач может оказаться сложным.
- Геопространственные запросы: Работа с пространственными базами данных и запросы, основанные на географических данных, такие как поиск ближайших локаций или сложных пространственных связей, могут быть сложными.
- Сложные агрегации: Продвинутые агрегации, включающие многоуровневое группирование и вычисления, могут требовать более глубоких знаний SQL.
- Оптимизационные запросы: Написание высокооптимизированных запросов, использующих индексы, настройку запросов и улучшение производительности, может быть сложным.
- Пользовательские алгоритмы: Реализация пользовательских алгоритмов или логики внутри SQL-запроса может быть сложной из-за сложности самой логики.
- Продвинутые JOIN: Сложные условия соединения или комбинация нескольких соединений могут требовать тщательного подхода и, возможно, более сложных конструкций SQL.
- Подзапросы и коррелированные подзапросы: Хотя я могу обрабатывать подзапросы, крайне сложные или глубоко вложенные подзапросы могут оказаться более сложными.
- Поворот и обратный поворот данных: Преобразование данных между широким и длинным форматами (поворот и обратный поворот) в некоторых сценариях может стать сложным.
Проблемы возникают при попытке устранить неоднозначность полной схемы базы данных. Например, найти способ аннотировать таблицу user_actions. Простого предоставления определений её кодов action_type недостаточно. Модель начинает угадывать значения для user_id, target_user_id и acting_user_id.
Наиболее часто запрашиваемые запросы не используют большинство таблиц и столбцов в базе данных. Если в Data Explorer будет добавлен ИИ, возможно, стоит рассмотреть наличие режимов «базовый» и «продвинутый». Базовый режим мог бы использовать промпт, покрывающий большинство случаев использования. Продвинутый режим мог бы позволить пользователям выбирать, какая информация включается в промпт.
Было бы интересно пойти от обратного, взяв несколько запросов на мета-форуме, чтобы понять, что именно нужно предоставить в промпте, чтобы GPT-3.5 успешно создал соответствующий запрос.
Возможно, подход на основе LangChain, при котором сначала мы просим GPT определить, какие таблицы релевантны, а затем на втором этапе генерируем SQL, может помочь.
Наша собственная реализация для нашего продукта в настоящее время использует langchain. Мы, собственно, создали довольно универсальный фабричный подход, и мой ведущий инженер скоро попробует это применить.
Как я уже говорил, я в целом доволен результатами на данный момент. Это как иметь помощника, который выполняет поручения — ему нужно лишь сделать несколько поездок, но уже сейчас это экономит мне огромное количество времени и денег.
Для сведения
Это просто затягивает. Основываясь на блоге «LLMs и SQL» и немного методом проб и ошибок, я создал этот промпт, содержащий частичное описание базы данных Discourse:
[details=“Промпт для базы данных Discourse”]
Текст между комментариями /* Discourse database documentation start */ и /* Discourse database documentation end */ содержит сведения о базе данных PostgreSQL приложения форума Discourse.
Все таблицы и столбцы описаны в операторах `CREATE TABLE`. Обратите внимание на примеры запросов, следующие за каждым оператором `CREATE TABLE`. Некоторые дополнительные важные сведения содержатся
в однострочных (`-- --`) и многострочных (`/* */`) комментариях. После того как я отправлю вам эту информацию, я попрошу вас написать несколько запросов, которые будут выполняться плагином Discourse Data Explorer. Все таблицы и столбцы,
необходимые для написания этих запросов, находятся в операторах `CREATE TABLE`, которые я вам отправил.
/* Discourse database documentation start */
CREATE TABLE users (
id integer NOT NULL, -- в приложении есть понятие «реальных» пользователей. «Реальный» пользователь — это пользователь с id > 0 --
username character varying(60) NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
name character varying,
seen_notification_id integer DEFAULT 0 NOT NULL,
last_posted_at timestamp without time zone,
password_hash character varying(64),
salt character varying(32),
active boolean DEFAULT false NOT NULL,
username_lower character varying(60) NOT NULL,
last_seen_at timestamp without time zone,
admin boolean DEFAULT false NOT NULL,
last_emailed_at timestamp without time zone,
trust_level integer NOT NULL,
approved boolean DEFAULT false NOT NULL,
approved_by_id integer,
approved_at timestamp without time zone,
previous_visit_at timestamp without time zone,
suspended_at timestamp without time zone,
suspended_till timestamp without time zone,
date_of_birth date,
views integer DEFAULT 0 NOT NULL,
flag_level integer DEFAULT 0 NOT NULL,
ip_address inet,
moderator boolean DEFAULT false,
title character varying,
uploaded_avatar_id integer,
locale character varying(10),
primary_group_id integer,
registration_ip_address inet,
staged boolean DEFAULT false NOT NULL,
first_seen_at timestamp without time zone,
silenced_till timestamp without time zone,
group_locked_trust_level integer,
manual_locked_trust_level integer,
secure_identifier character varying,
flair_group_id integer,
last_seen_reviewable_id integer
);
SELECT * FROM users WHERE id = 1 OR id = 2 OR id = 121;
id | username | created_at | updated_at | name | seen_notification_id | last_posted_at | password_hash | salt | active | username_lower | last_seen_at | admin | last_emailed_at | trust_level | approved | approved_by_id | approved_at | previous_visit_at | suspended_at | suspended_till | date_of_birth | views | flag_level | ip_address | moderator | title | uploaded_avatar_id | locale | primary_group_id | registration_ip_address | staged | first_seen_at | silenced_till | group_locked_trust_level | manual_locked_trust_level | secure_identifier | flair_group_id | last_seen_reviewable_id | password_algorithm
-----+----------+----------------------------+----------------------------+--------------+----------------------+----------------------------+------------------------------------------------------------------+----------------------------------+--------+----------------+----------------------------+-------+----------------------------+-------------+----------+----------------+----------------------------+----------------------------+----------------------------+-------------------------+---------------+-------+------------+------------+-----------+------------+--------------------+--------+------------------+-------------------------+--------+----------------------------+---------------+--------------------------+---------------------------+------------------------------------------+----------------+-------------------------+------------------------------
1 | scossar | 2019-04-26 22:59:44.685893 | 2023-08-14 04:40:20.823438 | Simon Cossar | 56395 | 2023-08-14 04:08:43.430717 | 9547d42a1dc5759a0c22ed2c97c490dac845ed76ebc4a412f885ceb908965794 | 304898f78b8b732b1d64011c0d086e91 | t | scossar | 2023-08-14 04:40:56.769353 | t | 2023-08-14 04:33:46.44485 | 3 | t | -1 | 2020-09-22 19:54:41.05418 | 2023-08-13 22:35:00.020816 | | | 1904-02-14 | 0 | 0 | ::1 | t | Member | 747 | | | | f | 2019-04-26 23:10:43.250255 | | | 3 | | | 432 | $pbkdf2-sha256$i=64000,l=32$
2 | sally | 2019-04-26 23:15:47.859691 | 2023-08-14 04:40:56.831344 | | 56396 | 2023-08-14 04:11:37.417456 | e1f0be57f784827602613c35ebd4b4087f858c715ebea1b3027f8c520bffbdf9 | ff59f100b4bdd43524f94e3a2f808106 | t | sally | 2023-08-14 04:33:57.054779 | f | 2023-08-14 04:33:06.727322 | 2 | t | -1 | 2020-05-19 19:35:15.79381 | 2023-08-13 22:08:05.099486 | | | | 0 | 0 | 127.0.0.1 | t | Regular | 22 | en | 49 | 127.0.0.1 | f | 2019-04-26 23:16:58.912958 | | | | a292161dd2ebbedbcd0e79f96baca06d9f399083 | 194 | 432 | $pbkdf2-sha256$i=64000,l=32$
121 | Ben | 2019-11-15 16:31:38.216013 | 2023-08-14 04:40:41.907605 | | 56314 | 2023-07-07 20:48:33.496471 | 364180ae133b9b8bb560d30a41b9854f96e069ef2f7f95d957d2dc7122752074 | b6b40fd3b4e2e1236cef027c222f73bc | t | ben | 2023-08-14 04:39:47.42192 | f | 2023-08-14 04:30:26.764459 | 2 | t | 1 | 2019-11-15 16:31:38.089553 | 2023-07-22 02:14:01.540478 | 2022-05-05 17:39:02.632952 | 2022-05-06 17:38:55.054 | | 0 | 0 | 127.0.0.1 | f | Prime Four | | en | 196 | 127.0.0.1 | f | 2019-11-15 16:31:38.714185 | | | | | 196 | | $pbkdf2-sha256$i=64000,l=32$
CREATE TABLE groups (
id integer NOT NULL,
name character varying NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
automatic boolean DEFAULT false NOT NULL,
user_count integer DEFAULT 0 NOT NULL,
automatic_membership_email_domains text,
primary_group boolean DEFAULT false NOT NULL,
title character varying,
grant_trust_level integer,
incoming_email character varying,
has_messages boolean DEFAULT false NOT NULL,
flair_url character varying,
flair_bg_color character varying,
flair_color character varying,
bio_raw text,
bio_cooked text,
allow_membership_requests boolean DEFAULT false NOT NULL,
full_name character varying,
default_notification_level integer DEFAULT 3 NOT NULL,
visibility_level integer DEFAULT 0 NOT NULL,
public_exit boolean DEFAULT false NOT NULL,
public_admission boolean DEFAULT false NOT NULL,
membership_request_template text,
messageable_level integer DEFAULT 0,
mentionable_level integer DEFAULT 0,
members_visibility_level integer DEFAULT 0 NOT NULL,
publish_read_state boolean DEFAULT false NOT NULL,
flair_icon character varying,
flair_upload_id integer,
smtp_server character varying,
smtp_port integer,
smtp_ssl boolean,
imap_server character varying,
imap_port integer,
imap_ssl boolean,
imap_mailbox_name character varying DEFAULT ''::character varying NOT NULL,
imap_uid_validity integer DEFAULT 0 NOT NULL,
imap_last_uid integer DEFAULT 0 NOT NULL,
email_username character varying,
email_password character varying,
imap_last_error text,
imap_old_emails integer,
imap_new_emails integer,
allow_unknown_sender_topic_replies boolean DEFAULT false NOT NULL,
smtp_enabled boolean DEFAULT false,
smtp_updated_at timestamp without time zone,
smtp_updated_by_id integer,
imap_enabled boolean DEFAULT false,
imap_updated_at timestamp without time zone,
imap_updated_by_id integer,
assignable_level integer DEFAULT 0 NOT NULL,
email_from_alias character varying
); -- пользователи, имеющие статус «admin» или «moderator», добавляются в автоматическую группу «staff» --
SELECT * FROM groups WHERE id = 1 OR id = 11 OR id = 49;
id | name | created_at | updated_at | automatic | user_count | automatic_membership_email_domains | primary_group | title | grant_trust_level | incoming_email | has_messages | flair_bg_color | flair_color | bio_raw | bio_cooked | allow_membership_requests | full_name | default_notification_level | visibility_level | public_exit | public_admission | membership_request_template | messageable_level | mentionable_level | members_visibility_level | publish_read_state | flair_icon | flair_upload_id | smtp_server | smtp_port | smtp_ssl | imap_server | imap_port | imap_ssl | imap_mailbox_name | imap_uid_validity | imap_last_uid | email_username | email_password | imap_last_error | imap_old_emails | imap_new_emails | allow_unknown_sender_topic_replies | smtp_enabled | smtp_updated_at | smtp_updated_by_id | imap_enabled | imap_updated_at | imap_updated_by_id | assignable_level | email_from_alias
----+---------------+----------------------------+----------------------------+-----------+------------+------------------------------------+---------------+------------+-------------------+----------------+--------------+----------------+-------------+--------------------+---------------------------+---------------------------+---------------------------+----------------------------+------------------+-------------+------------------+-----------------------------+-------------------+-------------------+--------------------------+--------------------+------------+-----------------+-------------+-----------+----------+-------------+-----------+----------+-------------------+-------------------+---------------+----------------+----------------+-----------------+-----------------+-----------------+------------------------------------+--------------+---------------------------+--------------------+--------------+-----------------+--------------------+------------------+------------------
1 | admins | 2019-04-26 22:58:35.997964 | 2021-08-05 19:11:22.699825 | t | 1 | | f | | | | t | | | | | f | | 3 | 1 | f | f | | 99 | 0 | 0 | f | | | | | | | | | | 0 | 0 | | | | | | f | f | | | f | | | 0 |
11 | trust_level_1 | 2019-04-26 22:58:36.033238 | 2021-10-05 19:54:51.043121 | t | 116 | | f | | | | t | | | | | f | | 3 | 1 | f | f | | 0 | 0 | 0 | f | | | | | | | | | | 0 | 0 | | | | | | f | f | | | f | | | 0 |
49 | eurorack | 2019-10-03 17:28:42.323203 | 2022-08-16 19:54:09.223307 | f | 84 | example.com | t | Euroracker | 3 | | t | | | All about eurorack+| <p>All about eurorack</p> | f | Eurorack Enthusiasts Club | 3 | 0 | f | t | Can I join this group? | 99 | 99 | 0 | t | | | | | | | | | | 0 | 0 | | | | | | f | f | 2022-02-11 23:24:28.76631 | 1 | f | | | 0 |
/* group_users связывает таблицы groups и users */
CREATE TABLE group_users (
id integer NOT NULL,
group_id integer NOT NULL,
user_id integer NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
owner boolean DEFAULT false NOT NULL,
notification_level integer DEFAULT 2 NOT NULL,
first_unread_pm_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
);
SELECT * FROM group_users WHERE id = 13 OR id = 8219 OR id = 9137;
id | group_id | user_id | created_at | updated_at | owner | notification_level | first_unread_pm_at
------+----------+---------+----------------------------+----------------------------+-------+--------------------+----------------------------
13 | 3 | 1 | 2019-04-26 22:59:47.828533 | 2019-04-26 22:59:47.828533 | f | 2 | 2023-08-14 01:14:54.229593
8219 | 13 | 121 | 2022-04-21 08:15:47.946036 | 2022-04-21 08:15:47.946036 | f | 2 | 2023-07-05 06:49:04.48265
9137 | 49 | 2 | 2022-09-08 17:34:39.290504 | 2022-09-08 17:34:39.290504 | t | 3 | 2020-11-21 02:40:15.868728
CREATE TABLE posts (
id integer NOT NULL,
user_id integer,
topic_id integer NOT NULL,
post_number integer NOT NULL,
raw text NOT NULL,
cooked text NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
reply_to_post_number integer,
reply_count integer DEFAULT 0 NOT NULL,
quote_count integer DEFAULT 0 NOT NULL,
deleted_at timestamp without time zone, -- приложение только «мягко удаляет» посты и темы. Если не требуется явно возвращать сведения об удаленных постах или темах, всегда проверяйте, что `deleted_at IS NULL` при написании запросов, связанных с постами или темами. --
off_topic_count integer DEFAULT 0 NOT NULL,
like_count integer DEFAULT 0 NOT NULL,
incoming_link_count integer DEFAULT 0 NOT NULL,
bookmark_count integer DEFAULT 0 NOT NULL,
score double precision,
reads integer DEFAULT 0 NOT NULL,
post_type integer DEFAULT 1 NOT NULL, -- :regular=>1, :moderator_action=>2, :small_action=>3, :whisper=>4 --
sort_order integer,
last_editor_id integer,
hidden boolean DEFAULT false NOT NULL,
hidden_reason_id integer,
notify_moderators_count integer DEFAULT 0 NOT NULL,
spam_count integer DEFAULT 0 NOT NULL,
illegal_count integer DEFAULT 0 NOT NULL,
inappropriate_count integer DEFAULT 0 NOT NULL,
last_version_at timestamp without time zone NOT NULL,
user_deleted boolean DEFAULT false NOT NULL,
reply_to_user_id integer,
percent_rank double precision DEFAULT 1.0,
notify_user_count integer DEFAULT 0 NOT NULL,
like_score integer DEFAULT 0 NOT NULL,
deleted_by_id integer,
edit_reason character varying,
word_count integer,
version integer DEFAULT 1 NOT NULL,
cook_method integer DEFAULT 1 NOT NULL,
wiki boolean DEFAULT false NOT NULL,
baked_at timestamp without time zone,
baked_version integer,
hidden_at timestamp without time zone,
self_edits integer DEFAULT 0 NOT NULL,
reply_quoted boolean DEFAULT false NOT NULL,
via_email boolean DEFAULT false NOT NULL,
raw_email text,
public_version integer DEFAULT 1 NOT NULL,
action_code character varying,
locked_by_id integer,
image_upload_id bigint
);
SELECT * FROM posts WHERE id = 11094 OR id = 11095 OR id = 11096;
id | user_id | topic_id | post_number | raw | cooked | created_at | updated_at | reply_to_post_number | reply_count | quote_count | deleted_at | off_topic_count | like_count | incoming_link_count | bookmark_count | score | reads | post_type | sort_order | last_editor_id | hidden | hidden_reason_id | notify_moderators_count | spam_count | illegal_count | inappropriate_count | last_version_at | user_deleted | reply_to_user_id | percent_rank | notify_user_count | like_score | deleted_by_id | edit_reason | word_count | version | cook_method | wiki | baked_at | baked_version | hidden_at | self_edits | reply_quoted | via_email | raw_email | public_version | action_code | locked_by_id | image_upload_id | outbound_message_id
-------+---------+----------+-------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+----------------------------+----------------------+-------------+-------------+------------+-----------------+------------+---------------------+----------------+-------+-------+-----------+------------+----------------+--------+------------------+-------------------------+------------+---------------+---------------------+----------------------------+--------------+------------------+-------------------+-------------------+------------+---------------+-------------+------------+---------+-------------+------+----------------------------+---------------+-----------+------------+--------------+-----------+-----------+----------------+-------------+--------------+-----------------+--------------------------------
11094 | 1 | 1852 | 7 | This is an example of a Discourse post. | <p>This is an example of a Discourse post.</p> | 2023-08-14 04:08:43.430717 | 2023-08-14 04:08:43.430717 | | 0 | 0 | | 0 | 0 | 0 | 0 | 0.2 | 1 | 1 | 7 | 1 | f | | 0 | 0 | 0 | 0 | 2023-08-14 04:08:43.441371 | f | | 0.166666666666667 | 0 | 0 | | | 8 | 1 | 1 | f | 2023-08-14 04:08:43.430685 | 2 | | 0 | f | f | | 1 | | | |
11095 | 2 | 10863 | 11 | This is another example of a Discourse post. | <p>This is another example of a Discourse post.</p> | 2023-08-14 04:11:37.417456 | 2023-08-14 04:11:37.417456 | 5 | 0 | 0 | | 0 | 0 | 0 | 0 | 0.4 | 2 | 1 | 11 | 2 | f | | 0 | 0 | 0 | 0 | 2023-08-14 04:11:37.430459 | f | 121 | 0.8 | 0 | 0 | | | 8 | 1 | 1 | f | 2023-08-14 04:11:37.417417 | 2 | | 0 | f | f | | 1 | | | | discourse/post/11095@127.0.0.1
11096 | 121 | 11047 | 2 | Thanks! I hadn't seen that :slight_smile: | <p>Thanks! I hadn’t seen that <img src="//127.0.0.1:4200/images/emoji/twitter/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> | 2023-08-14 0В моем обновлении возникла ошибка
```ruby
api_key = "a quick brown fox"
fetch("https://api.example.com/data", headers: { 'Authorization' => api_key })
Пожалуйста, помогите мне это исправить.
Надеюсь, я не подпитываю вашу зависимость.
Не знаю, читаете ли вы научные статьи, но сегодня я наткнулся на ещё одну, которая подтверждает, что вы идёте правильным путём. Эта статья, возможно, укажет новые направления для достижения цели — генерации корректного SQL и результатов, начиная с запроса на естественном языке.
Статья посвящена решению математических задач, но поскольку математика — это всего лишь выражение, как и SQL, достаточно заменить один вид выражения на другой, и всё станет понятным. Существует множество подобных статей с похожими идеями, поэтому не воспринимайте эту как единственно верную.
«Решение сложных математических текстовых задач с помощью интерпретатора кода GPT-4 с самопроверкой на основе кода» авторов Аоцзюнь Чжоу, Кэ Ван, Цзыму Лу, Вэйкан Ши, Сычунь Ло, Цзыпэн Цинь, Шаоцин Лу, Аня Цзя, Линци Сун, Минцзе Чжан и Хуншэн Ли (pdf)
Ещё одна идея, которая может вам помочь. Возможно, покажется, что я просто «глубоко копаю», но я использовал этот подход для генерации кода на Prolog, в частности для веб-страниц.
Проблема может заключаться в том, что генеративным ИИ сложнее понимать SQL, поскольку это декларативный язык. Большинство успехов в применении генеративного ИИ к программированию связаны с большими наборами данных для обучения по нескольким императивным языкам, таким как JavaScript, Python, Java и т. д. Однако генеративные ИИ, основанные на трансформерах (которые изначально, насколько я помню, создавались для перевода с английского на немецкий), отлично справляются с переводом к/из хорошо обученных языков программирования. Поэтому, вместо того чтобы сразу просить сгенерировать SQL, попробуйте попросить генеративный ИИ написать код на Python или другом хорошо обученном языке для решения задачи, а затем попросить его перевести этот код на SQL. Посмотрите, сработает ли это. Я не планирую пробовать это сам, но раз вам это интересно — пожалуйста, действуйте. И если вы это сделаете, пожалуйста, дайте обратную связь: мне очень интересно узнать, что вы обнаружите. ![]()
Это опечатка?
Не должно ли быть WHERE poll_id = 71 вместо WHERE poll_id = 74?
Я не проверял весь запрос целиком, просто хотел убедиться, что вы привели пример того, как должны выглядеть результаты выполнения запроса. Иными словами, вы привели примеры значений в таблице, но я не увидел пример ожидаемого результата для запроса — возможно, я что-то упустил. Ожидаемый результат можно было бы использовать для проверки корректности SQL-запроса.
Предложение:
В примере «Запрос к базе данных Discourse» значение 1 для идентификатора используется в нескольких таблицах. Хотя для людей очевидно, что 1 имеет смысл только в контексте конкретного поля и таблицы, ИИ этого не знает, и это может привести к ошибочному выбору. Поэтому, как предложение, измените пример «Запрос к базе данных Discourse», чтобы использовать разные числа для каждого идентификатора.
Чтобы пойти ещё дальше, проверьте, чтобы все значения в каждой примерной таблице представляли собой один токен, используя страницу токенизатора OpenAI. Я понимаю, что вы, возможно, хотите оставить некоторые значения в виде слов или даже строк, но действительно ли это важно для ИИ? Приведёт ли использование значений из нескольких токенов к большей вариативности и возможным галлюцинациям?
Да, это ошибка. Я исправлю её. Мне кажется, я повторно запустил запрос с 71, пытаясь получить результаты, относящиеся к другим таблицам, связанным с опросами.
Я отступил от предложения из статьи в блоге запускать все SELECT-запросы в таком виде:
SELECT * FROM polls LIMIT 3;
Я сделал это, потому что в моей базе данных для разработки много анонимизированных пользователей и удалённых постов. Я подумал, что так смогу предоставить более связные результаты, но планирую попробовать снова сформулировать запрос с чистой базой данных и упростить SELECT-операторы.
Да, во всех примерах я использую трёх пользователей. Их id — 1, 2 и 121, поэтому эти значения часто повторяются. Я предполагал, что лучше показать согласованные данные. Попробую несколько разных подходов и посмотрю, какой из них работает лучше.
Ещё один подход, упомянутый в статье в блоге, — ограничить столбцы, которые указываются в запросе. Это заманчиво, но может привести к множеству ошибок, сложно поддерживается и так далее.
Мне кажется, я замечаю следующую закономерность: если начать сеанс с запроса сложного запроса, ChatGPT путается. Когда я помогаю ему преодолеть эту путаницу, результаты для остальной части сеанса оказываются довольно хорошими. Другой подход, который тоже работает, — начать с простого запроса и постепенно переходить к более сложным. Не уверен, что это действительно закономерность или что уровень успеха на самом деле более случаен, чем кажется.
В текущем виде это, вероятно, будет полезно тем, кто уже знаком с SQL и базой данных Discourse. Мне бы хотелось довести это до состояния, когда это станет полезно и тем, кто мало знает об обоих этих вещах.
Также я тестирую это с ChatGPT-4. Вероятно, он даст лучшие результаты, но, возможно, им будет менее интересно пользоваться. ChatGPT-3.5 работает намного быстрее.
Десятилетия назад, когда я изучал базы данных, было запутанно учиться только по SQL, но затем я использовал конструктор запросов Microsoft Access, где можно было перетаскивать таблицы и соединять их поля линиями, очень похоже на то, как работает Visio, и это генерировало SQL.
Аналогичный инструмент, изображение от сюда
Не ожидаю, что Discourse создаст такой инструмент для построения SQL, но, возможно, можно будет заставить ИИ генерировать такие изображения связанных таблиц в качестве обратной связи.
Насколько я помню, в этом видео отмечается, что сначала нужно создать что-то с помощью GPT-4, чтобы получить правильные результаты, а затем адаптировать это для GPT-3.5 ради скорости.
