ラベル litellm の投稿を表示しています。 すべての投稿を表示
ラベル litellm の投稿を表示しています。 すべての投稿を表示

2026年7月22日水曜日

Aider CLI + litellm で独自のエンドポイントを使う方法

Aider CLI + litellm で独自のエンドポイントを使う方法

概要

前回 Hermes CLI + litellm を試しました
今回は Aider CLI を試してみます

なお LLM は gpt を使い設定は Hermes と同じでいけます

環境

  • Ubuntu 24.04
  • Aider 0.86.2
  • litellm 1.90.2

インストール

  • curl -LsSf https://aider.chat/install.sh | sh

litellm_config.yaml

Azure OpenAI の gpt-5.1 をモデルを使う場合は以下のようにします
モデル名は適宜変更してください

model_list:
  - model_name: chatAI
    litellm_params:
      model: azure/gpt-5.1
      api_base: https://your-custom-endpoint/gpt-5.1
      api_key: os.environ/AI_SERVICE_API_KEY
      max_tokens: 4096
      temperature: 0.2
      rpm: 30
      tpm: 60000
    model_info:
      base_model: azure/gpt-5.1

litellm_settings:
  drop_params: true

general_settings:
  global_max_parallel_requests: 1
  max_parallel_requests: 1
  max_request_size_mb: 10

router_settings:
  num_retries: 0
  retry_after: 20
  allowed_fails: 1
  cooldown_time: 180
  timeout: 120
  stream_timeout: 120

server_settings:
  port: 4000

compose.yaml

litellm を起動します

services:
  litellm:
    image: docker.litellm.ai/berriai/litellm:latest
    container_name: litellm
    environment:
      - AI_SERVICE_API_KEY=${AI_SERVICE_API_KEY}
    ports:
      - "4000:4000"
    volumes:
      - ./litellm_config.yaml:/app/config.yaml
    restart: unless-stopped
    command: ["--config", "/app/config.yaml"]

動作確認

  • export AI_SERVICE_API_KEY=secret
  • docker compose up -d

で LiteLLM を起動します

  • export OPENAI_API_BASE=http://localhost:4000/v1
  • export OPENAI_API_KEY=dummy
  • aider --model openai/chatAI

設定ファイルではなく環境変数で LiteLLM に向けます
aider が OpenAI 互換の API を使うように openai/ というプレフィックスを付与してプロバイダ名を指定します

最後に

Aider + LiteLLM の設定を紹介しました
Aider 自体が内部的に LiteLLM を使っているので簡単に呼べるようになっていました

参考サイト

2026年7月21日火曜日

Hermes CLI + litellm で独自のエンドポイントを使う方法

Hermes CLI + litellm で独自のエンドポイントを使う方法

概要

前回 gemini-cli でカスタムエンドポイントを使う方法を紹介しました
今回は Hermes CLI でカスタムエンドポイントを紹介します
ただ gemini は使えなかったので gpt を使います (前回のように Python で頑張ればできるかもです)

環境

  • Ubuntu 24.04
  • hermes cli 0.18.2
    • python 3.11.15

インストール

  • curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash

~/.hermes/config.yaml

hermes cli からは litellm を使うように指定します
デフォルトだと他にも設定項目がいろいろありますが model の部分だけ以下のように修正してください
それ以外の項目はそのままで OK です

model:
  default: chatAI
  provider: custom
  base_url: http://localhost:4000/v1
  api_key: dummy

litellm_config.yaml

Azure OpenAI の gpt-5.1 をモデルを使う場合は以下のようにします
モデル名は適宜変更してください

model_list:
  - model_name: chatAI
    litellm_params:
      model: azure/gpt-5.1
      api_base: https://your-custom-endpoint/gpt-5.1
      api_key: os.environ/AI_SERVICE_API_KEY
      max_tokens: 4096
      temperature: 0.2
      rpm: 30
      tpm: 60000
    model_info:
      base_model: azure/gpt-5.1

litellm_settings:
  drop_params: true

general_settings:
  global_max_parallel_requests: 1
  max_parallel_requests: 1
  max_request_size_mb: 10

router_settings:
  num_retries: 0
  retry_after: 20
  allowed_fails: 1
  cooldown_time: 180
  timeout: 120
  stream_timeout: 120

server_settings:
  port: 4000

compose.yaml

litellm を起動します

services:
  litellm:
    image: docker.litellm.ai/berriai/litellm:latest
    container_name: litellm
    environment:
      - AI_SERVICE_API_KEY=${AI_SERVICE_API_KEY}
    ports:
      - "4000:4000"
    volumes:
      - ./litellm_config.yaml:/app/config.yaml
    restart: unless-stopped
    command: ["--config", "/app/config.yaml"]

