惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

U
Unit 42
K
Kaspersky official blog
L
LangChain Blog
有赞技术团队
有赞技术团队
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
Microsoft Azure Blog
Microsoft Azure Blog
Stack Overflow Blog
Stack Overflow Blog
美团技术团队
Vercel News
Vercel News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
G
Google Developers Blog
宝玉的分享
宝玉的分享
月光博客
月光博客
爱范儿
爱范儿
The Register - Security
The Register - Security
S
SegmentFault 最新的问题
M
MIT News - Artificial intelligence
F
Full Disclosure
Engineering at Meta
Engineering at Meta
阮一峰的网络日志
阮一峰的网络日志
Hugging Face - Blog
Hugging Face - Blog
A
About on SuperTechFans
WordPress大学
WordPress大学
D
Docker
Y
Y Combinator Blog
N
News and Events Feed by Topic
P
Proofpoint News Feed
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Recorded Future
Recorded Future
IT之家
IT之家
C
CXSECURITY Database RSS Feed - CXSecurity.com
Security Latest
Security Latest
Spread Privacy
Spread Privacy
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Fortinet All Blogs
AWS News Blog
AWS News Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
D
DataBreaches.Net
Recent Announcements
Recent Announcements
博客园 - Franky
Google DeepMind News
Google DeepMind News
小众软件
小众软件
B
Blog RSS Feed
I
InfoQ
Attack and Defense Labs
Attack and Defense Labs
云风的 BLOG
云风的 BLOG

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Как научить AI писать коммиты по правилам вашего проекта, а не Conventional Commits по умолчанию
zzzkorn · 2026-06-08 · via Все публикации подряд на Хабре

Любой AI-инструмент умеет генерировать commit message. Проблема в том, что он генерирует что-то разумное — но не то, что принято в вашем проекте: не знает ваш формат с тикетами, не вытаскивает номер задачи из ветки, не учитывает какие типы у вас разрешены.

В этой статье я покажу как один раз описать правила своего проекта так, чтобы AI следовал им предсказуемо — каждый раз. Основной пример на Claude Code, но паттерн и готовый скрипт переносятся на любой инструмент: Cursor, Copilot Chat, git hook с API-вызовом.


Проблема, которую не решает commitlint

Commitlint — отличный инструмент. Он ловит коммиты неправильного формата и не даст смержить ветку с wip или асдф в истории. Но он не помогает их написать.

Он говорит «неправильно» — и возвращает тебя к пустой строке. Сформулировать правильное сообщение всё равно надо самому.

В конце рабочего дня, когда ты только что пофиксил хитрый баг в маппере — это отдельная мыслительная задача после нескольких часов другой мыслительной работы. Поэтому даже в проектах с commitlint история нередко выглядит так:

git log --oneline

a3f1c2e fix: fixed
9bd04a1 feat: wip
c782d3f refactor: changes
4e910bb fix: bug
2a33f0c chore: update

Формат формально соблюдён. Commitlint доволен. История бесполезна.

Вместо того что должно быть:

git log --oneline

a3f1c2e DEV-1677/feat(discrepancies): реализовать полнотекстовый поиск ТОРГ-2
9bd04a1 DEV-1676/feat(auth): добавить JWT-аутентификацию с mock-режимом для разработки
c782d3f DEV-1704/fix(delivery): исправить фильтрацию поставок по статусу
4e910bb DEV-1698/refactor(etrn): упростить маппер статусов электронной накладной
2a33f0c DEV-1690/test(acceptance): добавить интеграционные тесты приёмки

Как я к этому пришёл

Проблема не новая, решений много. Я прошёл через несколько:

commitizen — первое что попробовал. Интерактивный wizard в консоли задаёт вопросы: тип? scope? описание? Звучит удобно, но на практике замедляет: ты и так знаешь что хочешь написать, просто не хочешь думать о синтаксисе. Плюс под наш нестандартный формат с тикетом в префиксе он не гнётся без плясок с конфигом.

Git hook + локальная LLM — видел статью на Хабре, попробовал. Работает, но требует настройки на каждой машине и зависит от того, какая модель стоит локально. При смене ноутбука надо всё поднимать заново.

