まさに最強で無敵のタイピングゲームを、知識がゼロでもそれを完全なAI、だけで作る物語

# 概要

ゼロ知識 × ゼロコーディングの完全な「AI」だけで、
誰もが目を奪われるような完璧なタイピングゲームを作成し、
その手法とノウハウを作ってくストーリー。

以下のような複数の要素があります。

* 昨今流行りのAIコーディングに対する課題意識
* 開発したタイピングゲームの紹介
* 作成時の体験談、課題、工夫などの物語 （本稿は主にココ）
* ゼロ知識、ゼロコーディング開発のノウハウ
    * ⇒ 【Brick AI Coding】として別記事にまとめます。 

実際に個人開発した【コスモス☆タイピング】は以下から無料で遊べます。
タイピングゲームなので、スマホやタブレットではなくPCでお試しください。

https://cosmos-typing.web.app/

本稿は、以下の３要素から構成されています。

* ①【やりたいことリスト】全然埋まってない！
    * 本件の背景、目的、課題意識、やりたいこと、望み
* ②【実践】僕たちが作っていくストーリー
    * 開発物語、失敗したこと、その対策検討、作成過程
* ③【AI開発雑記】何を聞かれてものらりくらり
    * AI開発を経て、考察や所感等

ゼロ知識、ゼロコーディングの「ゼロ・システム開発」で、
どこまで完璧で究極のタイピングゲームが作れるのでしょうか！？
AIによるコーディングをした情報は数多くあれど、
ゼロ知識前提 ＆ 一切自分でコードを書かない 
＆ 作ったモノをちゃんと触れる形でリリースまでやり切る
＆ さらにその得られた開発手法をまとめる
と、唯一無二じゃなくちゃイヤイヤ、欲張りなAIコーディングの物語です。

※当初、要素がバラバラなので、各要素ごとの章にして
　某サイトに「本」として書こうとしていましたが、
　各章ごとのバランスが悪かったので記事にしてみます。

---

# 【やりたいことリスト】全然埋まってない！

## 【プロローグ】知識がゼロでもそれを完全なAIで作る

昨今AIコーディングが流行ってきており、多くの人が驚きを表明しています。
しかし「驚き屋」はサンプルアプリ程度しか作っていません。
**実際に使えるものなのでしょうか？**
**実践ではどんな課題が出るのでしょうか？**

一方で、AIを使役して凄い開発をしている熟達の魔術師も増えてきました。
熟達者の多くが「AIの言葉を鵜呑みにせず、自分の技量で確認するように」
「このような個所/このような依頼なら(元々自分が出来ていた)作業が瞬時に終わる」
という趣旨の発言をよくしています。

しかし、私のたった一つの望み、可能性の獣、希望のAI開発は、
上記どちらでもなく、以下の要望なのです。

* サンプルではない＝リリースする価値がある**実践的なアプリ**
* ゼロ知識、ゼロコーディングで、技量不要で**AIに話すだけで作りたい**

**ゼロ・システム開発** と名付けます。

Cline, Cursor, GeminiCodeAssist, GitHubCopilot, Devin, 
などなどの、いわゆるAIエディターやAIエージェントの活用との違いは、
「**該当言語は一切分からない、一切開発しない、知識ゼロ**」という前提です。

AIエディターやAIエージェントに任せて開発する事例も増えてきてはいますが、
まだ、「人間がちゃんとレビューして使おう」みたいな、
優秀な人間コーダーの監督の元で、という風潮が強いように思えます。

私は、一切知らない言語で、ノーコーディングで開発したいのです。

既存の概念で言うと、「バイブ・コーディング」と呼ばれるものに近いです。
しかし、「バイブ・コーディング」では、サンプルアプリまでしか作れません。
機能が複雑になるにつれ対応コストが増え、最後はエラー対応ループで詰まります。

AIへの依頼方法を工夫することによって、より本格的なアプリを、
初心者でも、熟達者が作るのと同様に作れないでしょうか？

一切人間がコードを書かなくても、AIのコードだけで役立つアプリが作れるのか？
コード不要、前提知識無しで、AIだけでどこまで複雑なものを作れるのか？
そして、そのために気を付けるべき「AIへの依頼の方法」をまとめること。
これが今回実施したい内容です。

ゼロ知識 × ゼロコード ＝ ゼロ・システム開発でどこまで行けるのか？
また、ゼロで高く飛ぶためにはどのようにAI依頼をすればよいのか？
いけるところまで複雑本格的なものを作ってみよう、というわけです。

~~教えてくれゼロ、俺たちはあと何行コードを書けばいい？ゼロよ、俺を導いてくれ~~

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193512/f9cff283-84d1-4c1f-9059-099f96b88cec.png)


## 【要件定義】まさに最強で無敵のタイピングゲームとは？

世の中に素晴らしいタイピングゲームは数多くあれど、
個人的には大きく以下の３点で不満がありました。

* 【入力】柔軟なローマ字入力に対応していない
* 【記録と競争】記録や競争がシンプル過ぎ、一度高得点を出すと終わり感
* 【問題文】問題文がつまらない、重複が多い。それをタイプする嬉しさが少ない

まず、「jyu」「zyu」、「ti」「chi」のような複数の入力方法について、
どちらとも受け付けるゲーム、という条件の時点で、多数のゲームがダメです。

