mcpField
O
OpenZiti / LLM-Gateway

OpenZiti / LLM-Gateway

認証済みおすすめローカル
netfoundry.ioAI・エージェント1032 週間前に更新

OpenZiti / LLM-Gateway について

NetFoundry LLM Gateway は OpenZiti プロジェクトの OpenAI 互換 API プロキシで、OpenAI、Anthropic、その他の互換バックエンドへリクエストをルーティングします。zrok と OpenZiti により、NAT 配下の推論サーバーにポートを開かずに接続できます。複数の LLM バックエンドへゼロトラストでアクセスするチーム向けです。

主な機能

  1. 01OpenAI 互換 API と Anthropic 形式の変換
  2. 02モデル名プレフィックスによるルーティング
  3. 03三層のセマンティックルーティング
  4. 04重み付きラウンドロビンとヘルスチェックによるフェイルオーバー
  5. 05zrok 共有によるゼロトラストなバックエンド接続
  6. 06Prometheus メトリクスと仮想 API キー

活用シーン

  1. 01Ollama や vLLM のサーバーを単一のゲートウェイ経由で利用
  2. 02ファイアウォールのポートを開けずに zrok でゲートウェイを公開

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

インストール方法は未掲載です

このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。

リポジトリ

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

llm-gateway

OpenAI、Anthropic、および OpenAI 互換バックエンド(Ollama、vLLM、llama-server、SGLang など)にリクエストをルーティングする、OpenAI 互換の API プロキシです。必要に応じて、zrok 経由でゲートウェイを公開し、ゼロトラストアクセスを実現できます。

ほかの LLM ゲートウェイではなく、これを使う理由

多くの LLM プロキシが解決するのは、API の変換です。このゲートウェイは、ネットワークの問題も解決します。NAT の内側にある GPU マシンにゲートウェイを接続し、ポートを開放せずにクライアントへ公開して、適切なモデルにリクエストをルーティングするにはどうすればよいでしょうか。VPN、サービスメッシュ、ルーティングデータベースを後付けする必要はありません。

  • zrok(OpenZiti 経由)によるゼロトラストネットワーク — ゲートウェイとバックエンドは、OpenZiti オーバーレイネットワーク上で zrok を使って通信します。ファイアウォールルールやポートフォワーディングなしで、NAT、エアギャップネットワーク、クラウド境界を越えて、ゲートウェイを公開したりバックエンドにアクセスしたりできます。どちらの方向も同じ方法で動作します。
  • セマンティックルーティング — 3 層のカスケード(キーワードヒューリスティック、埋め込み類似度、LLM 分類器)により、クライアントが model フィールドを省略した場合に最適なモデルを自動で選択します。手動で管理するルーティングテーブルは不要です。
  • 複数エンドポイントのロードバランシング — 推論サーバーのプール全体で、重み付きラウンドロビン、パッシブフェイルオーバーを備えたヘルスチェック、VM のスリープ検出に対応します。Ollama、llama-server、vLLM、SGLang、または /v1/chat/completions を公開するあらゆるものと連携します。実際のハードウェアに推論を分散するために設計されています。
  • 単一バイナリで、インフラストラクチャ不要 — Go バイナリ 1 つと YAML ファイル 1 つだけです。データベース、メッセージキュー、サイドカーは不要です。

機能

  • OpenAI 互換 API:OpenAI クライアントライブラリのドロップイン代替として利用できます
  • 複数プロバイダーへのルーティング:モデル名に基づいてリクエストを自動でルーティングします
  • セマンティックルーティング:任意で 3 層のカスケード(ヒューリスティック、埋め込み、LLM 分類器)を使い、model が省略された場合に最適なモデルを自動で選択します
  • Anthropic 形式への変換:OpenAI 形式を Anthropic の Messages API との間で透過的に変換します
  • ストリーミング対応:すべてのプロバイダーで Server-Sent Events(SSE)ストリーミングに対応します
  • 複数エンドポイントのロードバランシング:複数の推論バックエンド間で、ラウンドロビンによる負荷分散と自動フェイルオーバーを行います
  • OpenTelemetry メトリクス:リクエスト、レイテンシ、トークン、エンドポイントの健全性に関するメトリクスを Prometheus 向けにエクスポートします
  • zrok 連携:zrok のプライベート共有またはパブリック共有を通じてゲートウェイを公開します
  • ゼロトラストバックエンド:zrok 共有を通じて任意のプロバイダーに接続します(ポートの公開は不要です)