動作確認

  • export AI_SERVICE_API_KEY=secret
  • docker compose up -d
  • hermes

最後に

Hermes CLI + litellm でカスタムエンドポイントを設定する方法を紹介しました
Hermes CLI 自体は Google AI Studio に対応しているので使えます
設定しているカスタムエンドポイント側の gemini が function calling や web_search に対応していなかったりリクエストやレスポンスの形式が少し異なる場合にはそのままでは使えません

前回のように Python なりでプロキシを立てて工夫する必要がありそうです

参考サイト

2026年7月17日金曜日

Gemini CLI + litellm で独自のエンドポイントを使う方法

Gemini CLI + litellm で独自のエンドポイントを使う方法

概要

前回 Codex 版を紹介しましたが今回は Gemini CLI での方法を紹介します

環境

  • Ubuntu 24.04
  • nodejs 22.21.0
  • gemini-cli 0.51.0

インストール

  • npm install -g @google/gemini-cli

構成概要

  • gemini-cli -> python proxy (docker) -> litellm (docker) -> custom endpoint

という流れになっています
python proxy は nginx などでも代用できるケースはありますが今回はリクエストを削る必要があるため python (fastapi) を使っています

理由は custom endpoint が gemini に完全に互換しているわけではなく使える機能により受け付けないパラメータがあるためそれを削るために用意しています
なので custom endpoint が完全互換であれば litellm だけで OK です

compose.yaml

gemini-proxy が python 製のプロキシになります
fastapi で gemini-cli から来たリクエストを受け使えないパラメータを削った後 litellm にリクエストします

services:
  litellm:
    image: docker.litellm.ai/berriai/litellm:latest
    container_name: litellm
    environment:
      - AI_SERVICE_API_KEY=${AI_SERVICE_API_KEY}
    ports:
      - "4000:4000"
    volumes:
      - ./litellm_config.yaml:/app/config.yaml
    restart: unless-stopped
    command: ["--config", "/app/config.yaml"]

  gemini-proxy:
    # Python proxy for gemini CLI (native Gemini API format).
    # Replaces nginx because request body JSON transformation is required:
    # strips unsupported 'id' field from function_call/function_response,
    # rewrites :streamGenerateContent?alt=sse → :streamGenerateContentSse,
    # and injects AI_SERVICE_API_KEY as x-goog-api-key header.
    # Configure gemini CLI to use port 4001 instead of 4000.
    build:
      context: .
      dockerfile: Dockerfile.proxy
    container_name: gemini-proxy
    environment:
      - AI_SERVICE_API_KEY=${AI_SERVICE_API_KEY}
    ports:
      - "4001:4001"
    restart: unless-stopped

proxy.py

API を互換させるためのプロキシです
先ほども紹介しましたが custom endpoint が完全互換の場合は不要です

#!/usr/bin/env python3
"""
Proxy for gemini CLI → Your custom Gemini endpoint.

Handles:
- URL mapping: :streamGenerateContent?alt=sse → :streamGenerateContentSse
- Request body: strip unsupported 'id' field from function_call / function_response
- Auth: replace incoming key with AI_SERVICE_API_KEY as x-goog-api-key header
"""

import json
import os

import httpx
from fastapi import FastAPI, Request
from fastapi.responses import Response, StreamingResponse

CUSTOM_BASE = os.environ.get(
    "CUSTOM_BASE",
    "https://your-gemini-custom-endpoint",
)
API_KEY = os.environ["AI_SERVICE_API_KEY"]

app = FastAPI()


def strip_unsupported_fields(body: dict) -> dict:
    """Strip 'id' from function_call/function_response — field not supported by this endpoint."""
    for content in body.get("contents", []):
        for part in content.get("parts", []):
            for key in ("functionCall", "function_call"):
                if isinstance(part.get(key), dict):
                    part[key].pop("id", None)
            for key in ("functionResponse", "function_response"):
                if isinstance(part.get(key), dict):
                    part[key].pop("id", None)
    return body