IDE плагины (JetBrains AI, GitLens) — кнопка "Generate commit message" есть. Жмёшь — получаешь что-то вроде feat: update delivery service. Формат проекта не знает, тикет не вытаскивает, каждый раз дописываешь руками.

Готовые скилы из Claude Directory — когда начал плотно работать с Claude Code, нашёл готовый /commit в маркетплейсе. Тот же результат: Conventional Commits по умолчанию, без понятия о нашем формате с тикетами.

Просто спрашивать Claude — "напиши коммит для этих изменений" работает, но непредсказуемо: иногда одна строка, иногда три абзаца с объяснениями, иногда в markdown-блоке. Нельзя просто скопировать.

У всех этих решений одна общая проблема: они не знают о правилах конкретного проекта. Генерируют что-то разумное — но не то, что ожидает ваш commitlint и ваши коллеги. Решение — один раз явно описать правила своего проекта и получать предсказуемый результат каждый раз.


Соглашения по коммитам

Чтобы было понятно о чём речь — вот формат с которым я работаю:

<ticket>/<type>(<scope>): <description>
  • <ticket> — номер задачи из трекера: DEV-123PROJ-42

  • <type> — featfixrefactortestcidocsstyleperfbuildhotfix

  • <scope> — модуль или слой: deliveryauthgoods

  • <description> — повелительное наклонение, строчная буква, без точки, на русском

Правила зафиксированы в .git-commit-template — он открывается в редакторе при ручном git commit. Этот же алгоритм мы реализуем для AI-assisted пути.

Формат несложный, но каждый раз требует: вспомнить номер задачи из имени ветки, выбрать правильный тип, сформулировать повелительное наклонение, не забыть про строчную букву. Это ~10 секунд думать — каждый коммит, каждый день.


Что такое скилы в Claude Code

Claude Code — AI-ассистент в CLI, который работает прямо в терминале. Скилы — это его расширение: markdown-файл с инструкциями, который живёт в ~/.claude/skills/<name>/SKILL.md и вызывается командой /name.

Это не плагин и не скрипт. Это структурированный prompt с жёстким алгоритмом — предсказуемый, версионируемый, командный.

Ключевое отличие от "просто спросить модель": скил каждый раз выполняет одни и те же шаги в одном и том же порядке и выдаёт результат в одном и том же формате. Это воспроизводимо.

Почему не просто CLAUDE.md?

Резонный вопрос: а зачем отдельный скил, если можно добавить правила коммитов прямо в CLAUDE.md?

Можно. Но разница в том, как работает каждый из инструментов.

CLAUDE.md — это фоновый контекст: файл загружается в каждый разговор и описывает проект в целом — архитектуру, соглашения, стек. Это инструкции "как думать об этом коде". Если туда добавить пошаговый алгоритм генерации коммита, он будет лежать мёртвым грузом в каждом запросе — когда вы просите объяснить функцию, исправить баг, написать тест.

Скил — это явный вызов/commit-msg говорит модели "сейчас делаем только это, по этому алгоритму". Нет борьбы за внимание с архитектурными правилами и описанием стека. Алгоритм выполняется полностью, в нужном порядке, без оговорок.

Ещё один аргумент: скил — единица распространения. Его можно поставить из маркетплейса, передать коллеге одним файлом, опубликовать с версией. CLAUDE.md — это файл проекта, он не путешествует отдельно.

Практическое правило: CLAUDE.md описывает что есть в проекте, скил описывает что сделать прямо сейчас.


Демо

Шаг 1 — смотрим что изменилось:

$ git status
On branch feature/DEV-2041-delivery-pagination
Changes not staged for commit:
  modified: src/digital_delivery/infrastructures/db/repositories/delivery.py
  modified: src/digital_delivery/application/use_cases/list_deliveries.py
  modified: src/digital_delivery/presentation/api/rest/v1/controllers/delivery_controller.py
  modified: src/digital_delivery/presentation/api/rest/v1/schemas/delivery.py

Четыре файла, три слоя архитектуры. Формулировать руками — надо держать в голове что именно менялось.

Шаг 2 — запускаем скил:

> /commit-msg

Агент последовательно читает контекст — это видно в интерфейсе Claude Code:

● bash: git branch --show-current
● bash: git diff HEAD

