Claude Code に「同じ指摘を二度させない」仕組みを作る — 失敗台帳と patch/process 判定の自己改善ループ
TL;DR
- Claude Code を使い込むと、同じ修正を何度も指摘していることに気づきます。「そこじゃない」「次からこうして」を毎回言っているのに、翌日また同じことをやられます
- これは記憶の問題ではなく 「指摘を構造に書き戻す経路がない」 という設計の問題です
- そこで、セッションログ (
*.jsonl) から自分の修正・指摘を抽出し、失敗台帳 (ledger.md) に正規化キーで記録して再発回数を追跡するスキルを作りました - キモは 「再発 2 回以上は対症療法 (patch) を禁止し、構造修正 (process) を起案する」 という閾値ルールです。注意書きを足すだけの対応を意図的に禁じています
- 反映先 (CLAUDE.md / スキル /
README.mdなどディレクトリ固有のマニュアル / メモリ) は人間が決め、書き込み前に必ず差分を見せます。AI に自己改変の全権を渡しません - 反映の完全自動化はしていません。ルール (ガードレール) は成果物 (コード) より重要で、その所在と中身は人間が把握し続けるべきだ、という立場を取っています
- 記事の後半に、そのまま使えるスキル定義(プロンプト本体)を載せています
背景 — 「指摘の蒸発」が起きる
エージェントに作業を任せていると、こちらの修正は基本的にその場限りで消費されます。
- 「ファイルはここじゃなくてこっちに置いて」→ 直る。翌日また間違える
- 「コミットメッセージにこの行を必ず入れて」→ 入る。次のセッションでは忘れている
- 「新機能は既存の似た機能と UI を揃えて」→ 揃う。別の機能では揃わない
CLAUDE.md に書けば残る、というのは正しいです。ですが問題は 「何を CLAUDE.md に昇格させるべきか」を判断する経路がない ことです。すべての指摘を書き戻せばルールが肥大化してノイズになりますし、書き戻さなければ蒸発します。
人間相手なら「これ何回も言ってるよね」という体感がフィルタになります。エージェント運用にはその体感がありません。だから 「何回指摘したか」を機械的にカウントする台帳 が要る、というのがこのスキルの出発点でした。
設計 — フィードバックループの全体像
セッションログ (*.jsonl)
│ ① corrections を抽出
▼
失敗台帳 (ledger.md)
│ ② 正規化キーで照合 → 再発回数 +1
▼
判定 (patch か process か)
│ ③ 再発2回以上なら構造修正を起案
▼
人間が反映先を決定
│ ④ 差分を提示してから書き込む
▼
CLAUDE.md / スキル / README.md 等 / メモリ
ポイントは、抽出 → 記録 → 判定 までは自動化し、反映 (書き戻し) だけは人間のゲートを必ず通すことです。自己改変を全自動にすると、誤った学習が静かに蓄積して取り返しがつかなくなります。
① セッションログから corrections を抽出する
Claude Code は会話履歴を以下に逐次保存しています。
~/.claude/projects/<encoded-cwd>/<session-id>.jsonl
1 行 1 メッセージの JSONL で、type が "user" の行が人間の発話です。ここから 「行動を変えるべき指摘」 だけを拾います。
- 「〜じゃなくて〜にして」「やり直して」「それは違う」
- 「次から〜して」「〜は禁止」「〜のときは必ず〜」
- 同じ趣旨が複数回出ているもの(再発候補)
単なる感想や雑談(「いいね」「ありがとう」)は対象外です。直前のアシスタントの行動とセットで「何を直されたか」を 1 行に要約するのがコツです。指摘単体を切り出しても、何の行動への修正かが分からないと台帳に落ちません。
セッションの特定は mtime ではなく環境変数で
複数セッションを並行で走らせていると、「最新更新の jsonl = 自分」という前提が壊れます。別のセッションが後から書き込めば、そちらが mtime 最新になるからです。
自分のセッションは環境変数で一意に取ります。
echo "$HOME/.claude/projects/<encoded-cwd>/${CLAUDE_CODE_SESSION_ID}.jsonl"
これは地味ですが、並行運用時に間違ったセッションを振り返って的外れな学習をする事故を防ぐための要です。
② 失敗台帳 (ledger.md) で再発を数える
抽出した各 correction を 正規化したパターン名 に丸めて、台帳の既存エントリと照合します。
- 既存に一致 → 再発回数を +1、最新日付を更新
- 新規 → 再発回数 1 で新規エントリ
台帳の 1 エントリはこんな形にしています。
## 新機能を既存の類似機能と揃える (一貫性)
- 再発回数: 1 (セッション内で 3 回要求)
- 初出: 2026-06-20 / 最新: 2026-06-20
- スコープ: session
- 症状: 機能拡張時に「既存機能と揃えて / 統一感」を繰り返し要求された
- 構造修正: -
- ステータス: structured
- confidence: 中
- 反映先候補: docs/conventions/design-principles.md
- 反映実績: 2026-06-20 design-principles.md (§8 追加 + チェックリスト項目)
ここで効くのが 正規化キーの設計 です。表現は毎回違います(「揃えて」「統一感」「同じにして」)が、指している失敗は同じです。表層の文言で別エントリを作ると再発がカウントされません。「行動レベルで何を間違えたか」で正規化するのが肝心です。
③ patch か process か — これがこのスキルの本体
再発回数で対応の質を切り替えます。
| 再発回数 | 許容する対応 |
|---|---|
| 1 回目 | 注意書きレベルの対症療法 (patch) でよい |
| 2 回以上 | 対症療法を禁止し、構造修正 (process) を起案する |
「注意書きを足す」は一番安易で、一番効かない対応です。CLAUDE.md に「〜に注意」を増やしても、ルールが増えるほど一行あたりの拘束力は下がります。2 回再発したものは、注意ではなく「再発し得ない仕組み」に変えます。
- ❌ patch: 「コミット前に行を入れ忘れないよう注意」と CLAUDE.md に追記
- ✅ process: コミット文を生成する手順自体にその行を埋め込む / pre-flight チェック項目を新設する
この「2 回目は対症療法禁止」という縛りを明文化しておくと、安易な注意書きで茶を濁す逃げ道が塞がれます。再発カウントは、この判定を発動させるためのトリガーとして機能します。
④ 反映は人間のゲートを通す
判定まで終えたら、スキルは結果を提示していったん止まります。
- corrections 一覧(何を直されたか)
- 各パターンの再発回数とステータス
- 再発 2 回以上への構造修正の起案
- おすすめ反映先候補と confidence
反映先の候補は、用途に応じて使い分けます。
| 反映先 | 何を書くか |
|---|---|
| CLAUDE.md | プロジェクト全体に効かせたい普遍的な方針・禁止事項 |
.claude/skills/ のスキル |
特定の作業手順そのものに埋め込むべきルール |
README.md などディレクトリ固有のマニュアル |
そのディレクトリ/サブシステムでだけ効けばいい規約 |
| メモリ | 嗜好や事実など、挙動を縛るルールではない情報 |
反映先は人間が指定します。AI に「どこに書き戻すか」まで決めさせません。指定を受けたら、
- 反映後の差分 (diff) を必ず提示します
- 承認を得ます
- 承認後にスキルが実際に書き込みます
- 台帳に「反映実績(日付・反映先)」を追記し、ステータスを
structured/patchedに更新します
いかなる書き込み(ルール / スキル / CLAUDE.md / 台帳いずれも)も、事前の差分提示と承認なしには行いません。
なぜ反映先だけは人間が握るのか
ここは設計思想の話なので、はっきり書いておきます。反映の抽出・判定まで自動化しておきながら、反映先の決定だけを意図的に人間に残しているのには理由があります。
まず実利的な理由です。CLAUDE.md に何でもかんでも書き込むと、エージェントの性能はむしろ落ちます。CLAUDE.md は毎回コンテキストに載るので、雑多なルールが増えるほど 1 ルールあたりの拘束力は薄まり、本当に効かせたい方針がノイズに埋もれます。だから「このルールは CLAUDE.md か、スキルか、README.md のようなディレクトリ固有マニュアルか」という振り分けは、それ自体がエージェントの性能を左右する設計判断です。ここを LLM の自己申告に任せると、安易に CLAUDE.md へ積まれて全体が鈍ります。反映先の選定は、性能チューニングそのものだと考えています。
そしてより本質的な理由です。ルール (ガードレール) は、成果物 (コード) よりも重要です。コードは間違えても作り直せますし、レビューで弾けます。ですがガードレールが歪むと、そのあと生成されるすべての成果物が歪んだ前提の上に乗ります。影響範囲が桁違いに広いのです。だから自分は、コードの一行一行を完全に把握することにはこだわらない一方で、ガードレールがどこに・何と書かれているかは、人間が頭の中に持っておくことを最優先にしています。
この振り返り→反映までを完全に自動化することも、技術的には可能です。たしかに楽にはなります。ですが自分はあえてそうしていません。それは、反映先の判断を手放した瞬間、自分の運用環境のガードレールが「自分の知らないところで増殖している」状態になるからです。たまたまうまく動いているうちはいいですが、効かなくなったときに原因を追えません。自動化する場所と、あえて手で握る場所を分ける——その線引きをガードレールの境界に引いている、というのがこのスキルの一番の主張です。
スキル定義(そのまま使える形)
ここまでの仕組みを、Claude Code のスキルとして書き起こしたものが以下です。環境固有の情報は一般化してあります。.claude/skills/feedback/SKILL.md のように置けば、/feedback で呼び出せます。
---
name: feedback
description: セッションのログ(*.jsonl)を振り返り、ユーザーの修正・指摘(corrections)を抽出して失敗台帳 .claude/ledger.md で再発を追跡する再発防止フィードバックループ。再発2回以上は対症療法を禁じ構造修正を起案。反映先はユーザーが決定し、書き込み前に必ず差分を提示してからスキルが反映する。引数なし=現在のセッションのみ / all=全セッション横断。
---
セッションでやり取りした内容を振り返り、ユーザーから繰り返し受ける修正・指摘を
「学び」としてルール / スキル / CLAUDE.md / ディレクトリ固有のマニュアルに
書き戻すための再発防止フィードバックループ。
## スコープ (引数)
| 引数 | scope | 対象 jsonl |
|---|---|---|
| (なし) | session | 現在のセッション 1 本だけ |
| `all` | all | プロジェクトの全セッション横断 |
| `since <ISO時刻>` | all (範囲指定) | 指定時刻以降のメッセージのみ |
## 手順
### 1. スコープと対象範囲を決める
- session (引数なし): 環境変数で自分のセッションを一意に特定する。
```bash
echo "$HOME/.claude/projects/<encoded-cwd>/${CLAUDE_CODE_SESSION_ID}.jsonl"
```
※ 「mtime 最新 = 自分」は他セッション並行稼働時に誤爆するため使わない。
- all: 全 jsonl を対象にする。範囲は (1) `since` 引数 → (2) 直近の日次振り返り
markdown の mtime 以降 → (3) 直近 24 時間、の優先順で決める。
### 2. corrections を抽出する
`type: "user"` のテキストから、ユーザーの修正・指摘・やり直し・禁止・好みの表明を
抽出する。assistant 側の直前の行動とセットで「何を直されたか」を要約する。
単なる感想や雑談は対象外。行動を変えるべき指摘だけを拾う。
### 3. 失敗台帳 (.claude/ledger.md) を照合・更新する
各 correction を正規化したパターン名で既存エントリと照合する。
一致 → 再発回数 +1・最新日付更新 / 新規 → 再発回数 1 で作成。
### 4. 判定 — patch か process か
- 初回 (再発回数 1): 注意書きレベルの対症療法 (patch) を許容。
- 再発 2 回以上: 対症療法を禁止し、構造修正 (process) を起案する。
例: 注意書き追記ではなく、再発し得ない手順・チェックの新設。
### 5. 結果を提示して停止する
corrections 一覧 / 各パターンの再発回数とステータス / 再発 2 回以上への構造修正の
起案 / おすすめ反映先候補 (CLAUDE.md・スキル・README 等のマニュアル・メモリ) と
confidence をまとめて提示し、反映先はユーザーの指示を待つ。
スキルが勝手に反映先を決めない。
### 6. 反映 — 必ず差分を見せてから書き込む
ユーザーが反映先を指定したら、反映後の差分を提示 → 承認 → スキルが書き込む →
台帳に反映実績を追記しステータスを structured / patched に更新する。
いかなる書き込みも、事前の差分提示と承認なしには行わない。
スキルの規模はこの 1 ファイル(100 行強)で十分です。複雑なコードは要らず、「何をルールとして昇格させるかの判断基準」を文章で固定することが本質だからです。
落とし穴
1. corrections と感想の切り分けが曖昧だと台帳が汚れる
「いいね」「助かる」のような肯定的感想を correction として拾うと、台帳がノイズで埋まります。行動の変更を要求しているかを基準に切ります。迷ったら拾わない方が台帳は健全に保てます。
2. 正規化キーが甘いと再発が永遠に 1 のまま
表層の言い回しでエントリを分けると、同じ失敗が毎回「新規・再発 1」で記録され、process 判定が永遠に発動しません。行動レベルで丸めることです。逆に丸めすぎると無関係な指摘が同一視されるので、ここは運用しながら粒度を調整します。
3. 全自動の自己改変は事故る
「振り返って学んだことを自動で CLAUDE.md に反映」まで通すと、誤抽出・誤判定がそのままルール化されます。しかもルールは次セッション以降の挙動を縛るので、誤りが自己増殖します。反映だけは必ず人間のゲートを通す設計にして、利便性を意図的に削りました。
4. スコープの取り違え
「現在のセッションだけ」と「全セッション横断」を混同すると、関係ないセッションの指摘を拾います。範囲指定(このセッション / 全体 / 指定時刻以降)を引数で明示的に切り替えられるようにしておくと安全です。
応用
- 作業の区切りで「振り返り → コンテキスト圧縮」をセットで回す: 一日の作業の節目ごとに feedback を走らせて corrections を台帳に積み、そのうえでコンテキストを compaction します。学びを先に台帳へ逃がしてから圧縮するので、文脈を畳んでもルール候補が失われません。私はこれを日々の区切りのルーチンにしています
-
CLAUDE.md の健康診断: 台帳の
structured比率を見れば、「指摘 → 仕組み化」がどれだけ回っているかが分かります - チーム展開: 個人の CLAUDE.md だけでなく、共有のコーディング規約ドキュメントへの昇格判断にも同じ閾値ルールが使えます
まとめ
エージェント運用で「同じ指摘を繰り返す」のは、記憶力ではなく 指摘を構造に書き戻す経路の不在 が原因です。
- セッションログから corrections を抽出し、失敗台帳で再発回数を数えます
- 再発 2 回以上は対症療法を禁止し、構造修正を起案するという閾値を明文化します
- 反映先 (CLAUDE.md / スキル /
README.md等 / メモリ) は人間が決め、書き込み前に必ず差分を見せます - 抽出と判定は自動化し、ガードレールの反映先決定だけは人間が握ります。ルールは成果物より重要で、影響範囲が桁違いに広いからです
「振り返り」を体感任せにせず、カウント可能なループにしたことで、指摘が蒸発せずに仕組みへ昇格していきます。注意書きを増やす運用から、注意が要らない設計へ寄せていく——その手綱を、自動化に渡しきらずに自分で握り続けるための足場です。
参考
- Claude Code: https://claude.com/claude-code
- Claude Code memory (CLAUDE.md): https://docs.claude.com/en/docs/claude-code/memory
Discussion