トップクラスの、複数の入力にも対応した本格有名ゲームでも、
次にシャドウで表示されているローマ字については、
過去に自分が入力した方法と合わせくれるものはほとんどありません。
**自分にあったローマ字入力へ、自動調整してくれるゲームが欲しいのです！**

次に、タイピングゲームの記録は、点数だけとシンプル過ぎ、
ネットランキングがあったとしても、
そこには過去の廃人みたいな記録がずっと残っているような状態です。
問題文の課題ともセットなのですが、
単純に早いだけの人や、問題文が少ないので何度かやって覚えた人、
が有利過ぎないようにして、または各時期ごとのランキングも設けるような、
**誰よりも強いキミ以外も認めたいランキング機能が欲しいのです！**

最後に、問題文にも不満です。タイピングゲームを作るときに、
問題文を増やすのは実はかなり面倒な話であり仕方がないのですが、
問題文の量やパターンが少なく、面白みに欠けることが多いです。
問題文の作成はLLMが得意な領域で、これを活用して質と量を増やしやすくしましょう。
また、せっかくタイピングするのですから、覚えたい事柄、等も欲しいですね。
いまは小学生でもタイピングを学ぶ時代です。
小学生に必要な知識をタイピング学習出来るとしたら嬉しいのでは？
**問題文をAIでどんどん作成、クイズ機能も欲しいのです！**

このクイズ機能は、単純な打鍵の早さだけでなく、
クイズ方面で有利な人のランキングが高くなる、という、
ランキングの独特性にも寄与します。

上述のような複数の条件を満たす、
**私が実際に欲しい、と思った有益なもの**、を作るならば、
それはサンプルではなく「実践的な」プロジェクトですし、
上記の範囲だけでも十分に複雑度の高い実装になりそうです。
実益も兼ねて、このような本当に欲しい複雑な機能を持つアプリを、
AIだけでゼロから作れるのでしょうか！？


## 【既存AI開発の課題】AIしてるっと嘘で詰む課題

ゼロ知識、ゼロコーディングの**ゼロ・システム開発**でも、
最初のサンプルアプリ、たたき台程度ならばすぐに出来ます。
しかし、規模が大きくなると、エラーや改善時に、
AIが嘘の直し方、間違った対応、を言ってくることが増えます。
最初はエラーコードを張り付けるだけ、で治してもらえますが、
だんだん対応工数が増えてゆきます。そして、ある一定限界から対応不可能に。

**規模が大きくなるにつれエラー対応工数が増加し、最終的に無限ループで詰む**

これが、ゼロ・システム開発の場合や、または、
Cursor任せでの開発、Devinなどの自立型のAI開発、等でも良く見られる事象です。

多くの熟達者は、このAIの性質を熟知し、依頼の方法や内容をコントロール、
例えば難しい箇所は自分で実施する、レビューする、テストを作る、等の方法で、
この事象を回避するようです。しかし、
知識がゼロで、自分でコーディングが出来ない初心者はこの回避が出来ません。

この課題が生じる原因は、
**AIが一度に理解可能なコンテキスト量には限界がある**
ために生じています。AIに入力出来るコンテキスト量ではなく、
その内容を完全に把握し、理解し、正しく指示に従える量、という意味です。

簡単な実験でもコレが実感できます。
例えば「``print(4+9)``の実行結果を予測して書いてください」
という指示は、コードの実行環境が無くても、AIは間違えません。
しかし、これが数千行のコードであれば、入力は受け付けるものの、全正解は困難です。

１行１行であればAIの脳内で正しく実行できる簡単な指示であったとしても、
一括で同時に全量全行を、となると正確に従うのは無理になってしまいます。

以下のコードは、人間ならば一万行くらい指示に従って頑張れば出来るが、
AIは、自然言語としての思考だけでは、全行指示に従えないコードの例です。

```人間ならば時間があれば指示に従えるが、AIには出来ないコードの例.py
a = 0
a += 2; print(a)
a += 5; print(a)
a += 8; print(a)
a += 6; print(a)
# ～～中略(乱数的加算)～～ ここが何行までならコード実行環境が無くても当てられる？
a += 8; print(a)
a += 3; print(a)
a += 4; print(a)
a += 9; print(a)
print("最終的なaの値は:", a)
```


この「理解可能なコンテキストの上限」によって、
以下のようなエラー無限ループが生じます。

* ある程度プロジェクトが複雑になってくると、エラーの対応時も複数の参照箇所が必要
* 一回の修正でなおせかった場合は、その修正ではダメだった、という情報＝経験も必要
* 三回～五回くらい修正＆NG、を繰り返すと、コンテキストに載らない情報量になる
* すると、一回目で試してダメだったことを忘れてしまい、修正が無限ループ化する

今回の開発は、「理解可能なコンテキストの上限」とどのように向かい合うか？
この課題をクリアするための工夫やノウハウは何か？が重要なテーマになります。


![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193512/b8646a80-21de-477f-bb6f-1be7877bcf64.png)

---

# 【実践】僕たちが作っていくストーリー

## 【実践１】始めは順調。弱点なんて見当たらない？

いよいよ、AIだけでコーディングを開始します。
まず、今回は``Flutter``を採用、つまり`Dart`で開発することにしました。
また、誰でも実施できるように、Webアプリにして、
``Firebase`` でリリースするつもりです。

AIだけでコーディングさせるためには、ある程度メジャーな言語にする必要があります。
また、当初時点では、``Gemini Code Assist`` を主に使用しました。
これは、無料で``GitHub Copilot``や``Cline``のようなことができ、
Google製のためDartやFirebaseとも相性が良いだろうと考えたからです。

