Я пытаюсь заполнить данные за последние 90 дней. Успешно обработано около 500 из 2000 тем, но теперь процесс остановился, так как задача (запускаемая каждые 5 минут) каждый раз обрабатывает одну и ту же тему. Не понимаю почему — у темы уже есть валидная сводка, и за последние 12 дней новых постов не было. Таблица AI Audit Logs показывает, что каждый запрос успешен. Статус Sidekiq в норме. В /logs ничего релевантного нет. Как отладить это?
SELECT request_tokens,
response_tokens,
raw_response_payload,
topic_id,
created_at AS summary_created_at,
language_model
FROM ai_api_audit_logs
WHERE raw_request_payload LIKE '%Franklin Lexington%'
ORDER BY created_at DESC
LIMIT 40
Не знаю, является ли это подсказкой, но означает ли 103 то, что система считает, что она подвела итог только до поста 103, а всего постов 108, поэтому требуется новая сводка?
-- [params]
-- integer :summary_type = 0
-- integer :max_age_days = 30
-- integer :min_word_count = 100
WITH topic_candidates AS (
SELECT
t.id as topic_id,
t.title,
t.created_at,
t.word_count,
t.highest_post_number,
t.last_posted_at,
ais.id as summary_id,
ais.content_range,
ais.created_at as summary_created_at,
UPPER(ais.content_range) as content_range_upper
FROM topics t
LEFT OUTER JOIN ai_summaries ais ON
t.id = ais.target_id AND
ais.target_type = 'Topic' AND
ais.summary_type = :summary_type
WHERE
-- Порог по количеству слов
t.word_count >= :min_word_count
-- Ограничение по возрасту
AND t.updated_at > CURRENT_TIMESTAMP - (:max_age_days || ' DAYS')::INTERVAL
-- Либо сводки не существует, либо её нужно обновить
AND (
ais.id IS NULL OR
(
UPPER(ais.content_range) < t.highest_post_number + 1
AND ais.created_at < (CURRENT_TIMESTAMP - INTERVAL '5 minutes')
)
)
)
SELECT
topic_id,
title,
word_count,
highest_post_number,
created_at,
last_posted_at,
summary_id,
content_range,
summary_created_at,
content_range_upper
FROM topic_candidates
ORDER BY summary_created_at DESC NULLS FIRST, last_posted_at DESC
В этой теме скрыто или удалено 5 сообщений. 108 - 103 = 5. Возможно, проблема в том, что скрытые и удалённые сообщения обрабатываются некорректно? Да, 108 — это номер последнего сообщения, но передаётся только 103, поэтому система постоянно считает, что есть 5 новых сообщений для сводки.
У меня есть ещё одна тема, у которой тоже постоянно обновляется сводка. В этой теме нет скрытых или удалённых постов, но она закреплена, что создаёт пост «эта тема была закреплена глобально…». Таким образом, максимальное количество постов — 8, но последний пост, по-видимому, не передаётся?
best_replies не гарантирует включение последнего публичного поста в теме. Мы должны безоговорочно добавлять последний пост, даже при выборе best_replies.
Спасибо за проверку. И чтобы прояснить влияние: дело не только в неэффективности многократной генерации одного и того же резюме — это полностью останавливает процесс заполнения пробелов. Например, если у вас установлено заполнение пробелов для 24 тем в час, то каждые 5 минут система пытается обработать 2 темы. В конце концов обе темы сталкиваются с проблемой — удалённые темы, закреплённые темы или что-то ещё — и система продолжает повторять попытки для тех же двух тем каждые 5 минут. Она даже не пробует другие темы.
Необходимо ли также добавить .where("NOT deleted")? Я не понимаю разницы между hidden и deleted, но в моей проблемной теме присутствуют и скрытые, и удаленные элементы.
Я сейчас разбираюсь в этой ситуации и пытаюсь понять, что происходит. То, на что указал @sam, верно: если best_replies не включает последний пост, это может привести к зависанию задачи. Я вот-вот завершу исправление этой проблемы и добавлю механизм аварийной остановки, который превратит задачу в операцию без эффекта (no-op) и запишет ошибку в лог, если в запросе обнаружится ошибка. Это не идеальный вариант, и такого не должно происходить, но это лучше, чем бесконечная регенерация одной и той же сводки.
С другой стороны, я рассматриваю пример Franklin Lexington..., который вы предоставили. Я подозреваю, что это другая проблема, потому что:
У него уже есть сводка (149).
Условие UPPER(ais.content_range) < t.highest_post_number + 1 должно возвращать FALSE. Функция UPPER должна вернуть 109, что равно highest_post_number + 1.
Чтобы задача зависла по этой причине, верхняя граница интервала content_range должна быть ниже. При определении, устарела ли сводка, мы не особо беспокоимся о скрытых или удалённых постах; мы просто хотим избежать их сводирования.
У вас включена настройка ai_summary_gists_enabled? Если да, подтвердите, пожалуйста, что для этой темы есть две сводки: одна с типом 0, а другая с типом 1. Также, в запросе к ai_api_audit_logs, который вы поделили, какое значение в столбце feature_name?
Больше не генерируются сводки для тем, у которых уже есть сводка, что хорошо.
Однако сводки не создаются для многих тем, даже при наличии новых сообщений, из-за:
Поэтому функция заполнения считает, что работа завершена, но, возможно, 75% тем в разделе «Последние» не имеют сводки, хотя в них есть новые сообщения, просто потому, что они были созданы более 90 дней назад. Уверен, это не было задумано. Пожалуйста, измените это или помогите мне понять, почему так происходит.
Я сделал форк репозитория ai, чтобы изменить created_at на updated_at и продолжить работу. С радостью сообщаю, что он успешно сгенерировал сводки для всех 400+ тем, которые я ожидал. Некоторые не прошли первую попытку заполнения, возможно, из-за превышения квоты за эту минуту, но они были успешно обработаны при второй попытке.
В частности, тема Franklin Lexington теперь имеет сводку.
Однако заполнение исторических данных пока не будет работать хорошо для других тем из-за проблемы с created_at.
Если разница заключается в правках, я бы проголосовал за регенерацию при их внесении. У нас есть вики в качестве первого поста каждой темы, где участники вносят правки с критически важной информацией, которая может повлиять на резюме.
Но если вы решите не делать этого, я могу продолжать поддерживать свой форк.
Фоновая задача теперь использует last_posted_at вместо created_at. Я также внес изменения в логику определения устаревания сводки, проверяя, не новее ли last_revised_at какого-либо из постов по сравнению со сводкой, чтобы учитывать правки.