初めての方へ:ゼロから動作するゲートウェイを構築するまでの手順は、Getting Started ガイドをご覧ください。

インストール

Linux、macOS、Windows 用のビルド済みバイナリは、リリースページから入手できます。

または、Go でインストールします。

go install github.com/openziti/llm-gateway/cmd/llm-gateway@latest

ソースからビルドすることもできます。

git clone https://github.com/openziti/llm-gateway.git
cd llm-gateway
go install ./...

クイックスタート

  1. 設定ファイルを作成します。
# config.yaml
listen: ":8080"

providers:
  open_ai:
    api_key: "${OPENAI_API_KEY}"
  anthropic:
    api_key: "${ANTHROPIC_API_KEY}"
  local:                               # works with any OpenAI-compatible backend
    base_url: "http://localhost:11434"
  1. ゲートウェイを実行します。
export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."
llm-gateway run config.yaml
  1. 任意の OpenAI 互換クライアントを使ってリクエストを送信します。
curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

プロバイダーへのルーティング

リクエストはモデル名のプレフィックスに基づいてルーティングされます。

モデルのプレフィックスプロバイダー
gpt-*OpenAI
o1-*OpenAI
o3-*OpenAI
claude-*Anthropic
その他すべてローカル/セルフホスト

OpenAI または Anthropic のプレフィックスに一致しないモデルは、すべてローカルプロバイダーにルーティングされます。Ollama、vLLM、llama-server、SGLang など、あらゆる OpenAI 互換バックエンドと連携します。

複数エンドポイントの負荷分散

複数の推論バックエンドにリクエストを分散し、負荷分散と耐障害性を実現します。endpoints が指定されている場合、ゲートウェイはラウンドロビン方式で選択し、自動フェイルオーバーを行います。

providers:
  local:
    endpoints:
      - name: gpu-box-1
        base_url: "http://10.0.0.1:11434"
        weight: 3
      - name: gpu-box-2
        base_url: "http://10.0.0.2:11434"
      - name: remote
        zrok_share_token: "abc123"
    health_check:
      interval_seconds: 30   # default: 30
      timeout_seconds: 5     # default: 5

各エンドポイントでは、直接 HTTP または zrok share を使用できます。省略可能な weight(デフォルト:1)は、エンドポイントが受け取るトラフィックの割合を制御します。weight が 3 のエンドポイントは、weight が 1 のエンドポイントの約 3 倍のリクエストを受け取ります。バックグラウンドの goroutine が設定された間隔で各エンドポイントに ping を送信し、異常なエンドポイントをマークして自動的にスキップします。リクエスト中のネットワークエラーも、即時のパッシブフェイルオーバーを引き起こします。ローカルプロバイダーを使用するすべてのゲートウェイ機能(チャット補完、埋め込み、分類器)で、エンドポイントグループ内にリクエストを分散します。

すべてのエンドポイントで同じソフトウェアを実行する必要はありません。同じプール内で Ollama、vLLM、llama-server、その他の OpenAI 互換サーバーを混在させることができます。負荷分散レイヤーは、URL の背後で何が動作しているかを問いません。

API エンドポイント

POST /v1/chat/completions

OpenAI 互換のチャット補完エンドポイントです。ストリーミング(stream: true)と非ストリーミングの両方のリクエストをサポートします。セマンティックルーティングが有効な場合、model フィールドは省略できます。

GET /v1/models

