coding agentでlintのチェックを行う
なぜlintから始めるのか
AI Agentの品質を考えるとき、最初に気になるのは「回答が正しいか」「ユーザーにとって役に立つか」といったAI特有の評価です。しかし、その前に、通常のソフトウェアとして確認できる問題を切り分ける必要があります。
lintは、プログラムのコードを自動チェックして、問題点を見つけるツールやその作業のことです。もともとはUnixのlintというC言語向けツール名から来ています。lintを通して、例えば文法ミス、書き方のルール違反、バグになりそうなコード、不要な変数、読みにくいコードを見つけていきます。
formatterというインデント、改行、空白、クォートの使い方など、コードの見た目を一定のルールで整えるためのものがありますが、近年のツールには、Biomeのようにlintとformatterの両方を提供するものもあります。
lintやformatterで機械的に検出できる問題を先に落としておくことで、その後のAI評価や統合テストに余計なノイズを持ち込まずに済み、効果的に後段のテスト・評価を行うことができるので、まずはこのプロセスを進めることが重要です。
Coding Agentにlintの仕事をさせない
Coding Agentに「コードをきれいにして」「問題がないか確認して」と頼むことはできます。しかし、lintで判定できる問題を、LLMの自然言語判断に任せる必要はありません。
リンター、フォーマッター、型チェッカーのような決定論的なツールで確認できることは、ツールに任せるべきです。毎回LLMに確認を依頼すると、応答を待つ時間が発生し、トークンやAPI利用料のコストも積み重なります。さらに、LLMは便利ですが、同じ入力に対して常に同じ判断を返すとは限りません。一方でlintは、同じルールと同じコードであれば同じ結果を返します。決定論的なツールとガードレールで品質を強制することができるのであれば、そうした手段を積極的に採用していきましょう。
ただし、全くCoding Agentを使わないというわけではありません。lintの結果を読み、失敗の原因を理解し、コードを修正する役割をLLMに担わせます。
- lintは、機械的に検出できる問題を見つけます。
- Coding Agentは、lint結果をもとにコードを直します。
この分担にすると、Agentの柔軟性を活かしながら、最低限守るべき品質ラインを機械的に固定できます。
lintの実行方法
実際、Agentforgeのアプリケーション部分では、BiomeによるlintとTypeScriptの型チェックを使っています。以下、lintチェックのコマンド例です。
pnpm lint # Biomeでコードスタイルや静的な問題を確認します
pnpm typecheck # React Routerの型生成後、TypeScriptで型の整合性を確認します
pnpm check # lintとtypecheckをまとめて実行します
pnpm lint:fix # Biomeで自動修正できる問題を修正しますpnpm lint:fixは、Biomeが自動修正できる問題を実際に書き換えるコマンドです。このリポジトリではBiomeの--writeを使うため、formatterとして整えられる見た目のずれと、一部のlintルール違反の自動修正がまとめて適用されます。一方で、設計判断が必要な問題や、コードの意味を変える必要がある問題は自動修正できません。その場合は、Coding Agentがlint結果を読み、コード側を修正します。ただし、lint:fixで直らないエラーを、無理に設定変更で通そうとしてはいけません。lint設定を緩める、対象ファイルを除外する、警告を無視する、といった変更は、品質ラインそのものを下げる行為です。Coding Agentには、基本的に「lint設定ではなく、コードを直して通す」ように指示します。
Hookにlintを組み込む
lintのチェックは、最小構成では、作業依頼の最後に依頼を書くだけでも構いません。一方、品質を高めたい場合は、Hooksを利用し、Coding Agentの実装後に毎回フィードバックを返す仕組みを作ることが推奨されます。人間が毎回「lintを実行して」と思い出さなくても、このループが回るようになると、Coding Agentの出力品質は安定しやすくなります。
Codexでは、Codex Hooksを使うと、Codexのライフサイクル中に決定論的なスクリプトを実行できます。
Claude Codeでは、Claude Code hooks guideとHooksリファレンスに、PostToolUseで編集後にコマンドを実行する例があります。
Hookを使うと、単にlintを実行するだけでなく、品質フィードバックループを作れます。
- 1Coding Agentがコードを書きます。
- 2
PostToolUseなどのタイミングでHookが動き、lint、formatter、typecheck、テストを実行します。 - 3エラーがあれば、その内容をAgentに返します。
- 4Agentが次のアクションでエラーを読み、コードを修正します。
- 5この流れを、ファイル編集のたびに繰り返します。
このとき重要なのは、Hookの実行結果をAgentが読める形で返すことです。特にClaude Codeでは、通常のstdoutに文字列を出すだけでは、修正用の追加コンテキストとして扱われない場合があります。Agentにフィードバックを注入したい場合は、hookSpecificOutput.additionalContextを含むJSONを返すようにします。
OxlintやBiome、Ruff、ast-grepなど、リンターのためのツールはいくつか用意されているので、都度検索をし、最適なものを探してみて下さい。
なお、リンターをカスタムして作る例もあり、OpenAIのCodex開発におけるカスタムリンターの例が以下で公開されています。
Harness engineering: leveraging Codex in an agent-first world
なお、必要に応じてプロジェクト固有のカスタムリンターを作ることもあります。OpenAIのCodex開発に関する記事では、アーキテクチャの依存方向、構造化ログ、命名規則、ファイルサイズなどをカスタムlintや構造テストで機械的に確認している例が紹介されています。標準のlintで見られないチーム固有のルールは、自然言語の注意書きだけでなく、実行できるルールとして表現するとAgentにも伝わりやすくなります。
lintで何が守れるのか
lintはAI Agentの回答品質そのものを評価するものではありません。また、ソフトウェアの不具合をすべて検出できるものでもありません。型の不整合、API連携の失敗、DBとの接続、UIの崩れなどは、それぞれtypecheck、統合テスト、UI確認で見る必要があります。
AI Agentの品質評価では、後の章でoffline evalやonline evalを扱います。ただし、それらを信頼できるものにするためにも、まずは普通のソフトウェアとして壊れていない状態を作る必要があります。AI Agentの精度や回答品質を評価したいのに、その評価の中に「そもそもソフトウェアとして壊れているかどうか」の確認まで混ざっていると、評価サイクルが遅くなります。
そのため、何をどの段階でテスト・評価するのかを切り分けることが重要です。lintで見つけられる問題はlintで軽く自動化し、型で見つけられる問題はtypecheckで確認し、AIの出力品質はoffline evalやonline evalで見る。このように層を分けることで、AI品質評価に入る前のノイズを減らせます。lintは、そのための最も軽く、最も早いフィードバックの一つです。
次の章では、複数のコンポーネントがつながったときに期待どおりに動くかを確認する、統合テストについて見ていきます。