🙆

OpenHands をローカル LLM で動かしてみた

デジタルマーケティング事業部エンジニアの石原です。
本記事では、ローカルLLMでOpenHandsを用いてコードエージェントとしてどの程度使えるかを検証しました。

0. はじめに

  • 目的:
    • OSS の OpenHands を使い、開発者補助としての「コードエージェント」的な使い方を試す
    • Devin のような開発支援 AI を、ローカル環境 × 軽量 LLMでどこまで再現できるかを検証
  • 概要:
    • OpenHands(旧 OpenDevin)は、Devin 風の OSS コードエージェントであり、開発者の操作を補助する自然言語インタフェースを提供(2025 年 6 月 12 日現在のバージョンは 0.42.0)
    • LLM は外部 API(例:OpenAI)もローカル LLM(Devstral、Gemma 3 など)も接続可能(ただし、今回はGemma3は環境または相性の問題か失敗)

1. 使用環境

  • 実行環境:
    • OS: Windows11 (Ubuntu on WSL2)
    • CPU: Ryzen9 3950
    • Memory: 128GB (DDR4)
    • GPU: RTX 3090(VRAM 24GB)
    • OpenHands 0.42.0
  • 使用 LLM:
    • devstral:24b(ローカル/Ollama)
    • gemma3:27b-it-qat(ローカル/Ollama)

2. OpenHands(旧 OpenDevin) とは?

  • Devin の OSS クローン的ポジション
  • 特徴:
    • CLI や Web 上のエディタの操作を自然言語で補助
    • コードの変更、コマンドの実行、Web の閲覧など、人間の開発者ができることはすべて実行可能(と謳っている)

3. 使用するモデルの説明

名称 ベンダ 概要 参考 URL
devstral:24b Mistral AI, All Hands AI 2025 年 5 月末に公開、ソフトウェアエンジニアリングタスク用のエージェント LLM、コードベースの探索、複数のファイルの編集、ソフトウェアエンジニアリングエージェントに使える URL
gemma3:27b-it-qat Google Gemini の技術に基づいて構築された Google の軽量モデル ファミリ、テキストと画像を処理するマルチモーダルを備えている。1B、4B、12B、27B のパラメータサイズがある。今回は量子化対応学習済みモデル(27B モデルを使う場合はこうしないと VRAM が足りない) URL

4. セットアップと使用方法

4-1. セットアップ

  1. WSL上のubuntuへのDocker、CUDA の導入(省略)

  2. 任意のディレクトリにプロジェクトルートフォルダ作成する

  3. docker compose.ymlをプロジェクトルートに置く

    docker-compose.yml

    services:
      openhands-app:
        image: docker.all-hands.dev/all-hands-ai/openhands:0.42
        container_name: openhands-app
        environment:
          SANDBOX_RUNTIME_CONTAINER_IMAGE: "docker.all-hands.dev/all-hands-ai/runtime:0.42-nikolaik"
          LOG_ALL_EVENTS: "true"
          LLM_API_KEY: "ollama"
          LLM_BASE_URL: http://host.docker.internal:11434
          SANDBOX_VOLUME_MOUNTS: "/home/user:/home/user"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - ~/.openhands-state:/.openhands-state
          - ~/openhands_workspace:/home/user
        ports:
          - "3000:3000"
        extra_hosts:
          - "host.docker.internal:host-gateway"
        stdin_open: true
        tty: true
        pull_policy: always
    
      ollama:
        image: ollama/ollama
        container_name: ollama
        network_mode: host
        gpus: all
        volumes:
          - ollama:/root/.ollama
        ports:
          - "11434:11434"
        restart: unless-stopped
    
    volumes:
      ollama:
    
  4. サービス起動

    docker compose up -d
    
  5. ollama にLLMモデルをpullする

    # コマンド<モデル名>に導入したいLLMのモデル(ollama対応したもの)を入力
    docker exec -it ollama ollama pull <モデル名>
    
    # gemma3:27b-it-qatを使う場合
    docker exec -it ollama ollama pull gemma3:27b-it-qat
    
    # devstral:24bを使う場合
    docker exec -it ollama ollama pull devstral:24b
    

