AI Summarization Backfill завис: постоянно генерирует одну и ту же тему

Я пытаюсь заполнить данные за последние 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

Все сырые ответы выглядят валидно. Каждый из них немного отличается, как и ожидалось. Вот пример (я удалил большую часть текста):


{
  "id": "msg_016C2dHZik2Miwe16pRHFe9z",
  "type": "message",
  "role": "assistant",
  "model": "claude-3-5-sonnet-20241022",
  "content": [
    {
      "type": "text",
      "text": "The Franklin Lexington Private Markets Fund (FLEX) is a new private equity secondaries fund... [УДАЛЕНО] "
    }
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 13848,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0,
    "output_tokens": 416
  }
}

Не знаю, является ли это подсказкой, но означает ли 103 то, что система считает, что она подвела итог только до поста 103, а всего постов 108, поэтому требуется новая сводка?

Запрос, сгенерированный SQL Helper:

-- [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
1 лайк

В этой теме скрыто или удалено 5 сообщений. 108 - 103 = 5. Возможно, проблема в том, что скрытые и удалённые сообщения обрабатываются некорректно? Да, 108 — это номер последнего сообщения, но передаётся только 103, поэтому система постоянно считает, что есть 5 новых сообщений для сводки.

@Falco @sam

1 лайк

У меня есть ещё одна тема, у которой тоже постоянно обновляется сводка. В этой теме нет скрытых или удалённых постов, но она закреплена, что создаёт пост «эта тема была закреплена глобально…». Таким образом, максимальное количество постов — 8, но последний пост, по-видимому, не передаётся?

Да, думаю, вы на правильном пути, @Roman.

best_replies не гарантирует включение последнего публичного поста в теме. Мы должны безоговорочно добавлять последний пост, даже при выборе best_replies.

1 лайк

Спасибо за проверку. И чтобы прояснить влияние: дело не только в неэффективности многократной генерации одного и того же резюме — это полностью останавливает процесс заполнения пробелов. Например, если у вас установлено заполнение пробелов для 24 тем в час, то каждые 5 минут система пытается обработать 2 темы. В конце концов обе темы сталкиваются с проблемой — удалённые темы, закреплённые темы или что-то ещё — и система продолжает повторять попытки для тех же двух тем каждые 5 минут. Она даже не пробует другие темы.

2 лайка

Необходимо ли также добавить .where("NOT deleted")? Я не понимаю разницы между hidden и deleted, но в моей проблемной теме присутствуют и скрытые, и удаленные элементы.

Привет, Марк,

Я сейчас разбираюсь в этой ситуации и пытаюсь понять, что происходит. То, на что указал @sam, верно: если best_replies не включает последний пост, это может привести к зависанию задачи. Я вот-вот завершу исправление этой проблемы и добавлю механизм аварийной остановки, который превратит задачу в операцию без эффекта (no-op) и запишет ошибку в лог, если в запросе обнаружится ошибка. Это не идеальный вариант, и такого не должно происходить, но это лучше, чем бесконечная регенерация одной и той же сводки.

С другой стороны, я рассматриваю пример Franklin Lexington..., который вы предоставили. Я подозреваю, что это другая проблема, потому что:

  1. У него уже есть сводка (149).
  2. Условие 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?

Я буду держать вас в курсе того, что выясню.

Спасибо, что взялись за это. Готов предоставить логи ошибок, как только ваше исправление будет готово.

https://meta.discourse.org/t/summarize-gists/340269/3

Я не вижу, как её включить, поэтому полагаю, что она не активна.

“summarize”

Это разблокирует очередь и сделает задачу более устойчивой к подобным проблемам:

Не могли бы вы сообщить, как обстоят дела после обновления вашего сайта?

3 лайка

Больше не генерируются сводки для тем, у которых уже есть сводка, что хорошо.

Однако сводки не создаются для многих тем, даже при наличии новых сообщений, из-за:

Поэтому функция заполнения считает, что работа завершена, но, возможно, 75% тем в разделе «Последние» не имеют сводки, хотя в них есть новые сообщения, просто потому, что они были созданы более 90 дней назад. Уверен, это не было задумано. Пожалуйста, измените это или помогите мне понять, почему так происходит.

Я сделал форк репозитория ai, чтобы изменить created_at на updated_at и продолжить работу. С радостью сообщаю, что он успешно сгенерировал сводки для всех 400+ тем, которые я ожидал. Некоторые не прошли первую попытку заполнения, возможно, из-за превышения квоты за эту минуту, но они были успешно обработаны при второй попытке.

В частности, тема Franklin Lexington теперь имеет сводку.

Однако заполнение исторических данных пока не будет работать хорошо для других тем из-за проблемы с created_at.

1 лайк

Да, я согласен, нам нужно посмотреть на updated_at или last_posted_at, что немного менее радикально.

В конечном счёте, если мы занимаемся заполнением пробелов, мы должны основываться на изменении контента.

2 лайка

Если разница заключается в правках, я бы проголосовал за регенерацию при их внесении. У нас есть вики в качестве первого поста каждой темы, где участники вносят правки с критически важной информацией, которая может повлиять на резюме.

Но если вы решите не делать этого, я могу продолжать поддерживать свой форк.

Извините за молчание. Я постараюсь найти время, чтобы заняться этим в ближайшее время.

1 лайк

Это было слито сегодня утром:

Фоновая задача теперь использует last_posted_at вместо created_at. Я также внес изменения в логику определения устаревания сводки, проверяя, не новее ли last_revised_at какого-либо из постов по сравнению со сводкой, чтобы учитывать правки.

4 лайка

Эта тема была автоматически закрыта через 3 дня. Новые ответы больше не допускаются.