設定されているすべてのプロバイダーの利用可能なモデルを返します。セマンティックルーティングが有効な場合、自動モデル選択を行う auto 仮想モデルが含まれます。複数エンドポイントモードでは、正常なすべてのエンドポイントから取得したモデルを重複なしで返します。

GET /health

HTTP 200 とともに {"status":"ok"} を返します。死活監視に使用します。

GET /metrics

Prometheus メトリクスエンドポイントです(metrics.enabled: true の場合)。リクエスト数、所要時間のヒストグラム、トークンカウンター、ルーティングの判断、プロバイダーエラー、処理中リクエストのゲージ、エンドポイントのヘルス状態を公開します。

設定

設定の全例
listen: ":8080"

zrok:
  share:
    enabled: false
    mode: private      # public or private
    token: ""          # use existing persistent share (private only)

providers:
  open_ai:
    api_key: "${OPENAI_API_KEY}"
    base_url: ""             # optional: override for Azure or compatible APIs
    zrok_share_token: ""     # optional: connect via zrok share

  anthropic:
    api_key: "${ANTHROPIC_API_KEY}"
    base_url: ""             # optional: override base URL
    zrok_share_token: ""     # optional: connect via zrok share

  local:
    base_url: "http://localhost:11434"
    zrok_share_token: ""     # optional: connect via zrok share

    # or use multi-endpoint mode for round-robin + failover:
    # endpoints:
    #   - name: gpu-box-1
    #     base_url: "http://10.0.0.1:11434"
    #   - name: gpu-box-2
    #     base_url: "http://10.0.0.2:11434"
    #   - name: remote
    #     zrok_share_token: "abc123"
    # health_check:
    #   interval_seconds: 30
    #   timeout_seconds: 5

metrics:
  enabled: false
環境変数

API キーでは、${VAR} 構文を使用した環境変数の展開をサポートしています。

API キー

ゲートウェイは、クライアント認証用の仮想 API キーをサポートしています。キーを生成し、設定に追加します。

llm-gateway genkey
# sk-gw-a1b2c3d4e5f6...
api_keys:
  enabled: true
  keys:
    - name: alice
      key: "sk-gw-a1b2c3d4e5f6..."

クライアントは Authorization: Bearer <key> ヘッダーでキーを送信します。/health と /metrics エンドポイントは、引き続き認証なしで利用できます。キーは、グロブパターンを使用して特定のモデルに制限できます。クライアント向けの仕様については docs/current/api-keys.md、再読み込み可能な YAML および HTTP ソースについては docs/current/key-sources.md を参照してください。

セマンティックルーティング

設定すると、ゲートウェイはリクエストの内容に基づいて最適なモデルを自動選択できます。model フィールドは省略可能になり、省略された場合、リクエストは次の 3 層カスケードを通ります。

  1. ヒューリスティクス — 高速なキーワード/パターンマッチング(例:「翻訳」→高速モデル、ツール使用→ツール対応モデル)
  2. 埋め込み — Ollama または OpenAI の埋め込みを使用し、ユーザープロンプトとルートの例文とのコサイン類似度を計算
  3. LLM 分類器 — 埋め込みで判断できない場合に、LLM にリクエストの分類を依頼

各層は個別に有効化または無効化できます。たとえば、埋め込みを使わずに分類器を使用できます。すべての層がスキップされた場合、または結論が出ない場合は、設定されたデフォルトルートが使用されます。セマンティックルーティングが無効または未設定の場合、動作は変わりません。