@app.post("/v1beta/models/{model}:{method}")
async def proxy(request: Request, model: str, method: str):
    is_streaming = method == "streamGenerateContent"
    # Custom endpoint uses a dedicated SSE endpoint instead of ?alt=sse query param
    target_method = "streamGenerateContentSse" if is_streaming else method
    target_url = f"{CUSTOM_BASE}/{model}:{target_method}"

    body_bytes = await request.body()
    try:
        body = strip_unsupported_fields(json.loads(body_bytes))
        body_bytes = json.dumps(body, ensure_ascii=False).encode()
    except (json.JSONDecodeError, AttributeError):
        pass

    upstream_headers = {"Content-Type": "application/json", "x-goog-api-key": API_KEY}

    if is_streaming:

        async def generate():
            async with httpx.AsyncClient(timeout=120.0) as client:
                async with client.stream(
                    "POST", target_url, content=body_bytes, headers=upstream_headers
                ) as resp:
                    async for chunk in resp.aiter_bytes():
                        yield chunk

        return StreamingResponse(
            generate(),
            media_type="text/event-stream",
            headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"},
        )
    else:
        async with httpx.AsyncClient(timeout=120.0) as client:
            resp = await client.post(
                target_url, content=body_bytes, headers=upstream_headers
            )
        return Response(
            content=resp.content,
            status_code=resp.status_code,
            media_type=resp.headers.get("content-type", "application/json"),
        )

Dockerfile.proxy

先程の proxy.py をビルドしてイメージを作成する dockerfile です

FROM python:3.12-slim
WORKDIR /app
RUN pip install --no-cache-dir fastapi httpx uvicorn
COPY proxy.py .
CMD ["uvicorn", "proxy:app", "--host", "0.0.0.0", "--port", "4001"]

litellm_config.yaml

gemini-3.1-flash-lite 側は基本不要ですが gemini-cli がデフォルトで gemini-3.1-flash-lite のモデルの定義を探しに行くのでエラーにならないように追加しています
pass_through_endpoints でパスのオーバライドをしていますがこれも状況によるので必須ではないです

model_list:
  - model_name: gemini-3.5-flash
    litellm_params:
      # gemini/ prefix is required to use API key auth instead of Vertex AI ADC.
      # Model name must match model_name above to avoid LiteLLM response model override error
      # that corrupts streaming responses. drop_params: true handles unsupported fields.
      model: gemini/gemini-3.5-flash
      api_base: https://your-gemini-custom-endpoint:generateContent
      api_key: os.environ/AI_SERVICE_API_KEY
      max_tokens: 4096
      temperature: 0.2
      rpm: 30
      tpm: 60000
  - model_name: gemini-3.1-flash-lite
    litellm_params:
      # gemini/ prefix is required to use API key auth instead of Vertex AI ADC.
      model: gemini/gemini-3.5-flash
      api_base: https://your-gemini-custom-endpoint:generateContent
      api_key: os.environ/AI_SERVICE_API_KEY

litellm_settings:
  drop_params: true

general_settings:
  global_max_parallel_requests: 1
  max_parallel_requests: 1
  # Pass-through: forward native Gemini API requests (/v1beta/models/...) directly
  # to the upstream endpoint, bypassing LiteLLM's model routing and SDK layer.
  # This avoids the "cannot override response model" bug caused by GenerateContentResponse
  # not having a 'model' attribute in LiteLLM's google_genai provider path.
  pass_through_endpoints:
    - path: "/v1beta/models/{path:path}"
      target: "https://your-gemini-custom-endpoint/gemini/{path}"
      headers:
        x-goog-api-key: os.environ/AI_SERVICE_API_KEY

router_settings:
  num_retries: 0
  retry_after: 20
  allowed_fails: 1
  cooldown_time: 180
  timeout: 120
  stream_timeout: 120

server_settings:
  port: 4000

動作確認

  • docker compose up -d
  • export GOOGLE_GEMINI_BASE_URL="http://localhost:4001"
  • gemini --model=gemini-3.5-flash

で「hi」とか打ってレスポンスが返ってくればとりあえず接続はできています

最後に

gemini-cli + litellm + custom endpoint の設定方法を紹介しました

独自のエンドポイントが提供している gemini などがあり API が完全互換していない場合は自分でリクエストやレスポンスを細工する必要があります
今回は fastapi + litellm で対応しましたが方法は様々なので自分に合う方法で互換させれば OK です

基本はエラーに合わせてプロキシや litellm 側で調整するしかないです

{
  "error": {
    "code": 400,
    "message": "Invalid JSON payload received. Unknown name \"id\" at 'contents[2].parts[0].function_call': Cannot find field.\nInvalid JSON payload received. Unknown name \"id\" at 'contents[3].parts[0].function_response': Cannot find field.",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.BadRequest",
        "fieldViolations": [
          {
            "field": "contents[2].parts[0].function_call",
            "description": "Invalid JSON payload received. Unknown name \"id\" at 'contents[2].parts[0].function_call': Cannot find field."
          },
          {
            "field": "contents[3].parts[0].function_response",
            "description": "Invalid JSON payload received. Unknown name \"id\" at 'contents[3].parts[0].function_response': Cannot find field."
          }
        ]
      }
    ]
  }
}

参考サイト

