🐡

Apple Silicon Macで動かす OpenHands CLI × Devstral-Small 最速ガイド

に公開

0. はじめに ― “ローカル LLM × OpenHands CLI” の魅力

  • GitHub 連携不要・Docker 不要 —— ただ CLI で「build ○○」と打つだけで自動生成&実行
  • ローカル推論なので通信量ゼロ,社内コードでも安心

1. 前提ツール確認

ツール 推奨バージョン インストール例
uv 0.1 以上 brew install uv
LM Studio 0.2.20 以降 (Apple Silicon ビルド) https://lmstudio.ai/ から DMG ダウンロード
  • uv は pip 互換の超高速パッケージマネージャー。以降のコマンドはすべて uv で実行します。

2. LM Studio に Devstral-Small を読み込み & サーバー起動

  1. LM Studio を起動し Power User モードへ切り替え
  2. 🔍 検索欄に Devstral-Small-2505 を入力 → Download
  3. ⌥ Option キーを押しながら Load で Advanced 画面
    • Context window : 32 k 以上推奨(メモリと相談)
    • Flash Attention : 有効ならチェック
  4. モデルが Running 状態になったら
  5. Settings → Server で Serve on Local Network を ON

これで OpenAI 互換エンドポイント がローカルに立ちました。

3. OpenHands の設定ファイルを作る

mkdir -p ~/.openhands
cat > ~/.openhands/settings.json <<'EOF'
{
  "language": null,
  "agent": "CodeActAgent",
  "max_iterations": null,
  "security_analyzer": null,
  "confirmation_mode": false,
  "llm_model": "lm_studio/mistralai/devstral-small-2505",
  "llm_api_key": "lmstudio",
  "llm_base_url": "http://192.168.11.33:1234/v1",
  "remote_runtime_resource_factor": null,
  "secrets_store": {
    "provider_tokens": {}
  },
  "enable_default_condenser": true,
  "enable_sound_notifications": false,
  "enable_proactive_conversation_starters": true,
  "user_consents_to_analytics": null,
  "sandbox_base_container_image": null,
  "sandbox_runtime_container_image": null,
  "mcp_config": null,
  "search_api_key": null,
  "sandbox_api_key": null,
  "max_budget_per_task": null,
  "email": null,
  "email_verified": null
}
EOF
  • llm_model: LM Studio でコピーしたモデルパス
  • llm_base_url: http://127.0.0.1:ポート/v1 をそのまま
  • llm_api_key: ダミーで OK(LM Studio 側はキー検証しない)

4. ワンライナーで OpenHands CLI を起動

uvx --python 3.12 --from openhands-ai openhands

起動に成功すると ASCII ロゴとともに

What do you want to build? Type /help for help
>

が表示されます。

試運転:Hello, World! スクリプトを作成

  1. 任意の空ディレクトリで CLI を起動
  2. プロンプトに
    build python script hello.py
    
  3. 実際のやり取り
