0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Codeのように自然言語でリポジトリ丸ごと生成——ローカルLLMだけで実現した(しかもClaude Code解約)

0
Last updated at Posted at 2026-04-15

はじめに

Claude Codeのセッションが短すぎるので、ローカルLLMで自作しました。
「AIにコードを書いてもらいたいけど、APIにお金を払いたくない」「ソースコードをクラウドに送信したくない」「オフライン環境でも使いたい」——そんな悩みを全部解決するために、LocalForge というツールを自作しました。

LocalForgeは、Ollama をバックエンドとして使うローカルファーストのAIコード生成IDEです。コードは一切インターネットに出ていきません。LLMの推論はすべて自分のマシン上で完結します。

そして実際に Qwen 2.5 Coder 7B(量子化版) で試したところ、複数ファイルにまたがる中規模プロジェクトを、コンテキストを保ちながら自動生成できることを確認できました。


LocalForgeが解決する問題

通常、LLMにプロジェクト全体を生成させようとすると、すぐに壁に当たります。

  • コンテキスト枯渇問題:ファイルが増えるにつれ、LLMが最初の設計方針を「忘れる」
  • ファイル間の一貫性:後から生成したファイルが、先に生成したファイルと整合しない
  • コスト問題:Claude APIやGPT-4 APIを使い続けると請求が膨らむ
  • プライバシー問題:業務コードをクラウドに送信したくないケース

LocalForgeはこれらをすべてローカルで解決します。


アーキテクチャの全体像

localforge/
├── domain/          # ドメインモデル・ポート定義・例外
├── application/     # ビジネスロジック(生成・コンテキスト・プロジェクト管理)
├── infrastructure/  # Ollama HTTP クライアント・FS・Git アダプター
└── interface/       # Tkinter UI・ウィジェット群

Clean Architectureを採用しており、ビジネスロジックとインフラ層が明確に分離されています。UIからOllamaを直接呼び出すことはなく、すべてポートインターフェース(typing.Protocol)を通じて抽象化されています。

これにより、たとえば将来的にOllamaをllama.cppに差し替えても、LLMPortを実装する新しいアダプターを書くだけで対応できます。


ローリングサマリーによるコンテキスト管理

LocalForgeの核心は context.md と呼ばれるローリングサマリーの仕組みです。

仕組み

  1. ユーザーがプロジェクトの要件を自然言語で入力します
  2. LLMが 構造化されたJSONプラン(ファイル一覧・生成順序・依存関係)を生成します
  3. ファイルを1つ生成するたびに、そのファイルの役割・インターフェース・設計判断を context.md に追記・更新します
  4. 次のファイル生成時は、context.md の内容をコンテキストに注入します
# application/context_service.py から抜粋

def build_generation_prompt(
    self,
    project: Project,
    plan: GenerationPlan,
    plan_file: PlanFile,
    generated_files: dict[str, str],
) -> tuple[str, str]:
    # コンテキストドキュメントを読み込む
    context_content = self._read_context(project)

    # 依存ファイルの内容を収集
    dependency_contents = self._collect_dependencies(plan_file, generated_files)

    user_prompt = f"""## プロジェクトコンテキスト
{context_content}

## 生成プラン全体
{plan.to_json()}

## 依存ファイルの内容
{dependency_contents}

## 生成対象ファイル
パス: {plan_file.path}
説明: {plan_file.description}
..."""
    return system_prompt, user_prompt

ファイル生成後は update_context() を呼び、LLMに context.md800トークン以内に要約・更新 させます。これによって、プロジェクトが大規模になってもコンテキストがトークン制限を超えません。

なぜこれが重要か

ローカルの7Bモデルはコンテキストウィンドウが限られています。context.md がないと、10ファイル目を生成するころには、LLMは1ファイル目に何を作ったかを完全に忘れています。ローリングサマリーがあることで、小さなモデルでも大きなプロジェクトを「覚え続けながら」生成できます。


Qwen 2.5 Coder 7B で実際に動きました

重要なのは実際に動作するという事実です。

テスト環境:

  • モデル:qwen2.5-coder:7b-instruct-q4_K_M(量子化版)
  • バックエンド:Ollama(ローカル)
  • OS:Windows11

生成できたもの:

  • Pythonの複数モジュール構成プロジェクト
  • FastAPI + SQLiteのREST APIスケルトン
  • 設定クラス・例外クラス・リポジトリパターンを含む構成

実際の流れ:

1. プロンプト入力
   └─ "PythonでFastAPIを使ったTODOアプリを作ってください。
      Clean Architectureで、SQLiteを使い、CRUD操作をサポート。"

2. プラン生成(JSONで出力)
   └─ requirements.txt
   └─ main.py
   └─ app/domain/models.py
   └─ app/domain/exceptions.py
   └─ app/infrastructure/database.py
   └─ app/application/todo_service.py
   └─ app/interface/routes.py
   └─ tests/test_todo_service.py

3. ファイルを順に自動生成(ストリーミング表示)
   └─ 各ファイル生成後にcontext.mdを自動更新
   └─ 各ファイルをgitコミット

4. 完成

