虎の穴ラボ技術ブログ

虎の穴ラボ株式会社所属のエンジニアが書く技術ブログです

MENU

OpenHands と Ollama で無料のローカル AI コーディングエージェント環境の構築に挑戦してみた

こんにちは。

虎の穴ラボ株式会社の iwady です。

今回は OSS の AI コーディングエージェントツールの OpenHandsOllama を使って

ローカルで無料の AI コーディングエージェント環境の構築に挑戦してみようと思います。

1. OpenHands とは

OpenHands とは、OSS の自律型 AI コーディングエージェントツールです。

「Python で FizzBuzz を書いて」「Pytest でテストを書いて実行して」のように自然言語で指示を行う事で、

コーディング、デバッグ、テスト、ファイル操作、コマンド実行などを自律的に行なってくれます。

github.com

元々は OpenDevin という名前でしたがブランディングや商用である Devin の存在もあって、

現在の OpenHands に改名されました。

特徴としては、OSSである事、ローカル起動が可能である事、多様な LLM モデルを利用可能である事などありますが、

個人的にはコミュニティドリブンなところが非常に良いと思います。

OpenHands のコミュニティが気になる方は、

OpenHands公式GitHubHow to Join the Community をご覧ください。

2. Ollama とは

Ollama はローカルでの LLM 運用をサポートしてくれる OSS です。

今回はローカルにダウンロードしてきた GGUF 形式のモデルファイルを利用するため、Ollama を利用します。

ollama.com

本記事では OpenHands が主題なので Ollama の詳細については割愛しますが、

Ollama については過去の記事で触れていますので、よろしければそちらもご覧ください。

toranoana-lab.hatenablog.com

3. 導入

OpenHands の導入方法は、公式で CLI での起動と Docker の2種類公開されています。

公式で推奨されているのは CLI での起動になりますが、

今回は Ollama も使いますので DockerCompose を使おうかと思います。

また、全ファイルを記載するとかなり冗長になってしまいますので、

ここでは各ファイルの概要と docker-compose.yml について説明します。

4. 構成

構成は以下になります。

整理したい方はディレクトリを切っても大丈夫です。

root
├── Dockerfile
├── Modelfile
├── entrypoint.sh
├── MyCustomModel.gguf
├── .env
├── docker-compose.yml
├── workspace

各ファイルの概要は以下のとおりです。

4-1. Dockerfile

Ollama の Dockerfile になります。執筆時点(2025/9)で最新の 0.11.8 を利用しました。

公式イメージからollamaの実行ファイルのみを抽出し、

ヘルスチェックに必要なソフトをインストールします。

その後、起動スクリプトをコピー+実行権限付与し、ENTRYPOINT で実行する流れです。

MyCustomModel.gguf と Modelfileは Volume で共有しているため、コピーは不要です。

4-2. Modelfile

Modelfile には、ollama create で利用する GGUF モデルを FROM で指定します。

今回は PARAMETER、SYSTEM、TEMPLATE を指定しました。

4-3. entrypoint.sh

entrypoint.sh は、 Ollama の Dockerfile の ENTRYPOINT で指定する起動スクリプトになります。

基本的には ollama serve で Ollama を起動し 、

ollama create MyCustomModel -f Modelfile で Modelfile からカスタムモデルを作成します。

4-4. MyCustomModel.gguf

実際に利用する GGUF モデルです。

今回はローカルでの利用のため、軽量なコーディングエージェント向きのモデルを利用しています。

指示する作業次第で適切なモデルも変わってきますので、作業内容に適切なモデルを選択してください。

ここでは、MyCustomModel.gguf としています。

4-5. .env

.env には OpenHands と Ollama の設定値を定義します。

OpenHands の設定値としては、OH_LLM_MODEL、OH_LLM_BASE_URL、OH_LLM_API_KEY を指定します。

OH_LLM_MODEL は entrypoint.sh で指定したモデル名を指定しましょう。

OH_LLM_API_KEY はローカル実行のため不要ですが、空文字はNGなので適当な文字列を入れておきます。

今回はローカルリポジトリで作業を行いますので、OH_SANDBOX_WORKSPACE なども定義しました。

4-6. docker-compose.yml

docker-compose.yml は以下のようになっています。

# docker-compose.yml
version: '3.8'

