はじめに

こんにちは。and factory で新卒2年目のサーバーサイドエンジニアをしている松ヶ浦です。

新卒2年目ですが、いまはもう、自分でコードをほとんど書いていません。エディタも「書く道具」というより「読む道具」になりました。

ただ、最初からそうだったわけではありません。大学1年の頃は、VS Codeで普通に手書きでコードを書いていました。

きっかけは大学2年で触れたGitHub Copilotでした。そこからAIに任せる比重は増え続け、4年の卒業研究では、VS Codeの拡張機能をほとんどvibe codingで作りました。入社後もこの流れは止まらず、Claude Codeを使うようになった頃には、自分でエディタにコードを打ち込むことはほとんどなくなっていました。

手書きでまともなプロダクトを作った経験はないので、「コーディング力がついた」という実感はもともとありません。

この記事で言いたいことは、2つです。

  • 新卒の仕事は、「コードを書くこと」から「判断と段取り」に移った。
  • そのうえで厄介なのは、AIが、自分の理解できていないことまで隠してしまうこと。だから僕は、実装に入る前の見積もりで理解を詰め切ることに時間を使っている。

以下では、1つのタスクを概念からPRまでどう進めているかを、実際の流れに沿って書きます。まずは全体像です。各ステップで「人(僕)が握る」か「AIに逃がす」かも併記しました。

flowchart TB
    A["① タスク受領 〔人〕<br/>何をする機能かを言語化し<br/>設計の方向性を固める"]
    B["② 見積もり 〔人主体 + AI〕<br/>実装より先に理解を詰め切る<br/>Devin = 一次調査 / Claude Code = 厳密調査"]
    C["③ 実装 〔AI主体〕<br/>Claude Code が実装<br/>Plan は人が確認"]
    D["④ PR前確認 〔人〕<br/>コードを読んで検証する"]
    E["⑤ 動作確認 〔AI + 人〕<br/>自作 skill で実行し手でも触る"]
    F["⑥ PR提出 〔AI〕<br/>push 〜 PR作成 / Draft は人が Open"]
    A --> B --> C --> D --> E --> F

この図のとおり、コードを書く部分はAIに任せ、僕は「理解」「確認」「判断」に回ります。それでは、各ステップを順に見ていきます。

① タスクを受け取る:まず「何をする機能か」を言語化する

タスクは自分起点ではなく、振られることがほとんどです。受け取ったらまず、自分用のNotionタスクDBに登録して、「なぜこのタスクをやるのか」「この機能は結局、何をするものなのか」を自分の言葉で書きます。

これは記録のためというより、設計の方向性を最初に固めるためです。機能の目的を言語化しないまま手を動かすと、見当違いの設計に進んでしまうことがあります。逆に、背景を書こうとすると、自分がこの機能をどこまで理解できているか、どこが曖昧なのかがはっきりします。曖昧なまま残った部分は、次の見積もりで詰める宿題になります。

② 見積もり:実装より先に「理解」を終わらせる

僕の開発で一番時間がかかるのは、コーディングではなく調査と仕様確認です。逆に言えば、ここさえ終われば実装はAIに流すだけです。そのため見積もりの段階で、「あとはAIに実行させるだけ」のところまでPlanを詰めます。

ここを徹底するようになったのは、1年目の失敗があったからです。

あるサービスの管理画面で、サブクエリが複数走る少し複雑な集計APIを担当しました。当時の僕はドメイン知識が足りておらず、仕様書をよく理解しないまま、AIの提案を鵜呑みにして実装を進めました。結果、レビューで大量の指摘をもらい、ほとんど丸ごと書き直しになりました。

このとき問題だと感じたのは、「AIは間違える」ことではありません。理解していない自分でも、動くコードを完成させてPRまで出せてしまったことです。自分の手で書いていた頃なら、ドメインや仕様を理解していなければ、そもそも手が止まっていたはずです。書けないという事実が、まだ理解できていないことを教えてくれる。理解の足りなさには、ちゃんと摩擦がありました。