7Bモデルはときどき JSON のフォーマットが崩れることがありますが、LocalForgeは正規表現でマークダウンフェンスや前後のテキストを除去し、JSONオブジェクトを抽出する堅牢なパーサーを内蔵しているため、大抵の場合は自動回復できます。


ストリーミングとスレッド設計

UIがフリーズしないよう、すべてのOllamaコールはワーカースレッドで実行され、結果は queue.Queue 経由でメインスレッドに送られます。

# ワーカースレッドがキューにイベントを送る
for chunk in self._llm.stream_completion(...):
    ui_queue.put(GenerationEvent(EVENT_CHUNK, chunk))

# UIスレッドは50msごとにキューをポーリング
def _poll_ui_queue(self) -> None:
    try:
        while True:
            event = self._ui_queue.get_nowait()
            self._handle_generation_event(event)
    except queue.Empty:
        pass

    if self._state.is_generating.get():
        self._root.after(50, self._poll_ui_queue)

widget.after(50, poll) パターンにより、Tkinterのイベントループをブロックせずにリアルタイムストリーミングを実現しています。


Git統合:自動コミットで進捗を追跡

LocalForgeはファイルを1つ生成するたびに自動的にgitコミットを作成します。

feat: generate app/domain/models.py
feat: generate app/infrastructure/database.py
feat: generate app/application/todo_service.py
...

これにより:

  • どのファイルがどの順序で生成されたかが明確になります
  • 生成途中でエラーが起きても、最後の正常コミットまで戻れます
  • diff ビューアで生成内容を確認できます

GitPythonが利用できない環境では subprocess へのフォールバックが自動的に行われます。


セキュリティとアーキテクチャ上の設計判断

ポートパターンによる依存性逆転

# domain/ports.py
class LLMPort(Protocol):
    def stream_completion(self, prompt: str, model: str, ...) -> Generator[str, None, None]: ...
    def complete(self, prompt: str, model: str, ...) -> str: ...
    def is_available(self) -> bool: ...

OllamaClientLLMPort を実装していますが、アプリケーション層は LLMPort しか知りません。これはテストでも威力を発揮し、MagicMock(spec=LLMPort) を渡すだけで実際のOllamaなしに全サービスをユニットテストできます。

ハードコードされた秘密情報ゼロ

APIキーもトークンも存在しません。Ollamaのエンドポイント(デフォルト http://localhost:11434)は設定として外部化されており、起動時にバリデーションされます。

エラーハンドリングの階層化

# domain/exceptions.py
class LocalForgeError(Exception): ...          # 基底クラス
class OllamaConnectionError(LocalForgeError): ...   # 接続エラー
class PlanParseError(LocalForgeError): ...     # JSONパースエラー
class GitOperationError(LocalForgeError): ...  # Git操作エラー

ベアの except Exception は使わず、すべての失敗モードが型付きで明示的に処理されます。


ファイル再生成機能

生成されたファイルが気に入らなければ、右クリック→「新しい指示で再生成」で追加指示を与えて再生成できます。

既存ファイルの内容 + git diff + 追加指示 → LLM → 新しいファイル内容

この際も git diff が自動的にコンテキストに含まれるため、LLMは「何が変わっているか」を把握した上で改善できます。


インストールと起動

# Ollamaをインストール(https://ollama.com)
ollama serve
ollama pull qwen2.5-coder:7b-instruct-q4_K_M

# LocalForgeをクローン
git clone <repo-url>
cd LocalForge
python -m venv .venv 
venv/bin/activate
pip install -r requirements.txt

# 起動
python -m localforge.main

必要なパッケージは3つだけです:

requests==2.31.0
gitpython==3.1.43
pydantic==2.7.1

UIはTkinter(Python標準ライブラリ)なので、追加の依存はありません。


ローカルLLMの実力について

Qwen 2.5 Coder 7B(量子化版)は2024年末時点で最強クラスのコーディング特化小型モデルのひとつです。商用品質には届きませんが、定型的な構造(CRUD API、設定クラス、テストスケルトン)の生成であれば十分に実用的なコードを出力できます。

量子化によってVRAMは4〜5GB程度に収まり、16GBのRAMがあれば一般的なノートPCでも動作します。

そして何より——完全に無料オフラインで動作コードはマシンから一切出ていきません


まとめ

LocalForgeで実現できたこと:

機能 詳細
ローカルLLM推論 Ollamaベース、インターネット不要
ローリングサマリー context.mdで大規模プロジェクトのコンテキストを維持
ストリーミング生成 トークン単位でリアルタイム表示
Git自動コミット ファイル生成ごとに自動コミット
ファイル再生成 追加指示で任意のファイルを再生成
Clean Architecture テスタブルな設計、依存性逆転

完全無料・完全オフライン・完全ローカルで、プロジェクトをゼロから自動生成する——LocalForgeはそのための実用的な土台です。ぜひ試してみてください。


レポジトリのリンクは下記となります:

テスト環境:Qwen 2.5 Coder 7B Instruct Q4_K_M / Ollama 0.20.7 / Python 3.11.9 / Windows11

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?