services:
  ollama:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_models:/root/.ollama
      # entrypoint.shが参照できるようにモデルファイルを/appにマウント
      - ./MyCustomModel.gguf:/app/MyCustomModel.gguf
      - ./Modelfile:/app/Modelfile
    networks:
      - openhands_net
    environment:
      - OLLAMA_HOST=0.0.0.0
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:11434/"]
      interval: 10s
      timeout: 5s
      retries: 20
      start_period: 120s
    restart: unless-stopped

  openhands:
    image: 'docker.all-hands.dev/all-hands-ai/openhands:0.55'
    container_name: openhands-app
    ports:
      - "3000:3000"
    volumes:
      - './.openhands:/.openhands'
      - '/var/run/docker.sock:/var/run/docker.sock'
    networks:
      - openhands_net
    environment:
      - LLM_MODEL=${OH_LLM_MODEL}
      - LLM_API_KEY=${OH_LLM_API_KEY}
      - LLM_BASE_URL=${OH_LLM_BASE_URL}
      - SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.55-nikolaik
      - SANDBOX_VOLUMES=${OH_SANDBOX_WORKSPACE}
      - SANDBOX_USER_ID=${OH_SANDBOX_USER_ID}
      - LOG_ALL_EVENTS=true
    depends_on:
      ollama:
        condition: service_healthy
    tty: true
    stdin_open: true
    restart: unless-stopped

volumes:
  ollama_models:
    driver: local

networks:
  openhands_net:
    driver: bridge

ollama サービスは Dockerfile からビルドを行い、

openhands サービスは depends_on で ollama サービスが起動且つ healthy になるまで待機するようにしています。

OpenHands は、執筆時点で最新バージョンである 0.55 を利用しました。

SANDBOX_RUNTIME_CONTAINER_IMAGE は実際にローカルでエージェントが作業するコンテナのイメージを指定します。

4-7. workspace

OpenHands が作業するディレクトリです。

今回は OH_SANDBOX_WORKSPACE で指定し、

ホスト上の ./workspace ディレクトリをコンテナ内の /workspace にマウントする形としました。

5. 起動

それでは、docker compose up コマンドで起動してみます。

localhost:3000にアクセスして、以下の画面が起動したら成功です。

LLM Provider に Ollama を選択すると、

LLM Model で MyCustomModel:latest が選べますので、MyCustomModel を選択します。

左サイドメニューの Settings(歯車アイコン)から LLM タブに遷移すると、

現在選択中のモデルや BASE_URL、API KEY などの設定の確認ができますので、

実際に作業を行う前に確認をしておきましょう。

以下のような画面です。

6. 実際に作業してもらってみた

今回は Python で HelloWorld を出力するプログラムの作成を指示してみました。

が、実際の出力は...

上記のように不明な文字列が生成される厳しい結果となりました。

生成結果・速度はモデル・スペックの割当・設定やスクリプトなどに左右されます。

今回はこのような結果になりましたが、

ローカルのカスタムモデルを利用し Ollama と OpenHands で連携する事までは出来ました。

7. 所感

ローカル環境で軽量なコーディングエージェントモデルで試した結果、

パフォーマンス、モデル選定・設定(プロンプトテンプレート等)、環境設定において留意すべき点が見られました。

7-1. パフォーマンスとタイムアウト問題

ローカルの MacBook Pro 環境では、コンテンツ生成に20~30分を要するなど、処理にかなりの時間がかかりました。

また、タイムアウトも頻発したため、LLMとOpenHands間のセッションタイムアウト時間を長めに設定しておくことをお勧めします。

スペック的な負荷も大きいため、もしカスタムモデルを使用しないのであれば、

ローカル環境にこだわらず各種 SaaS の API を利用する方が良いと思います。

7-2. モデル選定・設定(プロンプトテンプレート等)の重要性

今回はローカルの MacBook Pro で完結させたかったので、

低ビット数に量子化されたモデルを使用しましたが、

生成されるコンテンツの品質は利用したモデルに比例する結果となります。

目的や用途に適したモデルを選定しましょう。

また、Modelfile における PARAMETER、SYSTEM、TEMPLATE についても同様で、

モデル毎に適切な設定やスクリプトが必要となりそうです。

7-3. 環境設定における注意点

試行錯誤を繰り返す中で、自動生成される .openhands ディレクトリに過去の設定が残り、

意図しない挙動を引き起こすことがありました。

環境構築の際には .openhands ディレクトリを適宜削除し、

設定をクリアする作業が必要になる時もあるかもしれません。

その場合、エージェントの作業コンテナが残る事がありますので、

こちらも適宜掃除しましょう。

8. まとめ

今回は、Ollama と OpenHands を使い、ローカルで動作する無料のAIコーディングエージェント環境構築に挑戦しました。

目標であったコードの自動生成には至りませんでしたが、

Docker Compose を使って上記 2 つの OSS をスムーズに連携させる手順を確立できたのは、良かったかと思います。

今後は、

  • モデルの品質: 量子化レベルの見直しや、より高性能なモデルを試す

  • プロンプト: モデルに最適化されたテンプレートを用意する

  • パラメータ: temperature などの値を適切に調整する

といった点を改善し、リベンジしたいと思います。

この記事が、ローカル AI エージェント構築を目指している方の一助となれば幸いです。

採用情報

虎の穴では一緒に働く仲間を募集中です!

この記事を読んで、興味を持っていただけた方はぜひ弊社の採用情報をご覧下さい。

カジュアル面談やエンジニア向けイベントも随時開催中です。ぜひチェックしてみてください。

toranoana-lab.co.jp