OpenHandsのLLMにCloudflare AI Gatewayを使おうとしてダメだった話

OpenHandsを利用したAIコーディングに挑戦中。CloudflareのAI Gatewayは使えない可能性が高い。API構造が異なるため、エラー発生。CloudflareのAPI key取得やAI Gateway作成を試みるも失敗。OpenHandsの準備も進めるも、API認証エラーで実行失敗。401 UnauthorizedエラーでCloudflare AI Gatewayのサポート必要。OSSな解決策を模索。今後同様の課題に直面する方への参考に。

広告ここから
広告ここまで

目次

    OpenHandsを利用したAIコーディングに現在挑戦中です。どのようなモデルやAPIが使えるかを深掘りしてみるため、GitHub Actionsから利用する方法でCloudflareのAI Gatewayが使えるかどうかを検証してみます。

    結論: Cloudflare AI Gatewayは現状使えなさそう

    いくつかのメソッドでパスがハードコードされています。Cloudflare AI GatewayのAPI構造が他のLLMと異なる形式であるため、現状は使うことができなさそうです。以下に発生したエラー文を記載します。

    07:27:16 - openhands:ERROR: agent_controller.py:228 - [Agent Controller default] Error while running the agent (session ID: default): litellm.AuthenticationError: AnthropicException - {"result":null,"success":false,"errors":[{"code":10000,"message":"Authentication error"}],"messages":[]}. Traceback: Traceback (most recent call last):
      File "/opt/hostedtoolcache/Python/3.12.9/x64/lib/python3.12/site-packages/litellm/llms/anthropic/chat/handler.py", line 412, in completion
        response = client.post(
                   ^^^^^^^^^^^^
      File "/opt/hostedtoolcache/Python/3.12.9/x64/lib/python3.12/site-packages/litellm/llms/custom_httpx/http_handler.py", line 557, in post
        raise e
      File "/opt/hostedtoolcache/Python/3.12.9/x64/lib/python3.12/site-packages/litellm/llms/custom_httpx/http_handler.py", line 538, in post
        response.raise_for_status()
      File "/opt/hostedtoolcache/Python/3.12.9/x64/lib/python3.12/site-packages/httpx/_models.py", line 829, in raise_for_status
        raise HTTPStatusError(message, request=request, response=self)
    httpx.HTTPStatusError: Client error '401 Unauthorized' for url '***/v1/messages'

    とはいえせっかくなので、挑戦の記録をここに残しておきます。

    CloudflareのAPI keyを取得する

    CloudflareのAI Gatewayを使うには、ユーザーAPIトークンを取得します。これはアカウントのプロフィールページから取得しましょう。「Workers AI」のテンプレートがありますので、これを使用します。

    取得したトークンはGitHub Actionsで利用しますのでコピーしておきましょう。

    Cloudflare AI Gatewayを作成する

    続いてAI Gatewayを作成しましょう。レート制限については少なくともオフにしておきましょう。

    動作確認のため、curlで呼び出してみましょう。ここではDeepSeekを選んでみました。

     curl -X POST https://gateway.ai.cloudflare.com/v1/xxxxx/for-openhands-demo/workers-ai/@hf/thebloke/deepseek-coder-6.7b-base-awq \
    --header 'Authorization: Bearer CF_TOKEN' \
    --header 'Content-Type: application/json' \
    --data '{"prompt": "What is Cloudflare?"}'

    返答が生成されている様子ならば、Cloudflare側の設定はOKです。

    GitHubリポジトリのシークレットへ投入する

    続いてOpenHandsの準備を始めます。ドキュメントに従って環境変数を設定しましょう。

    • LLM_API_KEY: CloudflareのAPIキー
    • LLM_BASE_URL: Cloudflare AI GatewayのURL

    LLM_MODELも指定できそうなのですが、OpenHandsが想定するフォーマットではないため、今回は指定せずに進めます。

    実行結果: API認証エラーで失敗

    ドキュメントを読む範囲では、これで動きそう・・・に見えます。ただ、実際にActionsを実行するとエラーが発生しました。

    エラーログがこちらです。POSTリクエストがうまくいっていない様子が伺えます。

    07:27:16 - openhands:ERROR: agent_controller.py:228 - [Agent Controller default] Error while running the agent (session ID: default): litellm.AuthenticationError: AnthropicException - {"result":null,"success":false,"errors":[{"code":10000,"message":"Authentication error"}],"messages":[]}. Traceback: Traceback (most recent call last):
      File "/opt/hostedtoolcache/Python/3.12.9/x64/lib/python3.12/site-packages/litellm/llms/anthropic/chat/handler.py", line 412, in completion
        response = client.post(
                   ^^^^^^^^^^^^
      File "/opt/hostedtoolcache/Python/3.12.9/x64/lib/python3.12/site-packages/litellm/llms/custom_httpx/http_handler.py", line 557, in post
        raise e
      File "/opt/hostedtoolcache/Python/3.12.9/x64/lib/python3.12/site-packages/litellm/llms/custom_httpx/http_handler.py", line 538, in post
        response.raise_for_status()
      File "/opt/hostedtoolcache/Python/3.12.9/x64/lib/python3.12/site-packages/httpx/_models.py", line 829, in raise_for_status
        raise HTTPStatusError(message, request=request, response=self)
    httpx.HTTPStatusError: Client error '401 Unauthorized' for url '***/v1/messages'

    エラー文に、 '401 Unauthorized' for url '***/v1/messages'と記載されています。Cloudflare AI Gatewayを使っているならば、v1/messagesというパスにはならないため、この辺りはハードコードされたパスである可能性が高そうです。

    実現するには?

    Cloudflare AI Gatewayをサポートしてもらうしかなさそうです。Amazon BedrockのProxyらしきものがありましたので、同様のクラスを作ってマージしてもらうか、forkすることで対応できるのではないかと思います。この辺りはOSSならではの解決策ではありますね。

    同様にCloudflare AI Gatewayの利用を検討される方が今後出てきた時、この記事が対応や提案の参考になれば幸いです。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark