1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

dotsへの開発依頼を連鎖にする 指示書とCIと独立レビューの実例

1
Posted at

この記事自体もdotsが執筆しています。事実整理・独立検収・公開は手元の担当です。

AIエージェントに複数工程を任せるとき、今回は「共通の取り決めを先に書く」「最初に1回承認する」「検証はPRのCIで行う」という型を使いました。さらに、CI成功後の独立レビューで重大な問題が見つかったため、最後に別の製品のAIが全行を読む工程を加えることにしました。

前作「ChatGPTとClaudeからSlack経由でdotsに指示を出す仕組み」の続編です。案件番号とGitHubの固定commitの指示書を使い、PROGRESS.mdを看板にして、Slackの同じ会話で受付と報告をつなぎます。独立レビューと手元の検収まで含めて依頼を扱う仕組みを、実際の機能開発に使いました。

dotsに機能開発を任せる。取り決め、1回の承認、別のAIのレビューを組み合わせる

取り決めを先に書く、1回の承認で連鎖させる、別のAIがレビューする、直して読み直して取り込むという4手順

今回の対象とできた範囲

対象は、作り直し途中のDesklyに載せる「AI依頼の台帳」です。Desklyは連絡と案件の台帳アプリで、今回の機能は人とAIエージェントへの依頼を同じ番号で受付から人の受入まで追います。

Desklyの作り直しの中核と同じコードを使い、個人用・会社用など依頼を管理する組織の単位である「ゾーン」ごとに、別のインスタンスとして動かす方針です。実装は非公開の作業用repoで進めました。

完了した範囲はメモリ保存の試作、状況表示の部品、看板の生成です。DB保存、機械用の認証、HTTPとMCP、配備は含まれていません。この記事では機能の全仕様より、依頼と検証の組み立て方を扱います。

指示書の前に取り決めを固定する

最初にあった看板用Git repoを台帳にする案は採りませんでした。持ち主が検討シートで論点を選び、共通の取り決めを文書化し、非公開の看板repoに固定commitで置きました。

ここで決めた主な境界は次のとおりです。

  • 正本はゾーンごとの管理サービスに置く
  • 番号は入口が #<ゾーン印>-YYYYMMDD-NNN で振る。日本時間の受付日と日ごとの連番を使い、999の次は1000とし、再利用しない
  • 作業の状態と送信の状態は別に持つ
  • 送ったかどうか不明なときは自動で送り直さない
  • 本人と各人が1つ持つbotを分け、botは複数のエージェントで共用する

作業の状態は登録済みから担当決定、着手受付済み、作業中、提出済み、レビュー済み、完了へ進みます。送信側は送信待ち、送信中、送信済み・不明・失敗です。レビューでは、この状態の境目が文書どおりになっているかを読むことになりました。

作業者の印を権限として使わない

同じbotを使うエージェントは、branchの頭、commit末尾の Agent: <名前>、PRラベルで区別します。印は作業者を識別するためのもので、許可には使いません。指示書でも、作業の印と許される範囲を分けて扱います。

この名義の形にはGitHub側の制約もあります。無料の個人アカウントに加えて持てる無料のmachine accountは1つまでという規約から、エージェントごとに専用アカウントを作る方式は取れないと判断しました。GitHub Terms of ServiceのB. Account Terms

また、個人アカウントのrepoのcollaboratorには読むだけの権限を渡せないため、看板repoに案件の中身を置かないことにしました。個人アカウントのrepoの権限

依頼を分け、連鎖の範囲を最初に承認する

dotsへの依頼番号は4つに分けました。

  • 設計だけ。コードは書かない
  • 試作の4工程を連鎖で進める
  • 状況表示と看板を生成する
  • レビュー指摘を修正する

設計では、既存の受付であるcaseの仕組みを読み、「保存と取引の土台は流用し、AI依頼は専用の表と採番にする」案と、決めるべき論点を返してもらいました。持ち主は推奨どおりに決定しています。

当初は次の担当へ送るたびに本人が確認する取り決めでしたが、持ち主の意向で途中の確認をなくしました。最初に手順・担当・範囲・止まる条件を承認し、その中は自動で進めます。人が関わるのは最後の受入と、止まったときです。

指示書で読み取れるようにする項目

今回の型を使うなら、次の項目をひとまとまりにします。

  • 参照する共通の取り決めと、その固定commit
  • 依頼番号、成果物、作業範囲
  • 工程の順番、実装とレビューの担当
  • 途中で止めて人に戻す条件
  • 検証の場所と、次の工程へ進む条件
  • branch、commit、PRに付ける作業者の印
  • 受付・進捗・最後の報告を追う場所

「最初に1回の承認」は、以降の作業を無条件に任せるという意味ではありません。承認した手順と範囲の中を自動で進め、条件に当たったら止まる形です。実際に、今回の試作は実行環境の前提が合わず、工程0で一度止まりました。

最初の承認から工程0と工程1〜4を進め、停止条件に当たったときだけ人へ戻す。最後に別の製品のAIが全行を読み、人が受け入れて取り込む

図の細かい文字は、画像を拡大して確認できます。要点は本文にも書いています。

図は今回の学びを含めた次の型です。別の製品のAIによる全行レビューを取り込み前に置いていますが、今回の最初の全行レビューは初回の取り込み後でした。

検証の場所をPRのCIにそろえる

最初の指示では全工程で手元のテストを必須にしていました。しかし、dotsの作業環境で依存を取得できず、pnpm test が失敗しました。依存確認の通信も自動承認の取消で通りませんでした。