2026年7月3日金曜日

Codex + LiteLLM + カスタムOpenAIエンドポイントの設定方法

Codex + LiteLLM + カスタムOpenAIエンドポイントの設定方法

概要

素の OpenAI エンドポイントではなく特定の環境でラップされている URL の場合には LiteLLM を挟みましょう もしくは API が完全非互換でなかったり https プロトコルのみ提供されている場合なども LiteLLM を挟むと解決することがあります

環境

  • Ubuntu 24.04
  • codex 0.142.5
  • LiteLLM 1.90.0

LiteLLM 設定

api_base と api_key に自身の環境のカスタムOpenAIエンドポイントとカギを設定しましょう

  • vim litellm/litellm_config.yaml
model_list:
  - model_name: claude-chatAI
    litellm_params:
      model: anthropic/claude-sonnet-4-6
      api_base: https://your-api-endpoint
      api_key: xxx
      max_tokens: 4096
      temperature: 0.2

server_settings:
  port: 4000
  • vim litellm/compose.yaml
services:
  litellm:
    image: docker.litellm.ai/berriai/litellm:latest
    container_name: litellm
    ports:
      - "4000:4000"
    volumes:
      - ./litellm_config.yaml:/app/config.yaml
    restart: unless-stopped
    command: ["--config", "/app/config.yaml"]
  • docker compose up -d

codex 設定

base_url は LiteLLM が Listen しているアドレスで env_key は下記の SONNET_API_KEY を指定します
LiteLLM 側で認証情報を指定していますが一応 codex 側でも鍵情報を指定するためです

  • vim ~/.codex/litellm.config.toml
model_provider = "litellm"
model = "anthropic/claude-sonnet-4-6"
web_search = "disabled"

[model_providers.litellm]
name = "sonnet"
base_url = "http://localhost:4000"
env_key = "SONNET_API_KEY"
wire_api = "responses"

動作確認

  • export SONNET_API_KEY="xxx"
  • codex --profile litellm

これでインタラクティブモードで起動するので「test」など投げて応答がくれば OK です

最後に

たぶん OpenInterpreter も同じ方法でいけます
--full-auto オプションなどは廃止になっているの注意しましょう

参考サイト

https://docs.litellm.ai/docs/tutorials/openai_codex

2025年5月12日月曜日

OpenWebUI で Filesystem MCP Server を使ってローカルにあるファイルなどを操作する

OpenWebUI で Filesystem MCP Server を使ってローカルにあるファイルなどを操作する

概要

各種設定などは前回のものを流用しています

環境

  • Ubuntu 24.04
  • OpenWebUI 0.6.7
  • LiteLLM Proxy 1.68.1
  • Python 3.12.9
    • mcpo 0.0.13
    • mcp 1.8.0
  • secure-filesystem-server - v0.2.0

config.json

{
  "mcpServers": {   
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/home/devops"
      ]
    }
  }
}

/home/devops の部分は MCP サーバにファイルやディレクトリの操作を許可するパスをフルパスで指定します

OpenWebUI から接続の追加

これは前回までと全く同じです
URL は適宜変更してください

設定 -> ツール -> 追加

  • URL -> http://192.168.0.100:8000/filesystem
  • Auth -> Bearer top-secret

動作確認

あとは質問するだけですがいろいろと工夫が必要だったのでポイントを紹介します

  • フルパスで指定すること
    • 相対パスでは MCP サーバが起動しているパスからの相対パスで検索しようとするのでフルパスで指定したほうがいい
  • 質問に工夫が必要なケースがある
    • OK /home/devops/api 配下のファイルでファイル名に py が含まれるファイルの一覧を表示してください
    • NG /home/devops/api 配下に py で終わる拡張子のファイルの一覧を表示してください
    • 以下のようなクエリとなる質問にしなければならない
    • 拡張子などを質問に含めると pattern が「.*\\.py」というマッチしない条件になったりする
curl -X POST \
     -H "Authorization: Bearer top-secret" \
     -H "Content-Type: application/json" \
     -d '{"path": "/home/devops/api", "pattern": "py", "excludePatterns": []}' \
     http://localhost:8000/filesystem/search_files
  • Filesystem MCP サーバが実装している機能を確認したほうがいいかも (参考サイトのURL参照)
  • 便利な使い方はいろいろあるがローカルにあるプログラムへのパスを指定して「このファイルが何をしているか説明して」というのは便利
    • 今までは自分でコピペしてコンソールなどに食わせていたのがそれをしなくて済む
    • ただそのあと直接ファイルを編集してなどはできなかった (質問の仕方なのかそういった機能がないのかは不明)

最後に

