1
1

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
Posted at

月曜の朝七時。コーヒーがまだ熱くて、Slackの未読が冷めている時間帯。この記事は、そういう時間に読めるよう置いておく。通勤電車のなかで、隣の人の肩越しに盗み見されても恥ずかしくない程度の、現場の話だ。

最初に白状しておく。私はコードを書けないスクラムマスターだった。「だった」と過去形にできたのは、ここ数週間の出来事のおかげで、その肩書きが少しだけ嘘になったからにすぎない。

速いチームほど、何も残らない

ここ一年、チームは速くなった。AIに下書きを投げ、テスト設計のたたき台を吐かせ、レビューの観点まで先回りさせる。ベロシティのグラフは右肩上がり。経営に見せると、みんな満足そうにうなずく。

ところが、だ。スプリントレビューのたびに、私の胃の底に小石が一つずつ溜まっていった。速くなったのに、組織サーベイの成長指標は、良くなるどころか芳しくない方向へまっしぐら。タスクは溶けるように消えていくのに、消えたあとに手触りが残らない。畑は耕されているのに、収穫の話を誰もしない。

速さは、効きの早い鎮痛剤。痛みは黙るが、患部はそのまま残っている。効いている間は、誰も病院に行こうとしない。研究開発という畑に、気づけばそれなりの年輪を重ねていた身。速さの正体が「学びの副産物」でしかないことくらい、何度か痛い目を見れば、嫌でも体で覚える。速さそのものを目的に据えた瞬間、チームは"消費"を始める。自分の在庫の知識を切り崩し、それを「こなした」と呼ぶ。新しい引き出しは、一つも増えていない。

あるスプリントのふりかえりで、一人のメンバーがぽつりと言った。「自分の知識の中でタスクを消化してしまって、あまり成長を実感できなかった」と。声には、本気で困っている色がにじんでいた。その声を聞いて、私は決めた。成長を、目に見える場所に引きずり出す。畑のなかで何が芽吹いたのかを、本人にも、隣の席にも、経営にも、嫌でも見えるようにする。

なぜ「草」だったのか

可視化、と口で言うのは簡単。難しいのは、それが"裁きの道具"に化けないようにすることだ。スキルの一覧を作って点数をつければ、それは静かに人事評価の影武者になる。誰かが誰かと比べられ、低い数字をつけられた人間は、二度と本音を書かなくなる。心理的安全性という言葉は、こうして死ぬ。

私が欲しかったのは、通知簿ではなかった。GitHubの、あの草だ。コミットを重ねると緑が濃くなる、あの罪のないマス目。あれは順位をつけない。隣の誰かと比べさせない。ただ「今日、手を動かしたね」と肯定するだけの、無口な相棒。あの思想を、スプリントの学びに移植したかった。

縦にスキルのカテゴリ、横にスプリント。そのスプリントで「塗りが動いた」と手を挙げた人数だけ、マスが緑に染まる。多ければ濃い緑。ゼロなら灰色のまま、けれど責めない。森が育つのを、全員で同じ画面から眺める。それだけ。

問題は、それを作る人間が、私だったことにある。

コードを書けない男が、コードを書いた

正直に言う。私のJavaScriptは、十年前にコピペで止まっている。varlet の宗派対立に、いまだに肩身が狭い。だが今は、隣に壁打ち相手がいる。Claude Coworkに向かって、私はこう投げた。「カテゴリごとにGitHubの草を生やすみたいに、各スプリントの成長を可視化したい」。

返ってきたのは、説教ではなく、たたき台だった。これがAIと組む醍醐味で、こちらの語彙が幼くても、向こうは"意図"を拾ってくる。仕様書を書けない発注者の、頭の中の落書きを、動くHTMLに翻訳してくれる。他人の書いた原稿用紙のマス目を、こちらの言葉で埋め直してくれる相棒、とでも言えばいいか。

草の濃さを決めるロジックは、拍子抜けするほど短い。

// そのスプリントで「伸びた」と手を挙げた人数を数える
function grewCount(sprint, cat) {
  return sprint.members.filter(m => (m.grew || []).includes(cat)).length;
}

