AI時代のエンジニア育成 - 依存ではなく活用を促進するための3つの実践的アプローチ
ここ数ヶ月の間、コーディングエージェントを積極的に活用しており、開発スタイルが大きく変化しました。
この変化は、チーム構成にも大きな影響を与えていると感じています。
特に、ジュニアエンジニアが担当していた、軽微なバグ修正や類似機能の追加などの難易度の低いタスクは、AIにより短時間で実装できるようになりました。
Devinなどの自立型のツールを使用すれば、独立してタスクを進めることも可能です。
それに伴い、Xなどではジュニアエンジニア不要論なども見かけるようになりました。
短期的な生産性だけを考えれば、その主張にも一理あるかなと思います。
しかし、組織の持続的な成長を考えると、育成は依然として不可欠だと感じています。
ただし、AI時代においては、育成の方法も変化させていく必要があります。
そこで今回は、AI時代の育成における課題と、それに対して実際に取り組んでいる具体的な内容について紹介したいと思います!
AI時代にジュニアエンジニアが直面する課題
AIが普及する中で、ジュニアエンジニアが直面する課題がいくつかあると感じています。
成長機会の減少
AIの普及により、事業スケールにおける人員拡大の必要性が薄れました。
以前であれば、ジュニアエンジニアやインターン生を採用し、簡単なタスクを任せるという体制がありました。
人を管理するコストが発生しますが、当時はアウトプットを増やす手段として採用以外の選択肢が限られていたのと、生産性の向上が管理コストを上回っていたため、ジュニアエンジニアを採用・育成するメリットがありました。
しかし、AIが普及した今では、簡単なタスクをAIに任せることで、同様のアウトプットをより安価に、より早く実現できるようになりました。
短期的な視点だけで考えれば、ジュニアエンジニアの採用・育成にコストをかけるよりも、AI活用に注力する方が生産性が向上するため、育成の比重が下がっている企業が多いと感じています。
また、AIの精度が向上したことで、理解が不十分なままでも、ある程度のクオリティのコードを生成できるようになりました。
今までは、コードを見れば、ある程度理解できているかどうかが判断できていたのが、コードだけでは理解度を判断しづらくなりました。
それにより、理解が不十分なことが表面化しにくくなり、レビュー時の学習機会を失っている可能性があります。
学習の質の低下
AIによって学習が効率化された反面、学習の質が低下しているとも思います。
自分の経験を振り返っても、課題に対して、試行錯誤したり考え込んだりした経験は、非常に重要な経験でした。
苦労して身につけた知識や経験は、忘れにくいですし、応用も効きやすいです。
また、その過程は知識だけでなく、課題解決に対するアプローチや学習の仕方を身につける機会にもなりました。
ある程度の負荷により学習が促進されることは、学習科学や心理学の世界で「望ましい困難(desirable difficulties)」として知られています。
AIによって、答えを得やすくなったことで、この「望ましい困難」を経験する機会が減少し、学習内容が定着しにくくなっていると感じています。
また、課題解決のプロセスを経験する機会が減ることで、答えがない問題に直面した際に、太刀打ちできなくなってしまうリスクもあります。
責任感の希薄化
AIに実装を任せることで、「自分が書いたコード」という意識が薄れているのも課題だと感じています。
自分が書いた意識が薄れ、さらに理解が曖昧な箇所があれば、責任感も希薄になります。
キャリアアップするということは、責任の範囲が広がるということです。
責任感が醸成されない状況では、成長が頭打ちになり、常に誰かにフォローしてもらう必要がある状況から抜け出せなくなってしまうと思います。
成長曲線の傾きは、物事をどれだけ自分ごとにできるかに左右されます。
だからこそ、AIを活用しながらも責任感を持って取り組むための姿勢や仕組みが必要だと感じています。
目指すべき育成方針
AIの普及により、エンジニアの2極化が進んでいます。
今後、指示を待って手を動かすだけのエンジニアは、生き延びていくのは難しくなっていくと思います。
しかし、シニアエンジニアは無から生まれるわけでもないですし、誰しも最初はジュニアエンジニアです。
やはり、持続可能な開発のためには、ジュニアエンジニアの育成は必要です。
とはいえ、これからの時代は、AIに依存しすぎても、AIを活用できなくても生き残れません。
目指すべき姿は、AIに依存しない基礎力を身につけつつ、AIを活用するスキルも身につけていくことです。
そのために、AIにより開発スタイルが変化したのと同じように、育成のアプローチも変化させていく必要があります。
AIの依存と活用のバランスを取りながら、自律的な学習を促進するのが、今後の育成の鍵になると考えています。
実践的な取り組み事例
ここからは実際に取り組んでいる育成のアプローチをいくつか紹介します!
learn
コマンド
課題で挙げたように、AIを使うとある程度のコードが書けてしまい、理解が十分かの判断がつきづらいです。
そこで、Claude Codeのカスタムスラッシュコマンドでlearn
コマンドというものを作成して、実装内容の理解度を確認するための仕組みを作りました。
learnコマンド
---
description: "実装内容の理解度チェック"
---
このセッションで実装した内容についてあなたの理解度をチェックし、必要に応じて学習提案を行います。
# 実行フロー
1. **事前準備**: `.claude/learn/[session-name].md`ファイルを生成
2. **実装内容分析**: 実装内容とユーザーの指示・要求内容を総合的に分析
3. **理解度事前評価**: セッション中のやりとりから理解度を評価し、質問生成の必要性を判断
4. **理解度評価**: 理解が不十分な領域や学習意欲のある領域に対してのみ質問を作成、実装者が解答欄に回答後Claudeが評価
# 実行フロー詳細
## 1. 事前準備
- このセッションでの実装内容を把握します。
- `mkdir -p ./.claude/learn` を実行します。
- `./.claude/learn` 内に適切なセッション名でファイルを作成します。
- 例:「GraphQL API実装」→ `./.claude/learn/graphql-api-implementation.md`
- セッション内容を反映した簡潔で分かりやすい名前にします。
## 2. 実装内容分析
まず、このセッションでの実装内容を分析し、以下の観点から動的に質問を生成します:
### 実装内容の分析
- 変更されたファイルとその内容
- ビジネス要件との関連性
### セッション指示内容の分析
実装内容だけでなく、セッション中のユーザーの指示や要求も重要な学習材料として分析します:
- ユーザーが重視した技術的観点
- 実装方針や設計思想に関する指示
- 品質要求やパフォーマンス要件
- コーディング規約や慣習への言及
- 学習目標や理解したい技術領域
- 困っていた点や不明だった概念
- 実装中の判断基準や優先順位
## 3. 理解度事前評価
実装内容とセッション中のやりとりから、ユーザーの理解度を事前評価します。
- **十分な理解を示している領域**: セッション中に適切な判断や実装を行えた技術領域
- **質問や迷いが見られた領域**: セッション中に困っていた点や不明だった概念
**質問生成ルール**:
- 十分な理解を示している領域:質問を生成しない、または簡易な確認質問のみ
- 質問や迷いが見られた領域:重点的に質問を生成
## 4. 理解度評価
実装内容分析と理解度事前評価をもとに、以下の形式で理解度チェックファイルを生成します。
理解度事前評価フェーズで、十分な理解を示している領域は質問を生成しません。
質問数は0~3問を目安にします。
ファイルの作成後、ユーザーが必要な質問の回答を記入し、Claudeが評価を行います。
理解が不十分な可能性がある場合は、追加で深掘りの質問を生成します。
### `[session-name].md` - 理解度チェックファイル
```markdown
# [セッション名]の実装内容 - 理解度チェック
## セッション概要
### 実装した内容
- 実装された機能の一覧
- 変更されたファイルとその役割
### セッション中の理解度評価
- **十分な理解を示した領域**: [具体的な技術領域とその根拠]
- **質問や迷いが見られた領域**: [困っていた点や不明だった概念]
## 理解度チェック質問
#### 質問1
[セッション中の困っていた点に基づく具体的な質問]
#### 質問1への回答
<!-- 実装者がここに回答を記入 -->
#### 質問1の評価結果
<!-- Claude評価結果がここに記載される -->
- **理解度**: [評価、例: 十分理解している、理解できていない可能性がある、理解が不十分]
- **強み**: [具体的な評価コメント]
- **改善点**: [具体的な改善アドバイス]
#### 質問1の学習リソース提案
<!-- この質問に関連する学習提案 -->
- **推奨リソース**: [具体的なリソース]
- **学習手順**: [ステップバイステップ]
- **理由**: [なぜこの学習が必要か]
<!-- 必要に応じて追加の質問をここに記載 -->
## 総合評価
### セッション全体の理解度評価
- **実装内容の理解**: 実装内容をどの程度理解できているか
- **指示内容の評価**: 実装内容を理解して指示を行えているか
- **学習提案**: 次回実装に向けた学習リソースの提案
```
このコマンドは、実装内容とセッション中のやりとりを元に、理解度をチェックするための質問を投げかけ、回答を評価します。
ポイントはコンテキストとして、実装過程のやりとりも含めていることです。
AIのレビューは成果物に対するものになりがちで、プロセスについての評価はあまり行いません。
しかし、人間がレビューする際は、対話を通して実装内容が理解できているかを確認し、理解が不十分な箇所はヒントを提示することができます。
learn
コマンドは、このプロセスを再現するために作成しました。
実装後に/learn
コマンドを実行すると、以下のようなMarkdownファイルが作成されます。
そこに質問が記載されるので、実装者が回答を記入します。
その後、実装者が回答の評価をClaude Codeに依頼することで、理解度の評価と学習リソースの提案がMarkdownファイルに追記されます。
learnコマンド実行例
... 実装のやり取り ...
> /learn is running…
✻ Thinking…
ユーザーが /learn コマンドを実行して、このセッションで実装した内容についての理解度チェックを行いたいということです。
まず、このセッションの内容を分析してみます:
実装内容の分析
1. Clean Architecture に従った TODO 作成機能の実装
- domain/model/todo.go - Todoドメインモデルの作成
- domain/repository/todo.go - TodoRepositoryインターフェースの作成
- usecase/todo.go - TodoServiceインターフェースとCRUD操作の実装
セッション中の指示・要求内容の分析
1. ユーザーの最初の指示: @usecase/todo.go にtodo作成メソッド(Create)を作成してください
2. Clean Architectureに関する質問: データの取得をrepositoryで定義した理由について質問
3. コードレビュー依頼: Deleteメソッドの修正後のレビュー依頼
理解度事前評価
- 十分な理解を示している領域:
- Clean Architectureの原則について質問し、的確な回答を得た
- Deleteメソッドのレビューを求めるなど、コード品質への関心が高い
- 質問や迷いが見られた領域:
- Clean ArchitectureでRepositoryパターンを使う理由について疑問を持っていた
- usecaseでSQL実行することの問題点について理解が必要だった
この分析を基に、理解度チェックファイルを生成します。
⏺ このセッションでの実装内容について理解度チェックを行います。
⏺ Bash(mkdir -p ./.claude/learn)
⎿ (No content)
✻ Thinking…
セッション内容を分析して、適切なファイル名を決定します。このセッションは「Clean ArchitectureでのTODO機能実装」なので、clean-architecture-todo-implementation.md が適切だと思います。
実装内容の分析:
1. Clean Architecture パターンに従ったTODO機能の実装
2. Domain層(model/todo.go, repository/todo.go)の作成
3. UseCase層(usecase/todo.go)の実装
4. CRUD操作の実装
セッション中の理解度分析:
- ユーザーはClean ArchitectureでRepositoryパターンを使う理由について質問しており、この部分に関する理解を深めたいという意図が見られる
- コードレビューを求めるなど、コード品質への関心が高い
- 最初はRepositoryパターンの必要性について疑問を持っていたが、説明後に理解を示している
質問生成方針:
- Clean Architectureの依存関係の原則についての理解度を確認
- Repositoryパターンの利点についての理解度を確認
- 実装したコードの設計判断についての理解度を確認
2-3問程度の質問を生成します。
⏺ Write(.claude/learn/clean-architecture-todo-implementation.md)
⎿ Wrote 83 lines to .claude/learn/clean-architecture-todo-implementation.md
# Clean Architecture TODO機能実装 - 理解度チェック
## セッション概要
### 実装した内容
- **Domain層**:
- `domain/model/todo.go` - Todoエンティティ(ID、タイトル、説明、完了状態、日時)
- `domain/repository/todo.go` - TodoRepository インターフェース(CRUD操作)
- **UseCase層**:
… +73 lines (ctrl+r to expand)
✻ Thinking…
理解度チェックファイルを作成しました。このファイルには:
1. セッション概要:
- 実装した内容の一覧
- セッション中の理解度評価(十分理解した領域と迷いが見られた領域)
2. 理解度チェック質問(3問):
- 質問1: Clean ArchitectureでRepositoryパターンを使う理由(セッション中に質問されたトピック)
- 質問2: UseCaseでバリデーションを行う理由(設計判断の理解度確認)
- 質問3: Deleteメソッドの実装に関する設計判断(レビュー内容の理解度確認)
各質問は、セッション中にユーザーが疑問を持った点や理解を深めたいと思われる領域に焦点を当てています。
ファイルが作成されたので、ユーザーに回答記入と評価依頼の案内をします。
⏺ 理解度チェックファイルを生成しました: .claude/learn/clean-architecture-todo-implementation.md
セッション分析結果
実装内容: Clean Architectureパターンに従ったTODO機能のCRUD操作実装
理解度事前評価:
- ✅ 十分な理解: コード品質への関心、既存パターンの踏襲
- ⚠️ 要確認領域: Repositoryパターンの必要性、依存関係逆転の原則
次のステップ
1. .claude/learn/clean-architecture-todo-implementation.md を開く
2. 3つの質問に回答を記入
3. 記入後、このファイルをClaudeに評価依頼
質問内容:
- Clean ArchitectureでRepositoryパターンを使う理由
- UseCaseでバリデーションを実装する理由
- Deleteメソッドの検証処理の適切な使用場面
目的: セッション中に疑問を持たれたClean Architectureの設計原則について理解度を確認し、必要に応じて学習リソースを提案します。
> 回答しました
⏺ 回答を評価いたします。
⏺ 理解度チェック完了
評価結果サマリー
🔍 全体評価: 基礎レベル
- ✅ 実装スキル: 基本的なCRUD機能は実装できている
- ⚠️ 設計理解: Clean Architectureの原則理解が表面的
- ❌ アーキテクチャ思考: 設計判断の根拠が不明確
重要な学習ポイント
1. 依存関係逆転の原則(DIP): 「コードがスッキリする」ではなく、テスタビリティと技術独立性が本質
2. 層の責任分離: 単なる「事前チェック」ではなく、ビジネスルール vs データ制約の適切な配置
3. 設計判断基準: 技術的制約だけでなく、ビジネス要件に応じた検証レベルの選択
推奨学習順序
1. 📚 Clean Architecture 第11-14章(依存関係逆転)
2. 📚 ドメイン駆動設計 エンティティとバリデーション章
3. 🛠️ 実践: モックを使ったテスト書いてみる
次回実装時は「なぜその設計にするのか」の理由を明確に説明できることを目標にしましょう。
作成されるMarkdownファイルの例
# Clean Architecture TODO機能実装 - 理解度チェック
## セッション概要
### 実装した内容
- **Domain層**:
- `domain/model/todo.go` - Todoエンティティ(ID、タイトル、説明、完了状態、日時)
- `domain/repository/todo.go` - TodoRepository インターフェース(CRUD操作)
- **UseCase層**:
- `usecase/todo.go` - TodoService インターフェースと実装(Create、Get、Update、Delete)
- **実装機能**: TODO作成、取得、更新、削除の基本的なCRUD操作
- **設計パターン**: Clean Architectureの依存関係の原則に従った層分離
### セッション中の理解度評価
- **十分な理解を示した領域**:
- コード品質への関心(Deleteメソッドのレビュー依頼)
- 既存コードパターンの分析と踏襲
- バリデーション、エラーハンドリングの実装
- **質問や迷いが見られた領域**:
- Clean ArchitectureでRepositoryパターンを使用する理由
- UseCaseでSQL直接実行することの問題点
- 依存関係逆転の原則の具体的な利点
## 理解度チェック質問
### 質問1
今回の実装で、なぜTodoServiceがTodoRepositoryインターフェースに依存し、具体的なデータベース実装(PostgreSQLやDatastore)に直接依存しないのでしょうか?この設計の3つの主要な利点を説明してください。
#### 質問1への回答
<!-- 実装者がここに回答を記入 -->
役割が明確になるので、コードがスッキリするから。
#### 質問1の評価結果
- **理解度**: 理解が不十分
- **回答の評価**: 「役割が明確になるので、コードがスッキリする」という回答は表面的で、Clean Architectureの核心的な利点を捉えていません
- **不足している観点**:
- 依存関係逆転の原則(DIP)の理解
- テスタビリティの向上
- 技術的詳細からの独立性
- **改善点**: Clean Architectureの「依存関係の方向」が外側から内側へ向かう原則を理解する必要があります
#### 質問1の学習リソース提案
- **推奨リソース**:
- 「Clean Architecture 達人に学ぶソフトウェアの構造と設計」第11章-14章
- Uncle Bob の「The Dependency Inversion Principle」記事
- **学習手順**:
1. 依存関係逆転の原則(DIP)の概念を学習
2. インターフェースによる抽象化の利点を理解
3. モックを使ったテストの書き方を実践
- **理由**: 表面的なコード整理ではなく、アーキテクチャ原則の本質的な理解が必要
### 質問2
`usecase/todo.go`のCreateメソッドで以下のようなバリデーションを実装しました:
```go
if title == "" {
return nil, failure.New(domain.ErrValidation, failure.Message("title is required"))
}
```
このバリデーションをRepositoryではなくUseCaseで実装した理由は何でしょうか?Clean Architectureの観点から説明してください。
#### 質問2への回答
<!-- 実装者がここに回答を記入 -->
データベースに保存する前にチェックした方が良いから。
#### 質問2の評価結果
- **理解度**: 基本理解はあるが不完全
- **回答の評価**: 「データベースに保存する前にチェック」は正しい方向性ですが、Clean Architectureの層の責任について詳細が不足
- **良い点**: データ保存前のバリデーションの重要性を理解
- **不足している観点**:
- ビジネスルール vs データ制約の区別
- 各層の責任分離
- ドメインロジックの配置場所
- **改善点**: バリデーションの「種類」を理解し、適切な層に配置する判断基準を身につける
#### 質問2の学習リソース提案
- **推奨リソース**:
- 「ドメイン駆動設計」エンティティとバリューオブジェクト章
- Clean Architecture の「ビジネスルール」章
- **学習手順**:
1. ビジネスルール vs データ制約の違いを学習
2. 各層で行うべきバリデーションの種類を整理
3. ドメインモデルでのバリデーション実装パターンを学習
- **理由**: 単なる「事前チェック」ではなく、適切な責任分離による保守性向上のため
### 質問3
Deleteメソッドで削除前の存在確認と削除後の検証を行う実装について「不要」とレビューしましたが、どのような場合であれば、こうした追加の検証処理が適切になると考えますか?具体例を挙げて説明してください。
#### 質問3への回答
<!-- 実装者がここに回答を記入 -->
削除が非同期で行われる場合などで、削除が完了するまでに時間がかかる場合。
#### 質問3の評価結果
- **理解度**: 部分的に正しいが不完全
- **回答の評価**: 「削除が非同期で行われる場合」は適切な観点の一つですが、具体例や他のケースが不足
- **良い点**: 非同期処理での検証の必要性を認識
- **不足している観点**:
- 分散システムでの整合性保証
- 重要なビジネスデータでの確実な削除保証
- 外部システムとの連携が必要な場合
- 監査要件がある場合
- **改善点**: 技術的制約だけでなく、ビジネス要件に応じた判断基準を理解する
#### 質問3の学習リソース提案
- **推奨リソース**:
- 「マイクロサービスアーキテクチャ」分散データ管理章
- 「Designing Data-Intensive Applications」一貫性と合意章
- **学習手順**:
1. 分散システムでの一貫性の課題を学習
2. Eventually Consistent vs Strong Consistency の使い分けを理解
3. ビジネス要件に応じた検証レベルの判断基準を学習
- **理由**: システムの複雑さとビジネス要件に応じた適切な設計判断ができるようになるため
## 総合評価
### セッション全体の理解度評価
- **実装内容の理解**: ⚠️ **基礎的**
- 基本的なCRUD実装は完了できている
- 既存コードパターンの踏襲はできている
- コード品質への関心がある(レビュー依頼)
- **設計原則の理解**: ❌ **不十分**
- Clean Architectureの核心原則(依存関係逆転)の理解が表面的
- 各層の責任分離について概念的理解が不足
- ビジネスロジックとデータ制約の区別ができていない
- **学習提案**:
1. **優先度高**: Clean Architecture の依存関係逆転原則を深く学習
2. **優先度中**: ドメイン駆動設計でのバリデーション責任分離
3. **優先度低**: 分散システムでの一貫性管理(将来の拡張時に重要)
**次回セッションでの改善点**:
- 「なぜその設計にするのか」の理由を具体的に説明できるようになる
- テスト可能性や保守性などの非機能要件を意識した設計判断
- ビジネス要件に応じた適切な抽象化レベルの選択
---
*回答記入後、Claude にこのファイルの評価を依頼してください*
メンバーには出力されたMarkdownファイルをPRに添付してもらっていて、それを元にさらに深掘りが必要かどうかを判断しています。
自分のチームでは、Claude Codeを使用しているので、カスタムスラッシュコマンドとして実装しましたが、他のコーディングエージェントを使用している場合でも、同様の仕組みを作ることは可能だと思います。
No AI Day
AIに依存しない基礎力を身につけることを目的として、隔週に1日、AIツールを一切使わずにコーディングする日を設けています。
特に、コードリーディングやデバッグなど、AIに依存しがちなスキルを鍛えることを意識しています。
最初は生産性が大幅に落ちるのではないかと心配でしたが、実際にやってみると、思ったほど生産性は変わりませんでした。
これは個人的にも大きな気づきで、AIを使っている時も生成したコードの理解や修正に時間がかかっていて、AIを活用しきれていない部分があったのだと思います。
AIを活用することで、生産性を向上させるためには、一定の基礎力が必要ということを再認識できました。
この取り組みは始めたばかりなのですが、様子を見ながらAIを使用しない日を増やすことも検討しています。
より経験が浅いエンジニアほど、AIを使わない割合を増やすのが良いのではないかと考えています。
ペアプロ
AIが普及した今でも、ペアプロの価値は変わらないと感じています。
ペアプロを通じて、答えの提示ではなく、思考の言語化をサポートすることを意識しています。
ここが人間同士ならではの強みだと思います。
AIを使えば、答えを瞬時に得られるところを、「なぜそう考えたのか」「どういう観点で判断したのか」といった質問を通じて、自力で答えにたどり着く力を養うことができます。
また、AIを使うタイミングの判断や使い方もこれからの時代は重要なスキルです。
それらを共有する場としても、ペアプロは有効だと感じています。
最近はChatGPTのStudy ModeやClaude CodeのLearning Modeなども登場してきているので、ペアプロの代替としてそれらを活用するのも良いと思います。
まとめ
今回はAI時代における育成の課題とアプローチについて紹介しました!
これからの時代は、育成のフローにもAIを取り入れながら、依存と活用のバランスを取りつつ、自律的な学習を促進していくことが重要になると思います。
今回紹介した内容は、育成する側の視点で書きましたが、育成される側でも自分で取り込める部分はあると思うので、ぜひ参考にしてもらえれば嬉しいです!
Discussion