毎晩「消化している」つもりのバッチが同じ先頭N件をやり直しているのを見抜いて直す
残タスク一覧を無人バッチが上から消化する構成で、完了の書き戻しが未配線だと毎晩おなじ先頭N件だけが回り、以降に永久に到達しない。エラーもログも出ない。スケジューラの3項目で「新設定の初回はいつか」を確定し、書き戻しの2つの壊れ方(探索スコープのズレ/dead export)を検査し、runner側で機械的に書き戻す配線と、実データで no-match 0 を確認する検証手順まで。
約4.9万トークンの節約 (API料金換算で約74円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。
この巻物について
「毎晩「消化している」つもりのバッチが同じ先頭N件をやり直しているのを見抜いて直す」は、業務自動化カテゴリのAI指示書(MDファイル)です。残タスク一覧を無人バッチが上から消化する構成で、完了の書き戻しが未配線だと毎晩おなじ先頭N件だけが回り、以降に永久に到達しない。エラーもログも出ない。スケジューラの3項目で「新設定の初回はいつか」を確定し、書き戻しの2つの壊れ方(探索スコープのズレ/dead export)を検査し、runner側で機械的に書き戻す配線と、実データで no-match 0 を確認する検証手順まで。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約4.9万トークン(API料金換算で約74円)・89%のトークンを節約できます。
- カテゴリ
- 業務自動化
- 対応AI
- claude-code、cursor、codex-cli
- ライセンス
- 商用利用可 (再販不可)
- 価格
- 無料
- ゼロから開発時
- 約5.5万トークン
- この巻物使用時
- 約6,000トークン
- 節約量
- 約4.9万トークン (約74円)
- 更新日
- 2026-08-30
使い方 (AIに渡す3つの方法)
いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。
claude "https://makimono-md.vercel.app/api/v1/files/md-49503237/raw を読み込んで、この指示書どおりに実装して"
中身
毎晩「消化している」つもりのバッチが、同じ先頭N件をやり直しているのを見抜いて直す
残タスク一覧(Markdown / Issue / DB)を無人バッチが上から順に消化する構成は広く使われる。 このとき 「完了したタスクに印を付けて一覧から外す」処理(書き戻し)が配線されていないと、 バッチは毎晩おなじ先頭N件を実行し、N+1件目以降には永久に到達しない。 失敗ログも例外も出ないので、「毎晩ちゃんと動いている」ように見え続ける。
この指示書は ①その状態を検査する手順 ②書き戻しの正しい配線 ③実データで検証する手順 を与える。
前提の構成(読み替えて使う)
<状態ファイル>: 残タスクが書かれた Markdown。過去分が複数ブロック積み上がる(新しいものが先頭)<runner>: 定期実行から起動され、<状態ファイル>からタスクを選び、1件ずつ子プロセスに渡す- 定期実行: OS のスケジューラ(Windows なら
schtasks、Unix なら cron / systemd timer)
1. まず「本当に新しい設定で走ったのか」を確かめる
設定を変えた直後の夜は、変えたつもりの設定で走っていないことが多い。 スケジューラのタスクをその日の実行時刻より後に登録・再登録すると、当日分は実行されず初回は翌日になる。
# Windows
schtasks /Query /TN <タスク名> /V /FO LIST | findstr /C:"Last Run Time" /C:"Next Run Time" /C:"Last Result" /C:"Task To Run"
# Unix
systemctl list-timers <unit> # LAST / NEXT を見る
読み方(ここを飛ばすと、存在しない実行結果を探して1セッション溶かす):
| 見るもの | 判定 |
|---|---|
Last Run Time: 1999/11/30 + Last Result: 267011 | 0x41303 = SCHED_S_TASK_HAS_NOT_RUN。一度も走っていない。0 と並べて「成功」と読まない |
Last Run Time が旧設定の時刻 | 昨夜は旧コード・旧引数で走った。新構成の初回はまだ来ていない |
Task To Run の引数 | 実際に渡っている引数はここ。ドキュメントや記憶ではなくこれを信じる |
「今夜から新構成」と報告する前に、Next Run Time が今夜であることを目視する。
2. 書き戻しが効いていないことを確かめる
壊れ方は次の2つで、両方同時に起きていることがある。
(a) 探索スコープが本体とズレている
タスクの収集が全ブロック対象に拡張されたのに、書き戻しが「先頭ブロックだけ」の旧前提のまま、という形。 収集側と書き戻し側で同じ範囲を見ているかをコードで確認する。
grep -n "firstBlock\|blocks\[0\]\|slice(start, end)" <runner のソース>
(b) 書き戻し関数が誰からも呼ばれていない(dead export)
テストがあると「実装されている」と錯覚するが、本番経路から呼ばれていないケース。 テストは緑、関数は正しい、なのに一覧は永久に減らない。
# 定義とテスト以外に参照があるか。2件(定義+テスト)しか出ないなら未配線
grep -rn "<書き戻し関数名>" <ソースディレクトリ>
さらに、書き戻しを子プロセス(LLM エージェント等)への自然言語指示だけに頼っていないか確認する。 指示は守られないことがあり、守られたかを誰も検査していないなら、それは配線ではない。
3. 直し方
3-1. 書き戻しは runner 側で機械的に行う
子に「終わったら印を付けてね」と頼むのをやめ、子が成功で終わった直後に runner 自身が書き戻す。 子側の指示は残してよいが、二重に印が付かないよう「すでに印があれば何もしない」を明記する。
// 成功したときだけ。失敗・timeout を消すと再挑戦されなくなる
if (result.status === 'success') writeTaskDone(stateFile, task, `${today()} 完了`);
3-2. 書く直前にディスクから読み直す
状態ファイルは他のプロセス/人間が並行して編集する。バッチ開始時に読んだ内容を使って全文を書き戻すと、 その間に足された行を丸ごと消す。読み直す → 1行だけ置換 → 書く。
export function writeTaskDone(file, task, note, io = {}) {
const read = io.read ?? fs.readFileSync;
const write = io.write ?? fs.writeFileSync;
try {
const current = read(file, 'utf8'); // ← 書く直前に読み直す
const changed = markTaskDone(current, task, note);
if (changed === current) return false; // 該当行なし → 何もしない
write(file, changed, 'utf8');
return true;
} catch (error) {
console.warn(`完了を書き戻せませんでした(実行は継続します): ${error?.message ?? error}`);
return false; // 書き戻しの失敗でバッチ全体を落とさない
}
}
3-3. 同一タスクが重複しているなら「全件」に印を付ける
過去分が積み上がる形式では、同じタスクが複数ブロックに残る。
先頭1件だけ消すと、双子が翌晩また採用され、同じ作業を永久に繰り返す。
一致する行はすべてマークする(正規表現なら m ではなく gm)。
すでに印が付いた行を再マッチしない否定先読みも入れる。
const escaped = firstLine.replace(/[.*+?^${}()|[\]\]/g, '\$&');
const lineRe = new RegExp(`^(\s*\d+[.)、]\s+)(?!~~)${escaped}(\s*)$`, 'gm');
return source.replace(lineRe, (_w, prefix, suffix) => `${prefix}~~${firstLine}~~ → ✅ ${note}${suffix}`);
4. 合成フィクスチャだけで緑にしない(最重要)
この種のバグは合成サンプルでは必ず緑になる(サンプルは1ブロック・重複なし・整形済みだから)。 本番の状態ファイルを1回食わせて、件数を見る。
// 実データに対する非破壊チェック。書き込みはしない
const md = fs.readFileSync(stateFile, 'utf8');
const adopted = collectTasks(md).filter(t => !excluded(t));
let marked = 0, noMatch = 0;
for (const t of adopted) {
const out = markTaskDone(md, t, 'note');
if (out === md) { noMatch += 1; console.log('NO-MATCH:', t.slice(0, 60)); continue; }
marked += 1;
const a = md.split('\n'), b = out.split('\n');
if (a.length !== b.length) console.log('行数が変わった:', t.slice(0, 40));
const diff = a.map((l, i) => l === b[i] ? null : i).filter(i => i !== null);
if (diff.length > 2) console.log('複数行が変わった:', diff.length, t.slice(0, 40));
}
console.log('marked', marked, '/ no-match', noMatch);
合格条件は no-match 0 かつ 行数不変 かつ 変わるのは対象1行だけ。
no-match が1件でもあれば、そのタスクは永久にマークされない=毎晩再実行される。
5. 配布物なら「実際に走るコピー」で確認する
定期実行が固定 worktree / 別クローンから起動される構成では、 main にマージしただけでは今夜の実行に入らないことがある。マージ後に、 そのコピーの HEAD と、修正が入ったことを示す文字列を直接見る。
cd <定期実行が使うディレクトリ> && git log --oneline -1 && grep -c "<新しい関数名>" <ソース>
6. チェックリスト
-
Last Run Time/Next Run Time/Last Resultの3つを読み、新設定の初回がいつかを言えた - 収集側と書き戻し側の探索スコープが一致している
- 書き戻し関数が本番経路から呼ばれている(
grepの結果が定義+テストの2件だけでない) - 書く直前に読み直している(開始時スナップショットで全文上書きしていない)
- 重複は全件マーク/印済みは再マッチしない
- 該当なしは no-op、例外は warn だけでバッチを止めない
- 実データで
no-match 0を確認した - 定期実行が実際に使うコピーに修正が入ったことを確認した
効き目
未配線のまま「全件消化モード」に切り替えると、採用51件に対し1晩の枠が12件でも、 毎晩おなじ12件だけが回り、残り39件は永久に着手されない。 症状は「毎晩正常終了・エラーなし・でも一覧が減らない」なので、ログ監視では絶対に見つからない。
よくある質問
+「毎晩「消化している」つもりのバッチが同じ先頭N件をやり直しているのを見抜いて直す」とは何ですか?
残タスク一覧を無人バッチが上から消化する構成で、完了の書き戻しが未配線だと毎晩おなじ先頭N件だけが回り、以降に永久に到達しない。エラーもログも出ない。スケジューラの3項目で「新設定の初回はいつか」を確定し、書き戻しの2つの壊れ方(探索スコープのズレ/dead export)を検査し、runner側で機械的に書き戻す配線と、実データで no-match 0 を確認する検証手順まで。
+どれくらいトークン(費用)を節約できますか?
ゼロから開発すると約5.5万トークンかかりますが、この巻物を使えば約6,000トークンで済みます。差し引き約4.9万トークン(API料金換算で約74円)・89%の節約です。
+どうやって使いますか?
無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。
+どのAIツールに対応していますか?
claude-code、cursor、codex-cli に対応しています。
+商用利用できますか?
ライセンスは「商用利用可 (再販不可)」です。
🤝 自分でAIを動かすのは、まだ不安…という方へ
この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。
関連する巻物
Google Meet 自動参加&動画配信Bot 開発指示書
指定した時刻に Google Meet へ自動参加し、動画を再生しながら画面共有する Bot を、Claude Code に一発で作らせる開発指示 MD。朝会の定例動画配信・ウェビナーの自動放送に。
受信メール添付を案件フォルダへ自動取込するパイプライン
メールを読むアプリとドライブに書くアプリが別、という現実的な構成で顧客メールの添付を案件フォルダへ無人保存する設計。権限追加を避ける理由、実行時間制限下の予算3本立て、二重の重複防止、base64url/行数上限/変換判定などの実装罠、案件と顧客のマッチング、名寄せは候補提示+人の承認にする型まで。
Gmail 自動仕分け&返信ドラフト生成MD
受信メールを AI が分類 (要返信/情報/営業/スパム) してラベル付けし、要返信メールには返信ドラフトまで自動生成する仕組みを作らせる指示書。DWD (ドメイン全体委任) 設定手順込み。
この巻物、誰かのトークンも救えます
𝕏 で節約レシートをシェア