筆者は、**Flutterの開発も、Dartも完全に初めて**であったため、
環境構築の手順から、ゼロからAIに聞きながら、AIの指示通りに実施しました。

環境構築と、最初のサンプルアプリを動かすところまではサクサクと進み、
``flutter pub get`` などのビルド時のお作法的な所なども、
全く分かっていなかったレベルから開始しながらも、
環境構築、サンプルアプリのビルド、Firebaseの設定とリリース、
までサクサクと進めることが出来ました。

最初は、何の特別な機能も持たない「普通のタイピングゲーム」です。
モックアップやたたき台、サンプル程度のアプリであれば、
何の知見が無くても、AIへの依頼の方法を工夫しなくても、
AIに聞きながらコピペする程度で、簡単に作れてしまいます。

ここまでは、驚き屋や、バイブコーディングの体験者が言われていることであり、
特筆すべき点も無いでしょう。
テトリス、オセロ、タイピングゲーム程度の、
何の味付けもないシンプルなアプリであれば、AIとの会話だけで出来てしまいます。


## 【実践２】最初にして最大の課題

最初にして最大の課題は、柔軟なローマ字入力への対応方法です。
日本人の90%ほどがローマ字入力と言われているそうです。
しかしそのほとんどが「方言」でタイプしていると言っても過言ではないほど、
日本語には、通常の人が思う以上の入力パターンがあります。

例えば「じゅ」だけでも
``ju``, ``jyu``, ``zyu``, ``jilyu``, ``jixyu``, ``zilyu``, ``zixyu``
などの多様なパターンが存在します。
    
この課題の解決方法については、
以下のプロジェクトを参考にさせていただきました。感謝。

RomanTypeParser：
https://github.com/WhiteFox-Lugh/RomanTypeParser/tree/main

上記参考サイトとは、開発言語が違うため
直接的にはFlutterのコードは得られません。
考え方やデータ的なところを活用させていただきました。
また、筆者はこの内容をあまり理解していません。
「**AIに、参考資料として読ませた上で作業をさせている**」のみです。

このあたりから、既に当初の計画に綻びがでてきます。
最もラクチンな方法として、
``Gemini Code Assist`` （無料！素晴らしい！）を開いておき、
全てそれに実装をやらせる。AIと会話しているだけで終わる、というのが
当初の理想モードであったのですが、全任せ、は全く無理でした。

``Gemini Code Assist`` に直接実装を依頼すると間違いや手戻りが多く、
**OpenAIのWebインターフェースで聞くほうが、精度が高い**のです。
ローマ字入力の判定方法は、かなり複雑なロジック方法になるため、
Googleの無料で使えるモデルとの精度の違い、という問題が一つありそうです。

また、同じモデルであっても、Cline経由で同様にOpenAIを呼び出すと、
全体的に少し精度が低くなるように見えました。Code AssistやClineでは、
統合エディタとして、より複雑なシステムプロンプトが設定されている状態で、
さらに複雑な参考資料を追加することになるため、
手動で明確な依頼をしたときに比べて精度が下がるのかもしれません。

また、エディタ統合型の場合、
どのみち筆者がコードを理解していないので事前にレビューは出来ず、
常に「全てAccept」せざるを得ず、実際にビルドや実行することで確認する、
という流れが必須となります。このAccept後にエラーが生じたときに、
コードを元の状態に戻すのが逆に手間になる、という課題がありました。
（特に複数のファイルや箇所に手が入ってしまう場合など）

細かな背景説明や、既存のコード紹介が不要という意味では、
エディタ統合型（Gemini Code Assist やClineなど）のほうが楽なのですが、
間違いが多く手戻り時の手間を考えると、
依頼の方法を少し丁寧に書くことにして、
Webインターフェースで直接聞く、という原始的な方法のほうが、
精度が高く、手戻りが少ないく、結果が扱いやすい、という傾向がありました。

また、時に環境構築、時にコード生成、時にタイピングの問題作成、
など複数のスレッドを使い分けて進める場合にも、
全部エディタ内にあるより、テーマごとにブラウザを開く方がUI的に便利でした。

とりあえずエディタのAIに依頼する、ではうまくいかず、
適切に質問を切り出してWebのチャットインターフェースに聞くほうが、
総合的な生産性が高かったのです。
特に、コードが複雑化してくるとその傾向は顕著でした。

**AIエディターにお任せすると全てやってくれるか？は「全てはムリ」だったのです**。

最終的に、きちんと聞き方や情報の与え方を正しく行ったGPTちゃんは、
柔軟なローマ字入力を可能にする正しい実装を与えてくれました。
初期時点でデバッグ用に「うちゅうせん」のローマ字入力候補を
全て表示させてみた画像を貼り付けます。

![utyuusenn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193512/fc4a5f60-a24e-4360-9f14-dc62742d1be1.png)


「うちゅうせん」だけで、こんなに**凄まじいパターンの入力方法がある**、
なんて全然思いませんよね。
参考資料のRomanTypeParserサマサマなのですが、
筆者がコレを理解しているわけではない＆Dartも全く書いたことがないのに、
このような複雑なロジックをうまく作ってくれたAIも凄いですね。

**しかし、後で分かるのですが、実はこの実装には大問題を抱えていたのです！**

まだその大問題に気が付かず、
Dartも、この参考資料も、どちらも一瞬しか見ていないのに、
こんな複雑なロジックのコードが出来てしまうことに驚きを覚えながら、
次の実装に進むのでした。


