🤗

openhands cli で Gemini 2.5-flash を使って Cloud Run でアプリケーションをデプロイする

に公開1

概要

タイトルの通りのことをやってみるという企画です。
claude code ってみんないうからうーんどうしよう、会社で使ってもらいたいけど Gemini 使いたいなーっていうのを見てたら openhands っていうのがあって、それの cli が良さそうということで、触ろうというモチベーション

アプリケーションを作ってもらう

とりま動かすだけをやってみます
https://docs.all-hands.dev/usage/how-to/cli-mode

flash でやっているのはめっちゃお金かかったらどうしようという気持ちからです。

export CLOUDSDK_ACTIVE_CONFIG_NAME="xxxxx"
export SANDBOX_VOLUMES="$(pwd):/workspace:rw"
export LLM_API_KEY="google ai studio で取得したkey"
export LLM_MODEL="gemini/gemini-2.5-flash"

API_KEY は ai studio から持ってきます。

documents に置いて volume の部分が良くなかったので、そのあたりを調整しておきます。

docker run -it -P --rm \
    --pull=always \
    -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.44-nikolaik \
    -e SANDBOX_USER_ID=$(id -u) \
    -e SANDBOX_VOLUMES=$SANDBOX_VOLUMES \
    -e LLM_API_KEY=$LLM_API_KEY \
    -e LLM_MODEL=$LLM_MODEL \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v ~/.openhands:/.openhands-state \
    --add-host host.docker.internal:host-gateway \
    --name openhands-app-$(date +%Y%m%d%H%M%S) \
    docker.all-hands.dev/all-hands-ai/openhands:0.44 \
    python -m openhands.cli.main --override-cli-mode true

実行すると以下のように docker container がいます。

ちなみに、port、空いているやつなんなんって言うことで消すと、以下のようにエラーになります(1敗

実際にアプリケーションを作ってもらいます

> typescriptを使ったwebapplicationのサンプルを作成してください

最終 screenshot を吐き出して終了しました。

アプリケーション自体は動くものになりました。(ただのsampleだからあんま意味ないけど)

Cloud Run に deploy

docker build だと、gcloud の設定や docker in docker が面倒だったので、 uvx を使ったほうで実行しています。

> cloud run に deploy してください

なんか Dockerfile をつくり始めました。

というように自動的に色々動いていきます。

  • gcloud config で現状の設定を見てその deploy するプロジェクトを考える
  • gcr.io/project_id/my-ts-app への upload
  • とはいえ container registry は廃止になるので、artifacts docker upgrade migrate までやって、なんだかんだ試行錯誤して artifact registory に image の upload
  • image を使って cloud run に deploy

という感じで作業をしてくれました。
最終的に URL を吐き出してくれました。

またちゃんと deploy まで持っていってくれました

その他

設定

/settings でモデルの情報を設定できます。

設定は以下のように保存されます。ただ cli で動かした際にこのあたりが読まれていなさそうな気がする(language が聞きそうな気もしているが。。。)。

$ cat ~/.openhands/settings.json
{"language":null,"agent":"CodeActAgent","max_iterations":null,"security_analyzer":null,"confirmation_mode":null,"llm_model":"gemini/gemini-2.5-flash","llm_api_key":"xxxxxx","llm_base_url":null,"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,"email":null,"email_verified":null}

status

/status としてやると現在の利用状況が見えます。

使い終わった後に利用 token 量が金額が見えます。

ちなみに今回だと 0 から docker のdeploy 完了までで $0.2 ぐらい。
deploy 後 To allow this host, add "xxxxx.asia-northeast1.run.app" to preview.allowedHosts in vite.config.js. というまぁよくあるエラーが出たので fix してもらって $0.3 ぐらい

まとめ

2回プロンプト打ったら Cloud Run に deploy されていたという事実に驚いています。

利点として claude 以外のモデルを利用できる点と、他の litellm のような proxy を通してやることができます。 https://docs.all-hands.dev/usage/llms/litellm-proxy
コレによりエンタープライズとしては様々なとしては手が取れるかと思います。
LocalLLM を通せるというのもコスト面では考えていっても良さそうな点ですね。

課題として以下が挙げられると思います。

  • claude.md のような設定がなさそう?
  • Browser functionality is not implemented in CLIRuntime とあって、ブラウザ上のエラーを見てもらうことができない
    • コレは cli では対応しないほうが良いのか?そういう指針?
  • ちょっとバギーな部分が多い
    • スクリーンショット取ってくれているのは良いけど落ちる
    • 御愛嬌ですね。後に改善すると思います

このあたりが超えられてくると十分使えてきそうな気がします。
とはいえ、claude code をきちんと触ってからきちんと比較してみようかと思います。

P.S.
ちなみに gemini-2.5-flash-lite を使ってみるとレスポンス早く返ってくるので、見ててちょっと楽しいです。

Discussion