
Claude Code
イベント
マガジン
技術ブログ
はじめに お久しぶりです!株式会社スタメンのちぇるです。 2026/9/19(土)に大須演芸場で開催された「 名古屋Ruby会議05 」で、スポンサーLTとして登壇してきました! ちょうど1年前、僕は「 ながらRuby会議01 」に 聞く側 として参加していました(そのときの 参加レポート )。その年末の 振り返り記事 では「来年は自らプロポーザルを提出し、コミュニティへ還元する側に回ることに挑戦したい」と書いています。今年の2月に社外の勉強会で初めてLTをして、今回が2回目の社外登壇です。しかも地元・名古屋の Ruby 会議で話せたのは、ちょっと感慨深いものがありました。 この記事では、LTの内容をなぞるのではなく、 5分には入りきらなかった裏話 と、 話す側に回ってみて感じたこと を書きます。 LTで話したこと TUNAG のカレンダーで、繰り返し予定に「出欠」を足したときの設計判断の話をしました。中身はスライドをご覧ください。 ただ、話し終えてから少し反省しました。スポンサーLTということで「会社の看板を背負って話すのだから、ちゃんとしなきゃ」と構えてしまい、 少し真面目すぎた と思います。業務でやったことを、そのまま順番に説明しすぎました。聞いている人にとっては、TUNAG のテーブル設計そのものよりも、その途中で僕が何に迷い、何を学んだのかのほうが、持ち帰りやすかったはずです。作るものは違っても、どこで迷い、何を決め手にしたのかがわかれば、自分の開発に当てはめられるからです。 なので、この記事ではそちらを書いてみます。スライドでは、きれいに決まった判断だけを話しました。でも実際には、その前にもあとにも、何度もつまずいています。 スライドに載らなかったこと このプロジェクトは、ちょうど Claude Code を本格的に使い始めた時期と重なっていました。仕様をまとめたドキュメントを AI に渡して、実装を進めてもらう。作業のスピードは、体感で2倍くらいになりました。 一方で、リリースまでの期限は厳しく決まっていました。限られた時間の中で、どこに時間を使い、どこを削るかを常に選び続ける必要がありました。 仕様を渡すだけでは、足りなかった そんな中、途中で設計の手戻りが起きました。テーブル設計は AI と壁打ちしながら固めていったのですが、やりとりを重ねるうちに、「予定を作った本人も出欠を回答できる」という前提が AI のコンテキストから抜け落ちていたんです。ドキュメントに書いて渡していたこともあって、僕自身もそれに気づかないまま、抜けのあるテーブル設計で実装を進めていました。 いちばん効いたのは、それが「自分は確認を徹底しているから、大きな手戻りは起きないだろう」と思っていた矢先だったことです。 振り返ると、AI との対話が長くなるほど、最初に渡した前提は薄れていきます。それなのに、できあがった設計が仕様を満たしているかを確かめていませんでした。 人が責任を持つべきなのは、何を作るかを決める最初と、それが設計に漏れなく落ちたかを確かめる最後です。 それからは、AI に意図どおりのものを作ってもらい続けるための仕組みを考えるようにしました。意図と違う出力が出たら、その判断基準を言葉にして残し、次の会話でも AI が参照できるようにする。そして最終承認の前には、「仕様と設計に食い違いがないか」を AI にレビューさせる。AI が間違えない前提に立つのではなく、間違えても気づける仕組みを用意しておく。いわば、AI に安心して任せるためのガードレールです。 動くことと、使えることは違った このプロジェクトでは、コードの読みやすさとシンプルさを優先して、パフォーマンスへの対応は後回しにしていました。 機能としては期待どおりに動いていました。でも、リリース前にパフォーマンスの基準を満たせず、書き込みまわりのロジックをごっそり作り直すことになりました。 コードのシンプルさとパフォーマンスは、たいていトレードオフになります。たとえば、1件ずつ保存する書き方なら素直で読みやすい一方、件数が増えるほど遅くなります。まとめて書き込めば速くなりますが、そのぶん処理は複雑になり、整合性も自分で担保しなければなりません。どちらを取るかは、コードの中だけを見ても決まりません。 どれくらいの頻度で、どれくらいの量で、どう使われるのか。 実際の使われ方まで想像して、はじめて落とし所が決まるのだと学びました。 最初に固めるものを、3つに絞った 逆に、手放してよかったものもあります。 以前の僕は、リリース前に懸念をすべてつぶしてから進めたいタイプでした。でも今回は、そこまでの時間はありません。そこで、最初に固めるのを データの持ち方、APIの形、主要なクラス同士のやりとり の3つに絞りました。あとから直しにくいところにだけ時間をかけて、それ以外は走りながら決めます。たとえばデータの持ち方は、リリースした瞬間から本番に出欠の回答がたまり始めます。あとから形を変えると、それまでの回答をすべて新しい形に移し替えなければなりません。 細かい懸念も、影響の大きさと直すコストを天秤にかけて、一部はあえてそのままリリースしました。そのときは、どこまでの影響なら許容するのかを明記しました。「これは今やる必要があるのか?」と立ち止まれるようになったのは、大きな変化でした。 結局、何を握って、何を手放すかだった 振り返ると、このプロジェクトで学んだのは、設計のテクニックよりも どこに力を入れて、どこを手放すか の見極めでした。 AI に任せるところと、自分で握るところ。シンプルに保つところと、パフォーマンスを取るところ。最初に固めるところと、走りながら決めるところ。 どれも、最初からうまく線を引けたわけではありません。手戻りや作り直しを経験して、ようやく引けるようになりました。たぶんこの線は、扱う領域やチームが変わるたびに引き直すものなんだと思います。AI でコードを書くスピードが上がったいま、エンジニアに求められるのは、こうした線を引く力なのかもしれません。 おわりに 去年の自分は、カンファレンスで話している人たちを「すごいなあ」と眺める側でした。実際に話す側に回ってみると、登壇はすごい人だけがするものではなく、 自分の仕事を言葉にし直す機会 なのだと感じました。 またこの場所に立ちたいと素直に思いました。次は、自分でプロポーザルを出すことにも挑戦してみたいです。 改めて、素敵な場を作ってくださった名古屋Ruby会議05の運営の皆さま、聞いてくださった皆さま、ありがとうございました! 最後に スタメンでは一緒に働くエンジニアを募集しています!興味を持っていただけた方は、ぜひ下記からご覧ください。
■ 目次 目的は少ない人数でリリースの量を上げること 使う側から見た1件の流れ ready を付けると、トリアージが始まる 仕様書が PR で届く 実装も PR で届き、いつも通りレビューしてマージする 迷わないための工夫 構造: 状態ラベルとループ 人の判断の置き場所 承認ゲートは2つに絞る チェックシートは AI が下書きし、人が確定する 安心して任せられる理由 指示・手順で頼むことと、コードで強制することを分ける 迷ったら止まり、どこからでも再開できる 何が変わったか まだ甘いところと、これから こんにちは!楽楽精算でモバイルアプリを開発しているhirakawaです。 私たちのチームでは少ない人数でリリースの量を上げるために、開発プロセスを Claude Code で動く自律 AI のループで無人化しています。 Issue に ready というラベルを付けると、トリアージ、仕様書の作成、実装までを AI のループが順に進めます。人の判断が要るところに来ると、AI は止まって人を待ちます。 人がすることはこれまでと大きく変わりません。Issue・PR・チェックシートという、いつもの場所で、いつも通り返事をし、レビューをし、PR の承認・マージをします。 工場に例えるなら、人が作業台に張り付かなくても仕事が流れ、人は要所の検査と判断にだけ立ち会う、ソフトウェアファクトリーのような形です。ループをノード、状態をエッジとしてつなぐ「グラフエンジニアリング」も、近い考え方です。 この記事では無人で回るプロセスに人の判断をどう残したかを、設計の考え方を中心に紹介します。 目的は少ない人数でリリースの量を上げること 最初に何のために作ったかですが、目的は限られた人数のままリリースの量を増やし、届けられる価値を増やすことです。 制約は人の時間でした。指示を書く、定型作業をこなす、AI とのペア作業に立ち会う、レビューする。こうした時間が足りず、大きな機能開発をしている間は、他の対応がなかなか進みませんでした。 1件ずつの速さなら、人と AI がペアで進めるほうが速いです。ただ、ペアでは人がその場に張り付く時間は減りません。無人のループが勝つのは、人が張り付かなくても工程を跨いで並行に回せる量です。人の時間は判断にだけ使う。無人で回すのはそのための手段です。 使う側から見た1件の流れ 使う側から見ると、この仕組みは同僚に仕事を頼むのに近い感覚で使えます。1件の Issue が ready からマージまで進む様子を、人の目線でたどってみます。 ready を付けると、トリアージが始まる 担当者が自分の Issue に ready というラベルを付けます。人がすることはこれだけです。平日の日中なら、トリアージの定期ループがその Issue を拾います。 AI はトリアージの結果と、仮説つきの質問を Issue に書き、Slack で知らせてきます。「こういう意図だと理解しましたが、合っていますか」という形で聞いてくるので、人は普段通りに返信すれば答えになります。 3日たっても返事が無ければ、AI はその Issue を作業中から外し、論点をまとめたコメントを残して待つのをやめます。人が話し合って方針を決め、もう一度 ready を付ければ再開します。 仕様書が PR で届く 疑問が解けると AI が仕様書を書き、PR として届けます。このとき AI はチェックシートの下書きも作り、その結果を PR の本文に載せます。レビュー待ちになったことは Slack で知らせてきます。人は PR をレビューし、問題がなければマージします。 PR に指摘を書けば、AI が仕様書を直して PR を更新し、また Slack で知らせてきます。指摘が仕様の前提を覆すような内容なら、AI はトリアージからやり直します。 小さな修正では仕様書を省きます。その代わりに、Issue に書かれた対応方針を確認してほしいと AI がコメントしてくるので、人は「OK」と返すだけで先に進みます。 実装も PR で届き、いつも通りレビューしてマージする 仕様書の PR をマージすると、順番が来たところで実装が始まります。実装が終わると、AI が実装 PR を作り、Slack で知らせてきます。実装 PR には、動作確認の観点とチェックシートの確認欄が付いています。 実装 PR は AI が作るので、依頼した人はいつも通りレビューして、承認・マージできます。レビューで指摘を書けば、AI が直してもう一度レビュー待ちにします。 迷わないための工夫 無人で回る仕組みは、人が「いま何を待たれているのか」を見失うと止まります。そこで、人が迷わないための工夫をいくつか入れています。 AI が止まって人に何かを頼むときのコメントは、お願いしたいことを最初に書きます。その後に、次に何が動くか、人の追加操作は要らないこと、急ぐときは手動で実行して良いことを続けます 人は自分が assignee になっている Issue だけを見れば良いようにしています。担当が別の人なら、その人のループが受け持ちます Slack の通知は営業時間内に新しい出来事があったときだけ、担当者宛てに届きます。通知が来たら見る、という使い方で回ります 構造: 状態ラベルとループ この体験を支えている骨格は単純です。 記事用に簡略化した図 Issue に状態ラベルを1つ付け、工程ごとのループがそれぞれ担当の状態を拾って、処理を終えたら次の状態へ渡します。ループは7つあり、トリアージ、仕様書の作成、実装、PR のレビュー、開発完了処理、テストで見つかった不具合の一次調査を受け持っています。残りの1つは Slack への通知を受け持ち、PR がマージされたといった外で起きたことを見て、状態ラベルを先へ進める役も兼ねています。 全体を指揮する司令塔は置いていません。各ループは自分の担当の状態の Issue があるかを見て、あれば処理するだけです。このため、ループごとに責務がはっきり分かれ、1つのループを直しても他に波及しにくくなっています。 状態の移り方は状態遷移表で制限しています。表にない遷移を AI が試みると、ラベルを付け替えるスクリプトが拒否します。入口の ready は人だけが付けられるラベルで、AI 側からは付けられないようにしています。 各ループが何を受け取り、何を作り、どの状態へ渡すかは、ループごとの定義ファイルで宣言しています。宣言した遷移が状態遷移表に無ければ、機械の検査が落ちます。全体図もこの定義ファイルから生成しているので、図だけが古くなって取り残されることが起きにくくなっています。 人の判断の置き場所 量が増えるほど、人のレビューがボトルネックになります。人の判断の負荷を抑えつつ、判断そのものは手放さない。この章ではそのために人の判断をどこに置いたかを書きます。 承認ゲートは2つに絞る 主な承認ゲートは仕様書のレビューと実装 PR のレビューの2つです。小さな修正では仕様書の代わりに、Issue 上で対応方針を確認してもらいます。実装の途中やテストの実行には承認ゲートを置いていません。判断が要らない工程に人を立ち会わせると、そこで量が止まるからです。 仕様書のレビューを承認ゲートにしているのは、SDD(仕様駆動開発)の考え方を取り入れているからです。仕様の段階で人と AI が合意しておけば、実装はその仕様に沿って進められます。 チェックシートは AI が下書きし、人が確定する 私たちの開発ではリリースまでにいくつかのチェックシートを通す必要があります。この記入は AI が下書きし、判定の確定は人がします。この境界を守るために、次の決まりを設けています。 AI は人が確定した判定を上書きしません 開発の途中では AI が付けた「要確認」を AI 自身は取り下げません。完成したコードで見直した結果を提案することはありますが、確定するのは人だけです AI の記入には印を付け、人の記入と区別できる形で書きます 人が普段通りに書いた確定のメモを、AI の側で読み取ります。読めない形なら、保留して人に聞きます 最後の決まりは、人に入力の型を覚えさせないためです。人の書き方に、機械のほうを合わせています。 また、AI の記入には、人がどれくらい注意して見るかの目安として、確信度を付けています。 安心して任せられる理由 無人で回すからには、事故を起こさないこと、起きたときに後から追えることが欠かせません。 指示・手順で頼むことと、コードで強制することを分ける AI への指示・手順はどれだけ丁寧に書いても一定の確率で破られます。そこで、指示・手順で頼むことと、コードで強制することを分けました。 AI の操作は3つの層で限定しています。 GitHub や社内の資料、スプレッドシートといった外への書き込みは、ラッパースクリプトを通してしか行えません。ラッパースクリプトに無い操作は、そもそも実行する手段がありません 実行して良いコマンドは許可リストで決めています。リストに無いコマンドは、無人の実行では誰も許可しないので、そこで止まってしまいます そうなる前に hooks が検知して止め、代わりに使う正しいコマンドを AI に伝えます。許可したコマンドを使った抜け道も、同じ hooks が塞ぎます このため、Claude Code の auto モードに頼らなくても、無人で回る設計になっています。 例えば git の操作は、ラッパースクリプトに決まったものしかありません。 できるのは、ブランチを作る、コミットする、push する、PR を作る、といった開発に必要な操作だけです マージ、force push、ブランチの削除は、コード自体がありません 対象のリポジトリと、使って良いブランチ名の形は決まっています。main への直接の push はできません push や PR の作成のあとは、実際に反映されたかを読み直して確かめます マージは人だけの操作として残るので、承認ゲートが仕組みとして守られます。 迷ったら止まり、どこからでも再開できる 状態は Issue のラベルにあるので、どこで止まっても次の実行で続きから再開できます。再開する位置が分からなければ、推測で進めずに人に聞きます。実行ログと会話の記録も残しているので、問題が起きたら AI に原因を調べさせられます。 何が変わったか 今は大きな機能開発と並行して、不具合修正などを複数件リリースできています。少ない人数で、サーバとモバイルアプリなど複数のプラットフォームの開発を並行して回せています。 まだ甘いところと、これから もちろん、全てがうまくいっているわけではありません。 人がレビューで指摘したことが、次の案件に引き継がれません 実装を全てマージした後のリリース準備は、まだ人が担っている部分も多いです 今は自分の PC で定期実行しています。イベントをきっかけに動かすことと、PC を閉じていても回るよう、クラウドや self-hosted environments へ移すことを検討しています 他のチームにも広げたいと考えています。1件を早く仕上げたい仕事や判断の多い仕事は AI と人のペアで、数をこなしたい仕事は無人のループで、という使い分けと、無人のループで回るためのコンテキストの用意を合わせて広げていくつもりです AI を利用して無人で回すほど、人が手を動かす時間は減ります。その分、人の判断がボトルネックになるため、上記をやりつつ、人が判断する負担を減らしたいと考えています。
はじめに こんにちは、Insight Edgeの小林まさみつです。 ※ 本記事はPoC案件での技術検証の内容であり、商用環境での実用性は今後の検証課題です Claude Codeのようなコーディングエージェントに実装を任せる場面は珍しくなくなりました。一方で、実装を任せたあとの「意図どおりに動いているかを確認する」「レビューする」「マージして後片付けをする」といった作業は、人の手に残りがちです。 今回は、あるPoC案件の開発で、タスクの起票からレビュー、マージ依頼までをAIエージェントに任せる仕組みを作って運用しました。本記事では、背景、設計の考え方であるハーネスエンジニアリング、具体的な仕組み、導入結果と今後の課題を紹介します。 なお、本記事は実務で行った内容をもとにしていますが、案件を特定できないよう、案件の内容はぼかして書いています。 TL;DR タスクの起票、設計、実装、レビュー、マージ依頼、後片付けをAIエージェントに任せ、人は「planとDRのレビュー」と「マージ」の判断だけを担当した 仕組みで強制する制約( deny 、フック、CI)と、プロンプト側で規定する振る舞い(レビューの3分類など)を分けて設計した PoCでの成果であり、商用の開発で通用するかは今後の検証課題 目次 背景 ハーネスエンジニアリングを活用した開発 具体的な仕組み 導入結果 今後の課題 まとめ 参考文献 背景 対象は、ドキュメントを分析し、意思決定を支援するレポートを作るPoCです。バックエンドはFastAPI、フロントエンドはReact、分析はクラウド上のLLMを使ったマルチエージェントで行っています。 このPoCでは、次の状況が重なっていました。 他案件のリリースと時期が重なり、人手が足りない 開発者が1人のため、コードレビューをする人がいない 開発タスクが60件を超え、どれも「worktreeを切る → 実装 → PR → レビュー → マージ → 後片付け」という同じ作業の繰り返しになる 一方で、PoCなので要件が限られており、試したい手法をすぐ検証できる立場でもありました。そこで、定型作業をまとめてAIに渡し、人は「何を作るか」の判断に集中する形を目指しました。 実際にどの程度の範囲を回したかは、タスクの内訳で伝わりやすいと思います。認証認可、セキュリティ対策、性能とコストの改善、テスト戦略とE2Eテスト、インフラのコード化とCI/CD、アクセシビリティの改善といった、機能要件から非機能要件、DevOpsまで幅広い領域が含まれます。これらすべてのタスクを、この仕組みで進めました。 ハーネスエンジニアリングを活用した開発 この仕組みを設計するうえで参考にしたのが、Birgitta Böckelerさんの記事 Harness engineering for coding agent users (martinfowler.com、2026年4月)です。 Agent = Model + Harness 記事では、エージェントを「Agent = Model + Harness」と捉えます。ハーネスとは、モデル以外のすべて、つまりエージェントを取り巻く仕組みのことです。エージェント製品に最初から組み込まれた部分(inner harness)と、利用者が自分のユースケース向けに作る部分(outer harness)があり、本記事で扱うのは後者です。 outer harnessは、2種類の制御で構成されます。 ガイド :エージェントが動く前に方向づける(feedforward) センサー :動いた結果を観測し、自己修正させる(feedback) さらに、それぞれを次の2種類に分けて考えられます。 computational :機械的に決まる。テスト、リンター、権限設定など inferential :LLMの判断に頼る。レビューや方針の記述など 人の役割は、同じ問題が繰り返されたときに、ガイドとセンサーを改善してエージェントを操ることです。 この関係を、本記事の内容に当てはめて図にすると次のようになります。 ハーネス概要 この図は、Böckelerさんの記事にある図を、本プロジェクトの部品で描き直したものです。原典の図は 記事 で確認できます。 人がやること、AIがやること ハーネスで周囲を固めたうえで、人の仕事は「判断」に絞りました。 担当 やること 人 起票の指示、着手の指示、planファイルとDecision Recordのレビュー(重要なタスクはテストケースも確認)、マージ、必要に応じたデプロイ作業 AI 要望の分解と調査、Issueの起票、カンバンの移動、設計、実装、テスト、PR作成、デモ動画の撮影と添付、レビューと指摘対応、マージ依頼、worktreeなどの後片付け Decision Record(DR)は、意思決定の理由と採用しなかった代替案を残すためのMarkdownです。タスクごとにAIが書き、人が読んで方針を確認します。 このプロジェクトの部品を並べる 本プロジェクトの部品を、ガイドとセンサー、computationalとinferentialの2軸で整理すると次のようになります。各部品の詳細は、次章で紹介します。 computational(機械的) inferential(LLMの判断) ガイド (事前) settings.json の deny でPRのマージを禁止、レビュー系エージェントに書き込みツールを与えない、worktreeによる作業の分離 CLAUDE.md の設計原則とコメント規約、DRのテンプレート、Issueの「やらないこと」 センサー (事後) 編集後のformatフック、コミット時のシークレット検査、CI(lint、単体テスト、E2E、ビジュアルとa11yの検査、ライセンス検査)、PRへのカバレッジコメント、ミューテーションテスト レビュー指摘の3分類、デモ動画の比較 この表を作ると、何が「強制」で何が「約束」なのかが見えます。実際には、仕組みで強制できているのは、 deny 、ツール権限、シークレット検査、CIだけです。ループの3ラウンド上限や、指摘の3分類、Slack通知の条件は、プロンプトに書いた約束にすぎません。この線引きをどう考えるかは、 今後の課題 で触れます。 具体的な仕組み 構成 構成は、Claude Codeのスキル2つ( /create-task 、 /run-task )と、サブエージェント3つ(planエージェント、devエージェント、reviewエージェント)です。 エージェントのワークフロー ポイントは、エージェント同士が直接やり取りしないことです。司令塔(Orchestrator、 /run-task )が SendMessage で仲介するため、各エージェントは自分の役割だけを見ればよくなります。また、Claude Codeのサブエージェント機能を利用することで、コンテキストを分離しつつ、必要な情報を共有できます。 1タスクの流れ 全体の流れは次のとおりです。人が関わるのは、planとDRのレビューと、最後のマージだけです。 起票( /create-task ) :要望を分解し、コードベースを並列に調査して既存Issueとの重複を判定します。続いて、選択式の質問で要件を固め、優先度とストーリーポイントを見積もります。最終確認を取ったうえで、固定の節構成(背景・目的、要件、やること、やらないこと、依存関係)と固定のラベル(優先度、ストーリーポイント、変更対象項目など)でIssueを起票し、カンバンに登録します。「やらないこと」を明記しておくと、後のレビューで範囲の逸脱を検出できます。 たとえば、次のように要望を一言伝えるだけで起票されます。以下は、実際に起票されたIssueの例です(一部をマスクしています)。 /create-task 画面サイズが大きいと余白が目立つ。見づらいので幅をディスプレイサイズに応じて調整したい 起票されたIssue 設計(planエージェント) :Issueを確認し、作業用のworktreeとブランチを作ります。カンバンを「進行中」に移し、planファイルとDRを書きます。planが完了するまで実装は始めません。人が確認するポイントはここです。正しい設計が行われているかをレビューし、必要に応じて修正指示を出します。問題が無くなれば、実装フェーズに進みます。 planファイルには、背景と要件の要約、設計方針の結論、ファイル単位の実装ステップ、テスト方針、そして「設計上の懸念点・判断が分かれる点」を書かせます。最後の項目は、人がレビューするときの着眼点になります。DRには、背景、決定事項とその理由、検討した代替案と採用しなかった理由を残します。後から「なぜこうなっているのか」をたどるための記録です。 実装(devエージェント) :planに沿って実装します。テストは必須で、LLM呼び出しのみ時間とコストの兼ね合いからモックにします。formatとテストを通してからPRを作り、PRの先頭行にIssueを閉じる記法を書いてカンバンと連動させます。さらに、人のレビューをしやすくするために、変更前後の画面を並べたデモ動画を録画してPRに添付します。後段のレビュー指摘を受け取った際、内容に同意できない場合は、反論してよいことにしています。 一方で、force push、マージ、Issueの「やらないこと」への着手は禁止です。 PRに添付されたデモ動画。左が変更前、右が変更後 レビュー(reviewエージェント) :次の8観点をレビューします。 シークレットの混入 「やらないこと」への逸脱 要件の充足 アーキテクチャ方針が適切か テストの有無と妥当性 Decision Recordが適切に記録されているか 実装品質 セキュリティ これに加えて、デモ動画の挙動がIssueの要件と一致しているかも確認します。ループは最大3ラウンドで、反論が2往復続いた場合は打ち切って人に判断を仰ぎます。これは過剰な議論や実装を防ぐための仕組みです。試しにラウンド数に制限をかけずに運用してみたところ、4ラウンド以降は些細な指摘が延々と続き、効率が大幅に低下しました。そのため、3ラウンドを上限としました。 reviewerエージェントが投稿したレビューコメントの例 マージと後片付け :レビューが承認されると、SlackのIncoming Webhookにより通知が届きます。人が内容を確認してマージすると、司令塔がマージを確認し、worktree、ローカルブランチ、リモートブランチを削除して main を更新します。マージだけは人が握り、それ以外は自動で片付く設計です。また、Slackのメッセージには追加で対応が必要な事柄(例えば、インフラリソースの変更など)も含めるようにし、何をすれば良いかが一目でわかるように工夫しています。 実装例:computationalなガイドとセンサー 強制力のある部分は、設定ファイルに数行書くだけで実現できます。たとえば、PRのマージをエージェントに禁止し、ファイルを編集するたびに自動でフォーマットをかける設定は、 .claude/settings.json に次のように書きます。 { " permissions ": { " deny ": [ " Bash(gh pr merge:*) " ] } , " hooks ": { " PostToolUse ": [ { " matcher ": " Edit|Write|MultiEdit ", " hooks ": [{ " type ": " command ", " command ": " mise run format " }] } ] } } deny はプロンプトでの「マージしないでください」と違い、エージェントがこのコマンドを実行できなくなります。実は最初の版では、reviewエージェントが承認後に自動でマージしていました。マージだけは人が握る、という方針をルールとして書くのではなく、仕組みで担保した例です。 --- name : review description : devエージェントが作成したPRをレビューし、承認時は司令塔へ報告する。マージは行わない。 tools : Bash, Read, Glob, Grep, SendMessage model : opus --- コミット時のシークレット検査(pre-commit)は、あえて検査を1つに絞っています。整形や単体テストは数十秒かかり、コミットのたびに走らせるには重いためです。フックが守るのは、一度コミットすると履歴から消すのが極めて高コストな「シークレット」だけにし、残りはCIに任せています。CIと同じコマンド、同じgitleaksのバージョンを使うため、フックが通ればCIでも通ります。なお、前述のPostToolUseフックにより、ファイルを編集するたびに自動でフォーマットがかかるようになっているため、基本的にはCIでLinter/Formatterによる失敗は起こりません。 #!/bin/sh set -e exec mise run scan:secrets:staged センサーの事例①:指摘を握りつぶさせない3分類 最初のレビューの運用では、「軽微な指摘ならAPPROVEしてコメントを残す」という余地がありました。その結果、マージ済みの3タスクで、10件以上の指摘が誰にも対応されないまま残りました。「任意対応」は、誰も対応しないことの丁寧な言い換えでした。 そこで、レビューの指摘を必ず次の3つのどれかに分類するようにしました。「任意」という分類は作りません。 分類 判断 扱い 狙い 要修正 このPRの目的や品質に必要 このPRで直す 品質を守り、要件を満たす 別タスク化 重要ではないが、いずれ直すべき 優先度を下げてIssueを起票する レビュー負荷の軽減と、過剰な実装の防止 取り下げ 些細で、直しても価値がほとんどない 理由を書いて撤回する 些細な対応の繰り返しによる、フローの長期化と無駄な実装の防止 「別タスク化」には、いまは過剰でも将来あるとよい改善も含めます。起票が終わるまでは、Slack通知もマージもできない流れにしました。これで、指摘が放置されることも、些細な指摘でPRが延々と往復することも減りました。 reviewエージェントのプロンプトには、次のように書いています(抜粋)。 すべての指摘は、次の3分類のいずれかに必ず割り当てます。 「任意対応」「参考」「好みの問題」「余力があれば」といった曖昧な分類を作ることを禁止します。曖昧な分類は、対応されないことを丁寧に言い換えただけで、実質的に指摘を捨てています。 「取り下げ」を分類に用意しているのは、指摘の水準に達しない些細な気づきを無理に起票させないためです。すべてを別タスク化すると起票が膨張し、Projectsのボードが機能しなくなります。 直す価値があるかを自分に問い、無ければ取り下げてください。 禁止する分類の名前まで具体的に列挙し、「なぜ禁止するのか」「なぜこの分類が必要なのか」という理由を添えている点がポイントです。理由を書いておくと、エージェントが想定外のケースに出会っても、意図に沿って判断してくれます。判定は「要修正が1件でもあればREQUEST_CHANGES、0件ならAPPROVE」と機械的に決まるようにし、別タスク化を提案した指摘は、GitHubのレビュー本文にも「別タスク化を提案」と明記させています。レビューを読んだ人が、その指摘が放置されたのか、起票されたのかを判別できるようにするためです。 センサーの事例②:使い捨てのデモ動画 もう一つのセンサーが、デモ動画です。PRのベースとなるコミットと、PRのブランチを並べて録画し、PRに添付します。コードを読むだけでは気づきにくい「見た目や動きの食い違い」を、レビュー時に確認できます。動画は使い捨てで、リポジトリにはコミットしません。 工夫①:役割ごとにモデルを変える エージェントごとに、使うモデルを変えています。 エージェント モデル 理由 plan fable 設計の質が後工程の品質を決める dev sonnet 設計どおりにコードへ落とす作業のため review opus 品質を担保したいが、最上位のモデルではコストが高すぎるため、折衷案とした 工夫②:運用の手間を減らす 人とエージェントの手作業を、自動化と検出に置き換えました。 カンバンの移動 :カンバンの「Todo → 進行中」だけは、planエージェントが移します。残りはGitHub Projectsの自動化に任せています。PRの先頭行にIssueを閉じる記法があれば「レビュー中」へ、マージされれば「完了」へ移ります。 Slack通知 :通知は1タスクにつき1通に絞りました。送る条件は、レビューがAPPROVEであること、別タスクの起票が終わっていること、PRがマージ可能な状態( MERGEABLE かつ CLEAN )であること、の3つがすべて揃ったときです。なお、MCP経由で投稿すると投稿者が自分自身になり、通知が鳴りません。そのため、Slack Appを作り、Incoming Webhook経由で投稿しています。 投稿はシェルスクリプトに閉じ込めています。Webhook URLを取得し、このスクリプトの中でだけ扱うことで、URLがシェル履歴や会話ログに残らないようにしています。エージェントには、このスクリプトの実行だけを許可します。 #!/usr/bin/env bash set -euo pipefail WEBHOOK_URL = " <YOUR_WEBHOOK_URL_HERE> " RESPONSE = " $( curl -sS -X POST -H ' Content-type: application/json ' \ --data @ " $1 " " $WEBHOOK_URL " ) " unset WEBHOOK_URL [ " $RESPONSE " = "ok" ] || { echo " Slackへの送信に失敗: ${RESPONSE} " >&2; exit 3 ; } 通知の本文には、マージコマンドと、マージ後に人がやることも含めます。たとえばインフラの変更を伴うPRなら、「マージ後にterraform applyを実行し、実環境で確認する」といった手順まで書いてあるため、通知を開いた時点で何をすればよいかが分かります。 Slackに届くマージレビュー依頼の通知 コンフリクト :最初は、並行して進めるタスクのうちコンフリクトしそうな組を事前に予測しようとしましたが、予測は外れました。そこで、予測をやめて検出に切り替えました。人から1件のマージ報告を受けるたびに、司令塔が残りのPRについて次のコマンドを実行します。 for n in { 残っているPR番号 } ; do gh pr view $n --json number,mergeable,mergeStateStatus done 結果が MERGEABLE ならそのまま進め、 CONFLICTING ならdevエージェントにコンフリクトの解消を依頼します。 UNKNOWN は、GitHubがまだ判定を計算中の状態です。これをコンフリクトと誤認すると不要な取り込みを依頼してしまうため、数秒待ってから再取得するようにプロンプトに明記しています。解消はrebaseではなくmergeで行います。rebaseはforce pushが必要になり、devエージェントに禁止しているルールとぶつかるためです。同じPRで解消に2回失敗した場合は、別の変更を壊している可能性があるため、人にエスカレーションします。 導入結果 数値 0.8人月での開発実績は次のとおりです。 項目 値 マージしたPR(bot除く) 86本 PR作成からマージまでの時間 中央値 約0.8時間、平均 約2.6時間 テストコードとプロダクトコードの行数比 約1.7倍 人の工数 1タスクあたり平均 約15分 実装済みの主な機能/非機能は次のとおりです。 区分 主な内容 機能要件:分析 複数の観点での分析と集約、追加の質問チャット、根拠箇所へのトレーサビリティ、追加資料での再分析とバージョン管理、失敗分だけの再実行 機能要件:レポートとUX 経済性シミュレーション、リスク注記、履歴の検索、PDF・JSONの入出力、ブラウザを閉じても続く分析と進捗配信、ダークモードとアクセシビリティ対応 非機能:認証とセキュリティ MFA込みの認証認可とユーザー管理、LLM認証の鍵レス化、保存データの暗号化、シークレット・ライセンス検査 非機能:性能とコスト プロンプトキャッシュと圧縮、ストリーミング化、リトライ、分析結果の永続化 非機能:品質保証 単体テスト、E2E、ビジュアルリグレッションとa11yの自動監査、ミューテーションテスト DevOps・基盤 Terraformによるインフラのコード化、GitHub ActionsのCI、mainマージでの自動デプロイ、依存更新の自動化 定性的な変化 人がやることは、「何を作るか」と「planとDRのレビュー」に絞られました。他案件の対応と並行しながらでも、この案件を止めずに進められたのが大きな変化です。 今後の課題 良い点だけでなく、残っている課題や今後検証したい点も挙げておきます。 設計と適用範囲 AIの処理時間とレートリミット :人の工数は小さくなりましたが、PRが出るまでの時間は、AIの処理時間とレートリミットに縛られます。設計、実装、最大3ラウンドのレビュー、デモ動画の録画にはそれぞれ時間がかかります。並行して回すタスクは最大5件を目安にしていますが、増やすほどレートリミットにぶつかりやすくなります。また、並行するPRが増えるほど、コンフリクトの確率も上がります プロンプト上のルールをどこまで仕組みで強制するか :仕組みで強制できているのは deny 、ツール権限、シークレット検査、CIだけで、ループの3ラウンド上限、指摘の3分類、Slack通知の条件はプロンプトに書いた約束にすぎません。PoCではこれで十分でしたが、商用開発に適用するなら、ここが最初の論点になると考えています 商用開発でも同じ形が通用するか :今回のPoCは要件が限られており、効率を最優先できました。品質や監査の要求が高い商用開発で、同じ人の関与の度合いでよいかは、今後の検証課題です 運用上の課題 devエージェント、reviewエージェント、人が同じGitHubアカウントを使っているため、GitHub上の承認が形式的になりやすい。実際、自分のPRにはGitHubの機能におけるAPPROVEができず、コメントで代用している ミューテーションテストは手動で、適切な頻度は検討中 バックグラウンドで動くサブエージェントが、権限の確認待ちで何も言わずに止まることがある まとめ 本記事では、タスクの起票からレビュー、マージ依頼までをAIエージェントに任せる仕組みを、ハーネスエンジニアリングの考え方とあわせて紹介しました。人によるレビュー粒度とプロンプトの設計を適切に行えば、効果的に使えるという手応えを得ました。商用の開発でそのまま通用するかは、今後の検証課題です。 案件に依存せず、他のプロジェクトにも持ち出せると考えている点は次の3つです。 AIに作業を任せるだけでなく、周囲の仕組みを設計する :事前に縛るガイドだけでも、事後に検知するセンサーだけでも足りません。指摘の3分類のように、抜け道が実際に指摘の放置を生んだ箇所を、センサー側で塞ぎました。 強制できるものは仕組みに寄せる :マージの禁止は deny で、シークレットの混入はpre-commitとCIで防いでいます。プロンプトに書いた約束は、あくまで「守られやすくなる」だけです。また、最初から完成した仕組みではなく、自動マージの全廃、3分類、コンフリクト検出、デモ動画の比較方式への修正など、事故のたびにDRに残して直してきた結果です。 人の仕事を「作業」から「判断」に寄せる :人の仕事を「判断」に絞れたことが、1人でも複数の案件を並行して進められた一番の要因でした。 AIエージェントによる開発の半自動化を検討されている方の参考になれば幸いです。 参考文献 Harness engineering for coding agent users(Birgitta Böckeler、martinfowler.com)




