## 【実践３】そう淡々と問題文の追加、とその限界

さて、タイピングゲームの根幹が出来たところで、
タイピングゲームとLLMの相性が良い理由の一つ、
「問題文の作成」もAIにやらせてみます。

以下のように、サンプルとフォーマットを指定して依頼するだけで、
そう淡々とだけど燦々と、問題文を作らせることができます。

> 以下のような、タイピングゲーム用の問題データを作っています。
> あと１０個、追加で問題を作ってください。
> displayText,acceptableInputs
> 猿も木から落ちる,さるもきからおちる
> 石の上にも三年,いしのうえにもさんねん

判定用のひらがなも同時に作ってくれるのは楽ですね。また、
以下のような、テーマの指定や、クイズ形式もどんどん作らせることができます。

> 日常に結びつく哲学的な言い回しで作ってください
> 中学校受験に役立つ歴史の問題を作ってください

ただし、ここで重要なのは、
AI側は「あと100個でも出しますよ！」などと景気の良いことを言ってくるのですが、
実際はそんなに大量同時に出すことが出来ません。
また、同じスレッド内で実施していても、すぐに過去のものと重複します。

一字一句を正確に把握出来る人間サマへの依頼ならば、
同会話内で、同じ文章を出さないようにする、のは時間をかければ容易なことです。
しかし、AIサマは、300行程度過ぎれば前に言ったことを忘れているようです。
たびたび、同じ文章を重複して挙げてきます。
概要としては覚えているのでしょうが、一字一句は理解していないのです。

重複を許さないようにするためには全行一字一句把握していないといけませんので、
「重複を許さないように、任意の例文を20個作って」程度であればOKであるが、
「重複を許さないように、任意の例文を200個作って」程度でも既に問題が生じる、
というわけです。後者は人間サマには簡単なタスクなので、これは少し意外でしょう。

モデルの性能にもよるものの「一字一句を正しく出させるように出来る分量」と、
「１行ずつ正しく把握し、出力を完全予測出来る程度のプログラムの量」
が同じくらい量のように思えます。

重複については、出力した後で重複削除処理をかければ良いため、
唯一無二じゃなくちゃイヤイヤということは無いのですが、
100種類を超えたあたりから、重複しか出ない確率がかなり高くなり、
効率が悪くなるので、自動で1万問、等は出来ません。

少しテーマを味変しながら依頼する、等の工夫が必要になってきます。
ただのタイピング問題 ＝ あまり意味のない文章の集まり、であったとしても、
**無制限に出し続けられるわけではない、点は罠でした**。

多少問題の吟味も必要ですので、タイピング問題の生成については
**飛躍的に楽になるが、フルオートでは(適切で面白いものは)出来ない**
という結論になりました。

過去の会話履歴を参照することが出来るといっても、
これまでの問題と重複しない問題を作って、と指示しても、
その指示は完璧に順守することは出来ない。
これは、AIの限界を示す一つの分かりやすい例なのではないでしょうか？
これも、冒頭で述べている、
「**AIがその内容を完全に把握し、理解し、正しく指示に従える量には限界がある**」
という課題の証拠でもあります。

とはいえそれでも、十分な量の問題数が得られて、次のステップに進みます。


## 【実践４】思わぬ伏兵。なんかわからないけど落ちる

かなり本格的なタイピングゲームとしての問題と、
柔軟なローマ字入力に対応した複雑なロジックの実装を、
一切コードを書かずに実現できたワケですが、

ここで思わぬ難問が生じました。
「**なんかわかんないけど、稀にアプリがフリーズして落ちることがある**」

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193512/2c593096-b1b0-46ba-866c-a7e6698f89bd.png)


これまでは、何かエラーが出ていても、
そのエラーログと、その周辺のコードを、AIに食べさせることで、
何回かやり取りする程度で修正できていました。
**「エラーログ」等、結果をAIに説明しやすいものは対応しやすい**のです。

今回は、落ちる時にログが出ておらず、必ず同じ箇所で落ちるわけではなく、
何が原因なのか、どの箇所のコードを実行中に落ちているのか、
が良くわからなかったのです。
ただどうも、問題と問題の切れ目、次の問題へ進んで、
その問題を描画する前に落ちることがある、ようでした。

つまり、何か特定の問題へ差し掛かった時に落ちている、というアタリが付きます。
一部の問題に、ローマ字変換できないようなフォーマット不正文字があったのでしょうか？
フォーマットを確認しても、それらしきものは見当たりません。
次の問題が表示される直前で落ちてしまうため、
どの問題で落ちているのか、すぐには分かりませんでした。

「事象の説明」と「デバッグ用のコードを追加して」などの指示により、
コードの中で落ちている箇所を特定し、AIと共に原因を考察します。
この問題のカギは「うちゅうせん」にありました。

【原因】
問題文が短い時には大丈夫だったのですが、
ある程度の長さの文章になり、かつ、「うちゅうせん」のような
多様な入力パターンを持つ単語が複数重なっているような場合、
入力パターンの量が、100×100×100・・・のように指数的に増えてしまい、
短文といえど、**作り切れないほどのパターン数**になってしまいます。
問題文を読みこむ処理の冒頭で、
該当の問題に対応する全てのローマ字入力パターンを生成する、
という処理をしていたのですが、
このパターンが指数的に増加する場合があることにより、
性能的な許容量をオーバーし、特定の問題時だけ落ちていたのでした。

