結論
skill(指示書)に正しいテンプレートを書いても、AI agent はそれを守らないことがある。守らせるには機械ガードが必要。
今回の事故では、記事公開 agent(night-writer)が Qiita 用 frontmatter の必須フィールドを欠落させた記事を 3 件出力し、qiita-cli --all モードが全停止。10 日間で 14 回連続 CI 失敗を引き起こしました。
何が起きたか
2026 年 5 月、AI agent が adapt した Qiita 記事 3 件の frontmatter に以下の問題がありました。
| 問題 | 件数 |
|---|---|
updated_at の引用符欠落 |
2 件 |
id: null(既存記事は UUID 必須) |
1 件 |
qiita-cli publish --all は内部で Promise.all を使い並列 POST します。1 件で QiitaInternalServerError (500) が出ると処理全体は中断しますが、並列実行中の他の POST は完走する場合があります。
「CI ログは全件失敗に見えるが、Qiita 側には一部が投稿済み」という不整合状態が生まれました。修正→再 push を繰り返した結果、10 日間 14 回連続赤。
同じパターンで 2026-04-27 にも事故が起きており、skill に「次回は直せ」と書くだけでは再発を止められませんでした。
なぜ skill は守られなかったのか
AI agent の skill(= .md ファイルで書いた指示書)は「期待を文書化する場所」であり、「実行を保証する場所」ではありません。
特に以下のケースで守られにくいです。
- frontmatter のような定型構造: 本文生成に集中すると末尾の細部が崩れる
- 過去事例の未参照: context window に以前の事故ログが入っていない時
- 「次回は直す」系の記述: モデルは「次回」を覚えていない
対策:CI 多段防御
1. validate-frontmatter.sh
#!/usr/bin/env bash
set -euo pipefail
ERRORS=0
for f in public/*.md; do
if grep -qP "^updated_at:\s+[0-9]{4}-" "$f"; then
echo "❌ $f: updated_at missing quotes"
ERRORS=$((ERRORS + 1))
fi
if grep -qP "^id:\s+null\b" "$f"; then
echo "❌ $f: id must not be null"
ERRORS=$((ERRORS + 1))
fi
if grep -qP "^published_at:" "$f"; then
echo "❌ $f: published_at is not a valid Qiita field"
ERRORS=$((ERRORS + 1))
fi
done
[ "$ERRORS" -gt 0 ] && exit 1 || echo "✅ All frontmatter passed"
2. workflow に validation step を挿入
- name: Validate frontmatter
run: bash scripts/validate-frontmatter.sh
- name: Publish to Qiita
run: npx qiita publish --all
3. Rate Limit / 500 を warning 降格
- name: Publish to Qiita
run: |
set +e
OUTPUT=$(npx qiita publish --all 2>&1)
EXIT_CODE=$?
echo "$OUTPUT"
if echo "$OUTPUT" | grep -qE "QiitaRateLimitError|QiitaInternalServerError"; then
echo "::warning::Qiita API rate limit or 500 — not critical"
exit 0
fi
exit $EXIT_CODE
4. 投稿済み記事は ignorePublish: true 固定
一度投稿した記事は ignorePublish: true を付け、更新したい時のみ false に戻します。
5. Qiita API 直叩きで突合確認
curl -s -H "Authorization: Bearer $QIITA_TOKEN" \
"https://qiita.com/api/v2/items/{id}" | jq '.id, .title'
まとめ
AI agent が生成したファイルを CI に乗せる場合、skill だけでは品質保証にならない。
skill → CI validate → error handling の多段防御が必須。
詳細な実装と「で、どう稼ぐ?」の視点は masatoman.net で公開しています。