Filesystem MCP サーバを OpenWebUI に導入してみました
自然言語でローカルのファイルを操作できるようになるのは便利かなと思います
ただシェルが扱えればわざわざ MCP サーバを導入するレベルでもないかなとは思いました

参考サイト

2025年5月11日日曜日

OpenWebUI で mcp-server-mysql を使って自然言語で MySQL を操作してみる

OpenWebUI で mcp-server-mysql を使って自然言語で MySQL を操作してみる

概要

前回 open-webui から mcp サーバに接続する方法法を紹介しました
今回は localhost にある mysql サーバに接続しいろいろな操作を試してみます
なお INSERT,UPDATE,DELETE も行える設定なのでテスト用のテーブルなどに対して行いましょう

環境

  • Ubuntu 24.04
  • OpenWebUI 0.6.7
  • LiteLLM Proxy 1.68.1
  • Python 3.12.9
    • mcpo 0.0.13
    • mcp 1.8.0
  • @benborla29/mcp-server-mysql - v0.1.18

nodejs 環境準備

mcp-server-mysql は nodejs で動作するので nodejs が動作する環境を準備します
何でも OK ですが今回は nvm を使う方法を紹介します

  • nvm use --save 20.19.0

ここで保存された .nvmrc があるパスで MCPO を動かします

config.json

mcpServers に追記します
今回は INSERT,UPDATE,DELETE も試したいので ALLOW_INSERT_OPERATION などは true に設定しています

{
  "mcpServers": {
    "time": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "mcp/time"]
    },
    "mcp_server_mysql": {
      "command": "npx",
      "args": [
        "-y",
        "@benborla29/mcp-server-mysql"
      ],
      "env": {
        "MYSQL_HOST": "127.0.0.1",
        "MYSQL_PORT": "3306",
        "MYSQL_USER": "test",
        "MYSQL_PASS": "xxx",
        "MYSQL_DB": "devops",
        "ALLOW_INSERT_OPERATION": "true",
        "ALLOW_UPDATE_OPERATION": "true",
        "ALLOW_DELETE_OPERATION": "true"
      }
    }
  }
}

localhost で mysql -u test-p devops -h 127.0.0.1 でアクセスできれば上記でもアクセスできます

MCPO 起動

先ほど作成した .nvmrc と config.json があるパスで実行します

  • pipenv run mcpo --port 8000 --host 0.0.0.0 --config ./config.json --api-key "top-secret"

MCP サーバの接続

open-webui から行います
uri の部分は config.json に定義した MCP サーバのキー情報を入力します
Bearer は api_key で指定した情報をしていします   接続テストもしておきましょう

動作確認

チャット上のツールが増えていることを確認します
あとはテーブル情報などを含めて質問することでいろいろな操作をしてくれます

MCPO のログを見ると実際に投げている SQL の情報なども確認できます

最後に

open-webui + mcp-server-mysql を試してみました
自然言語でデータベースを操作できる時代が本格的に到来したなと実感しました
以下は試してみた感想です
本番ではまだ使わないほうが安全かなと思います

命令を詳細にすれば実用レベルになる気はします

  • 雑なSQLを投げたりするので本番では更新削除追加系はやらないほうがよさそう
    • WHERE 句 id などのユニークキーを使わずに更新や削除を行ったりする
    • 命令をしっかりすれば id を使ってやってはくれそうだが雑な質問だとやらない
  • コンテキストがおかしくなる場合があるのでSQLを投げたい場合は新規のチャットを作成したほうがいい
  • 外部キー制約などがある場合はそれも伝えるとやってくれる
    • 「先にAテーブルの外部キーを削除してからBテーブルのレコードも削除して」など
  • データをINSERTするときは各カラムの情報を正確に伝えないとやってくれない
    • テーブルの各カラムに制約がある場合などはちゃんと伝えなければダメそう
    • 適当な値でお願いしますと命令もできるがその場合はテーブルのスキーマ情報から適当な数値や文字列を入れようとはする

参考サイト

2025年5月10日土曜日

OpenWebUI で MCP を使う方法

OpenWebUI で MCP を使う方法

概要

OpenWebUI 上でも MCP サーバと連携していろいろなエージェントや拡張ツールを動かすことができるので試してみました
今回は簡単な mcp/time サーバを使って LLM 経由で現在時刻が取得できるようにしてみます

環境

  • Ubuntu 24.04
  • OpenWebUI 0.6.7
  • LiteLLM Proxy 1.68.1
  • Python 3.12.9
    • mcpo 0.0.13
    • mcp 1.8.0

事前準備

litellm と open-webui は前回の記事を元に起動中とします

compose.yaml、litellm_config.yaml、.env を用意して起動しておきます