【対策】
ちょっとした短文程度で落ちると思っていなかったため、
また、問題を表示する時点で、シャドウでローマ字入力候補の表示も行っているため、
出題の冒頭で入力対象単語が決まった瞬間で全探索実行をするのは妥当、
と考えていたのですが、
方針を再考し「ある程度の文字範囲に区切って、１文字の打鍵のたびに、
次の文字範囲の入力候補を探索する、というような段階的な探索実装」と、
「シャドウでの入力候補表示については、その探索結果とは別実装」に
するような、さらにもう一段複雑な実装をAIに依頼しました。

【改修結果】
正しいローマ字入力の判定処理、をコードとして切り出していたこともあり、
上記のような方針のみ提示する実装依頼だけで、
なんとAIはかなりスムーズに、複雑な実装変更を実現してくれました。
当初の参考資料ですら完全には理解していなかったのに、
ここまでくると実際にどういう処理で動いているのか？は良く分かりません。
Dartのコードを全く分からない人が書けるコードではありません。
該当のファイルはどんなことをしているのか、
そのアバウトな内容や方針は知っているが中身は良くわからん、という状態です。
**その言語仕様を全く知らず、ロジックも概要程度の理解で、**
**ここまで複雑な仕様の実装が出来たことに驚きです。**

一方で、完全な初心者、プログラミングそのものの未経験者、が
このようなエラーに遭遇した場合、AIを使ってといっても、
おそらく改修するのはもっと時間がかかるでしょう。
筆者は確かにFlutterやDartについては未経験ですが、
初めて見る言語でもある程度コードの内容の予測はできますし、
問題が生じたときのカン、をはたらかせることも出来ます。

**AI開発の時代になっても、個々の実装や言語の仕様についての習得をゼロにできるだけで**、
**これまでの開発経験値や、センス的なものは、引き続き重要な素養になってくるのです**。

似たような例としては他に、
タイピング開始時のアプリの動きがもっさりしている気がする
⇒効果音のファイルの事前ロードをすることで解消する
などのような調査と改修もありました。

どこが原因かアタリをつけるところは、
およそどの開発言語でも変わりませんので、そのようなカンをはたらかせ、
AIに、そのような課題があるか確認しながら解決する、と上手くいきます。
**無条件でAIに依頼し続けるのではなく、どんな内容で作っているのか、は**
**常に「自然言語レベルでの理解」(コードレベルは不要)をしておくと良いでしょう**

言語やコード書きとしてはゼロ知識の初心者で良いが、
開発しているアプリのファイル単位程度での概要を把握し、
目指す仕様や実装方針を理解したうえで、開発者視点でAIに指示を出すことが必要。
AIが書いたコードを理解する必要は無いが、動かして確認する必要はあるのです。

全ての一般人が、AIに依頼するだけで好きなアプリが作れる、
という未来は、まだもう少し先のことでしょう。
現在は、「開発スキルの性質が変わってきている」段階です。
弓矢を使うための力や技の代わりに、
鉄砲の射撃スキルに変わってきた感じでしょうか。
弓矢は難しくてもピストルなら、一般人でも多少戦力になれますが、限界があります。
まだまだ、専門の射撃スキルを訓練したエンジニアは重要な役割をはたしそうです。

![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193512/6c1c9e0e-2c7f-46e7-8221-8d9a48da5994.png)



## 【実践５】誰も彼もどんな機能もとりくんでいく

さて、このような複雑な入力機能追加や、ユーザの打鍵癖を覚えておく機能や、
スコアの計算機能、その過去最高記録の履歴管理機能など、
どんどんと作りたい機能を追加していきます。

ここで、最も大きな効果を発揮したノウハウは、
「**常に１ファイル300行程度以下にキープすること**」でした。

当初は「特定のDartの関数」に対して修正コードをAIに書いてもらったり、
こう書かれている行をこう変えて、などと差分更新方法を提示してもらったり、
いわば部分的なコードを提示されていたのですが、
Dartの前提知識がゼロの身としては、
**コピペする場所を正しく探すだけでも一苦労**です。
（本当に知識ゼロから始めているので、IF文の書き方すら分からん）

そして、間違ったコピペをしてしまうと、
私「さっきの修正で直らなかったんだけど？」
AI「（あれ？そんなハズないけど）ではこちらの方法をお試しください」
のように、AIも含めて問題が泥沼化してきてしまいます。

よって、「**全行食わせて、全行出力**」（どのパスのファイルを渡したか、は明記）
という出力方法を多用するようにしました。
とにかくAIに、直した部分のコードだけでなく全行出して！と言うだけです。
ファイル単位で、``ctrl+A``＋``ctrl+V`` の全行置き換えならば間違えません。
この前提として、１ファイルを短くする必要があります。

１ファイルが長すぎると、
AIは全行の修正結果を出すことなく、変わっていない部分は省略してきたり、
最悪、一部の既存コードを省略してデグレードさせてきたりします。

１ファイルを300行程度以下にしておけば、質問時にも、全行渡して、
このファイルをこう修正して、と問題を伝えやすいですし、
AI出力をコードに反映する際も、``ctrl+A``＋``ctrl+V``で済み、
また、AIは正しいのに貼り付けかたで間違えるような悲しいすれ違いも生じません。