Читает реальный код, а не только имена файлов — поэтому понимает смысл изменения, а не просто перечисляет что поменялось.

Шаг 3 — результат:

DEV-2041/feat(delivery): добавить пагинацию в список поставок

Одна строка. Копируешь, вставляешь:

git commit -m "DEV-2041/feat(delivery): добавить пагинацию в список поставок"

Полный исходник скила

Файл ~/.claude/skills/commit-msg/SKILL.md:

---
name: commit-msg
description: >
  Генерирует готовое git commit message по изменениям текущей ветки
  в формате проектного шаблона: <ticket>/<type>(<scope>): <description>.
  Использовать когда: "напиши commit message", "придумай коммит",
  "suggest a commit", /commit-msg.
---

# commit-msg

Сгенерировать точное commit message по формату проекта.

## Шаги

1. Получить контекст изменений:
   git branch --show-current
   git diff HEAD
   git diff --cached

   Если оба diff пусты — посмотреть на untracked файлы в git status.

2. Определить ticket из имени ветки: паттерн [A-Z]+-\d+
   - feature/DD-123-add-pagination → DD-123
   - fix/PROJ-7-broken-mapper → PROJ-7
   - Если не найден — писать без префикса: <type>(<scope>): <description>

3. Проанализировать изменения: что добавлено, удалено, изменено
   и каков смысл изменения, а не только какие строки поменялись.

4. Выбрать тип:
   feat     — новый функционал
   fix      — исправление ошибки
   refactor — рефакторинг без изменения поведения
   test     — тесты
   ci       — CI/CD, скрипты, пайплайны
   docs     — документация
   style    — форматирование, codestyle
   perf     — оптимизация производительности
   build / chore — сборка, зависимости, конфиги
   hotfix / revert — критические исправления или откат

5. Составить описание:
   - Повелительное наклонение: «добавить», не «добавлено»
   - Строчная первая буква, без точки в конце
   - На русском языке
   - Не более ~72 символов включая весь префикс

6. Вывести ТОЛЬКО результат — без объяснений, без markdown-блоков,
   без «вот твоё сообщение:». Просто текст для копирования.
   - Одно изменение: одна строка commit message.
   - Два или более несвязанных изменения: перечислить найденные изменения,
     предложить разбить на отдельные коммиты и для каждого выдать
     готовое сообщение.

Ещё два случая из практики

Уточнение формулировки

Первый вариант не нравится — слишком общий:

> перефразируй, акцент на том что mock только для dev-окружения

DEV-1676/feat(auth): добавить JWT с автоматическим mock-режимом вне production

Это диалог, не одноразовый prompt. Можно итерировать.

Грязный diff — самый ценный сценарий

Ты работал над фичей и по пути исправил несвязанный баг. В diff — два разных изменения. Сам бы ты, скорее всего, написал один коммит и не заметил.

Агент видит diff целиком и реагирует иначе:

> /commit-msg

В diff обнаружено два несвязанных изменения.
Рекомендую разбить на два коммита — добавьте файлы каждого изменения отдельно через git add.

1. DEV-1677/feat(discrepancies): реализовать полнотекстовый поиск ТОРГ-2
2. DEV-1677/fix(delivery): исправить обработку пустого списка позиций

Адаптация под свой проект за 5 минут

Скил — текстовый файл. Правила проекта прописываются в SKILL.md явно — всегда понятно чему именно он следует, менять легко.

Ниже примеры того, что вписать в секцию ## Шаги вместо наших правил — под разные командные форматы:

Conventional Commits, английский:

Формат: <type>(<scope>): <description>
Язык: английский, imperative mood ("add", "fix", "remove")
Тикет: не используется

Jira в скобках:

Формат: [PROJ-123] <type>(<scope>): <description>
Тикет: в квадратных скобках в начале, из имени ветки

Автоопределение языка по истории:

Посмотреть последние 5 коммитов через git log --oneline.
Если коммиты на русском — описание на русском.
Если на английском — на английском.

Принудительный тип по ветке:

Если ветка начинается с hotfix/ — тип всегда hotfix, игнорировать остальные правила выбора типа.

Правила прописываются один раз — если конвенции команды изменились, обновляешь SKILL.md тем же PR.


