9 ポイント 投稿者 GN⁺ 2025-12-24 | 1件のコメント | WhatsAppで共有
  • 大規模コードベースでLLMを効果的に活用するには、「ガイド(guide)」と「監督(oversight)」への投資が中核である
  • ガイドは文脈と環境を提供してLLMがより良い選択をできるよう支援し、監督は結果を検証して方向性を示す役割を果たす
  • プロンプトライブラリを構築し、コードベースの規則、文書、ベストプラクティスをLLMが理解できるようにすることが重要
  • 技術的負債の管理とコード構造の単純さ、モジュール化、一貫性は、LLMのコード理解力と生産性向上に直結する
  • 自動化された監督と検証の仕組みによって、LLMが安全で一貫したコードを生成できるよう支援することが、長期的な拡張性の鍵である

LLM拡張のための中核概念

  • LLMを大規模コードベースに適用する方法はまだ確立されていないが、ガイドと監督への投資が最も効果的なアプローチとして示されている
  • ガイド(Guidance) は、LLMが正しい選択を行うのを助ける文脈と環境を意味し、監督(Oversight) は生成された結果を検証し、方向を調整する役割を担う

ガイドへの投資

  • LLMが一度の試行で高品質なコードを生成する**「ワンショット(one-shotting)」**を達成するには、明確なガイドが必要
    • 逆に、結果が不適切で手動修正が必要な場合は**リワーク(rework)**となり、非効率である
  • LLMはコード内のあらゆる選択(変数名、関数構造、技術スタックなど)を生成するため、プロンプトにはビジネス要件だけを含め、それ以外は推論可能またはエンコード済みの状態が理想的

プロンプトライブラリの構築

  • プロンプトライブラリは、コードベースの文書、ベストプラクティス、構造マップなどを含むLLM向けの文脈集合である
    • LLMの出力が外れるたびに、「何を明確にすべきだったか」を見直し、それをライブラリに追加する
    • 網羅性と簡潔さのバランスが重要
  • 例では、@prompts/How_To_Write_Views.md@prompts/The_API_File.md などの文書をLLMに提供して機能開発を導いている
  • プロンプトは十分に具体的であるべきだが、生成されたコードのすべての行をレビューする必要がある

環境とコード品質

  • **技術的負債(technical debt)**が多いコードベースは、LLM活用の効率を低下させる
    • Metaの事例では、技術的負債のために自動化目標の達成が難しかったと述べられている
  • クリーンなコード、モジュール化、明確な命名、単純な構造が、LLMの理解度と正確性を高める
  • Djangoの例では、各アプリのエントリーポイントを _api.py ファイルに置くことで、LLMが必要な機能を素早く見つけられるよう構造化している
    • 例: visit_api.handoff_to_doctor(user) の形で外部アクセスを単一化
    • _api パターンをプロンプトライブラリに明記し、LLMが正しい場所を参照するよう誘導する

監督への投資

  • LLMの自動化は、エンジニアを置き換えるのではなく、チームを強化する方向で捉えるべき
  • 監督は、チーム、アラインメント(alignment)、ワークフローへの投資へとつながる
    • チームの観点では、設計能力の向上が重要であり、それがアーキテクチャ品質につながる
  • 設計能力を高める方法としては、本・ブログ・コードを読むこと、優れた作品の再現、直接実装の練習などが挙げられている
    • 例: TLDraw、SerenityOS Jakt などのコード分析を通じて設計感覚を広げる

自動化された監督

  • 一部の設計検証はプログラムによって自動化できる
    • 例: 型エラーやルール違反を環境内で即座にフィードバックする
  • **「安全性(safety)」**とは、抽象化を保護することを意味する
    • Pierceの定義によれば、安全な言語は、プログラマーが意図せず抽象化を壊してしまわないよう保証する
  • 例: Djangoアプリ間で内部ファイルへ直接アクセスすることを禁じるルールを、ASTベースの検査スクリプトで自動化する
    • from visit import logic.internal_file 形式の不正アクセスを検出

検証(Verification)

  • 設計と実装に加えて、**検証段階(コードレビュー、QA)**も品質確保に不可欠
  • 作業量が増えるほどレビュー速度がボトルネックになるため、次のような改善策が示されている
    • 開発環境がなくてもQAを実施できるよう、参入障壁を下げる
    • テストデータ生成など、テスト作成が容易な環境を構築する
    • 繰り返されるPRフィードバックを文書化し、LLMが一部レビューを自動実行できるよう支援する
    • セキュリティルールをフレームワークのデフォルトとして組み込む