セマンティックルーティングの設定
routing:
  allow_explicit_model: true    # clients can still specify a model directly
  default_route: general        # fallback when no layer matches

  heuristics:
    enabled: true
    rules:
      - match:
          keywords: ["translate", "translation"]
        route: fast
      - match:
          has_tools: true
        route: tools
      - match:
          system_prompt_contains: "you are a code assistant"
        route: coding
      - match:
          max_tokens_lt: 100
          message_length_lt: 200
        route: fast

  semantic:
    enabled: true
    provider: local             # local or openai
    model: nomic-embed-text
    threshold: 0.82             # confident match
    ambiguous_threshold: 0.65   # escalate to classifier
    comparison: centroid         # centroid, max, or average

  classifier:
    enabled: true
    provider: local
    model: llama3
    timeout_ms: 5000
    confidence_threshold: 0.7

  routes:
    - name: coding
      model: claude-sonnet-4-20250514
      description: "code generation, debugging, and technical tasks"
      examples:
        - "write a python function to sort a list"
        - "debug this segfault in my C code"

    - name: creative
      model: claude-sonnet-4-20250514
      description: "creative writing, storytelling, and artistic content"
      examples:
        - "write a poem about the ocean"
        - "tell me a story about a dragon"

    - name: fast
      model: llama3
      description: "simple tasks, translations, and short responses"
      examples:
        - "translate hello to French"
        - "what is 2+2"

    - name: tools
      model: gpt-4
      description: "tasks requiring tool use and function calling"
      examples:
        - "search the web for recent news"
        - "call the weather API for New York"

    - name: general
      model: llama3
      description: "general conversation and miscellaneous tasks"
      examples:
        - "what is the capital of France"
        - "explain quantum computing"
ヒューリスティックマッチ条件

各ヒューリスティックルールには、1 つ以上の条件を含む match ブロックがあります。1 つのルールに複数の条件が指定されている場合、すべての条件が一致する必要があります(AND ロジック)。keywords 内では、いずれかのキーワードが一致するとルールが適用されます(OR ロジック)。使用できる条件は次のとおりです。

条件説明
keywordsユーザーメッセージの内容に対する、大文字と小文字を区別しない単語境界マッチ
has_toolsリクエストにツール定義が含まれる、または含まれない場合に一致します
system_prompt_containsシステムメッセージに対する部分文字列マッチ
max_tokens_ltmax_tokens がしきい値を下回る場合に一致します
message_length_ltメッセージ全体の文字数がしきい値を下回る場合に一致します
excludeユーザーメッセージ内に見つかった場合、キーワードマッチを抑制するフレーズのリスト
モデルを指定せずにリクエストを送信する

セマンティックルーティングが有効な場合、model フィールドを省略できます。

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [{"role": "user", "content": "Write a Python function to sort a list"}]
  }'
チャットクライアントでの使用(Open WebUI など)

Open WebUI などのチャットクライアントでは、モデルリストからモデルを選択する必要があり、常に model フィールドを送信します。セマンティックルーティングが有効な場合、ゲートウェイは自動ルーティングを実行する仮想の auto モデルを公開します。

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [{"role": "user", "content": "Write a Python function to sort a list"}]
  }'

クライアントの接続先を http://localhost:8080/v1 に設定し、モデルリストから auto を選択します。ゲートウェイはセマンティックルーティングのカスケードを通じて、各リクエストをルーティングします。

ゲートウェイは、使用した方式、信頼度スコア、レイテンシ、カスケードのトレースとともに、各ルーティング判断をログに記録します。

メトリクス

Prometheus エクスポーターを使用して OpenTelemetry メトリクスを有効にします。

metrics:
  enabled: true

有効にすると、ゲートウェイは同じリッスンアドレスの GET /metrics で Prometheus メトリクスを提供します。使用可能なメトリクスは次のとおりです。

メトリクス種類説明
llm_gateway.requestsカウンターリクエストの合計(プロバイダー、モデル、ストリーミング別)
llm_gateway.request.durationヒストグラムリクエストの所要時間(秒)(プロバイダー、モデル別)
llm_gateway.tokens.promptカウンタープロンプトトークンの合計(プロバイダー、モデル別)
llm_gateway.tokens.completionカウンター補完トークンの合計(プロバイダー、モデル別)
llm_gateway.routing.decisionsカウンターセマンティックルーティングの判断(方式別)
llm_gateway.provider.errorsカウンタープロバイダーのエラー(error_type 別)
llm_gateway.requests.inflightゲージ現在処理中のリクエスト数
llm_gateway.endpoint.healthyゲージエンドポイントのヘルスステータス

