最近、Claude Code に backlog-worker というスキルを作成しました。バックログの URL を渡せば実装の大半が終わるという目論見で作り始めたのですが、あれやこれややってるうちに、普段の仕事の殆どがこのスキルを起点に済んでしまうようになったという話です。最近はターミナルを開いても、このディレクトリから離れることもないし、エディタを開くこともあまりなくなってしまいました(そして、ここ数日はターミナルすら開かなくなった)。
※以下の文章で MR というのは、GitLabのMerge Request のことです。GitHubのPull Request と同じです
この話の前提
前提としてスクラムで開発しています。今回の話に関係しそうな前提は以下のとおりです。
- 2週間を1スプリント
- スプリントはNotionで管理
- プロダクトバックログはNotionで管理
- バックログにはステータスがある
- バックログはスプリントに紐づいている
- バックログの中に「実装」や「テスト」や「仕様書作成」などのタスクがある
- タスクにもステータスがある
使っているもの
| ツール | 何に使うか |
|---|---|
| Claude Code | スキル実行基盤。サブエージェント、/loop による定期実行 |
| Notion MCP | バックログの取得・更新、Scrum タスク作成 |
| glab | MR 作成、issue 作成、CI 確認、レビューコメント対応 |
| git worktree | ブランチの隔離(.tmp/worktree/<ブランチ名>/) |
| Playwright | フロントエンドの E2E スクリーンショット |
サブコマンド
以下、backlog-worker のサブコマンドです。最初は、notion のURLを渡すだけだったのに…。随分いっぱい作ってしまいました。
| コマンド | 説明 |
|---|---|
/backlog-worker setup |
初回セットアップ |
/backlog-worker status |
作業中タスク・worktree・未解決 issue を表示 |
/backlog-worker prep-repo |
リポジトリの足回り(.gitignore・CLAUDE.md・CI Auto Review 等)を整備 |
/backlog-worker help |
ヘルプ表示 |
/backlog-worker <NotionURL> |
指定バックログを処理(進行中・中断・完了済みからの再開もこれで扱う) |
/backlog-worker <GitLabMRURL> |
MR からバックログを検出して処理、なければ修正ループ |
/backlog-worker create |
対話的にバックログを作成 |
/backlog-worker refine <URL> |
既存バックログ/MR を再プランニングして実装ループへ |
/backlog-worker investigate |
コードベースを調査し、結果をナレッジ保存&Notion バックログに登録 |
/backlog-worker investigate3 |
3エージェント合議による高信頼性の調査 |
/backlog-worker staging <URL> |
MR のソースブランチを staging にマージ(staging環境にDeploy) |
/backlog-worker create-release |
Sprint に紐づくバックログからリポジトリ別にリリース用のMRを作成 |
/backlog-worker task <URL> |
コード変更を伴わないタスク(主に調査やデータ出し)を実行し、結果を Notion に追記 |
/backlog-worker knowledge-refresh |
ナレッジを自動メンテナンス(stale・重複・CONVENTIONS 違反) |
/backlog-worker cleanup |
不要になった worktree を選択削除 |
/backlog-worker update-e2e-settings |
E2E Screenshot 設定をソースから同期 |
/backlog-worker editor |
作業中の worktree を任意のエディタで開く。稀に見たくなるときがあります |
他にもあるのですが、よく使うもの(多いな...)をピックアップしました。
backlog-worker のディレクトリ構成
backlog-worker はClaude Codeのスキルですが、それ自体がリポジトリです。backlog-worker のリポジトリそのものが、Notion からタスクを拾ってきて worktree を切る「作業基地」になります。だいたいこんな感じです。
backlog-worker/
.claude/
hooks/ # コミット・push 時に走るゲートスクリプト
settings.json # hook 定義(チームで共有)
settings.local.json # 個人ローカル設定(.gitignore 対象)
skills/
backlog-worker/ # 本スキル(SKILL.md と references/ 配下)
review/ # /review local 用のスキル
repositories/
<group>/<repo>/ # 対象リポジトリ(自動 clone)
.tmp/
worktree/<branch>/ # タスクごとの git worktree
bw/<branch>/ # 進捗カウンター(progress / cycle)
docs/ # 設計書・ブログ・スライド
CLAUDE.md # backlog-worker 自体のルール
README.md / README.en.md
特徴的なのは「対象リポジトリは backlog-worker の中に clone する」ところで、自分のホーム配下にある ~/git/... のような既存 clone は使いません。複数人で同じ仕組みを使う前提なので、「誰がどこに clone しているか」という個人依存の前提を作らないためです。これにより、hook やスキルが対象リポジトリのパスを repositories/<group>/<repo> で決め打ちで参照できます。
タスクごとの作業は repositories/<group>/<repo>/.tmp/worktree/<ブランチ名>/ の git worktree の中で進み、同じ階層の .tmp/bw/<ブランチ名>/ に progress / cycle というカウンターファイルが置かれます。これらのファイルが hooks のゲート判定に使われる、というのが後段の「実装フローの仕組み」につながっていきます。
あと地味なところですが、サブコマンドの起動時に backlog-worker リポジトリ自身を git pull するようにしています。誰かが新しい観点をカタログに足したり、ナレッジを更新したり、hook の誤発火を一つ潰したりしたら、次に誰かが /backlog-worker ... を叩いた時点で全員の手元に反映される、という運用です。改善が個人の手元に閉じないので、複数人で育てる前提の仕組みとしては割と効いています。
プロンプトの分割と遅延読み込み
最初は1つの大きなスキルファイルに全部書いていたんですが、当然コンテキストウィンドウが足りなくなります。そこで、ワークフローの各ステップを別ファイルに分割して、そのステップに到達した時点で初めて Read する方式にしました。
.claude/skills/backlog-worker/
SKILL.md # エントリポイント
references/
workflow-auto.md # auto モードの定義
workflow-mr-fix.md # バックログなし MR 修正ループ
workflow-create.md # 対話的バックログ作成
workflow-investigate.md # コードベース調査
workflow-investigate3.md # 3エージェント合議調査
workflow-staging.md # staging マージ
proc-investigate-core.md # 調査ロジック共通部分
proc-task-fetch.md # タスク取得
proc-plan.md # プラン作成
proc-implement.md # 実装
proc-mr-monitor.md # MR モニタリング
proc-e2e-screenshot.md # E2E スクリーンショット
...
各ワークフローは独立したファイルに定義されていて、サブコマンドに応じて必要なものだけ Read される仕組みです。以降のサブコマンド説明で出てくる references/perspectives/、references/investigation-common-misses.md といったファイルもこの構造の中にあります。
各サブコマンドの詳細
ここからは、よく使うサブコマンドそれぞれの中身を順に説明します。
Notion URL 指定
URL を渡すだけでそのバックログの実装を開始します。会話内でプランの確認や疑問点のやり取りをしながら進めます。一番よく使うのはこの方法で、Notion のバックログを眺めて「これは Claude に任せられるな」と思ったら URL をコピーして投げる、という使い方をしています(まぁ、任されられないタスク、ほぼ無いけど...)。
内部の流れはおおよそこんな感じです。
- Notion のバックログを取得し、Status を
In progressに、Claimed by に自分をセット - Target Repositories のリポジトリを clone(または更新)し、git worktree を作成
- リポジトリごとにサブエージェントが並行でコードベースを調査
- プラン (
plan.md) を作成。Open Question があればここで解消する - プラン承認(後述の インタラクティブモード ではここで会話のやり取りが入る)
- (新規 API を追加するタスクの場合のみ)OpenAPI 仕様書フェーズ。spec の MR を先に出して、人間がマージしてから実装に進む
- サブエージェントが
plan.mdだけを見て実装・テスト・セルフレビュー → コミット → push → MR 作成 - CI の AI レビューが指摘を出してきたら自動で対応・返信。CI 失敗があれば修正
- AI 同士のやり取りが落ち着いたら Notion のステータスを更新
プラン承認は インタラクティブモード で動いていて、会話内でプランを表示し直接やり取りします。疑問点も会話で聞いてきます。要はプランモードですね。URL を渡してClaudeと会話しながら進めます。プランが承認されると、記録用に GitLab issue が作られます。
Open Question は、コードベースに当たって判断材料を集めた上で出してきます。「この設定値は新カラムを足す前提でいいか?」「既存の同種機能と表記を揃えるか別の表記にするか?」のような、調べないと答えられない類の質問が中心です。
セッションが途中で切れた場合は、同じ URL を渡し直すだけで勝手に再開してくれます。なぜ再開できるのか、サブエージェントが何をしているか、どうやってレビューが回っているかは次の「実装フローの仕組み」で説明します。
実装フローの仕組み
Notion URL 指定 / refine / GitLab MR URL 指定 のいずれでも、URL を渡してから MR ができるまでの実装フェーズは共通の仕組みに乗っています。ここではその支柱を 4 つ紹介します。
サブエージェントに実装を委譲
実装は サブエージェント に任せます。メインのセッションはプラン作成までを担当し、実際のコーディングはサブエージェントが plan.md だけを見て実行します。
コンテキストが分離されるので、サブエージェントは余計な情報に引きずられずに実装に集中できます。その代わり、プランにはファイルパス、関数名、データ構造、設計判断の根拠まで全部書く必要があります。ここが雑だと実装も雑になります。
複数リポジトリにまたがるバックログ(API の変更と管理画面の変更が同時に必要、みたいなケース)では、プラン作成時もリポジトリごとにサブエージェントを並行起動してコードベースを調査し、結果を統合してプランにまとめます。1 つのエージェントで複数リポジトリを見ると発見が抜け落ちることがあるので、分担させるのがポイントです。
サブエージェントが途中で停止することもあるので、完了後に cycle カウンターが期待値(5 = MR 作成完了)になっているかを検証し、なっていなければ URL を渡し直して再開する仕組みも入れています(再開は run に統合済みで、専用サブコマンドは不要)。
ファイルベースの進捗管理と cycle ゲート
Claude Code のセッションは途中で切れることがあります。再開時にどこまで進んだかわからないと困るので、ファイルで状態を持たせています。
$REPO_DIR/.tmp/bw/<ブランチ名>/progress # 大フェーズ(1=準備, 2=プラン, 3=spec, 4=実装)
$REPO_DIR/.tmp/bw/<ブランチ名>/cycle # サブステップ(0=作業, 1=レビュー, 2=コミット, 3=push, 4=E2Eスクリーンショット・デザイン確認, 5=MR作成)
<ブランチ名> は git ブランチ名そのもので、毎回この 2 ファイルを読んで「今どこにいるか」を判定し、適切なステップから再開します。
この cycle カウンターは単なる進捗記録ではなく、Claude Code の hooks と連携したゲートになっています。
-
cycle < 2だとコミットがブロックされる(= セルフレビュー必須) -
cycle < 3だと push がブロックされる(= コミット完了必須)
これがないと、AI は平気でレビューをスキップしてコミットしたりするので……。実装 → セルフレビュー → コミット → push → MR 作成の順序を仕組みとして強制しています。
hooks スクリプトをどこに置くかは、しばらく悩みの種でした。~/.claude/hooks/ のような個人ディレクトリに置くと、複数人で使う前提が崩れる。プロジェクト内に置きたいけれど、絶対パスを .claude/settings.json に書くと、clone する場所が違う人の環境で動きません。スキル本体側で「自分自身の絶対パスを動的に解決する」仕掛けを試したりもしましたが、設定ファイルに書く時点で詰みます。$CLAUDE_PROJECT_DIR という環境変数を Claude Code が hook 実行時に渡してくれることに気づいてからは、hooks をリポジトリ内の .claude/hooks/ に置いて、.claude/settings.json 側で $CLAUDE_PROJECT_DIR/.claude/hooks/... という形で参照するようになり、ようやく落ち着きました。
運用しながら誤発火を一個ずつ潰していったゾーンでもあって、cycle ゲートが backlog-worker リポジトリ本体(worktree ではない側)の git 操作で誤発火しないようガードを足したり、knowledge-refresh ブランチを cycle 管理の対象外にしたり、ルートディレクトリへのファイル作成検知を「作成時にブロック」から「git add 時にブロック」へ変更したりしています(一時ファイルをルートに置く分には許容、コミットに混ぜようとした瞬間だけ止める)。
AI レビューが 2 段階で入る
コードレビューは MR 作成の前後で 2 段階あります。
1 段階目はセルフレビュー(MR 作成前)で、Claude が自分の書いたコードに対して /review local を実行します。これは claude-code-action の GitHub 向けコードレビュー機能を参考に、GitLab 用にカスタマイズして別スキルとして作ったものです。中身は、3 つの専門エージェント(CLAUDE.md 準拠、バグ検出、コードコメント準拠)を並行起動 → それぞれ独立に指摘を出す → 各指摘に Haiku エージェントが 0〜100 の信頼度スコアを付ける → スコア 80 未満は除外 → 残った指摘を修正してから MR を作成、という流れです。
2 段階目は CI の AI 自動レビュー(MR 作成後)で、MR が作成されると CI で AI の自動レビュー(Codex ベース)が走ります。ここで指摘が来ると、Claude が自動で内容を確認して修正・返信します。
人間がレビューするのはこの 2 段階が繰り返され、CI の自動レビューが全て LGTM だし終わったか、これ以上 AI 同士では判断できなくなるまで続きます。粗い問題は AI 同士で潰した状態で回ってくるので、設計判断の妥当性やドメイン知識に基づく判断に集中できます。
E2E スクリーンショット後のデザイン確認
フロントエンドの実装では、E2E スクリーンショット撮影後、MR 作成前にデザイン崩れがないかを確認するステップを入れています。前述の cycle で 4=E2E スクリーンショット・デザイン確認 がそれです。スクリーンショットを撮っただけでは見た目の問題に気づけないので、撮影した画像を確認して明らかなデザイン崩れがあれば MR 作成前に修正します。撮影自体の仕組みは後述の「おまけ」で詳しく書きます。
GitLab Merge Request URL 指定
MR の description からNotionのバックログ URL を検出して通常ワークフローに入ります。バックログ URL がなければ、Notion 操作なしの修正ループに入り、レビュー指摘への対応のみを行います。既存の MR に対してレビュー修正を回したいときに便利です。
Notionのバックログを作っていない修正で、途中で放置していたものを引き続きでやってもらう時なんかに使ったりしています。
create
対話的にバックログを作成します。概要・リポジトリ・種別・担当 Product Manager をヒアリングして Notion にバックログを登録します。Notion ユーザー検索で Product Manager を選択できるので、手動で Notion を開いて入力する手間が省けます。Scrum タスクの生成漏れや Target Repositories の付け忘れがあったので、内部はチェックリスト方式で項目を埋めるようにしています。
実際よく使うのは、後述する investigate で何かを掘り当てたあとに、バックログ化するパターンです。Web の Notion でフォームを埋めるよりは、コードベースの文脈が残っている会話セッションでそのまま登録できるのが便利です。バックログの内容としては詳しすぎる可能性はありますが、コードの詳細を見た上でのバックログはAIにやらせるにはより良いです。
概要のヒアリング時には、Claude がコードベースを参照して「この機能なら〇〇のテーブルや API も関係しそうなので Target Repositories はこれかこれ」のような提案も入れてくれます。手動で全部選ばせると抜けるので、提案させて確認する形に倒しました。Target Repositories が複数選ばれた場合は、リポジトリの数だけ Scrum タスク(実装タスク)が自動で生成されます(実装_タスク名 (api) 実装_タスク名 (admin) のような命名)。
refine
既存の実装済み・実装中バックログを再プランニングするコマンドです。仕様変更や追加要件が出たときに、通常のワークフローに載せ直せます。既存セッションに対象 URL の文脈があれば再利用するか確認し、変更内容をヒアリングしてプランを作り直します。既存の MR に続けるか新しい MR を作るかも選べます。
内部的にはこういう手順で動きます。
- URL 解決 — Notion URL ならそのまま、GitLab MR URL なら description から紐づく Notion Backlog を検出(見つからない場合は MR-only モード)
- コンテキスト検出 — 現セッションに対象の文脈があれば再利用するかをユーザーに確認
-
変更内容のヒアリング → Notion ステータスを
Claude Workingに戻す → プラン作成(承認モードに従う) - MR 選択 — 既存 MR を修正するか、新しい MR を作るかをユーザーに確認
- 実装ループ — 通常のワークフローに合流
「プラン作成 → 実装」のサイクルを何度でも回せるのがポイントで、レビューで大きめの仕様調整が入ったときによく使います。MR コメントへの返信ベースで処理させると修正範囲がブレやすいので、refine でプランから組み直すほうが結果的に速い、というのが運用してみての感想です。
MR-only モード(紐づくバックログが取れない場合)は、MR の description と diff からプランを再構成します。MR の修正だけが回ります。
investigate
実装する以上に重宝していて、「これどうなってたっけ?」みたいな記憶ベースの話を、コードベースから掘り起こしてくれます。
掘り起こした知識はナレッジファイルに残し、次回以降の調査や実装で使われます。
また、調査の結果バグや改善すべきところが見つかった場合、調査結果をそのまま Notion バックログとして登録できます。
「調査 → バックログ化 → 次回 URL を渡して実装」という流れが自然にできます。
調査は 観点ベース になっていて、調査内容に応じて適切な観点(DB スキーマ変更影響、カラムの書き込みカバレッジ、過去変更からの学習、…)を Claude が選定し、ユーザーが確認した上で観点ごとに並列のサブエージェントを起動します。各観点には最低チェック項目と出力様式が定義されているので、調査の品質が AI の勘に依存しにくくなっています。詳しくは後段の「AI ができなかったことから SKILL を育てる」で触れます。
ナレッジファイルの保存先は、汎用なら knowledge/__general/<カテゴリ>/<トピック>.md、プロジェクト固有なら knowledge/<group>--<repo>/<トピック>.md で、命名規則・フロントマター・耐久性テストなどの基準は knowledge/CONVENTIONS.md で正典化しています。
参照する資料はコードリポジトリだけではありません。references/reference-repositories.md で定義された仕様書リポジトリや運用手順書リポジトリも、ターゲットリポジトリに関連する場合は自動で検索対象に含まれ、コードだけでは分からない仕様や運用背景を補完します。参照リポジトリは setup 時に clone され、各ワークフロー開始時に自動 pull されます。例えば管理画面リポジトリを調査するときは、対応する仕様書リポジトリと運用手順書リポジトリも合わせて検索される、というイメージです。また、BigQuery MCPと連携したり、zendesk APIと連携させたり、aws cli と連携させるなどで、各種データを取り扱わせることも可能です。
新規調査だけでなく、過去のナレッジも毎回検索対象になります。knowledge/ 配下を grep で検索して関連知見をプランや調査結果に反映します。最初は埋め込みベクトル検索(nomic-embed-text 等 3 モデル比較)で実装するつもりで eval harness まで作ったのですが、評価セットを当ててみたところ、識別子(テーブル名・関数名)の一致が極めて重要で、grep ベースのほうがリコールも精度も高いという結果が出たのでそのまま grep に倒しました。セルフレビュー(/review local)にも ENABLE_KNOWLEDGE_RETRIEVAL を入れて、レビュー観点に既存ナレッジを巻き込めるようにしています。
過去の GitLab issue(プラン履歴)も同じく検索します。「同じテーブルに前回も触っている」「過去プランで議論済みの懸念事項がある」を取りこぼさないためです。
investigate3
investigate の強化版で、同じ調査を 3 つの独立したサブエージェントに並行実行させ、結果を突き合わせます。全員が一致した内容を確定事実として採用し、見解が分かれた箇所は再調査を最大 3 ラウンド行います。トークンコストは高くなりますが、1 回の調査では見落としがちな暗黙の仕様やエッジケースを拾える確率が上がります。
自分の記憶が怪しいときに、なるべく詳細に調査してほしい場合や、リスクの高い仕様調査(外部連携、データ移行など、間違えるとクリティカルそうなもの)で使っています。普段の investigate でも十分なので、「これは絶対外せない」というときだけ investigate3 を使います。
差分が出る箇所は、各エージェントが「どこをどう調べた結果そう判断したか」の根拠を出し直し、もう一度突き合わせます。それでも合意に至らなければ次のラウンドへ。3 ラウンド回しても割れる場合は、その箇所を「未確定」として明示した上で結果を出します。token 消費は通常の investigate に対しておよそ 3〜4 倍になります。
staging
うちの環境では、stagingブランチにマージすると、ステージング環境が自動更新されるようになっています。stagingサブコマンドにNotion URL または GitLab MR URL を渡すと、MR のソースブランチを検出して staging にマージします。
Notion バックログの Branch/MR URL が複数あるとき(複数リポジトリにまたがるバックログ)には、どの MR を staging に流すかを「個別」「まとめて」のどちらにするかユーザーに選ばせます。staging ブランチ名はリポジトリごとに glab api で「stagingという文字列を含むブランチ」を取得して候補とし、候補が 1 つなら自動選択、複数ならユーザー選択、ゼロなら手動入力になります。
staging push をコマンド化したのは、複数リポジトリ・複数 staging 環境がある運用だと、対象 MR を選びながら手で merge & push を繰り返すのが地味に面倒だったからです。そもそも、backlog-worker で実装させるとブランチ名も勝手に決まるので、自分の覚えていないブランチ名だから探すの面倒なんですよね。
staging 系ブランチ名はリポジトリごとに違っていることもありますが、stagingという文字列は必ず含まれているので、それをもとにブランチの候補を検索させています。
create-release
スプリントが終わると、そのスプリントで実装が終わった複数のバックログをまとめてリリースする場合があります(個別にさっさとリリースしてしまう場合もあります)、その場合は、リリース用のページをNotionに作っています。色々あって以下のようなフローでリリースを行っています。
- 各ブランチを main にマージ
- main から release/yyyy-mm-dd のブランチを作成
- release/yyyy-mm-dd を production ブランチにマージ(deployされる)
リリース用のNotionのページの中に、そのタイミングでリリースするバックログが一覧化されているので、それを読み取って、各ブランチをmainにmerge & その時点のリリース用のブランチ(release/yyyy-mm-dd)を作成します。
内部の動きはこうです。
-
Sprint 特定 — 引数指定があればそれ、なければ
Finished = falseの Sprint を対話選択 -
バックログ収集 — Sprint に紐づく全バックログを
Target Repositoriesでリポジトリ別に分類 - MR マージ済みチェック — 紐づく MR が未マージのバックログがあれば一覧表示して終了(リリース対象外として人間判断を仰ぐ)
-
リポジトリごとに
mainからrelease/yyyy-mm-ddブランチを切ってproductionブランチへの MR を作る。同日 2 回目以降はrelease/yyyy-mm-dd-02のように suffix を増やす。同名の既存ブランチがあれば「既存 MR に追記 or 新ブランチ作成」を選ぶ
リリース MR の description には、Sprint 名・対象バックログ・対応する MR の一覧表を入れて、リリース内容が一目でわかるようにしています。release ブランチ名に日付を入れたのは、複数 release が並走する週にどれが何なのか見分けたいから。production ブランチ名にはバリエーションがある(リポジトリによって production/hogehoge 等)ので、staging コマンドと同じく候補検索ロジックで拾います。
task
コード変更を伴わない調査依頼(「直近1ヶ月で X 状態のレコード数を出して」みたいなもの)を Notion のタスクのURLから直接さばくためのコマンドです。BigQuery MCP が接続されていれば execute_sql_readonly で実行し、結果サマリと観察を Notion 本文末尾に追記します。
出力は Notion 本文末尾に ## 実行結果(YYYY-MM-DD by Claude Code) という見出しで追記され、クエリ・結果サマリ・観察の 3 ブロックに分けて書かれます。後で同じバックログを見返したときに「このときどう調べてどう判断したか」を辿れるようにするためです。
prep-repo
新しめのリポジトリで .gitignore が薄かったり CI Auto Review が入っていなかったりするのを冪等に整備するためのものです。.gitignore(共通テンプレ+言語別テンプレ+実ファイルスキャン)、CLAUDE.md(README から概要、package.json 等から開発コマンドを自動抽出)、AGENTS.md → CLAUDE.md の symlink、.editorconfig、.gitattributes、.claude/settings.json、.gitlab-ci.yml の code-review ジョブを必要に応じて追加し、chore/backlog-worker-prep-YYYYMMDD ブランチで MR を出します。再実行しても整備済みのものは触りません。
.env* が .gitignore に含まれているかの検査もここで走らせていて、含まれていなければ警告だけ出します(コミット側で消されるリスクは hooks 側のガードに任せます)。
CI Auto Review は社内で運用している Codex ベースの自動レビューで、.gitlab-ci.yml に code-review ジョブが定義されていれば動きます。新しめのリポジトリだとここが入っていないことがあるので、prep-repo で一括追加する運用です。CLAUDE.md の自動生成では README の本文・package.json / Cargo.toml 等の依存・Makefile のターゲット・.tool-versions などをスキャンして、概要 / 開発コマンド / 関連リポジトリのリンクを埋めます。後から人間が肉付けする前提の最低限のテンプレです。
knowledge-refresh
ナレッジ管理を自律化するためのコマンドで、/schedule で週次 routine 化することを想定しています。
-
stale 検知:
> 調査日: YYYY-MM-DDから 14 日以上経過したナレッジを対象に fact-check -
対象MR チェック:
> 対象MR: <URL>付きのナレッジは、紐づく MR が全て merged になるまで fact-check をスキップ。merged 後は対象MR:行を自動削除して通常メンテへ移行 - 重複検出: 全ナレッジを読み比べて実質重複(>50%)を検出
-
CONVENTIONS 違反:
knowledge/CONVENTIONS.mdに照らして high/medium 違反を MR 化
各 finding は 1 件 1 MR で backlog-worker リポジトリに発行されます。CONVENTIONS 違反の修正案を作るときは、関連ファイルを必ず先に pull して現行ソースと整合性を確認するようにしました。これは fact-check の途中で「古いソースのまま指摘してしまう」事故を踏んだあとに足したガードです。
作業は backlog-worker リポジトリ自身の .tmp/worktree/ 配下の worktree で行うため、ユーザーの現在の作業ディレクトリや現在のブランチには触れません。MR 作成前に findings 一覧を表示して (y/n) 承認を取ります。
CI で回すことも検討したのですが、ナレッジは個人の調査結果が積み上がる場所で、修正には判断が必要なので「誰か 1 人が担当として持つ routine」のほうが運用しやすそうだと判断しました。あと、CIだと、Api Tokenでの実装となり、追加料金が発生してしまいますからね。実行例としては「stale 8 件、重複候補 3 ペア、CONVENTIONS 違反 high 2 件・medium 5 件」のような findings をまず一覧で見せ、それぞれを MR 化するかをまとめて承認する流れです。
ナレッジ保存基準には「6 ヶ月後に読んでもこの記述は意味があるか」という 耐久性テスト を入れていて、コミットハッシュ単位の事実や暫定回避策がそのままナレッジ化されないようにしています。stale 検知の 14 日というしきい値は、この耐久性テストでは拾いきれない短期の変動(仕様追加・名称変更)を補うためのものです。
editor / cleanup
それぞれ作業中の worktree をエディタで開く、不要になった worktree をローカルブランチ・進捗ファイルごと選択削除する、というだけのコマンドです。
editor は worktree が複数あれば番号付き一覧から選択、Editor 設定が未設定なら settings.yaml に対話で保存します。Editor フィールドには code cursor subl などの GUI エディタコマンドを書きます(vim のようなターミナル型は Claude Code のセッション内で正しく動かないので非対応)。起動は nohup <Editor> <worktree> > /dev/null 2>&1 & disown のバックグラウンド実行で、Claude のセッションを止めません。
cleanup には少し気を遣っていて、リモートで消えたブランチには gone フラグを、未コミット変更には ⚠ dirty、未 push コミットには N↑ を表示し、最終確認で「この変更は失われます」と注意喚起します。worktree 削除は git worktree remove --force → git branch -D → rm -rf $REPO_DIR/.tmp/bw/<branch> の順で実行し、ローカルブランチとカウンターファイルもまとめて消します。
安全策
AI に自律的にコードを書かせるので、ここは一番気を使ったところです。
人間がゲートを握る:
- 実装プランは人間が承認してから実装に進む
- MR のマージは人間が行う
- OpenAPI spec も人間がマージしてから実装に進む
自動的な安全機構:
- hooks でサイクルゲート(レビュー → コミット → push の順序強制)
- ルートディレクトリへのファイル作成をリアルタイム検知する hook
- Bash のパイプ・チェーンを禁止して権限確認ダイアログを確実に表示させる
- Notion の
Claimed byフィールドで楽観的ロック。「空であることを確認 → 自分の ID をセット → 3 秒待つ → 再度 fetch して自分の ID が残っているか確認 → 上書きされていたら譲って別タスクへ」という手順で、複数人が同時に動かしても同じバックログを取り合わない(実際にぶつけたことはまだないですが、仕組みとしては入れています)
おまけ: E2E スクリーンショットの自動撮影
フロントエンドの MR では、Playwright で PC/SP 両方のスクリーンショットを自動撮影して MR に埋め込んでいます。
mock サーバーを立ち上げて、対象ページにアクセスして撮影し、GitLab の Upload API でアップロード。MR の description にテーブル形式で PC/SP 横並びに表示されます。ポート番号は撮影時にランタイム割り当てするようにしていて、複数リポジトリ・複数 worktree が並行で動いていても衝突しません。
単にページを開くだけだと、モーダルの文言を変えたタスクなのにモーダルが閉じたスクリーンショットが撮れたりするので、「バックログの内容が確認できる状態で撮影する」という指示を入れています。
また、レビュー指摘で修正が入った場合は、古いスクリーンショットを GitLab の DELETE API で削除してから再撮影し、MR description を更新するようにしています。
外部プラグインとの連携
superpowers と、社内メンバーが開発している社内プラグイン群の 2 つの外部プラグインと連携する仕組みを入れました。トークンコストが高いので常時有効にはせず、タスクの複雑度に応じて「使いますか?」と都度確認する方式にしています。
| スキル / プラグイン | 利用フェーズ | 効果 |
|---|---|---|
superpowers:brainstorming |
計画フェーズ | 設計の選択肢を洗い出し、アプローチを確定する |
problem-essence |
計画フェーズ | 表面的な要求の裏にある本質的問題を問い直す |
consult |
計画フェーズ | 要件〜行レベルの6階層で適切な抽象レイヤーを特定する |
assumption-analysis |
計画承認後 | プランの前提条件を構造化検証する |
superpowers:test-driven-development |
実装フェーズ | TDD で実装を進める |
pre-push-review |
ローカルレビュー | 6観点の詳細レビュー(自己完結性検証を含む)+ push ガード |
gitlab-mr |
MR 作成後 | 本質の問い直しと多層分析を含む深層 MR レビュー |
例えば計画フェーズでは、複数リポジトリにまたがるタスクや設計判断が多いタスクの場合に superpowers:brainstorming(設計の選択肢整理)、problem-essence(「本当に解くべき問題は何か」を問い直す)、consult(6つの抽象レイヤーで適切な粒度を特定する)を使うか聞いてきます。単純なバグ修正やテスト追加では聞きません。
実装フェーズでは superpowers:test-driven-development が利用可能な場合、サブエージェントはそれに従って TDD で進めます。
ローカルレビューでは、Backlog Worker 標準の /review local(信頼度スコアで偽陽性をフィルタリング)と pre-push-review(6観点の詳細レビュー + push ガード)を選択できます。セキュリティに関わる変更や複雑なロジックでは後者が有効です。
MR 作成後には gitlab-mr による深層レビューを使うか確認します。これは MR の description やリンク先ドキュメント(Notion、Issue 等)まで追跡して文脈を理解した上で、本質の問い直しと多層分析を含む深いレビューを行います。
ポイントは「常に全部載せ」ではなく「必要な時だけ重い分析を使う」ことです。スキルやプラグインがインストールされていなければ自動でスキップされるので、なしでも従来通り動きます。
実際に運用してみて
4 月頭から 1 ヶ月強使ってみた実績です。
単純なバグ修正
ある外部 SaaS の問い合わせ一覧取得にページネーションがなく、100 件を超えるチケットが切り捨てられていた問題。まず /backlog-worker investigate で原因を特定し(一覧取得関数にページネーションなし)、調査結果から Notion バックログを作成、そのまま URL を渡して実装しました。per_page=100 のループ追加とレートリミット対応、テストケース追加。MR 作成後の AI レビュー指摘への対応も自動で行い、Claude Finished まで自律で完了しています。
複数リポジトリにまたがる実装
API リポジトリと管理画面リポジトリの 2 リポジトリにまたがるタスクで、プランは 5 回修正しました。
- API リポジトリ: DB マイグレーション(2 テーブルにカラム追加)、設定構造体の追加、可否判定ロジック(12 パターンのユニットテスト付き)、V1/V2 API レスポンス対応、OpenAPI スキーマ更新
- 管理画面リポジトリ: 編集画面のセレクトウィジェット、CSV インポート/エクスポートのバリデーション追加
DB のある金額カラムを decimal(8,3) から decimal(12,3) に拡張するタスクでは、API・管理画面・フロントエンドの 3 リポジトリにまたがる影響範囲を事前調査(investigate)で洗い出し、マイグレーション・バリデーション修正・CSS 幅調整まで一気に MR を出しました。フロントエンドは結果としては必要はなかったんですが、まぁ、そういうこともありますね。
バッチ・インフラ系タスク
Go のバージョンを 1.25 にアップグレードするタスクでは、依存パッケージの更新、Docker イメージの変更(bookworm→trixie)、レビュー指摘への対応まで自律で完了しました。Go の脆弱性チェックタスクも自律完了しています。
調査タスク
investigate は実際によく使っています。コードだけでは把握しにくい仕様をいくつも掘り起こしてくれました。embulk の Aurora→BigQuery コピーを bq コマンドで高速化できないかという調査では、現状の embulk 構成を分析し、移行の実現可能性と具体的な対応案をまとめた上で Notion バックログとして登録しました。
注意が必要なこと
- プランの品質がすべてを決める。サブエージェントは plan.md しか見ないので、プランが雑だと実装も雑になる。
- 設計判断の妥当性は人間のレビューが必要
- 品質のチェックはまだ見ておいたほうが良い。いくらAIのレビューが2回走っていても、見落としはありますし、plan.mdを書いていてもコードの設計としてはイマイチなときはあります。まぁ、でも「やり直し」が気軽にできてしまうので、別に間違ってたらやり直してもらえばいいだけ...
面倒な紐付けは AI に任せる — Notion / Issue / MR が有機的に繋がる
backlog-worker を運用していて地味に効いてくると感じるのが、「人が忘れがちで面倒な紐付け作業を AI に任せると、関連情報が勝手に繋がっていく」 ということです。
具体的には、実装フローの中で AI に以下を必ずやらせています。
-
プラン → GitLab Issue 化: 実装計画 (
plan.md) を作ったら、その内容を GitLab Issue として登録する。後で「あの実装、どうしてあのアプローチにしたんだっけ?」となったとき、Issue を辿れば設計判断の経緯が読める - MR description に Notion URL / Issue ID を埋め込む: MR description には紐づく Notion バックログ URL と GitLab Issue ID を必ず書く。Issue は MR がマージされたら自動で close されるので、タスクのライフサイクルが MR とともに完結する
- Notion バックログに branch / MR URL を記録: 逆方向の参照として、Notion 側にも実装 branch 名と MR URL を書き戻す
これだけで、
- Notion バックログ → branch / MR / Issue を辿れる
- MR → Notion / Issue を辿れる
- Issue → MR / Notion を辿れる
の どこからでも文脈の全体に到達できる 状態になります。
人間がこれを毎回手でやれと言われると、後回しになったりサボったりするやつです。「Notion に URL 貼り忘れたので後で何の MR か分からない」「Issue 立て忘れて経緯が消えた」のような事故は、AI なら忘れません。逆に言うと、これを AI に任せられるからこそ、面倒な参照ルールを チームの規約として全員が漏れなく守れる 状態に持っていけます。
「AI に書かせる」よりも 「AI に忘れずやらせる」 という使い方が、地味だけど一番効いてる気がしています。1 つひとつのリンクは小さい仕事ですが、横串で繋がっていることで、調査・onboarding・障害対応のときに「あの時の判断は何だっけ」を 1 step で引き戻せるようになりました。
AI ができなかったことから SKILL を育てる
backlog-worker を運用していて気づいたのは、機能を増やすこと以上に、AI が一手間踏み忘れたとき「なぜできなかったか」を調べて SKILL に追加するサイクルが効くということです。「AI に任せる」ではなく 「AI が確実に動ける仕組みを育てる」 という発想です。
改善事例
実際に運用しながら積み上がった改善の一部です。
| AI が見落としていたこと | 追加した改善 |
|---|---|
| 調査・プラン時に過去の設計判断(GitLab issue)を参照していなかった | 過去プランの検索ステップを追加 |
| staging マージ後にテストなしで push していた | push 前に make test 実行を追加 |
| investigate 後にバックログ登録を確認なしで進めていた |
y/n 確認ステップを追加 |
| ALTER 影響調査で DML クエリをエントリポイントまで逆引きしていなかった | INSERT/UPDATE/DELETE の逆引きステップを追加 |
どれも 「指示がなかったからやらなかった」 というパターンでした。
段階的に進化させる
対処は段階的に進化します。
| 段階 | やること | 例 |
|---|---|---|
| 1. 観察 | 「惜しい」「抜け」を記録する | ALTER 調査で Lambda 経路を見落とした |
| 2. 明文化 | SKILL に明示ステップを追加 | DML 逆引きステップを追加 |
| 3. 資産化 | カタログ・ナレッジに抽出 | 観点をカタログ化 |
| 4. 仕組み化 | チェックリスト・hooks で強制 | 抜け対策チェックリスト + cycle ゲート |
| 5. 検証 | 同じテーマで再実行し、抜けが埋まるか確認 | 同テーマで再調査して経路が拾えるか確認 |
明文化(段階 2)で十分なケースもありますし、繰り返し飛ばされるなら段階 4 まで持ち上げます。
ケース詳細: ALTER 影響調査で Lambda を見落とした
あるテーブルへの ALTER 影響を investigate したところ、そのテーブルに INSERT する Lambda がひとつ取りこぼされました。原因はこうでした。
SQL のテーブル名
→ 自動生成された Go コード
→ repository インターフェース
→ Lambda ハンドラ ← この階層では「テーブル名」の文字列が出てこない
キーワード grep だけでは Lambda ハンドラに到達できなかったわけです。これを受けて、ALTER 影響調査では DML クエリ(INSERT/UPDATE/DELETE)をエントリポイントまで逆引きする ステップを必須化しました。「重要なクエリ」のような曖昧な言葉ではなく、具体的な動詞で判断基準を切ったのがポイントです。
観点を資産化する
ALTER の見落とし対策(前項)から一歩進めて、「調査の観点そのもの」を資産化しています。
references/perspectives/ 配下の観点ファイルには、以下を 1 ファイルにまとめてあります。
# <観点 slug>
## 適用条件 — どんな調査に使う観点か
## 最低チェック項目 — 必ず確認するチェックリスト
## 最低出力様式 — 出力に必ず含める表/セクション
## 参照ナレッジ — knowledge/ 配下のファイル
## サブエージェントプロンプトひな形 — $TABLE 等の穴埋め式
事実データ(ALTER アルゴリズムのマトリクス、判定基準など)は観点ファイルから分離して knowledge/ 配下に置いています。観点ファイルは軽い「プロンプトひな形」、ナレッジは事実を集約、と役割を切り分けています。
現在カタログ化されている観点は db-alter-impact(DB スキーマ変更影響)、column-write-coverage(カラムの書き込みカバレッジ)、validation-display-consistency(バリデーションと表示の一貫性)、past-change-learning(過去変更からの学習)、spec-doc-impact(仕様書への影響)など 10 ほどで、N+1 やインデックス効率といったパフォーマンス系の観点も追加してきました。
調査依頼を受けると Claude が観点を選定し、ユーザーに確認を取った上で観点ごとに並列のサブエージェントを起動します。観点が 2 つ以上のときは、観点間の接続・矛盾・優先順位・次アクションを含む 総合観点(synthesis) を最後に足し、結果は汎用 (knowledge/__general/) とプロジェクト固有 (knowledge/<group>--<repo>/) のナレッジに振り分けて自動保存します。調査中にカタログ外の観点が使われたら「カタログ化しますか?」と促す自己拡張フローも入れています。
調査の品質を「AI の勘」から「カタログで担保する」方向に寄せた、というのがこの仕組みの狙いです。
抜け対策チェックリスト
観点カタログだけでは 観点を横断する構造的な抜け を拾えません。例えば「あるテーブルに書き込むコード」を網羅する観点は当てられても、SQS / Lambda 経由で間接的に書く経路は観点だけでは漏れます。
そこで investigation-common-misses.md に固定のチェック項目を定義しています。
| ID | 項目 |
|---|---|
| M1 | Lambda 直接エントリポイント |
| M2 | SQS / SNS / Kinesis コンシューマ |
| M3 | repository 層の間接呼び出し |
| M4 | Terraform / インフラ定義 |
| M5 | Step Functions / SAM / serverless.yml |
| M6 | 全環境 cron(production・staging 全部) |
| M7 | Embulk / BigQuery export |
| M8 | 非同期通知 / webhook 受信 |
調査ごとに .tmp/bw/investigate-<timestamp>/misses-progress.md に [ ] で並べ、各項目について証跡を取れたら [x] を埋めます。全項目が [x] になるまで次ステップに進めません。観点で拾えないものは仕組みで強制する、という二段構えにしています。
ナレッジが回る — Feedback Loop とチーム共有
investigate / investigate3 で掘り起こした知識は knowledge/ 配下に Markdown で保存されます。次回以降の Backlog 実装 / Task 実行 / Logs 調査でも、Claude は実装前に該当する knowledge を grep で探して参照するため、「使えば使うほど Claude の前提知識が増える」 状態になります。
ポイントは knowledge/ 配下が git 管理されている ことです。
- 誰かが investigate で掘り起こした事実は、すぐに他のメンバーの Claude セッションでも参照される チームでナレッジを共有 できる状態になる
- ナレッジの妥当性は git の流れでレビューできる
- 個人の調査が チームの資産 として積み上がり、複利で効く
- 新規参加者の onboarding コストも下がる(過去調査を読めば前提知識を補える)
knowledge-refresh を定期的に走らせて事実の鮮度を確認するエントロピー対策も組み込んでいるので、古くなったナレッジが残り続けるリスクも一定程度緩和されています。
「Claude が知らないことを毎回ゼロから調査する」というコストが、ナレッジの累積で減っていく ── backlog-worker を運用していて一番強く感じる feedback loop です。
Knowledge の保存ルール
ナレッジの仕組みで一番工夫したのは、何を残し、何を残さないか の基準です。緩く運用すると「修正が終わった事実」が陳腐化して残り続け、新しい読者を混乱させてしまう。knowledge/CONVENTIONS.md で正典化していますが、骨子は以下のとおりです。
大原則: 耐久性テスト
このナレッジは、今回検出したバグが全て修正された後も、将来の開発者にとって有用か?
YES なら保存。NO なら保存しない。バグそのものはバックログ / MR description / コミットメッセージに書きます。
保存するもの (OK)
- データフロー — テーブル間の同期、cron による伝搬経路など、コードを読むだけでは全体像が把握しにくいもの
- 暗黙の仕様 — ドキュメント化されていない挙動(フィルタの要件、特殊なステータス処理、カラムの意味論など)
- 規約・使い分けルール — 「この経路で引いてはいけない」「このテーブルには必ずこのフィルタ」など、実装ガイドラインとして残るもの
- 起きやすい事故パターン (一般化) — 「コピペ時に X を取り違えやすい」のような再発防止策(特定ファイル名を主語にしない)
- 複数リポジトリにまたがる知見 — 単一リポでは完結しないフロー
- 運用知見 — cron のスケジュール、バッチの順序、リカバリ手順
保存しないもの (NG)
-
「特定行に今バグがある」という事実(例:
foo.sql:19に status フィルタ漏れ) → 修正されると嘘になる。代わりに「status フィルタの要件」を仕様として書く - 「現時点で X が不統一 / 未実装」という状態報告 → 改善で陳腐化する。代わりに「あるべき方針」を書く
- 調査過程の記録(「3 エージェント合議で CONFIRMED」「2 回訂正した」)→ MR description / バックログへ
- 単純なコード読解結果(「この関数は X を返す」)→ コードを読めば分かる
- 特定 MR / 特定修正のための一時メモ
判断に迷ったときの問い
- 主語のテスト: 主語が「特定ファイル / 特定期間の状態」になっていないか?
- 時制のテスト: 「現在〜である」「〜時点で」が骨格になっていないか?
- 修正後テスト: バグが全部直った世界でも、このナレッジは意味を持つか?
- 検索性テスト: 技術識別子(テーブル名・カラム名・関数名・cron 名)を 原語(英語スネークケース等)で本文に 1 回以上含めているか? grep 主体なので原語が必須。
保存先の判定
汎用かプロジェクト固有かを先に判定します。
-
汎用ナレッジ (MySQL / AWS / HTTP / 言語仕様 など):
knowledge/__general/<category>/<topic>.md -
プロジェクト固有ナレッジ:
knowledge/<group>--<repo>/<topic>.md
複数リポジトリにまたがる知見は 最も関連の深いリポジトリのディレクトリに 1 ファイル置く方針です(シンボリックリンクは作らない)。これで「同じ事実が複数箇所に書かれて整合性が崩れる」を回避しています。
メタデータでクロスリポ検索を効かせる
ナレッジ冒頭の blockquote に 対象リポジトリ と 関連リポジトリ を必ず書きます。
> 調査日: 2026-05-17
> 対象リポジトリ: popcorn--admin
> 関連リポジトリ: popcorn--pmall-api, popcorn--asp-importer
これでプラン作成時の knowledge 検索は、
-
__general/配下(汎用ナレッジは常に対象) - 対象リポジトリのディレクトリ配下
- 他リポのディレクトリに置かれていても、
関連リポジトリで対象を含むもの
の 3 種を find + grep でユニオン取って、その中をキーワード grep するだけで漏れなく拾えます。symlink を使わずに cross-repo discoverability を担保しているわけです。
メタデータ整合性は scripts/knowledge-check.sh でチェック(CI/pre-commit に組み込み予定)、既存ファイルの一括埋めは scripts/knowledge-fill-metadata.sh で対応しました。
この基準を決めてから、investigate 出力で「これは保存すべきか?」で迷うことがほぼなくなりました。とくに 耐久性テスト が効いていて、「直したらすぐ嘘になる事実」は自然とバックログ側に流れるようになっています。
関連概念: LLM Wiki
ちなみに、ニュースで流れてきた LLM Wiki – 知識を繋ぐ仕組み という記事の考え方が、ここで作っているナレッジ仕組みと 同じ系統で、思想もかなり近いものでした。「RAG が質問のたびに知識をゼロから再発見する ことへの解として、累積する成果物を作る」という出発点は完全に共通です。
記事の LLM Wiki の主要素を私の理解で並べると、
- 3 層構造: Raw sources(人, 不変)/ Wiki層(LLM 管理:サマリ + 概念ページ + クロスリファレンス)/ Schema(人定義の規約)
- Ingest オペレーション: 新ソース投入をトリガに LLM がサマリ生成 → 関連する概念ページに知見を波及(1 ソース投入で 10〜15 ページ更新が及ぶことも)
- Query オペレーション: 対話的に問い、価値ある回答は query ページとして wiki にファイリングされる(使うほど育つ)
- Lint オペレーション: 矛盾・孤立ページ・知識ギャップ・「次に聞くべき問い」を定期検出
-
[[wikilink]]+ Obsidian graph view で知識の繋がりを可視化 - Raw sources は不変、LLM は読み取り専用(推測しない、原典 1:1 対応で追跡可能)
これと backlog-worker の knowledge/ を並べると、対応関係が見えてきます。
| 観点 | 記事の LLM Wiki | backlog-worker の knowledge/
|
|---|---|---|
| 事実層 / 解釈層の分離 | Raw sources(不変) / Wiki層(LLM 管理) |
コードベース(不変、git 管理) / knowledge/(耐久テスト通過の解釈) |
| 生成トリガ | Ingest(新ソース投入で波及更新) |
investigate の都度(人の依頼) |
| Query → wiki への累積 | 価値ある回答は query page として wiki に保存され、次の推論の足場になる | 耐久テスト通過した質問結果は Knowledge として保存され、次の investigate で参照される(実質的に同じ振る舞い) |
| 検索 | Query operation | grep(識別子マッチを優先して embedding を断念した経緯あり) |
| 鮮度維持 | Lint operation(矛盾・ギャップ提案) |
knowledge-refresh(fact-check 中心) |
| 信頼性 | Raw sources 不変 + LLM 読み取り専用 |
investigate3 合議 + CONVENTIONS テンプレ + check script |
| 知識の繋がり |
[[wikilink]] の意味的グラフ |
パス参照(perspectives/*.md から直接) |
並べてみて気付いたのは、主要素は既におおむね対応しているということです。特に「Query が wiki に累積する」というコア概念は、我々のシステムでは「耐久テスト通過した質問結果のみを Knowledge に保存する」という形で既に実現できていました(耐久テストは、累積に値する Query を選別するゲートとして機能している)。
その上で、取り入れる余地があるのは以下 2 つ:
-
構造的 Lint: 我々の
knowledge-refreshは「書いてあることが今も正しいか」の fact-check が中心で、**「ある観点に関する knowledge が片寄っている / 孤立している」「ここに gap がある」**という構造的な抜け検出はしていない。記事の Lint operation はそこを含む -
original_queryのメタデータ化: 「なぜこの Knowledge を作ったか(発端となった問い)」を frontmatter に 1 行残しておくと、後から読み返したときの理解コストが下がる。investigate の進捗ファイルには残っているが、Knowledge 単体からは追えない
[[wikilink]] + graph view(Obsidian 的な可視化)はインスピレーションとして魅力的だが、現状の使い方ではパス参照で実害なく回っているので、実装コストに見合うかは要検討。
ハーネスエンジニアリングとの対応
特にハーネスエンジニアリングを意識していたわけではないのですが、Claude Codeに分析させたところ、OpenAI が公開している Harness Engineering の概念と、ここで作っている仕組みは多くの点で重なるようです。
並べてみると、できていること・足りないことが見えやすくなります。
| Harness Engineering の概念 | Backlog Worker での対応 | 状況 | 足りないこと |
|---|---|---|---|
| エンジニアは環境を設計する | ワークフロー(proc-*.md 等)を設計 |
○ | — |
| マップを与えよ(短いガイド) | 短い references/*.md + knowledge/
|
○ | — |
| 人間は承認・判断に集中 | プラン承認・MR マージのゲート | ○ | — |
| エントロピー対策 |
knowledge-refresh による定期 fact-check |
○ | — |
| フィードバックループを組み込む | セルフレビュー・CI レビューのループ | △ | コードレビューに閉じている。実行時のシグナル(ログ・メトリクス・本番エラー)を AI に戻す経路がない |
| エージェントの認識可能性 | ナレッジを knowledge/ にコミット |
△ | 個別タスクの実行ログ・失敗履歴は .tmp/ に散在し、過去どう動いた/何で詰まったかを横断的に AI が参照する手段がない |
| カスタムリンター・不変条件 | hooks による手順ゲート(コード品質ではなく順序) | △ | ドメイン固有の不変条件(マイグレーションに rollback 必須、API レスポンス形式、…)を機械チェックしていない |
| 計画はリポジトリにコミット | GitLab issue に残り検索・参照可能(repo 外) | △ | 計画がコードと同じリポジトリ・ブランチにないので、実装と一緒に diff したり過去ブランチの計画を辿るのに一手間かかる |
| アプリ可読性(ログ・メトリクス直接アクセス) | E2E スクリーンショットのみ | ✗ | — |
| スループット優先のマージ戦略 | 特に意識せず | ✗ | — |
共通言語ができたおかげで、何が足りないかが言語化しやすくなりました。
まとめ
「AI に仕事を任せる」というよりは「ワークフローの定型部分を自動化して、人間は判断に集中する」という感じです。気がつけば Backlog Worker の役割は「バックログ実装の自動化」よりも「Notion / GitLab / ナレッジを跨いだ開発周辺作業のオーケストレーション」に近くなってきました。
以下の2点は重要だったかなと思います。
- どこで人間が介入すべきかを明確にすること。全部自動化するのではなく、プラン承認・コードレビュー・マージという判断ポイントにゲートを設けて、そこだけ人間がやる。それ以外は Claude に任せる
- 「AI は指示を守らないことがある」という前提で、hooks による強制など、プロンプトだけに頼らない安全策を仕組みとして入れておくことですね
まぁ、しかし、最近は、backlog-worker ディレクトリに張り付いて、ブラウザからバックログ拾ってきて貼り付けるという作業だけやってると、「プログラム大好きな自分」というアイデンティティはもう崩壊してしまっていますね。まぁ、いいんだけど(いや、プラン確認とか、ちゃんと指示はしてるんですけどね)。
「ロボット掃除機を使い始めるとロボット掃除機が動きやすいように環境を整える」という話が感覚的に近いものを覚えました。「AIが動きやすいように、開発環境を整備する」のが最近のメインの仕事になってきています。
ちなみに、最終的には、NotionのバックログからClaude Codeにタスクを振るだけになる予定です(9割できている)。まぁ、既にDevinとかがやってることだとは思いますので、周回遅れかもしれませんが。
おまけ
Backlog Workerのおかげで色んなバックログをやりすぎて自分がなにしてるのか良くわからないし、同じところで色々やってると Claude Codeの /resume が使えなさすぎるという問題がでました。
「よしWebアプリを作ろう」と思ったらほぼ一日でできました。社内事情がありすぎるので、モザイクだらけのスクショですが。
- Backlogタブには、自分に割り当てられたNotionから取得したバックログがステータスごとに表示されています
- Create New Backlogで新たにバックログを作ることもできます
- バックログに紐づく、Git Worktreeがある場合は、Backlogの下に表示され、ブランチ名や進捗がわかります
- プランがあれば(普通はある)、
Plan↗があり、クリックすると、右上のペインに表示されます -
!数字はMRがある場合表示され、リンクになっています -
📂開くは、Worktreeをエディタで開きます - Backlog タイトルの横にある、
run、refine、stagingは、サブコマンドです- ボタンを押すと、右下のペインにClaude Codeがたちあがります
- Tasks タブには自分に割り当てられたタスクが表示されます
- これも、
runボタンをクリックすると、taskサブコマンドが実行
- これも、
- Investigate では investigate/investigate3 のサブコマンドでコードベースを調べられます
- テキスト入力すれば、そのテキストをサブコマンドと一緒にClaude Codeが開かれます
- 調べたものは、履歴として一覧され、
再開から引き続いて調査することもできます
- Chatはただのチャットするためのものです
- 右下に表示されているClaude Code の内容はチャットでGo1.25とGo1.26について聞いたものです
- これも履歴が一覧されます
- Knowledge は、溜まっているナレッジの一覧が表示されます
- クリックすると右上のペインに表示されます
- Knowledgeの再評価もここからできます
- Settings は、TokenやNotionの自分のUserIDを指定したりするもの
一度、Backlog, Task, Investigateなどから、Claude Codeを立ち上げた場合、それぞれに「再開」というボタンがつきます。再開で始めれば、次始めるときも以前のセッションを引き継いで動かすことができます。
また、Webサーバ側でローカルファイルなどを監視していて、いいタイミングで、Backlogタブ無いをリロードしてくれます。
ちょっと社内事情が入り組んでいるので、一般には公開不能だし、そのままはどっちにしても使えないと思うので、Claude Codeなり、Codexに作ってもらうと良いと思います。
さらに追加で、aws cli からログを検索する機能を追加し、ログを選択して、investigate に投げる仕組みを作りました。
いや本当に楽になってしまった。
また、今度詳しく書きます。