mcpo のインストール

mcpo は Python 制のツールなので pip でインストールできます
mcpo 経由でローカルホストにアクセスしたりするので可能な限り mcpo で操作させたいホストで直接起動しましょう

  • pipenv install mcpo

で OK です
上記では pipenv を使って venv 上にインストールしていますが問題なければグローバルにインストールしても OK です

MCPO 用の config.json の準備

この config.json は一般的な MCP サーバ用の config.json と同じになります
起動したいコマンド (MCP サーバ) を羅列していけば OK です

  • vim config.json
{
  "mcpServers": {
    "time": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "mcp/time"]
    }
  }
}

ここでローカルマシン上に mcp/time コンテナを起動する定義を記載します

MCPO の起動

先程も記載しましたが可能な限りコマンドなどを実行するホスト上で直接動かしましょう

  • pipenv run mcpo --port 8000 --host 0.0.0.0 --config ./config.json --api-key "top-secret"

ここで設定した api-key は open-webui から mcpo サーバに接続するときに使います

これで docker の状態は以下のようになります

  • docker ps
CONTAINER ID   IMAGE                                 COMMAND                  CREATED              STATUS                    PORTS                                         NAMES
385829c1f469   mcp/time                              "mcp-server-time"        About a minute ago   Up About a minute                                                       beautiful_bassi
26cb3f21bde5   ghcr.io/open-webui/open-webui:main    "bash start.sh"          22 minutes ago       Up 22 minutes (healthy)   0.0.0.0:3000->8080/tcp, [::]:3000->8080/tcp   open-webui
e38fe5175159   ghcr.io/berriai/litellm:main-latest   "docker/prod_entrypo…"   22 minutes ago       Up 22 minutes             0.0.0.0:4000->4000/tcp, :::4000->4000/tcp     litellm

OpenWebUI 上で MCPO サーバと接続設定をする

あとは open-webui 上から MCPO サーバに接続する設定をすれば OK です

設定からツールで MCPO を新規ツールとして接続します
ブラウザから直接アクセスするので localhost や local IP ではなくブラウザからアクセスできる IP アドレスを指定しましょう
また Bearer トークンに先ほど設定したシークレット情報を入力します

くるくるマークを押すと接続テストができるのでここでちゃんと接続できるか確認しておきましょう

動作確認

あとはチャットに戻り MCPO 経由で質問できるか確認します
まずチャット画面上でツールが有効になっているか確認します
ツールの数が 1 になっていれば OK です

また詳細を確認すると実際に MCPO で使えるコマンドが表示されます

あとは質問してみましょう

こんな感じでちゃんと MCPO 経由で回答が来ていることが確認できます

MCPO 側にも以下のようなログがあることが確認できると思います

INFO:     192.168.100.2:30848 - "POST /time/get_current_time HTTP/1.1" 200 OK

最後に

OpenWebUI で MCP と連携する方法を紹介しました
過去に紹介した Claude などは

  • Claude クライアント -> MCP サーバ

で直接通信していましたが OpenWebUI の場合は

  • OpenWebUI -> MCPO -> MCP サーバ

という感じで真ん中に一つ中継プロセスが入るのでそこが違います
そこまで負荷に影響はないですが挙動が少し異なるので認識しておきましょう

MCP サーバを追加したい場合は config.json に追記すれば OK です
MCP サーバも基本的にはローカルホストで起動するので追加しすぎると負荷になるので注意しましょう

参考サイト

2025年5月8日木曜日

OpenWebUI で Gemini を使う方法

OpenWebUI で Gemini を使う方法

概要

Gemini を LiteLLM Proxy でコールし OpenWebUI は LiteLLM Proxy に対してコールします
Gemini のエンドポイントはカスタムエンドポイントとします
過去に Azure OpenAI でやったバージョンの Gemini 版になります

環境

  • Ubuntu 24.04
  • OpenWebUI 0.6.7
  • LiteLLM Proxy 1.68.0

ポイント

OpenWebUI が起動できたらモデルの設定を開き高度な設定から「Stream Chat Response」をオフにしましょう

compose.yaml

services:
  openwebui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    ports:
      - "3000:8080"
    volumes:
      - open-webui:/app/backend/data
    extra_hosts:
      - "host.docker.internal:host-gateway"
    environment:
      - WEBUI_AUTH=False
      # - OPENAI_API_KEY=${MASTER_KEY}
      - OPENAI_API_BASE_URL=http://host.docker.internal:4000/v1
    restart: always

  litellm:
    image: ghcr.io/berriai/litellm:main-latest
    container_name: litellm
    ports:
        - "4000:4000"
    volumes:
        - ./litellm_config.yaml:/app/config.yaml
    environment:
      - GEMINI_API_BASE=${GEMINI_API_BASE}
      - GEMINI_API_KEY=${GEMINI_API_KEY}
    command: --config /app/config.yaml --port 4000 --detailed_debug
    restart: always