ところがAIを使うと、その摩擦が消えます。理解していなくても、それらしいコードが出てくる。仕様書に抜けがあっても、AIがそれっぽく埋めて完成させてしまう。結果として、自分が理解できていないことが、自分からも見えなくなります。これは、ドメイン知識をすでに持っている人がAIを使うのとは少し違う難しさで、知識の土台がまだない新卒のほうが起きやすいのではないかと思っています。

だから見積もりでは、実装の前に理解を詰め切ります。見積もりで詰まる部分が、まだ理解できていない場所です。ここで潰しておけば、理解しないまま実装が完成してしまう事態を避けられます。

調査はDevinとClaude Codeを使い分けています。判断基準は「速さが欲しいか、厳密さが欲しいか」です。

用途使うもの理由
一次調査・当たりをつける(複数リポジトリ横断)Devin (Ask)レスポンスが速く、多少間違っていてもすぐには困らない
厳密な調査・結果をドキュメントに残すClaude Code腰を据えた調査と、そのまま実装に使える出力

Devinは、答えが多少ずれていてもすぐには困らない、軽い確認に使います。たとえば、テスト仕様書が実装と乖離していないかをサッと確かめたいときに向いています。仕様書に書かれている状態ラベルが実装に本当に存在するステータスなのか、といった質問を投げると、複数リポジトリにまたがっていても数秒で返ってきます。

一方、腰を据えた調査が要るときは、Claude Codeを使います。実装の下準備として、調査結果をドキュメントに残したいときにも向いています。たとえば、こんな指示を出します。

1
2
3
4
対象の仕様を理解して、実装に必要な情報を集めて。
逆に、仕様に足りていない情報もまとめて。
あくまで調査なので、実装はしないこと。
結果はmdファイルに出して。

調査だけさせて、実装はさせません。出てきたmdは、そのまま実装時のインプットになります。この時点で実装の8割は決まっているので、見積もりの精度も上がります。

③ 実装:Claude Codeに任せ、僕は「読む」に回る

実装は基本的にClaude Codeに任せ、自分でエディタを叩くことはほとんどありません。

VS CodeやCursorを使っていましたが、Agentic Codingに移行するにつれて、作業の比重が「書く」から「読む」に移りました。書く快適さより、読むときの軽快さが欲しくなったので、Rust製で軽量なZedに乗り換えました。

流れはこうです。

  1. 見積もり時の調査をもとに、具体的なPlanを立てさせる(もう詰まっているので速い)
  2. Planは必ずmarkdownで確認する
  3. 実装させる(見積もりで詰めてあるので、想定外がなければすぐ終わる)

2のPlan確認には、ちょっとした工夫があります。Claude Codeのチャット上だとPlanが流れて読みづらいので、Planが確定したタイミングでmarkdownビューワー(Arto)が自動で開くようHooksを設定しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
"PreToolUse": [
  {
    "matcher": "ExitPlanMode",
    "hooks": [
      {
        "type": "command",
        "command": "arto \"$(ls -t ~/.claude/plans/*.md | head -1)\"",
        "timeout": 5
      }
    ]
  }
]

ExitPlanMode(Planモードを抜ける、つまりPlanが固まる瞬間)をフックして、最新のPlanファイルをArtoで開くだけです。たったこれだけですが、Planを腰を据えて読む習慣がつきました。なお、Planの保存先はデフォルトで ~/.claude/plans です。settings.jsonplansDirectory で変更している場合は、自分の保存先に合わせてパスを調整してください。

コードを書かなくなって、実力は落ちないのか

落ちると思います。ここに対する明確な答えは、まだ持てていません。

では、CS(コンピュータサイエンス)を学ぶ意味はないのか。一瞬そう思いましたが、そうとも言い切れません。

「AIの誤りを見極める力が要る」と言いたいところですが、技術選定はむしろAIが得意な領域です。「何を使うべき?」と聞けば、そこらの2年目より妥当な答えを返してきます。選ぶために詳細を知る必要はない、と言われれば、その通りです。

そこで残るのは、こういう形です。詳細が要るのは「選ぶ」ためではなく、AIの選択が間違っているときに、間違っていると気づいて棄却するためです。

ただ、2年目の僕は、AIの誤りを一人では棄却しきれません。1年目の集計APIがまさにそうでした。CSの知識は気づける確率を少し上げてくれますが、それだけでは足りません。