dotsは止まる条件に従って停止し、回避や再試行はしませんでした。ここは、指示が作業環境に合っていなかった点です。「検証はPRのCIで行う」という追加指示1枚で再開し、工程4まで止まらずに進みました。

各工程では実装とは別の担当がレビューし、CI 5種の成功を確かめてから次へ進みました。coreのテストは、状況表示までで346件から580件に増えました。

依頼には「テストする」だけでなく、どこで検証するかを書きます。今回はPRのCIを検証の場所とすることで、dotsの作業環境に依存取得を求める指示を修正しました。停止を迂回せず、指示の前提を直して再開できた点は、そのまま使える型でした。

CIが緑でも取り決めとの食い違いを読む

初回の取り込み後、手元のClaudeが5つのサブエージェントで分担して全行を読みました。dotsはOpenAIの常時稼働エージェント、ClaudeはAnthropicの製品です。別の製品を使うのは、見落としが重なりにくい読み直しを入れるためです。

実装を進めた作業役とは別の目が、成果全体を読み直す場面

CIのテスト580件がすべて成功し、dots内のレビューも指摘なしだった状態で、重大1件、中12件、軽約20件、テスト名とassertの食い違い約20件が見つかりました。

重大な問題は、次の順序で二重送信に至る経路です。

  • 依頼は送信中だが、宛先の履歴にまだ現れていない
  • それだけを根拠に失敗へ変更できる
  • 失敗1回目では連鎖が止まらず、別の冪等キーで次の送信が自動で作られる
  • 最初の送信が遅れて届くと、二重送信になる

「不明なら自動で送り直さない」と決めていても、その前段で安易に失敗へ移せると、別の送信が作られてしまいます。文書の条件を、状態遷移と次の操作までつないで読む必要がありました。

中の指摘には、工程を進むたびに人の停止確認が必要で途中の自動進行が成り立たないこと、作業役が報告IDを先取りして人の受入を失敗させられること、設定変更で控えが取れなくなることがありました。実装とテストがそろっていても、取り決めとの食い違いは残っていました。

テスト名が主張することをassertが見ているか

テストの弱さは、別の依頼でも点検に使える形で整理できました。

拒否された理由を確かめていない

期待するエラーの種類を見ず、「拒否された」ことだけを確認するテストがありました。対象の検査を消しても通る状態です。名前が特定の検査を主張しているなら、その検査による拒否であることをassertで確かめられるかを読みます。

同時実行という名前でも処理は直列

「同時100件」という名前のテストが、実際には1件ずつ順番に処理していました。件数を見るだけでは同時実行の確認になりません。テスト内で処理をどの順序で開始しているかまで読み、名前の条件と一致するかを確かめます。

呼ばれない関数の回数0を見ている

呼ばれない関数の呼び出し回数が0であることを確認するテストもありました。0という結果だけでなく、検証したい処理と確認している関数がつながっているかが点検の対象になります。

重大1件、中12件、軽約20件、テスト名とassertの食い違い約20件。拒否理由を見ない、同時実行が直列、呼ばれない関数の回数0というテストの弱さ

dots内のレビューは同じ製品の別担当でした。取り決めでは、製品名が違うことだけでは独立レビューと見なさないとしていました。今回分かったのはその反対側で、同じ製品の別担当も同じ見落としをしました。担当を分けたという記録に加えて、最後に別の製品のAIが全行を読む工程を置くのが今回の学びです。

修正依頼と読み直しを対応させる

指摘をR-01〜R-13に整理し、場所と直し方の要件を書いた修正依頼を、1回の承認で渡しました。dotsは約3時間で工程0〜4を終え、テストは718件になりました。

Slackの最後の報告が来なかったため同じスレッドで状況を聞くと、R-01〜R-13それぞれの修正箇所とテスト名が返りました。その後、手元のAIが3つのサブエージェントで読み直しています。

結果は重大0件で、二重送信の経路は閉じていました。新しい中の指摘は2件です。

  • 復元の検査を緩めたときに、機械の役割の照合まで抜けた
  • 解けない「不明」を人が失敗と決める出口が無い

この2件は次の工程の最初で直すことにして、持ち主の承認で手元が取り込みました。dotsにはmergeさせていません。修正済みの指摘と、新たに残った指摘を分けて受け入れる判断です。

依頼に持ち帰る要点

先に取り決めを固定すると、実装依頼もレビューも同じ文書を参照できます。最初の承認には工程・担当・範囲・止まる条件を含め、検証はPRのCIへ寄せます。最後には別の製品のAIが全行を読み、テスト名とassertも照合し、修正後にもう一度読み直します。

まだ本番の保存・認証・配備、ゾーンの印、控えを取る場所と間隔は未決です。試作の受入と、今後の実装範囲を分けて次へ進めます。

前作の依頼の入口に、今回の連鎖と検証の型を載せました。途中を任せるための条件を先に書き、最後に何を読んで受け入れるかまで、開発の手順に含める形です。


※ ヘッダー画像とインフォグラフィックの絵は AI(画像生成)で作成しています。

※ 本文の挿絵も AI(画像生成)で作成しています。

書いた人: ishizakahiroshi
群馬の北部で、保護猫2匹と暮らす、在宅エンジニア(何でも屋)
https://ishizakahiroshi.com/
https://github.com/ishizakahiroshi
X(業務委託・各種相談はこちら):
https://x.com/ishizakahiroshi

バックエンド・インフラ・AI連携まわりで、業務委託のご相談を受け付けています。フルリモートです。スポットや週2〜3時間からでも歓迎で、いろんな案件に携われたらうれしいです。こんな相談、歓迎です。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?