「１ファイル単位で全行置き換え」は、依頼＆反映の作業的にも楽で、
戻すのも簡単で、エディタやAIへの依存度も少なく柔軟性があり、
（全員に同じ有償のツールを入れる、ことが様々な理由で難しい現場もあるでしょう）
AIとの会話も誤解が生じにくいので、かなりいいことづくめでした。

※なお、必ずしもファイル＝１単位、である必要はなく、
　例えばPythonで開発する場合は、１つの関数ごと、等にしても構いません。
　つまり、十分少ない行数で、まとめて入れる＆まとめてコピペ、が
　出来る範囲ごとに作りましょう、というだけです。

そして、新しい機能をどんどん追加してゆくと、
300行を超えてしまう場合も出てきます。
既存のファイルの行数を見て、大きくなってきたファイルは、
AIにコードの分割を指示しました。
具体的にどう分割したいか、までは指示しません。
AIが思う、AIにとって自然な方向に分割してもらったほうが良い結果になります。

300行程度に分割するデメリットとしては、
分割後稀に、多数のファイルに修正が必要になるような機能追加があると
どのファイルを修正するのかの判断や、
その修正に必要なチャット回数がファイル数の分だけ増えてしまうことです。

個々のコードの内容は知る必要がなくとも、
システムの概要 ＝ どのファイルに何が書かれているのか、
は把握しておく必要がある、というタイプの開発なので、
この概要レベルは人間が把握しておく必要があります。

この概要把握のため、当初は、
AIにコメントやドキュメントを作らせよう、としていました。
ある程度コードが出来るたびに、その説明文を書いてもらったり、
理解しやすいようなコメントをコード内に追加してもらう、
またはそのコードの生成に使ったプロンプトをコメントとして追記しておく、
などの方法を実際に試したり、検討したりしていました。

**しかし、これらは全て悪手と分かりました**。
コメントを追加したコードをAIに食わせてさらに修正させようとした場合、
（何も指示しない限り）コードを消去してくることが多々あるのです。
かといって、コメントを残すようにすると、その分、
「AIの理解力の限界行」の量を消費してしまっていることになります。

特に余計な注文を付けずにAIが出力したコード、が
そのAIにとって最も自然＝最も理解しやすい、コードであるため、
それ以外に、人の手が入っていたり、コメントが書いてあったり、することは、
余計な摩擦を生み、理解力の減少につながるだけです。

コメントをそのまま残して、と指示してしまうと、
コメントとコードの同期も取れなくなります。

正しい対策は「**コメントの付与など余計なことは一切しない**」
そのコードの概要を知りたければ、
「**知りたいと思った時点で、AIに食わせて都度説明を求めること**」でした。

300行程度であれば、このように都度説明を求めても大した難点はありません。
既存の開発とコメントに対するプラクティスが異なる点は大きな発見でした。

コーディングルール、設計/説明用ドキュメント、等についても似たことが言えます。
コーディングルールは何のためにあるのでしょうか？

コードの一貫性/同一性/属人性の排除？
⇒同じAIモデルが同じゼロ前提で開発しているならば不要です。
　むしろ追加で何か言わないほうが、解釈のブレが生じず同一性が向上します。

保守性の向上/理解の向上/協調のため？
⇒AIが開発するのでAIにとって最も理解しやすい自然な状態にするべきであり、
　また、人間が理解する際には都度AIに聞けばよい状態、で十分です。

品質の向上/良いコードのため？
⇒AIの正確性は大多数の一般人より優れているため、余計なアドバイスを加えないほうが
　AIに開発は完全に任せたほうが、トータルでの品質が向上します。

もちろん、AI開発といえど設定したほうが良いコーディングルール、
が存在する可能性はありますが、既存のコーディングルールの９割は、
再度その存在意義や目的を考え、再考すべきでしょう。
**敢えてAIに指示するのではなく、もともとそのAIモデルが信じている宗教に依存し**、
**AIの思っているように、AIにとって自然なように書かせるのです。**。
**AIが読むものには人は手を加えない、AI自然環境を保護しましょう。**

![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193512/dd9f8ff4-a8e7-40ab-88fe-82eccd7c76ef.png)


さて、このように「**１ファイルを300行程度以下**」
「**コメントや追加ドキュメントは書かないで都度聞く**」によって、
新規の機能を個別に、段階的に追加してゆくことが可能になりました。
最高得点の履歴や、称号機能、または効果音、効果音の選択機能、などなど、
必要だと思った機能をガシガシと追加します。


## 【実践６】見えそうで見えない秘密、記載省略部

Firebaseへのリリース周辺のことや、
最高得点の管理方法のデータベースのこと、通信方式など、
まだまだ、開発の経緯や検討事項があるのですが、
既に記載したものに比べると少々特殊な領域なことと、
あまり記載しすぎるとハッキングしやすくなってしまうので、本稿では省略します。

また、ただのタイピングゲームではなく、
クイズ形式もつけたことや、その工夫点や設計思想などについても、
いろいろあるものの、AI開発というよりタイピングゲームの開発内容、に
なってしまうため、それらも本稿では省略します。

機能をガシガシと追加していく実践経験のなかで、
有用な開発ルールや考え方が集約洗練され、
同じAI開発手法で様々なサブ機能が同様の方法で追加できるようになりました。

また、途中で「テストコード」の追加や、
または「テストファースト」にする手法も試してみたのですが、
コードの内容自体を良く理解していない状態で作っても、
どこまでテスト出来ているのか、どこまでをモックにしているのか、も分からず、
ただ複雑で面倒になるだけで、全くの無意味でした。

