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?

AIエージェントが1回で読めない大きさのファイルを、CIで増やさせない ─ 既存の超過を例外にして縮むことしか許さない検査の作り方

1
Posted at

この記事でできること

AIエージェントにコードを書かせていると、ファイルは少しずつ大きくなっていきます。エージェントのファイル読み取りツールには1回で読める量の上限があり、それを超えたファイルは何回かに分けて読まれます。読んだ内容はその後の会話にも残るので、大きいファイルほどコンテキストを多く使います。

個人開発している技術記事キュレーションサービスDevPickでは、上限を超えたファイルを分割しても、数日後には別のファイルが上限を超えていました。そこで、上限を超えるファイルを新しく作らせず、すでに超えているファイルもそれ以上大きくさせない検査をCIに入れました。

この記事では、その検査の決めごとを点検リストの形でまとめます。実装のコードは載せず、作るときに決めておくべきことに絞ります。

背景:上限を超えたファイルは何回も読まれる

DevPickで使っているAIエージェントの読み取りツールは、1回に最大800行、または46,080バイトまでしか読みません。これを超えるファイルを全部確認しようとすると、エージェントは範囲を変えて何回も読み直します。

実際にエージェントのログを数えると、874行あったテストファイルの1つは、1つのセッションの中で範囲を変えて読み直された回数が、直近7日間で21回ありました。上限を超えたファイルは、少し直すだけでも毎回このように分けて読まれます。

点検1:上限の値は、使っているツールの読み取り上限から決める

上限の値は「何行くらいが読みやすいか」という好みではなく、使っているエージェントの読み取りツールが1回で読める量から決めます。DevPickでは800行と46,080バイトの両方を上限にして、どちらか一方でも超えたら違反にしています。行数だけを見ると、1行が長いファイルがすり抜けるためです。

  • 上限の値は、ツールの種類やバージョンで変わります。自分の環境で、どこまで1回で読まれるかを確かめてから決めます
  • 分割するときの目標は、上限ちょうどではなく600〜700行程度にします。上限ぎりぎりで分けると、テストを数件足しただけでまた超えます
  • 画像・ロックファイル・自動生成されたファイルのように、エージェントが全文を読まないものは対象から外します

点検2:すでに超えているファイルは、上限付きの例外リストに登録する

すでに上限を超えているファイルは、例外リストに登録したうえで検査を始めます。分割はその後、1本ずつ進めれば十分です。

例外リストには、ファイルごとに次の4つを書きます。

  • ファイルのパス
  • 許容する最大行数
  • 許容する最大バイト数
  • 例外にしている理由(関連するIssue番号など)

最大行数・最大バイト数には、登録した時点の実測値をそのまま入れます。「とりあえず大きめの値」を入れると、その分だけ肥大化を許すことになります。

点検3:例外リストは、縮むことしか許さない

例外リストに登録したファイルは「今の大きさまでは許す」という扱いです。そこから大きくなる方向の変更はすべて拒否し、小さくなる方向だけを認めます。このような一方向にしか動かない仕組みは、ラチェットと呼ばれます。

検査で拒否するのは次の4つです。

  • 例外リストに無いファイルが上限を超えた
  • 例外リストにあるファイルが、登録した最大値を超えた
  • 例外リストにあるファイルが小さくなったのに、登録した最大値が古いまま
  • 例外リストにあるファイルが上限内に収まったのに、リストに残っている

3つ目と4つ目が大事です。ファイルが小さくなっても最大値を書き換えなければ、次の変更でまた元の大きさまで戻せてしまいます。DevPickでは、リストの最大値を実測値まで縮め、解消したファイルをリストから消すコマンドを用意して、違反メッセージでそのコマンドを案内しています。

点検4:例外リストの比較は、PRの変更前の状態と行う

例外リスト自体もリポジトリの中のファイルなので、PRの中で書き換えられます。ファイルを大きくしたPRが、同じPRの中でリストの最大値も引き上げてしまえば、検査は通ってしまいます。

これを防ぐため、PRの検査では、変更前(マージ先のコミット)の例外リストと比べます。

  • 変更前のリストに無いファイルを、新しく例外に追加することは拒否する
  • 変更前のリストより最大値を引き上げることは拒否する
  • 変更前の時点では上限内だったファイルを、PRで大きくしてから例外に登録することは拒否する
  • 変更前のコミットを取得できなかったときは、検査を通さずに失敗させる

最後の項目は、取得に失敗したときに比較を飛ばして合格にすると、そのPRだけ何でも通ってしまうためです。

点検5:増えて当然のファイルは、別の決まりにする

要件定義書や設計書のように、機能を足すたびに追記するのが正しい文書もあります。こうした文書にコードと同じ「縮むことしか許さない」決まりを当てはめると、機能を足すPRがすべて止まります。

そこで、設計文書だけは別の決まりにしています。

  • 例外リストの最大値は、実測値に1〜2割の余裕を足した上限にする。上限までの追記は認め、小さくなっても最大値の書き換えは求めない
  • 上限を引き上げるときは、1回のPRで15%までにする。理由の欄にIssue番号と理由を書き直さないと拒否する
  • 新しく作る設計文書は、例外にせず上限内に収める

点検6:分割するときに、ファイル名に依存している箇所を探す

例外リストのファイルを分割すると、ファイル名が変わります。CIが変更されたファイルに応じて実行するテストを選んでいる場合、元のファイル名が書かれた箇所が残っていると、分割後のテストが実行されなくなります。

  • CIの設定やテストを選ぶスクリプトに、分割前のファイル名が書かれていないか検索する
  • 分割した両方のファイルで使う準備処理は、コピーせず共有の場所に移す
  • 分割の前後でテストの件数が減っていないことを確かめる

まとめ

  • 上限は、使っているエージェントの読み取りツールが1回で読める量から決める。行数とバイト数の両方を見る
  • すでに超えているファイルは、登録時点の実測値で例外リストに入れてから検査を始める
  • 例外リストは縮むことしか許さない。小さくなったら最大値を縮め、解消したら消すことまで検査する
  • 例外リストの比較はPRの変更前の状態と行い、比較できないときは失敗させる
  • 追記するのが正しい設計文書は、余裕のある上限と、1回あたりの引き上げ幅の制限で管理する

分割を繰り返しても終わらなかった経緯と、設計文書だけ別の決まりにした理由は、Zenn版に書いています。

1
0
2

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?