Идея работает без Claude Code

SKILL.md — это обычный текстовый файл. Внутри — пронумерованный алгоритм на человеческом языке. Ничего специфичного для Claude Code в нём нет.

Если вы работаете в другом инструменте, тот же подход переносится напрямую:

Cursor / Copilot Chat / любой чат с LLM — скопируйте содержимое секции ## Шаги как системный промпт или вставьте в начало запроса. Модель выполнит те же шаги.

Git hook + API — если хотите автоматику при каждом git commit, оберните алгоритм в commit-msg hook с curl-вызовом к любому LLM API:

#!/bin/sh
DIFF=$(git diff --cached)
BRANCH=$(git branch --show-current)
SKILL=$(cat "$(git rev-parse --show-toplevel)/.claude/skills/commit-msg/SKILL.md")

COMMIT_MSG=$(jq -n \
  --arg skill "$SKILL" \
  --arg branch "$BRANCH" \
  --arg diff "$DIFF" \
  '{model:"gpt-4o",messages:[
    {role:"system",content:$skill},
    {role:"user",content:"Branch: \($branch)\n\nDiff:\n\($diff)"}
  ]}' \
  | curl -s https://api.openai.com/v1/chat/completions \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -H "Content-Type: application/json" \
    -d @- \
  | jq -r '.choices[0].message.content')

echo "$COMMIT_MSG" > "$1"

Положите скрипт в .git/hooks/commit-msg и сделайте исполняемым:

chmod +x .git/hooks/commit-msg

При следующем git commit hook запустится автоматически и запишет сгенерированное сообщение.

Локальная модель (Ollama) — та же схема, только URL http://localhost:11434.

Скил в ~/.claude/skills/ — удобная форма упаковки для Claude Code. Но суть переносима: один раз описать правила проекта как чеклист, получать предсказуемый результат в любом инструменте.


Командное использование: скил как часть репозитория

Скил можно положить прямо в репо:

.claude/
  skills/
    commit-msg/
      SKILL.md

Тогда:

  • Все разработчики получают одинаковое поведение без настройки

  • Изменение формата коммитов = PR в SKILL.md, обсуждается как любой код

  • Новый человек в команде сразу пишет коммиты правильно

Это меняет природу инструмента: из личного помощника он становится частью командных конвенций.


Побочный эффект: дисциплина именования веток

Скил вытаскивает номер тикета из имени ветки. Если ветка называется fix-bug или my-feature — тикета нет, скил пишет коммит без префикса.

Это создаёт мягкое давление называть ветки правильно:

feature/DEV-123-add-search   → DEV-123/feat(search): ...  ✓
fix/PROJ-7-broken-mapper     → PROJ-7/fix(mapper): ...    ✓
my-branch                    → feat(<scope>): ...           (тикет потерян)

Никакого линтера на имена веток не нужно. Разработчик сам быстро замечает связь: назвал ветку правильно — скил работает полностью, назвал абы как — тикет в коммите пропал, придётся дописывать руками. Инструмент воспитывает привычку, не требуя её принудительно.


Ограничения

  • Не заменяет commitlint на CI. Скил помогает написать правильно, но не гарантирует это. Линтер всё равно нужен как страховка.

  • Большой грязный diff. На 500+ строках из несвязанных файлов формулировка может получиться общей. Лучше коммитить небольшими порциями.

  • Требует Claude Code в базовом варианте. Альтернативы — см. раздел «Идея работает без Claude Code».

  • Нет автозапуска в варианте с Claude Code. Скил вызывается вручную; для автоматики при каждом git commit используйте git hook — пример есть в разделе «Идея работает без Claude Code».


Итог

Коммит-сообщение — маленькая задача, которая повторяется сотни раз в год. Каждый раз несколько секунд на то, чтобы вспомнить формат, извлечь номер тикета из имени ветки, сформулировать повелительное наклонение. Скил убирает эту нагрузку и делает это воспроизводимо.

Главная идея не в том, что "Claude Code умеет генерировать коммиты". Главная идея — один раз описать правила своего проекта как пронумерованный чеклист и получать предсказуемый результат: в Claude Code через /commit-msg, в Cursor через системный промпт, в любом CI через git hook с API-вызовом.