300行程度ならAIは間違えないだろ、ということと、
テストコードの有無に関わらずどのみち動かして確認する、ために、
この手法の場合、**テストコードは不要**のほうが望ましいです。
これらテストの検討の詳細は割愛します。


## 【リリース】この言葉がいつか本当になる日をむかえて

このように、またはここに書ききれなかった（そのうち追記するかも？）
さまざまな苦戦、工夫を経て、
私の考える**タイピングゲームの理想形**が出来ました。

実際に開発した【コスモス☆タイピング】をぜひお試しください。

https://cosmos-typing.web.app/

もちろんまだ未熟な部分があり、今後更新しない、という意味ではないのですが、
当初作りたいと思ったほとんどの機能は一通り追加出来た、ので、
使った人の声を聞く、少し時間をかけて次の更新内容を考える、
という段階になったという意味です。

また、今回の開発実践、課題対応によって得られた、
【ゼロ・システム開発】の具体的なルールやノウハウは、
【Brick AI Coding】と称して以下のページにまとめていますので、
詳しい手法については、以下のChapterをご参照ください。

https://zenn.dev/youwht/books/219efcf7ce1e66/viewer/68fd15

むしろ、Brick AI Coding こそ記載したかったのですが、
ルールだけあっても検討経緯が無いと
意図が良くわからないために、本稿を書いているという意味もあります。

逃げ出すよりも進むことを君が選んだのなら、進めば二つ、手に入りました。
* **まさに最強で無敵のタイピングゲーム、コスモス☆タイピング**
* **知識がゼロでもそれを完全なAI、だけで作る方法、Brick AI Coding**

どちらもいわば「初版」なので、ユーザフィードバックや、
別のプロジェクトへの適用によって、適宜見直したいと思います。

Brick AI Coding は、レゴブロックの１ピースずつをAIに作らせるような手法で、
**完全初心者が即戦力化しやすい開発手法/AI依頼方法**、を目指しています。

![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193512/048835c8-b7fb-4237-8251-274bf0a47bb5.png)


---

# 【AI開発雑記】何を聞かれてものらりくらり

実際にプロジェクトで使えるような開発ルールや、
AI開発としての技術面でのコツは、前述参照先のリンクに記載するとして、
せっかくの「物語」なので、最後に、
のらりくらり、AI開発に対する考察やイメージなどの雑記を書いておきます。
参考になるかもしれないし、まあならなくてもいいと思います。

~~どうせ本稿は、タイトルを思いついたから書いた、だけ。~~

## AI開発は「使い捨てのピカソ放題」だ

### AIは「頼りになる鳥あたま」

AIが扱えるデータのレベルは、ざっくり以下の３種類に分類できます。
※もちろんここで言及しているAI、とはLLMのこと

* AIが取得できるデータ
    * AIが探しに行けば見つかる情報(サーバ全体に格納されている全ファイルなど)
    * RAGで参照できるDB、過去の会話履歴の圧縮情報等
    * MCPやFunctionCallingで扱る機能や、Web検索可能な情報等
* AIが処理できるデータ（コンテキスト）
    * AIが一度に処理できる、一度に入力出来る情報量(短い小説レベル)
    * 上限値＝コンテキストウィンドウのトークン数
    * システムプロンプト ＋ プロンプト ＋ 直近の会話履歴など
* AIが理解できるデータ
    * AIが、一字一句正しく把握できる情報(300行～1000行程度)
    * AIの理解力そのもの。完全に指示に従える分量
    * 一般的に、入力の抜粋/サマリ/概要、を理解している

「AIが処理できるデータ」＝「AIが理解できるデータ」と、
誤解している人が多い気がしますが、
これは本稿でもさんざん言及している通り、明確な違いがあります。

また、Clineや既存の方法は「AIが取得できるデータ」を最大化して、
言わば人が出来ること何でも出来るようにした状態を目指しています。
これは考え方として正しいと思いますが、「暴走特急」になってしまうので、
きちんと制御出来る、AI自身より強力な御者が必要になってきます。
（御者が居なくなると、星新一のSF短編「肩の上の秘書」の世界？）

AIは非常に頼りになりますが、
「AIが理解できるデータ」には限りがあるという性質も合わせて理解し、
**AIに対して、過不足なく正しく期待し、それに応じた適切な依頼方法を考える**
ことが、AI開発をうまく進めるためのコツと考えられます。

「AIガチャ」や「暴走特急」に賭けることが出来るのは、
ハズしたときに自分でフォローできる人だけでしょう。
私のような初心者や、または初心者を束ねてモノづくりをしたい時は、
「適切な依頼方法」をコツコツ積み重ねてゆく必要がありそうです。

では、どのよう考えれば「適切な依頼方法」が分かるのでしょう？
AIに対して過不足なく正しく期待するためには、
AI及びその依頼方法のイメージを持っていると、良い判断がしやすくなります。

そのイメージとは「使い捨てのピカソ放題」です。

### 「ピカソの30秒」のエピソードとは？

ある日、街でピカソが散歩をしていたとき、女性に声をかけられます。

> 「あら、ピカソ先生！ 私の似顔絵を描いていただけませんか？」

ピカソは笑顔で快諾し、**たった30秒ほどで**その女性の似顔絵をサッと描き上げました。
女性はとても感激して、「すばらしい！ おいくらですか？」と尋ねました。

ピカソはこう答えます。

> 「5000ドルです。」

