クラウドワークス エンジニアブログ

日本最大級のクラウドソーシング「クラウドワークス」の開発の裏側をお届けするエンジニアブログ

AIエージェントに開発プロセスを「できるだけ自走」させる ─ 要件確定から実装完了まで

タイトル: AIエージェントに開発プロセスを「できるだけ自走」させる ─ 要件確定から実装完了まで

はじめに

クラウドワークス エージェントの開発を行っております。 エンジニアの杉浦です。

今回はチームで行っているAI活用についての①一連の流れ(要件確定から実装完了)と②Tipsなどを書きたいと思います。

チームでは開発プロセスなどを管理するリポジトリを新しく作り、そこを起点に実装完了まで進めています。

※ 使用しているAIコーディングエージェントは Claude Code で、現在 v2.1.185 です。

①一連の流れ

AI: 要件定義
↓
人間: レビュー
↓
AI: 設計
↓
人間: レビュー
↓
AI: タスク分解
↓
人間: レビュー
↓
AI: 実装(PR作成まで)
↓
人間: レビュー

このように間に人間のレビューを挟む形で行っております。

一連の流れの詳細

1. フェーズそれぞれスキル化

要件定義・設計・タスク分解・実装といった各フェーズを、それぞれ独立した「スキル(手順の定義)」として切り出しました。

具体的には下記の通りです。

スキル名 説明
初期化スキル タスク用のドキュメントディレクトリを切り、doc/ 配下に作成する
要件定義スキル ヒアリングシートを起点に、一問一答で受け入れ条件まで詰め、doc/ 配下に作成する
設計スキル 要件をもとに構成、処理フロー、影響範囲を整理し、doc/ 配下に作成する
タスク分解スキル 設計書を「レビューしやすいPR単位」に割り、doc/ 配下に作成する
実装スキル タスク分解されたものから実装を行い、PR作成まで行う

また要件定義・設計・タスク分解までは、人間とひたすら会話しながら仕様や受け入れ条件を詰めていきます。

さらに、実装スキルでは /goal コマンドを参考にした仕組みを用いて実装し完了まで自律実行させます。

/goal とは完了条件を設定すると、その条件が満たされるまで Claude がターンをまたいで作業を続けるものです。

── Claude Code 公式ドキュメント「Keep Claude working toward a goal」 https://code.claude.com/docs/en/goal (日本語訳)

実装スキルの中には下記があります。

  • worktree を作って作業を隔離する
  • 変更したファイルに lint をかける
  • 変更したファイルに関連するテストを回す
  • lint・テストが通らなければ自己修正し、緑になるまで繰り返す
  • commit・push・PR 作成は1回の承認にまとめて人間に確認する

2. 人間のレビューについて

各フェーズの出口に人間のレビューを入れています。

タスク分解の際に仕様上の判断が迷う点などをプロダクトオーナーに質問し、テスト観点などをここで確認します。

やり取りはGitHub上で行っており問題なければApproveをもらう形です。

また、このやり方は「ループ・エンジニアリング」を参考にしています。そこで語られる要素のうち、採り入れたものとあえて作っていないものを補足しておきます。

  • 状態(State)= AIに持たせる記憶: タスクの成果物は doc/ 配下に吐き出し、タスク実施時には memory(過去の学び)も参照させています。ただ、ホームディレクトリに置かれる memory を管理し続けるのは正直めんどうで、汚染(古い・誤った記憶が混ざること)の管理が気が重い、というのが本音です。
  • 自動化(Automations)= 自動でタスクを拾う仕組み: 滞留したタスクを自動で拾う巡回は作っていません。チームの朝会があるので、そこで拾えば十分という今のところの判断です。

参考

②Tips

次に一連の流れで使っているTipsです。

1. どのセッションで作ったPRかを後から追えるようにする

地味ですが、作成したPRの本文末尾に、そのPRを作ったときのセッション再開コマンドを必ず書いておく ことです。

claude --resume <セッションID>

こうしておくと、「このPR、どういう経緯・文脈で作ったんだっけ?」となったときに、当時のAIとのやり取りをそのまま再開して追えます。 レビューで指摘が来たときの修正も、文脈を丸ごと引き継いだまま再開できるのが便利です。

問題は、セッションIDが「終わってから」割り当てられると、後付けで本文に書くのが面倒なこと。そこで、起動時にセッションIDを自分で固定してしまう シェル関数を用意しました。

ccs() {
  export CC_SID=$(uuidgen)
  echo "Session ID: $CC_SID"
  claude --session-id "$CC_SID"
}

ccs で起動すると、セッションIDが先に決まって環境変数 CC_SID に入っているので、PR本文を組み立てるときに claude --resume $CC_SID をそのまま埋め込めます。 「どのセッションがどのPRを作ったか」が常に1対1で追える状態になります。

2. ドキュメントと設定の同期忘れを、push 直前のフックで防ぐ

スキルやサブエージェント、フックを追加・変更すると、それらをまとめた設定ドキュメント(CLAUDE.md)の更新を忘れがちです。

そこで、git push の直前に走るフック(PreToolUse)を仕込みました。push に .claude/ 配下(skills / agents / hooks)の変更が含まれているのに CLAUDE.md が未更新の場合、 「設定ドキュメントの同期が要るかも」と確認を出す、というものです。

ポイントは、フックに余計なことをさせないこと。自動で書き換えたりはせず、ヘッドレスでAIを起動したりもせず、ただ「確認しますか?」と尋ねるだけ にしています。 実際に同期するか・そのまま push するかは人間が決める。フックに全て任せると暴走するので、「検知して人間に渡すだけ」に徹するのがいちばん安定しました。

最後に

この運用を始めて日が浅いですが導入する前とした後で何が変わったか述べたいと思います。

楽になったか?

→ いいえ。大変なポイントが移動しただけ、という気持ちです。なんというか、人間の確認にはどうしても時間がかかるためです。

ただ同じ指示をしなくても良くなった部分は楽になりました。

生産性は上がったか?

→ はい。さすがに上がりましたが人間の確認を頑張れば頑張るほど上がる形です。

成果物の品質はどうか?

→ 確認を怠ると下がる。タスク分解時点で人間のレビューなどをしないと一から作り直しになるケースもありました。

現状の運用で大枠はできましたが、今後は次のあたりを育てていきたいと思っています。

  • E2Eテストの整備: こちらまだ未整備で一番よくないと感じています。
  • 自動化(Automations)の見極め: 今は朝会で拾えば十分という判断で巡回は作っていませんが、運用が回り始めて滞留が増えてきたら、どこまでを自動で拾わせるかを改めて検討したいです。

またこの運用に縛られすぎず、いつでも手放せるくらいの軽い依存度にしたいと感じています。

AIをどう実務に組み込むかは難しいですが「うちはこのループでやっています」という一例として、どこか参考になれば嬉しいです。

© 2016 CrowdWorks, Inc., All rights reserved.