0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AI agent が skill 規範を守らなかった実録 — Qiita CI 14 回連続失敗と機械ガード設計

0
Posted at

結論

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 で公開しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?