🐡

ReactエンジニアがLLMにTypeScriptを書かせるときに気をつけなきゃいけなかったこと

に公開

LLMでコード生成を頼むときに気をつけたい大小文字の落とし穴

LLMにコードを書いてもらうと、実装者の直感とは違う出力が返ることがあります。特に目立つのが「大文字と小文字の扱い」です。自然言語では問題にならない揺れが、プログラムではそのままバグになります。ここでは、自分が実際に遭遇したケースをもとに、注意すべきポイントと対策をまとめます。内部実装の仕組みには踏み込まず、利用者目線の知見のみを扱います。

LLMは大文字と小文字をあえて緩く扱う

自然言語で質問するときは、TypeScripttypescript を同じ意味として扱ってほしいですよね。LLMもその期待に応えてくれますが、そのままコーディングに転用すると危険です。例えば次のプロンプトを考えてみます。

typescript の型の種類を教えてほしい」

期待する答えは TypeScript に関する情報ですが、返ってくるコード例では識別子がすべて小文字になってしまうことがあります。自然言語では些細な差なのに、プログラムでは致命的になります。

// 期待: status は大文字の定数
type Task = {
  title: string;
  status: "IN_PROGRESS" | "DONE" | "CANCELED";
};

// LLMが生成した例: すべて小文字で比較してしまう
if (task.status === "in_progress") {
  // ここは一致しない
}

一見正しく見えますが、実行すると条件が成立せず、画面表示が壊れてしまいます。

よくある落とし穴

1. 列挙値や定数の表記ゆれ

  • IN_PROGRESSin_progress と書き換える
  • HTTP メソッドを "post" と小文字で記述する
  • SQL の列名を userIduserid で混在させる

2. ファイル名・モジュール名のミスマッチ

  • macOS では動くが、Windows で Cannot find module './UserService' が発生
  • CSS/画像ファイルの import パスを小文字で生成し、CI (Linux) 上でのみ失敗

3. コマンドやオプションの表記崩れ

  • docker buildDockerfiledockerfile と書き換えてしまう
  • PowerShell の Get-ChildItemget-childitem にする(実行自体はできても慣例とズレる)

4. API レスポンスのキー名

  • REST API のスキーマが user_id なのに userId でアクセスするコードを生成
  • GraphQL のフィールド名を camelCase で生成し、Schema と合わずエラー

LLMへ伝えるときの工夫

  • 重要な識別子は引用する
    例: status"IN_PROGRESS" | "DONE" | "CANCELED" のいずれかです、と明記。
  • 大文字小文字の扱いを宣言する
    「大文字小文字は区別します」「enum は SCREAMING_SNAKE_CASE で定義済みです」と伝える。
  • 期待結果の例を提示する
    成功したときの JSON やログを添えると、モデルが揺れを検出しやすくなる。
  • 逆テストを促す
    in_progress を渡した場合はエラーにしてください」と条件を追加する。

自分でチェックするポイント

  • PR レビューでは変更された識別子の大文字小文字を再確認する
  • ESLint や TypeScript の noImplicitAny といったルールで表記ゆれを検知する
  • 小文字化が危険な箇所では const STATUS = Object.freeze(...) のように定数化して参照させる
  • ユニットテストでケース感度を明示的にカバーする (例: "IN_PROGRESS""in_progress" の両方をテスト)

プロンプトの書き方例

タスク管理APIのクライアントコードをTypeScriptで生成してください。
status フィールドは "IN_PROGRESS" | "DONE" | "CANCELED" のいずれかで、大文字小文字は厳密に区別します。
小文字で判定するコードや toLowerCase() を使うコードは生成しないでください。

このように事前に禁止事項や注意点を明示すると、出力のぶれが大幅に減ります。

まとめ

  • LLMは自然言語の都合上、大文字小文字を積極的に区別しない傾向がある。
  • コード生成にそのまま反映すると、定数やファイル名の解決に失敗する危険がある。
  • プロンプト内で厳密さを要求し、生成後は自動テスト・Lintで機械的に検証するのが安全。

LLMは強力なアシスタントですが、「人間側が伝え忘れそうな暗黙知」を明文化することが欠かせません。大小文字の扱いに限らず、前提条件は積極的に書き添えていきましょう。

Discussion