volumes:
  open-webui:

litellm_config.yaml

model_list:
  - model_name: gemini/gemini-2.0-flash
    litellm_params:
      model: gemini/gemini-2.0-flash
      api_base: os.environ/GEMINI_API_BASE # runs os.getenv("GEMINI_API_BASE")
      api_key: os.environ/GEMINI_API_KEY # runs os.getenv("GEMINI_API_KEY")
      api_version: ""

.env

GEMINI_API_KEY=xxx
GEMINI_API_BASE=https://your-api-endpoint/ai/chat-ai/flash

動作確認

  • docker compose up -d

で 3000 ポートにアクセスしコンソールから質問できることを確認しましょう

最後に

どうやら OpenWebUI からだとストリーム API のレスポンス形式は想定しておらず generateContent のレスポンスを使っているっぽいのでオフにしてあげる必要がありました

Gemini のカスタムエンドポイントを使う場合には設定してみるといいかなと思います

OpenWebUI で Gemini を使う場合には Pipeline を使うのが王道ですが LiteLLM Proxy でも動作するようです

参考サイト

2025年4月28日月曜日

LiteLLM Proxy を Gemini のカスタムエンドポイントで使用する方法

LiteLLM Proxy を Gemini のカスタムエンドポイントで使用する方法

概要

前回 Azure のカスタムエンドポイントを設定する方法を紹介しました
今回は Gemini flash の設定方法を紹介します

環境

  • docker 27.3.1
  • Ubuntu 24.04
  • litellm-proxy v1.67.0-stable

litellm_config.yaml

model_list:
  - model_name: gemini/gemini-flash
    litellm_params:
      model: gemini/gemini-flash
      api_base: os.environ/GEMINI_API_BASE # runs os.getenv("GEMINI_API_BASE")
      api_key: os.environ/GEMINI_API_KEY # runs os.getenv("GEMINI_API_KEY")
      api_version: ""

docker 起動

docker run --rm \
    -v $(pwd)/litellm_config.yaml:/app/config.yaml \
    -e GEMINI_API_KEY=b4xxx \
    -e GEMINI_API_BASE=https://your-api-endpoint/ai/chat-ai/gemini/flash \
    -p 4000:4000 \
    ghcr.io/berriai/litellm:main-latest \
    --config /app/config.yaml --detailed_debug

カスタムメソッド部の :streamGenerateContent は不要です

動作確認

リクエスト LiteLLM Proxy が互換にしてくれるので Azure のときと同じです

curl --location 'http://0.0.0.0:4000/chat/completions' \
    --header 'Content-Type: application/json' \
    --data '{
    "model": "gemini/gemini-flash",
    "messages": [
        {
        "role": "user",
        "content": "what llm are you"
        }
    ]
}'

レスポンスは以下です

{
  "id": "chatcmpl-2062ec16-2314-4772-a264-6f987407689d",
  "created": 1745811058,
  "model": "gemini-flash",
  "object": "chat.completion",
  "system_fingerprint": null,
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "I am a large language model, trained by Google.\n",
        "role": "assistant",
        "tool_calls": null,
        "function_call": null
      }
    }
  ],
  "usage": {
    "completion_tokens": 12,
    "prompt_tokens": 5,
    "total_tokens": 17,
    "completion_tokens_details": null,
    "prompt_tokens_details": {
      "audio_tokens": null,
      "cached_tokens": null
    }
  },
  "vertex_ai_grounding_metadata": [],
  "vertex_ai_safety_results": [],
  "vertex_ai_citation_metadata": []
}

最後に

LiteLLM Proxy で Gemini flash を動作させる方法を紹介しました
これで Open WebUI のモデルを簡単に変更することができます

2025年4月22日火曜日

Open WebUI を Azure のカスタムエンドポイントで使用する方法

Open WebUI を Azure のカスタムエンドポイントで使用する方法

概要

前回 LiteLLM を使って Azure OpenAI のカスタムエンドポイントを指定する方法を紹介しました
今回は Open-WebUI を起動して独自の Web Chat コンソールを構築します

環境

  • docker 27.3.1
  • Ubuntu 24.04
  • litellm-proxy v1.67.0-stable
  • open-webui 0.6.5

litellm_config.yaml

前回の内容と同じです
https://hawksnowlog.blogspot.com/2025/04/run-litellm-proxy-on-docker-via-azure-custom-endpoint.html#litellm_config.yaml