4-2. 使用方法

  1. WebUIに入る
    任意のWebブラウザ(Google Chrome等)でhttp://localhost:3000/にアクセス
    (※docker-compose.ymlでopenhands-appのportを書き換えていなければこれで接続可能)
    トップ画面

  2. 設定(LLM)
    トップ画面の左下の歯車から設定画面に入る
    LLMタブで詳細設定に切り替え(ローカルLLMでない場合は、詳細設定でなくても接続できるものが多い)
    設定画面

    設定内容

    • カスタムモデル:ここでセットアップでollamaにpullしてきたLLMを指定する。例:ollama/devstral:24b
    • ベースURL:dockerで立ち上げたollamaにアクセスするためのURL。例:http://host.docker.internal:11434
    • APIキー:dummyと入力
    • エージェント:CodeActAgent
  3. 設定(GitHub連携)
    GitタブでGitHubまたはGitLabとの連携を行う(トークン発行など画面に従って操作)

  4. リポジトリを開く
    左上の手のアイコンでトップページに戻り、リポジトリに接続から対象のリポジトリを選択、または「ゼロから始める」ボタンを押すとワークスペース画面に移動する。
    ワークスペース
    コンテナの準備に時間がかかる(初回はイメージのpullからなので待ち時間はより長くなる)

  5. 左側のチャット欄にエージェントにお願いしたいことを書いて「↑」ボタンを押すとLLMが解釈してアクションが起こる

5. 実験内容と所感

試したこと

  • 単純なコード作成(例:FastAPI のひな型作成)
  • git 操作
  • ファイル操作(生成・編集)

実施結果

devstral:24b

  • コード作成

    プロンプト:FastAPIのひな型のコードを作って
    結果:インストール手順から説明してきたので略

    from fastapi import FastAPI
    
    app = FastAPI()
    
    @app.get("/")
    def read_root():
        return {"Hello": "World"}
    
    @app.get("/items/{item_id}")
    def read_item(item_id: int, q: str = None):
        return {"item_id": item_id, "q": q}
    
  • ファイル操作

    プロンプト:このコードを反映したファイルを作って
    結果: 「ゼロから作成」では動かず、「main.pyに入れる」という具体的指示が必要だった(失敗して止まった)、リポジトリ連携してプロンプトを「FastAPIのひな型のコードを作って、main.pyに入れて」にしたら動作した。

  • git操作

    ファイル操作ができると、openhands上にプッシュしてPRを作成というボタンが出てくるのでそれを押す
    pushボタン
    プッシュボタンを押すとプロンプトが自動で入力され処理が開始される
    プロンプト:Please push the changes to GitHub and open a pull request. Please create a meaningful branch name that describes the changes. If a pull request template exists in the repository, please follow it when creating the PR description.
    結果:無限ループして失敗

gemma3:27b-it-qat

停止してしまい、openhands上では動かない(VRAM不足?)、動いてもランタイムエラーを起こすため、ollama上でコード生成のみ試す

  • コード作成(ollama)
    プロンプト:FastAPIのひな型のコードを作って
    結果:
    はい、FastAPIのひな型のコードを以下に示します。

    from fastapi import FastAPI
    
    app = FastAPI()
    
    @app.get("/")
    async def root():
        return {"message": "Hello World"}
    
    @app.get("/items/{item_id}")
    async def read_item(item_id: int, q: str = None):
        return {"item_id": item_id, "q": q}
    

    <--以下説明-->

  • コード作成(ollama)
    プロンプト:FastAPIのひな型のコードを作って
    結果:

  • git操作
    openhands上で動作しなかったため未検証

  • ファイル操作
    openhands上で動作しなかったため未検証

  • 補足
    gemma3:12bをgemma3:27b-it-qatの代替策として実行しようとしたが、これも同じくランタイムエラーが出た。
    このバージョンでは相性が悪いのかもしれない

モデル別比較(主観評価)

項目 devstral:24b gemma3:27b-it-qat(ollamaで動作)
応答速度 ◎(高速) ◎(高速)
操作精度 △(ファイル操作癖あり) ×
日本語自然さ 出力は英語
VRAM使用量 18GB程度 22GB程度
  • 所感
    • openhandsとローカルLLMのサイズが大きいため動かないこともあって操作がそもそも受け付けなかったり、ループすることが多い。(環境が悪い、VRAM不足などもあるかもしれない)
    • 生成されたFastAPIのテンプレのコードは各LLMで一言一句違わずだった事は正直驚き。
    • テンプレ生成など一部用途では実用的。ただし本格運用には安定性と精度向上が今後の鍵

6. 今後の展望・課題

  • 精度を高めるには?
    • Devstralの出力言語が英語であったことから、日本語よりも英語でプロンプトを書いたほうがいいかもしれない
  • 頻繁に止まるのを避けるには?
    • OpenHands自体の安定性が高くなる(2025年6月12日現在のバージョンは0.42.0)
    • 他ローカル LLM や外部の LLM の使用
    • より軽量かつソフトウェアエンジニアリングに特化したモデルを使う

7. まとめ

  • Devin のような開発支援 AI を、自前環境+ローカル LLM で多少再現可能
  • (電気代や PC 環境代を除く)費用ゼロでそこそこ動くのは魅力的、テンプレ生成など一部用途では実用的だが、本格運用には安定性と精度向上が今後の鍵
  • まだ完全代替とはいかないが、OSS ツールとしてのポテンシャルは期待度が高い

8. 補足リンク

オープン開発チーム

Discussion