結論および追加の観察

  • LLMは新規(greenfield)プロジェクトで特にうまく機能する
    • 既存の文脈がなく、一貫性への要求が低いため
  • プロジェクトが大きくなるほど、一貫性とモジュール化が生産性を左右する
    • 検証済みコンポーネントを再利用するモジュール型構造が、効率的な開発の中核である

1件のコメント

 
GN⁺ 2025-12-24
Hacker Newsの意見
  • モデルがどんどん改善され、複雑なコードベースや長いファイルも扱えるようになってきた
    そこで私は、繰り返し使うシンプルなフレームワークループを作った

    1. Research: 現在の機能を説明させ、関連ファイルをコンテキストにロードする
    2. Plan: 新機能実装やリファクタリングのベストプラクティスをブレインストーミングさせる。その結果をmdファイルとして書かせる
    3. Clear: コンテキストを完全に初期化する。単純な圧縮より結果が良い
    4. Execute plan: 計画だけを再ロードして実行させる。必要なら質問を繰り返す
    5. Review & test: 再びコンテキストを初期化し、計画がうまく反映されたかレビューさせる。このときテストコードやlint、型チェックなどを追加する
      このループを20〜30分回すと、かなり使える結果が出る。結局のところ重要なのは、コンテキスト管理とテストのフィードバックループを作ることだ
    • 2025年12月時点では、Sonnet/OpusやGPTCodexのようなモデルにはすでにsubagent探索機能が組み込まれている
      「explore」というキーワードで探索を始めると、別途計画を書いたりコンテキストを初期化したりしなくてもResearchが可能だ
      ただしコード言語をCやPythonだと想定しがちで、状態をオブジェクトにカプセル化せず関数5つに分けるような非構造的なコードを生成しがちだ
      またclaudeはしばしばCLAUDE.mdを無視するので、先にそのファイルを読ませてから「explore」させると安定する
      最新モデルは不要なコンテキストをうまく捨てるが、古いモデルでは依然として計画文書ベースのアプローチの方が良い場合がある
    • モデルが基本的な推論能力で失敗するなら、どんなワークフローも役に立たない
      計画やガイドラインを真逆に実行したり、同じ文を読み直しても反対の結論を出したりすることが多かった
      しばらくはLLM中心のプロセスを作れると信じていたが、今は確信が薄れている
      モデルが「良い状態」のときは問題ないが、その状態にすること自体がいまだに運任せ
    • 私も似たようなアプローチをしている。HumanLayerのAdvanced Context Engineeringガイドラインに着想を得た
      /research_codebase/create_plan/implement_planのようなカスタムコマンドをClaude Codeに追加した
      丁寧にレビューして修正すれば非常によく動くが、チーム全体には広がらなかった
    • 私はこういう手順をほとんど使わない。GitHub CopilotとClaude Sonnet 4.5を使えば、明確な指示だけでも十分うまく処理する
      完全に新しい機能を作るときだけコンテキストを初期化する。Codespacesでは問題ないが、Tasks機能はほとんど役に立たない
      大きな作業を任せるとおかしな方向へ行ってしまうこともあるので、常に監視する必要がある
    • 私もほぼ同じワークフローを使っている。計画mdファイルをリポジトリに残しておき、新機能追加時に参照させる
      コンテキストの再プライミングにも有用で、よく活用している
  • プロンプトライブラリを有用にするには反復的な改善が必要だ
    LLMが少し外すたびに、「何をもっと明確にすべきだったか?」と自分に問い、その答えをプロンプトに追加する
    ただEnterを押したり自動承認したりするだけではトークンを無駄にする。代わりにLLMがどこで詰まるのか観察し、CLAUDE.mdに短く記録する
    コンテキストファイルが大きくなったら、作業タイプごとに分ける
    私の主なユースケースは、コードベース探索、実行経路の追跡、必要なファイルの要約提供だ。質問タイプごとに結果の伝え方を明示しておくと、はるかに効率的になる

    • 「何を明確にすべきだったか?」より良い方法は、LLMに自分で問いかけさせること
      私はこれを「Student Pattern (Fresh Eyes)」と呼んでいる。サブエージェントが初心者の視点で文書やコードを読み、混乱点・矛盾・欠落情報を見つける方式だ
      開発者が見落としがちな暗黙知を拾い上げるのに非常に優れている。新しい文書レビューやプロンプト評価の前段階として有用だ
    • 私もそうしているが、Claude Codeはしばしばプロンプトや文書の無視がひどい
      CLAUDE.mdを読めと何度も指示しても無視することが多く、セッション開始直後でもランダムに抜ける
      文書と命令をすべて用意しても、なお「忘れる」ことが多い
  • 大きなコードベースをエージェントフレンドリーに構造化する実験をしている
    プロジェクトをnix flakesベースの有向グラフに分解し、各ノードが独立した開発環境を持つようにした
    Claude Codeをflake devshellで実行すると、その範囲だけを認識してコンテキスト過負荷を防げる
    flakes間の入出力で協調させ、互いに機能要求やテストをやり取りさせる
    このコンテキスト分割がトークン爆増問題を減らす鍵だと考えている

    • このアプローチは興味深い。私もソフトウェア構造と属性の相関関係を考えているところだ
      既存ワークフローを改善するだけでなく、LLMが容易にスケールできる構造を新たに設計すべきだ
      「テスト容易性・拡張性・安全性」といった属性とコード構造の関係を探っている
    • コンテキスト分割だけでなく、再現性と依存関係の固定という観点でも興味深い
      私もDockerベースのプロジェクトで似た実験をしたことがあるが、これを自動化してくれるツールがあるとよい
  • LLMは私があまり知らないテーマは見事に説明するが、専門分野では自信満々に間違える

    • これはGell-Mann Amnesia効果のようだ
    • テーマによってばらつきが大きい。私はWeb分野では正確だったが、Hareのような珍しい言語ではひどかった
    • 私たちは知らない分野では単純な質問をし、知っている分野ではずっと難しい質問をするので、そう感じるのかもしれない
    • 実際には、知らない分野ではでたらめを見分けられないだけかもしれない
  • 私は別の見方をしている。LLMの性能を高める最良の方法は、コードベース自体に意味を埋め込むこと
    つまり、DDD(Domain-Driven Design)のように構造化されたコードはLLMにも理解しやすい
    複雑なコードをツールで無理やり扱おうとするのは金の無駄
    結局LLMが証明したのは、「言語と意味」を重視するDDDの哲学が正しかったということだ
    関連記事: DDD & the Simplicity Gospel

    • 私も2つの大規模コードベースを管理しているが、構造化された方はLLMの理解がはるかに良い
  • 「LLMはなぜグリーンフィールドプロジェクトでうまく動くのか?」という問いに対して、私は逆の経験をしている
    コードベース内でパターンが2〜3回繰り返されると、LLMはそれを学習して一貫して複製する
    しかし「一貫性」がそのまま「品質」を意味するわけではない。基準なしに一貫性だけを追えば、保守不能なコードになる

  • 「エンジニアが理解できないコードはLLMも理解できない」というのは正しいが、その逆は成り立たない
    人間には理解できてもエージェントには理解できないケースが多い
    コードベースを人間よりエージェントに理解しやすくする方が難しい
    「フィードバックをコンピュータに移せば一発成功率が上がる」という主張もあるが、これはP=NPを主張するのに近い
    検証が容易だからといって、解を見つけるのが容易になるわけではない
    ATSやIdrisのような言語では、正しさの証明をコードと一緒に書ける
    もしその主張が正しいなら、こうした言語でLLMが最高の性能を示すはずだ
    しかし現実はそうではない。結局、今はモデルの改善を待つ方がましだという考えだ

  • こうした問題のため、私は意見の強いフレームワークがAIコーディングの生産性を高めると見ている
    フレームワークのルールをLLMがすでに知っているので、別途ガイドラインが不要だからだ

    • 160万行のコードベースで働いているが、パターンの不一致が激しい箇所ではLLMはほとんど役に立たなかった
    • 同じアプリを複数の言語で作ってみたが、Railsはほぼ即座に完成し、Bunも悪くなかった
      一方でGo、Rust、Elixir、C#は、はるかに多くの依存関係と指示を必要とした
      Rustは結果自体は良かったが、200を超えるパッケージを引っ張ってきて負担が大きかった
  • 「Garbage in, garbage out」の原則は正しいが、LLMには完全には当てはまらない
    インターネット全体のノイズだらけのデータで学習していても、かなりうまく動く
    ハルシネーション(hallucination) は、単なるノイズよりも不正確なコンテキストでより頻繁に起きる
    構造がひどいコードベースでも、情報量が多ければ依然として有用なコンテキストを提供する

  • 結局のところ、人々は基本原則を学び直している
    ドキュメント化(=プロンプトライブラリ)と整ったコード構造が開発速度を高めるという事実を、あらためて実感しているのだ

    • それでも、そのおかげでより多くの人がテストを書くようになるなら悪いことではないと思う