.env

キー情報を記載します

AZURE_API_KEY=b4xxx

compose.yaml

OpenWebUI -> LiteLLM は内部的に通信します
サービス経由でも問題ないかもです

services:
  openwebui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    ports:
      - "3000:8080"
    volumes:
      - open-webui:/app/backend/data
    extra_hosts:
      - "host.docker.internal:host-gateway"
    environment:
      - WEBUI_AUTH=False
      - OPENAI_API_BASE_URL=http://host.docker.internal:4000/v1
    restart: always

  litellm:
    image: ghcr.io/berriai/litellm:main-latest
    container_name: litellm
    ports:
        - "4000:4000"
    volumes:
        - ./litellm_config.yaml:/app/config.yaml
    environment:
      - AZURE_API_BASE=https://your-custom-azure-endpoint/chat-ai/gpt4
      - AZURE_API_KEY=${AZURE_API_KEY}
    command: --config /app/config.yaml --port 4000
    restart: always

volumes:
  open-webui:

動作確認

  • docker compose up -d

で起動し :3000 ポートにアクセスすると Open WebUI にアクセスできます
チャットの履歴は今回コンテナボリュームを使っていますが必要であればデータベースなどに保存しても OK です

最後に

OpenWebUI + LiteLLM Proxy を使って Azure のカスタムエンドポイント用に専用の Chat UI を構築してみました
OpenAI API 以外のエンドポイントでは基本的に LiteLLM Proxy を使うのが主流のようです

参考サイト

2025年4月21日月曜日

LiteLLM Proxy を Azure のカスタムエンドポイントで使用する方法

LiteLLM Proxy を Azure のカスタムエンドポイントで使用する方法

概要

過去に dspy で使用したエンドポイントを LiteLLM Proxy で使用する方法を紹介します
ちなみに LiteLLM Proxy は簡単に言うと OpenAI API 互換に変換してくれるプロキシです

環境

  • docker 27.3.1
  • Ubuntu 24.04
  • litellm-proxy v1.67.0-stable

litellm_config.yaml

model_list:
  - model_name: azure-gpt-4-32k
    litellm_params:
      model: azure/gpt-4-32k
      api_base: os.environ/AZURE_API_BASE # runs os.getenv("AZURE_API_BASE")
      api_key: os.environ/AZURE_API_KEY # runs os.getenv("AZURE_API_KEY")
      api_version: ""

docker 起動

docker run \
    -v $(pwd)/litellm_config.yaml:/app/config.yaml \
    -e AZURE_API_KEY=b4xxx \
    -e AZURE_API_BASE=https://your-api-endpoint/ai/chat-ai/gpt4 \
    -p 4000:4000 \
    ghcr.io/berriai/litellm:main-latest \
    --config /app/config.yaml --detailed_debug

動作確認

curl で動作確認します
model 名は litellm_config.yaml で指定した model_name を指定します

curl --location 'http://0.0.0.0:4000/chat/completions' \
    --header 'Content-Type: application/json' \
    --data '{
    "model": "azure-gpt-4-32k",
    "messages": [
        {
        "role": "user",
        "content": "what llm are you"
        }
    ]
}'

レスポンスは以下です

{
  "id": "chatcmpl-BOZAENZRJ1j3WErgssAmUj41gcl16",
  "created": 1745194742,
  "model": "gpt-4o-2024-08-06",
  "object": "chat.completion",
  "system_fingerprint": "fp_ee1d74bde0",
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "I am based on OpenAI's GPT-4 architecture, which is a type of large language model (LLM) designed for understanding and generating human-like text.",
        "role": "assistant",
        "tool_calls": null,
        "function_call": null
      }
    }
  ],
  "usage": {
    "completion_tokens": 34,
    "prompt_tokens": 12,
    "total_tokens": 46,
    "completion_tokens_details": {
      "accepted_prediction_tokens": 0,
      "audio_tokens": 0,
      "reasoning_tokens": 0,
      "rejected_prediction_tokens": 0
    },
    "prompt_tokens_details": {
      "audio_tokens": 0,
      "cached_tokens": 0
    }
  },
  "service_tier": null,
  "prompt_filter_results": [
    {
      "prompt_index": 0,
      "content_filter_results": {
        "hate": {
          "filtered": false,
          "severity": "safe"
        },
        "self_harm": {
          "filtered": false,
          "severity": "safe"
        },
        "sexual": {
          "filtered": false,
          "severity": "safe"
        },
        "violence": {
          "filtered": false,
          "severity": "safe"
        }
      }
    }
  ]
}

最後に

次回はこれと Open WebUI を組み合わせて自分専用の Chat 用 UI を構築します

参考サイト