Disclaimer
このエントリは筆者個人の感想文であり、所属組織の公式見解とは1ミリも関係ありません。「お前のエントリ、会社の意見だと思われるぞ」と言われる危険があるので、「違います、あれは僕個人の魂の叫びです」と答えるためにこのDisclaimerを書きました。
さらに重要な注意事項として、本文中に頻出する「お前」という二人称は、画面の前のあなた個人を指しているわけではありません。これは一般論としての架空の人物、つまり「生成AIに曖昧な指示を出しがちな人」や「生成AIを魔法の杖のように考え、何も言わなくても完璧な成果物が出てくると期待している人」といった、我々人類の総体としての象徴的存在を指しています。したがって、この「お前」はあなたではありません。谷沢です。胸を張って読み飛ばしてください。
ただし、もし心当たりがあるなら、その「お前」はあなたかもしれません。そして僕自身でもあります。我々は言語化という修行の途上にいる同志です。いっしょに頑張りましょう。
はじめに
最近、コーディングエージェントにコードを書かせる光景がすっかり日常になりました。しかし「いい感じのコードが出てこないから、生成AIはまだ使えない」という声を聞いたりします。わかります。わかりますよ。そうですね。その通りですね。
でもさ、その「いい感じ」が何を意味するのか、お前ちゃんと言語化できてるんですか?
お前の言ういいコードって何ですか?良い設計って何ですか?お前の言う「いい成果物」とかいうやつをさ、頼むからさ、屏風から出してくださいよ。
お前は普段、チームメンバーに指示を出すとき「いい感じにやっといて」と言ってますか?レビューで「いい感じにしろ」という曖昧模糊としたフィードバックをしてますか?
違いますよね。お前の頭の中にある「いい感じ」を言語化して、具体的に伝えているはずです。それは生成AIに対しても同じことなんです。ちゃんとしてください。雰囲気でわからせようとしないでください。お前がこれまで言語化せずに、「普通わかるだろ」とかいう雰囲気で乗り切ってきたツケを払うのが、この大生成AI時代なんです。
メンバーの力だって生成AIの力だって、お前のプロンプトとフィードバックによって引き出されるんです。お前が「いい感じ」とは何かを理解しないと、お前が言語化しないと、良い成果物は得られません。屏風の虎は屏風から出てこないんです。
生成AIとの相互作用はマネジメントそのものである
baigieの記事を読んで、僕は膝を打ちました。
AIとの相互作用は本質的に人間関係のマネジメントと同じプロセスだという指摘です。生成AIは統計的パターンから「次に来るべき最も確からしい言葉」を推測し続けるわけですが、この推測過程って相手の思考を想像する行為そのものじゃないですか。
ここでピーター・ドラッカー先生の教えを借りるなら、マネジメントには三つの要素があります。
- 目標設定
- 資源の最適な組織化
- 評価とフィードバック
さて、コーディングエージェントに対して、お前は目標を明確に設定できていますか。生成されたコードに対して、具体的で建設的なフィードバックを提供できていますか。できていないなら、それはお前のマネジメント力の問題です。生成AIの問題ではありません。たぶんお前が悪い。
フィードバックを具体化する第一歩としてのサイクロマティック複雑度
では、具体的なフィードバックとは何でしょうか。リファクタリングのフィードバックを例に考えてみます。
よく聞く話があります。「コードが読み解けなくて新規機能の追加に時間がかかる」「どこをどう修正すれば良いかわからない」「リファクタリングで解決したい」。わかります。わかりますよ。でもちょっと待ってください。その「リファクタリング」って具体的に何をすることですか。
コードを「きれいに」する?「わかりやすく」する?「保守しやすく」する?それ、全部「いい感じ」と同じ問題を抱えています。お前の頭の中にある理想の状態が言語化されていません。生成AIに「このコードをリファクタリングして」と指示して、何が返ってくると期待していますか。生成AIは困惑しています。お前が何を求めているのかわからないからです。
ここで役立つのが、測定可能な指標です。最も基本的な指標の一つがCyclomatic Complexity Number(CCN、循環的複雑度)です。これはコードの複雑さを定量的に測る指標で、簡単に言えば「コードの中に分岐や繰り返しがどれだけあるか」を数値化したものです。
例えば、お前が生成AIに「このメソッドをリファクタリングして」と指示したとしましょう。生成AIは何をもって「良いリファクタリング」とするのでしょうか。わかりません。お前が教えていないからです。でもCCNを使えば「CCNを10以下にしてリファクタリングして」という具体的な指示になります。これは曖昧さのない、測定可能な目標です。
CCNが高いコードは条件分岐が多く、テストケースも増え、バグの温床になりやすいです。だからCCNを下げることは保守性の高いコードへの第一歩となります。お前がこれを言語化できれば、生成AIは具体的な改善の方向性を持てます。
ちなみに、CCNを実際に測定するツールとしてLizardがあります。
Pythonで書かれた軽量なツールで、多くのプログラミング言語に対応しています。
使い方も簡単で、ファイルやディレクトリを指定するだけです。
uv run --frozen lizard src/vtt2minutes tests --CCN 10
こうすると、各関数のCCNが表示されます。「このメソッドのCCNが15だから、10以下にリファクタリングして」という具体的な指示が可能になります。お前の「いい感じ」が数値化される瞬間です。
しかし、CCNだけでは不十分です。世の中そんなに甘くありません。
CCNの限界と類似度による補完
CCNは制御フローの複雑さを測りますが、コードの構造的な重複や類似性は測れません。同じようなロジックが複数箇所に散らばっていても、CCNは何も教えてくれません。冷たいやつです。
ここで登場するのが類似度の概念です。
具体的なツールとしてsimilarityがあります。TypeScriptなどとともにPythonもBetaとしてサポートしています。
使い方の例として、ディレクトリ全体の類似度を分析できます。
similarity-py src/vtt2minutes/ --threshold 0.8 --min-lines 10 --print
実際の出力例を見てみましょう。
Analyzing Python code similarity...
=== Function Similarity ===
Checking 9 files for duplicates...
Duplicates in src/vtt2minutes/bedrock.py:
------------------------------------------------------------
src/vtt2minutes/bedrock.py:261-300 method _validate_bedrock_access <->
src/vtt2minutes/bedrock.py:536-571 method get_available_models
Similarity: 80.61%
Classes: BedrockMeetingMinutesGenerator <-> BedrockMeetingMinutesGenerator
--- src/vtt2minutes/bedrock.py:_validate_bedrock_access (lines 261-300) ---
def _validate_bedrock_access(self) -> None:
"""Validate that we can access Bedrock with the current credentials.
Raises:
BedrockError: If credentials or region are invalid
"""
try:
# Create client configuration for bedrock service
同じファイル内の2つのメソッドの類似が検出されました。リファクタリングの候補です。こういう具体的な情報があれば、「類似度0.8以上のコード片を見つけて共通化して」という具体的な指示が可能になります。
生成AIに「CCNを10以下にして、かつ類似度0.8以上のコード片を共通化してリファクタリングして」と指示すれば、どうでしょうか。これは具体的で、測定可能で、達成可能な目標です。生成AIはこの明確な基準に基づいて、お前が期待する「いい感じ」のコードを生成できる可能性が格段に上がります。もう「いい感じ」じゃなくて「CCN 10以下で類似度0.8以上のコード片を共通化した感じ」のコードですけどね。
具体例: プロジェクトのコーディング基準として言語化する
では、実際にどう言語化するのか。僕のプロジェクトでは、Claude Code向けにCLAUDE.mdというファイルを作って、コード品質の基準を明文化しています。その一部を紹介します。
## コード品質
- 全てのコードに型ヒントを必須とする
- 公開APIには必ずdocstringを記載する
- 関数は集中的かつ小さく保つ
- 既存のパターンに厳密に従う
- 行の長さ: 最大88文字
- **循環的複雑度**: 関数あたりCCN最大10
- チェック方法: `uv run lizard src/vtt2minutes --CCN 10`
- CCNが10を超える関数は、より小さな関数にリファクタリングする
- CIが自動的に複雑度を監視し、CCN > 10でビルドを失敗させる
- **コード類似度**: コードの重複を監視し削減する
- チェック方法: `./scripts/check-similarity.sh`
- 目標: 保守性のため関数の類似度を80%未満に保つ
- 詳細分析には `./scripts/check-similarity.sh -t 0.8 -p` を使用
- 共通パターンは共有ユーティリティ関数に抽出する
- 類似度が85%を超える関数はリファクタリングの候補として検討する
これを設定しておくと、生成AIに単に「リファクタリングして」と指示するだけで、次のような具体的なレポートが返ってくるようになります。
● 現在のコードベースの状態を確認しました。以下の問題点が見つかりました:
1. 循環複雑度 (CCN): すべての関数がCCN 10以下で、基準を満たしています ✓
2. コード類似度: cli.py、batch.py、bedrock.pyで多数の高い類似度(70-95%)の
関数ペアが検出されました
3. テストカバレッジ: 全体で91.06%ですが、いくつかのファイルが85%を下回っています:
- batch.py: 87.00% (目標85%以上 ✓)
- その他のファイルも基準を満たしています
主な問題はコードの重複です。特にcli.pyは非常に多くの重複があります。
リファクタリング計画を立てます。
見てください。お前の「いい感じ」が、測定可能な基準として言語化された瞬間です。CCN 10以下、類似度80%未満、カバレッジ85%以上。これらは全て測定可能で、達成可能で、具体的な目標です。生成AIはこの基準に基づいて、お前が本当に求めているリファクタリングを実行できます。
僕自身、この基準を明文化してからようやく、生成AIとまともにコミュニケーションが取れるようになりました。それまでは「なんか違うんだよな」を繰り返していたわけです。恥ずかしい話ですが、僕も言語化できていなかったんです。
お前の「いい感じ」を言語化する訓練
ここまで読んで、「そんな細かいこと、いちいち指示するのか」と思った人もいるかもしれません。はい、するんです。それこそがマネジメントです。
新人エンジニアに対して、お前は「いい感じにやっといて」と丸投げしますか。しませんよね。お前の中にある「いい感じ」の基準を、できるだけ具体的に伝えようとするはずです。それは測定可能な指標に落とし込み、相手が理解できる言葉で説明する訓練の積み重ねです。
生成AIに対しても同じことが必要になります。いや、むしろ生成AIの方が、お前の曖昧な指示をそのまま受け取る分、より具体的な指示が求められます。人間なら「あ、これ多分こういう意味だな」と忖度してくれますが、生成AIは忖度しません。お前の指示を額面通りに受け取ります。
定量指標がない場合はどうするか
ここまでCCNや類似度といった定量指標の話をしてきましたが、正直に言います。全てが数値化できるわけではありません。「コードの可読性」「適切な抽象化」「設計の良さ」。これらを数値化しろと言われても困りますよね。わかります。わかりますよ。
じゃあどうするのか。「いい感じ」に戻るのか。違います。数値化できなくても、言語化しよう。がんばろう。
そして、ソフトウェアエンジニアリングには既に、そのための語彙が用意されています。
ソフトウェアエンジニアリングの語彙を使え
例えば「良い設計のコードにして」という曖昧な指示。これ、生成AIに何をしろって言ってるんですか。わかりません。でも、たとえばこうやって書く。
設計原則で言語化する
- ❌ 「良い設計のコードにして」
- ✅ 「単一責任原則(SRP)に従い、1つのクラスは1つの責務のみを持つこと」
- ✅ 「依存性逆転の原則(DIP)に従い、具象ではなく抽象に依存すること」
- ✅ 「インターフェース分離の原則(ISP)に従い、使わないメソッドへの依存を作らないこと」
命名規則で言語化する
- ❌ 「適切な名前をつけて」
- ✅ 「ブール値には is/has/should などの述語形式を使うこと」
- ✅ 「ファクトリメソッドには create/build を使うこと」
- ✅ 「ユビキタス言語に従い、ドメインの用語を使うこと」
SOLID原則やDDDの用語を使うだけで、「いい感じ」が消滅しました。生成AIに「良い設計にして」と言うのではなく、「単一責任原則に従って」と指示できます。これらの原則は既に確立された語彙なので、生成AIも正確に理解できます。お前の「いい感じ」より、よっぽど明確です。
ただし、ここに落とし穴がある
ここまで読んで、「じゃあSOLID原則って言えばいいのか、簡単だな」と思った人。甘いです。
SOLID原則を指示するということは、お前がSOLID原則を理解している必要があります。単一責任原則が何を意味するのか、依存性逆転の原則がどういう設計をもたらすのか。お前が理解していないものを、生成AIに指示できるわけがありません。レビューするのお前だし。
つまり、生成AIにコーディングを任せる時代になっても、いや、任せる時代だからこそ、お前はその領域について理解と洞察を持つ必要があります。お前が「単一責任原則に従って」と言える理解を持っていなければ、生成AIは「いい感じ」という曖昧な指示のまま、お前の期待とは違うコードを生成し続けます。
生成AIは、お前の理解不足を補ってはくれません。お前の理解を増幅するだけです。お前が浅ければ、生成されるコードも浅い。お前が深ければ、生成されるコードも深い。
「生成AIがあれば学ばなくていい」と思った人、残念ですが逆です。生成AIを使いこなすために、お前は学び続ける必要があります。SOLID原則、デザインパターン、アーキテクチャパターン。これらを理解していなければ、お前は生成AIに具体的な指示を出せません。生成AIがコードを書く時代だからこそ、お前はソフトウェアエンジニアリングを学ぶ必要があります。
皮肉なことに、生成AIの登場によって、人類はより深く学ぶ必要性に迫られています。コードを書くだけなら生成AIに任せられますが、「何を作るべきか」「どう設計すべきか」を言語化するのは、依然として人間の仕事です。そして、その言語化には深い理解が必要です。
数値化できない基準でも、諦める必要はありません。ソフトウェアエンジニアリングの確立された語彙を使うか、既存コードを参照するか。どちらも有効な言語化の方法です。ただし、それにはお前自身が学び続け、理解を深めることが前提条件です。
baigieの記事では、日々の業務で試せるアプローチとして、「指示の言語化訓練」と「チーム内での指示方法の議論」を推奨しています。これは生成AIを使う上でも有効です。言語化の訓練は、人間に対するマネジメントスキルも、生成AIに対する指示スキルも、同時に向上させます。逆に言えば、生成AIに曖昧な指示しか出せないということは、人間に対しても曖昧な指示を出している可能性があります。生成AIは、僕たちのコミュニケーション能力を映す鏡です。自己点検のチャンスです。
権限委譲からプロジェクト全体へ
さらに踏み込むなら、単なる「作業分担」から「権限委譲」へシフトする視点も重要です。生成AIに「この関数をリファクタリングして」と個別のタスクを依頼するのではなく、「このモジュール全体の保守性を向上させるプロジェクトを設計して実行して」とプロジェクト単位で任せるわけです。
そのためには、お前がプロジェクトのゴールを明確に定義し、評価基準を設定し、途中経過でフィードバックを提供する必要があります。これはまさにマネジメントそのものです。お前がやっているのはコーディングエージェントへの指示ではなく、プロジェクトマネジメントです。肩書が「エンジニア」から「マネージャー」に変わる瞬間です。
まとめ
安西先生──いつかの先生の言葉が近ごろ、よく頭にうかびます。
「お前のために生成AIがあるんじゃねぇ。生成AIのためにお前がいるんだ」
ここでは誰も僕に完璧な成果物をくれません。曖昧な指示で生成AIに迷惑をかけておきながら、今おめおめと「AIはまだ使えない」と言うわけにはいきません。いつか僕の具体的な指示でAIに借りを返せるようになるまで、言語化の訓練を頑張るつもりです。
生成AIの国──その空気を吸うだけで僕は良い成果物が作れると思っていたのかなぁ…