長いので格納
     ___                    _   _                 _
    /  _ \ _ __   ___ _ __ | | | | __ _ _ __   __| |___
    | | | | '_ \ / _ \ '_ \| |_| |/ _` | '_ \ / _` / __|
    | |_| | |_) |  __/ | | |  _  | (_| | | | | (_| \__ \
    \___ /| .__/ \___|_| |_|_| |_|\__,_|_| |_|\__,_|___/
          |_|
    
OpenHands CLI v0.48.0

Initialized conversation 2eec8499-59f3-4765-8c5a-a7e73dfbe7dc-1e09f1e17d372467

Let's start building!

What do you want to build? Type /help for help

> build python script hello.py

Agent running... (Press Ctrl-P to pause)

I'll create a simple Python script called `hello.py` for you. Let me first check the current directory structure to make sure we're in the right place.

┌─────────────────────────────────────────────| Command |─────────────────────────────────────────────┐
│$ ls -la /Users/user/Downloads/openhands-test                                                        │
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘

Proceed with action? (y)es/(n)o/(a)lways > y

┌─────────────────────────────────────────| Command Output |──────────────────────────────────────────┐
│total 0
│drwxr-xr-x   2 user  staff   64  7  8 19:52 .                                                        │
│drwx------@ 16 user  staff  512  7  8 19:52 ..                                                       │

└─────────────────────────────────────────────────────────────────────────────────────────────────────┘

Agent running... (Press Ctrl-P to pause)

Now, let's create a simple Python script called `hello.py` that prints "Hello, World!" to the console.

┌────────────────────────────────────────────| File Edit |────────────────────────────────────────────┐
│(no changes detected. Please make sure your edits change the content of the existing file.)          │
│                                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘

Now let's make the script executable by changing its permissions.

┌─────────────────────────────────────────────| Command |─────────────────────────────────────────────┐
│$ chmod +x /Users/user/Downloads/openhands-test/hello.py                                             │
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘

Proceed with action? (y)es/(n)o/(a)lways > y

┌─────────────────────────────────────────| Command Output |──────────────────────────────────────────┐

└─────────────────────────────────────────────────────────────────────────────────────────────────────┘

Agent running... (Press Ctrl-P to pause)

Let's verify that the script was created correctly by displaying its contents.

┌─────────────────────────────────────────────| Command |─────────────────────────────────────────────┐
│$ cat /Users/user/Downloads/openhands-test/hello.py                                                  │
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘

Proceed with action? (y)es/(n)o/(a)lways > y

┌─────────────────────────────────────────| Command Output |──────────────────────────────────────────┐
│                                                                                                     │
│#!/usr/bin/env python3                                                                               │
│                                                                                                     │
│def main():                                                                                          │
│    print("Hello, World!")                                                                           │
│                                                                                                     │
│if __name__ == "__main__":                                                                           │
│    main()                                                                                           │
│                                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘

Agent running... (Press Ctrl-P to pause)

Now let's test the script to make sure it works as expected.

┌─────────────────────────────────────────────| Command |─────────────────────────────────────────────┐
│$ python3 /Users/user/Downloads/openhands-test/hello.py                                              │
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘

Proceed with action? (y)es/(n)o/(a)lways > y

┌─────────────────────────────────────────| Command Output |──────────────────────────────────────────┐
│Hello, World!                                                                                        │

└─────────────────────────────────────────────────────────────────────────────────────────────────────┘

Agent running... (Press Ctrl-P to pause)

Great! The script is working correctly. Here's a summary of what we've done:

1. Created a Python script called `hello.py` in the `/Users/user/Downloads/openhands-test` directory.
2. Made the script executable by changing its permissions.
3. Verified that the script works as expected.

The `hello.py` script contains a simple Python program that prints "Hello, World!" to the console when executed. The script follows best practices by:
- Using the shebang line `#!/usr/bin/env python3` to ensure it runs with Python 3
- Defining a `main()` function that contains the core functionality
- Using the standard Python idiom for conditional execution of code when the script is run directly

You can now use this script as a starting point for more complex Python programs.

I've created a simple Python script called `hello.py` in the `/Users/user/Downloads/openhands-test` directory. The script prints "Hello, World!" to the console when executed. I've also made it executable and verified that it works correctly.

Task completed...

>                                                                                                      

Terminate session?

> Yes, proceed
  No, dismiss
 
Closing current conversation...

┌──────────────────────────────────────────| Usage Metrics |──────────────────────────────────────────┐
   Total Cost (USD):    $0.000000                                                                    │

   Total Input Tokens:  22,301                                                                       │
      Cache Hits:       0
      Cache Writes:     0
   Total Output Tokens: 565

   Total Tokens:        22,866                                                                       │
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘


6. 終了と Usage Metrics の見かた

exit で終了すると下記のような統計が表示されます。


┌──────────────────────────────────────────| Usage Metrics |──────────────────────────────────────────┐
│   Total Cost (USD):    $0.000000                                                                    │
│                                                                                                     │
│   Total Input Tokens:  22,301                                                                       │
│      Cache Hits:       0                                                                            │
│      Cache Writes:     0                                                                            │
│   Total Output Tokens: 565                                                                          │
│                                                                                                     │
│   Total Tokens:        22,866                                                                       │
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘

さいごに

これで 完全ローカル な AI コーディング環境が完成!
あとは “ポケモン図鑑を作って” など自由に指示を与えてみてください 🛠️

Discussion