はじめに
みなさんこんにちは!!!!!
今朝、突然OpenHandsのCLI版が降ってきて飛び起きたんですが、アツいですねー!
最近はタイムラインを眺めていてもClaude Code一色なわけですが、Claude Codeは基本的にClaudeのモデルしか利用できないので比較的高価です。
(Maxプランで定額$200は、むしろ安いくらいだと思っていますが…)
Claude Code自体は最高ですが、この間のGCPの大規模障害の件などもあり、一応代替手段は持っておきたいなーと思っていたところでこのポストだったので、使わざるを得ませんでした!
最近のGeminiは激安だったり、オープンLLMの性能も上がってきたりするので、ハードルはさらに下がっていると思います!
なので今回はOpenHands CLIとオープン(ローカル)LLMでコーディングエージェントを構築してみることにします!
本記事では、OllamaとLiteLLM Proxyを使用して、完全にローカル環境でOpenHands CLIを動作させる方法を詳しく解説します!
環境構築
今回はmacOSでのコマンドを紹介していきますが、インストール方法以外はさほど変わらないと思うので、適宜読み替えてください!
Python環境の確認
OpenHands CLIはPython 3.12以上が必要ですので、確認しておきましょう。
Pythonのバージョンはuv
を利用するのが楽です。
こちらの記事なんかが参考になると思います!!
❯ python -V
Python 3.12.5
OpenHands CLIのインストール
pipを使って簡単にインストールできます。
❯ pip install openhands-ai
Ollamaのセットアップ
ローカルLLMを実行するためにOllamaを使用します。
僕はこの記事をいろいろ参考にしました!
# macOSの場合
❯ brew install ollama
# インストールの確認
❯ ollama -v
ollama version is 0.9.0
4. モデルのダウンロード
今回は高性能なQwen3の32Bモデルを使用します。
モデル性能(パラメーター数)と利用可能PCスペックはだいたいこんなイメージらしいです。
32Bのモデルを動かすにはそれなりのスペックのPCが必要ですので、もっと小さいモデルでも良いと思います!
ローカルllmの基礎から最新モデル比較・実践導入まで徹底解説【2025年版】
# モデルのダウンロード
❯ ollama pull qwen3:32b
# ダウンロードしたモデルの確認
❯ ollama ls
NAME ID SIZE MODIFIED
qwen3:32b 030ee887880f 20 GB 9 hours ago
# モデルの動作確認
❯ ollama run qwen3:32b
>>> Send a message (/? for help)
基本設定
OpenHands CLIをローカルLLMで使う方法は2つあります。
方法1: Ollamaに直接接続
最もシンプルな方法は、OpenHands CLIから直接Ollamaに接続することです。
まずOllamaのサーバーが起動している確認します。
# サーバーの立ち上げ
❯ ollama serve
Error: listen tcp 127.0.0.1:11434: bind: address already in use
# 立ち上がっているプロセスの確認
❯ lsof -i:11434
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ollama TCP localhost:11434 (LISTEN)
address already in use
というエラーが出て、すでにポートが占有されてしまっていますが、利用プロセスを調べるとollamaが立ち上がっているのが確認できますね!
次に~/.openhands/settings.json
を作成し、以下の内容を記述します。
先ほどダウンロードしたきたモデルの名称や、ローカルマシンのOllamaのURLを書き加えてあげます。
llm_api_key
は空文字でも良いはずですが、慣例としてollamaと記述しておくとかなんとか。
{
"llm_model": "ollama/qwen3:32b",
"llm_api_key": "ollama",
"llm_base_url": "http://localhost:11434",
"mcp_config": null
}
方法2: LiteLLM Proxy経由での接続
LiteLLMは様々なツールから配信されるモデルを統合して呼び出し可能にするツールです。
Ollamaのみを利用するよりも、より柔軟な設定が可能で、LiteLLM Proxyを利用することでhttp経由で複数のモデルを呼び出すことができます
LiteLLM Proxyのインストール
こちらもpip経由でインストールすることができます。
❯ pip install 'litellm[proxy]'
設定ファイルの作成
設定ファイルはどこに作ってもいいんですが、今回は~/.config/litellm/config.yml
を作成します。
以下の内容を記述します。
model_list:
- model_name: qwen3
litellm_params:
model: ollama/qwen3:32b
api_base: "http://localhost:11434"
model_info:
supports_function_calling: true
litellm_settings:
master_key: "my-master-key"
上記設定でOllamaを利用してインストールし、起動しているモデルのプロキシとして立ち上がることができます。
master_keyは空文字でもいいらしいですが慣例的にうんぬんかんぬん…
model_name
は任意のものを設定して良いですが、itellm_params.model
については<プロバイダー>/<モデル名>
で、かつモデル名は32b
まで含めた正確なものを記載する必要があるようです。
LiteLLM Proxyの起動
以下のようなコマンドでサーバーを起動できます!
--config
を指定することで、model_list
に設定されたモデルを利用することができます。
いちいちコマンドに設定ファイルのパスを入力するのがめんどくさい場合は、環境変数が設定できたはずです。
詳しくは公式を…
❯ litellm --config ~/.config/litellm/config.yml --port 8888
OpenHands CLIの設定
LiteLLMを利用する場合は以下のような設定になります。
~/.openhands/settings.json
を以下のように設定します:
{
"llm_model": "litellm_proxy/qwen3",
"llm_api_key": "my-master-key",
"llm_base_url": "http://localhost:8888",
"mcp_config": null
}
動作確認
LiteLLM Proxyが正しく動作しているか確認してみましょう。
curl -X POST 'http://0.0.0.0:8888/chat/completions' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer my-master-key' \
-d '{
"model": "qwen3",
"messages": [
{
"role": "user",
"content": "こんにちは。今日は何をしますか?"
}
]
}'
{
"id": "chatcmpl-08f6c7c2-f95e-4602-ba12-e4cdbf98887d",
"created": 1750253624,
"model": "ollama/qwen3:32b",
"object": "chat.completion",
"system_fingerprint": null,
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"content": "<think>\nThe message is in Japanese. It says \"Hello. What are you doing today?\" or more naturally \"Hi, what are you up to today?\"\n\nI should respond in Japanese since the question was asked in Japanese. I'll greet them back and offer to help with whatever they might be planning for the day.\n\nMy response should be friendly and open-ended to allow them to share what they're interested in doing.\n</think>\n\nこんにちは!今日は特に予定がありませんが、何か面白いことを計画しています。あなたはどんな一日にしたいですか?何かお手伝いできることがあれば、いつでも教えてください!",
"role": "assistant",
"tool_calls": null,
"function_call": null
}
}
],
"usage": {
"completion_tokens": 127,
"prompt_tokens": 19,
"total_tokens": 146,
"completion_tokens_details": null,
"prompt_tokens_details": null
}
}
正常にレスポンスが返ってくれば、設定は成功です。
OpenHands CLIの実行
設定が完了したら、OpenHands CLIを実行してみましょう!
❯ openhands
> あなたはどのようなことができますか?返事をしてください。
<think>
Okay, the user is asking, "あなたはどのようなことができますか?返事をしてください。" which translates to "What can you do? Please reply." I need to explain the capabilities based on the tools provided.
First, looking at the available functions: execute_bash, str_replace_editor, browser, and finish. These allow running commands, editing files, controlling the browser, and ending the session.
The example showed creating a Flask app, handling errors, and modifying code. So, I should mention web development help, file manipulation, running servers, and browser interactions. Also, note the restrictions like working directory and file access.
I should structure the response to list key abilities, mention the tools used, and clarify limitations. Make sure to use the function call format if needed, but since the user is asking about capabilities, a regular response is appropriate here.
</think>
I can assist with tasks involving file manipulation, running servers, browser automation, and basic development workflows within the allowed directory (~/sample-project). Key capabilities include:
1. Creating/editing files (via `str_replace_editor`)
2. Running command-line tools (via `execute_bash`)
3. Controlling browser interactions (via `browser` function)
4. Setting up simple web servers
5. Debugging and error resolution
I can only access files in the specified working directory and its subdirectories. Let me know what specific task you'd like to accomplish!
ちゃんとエージェントとして動作してそうですね!!!
これで、完全にローカル環境でAIエージェントを実行できるようになりました!!!
まとめ
OpenHands CLIを使うことで、完全にローカル環境でAIエージェントを実行できるようになりました!
特にLiteLLM Proxyを経由することで、柔軟な設定と拡張性を持たせることができます。
あまりオープンLLMを利用したことがなかったのですが、以下のようなメリットとデメリットがあるなーと思いました!
メリット
- プライバシーが完全に保護される
- APIコストがかからない
- オフライン環境でも動作する
- カスタマイズが容易
デメリット
- 初期設定がやや複雑
- 高性能なハードウェアが必要(特に大規模モデルの場合)
- モデルのダウンロードに時間がかかる
ただ、初期設定もそこまで大変ではないですし、今後、ローカルLLMの性能は向上していくことが目に見えているので、どんどん面白くなっていくと思います!
皆さんも使ってみましょうー!