// 人数を 0〜4 の濃さに丸める(GitHubの草と同じ5段階)
function level(n) {
  return n <= 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n === 3 ? 3 : 4;
}

たったこれだけで、灰色の地面に緑が点り始める。データさえあれば、可視化の本体は驚くほど痩せている。肥えているのは、データを集める仕組みと、人の言葉を機械が読み解くところ。後者で、私は一度、派手に転ぶことになる。それは後の章で。

データの入り口は、ふりかえりの最後に九十秒で答えるGoogleフォームにした。設問は欲張らない。「成長を感じたか」「学ぶ時間を取れたか」「このペースは持続できるか」を五段階で。それから、伸びたカテゴリにチェック。最後に、自由記述で「次に伸ばしたい一つ」を書いてもらう。この"自由記述"が、後で私の足を派手にすくう。気づいた読者は、勘がいい。

全員の画面に、同じ草を

初心者が必ず踏む地雷の在り処は、幸い、踏む前に見えていた。

完成したHTMLファイルを得意げにチームへ配って終わり、にはしなかった。HTMLを配るだけでは、入力したデータが各自のブラウザ(localStorage)のなかにしか残らない。五人に配れば、中身の違う五つの畑が別々にできあがる。隣の人が何を育てたかは、誰の画面にも映らない。そうなる前に、設計を一段ずらしておく。データは、一か所に集めてからでないと意味を持たない。

そこで Google Apps Script の出番。フォームの回答を読み、草マップが食べられる形のJSONに変換し、画面そのものもAppsScriptから配信する。一つのURLを開けば、全員が同じ最新の畑を見る。サーバー側でデータを画面に流し込むので、誰のブラウザでも結果は同じ。