トレーシング

ルーティング判断のデバッグ用に、リクエスト本文のログ記録を有効にします。

tracing:
  enabled: true
  max_content_length: 200   # max characters per message in log output

各チャット補完リクエストは、モデル、メッセージ数、ストリーミングフラグ、ツール数、および各メッセージのロールと省略表示された内容とともにログに記録されます。詳細については、docs/current/configuration.md を参照してください。

CLI リファレンス

llm-gateway run <configPath>

Flags:
      --address string     listen address (overrides config)
      --zrok               enable zrok sharing (overrides config)
      --zrok-mode string   zrok share mode: public, private (overrides config)

zrok との統合

ゲートウェイの公開

ファイアウォールのポートを開かずにゲートウェイを公開するには、zrok 共有を有効にします。

zrok:
  share:
    enabled: true
    mode: private

または CLI で設定します。

llm-gateway run config.yaml --zrok --zrok-mode private

ゲートウェイは起動時に共有トークンをログに記録します。クライアントは zrok access を使用して接続します。

永続共有の使用

再起動後も共有トークンを維持するには、zrok CLI で永続共有を作成し、それを指定します。

zrok:
  share:
    enabled: true
    token: "abc123xyz"  # your persistent share token
zrok 経由でバックエンドに接続する

直接 URL の代わりに zrok 共有を使用して、任意のプロバイダーに接続できます。

providers:
  open_ai:
    api_key: "${OPENAI_API_KEY}"
    zrok_share_token: "openai-proxy-share-token"

  anthropic:
    api_key: "${ANTHROPIC_API_KEY}"
    zrok_share_token: "anthropic-proxy-share-token"

  local:
    zrok_share_token: "ollama-share-token"

例

Python OpenAI クライアントでの使用
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8080/v1",
    api_key="not-needed"  # gateway handles auth
)

# routes to OpenAI
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}]
)

# routes to Anthropic (translated automatically)
response = client.chat.completions.create(
    model="claude-sonnet-4-20250514",
    messages=[{"role": "user", "content": "Hello!"}]
)

# routes to local backend (Ollama, vLLM, etc.)
response = client.chat.completions.create(
    model="llama3.2",
    messages=[{"role": "user", "content": "Hello!"}]
)
ストリーミング
stream = client.chat.completions.create(
    model="claude-sonnet-4-20250514",
    messages=[{"role": "user", "content": "Write a haiku"}],
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

ドキュメント

  • はじめに -- セットアップ手順を順を追って解説します
  • 設定 -- 設定と CLI フラグの完全なリファレンスです
  • プロバイダー -- プロバイダーの詳細、ストリーミング、エラー処理について説明します
  • セマンティックルーティング -- しきい値の調整、比較モード、キャッシュについて説明します
  • API キー -- キーごとのモデルとルートの制限について説明します
  • キーソース -- 再読み込み可能なキー情報、YAML と HTTP の仕様、古さ、可観測性について説明します
  • 複数エンドポイントの負荷分散 -- 重み付けによる負荷分散とフェイルオーバーについて説明します
  • メトリクス -- Prometheus の計測項目とクエリ例について説明します
  • ストリーミング -- SSE ストリーミングの詳細について説明します
  • zrok -- 共有とアクセスのためのオーバーレイネットワークについて説明します
  • Agora -- サービス提供と接続のための Agora オーバーレイネットワーク(zrok へのピアトランスポート)について説明します
  • ダミーモデル -- テストやデモ用の、OpenAI 互換の偽バックエンドについて説明します
  • ダミーキー -- 障害注入機能を備えた、HTTP キーソース仕様を提供するキー API のリファレンスです

ライセンス

Apache 2.0

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。