Гайд · TNWS AI
Как не обновлять lastmod у AI-статьи без изменения содержимого
Отличаем новую сборку сайта от значимого изменения страницы при выставлении lastmod в sitemap.
Практическая задача
Не выдавать каждую техническую пересборку за свежую редакцию статьи в XML sitemap. Google использует lastmod, если значение постоянно и проверяемо соответствует последнему существенному изменению страницы; простая смена года в копирайте не является таковым. В учебном примере сохранён отпечаток значимого контента статьи, ссылок и структурированных данных; время сборки не входит в отпечаток. Это архитектурная иллюстрация: ваша CMS должна хранить утверждённое время последней содержательной правки и не угадывать его по хешу задним числом. Не выдумывайте дату публикации. Этот сценарий применим, когда у команды есть контроль над входом или выходом AI-приложения и требуется конкретный сигнал о нарушении правила, а не общее впечатление от нескольких ответов. Все входы ниже вымышлены; числовые результаты относятся только к этим примерам.
Документация методов Python и синтаксиса workflow сверена 20.09.2026. Если вы используете другое окружение, проверьте совместимость до копирования команд. Статья не утверждает, что показанный код измеряет качество конкретной модели или заменяет ручную проверку.
Подготовка и проверяемый контракт
Перед запуском запишите, какие данные считаются входом, что является ожидаемым результатом, что именно означает отказ и кому предстоит разбирать расхождение. Для такой проверки храните тестовый вход, ожидаемый результат и фактический исход раздельно: если они смешаны, тест может подтверждать сам себя. Используйте стабильные синтетические ID, чтобы видеть ошибку в журнале, не раскрывая содержимое клиентских обращений.
Сначала прогоните тест на маленьком входе, где правильное поведение известно вручную. Затем внесите одну контролируемую ошибку и убедитесь, что код её замечает. После этого верните корректный набор и только тогда расширяйте проверку до реальных данных. Не переносите демонстрационные численные значения или пороги в производство без отдельного обоснования: они выбраны для наглядности, а не рассчитаны по вашей аудитории.
Вход и ожидаемый результат
Статья и ссылки не меняются между двумя сборками 20 и 21 сентября; lastmod сохраняет дату редакторской правки 19 сентября. Печатает False для пересборки и True для изменения тела статьи. Перед тем как применять правило к закрытым данным, обсудите пограничные случаи, которые могут поменять интерпретацию входа. Запись в документации о границах теста не менее важна, чем зелёный check.
Пошаговые действия
- Создайте
scripts/check.pyв корне репозитория и вставьте код из блока ниже. Он использует названия функций стандартной библиотеки, указанные в официальных ссылках в конце статьи. - Выполните
python scripts/check.pyлокально. Не продолжайте, если уже демонстрационная фикстура даёт иной результат: сначала проверьте копирование кода и кодировку файла. - Определите, какие поля рендера отражают значимое изменение, включая основные ссылки и структурированные данные. Запустите код для неизменной пересборки и для редакторской правки; сравните отпечатки. Свяжите изменение отпечатка с датой утверждённого релиза в CMS, а не с текущим временем запуска теста. Затем проверьте готовый sitemap и страницу, чтобы lastmod не опережал фактическую редакцию. Помните, что один хеш не доказывает, что изменение полезно читателю.
- Создайте
.github/workflows/ai-corpus-check.ymlиз YAML-шаблона. Событиеpull_requestполезно для проверки данных до слияния; чтение репозитория ограниченоpermissions: contents: read. Скрипт не должен получать ключ внешней модели или реальные секреты. - В разделе Actions откройте job
check, сопоставьте его код завершения с локальным прогоном и зафиксируйте ссылку на проверенный коммит в PR. Не принимайте зелёный результат на старой ревизии за проверку последнего изменения.
# scripts/check.py
import hashlib,json
def fingerprint(article):
selected={k:article[k] for k in ('body','links','structured_data')}
raw=json.dumps(selected,ensure_ascii=False,sort_keys=True,separators=(',',':')).encode('utf-8')
return hashlib.sha256(raw).hexdigest()
article={'body':'Проверенная инструкция','links':['/source'],'structured_data':{'type':'Article'}}
a=fingerprint(article)
rebuild=dict(article,build_time='2026-09-21T10:00:00Z')
assert fingerprint(rebuild)==a
revised=dict(article,body='Исправленная инструкция')
assert fingerprint(revised)!=a
print('rebuild changes lastmod?',fingerprint(rebuild)!=a)
print('editorial edit changes fingerprint?',fingerprint(revised)!=a)
name: AI corpus checks
on:
pull_request:
permissions:
contents: read
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: '3.13'
- run: python scripts/check.py
Ошибки интерпретации и границы
Если изменился только дизайн, выбор обновлять lastmod зависит от того, изменился ли существенный контент страницы; схема selected должна соответствовать реальному рендеру. Если вы расширяете набор случаев, добавляйте не только новые примеры, но и отрицательные случаи, на которых тест обязан упасть. Проверяйте, что изменение expected прошло ревью отдельно от изменения кода: иначе можно незаметно изменить правило под текущий ответ системы. Избегайте вывода полного приватного набора в CI и не сохраняйте в артефактах ответ закрытой модели без решения о доступе и хранении.
Ошибка выполнения самого Python, нераспознанный формат входа и обнаруженный бизнес-дефект — разные ситуации. В сообщении теста указывайте тип проблемы и безопасный ID. Если тест требует внешний сервис, вынесите его из PR с недоверенным кодом и явно ограничьте доступ к токенам; этот пример намеренно работает локально. Перед публикацией каких-либо результатов опишите методику, область применения и происхождение примеров, иначе читатель воспримет демонстрационную арифметику как характеристику продукта.
Практический разбор именно этого контроля
Не выдавать каждую техническую пересборку за свежую редакцию статьи в XML sitemap. Для самостоятельной проверки сначала выпишите три наблюдаемых состояния: допустимый вход, намеренно недопустимый вход и видимый сигнал отказа. В данной фикстуре это выглядит так: Статья и ссылки не меняются между двумя сборками 20 и 21 сентября; lastmod сохраняет дату редакторской правки 19 сентября. При успешном тесте ожидается: Печатает False для пересборки и True для изменения тела статьи. Не превращайте это в числовой KPI: здесь проверяется контракт на конкретных примерах, а не поведение модели на пользовательском трафике.
Если изменился только дизайн, выбор обновлять lastmod зависит от того, изменился ли существенный контент страницы; схема selected должна соответствовать реальному рендеру. Подключая проверку к продукту, расположите её до той операции, ради которой она написана: парсинга, сохранения, отображения или экспорта. Для каждого нового формата добавляйте отдельный негативный пример и письменное решение, почему он отклоняется. Отдельно просмотрите обработку ошибок: система должна отличать невалидный ответ AI от сбоя тестовой инфраструктуры, а пользователь не должен видеть сырой стек или приватное содержимое.
Чек-лист финальной проверки
- Синтетический вход и ожидаемый исход согласованы предметным владельцем.
- Команда
python scripts/check.pyработает локально и в CI на одной версии файлов. - Негативный случай обнаруживается, а не только успешный случай проходит.
- Имена ID и меток уникальны там, где этого требует контракт.
- В репозитории, логах и артефактах нет реальных секретов и приватных текстов.
- Понятно, какой дефект тест находит и каких выводов о качестве AI он не даёт.
- Ссылки на применённые функции и синтаксис workflow перепроверены при переносе.
FAQ
Можно ставить текущую дату при любом деплое?
Это может сделать lastmod неточным, если страница фактически не менялась.
Хеш сам сообщает дату изменения?
Нет, время хранится в редакционной записи отдельно.
Что если исправлены внутренние ссылки?
Google приводит изменения ссылок как пример значимого изменения; включите ссылки в отпечаток.
Зачем сортировка ключей JSON?
Чтобы порядок записи словаря не создавал ложный сигнал о правке.
Что делать после обнаружения сбоя
Сохраните конкретный ID, воспроизведите его на текущей ревизии и отделите ошибку входных данных от ошибки функции. Если неверна контракт, исправьте её после предметного ревью; если неверен код, сначала оставьте проваливающийся тест, затем вносите исправление. После зелёного запуска просмотрите соседние случаи с похожими признаками, чтобы локальная правка не изменила другое согласованное поведение. Сохраните версии кода, набора и параметров запуска рядом с выводом: без них сравнивать результаты в будущем нельзя. Не приводите цифру из синтетического примера как измеренный показатель продукта.
Официальные первоисточники
Проверено 20.09.2026: 1, 2, 3, 4, 5, 6. Описание переписано своими словами; изменяемые версии и поля нужно повторно сверять перед дальнейшим использованием.
Читайте также
Как исключить bias из weight decay через Optax
Optax 0.2.6: маска add_decayed_weights применяет decay к kernel и оставляет bias без изменения.
Как использовать Huber loss в Optax для регрессии с выбросами
Optax 0.2.6: Huber loss квадратичен около нуля и линеен после delta; проверяем ошибки 0,5 и 2.
Как использовать sigmoid focal loss в Optax
Optax 0.2.6: focal loss для logits 0 и labels 0/1 при gamma=2; проверка симметричного базового значения.
Комментарии
Пока тихо. Скажите первое слово