女性は驚いて言いました。

> 「たった30秒で描いたのに、5000ドルもするんですか？」

するとピカソはこう言ったとされます。

> 「いいえ、**これは30年と30秒**かかっているのです。」

### 生成AIによる開発の革新的部分は「ピカソ放題」

ピカソの３０秒が伝えようとしていることは以下です。

* 創作に必要なのは作品を作る時間だけではない。
* それまでに積み重ねた経験・技術・洞察の時間。
* 一見「短時間」で成果が出たように見えても、それは長年の鍛錬の結果である。
* 「成果」に対する報酬は、投入された努力と蓄積に対する対価である。
* プロのエンジニアが数行のコードでバグを直す
* → それを「数行」で解決できる力は、何年もかけて培った知識と経験。

このような、熟練の知識が必要なエンジニアの開発技能を常時召喚出来ること、
「**ピカソ放題**」
これが、生成AIによる開発が革新的である理由です。
30秒5000＄のような高額出費不要で、熟練の知識を使役出来るのです。

### 生成AIによる開発をうまくやるコツは「使い捨てのピカソ放題」

しかし、本当にピカソを召喚するのと、大きな違いがあります。
AIの理解力には限界があり、ピカソのような柔軟な対応は出来ない、ということです。

AIは、明日には全てを忘れています。（よって、``clinerules``とかがある）
AIに入力出来るコンテキストや、把握できる量には限界があります。
AIは概要や全体を把握しにくく、個別にその断面だけの把握になります。

そこで「ピカソ放題」ではなく、以下のような、その使い捨て版、
「使い捨てのピカソ放題」がAI開発におけるメタファーと考えます。

#### 使い捨てのピカソ放題

* 30年モノのピカソをコールドスリープさせてある
* **クローン技術で、何万人でもコールドスリープをコピー**してある
* ユーザは、ピカソを何人でも起こして絵を描く依頼が出来るが、制限がある
* **３分間しか、そのピカソは生きられない**
* 視野が非常に狭く、5cm四方程度しか一度に見たり描いたり出来ない

![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193512/2b5b130d-3ea3-4b1e-89f7-2a079001d0ec.png)


このような状況で、ピカソに絵を描いてもらうにはどうすればよいでしょうか？
生成AIによる開発のノウハウは、大部分はこのメタファーでイメージが出来そうです。

* ラフスケッチを作る場合(お試しバイブコーディング)
    * ５分で描けるラフスケッチなら、雑に一人目に依頼すればよいだけ
    * が、視野が狭いので全体の繋がりを見ながら描くことが出来ず、通常はラフ止まり
    * 何回か連続して召喚すれば、ある程度大きな絵や本格絵も作れる
    * 一度間違え始めると、前のピカソが間違った内容を直せず崩壊する
* 大作や大きな絵を作る場合(clineを使う熟達者が良くやってる方法)
    * 自分のアシスタントとして、面倒な部分ごとに、都度召喚して書いてもらう
    * 全体の説明の時間が惜しいので、先に全体のモチーフの説明や書き方のメモを作る
    * 既に書き終えている場所も全部一度見えるようにしておく、情報アクセス性の確保
    * 最初の１分でそれらを理解してもらったうえで作業してもらう
    * 一個前に召喚したピカソに引き継ぎ情報を作ってもらい、次のピカソに渡す
    * この引き継ぎ連鎖で、視野が狭くても必要な情報にたどり着ける
    * 多段によって、全体像に整合した正解的な描き方が出来る
    * どうせ何回でも召喚できるので、まずやらせてみる
    * ダメだったら次の召喚で依頼方法を変えて上書き修正していく
    * 引き継ぎ資料の量が多くなりすぎて詰むことがある
    * どうしても出来ない場合は、召喚者自身が介入修正して直接描く
* 本稿で提唱している方法（Brick AI Coding）
    * 基本は、ピカソ任せで自由に書いてもらう。絵のティストなどはピカソに従う
    * 以下のような「依頼方法」をルールとして定め、10秒で必要十分な情報のみ依頼する
    * 「今回のピカソの任務にとって必要十分な情報」
    * 「この部分の絵をこのように直して、という対象と任務の明確化」
    * 絵の全体は見せない。書き加えたい箇所に限定し、常時部分上書き
    * 常に、ピカソが見られる視野の範囲でしか依頼しない
    * 召喚者は全く絵を描けないので、ひたすらピカソへの依頼方法だけに注力

あなたならば、このルールで目覚めた使い捨ての大量のクローンピカソ達に対して、
どのような依頼をして絵を描かせるのが良いと思うでしょうか？
それはおそらく求めている絵の内容や性質によっても異なります。
正解というものはありません。

本稿で提唱している Brick AI Coding も、Clineでの開発と相反するものではなく、
前提が「自身では全く絵も描けない、絵の良し悪しも分からない」
「ゼロ知識の初級エンジニアが自然言語だけで作れるようにするための依頼方法」
というだけで、プロジェクトやエンジニアの背景に応じて、カスタマイズするべきです。
また、モデルやツールが進化すれば、300行という制限は緩くして大丈夫です。

「使い捨てのピカソ放題」を使ってどのように依頼すれば上手く欲しい絵が描けるのか、
あたまの体操として、考えてみると面白いかもしれません。

---

# 【おしまい】やっと言えた

これは絶対嘘じゃない「**AI**」してる！！

![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193512/f844677a-4a3b-4f1b-a872-1f27c768df11.png)


---