function doGet(e) {
  // 画面(HTML)を返す。データはサーバ側で埋め込む
  const tmpl = HtmlService.createTemplateFromFile('grass');
  tmpl.dataJson = JSON.stringify(buildGrassJson_()).replace(/</g, '\\u003c');
  return tmpl.evaluate()
    .setTitle('成長の草マップ')
    .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

URL一つで、全員が同じ畑の前に立つ。配り直しも、面倒なインストールもいらない。ここまでは、わりと順調だった。本当の落とし穴は、もっと静かなところに口を開けていた。

機械が、人を読み違えた夜

前に蒔いた種が、ここで芽を出す。それも、雑草の顔で。

「次に伸ばしたい一つ」を自由記述にした以上、書かれた日本語を機械がカテゴリに振り分けねばならない。私は素朴なキーワード照合を書いた。「テスト」と書いてあれば品質カテゴリ、「設計」と書いてあれば設計カテゴリ。一見、無害。

ところが、あるメンバーがこう書いていた。

テスト実行中の不明点を解決できるよう「A. ドメイン/業務知識」を高めたい

本人は、はっきり「A. ドメイン/業務知識」と名指ししている。なのに私のコードは、文頭の「テスト」に飛びついて、これを品質カテゴリと判定した。来期の焦点を集計したら、品質に四票。本人の意思は、機械の早とちりに踏み潰されて、どこにも残らなかった。

これを「ただのバグ」で片づけるわけにはいかなかった。本人がはっきり口にした願いを、システムが横から書き換える。やっていることは、検閲とそう変わらない。一度でもこれが起きれば、メンバーは静かに学習する。どうせ機械が適当に振り分けるなら、丁寧に書くだけ無駄だ、と。次のスプリントから、自由記述の欄はやせ細っていく。声を集めるはずの仕組みが、声を間引く装置へ。育てたかったのは草で、刈ろうとしていたのは、人の本音だった。ぞっとした。

修正の方針は、人間の明示を最優先にすること。文中に「A.」のようにカテゴリが名指しされていたら、キーワードの当て推量より、そちらを必ず立てる。

function guessCat_(text) {
  const t = String(text || '').trim();
  if (!t) return '';

  // ① 文中の明示コード「A.」「F.」を最優先(API. の誤検出は区切り限定で回避)
  const m = t.match(/(?:^|[\s「『((、,,])([A-J])\s*[\.]/);
  if (m) return m[1].toUpperCase();

  // ② 次に正式名の一致、最後にキーワード推定(ここは省略)
  // ...
}

直したあと、件のメンバーの票は、本来あるべき「A」の畑に戻った。たった一票。されど一票。その一票が、「お前の言葉はちゃんと届いている」という、システムからの返事になる。測定の精度の話に見えて、これは信頼の話だ。

ついでに、どうしても変な読み違いが残ったとき用に、設定ファイルへ一行足すだけで矯正できる逃げ道も用意した。機械の推測を、人間がいつでも上書きできる。AIに任せた領域に、人間が手綱を残しておく。この感覚は、現場でAIと付き合ううえで、たぶん一番大事な握り方。

Sprint 1 の畑に、何が芽吹いたか

最初のスプリントを終えて、五人ぶんの草が地面に点った。

濃く染まったのは、品質とテストの列。三人が「ここが伸びた」と手を挙げた。新しいテストの作法を覚えた人。どこまで検証すべきかの線引きを、誰かの指示を待たず自分で引けるようになった人。AIを壁打ち相手にして、設計の筋道を立てた人。やり方は、それぞれ違う。共通していたのは、速さの裏で、引き出しがちゃんと一つ増えていたこと。安心した。

成長実感の平均は五点満点で二・六。学ぶ時間は三・〇。持続可能性は三・四。胸を張れる数字ではない。むしろ、初回としては正直な数字。全員が満点をつけるサーベイは、サーベイではなく、忖度の貯金箱だから。低めの数字が出たことに、私はむしろ安堵した。本音が書ける土壌は、まだ枯れていない。

そして、来期に伸ばしたい一つとして、品質に票が集まった。冒頭で「自分の知識だけでタスクを消化してしまった」と漏らした、あの声の主。次の畑を品質と定めた。在庫を切り崩していた手が、新しい種に伸びようとしている。可視化が効いたかどうか、まだ分からない。けれど、本人が自分で次の一歩を名指しできたこと。それ自体が、灰色だったマスに芽が出た証拠だと、私は受け取った。

測るのは、裁くためではない

ここまで読んで、「結局はエンゲージメントサーベイの焼き直しでは」と斜に構えた読者もいるはず。その疑いは正しい。世の多くの可視化は、数字を握って人を並べ替えるために使われ、現場の口を重くしてきた。私はそれを、何度も見てきた。

この草マップが、ただのダッシュボードと違うと言い張れる根拠は、たった一つ。順位をつけないこと。誰が何点か、ではなく、畑全体でどこに緑が増えたか、を見る。個人を裁くための虫眼鏡ではなく、森を一緒に眺めるための窓。だから、ふりかえりでこの画面を映しても、誰も身構えない。犯人を探さず、芽の出ていない列を見て「次はここに水をやろうか」と相談する。数字が、対話のきっかけに化ける。

人を「コスト」として見るなら、可視化は監視になる。人を「資本」として見るなら、可視化は投資の進捗報告になる。同じ緑のマス目が、見る側の腹づもり一つで、鞭にも、肥料にもなる。私はこの道具を、肥料の側に置くと決めている。

速さの時代に、あえて学びの余白を守る。急がば、学べ。古臭い格言を、AIという最新の道具で裏打ちする。この矛盾めいた組み合わせが、たぶん、これからのスクラムマスターの仕事になる。AIに任せて空いた手で、何をするのか。私は、その空いた手で、畑に水をやることにした。

おわりに——コードを書けない、と言い訳していた過去の自分へ

最後に、この記事をいちばん読ませたい相手は、数週間前の私自身だ。「コードが書けないから、見える化なんて無理だ」と決めつけて、胃に小石を溜めていた、あの私。

伝えたいのは一つ。発注者の語彙が幼くても、意図さえ尖っていれば、AIは動くものに翻訳してくれる。必要なのは流暢なJavaScriptではなく、「何のために、誰の何を守りたいのか」という、一行の意地だった。道具は、もう手の中にある。あとは、畑に出るかどうか。

月曜の朝、コーヒーが冷めきる前に。あなたのチームの灰色のマス目に、最初の一粒を蒔いてみては。緑が点る瞬間は、想像よりずっと、こちらの胸を温める。

1
1
1

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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?