だから僕は、自分の判断を信用しないことにしました。判断を、人と仕組みに逃がす。ただし、ここで言う「逃がす」は「放り投げる」とは違います。1年目の集計APIは、分からないからAIの出力をそのまま受け取った、ただの放り投げでした。いま僕がやっているのは、分かる範囲で「何を確認し、誰に何を聞くか」を狙って渡すことです。問いを立てたり、確認する対象を指したりするには、結局そのドメインを読める程度の素養が要ります。CSは、自分でコードを書くためではなく、AIを監督するための読み書き能力として効いてきます。

④ PR提出前の確認:ここで初めて「読む道具」としてエディタを使う

実装が終わったら、変な実装になっていないかを自分の目で確認します。コードを細かく追うのはこの段階です。ジャンプや差分など、エディタの機能を使うのもこのタイミングです。普段はコードを書くために使っていない分、ここでは「読む・検証する道具」として使います。

⑤ 動作確認:lint・testとは別に、実際にAPIを動かす

自動テストやlintとは別に、実際にAPIを叩いて挙動を確認します。これは自作のskillでやっていて、Docker起動 → テストデータ用意 → API実行までを一通り流してくれます。毎回手で環境を立ててデータを用意するのは面倒なので、そこを固めておくと動作確認のハードルが下がります。

それとあわせて、自分でも手で触って確認します。skillで一通り通っていても、一応こちらで動作を保証してから出す、という感覚です。

⑥ PR提出:複数リポジトリにまたがるからAIが効く

確認してOKなら、PushからPR作成までClaude Codeにやってもらいます。参加しているプロジェクトはモジュラーモノリスです。1つの変更で複数リポジトリに同時にPRを出すことがよくあります。これを手でやると地味に時間が溶けるので、ここはAIの恩恵が大きい部分です。

PRはまずDraftで出します。改めて内容を軽く確認し、CIが通っていて問題なさそうならOpenにします。

AIに任せて、僕がやっていること

ここまで読むと「ほぼ全部AIじゃないか」と思うはずです。その通りです。だから最後に、僕が手放さずにやっていることを書きます。

ひとつだけ、徹底していることがあります。AIに「何をすればいい?」と聞いたら、必ず「なぜそれをするのか」まで聞く。

答えが欲しいわけではありません。前述のとおり、今の僕は自分の判断をまだ信用していません。でも、なぜを聞き続けないと、いつまでも信用できるようになりません。判断の基準を自分の中に少しずつ積むために、理由を集めているような感覚です。

そのうえで、いくつか自分ルールがあります。

  • 判断は自分で抱え込まない。でも、自分の考え(仮説)は必ず持ってから相談する。メンターに頼り切ると、判断力が育たない。
  • 詰まったら、長くても2時間で相談する。自分で考え続けるより、仕事を前に進める方が大事だと割り切る。
  • 相談するときは、「何をしていて」「何が分かっていなくて」「何に迷っているか」を伝える。脳内を整理するために、話すことを全部メモしてから相談に行く。

2週に1度、フローごと見直す

ここまで書いたフローは、最初から完成していたわけではありません。2週に1度、メンターとKPT(Keep/Problem/Try)で振り返り、失敗を1つずつ潰しながら作り直してきた結果です。1年目の集計APIの失敗も、鵜呑みでやり直した経験も、相談が下手だった反省も、全部この振り返りの中で「次からこうする」に変えてきました。フロー自体が、振り返りの産物です。

まとめ:手書き世代として、手放したものと握り続けるもの

手書きで覚えた世代として、僕はもう、自分でコードを書くこともエディタを叩くことも、ほとんど手放しました。前に書いたとおり、コーディング力は落ちると思います。

それでも、握り続けたいものがあります。ビジネスと実装の仲買人としての役割です。仕様の決定権はディレクターが持つとしても、その決定を技術的に成立させ、ビジネスの要求と実装の現実を訳す仕事は、エンジニアにしかできません。そして、両方の言語を話せなければ、仲買はできません。

だから僕にとってCSは、コードを書くためではなく、訳すうえで要るものへと変わりました。手書きで覚えた世代が最後に握っておくべきなのは、たぶんそれです。