OneRouter:実用的な例を用いたガイド
OneRouter ガイド
By アンドリュー・ジェン •
OneRouter ガイド



2025/12/21
アンドリュー・ジェン
複数のAIプロバイダーAPIの管理はすぐに圧倒されることになります。各プロバイダーには異なる認証方法、料金モデル、API仕様があります。開発者は、さまざまなモデルにアクセスするためにOpenAI、Anthropic、Googleなどのプラットフォーム間で切り替えるのに無駄な時間を費やします。
OneRouterは、数十のプロバイダーから250以上のモデルに接続する統一APIを提供することでこの複雑さを解決します。1つのAPIキーと一貫したインターフェイスを使用して、GPT-5、Claude 4、Gemini 2.5 Pro、およびその他の数百のモデルにアクセスできます。このプラットフォームは、裏で自動フォールバック、コスト管理、プロバイダーのルーティングを処理します。
このチュートリアルでは、OneRouterについて知っておくべきこと全て、最初のAPIコールの設定から、構造化出力のような高度な機能の実装までを説明します。最後には、特定のプロバイダーに縛られない信頼性の高いアプリケーションの構築方法を学べます。
OneRouterは、1つのエンドポイントを通じて数十のプロバイダーから250以上のAIモデルにアクセスできる統一APIプラットフォームです。OpenAI、Anthropic、Google、Metaなどのために別々のAPIキーを扱う代わりに、全モデルカタログにアクセスするために1つのキーを使用します。
このプラットフォームはインテリジェントなルーターとして機能し、認証、請求、エラーハンドリングを処理しながらリクエストを適切なプロバイダーに送信します。このアプローチは、複数のAIプロバイダーを使用する際に発生するいくつかの頭痛を解決します。
複数のAIプロバイダーで作業することはすぐに混乱します。それぞれが独自のAPIフォーマット、ログインプロセス、請求システムを持っています。結果として、開発者は各サービスごとに別々のコードを維持することになり、開発が遅れ、新しいモデルをテストするのが大変になります。
プロバイダーがダウンしたり、レート制限に達した場合、状況はさらに悪化します。アプリが壊れ、何もできずに待つことになります。また、似たモデルに対する最良の価格を提供するプロバイダーを特定するには、異なるプラットフォームで手動でコストを追跡する必要があります。
最大の問題は、1つのプロバイダーに縛られてしまうことです。特定のAPIを中心にしてすべてを構築すると、後でより良いモデルや安価なオプションに切り替えるのが大きなプロジェクトになります。
OneRouterは、一連の接続された機能を使用してこれらの問題を解決します:
1つのAPIキーで250以上のモデルにアクセスできます
最初の選択が失敗したときに自動的にバックアッププロバイダーに切り替えることを可能にします
すべてのモデルに対する並列価格設定が可能で、コストを瞬時に比較できます
既存のOpenAIコードと連携して機能します — エンドポイントURLを変更するだけです
リアルタイムモニタリングにより、最も速い利用可能なプロバイダーにリクエストをルーティングします
これらの機能は一体となって、AI開発をよりスムーズで信頼性の高いものにします。
異なるタイプのユーザーがこの統一アプローチから価値を得ます:
開発者は、あちこちでアカウントを設定することなく新しいモデルを試すことができ、実験が迅速になります
企業チームは、プロバイダーが失敗したときに自動バックアップを通じて必要なアップタイムを確保します
予算を重視するユーザーは、スプレッドシート計算なしで自分のニーズに合った最も安価なオプションを見つけることができます
研究者は、アカウント設定のオーバーヘッドなしに、最先端のモデルに即座にアクセスできます
OneRouterがどのような価値を提供するのかを理解したので、最初のAPIコールを設定してみましょう。
OneRouterに飛び込む前に、いくつかの準備が必要です。このチュートリアルは、基本的なPythonプログラミングに慣れ、以前にAPIで作業した経験があることを前提としています。専門家である必要はありませんが、HTTPリクエストの作成やJSONレスポンスの処理などの概念を理解している必要があります。
システムにPython 3.7以降がインストールされている必要があります。OneRouterのAPIと対話するためにopenai Pythonパッケージを使用し、環境変数を安全に扱うためにpython-dotenvも使用します。どちらも以下のコマンドでインストールできます:
また、OneRouterアカウントとAPIキーが必要です。OneRouter にアクセスして無料アカウントを作成してください。すぐに試すための小額のクレジットが付与されます。ログインしたら、アカウント設定のAPIキーセクションに移動して新しいキーを生成します。
APIキーを取得したら、プロジェクトディレクトリに.envファイルを作成し、次のようにキーを追加します:
これにより、APIキーが安全に保たれ、コードから外れます。テストを超えてOneRouterを使用する予定がある場合、クレジットページを通じてアカウントにクレジットを追加する必要があります。
これらの基本が整ったら、OneRouterを介して最初のAPIコールを行う準備が整いました。
OneRouterを使い始めるのは非常にシンプルです。以前にOpenAI SDKを使用したことがある場合、コードの1行を変更するだけで異なるプロバイダーから数百のモデルにアクセスできます。
OneRouterのアプローチを示す動作例から始めましょう:
import os from openai import OpenAI from dotenv import load_dotenv load_dotenv() client = OpenAI( base_url="https://llm.onerouter.pro/v1", api_key=os.getenv("ONEROUTER_API_KEY"), ) response = client.chat.completions.create( model="google-ai-studio/gemini-2.5-flash-preview-09-2025", messages=[ { "role": "user", "content": "Write a haiku about debugging code at 2 AM" } ] ) print(response.choices[0].message.content)
Night hum, coffee cooled cursor blinks, bug hides somewhere I chase ghosts 'til dawn
魔法は2つの場所で起こります。
まず、base_urlパラメータは、リクエストをGoogleのサーバーではなくOneRouterのサーバーにリダイレクトします。
次に、モデル名はprovider/model-nameフォーマットに従います - google-ai-studio/gemini-2.5-flash-preview-09-2025は、単にgemini-2.5-flash-preview-09-2025ではなく、どのプロバイダーのバージョンを望んでいるかをOneRouterに伝えます。
様々なモデルでの作業がいかに簡単かを見たので、選択したモデルが利用できない場合はどうなるのか、プロバイダーが問題に直面しても信頼性を維持するアプリケーションをどのように構築するのかについて疑問に思うかもしれません。これがOneRouterのルーティングとレジリエンス機能の出番です。
信頼性の高いAIアプリケーションを構築するには、予期しない事態に備える必要があります。プロバイダーはダウンタイムを経験し、モデルはレート制限に達し、時にはコンテンツモデレーションがリクエストをブロックします。モデルルーティングはOneRouterの解決策です — 自動的に異なるモデル間を切り替えて、アプリケーションがスムーズに動作し続けます。
レジリエンスを追加する最も簡単な方法は、バックアップモデルを指定することです。プライマリの選択が失敗したとき、OneRouterは順番に代替案を試します。
{ "model": "gemini-2.5-flash", "fallback_models": ["gemini-2.5-flash", "grok-4-fast-non-reasoning", "qwen3-next-80b-a3b-instruct"], "fallback_rules": "auto" // default value is "auto" ... // Other params }
OneRouterはgemini-2.5-flashを最初に試みます。それが利用できない場合、レート制限されている場合、またはブロックされている場合は、自動的にgrok-4-fast-non-reasoning、次にqwen3-next-80b-a3b-instructを試みます。response.modelフィールドには、実際に応答したモデルが表示されます。
すべてのモデルが互いに良いバックアップになるわけではありません。プロバイダーのダウンタイムは、その企業のすべてのモデルに影響を与える可能性があるため、異なるプロバイダーのバックアップを選択してください。レート制限やコストは大きく変動するため、高価なモデルには安価な代替を組み合わせてください:
# Good fallback chain: different providers, decreasing cost response = client.chat.completions.create( model="anthropic/claude-sonnet-4", messages=[ {"role": "user", "content": "Your prompt here"} ], extra_body={ "models": [ "x-ai/grok-4", # Close performance "moonshotai/kimi-k2", # Cheaper ] } )
これにより、利用可能な場合は高品質、バックアップとしてしっかりしたパフォーマンス、最後の手段としては保証された利用可能性が得られます。プロバイダー間のコンテンツモデレーションポリシーも異なるため、チェーンを多様化すると、敏感なトピックに対するカバレッジが向上します。
モデルページ models page では、プロバイダーや機能でフィルタリングしてチェーンを構築できます。DeepSeek R1やKimi-K2のような多くの強力なモデルは特に安価で、素晴らしいフォールバックとなります。
動的アプリケーションでは、プログラム的にモデルを発見できます:
def get_provider_models(api_key: str, provider: str) -> list[str]: r = requests.get( "https://llm.onerouter.pro/v1/models", headers={"Authorization": f"Bearer {api_key}"} ) return [m["id"] for m in r.json()["data"] if m["id"].startswith(provider)] # Build fallbacks across providers openai_models = get_provider_models(api_key, "openai/") anthropic_models = get_provider_models(api_key, "anthropic/")
このアプローチにより、新しいモデルが利用可能になった際に適応する堅牢なフォールバックチェーンを構築できます。
AIモデルを使用する際、特に長いレスポンスの場合、ユーザーは完全なレスポンスを待つのではなく、出力が徐々に表示されることを期待します。ストリーミングは、モデルが生成するたびにレスポンスのチャンクを送信し、ChatGPTのインターフェイスに似たよりインタラクティブな体験を作成します。
OneRouterでストリーミングを設定するには、リクエストにstream=Trueを追加します。レスポンスは、モデルが生成する際にチャンクを出力するイテレータになります:
response = client.chat.completions.create( model="openai/gpt-5", messages=[ {"role": "user", "content": "Write a detailed explanation of how neural networks learn"} ], stream=True ) for chunk in response: if chunk.choices[0].delta.content is not None: print(chunk.choices[0].delta.content, end="")
各チャンクにはレスポンスの小さな部分が含まれています。delta.contentフィールドには新しいテキストの断片が保持されており、ストリーミング効果を生み出すために、改行を追加せずに即座に印刷します。end=""パラメータは、チャンク間で改行を追加しないことを防ぎます。
プロダクションアプリケーションでは、ストリーミングプロセスに対してより多くのコントロールが必要です。ここでは、完全なレスポンスを管理するためのより包括的なハンドラーの例を示します:
def stream_response(model, messages, show_progress=True): response = client.chat.completions.create( model=model, messages=messages, stream=True ) complete_response = "" for chunk in response: if chunk.choices[0].delta.content is not None: content = chunk.choices[0].delta.content complete_response += content if show_progress: print(content, end="", flush=True) if show_progress: print() # Add final newline return complete_response # Use it with different models result = stream_response( "anthropic/claude-sonnet-4", [{"role": "user", "content": "Explain quantum entanglement like I'm 12 years old"}] )Powered By
このハンドラーは、進行状況を表示しながら完全なレスポンスをキャッチし、ストリーミング体験と最終的なテキストの両方を提供し、適切な出力フォーマットを含みます。
ストリーミングは、ユーザーの体験を「待って希望する」状態から「進行状況を見る」状態に変えます。これにより、AIアプリケーションはユーザーにとってより応答性が高く、魅力的なものに感じられます。
一部のAIモデルは、最終的な答えを出す前に「思考」プロセスを見せてくれます。これらの推論トークンは、モデルが複雑な問題に取り組む方法を透明に示し、結論を導くステップバイステップの論理を提供します。内部の推論を理解することで、回答を検証し、モデルの動作をデバッグし、より信頼性のあるアプリケーションを構築するのに役立ちます。
推論トークンは、レスポンスの別のreasoning_contentフィールドに表示され、メインコンテンツとは異なります。異なるモデルは異なる方法で推論をサポートしています—一部は努力レベルを使用し、他はトークン予算を使用します。
以下に、推論の実際の例を示します:
from openai import OpenAI client = OpenAI( base_url="https://llm.onerouter.pro/v1", api_key="<<API_KEY_REF>>", ) response = client.chat.completions.create( model="<<MODEL>>", messages=[ {"role": "user", "content": "How would you build the world's tallest skyscraper?"} ], extra_body={ "reasoning": { "effort": "high", "max_tokens": 2000 } }, ) print("Final answer:") print(response.choices[0].message.content) print("\nReasoning process:") print(response.choices[0].message.reasoning_content)
Final answer:
To count the 'r's in 'strrawberry', I'll go through each letter:
...
There are **4**
モデルは、最終的な答えとその結論に至るまでの内部推論の両方を示します。この二重出力は、モデルが問題に正しくアプローチしているかどうかを理解するのに役立ちます。
モデルがレスポンスにおいてどれだけの推論の努力をかけるかを、2つのアプローチを使用して制御できます。effortパラメータは、OpenAIのoシリーズのようなモデルと一緒に機能し、max_tokens設定に基づいて特定のトークンパーセンテージに相当するレベルを使用します:
"effort": "xhigh" - 推論に最大のトークンを割り当てます(最大トークンの約95%)
"effort": "high" - 推論に大部分のトークンを割り当てます(最大トークンの約80%)
"effort": "medium" - トークンの中程度の部分を割り当てます(最大トークンの約50%)
"effort": "low" - 小さい部分のトークンを割り当てます(最大トークンの約20%)
"effort": "minimal" - さらに小さい部分のトークンを割り当てます(最大トークンの約10%)
"effort": "none" - 推論を完全に無効にします
直接のトークン割り当てをサポートするモデルでは、具体的な推論予算を指定できます:
def get_reasoning_response(question, reasoning_budget=2000): response = client.chat.completions.create( model="anthropic/claude-sonnet-4", messages=[{"role": "user", "content": question}], max_tokens=10000, extra_body={ "reasoning": { "max_tokens": reasoning_budget # Exact token allocation } } ) return response # Compare different reasoning budgets response = get_reasoning_response( "What's bigger: 9.9 or 9.11? Explain your reasoning carefully.", reasoning_budget=3000 ) print("Answer:", response.choices[0].message.content) print("Detailed reasoning:", response.choices[0].message.reasoning_content)
高いトークン予算は一般的により詳細な推論を生成し、低い予算はより迅速ではあるが詳細が少ない思考プロセスを提供します。
マルチターンの会話を構築する際は、文脈を維持するために推論と最終答えの両方を保存する必要があります。これは、モデルの思考プロセスがその後の応答に影響を与える複雑な議論では特に重要です:
# First message with reasoning response = client.chat.completions.create( model="anthropic/claude-sonnet-4", messages=[ {"role": "user", "content": "Should I invest in renewable energy stocks? Consider both risks and opportunities."} ], extra_body={ "reasoning": { "max_tokens": 3000 } } ) # Build conversation history with reasoning preserved messages = [ {"role": "user", "content": "Should I invest in renewable energy stocks? Consider both risks and opportunities."}, { "role": "assistant", "content": response.choices[0].message.content, "reasoning_details": response.choices[0].message.reasoning_content # Preserve reasoning }, {"role": "user", "content": "What about solar energy specifically? How does that change your analysis?"} ] # Continue conversation with reasoning context follow_up = client.chat.completions.create( model="anthropic/claude-sonnet-4", messages=messages, extra_body={ "reasoning": { "max_tokens": 2000 } } ) print("Follow-up answer:") print(follow_up.choices[0].message.content) print("\nContinued reasoning:") print(follow_up.choices[0].message.reasoning_content)
フィールドreasoning_contentは、完全な推論チェーンを保持し、モデルが前の分析に基づいて後続の質問に答えることを可能にします。これにより、より一貫性があり、文脈を理解した会話が実現します。
推論トークンは出力トークンとして請求されるため、使用コストが増加します。しかし、特に精度が重要な複雑なタスクでは、通常のレスポンス品質を向上させるためその費用を正当化します。OneRouterのドキュメントによれば、推論トークンは、モデルの性能を向上させながら、意思決定プロセスの透明性を提供します。
コストを重視するアプリケーションでは、タスクの複雑さに基づいて努力レベルやトークン予算を調整することで、経費と推論品質をバランスさせることができます。簡単な質問では推論が全く必要ないかもしれませんが、複雑な問題には高い努力の推論が利益をもたらします。
これまでテキストで作業してきましたが、画像や文書を分析する必要がある場合はどうなりますか?チャートについて質問したり、PDFから情報を抽出したり、写真で何が起こっているかを説明したりしたい場合です。ここでマルチモーダルモデルが登場します — これらは同じリクエスト内でテキストと視覚コンテンツの両方を理解できます。
画像をテキストで説明しようとするのではなく、実際の画像を送信し、それについて直接質問することができます。これにより、モデルが実際にどのような情報を扱っているのかを正確に見ることができるため、アプリケーションがはるかに直感的になります。テキストの説明がすべての重要な詳細をキャッチしたかどうかを憶測する必要がありません。
マルチモーダルモデルは、これまで使用していたインターフェイスを通じて、視覚コンテンツを含むための追加のfileオブジェクトを持っているだけで使用できます。ファイルオブジェクトは、OneRouter上のすべてのモデルで機能します。
リクエストに画像をURLまたはbase64エンコーディングを通じて含めることができます。画像がすでにオンラインにある場合、URLアプローチはより簡単です:
import requests import json url = "https://llm.onerouter.pro/v1/chat/completions" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } messages = [ { "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "image_url", "image_url": { "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg" } } ] } ] payload = { "model": "{{MODEL}}", "messages": messages } response = requests.post(url, headers=headers, json=payload) print(response.json()["choices"][0]["message"]["content"])
ローカル画像の場合、base64エンコーディングを使用できます:
import requests import json import base64 from pathlib import Path def encode_image_to_base64(image_path): with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode('utf-8') url = "https://llm.onerouter.pro/v1/chat/completions" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } # Read and encode the image image_path = "path/to/your/image.jpg" base64_image = encode_image_to_base64(image_path) data_url = f"data:image/jpeg;base64,{base64_image}" messages = [ { "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "image_url", "image_url": { "url": data_url } } ] } ] payload = { "model": "{{MODEL}}", "messages": messages } response = requests.post(url, headers=headers, json=payload) print(response.json()["choices"][0]["message"]["content"])
モデルは実際の画像を確認し、それについて具体的な洞察を提供します。単に一般的なレスポンスではなく、実際に見ている内容を分析します。
PDF処理は同じ方法で機能し、文書分析を開きます。レポートについて質問したり、フォームを分析したり、複雑な文書から情報を抽出したりできます:
import requests import json url = "https://llm.onerouter.pro/api/v1/chat/completions" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } messages = [ { "role": "user", "content": [ { "type": "text", "text": "What are the main points in this document?" }, { "type": "file", "file": { "filename": "document.pdf", "file_data": "https://domain.org/file.pdf" } }, ] } ] payload = { "model": "{{MODEL}}", "messages": messages } response = requests.post(url, headers=headers, json=payload) print(response.json())
これは、財務報告書、学術論文、契約、または実際の内容に対するAI分析が必要な任意のPDFに対して優れた効果を発揮します。画像を比較したり、複数の文書を一緒に分析する必要がある場合は、単一のリクエストに複数の添付資料を含めることもできます。
マルチモーダルリクエストは、追加のデータタイプを処理しているため、テキストのみのリクエストよりもコストが高くなります。画像やPDFは、より多くの計算能力を必要とし、それが価格にあらわれます。各モデルの特定のマルチモーダル価格はモデルページで確認できます。
さまざまなモデルは視覚コンテンツに対して異なる強みを持っています。詳細な画像分析に優れているものもあれば、文書理解に優れたものもあります。異なるモデルを試して、特定のニーズや予算に最適なものを見つける必要があります。
実際のアプリケーションを構築する際には、コードが確実に解析できる予測可能なデータフォーマットが必要です。自由形式のテキストレスポンスはチャットインターフェイスに適していますが、特定の情報を抽出する必要があるアプリケーションには適していません。正規表現で解析する必要のある不確実なテキストを取得する代わりに、構造化出力 は、モデルが返すべきフィールドとデータ型の正確なJSONを強制します。これにより、解析エラーが排除され、アプリケーションコードがはるかにシンプルになります。
構造化出力は、次の基本構造を持つresponse_formatパラメータを使用します:
"response_format": { "type": "json_schema", # Always this for structured outputs "json_schema": { "name": "your_schema_name", # Name for your schema "strict": True, # Enforce strict compliance "schema": { # Your actual JSON schema definition goes here } } }
テキストから感情を抽出する完全な例を見てみましょう。これにより、構造化出力が実際にどのように機能するかがわかります:
response = client.chat.completions.create( model="openai/gpt-5-mini", messages=[ {"role": "user", "content": "Analyze the sentiment: 'This movie was absolutely terrible!'"} ], extra_body={ "response_format": { "type": "json_schema", "json_schema": { "name": "sentiment_analysis", "strict": True, "schema": { "type": "object", "properties": { "sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]}, "confidence": {"type": "number"} }, "required": ["sentiment", "confidence"] } } } } ) import json result = json.loads(response.choices[0].message.content) print(result)Powered By
ここで、スキーマ内で何が起こっているのかを見てみましょう:
sentiment: stringフィールドは、enumを使用して3つの特定の値に制限されています。モデルは「positive」、「negative」、または「neutral」以外の何かを返すことはできません
confidence: モデルの信頼度スコアのための数値フィールド
required: 両方のフィールドはレスポンスに存在しなければならず、モデルはそれらをスキップすることはできません
strict: True: スキーマ構造への厳密な遵守を強制します
構造化出力を使用しない場合、「感情は非常に悪い」とか「ネガティブです(95%確信)」のようなレスポンスを得る可能性があります。他の例に対して繰り返すことでリアルタイムデータを生成することができる.
strict: Trueを設定することで、モデルはスキーマに厳密に従うことになります-モデルは構造から逸脱できません。required配列は、レスポンスに存在しなければならないフィールドを指定します。enumを使用して特定の選択肢に値を制限したり、arrayを使用してリストを作成したり、複雑なデータのためにネストされたobjectタイプを利用したりできます。
OneRouterの統一APIを通じて数百のAIモデルにアクセスする方法、最初のリクエストを行う方法、ストリーミング、推論トークン、構造化出力のような機能を実装する方法を学びました。
プラットフォームの自動フォールバックとモデルルーティングにより、個々のプロバイダーが問題に直面している時でも、アプリケーションが信頼性を保ったまま機能します。同じコードパターンを使用して、モデルを比較したり、プロバイダーを切り替えたり、それぞれのタスクに最適なフィットを見つけたりすることができ、複数のAPIキーを管理する必要がなくなります。
シンプルなリクエストで実験を開始し、ニーズが成長するにつれて、徐々により多くの機能を試してみてください。さまざまなタスクに対して異なるモデルをテストし、創造的なライティング、データ分析、推論問題でどれが最も良く機能するかを確認してください。
ここで得た知識は、特定のプロバイダーにロックされないAIアプリケーションを構築するために必要なものであり、新しいモデルや機能が利用可能になるにつれて、柔軟に適応できる自由を与えてくれます。
複数のAIプロバイダーAPIの管理はすぐに圧倒されることになります。各プロバイダーには異なる認証方法、料金モデル、API仕様があります。開発者は、さまざまなモデルにアクセスするためにOpenAI、Anthropic、Googleなどのプラットフォーム間で切り替えるのに無駄な時間を費やします。
OneRouterは、数十のプロバイダーから250以上のモデルに接続する統一APIを提供することでこの複雑さを解決します。1つのAPIキーと一貫したインターフェイスを使用して、GPT-5、Claude 4、Gemini 2.5 Pro、およびその他の数百のモデルにアクセスできます。このプラットフォームは、裏で自動フォールバック、コスト管理、プロバイダーのルーティングを処理します。
このチュートリアルでは、OneRouterについて知っておくべきこと全て、最初のAPIコールの設定から、構造化出力のような高度な機能の実装までを説明します。最後には、特定のプロバイダーに縛られない信頼性の高いアプリケーションの構築方法を学べます。
OneRouterは、1つのエンドポイントを通じて数十のプロバイダーから250以上のAIモデルにアクセスできる統一APIプラットフォームです。OpenAI、Anthropic、Google、Metaなどのために別々のAPIキーを扱う代わりに、全モデルカタログにアクセスするために1つのキーを使用します。
このプラットフォームはインテリジェントなルーターとして機能し、認証、請求、エラーハンドリングを処理しながらリクエストを適切なプロバイダーに送信します。このアプローチは、複数のAIプロバイダーを使用する際に発生するいくつかの頭痛を解決します。
複数のAIプロバイダーで作業することはすぐに混乱します。それぞれが独自のAPIフォーマット、ログインプロセス、請求システムを持っています。結果として、開発者は各サービスごとに別々のコードを維持することになり、開発が遅れ、新しいモデルをテストするのが大変になります。
プロバイダーがダウンしたり、レート制限に達した場合、状況はさらに悪化します。アプリが壊れ、何もできずに待つことになります。また、似たモデルに対する最良の価格を提供するプロバイダーを特定するには、異なるプラットフォームで手動でコストを追跡する必要があります。
最大の問題は、1つのプロバイダーに縛られてしまうことです。特定のAPIを中心にしてすべてを構築すると、後でより良いモデルや安価なオプションに切り替えるのが大きなプロジェクトになります。
OneRouterは、一連の接続された機能を使用してこれらの問題を解決します:
1つのAPIキーで250以上のモデルにアクセスできます
最初の選択が失敗したときに自動的にバックアッププロバイダーに切り替えることを可能にします
すべてのモデルに対する並列価格設定が可能で、コストを瞬時に比較できます
既存のOpenAIコードと連携して機能します — エンドポイントURLを変更するだけです
リアルタイムモニタリングにより、最も速い利用可能なプロバイダーにリクエストをルーティングします
これらの機能は一体となって、AI開発をよりスムーズで信頼性の高いものにします。
異なるタイプのユーザーがこの統一アプローチから価値を得ます:
開発者は、あちこちでアカウントを設定することなく新しいモデルを試すことができ、実験が迅速になります
企業チームは、プロバイダーが失敗したときに自動バックアップを通じて必要なアップタイムを確保します
予算を重視するユーザーは、スプレッドシート計算なしで自分のニーズに合った最も安価なオプションを見つけることができます
研究者は、アカウント設定のオーバーヘッドなしに、最先端のモデルに即座にアクセスできます
OneRouterがどのような価値を提供するのかを理解したので、最初のAPIコールを設定してみましょう。
OneRouterに飛び込む前に、いくつかの準備が必要です。このチュートリアルは、基本的なPythonプログラミングに慣れ、以前にAPIで作業した経験があることを前提としています。専門家である必要はありませんが、HTTPリクエストの作成やJSONレスポンスの処理などの概念を理解している必要があります。
システムにPython 3.7以降がインストールされている必要があります。OneRouterのAPIと対話するためにopenai Pythonパッケージを使用し、環境変数を安全に扱うためにpython-dotenvも使用します。どちらも以下のコマンドでインストールできます:
また、OneRouterアカウントとAPIキーが必要です。OneRouter にアクセスして無料アカウントを作成してください。すぐに試すための小額のクレジットが付与されます。ログインしたら、アカウント設定のAPIキーセクションに移動して新しいキーを生成します。
APIキーを取得したら、プロジェクトディレクトリに.envファイルを作成し、次のようにキーを追加します:
これにより、APIキーが安全に保たれ、コードから外れます。テストを超えてOneRouterを使用する予定がある場合、クレジットページを通じてアカウントにクレジットを追加する必要があります。
これらの基本が整ったら、OneRouterを介して最初のAPIコールを行う準備が整いました。
OneRouterを使い始めるのは非常にシンプルです。以前にOpenAI SDKを使用したことがある場合、コードの1行を変更するだけで異なるプロバイダーから数百のモデルにアクセスできます。
OneRouterのアプローチを示す動作例から始めましょう:
import os from openai import OpenAI from dotenv import load_dotenv load_dotenv() client = OpenAI( base_url="https://llm.onerouter.pro/v1", api_key=os.getenv("ONEROUTER_API_KEY"), ) response = client.chat.completions.create( model="google-ai-studio/gemini-2.5-flash-preview-09-2025", messages=[ { "role": "user", "content": "Write a haiku about debugging code at 2 AM" } ] ) print(response.choices[0].message.content)
Night hum, coffee cooled cursor blinks, bug hides somewhere I chase ghosts 'til dawn
魔法は2つの場所で起こります。
まず、base_urlパラメータは、リクエストをGoogleのサーバーではなくOneRouterのサーバーにリダイレクトします。
次に、モデル名はprovider/model-nameフォーマットに従います - google-ai-studio/gemini-2.5-flash-preview-09-2025は、単にgemini-2.5-flash-preview-09-2025ではなく、どのプロバイダーのバージョンを望んでいるかをOneRouterに伝えます。
様々なモデルでの作業がいかに簡単かを見たので、選択したモデルが利用できない場合はどうなるのか、プロバイダーが問題に直面しても信頼性を維持するアプリケーションをどのように構築するのかについて疑問に思うかもしれません。これがOneRouterのルーティングとレジリエンス機能の出番です。
信頼性の高いAIアプリケーションを構築するには、予期しない事態に備える必要があります。プロバイダーはダウンタイムを経験し、モデルはレート制限に達し、時にはコンテンツモデレーションがリクエストをブロックします。モデルルーティングはOneRouterの解決策です — 自動的に異なるモデル間を切り替えて、アプリケーションがスムーズに動作し続けます。
レジリエンスを追加する最も簡単な方法は、バックアップモデルを指定することです。プライマリの選択が失敗したとき、OneRouterは順番に代替案を試します。
{ "model": "gemini-2.5-flash", "fallback_models": ["gemini-2.5-flash", "grok-4-fast-non-reasoning", "qwen3-next-80b-a3b-instruct"], "fallback_rules": "auto" // default value is "auto" ... // Other params }
OneRouterはgemini-2.5-flashを最初に試みます。それが利用できない場合、レート制限されている場合、またはブロックされている場合は、自動的にgrok-4-fast-non-reasoning、次にqwen3-next-80b-a3b-instructを試みます。response.modelフィールドには、実際に応答したモデルが表示されます。
すべてのモデルが互いに良いバックアップになるわけではありません。プロバイダーのダウンタイムは、その企業のすべてのモデルに影響を与える可能性があるため、異なるプロバイダーのバックアップを選択してください。レート制限やコストは大きく変動するため、高価なモデルには安価な代替を組み合わせてください:
# Good fallback chain: different providers, decreasing cost response = client.chat.completions.create( model="anthropic/claude-sonnet-4", messages=[ {"role": "user", "content": "Your prompt here"} ], extra_body={ "models": [ "x-ai/grok-4", # Close performance "moonshotai/kimi-k2", # Cheaper ] } )
これにより、利用可能な場合は高品質、バックアップとしてしっかりしたパフォーマンス、最後の手段としては保証された利用可能性が得られます。プロバイダー間のコンテンツモデレーションポリシーも異なるため、チェーンを多様化すると、敏感なトピックに対するカバレッジが向上します。
モデルページ models page では、プロバイダーや機能でフィルタリングしてチェーンを構築できます。DeepSeek R1やKimi-K2のような多くの強力なモデルは特に安価で、素晴らしいフォールバックとなります。
動的アプリケーションでは、プログラム的にモデルを発見できます:
def get_provider_models(api_key: str, provider: str) -> list[str]: r = requests.get( "https://llm.onerouter.pro/v1/models", headers={"Authorization": f"Bearer {api_key}"} ) return [m["id"] for m in r.json()["data"] if m["id"].startswith(provider)] # Build fallbacks across providers openai_models = get_provider_models(api_key, "openai/") anthropic_models = get_provider_models(api_key, "anthropic/")
このアプローチにより、新しいモデルが利用可能になった際に適応する堅牢なフォールバックチェーンを構築できます。
AIモデルを使用する際、特に長いレスポンスの場合、ユーザーは完全なレスポンスを待つのではなく、出力が徐々に表示されることを期待します。ストリーミングは、モデルが生成するたびにレスポンスのチャンクを送信し、ChatGPTのインターフェイスに似たよりインタラクティブな体験を作成します。
OneRouterでストリーミングを設定するには、リクエストにstream=Trueを追加します。レスポンスは、モデルが生成する際にチャンクを出力するイテレータになります:
response = client.chat.completions.create( model="openai/gpt-5", messages=[ {"role": "user", "content": "Write a detailed explanation of how neural networks learn"} ], stream=True ) for chunk in response: if chunk.choices[0].delta.content is not None: print(chunk.choices[0].delta.content, end="")
各チャンクにはレスポンスの小さな部分が含まれています。delta.contentフィールドには新しいテキストの断片が保持されており、ストリーミング効果を生み出すために、改行を追加せずに即座に印刷します。end=""パラメータは、チャンク間で改行を追加しないことを防ぎます。
プロダクションアプリケーションでは、ストリーミングプロセスに対してより多くのコントロールが必要です。ここでは、完全なレスポンスを管理するためのより包括的なハンドラーの例を示します:
def stream_response(model, messages, show_progress=True): response = client.chat.completions.create( model=model, messages=messages, stream=True ) complete_response = "" for chunk in response: if chunk.choices[0].delta.content is not None: content = chunk.choices[0].delta.content complete_response += content if show_progress: print(content, end="", flush=True) if show_progress: print() # Add final newline return complete_response # Use it with different models result = stream_response( "anthropic/claude-sonnet-4", [{"role": "user", "content": "Explain quantum entanglement like I'm 12 years old"}] )Powered By
このハンドラーは、進行状況を表示しながら完全なレスポンスをキャッチし、ストリーミング体験と最終的なテキストの両方を提供し、適切な出力フォーマットを含みます。
ストリーミングは、ユーザーの体験を「待って希望する」状態から「進行状況を見る」状態に変えます。これにより、AIアプリケーションはユーザーにとってより応答性が高く、魅力的なものに感じられます。
一部のAIモデルは、最終的な答えを出す前に「思考」プロセスを見せてくれます。これらの推論トークンは、モデルが複雑な問題に取り組む方法を透明に示し、結論を導くステップバイステップの論理を提供します。内部の推論を理解することで、回答を検証し、モデルの動作をデバッグし、より信頼性のあるアプリケーションを構築するのに役立ちます。
推論トークンは、レスポンスの別のreasoning_contentフィールドに表示され、メインコンテンツとは異なります。異なるモデルは異なる方法で推論をサポートしています—一部は努力レベルを使用し、他はトークン予算を使用します。
以下に、推論の実際の例を示します:
from openai import OpenAI client = OpenAI( base_url="https://llm.onerouter.pro/v1", api_key="<<API_KEY_REF>>", ) response = client.chat.completions.create( model="<<MODEL>>", messages=[ {"role": "user", "content": "How would you build the world's tallest skyscraper?"} ], extra_body={ "reasoning": { "effort": "high", "max_tokens": 2000 } }, ) print("Final answer:") print(response.choices[0].message.content) print("\nReasoning process:") print(response.choices[0].message.reasoning_content)
Final answer:
To count the 'r's in 'strrawberry', I'll go through each letter:
...
There are **4**
モデルは、最終的な答えとその結論に至るまでの内部推論の両方を示します。この二重出力は、モデルが問題に正しくアプローチしているかどうかを理解するのに役立ちます。
モデルがレスポンスにおいてどれだけの推論の努力をかけるかを、2つのアプローチを使用して制御できます。effortパラメータは、OpenAIのoシリーズのようなモデルと一緒に機能し、max_tokens設定に基づいて特定のトークンパーセンテージに相当するレベルを使用します:
"effort": "xhigh" - 推論に最大のトークンを割り当てます(最大トークンの約95%)
"effort": "high" - 推論に大部分のトークンを割り当てます(最大トークンの約80%)
"effort": "medium" - トークンの中程度の部分を割り当てます(最大トークンの約50%)
"effort": "low" - 小さい部分のトークンを割り当てます(最大トークンの約20%)
"effort": "minimal" - さらに小さい部分のトークンを割り当てます(最大トークンの約10%)
"effort": "none" - 推論を完全に無効にします
直接のトークン割り当てをサポートするモデルでは、具体的な推論予算を指定できます:
def get_reasoning_response(question, reasoning_budget=2000): response = client.chat.completions.create( model="anthropic/claude-sonnet-4", messages=[{"role": "user", "content": question}], max_tokens=10000, extra_body={ "reasoning": { "max_tokens": reasoning_budget # Exact token allocation } } ) return response # Compare different reasoning budgets response = get_reasoning_response( "What's bigger: 9.9 or 9.11? Explain your reasoning carefully.", reasoning_budget=3000 ) print("Answer:", response.choices[0].message.content) print("Detailed reasoning:", response.choices[0].message.reasoning_content)
高いトークン予算は一般的により詳細な推論を生成し、低い予算はより迅速ではあるが詳細が少ない思考プロセスを提供します。
マルチターンの会話を構築する際は、文脈を維持するために推論と最終答えの両方を保存する必要があります。これは、モデルの思考プロセスがその後の応答に影響を与える複雑な議論では特に重要です:
# First message with reasoning response = client.chat.completions.create( model="anthropic/claude-sonnet-4", messages=[ {"role": "user", "content": "Should I invest in renewable energy stocks? Consider both risks and opportunities."} ], extra_body={ "reasoning": { "max_tokens": 3000 } } ) # Build conversation history with reasoning preserved messages = [ {"role": "user", "content": "Should I invest in renewable energy stocks? Consider both risks and opportunities."}, { "role": "assistant", "content": response.choices[0].message.content, "reasoning_details": response.choices[0].message.reasoning_content # Preserve reasoning }, {"role": "user", "content": "What about solar energy specifically? How does that change your analysis?"} ] # Continue conversation with reasoning context follow_up = client.chat.completions.create( model="anthropic/claude-sonnet-4", messages=messages, extra_body={ "reasoning": { "max_tokens": 2000 } } ) print("Follow-up answer:") print(follow_up.choices[0].message.content) print("\nContinued reasoning:") print(follow_up.choices[0].message.reasoning_content)
フィールドreasoning_contentは、完全な推論チェーンを保持し、モデルが前の分析に基づいて後続の質問に答えることを可能にします。これにより、より一貫性があり、文脈を理解した会話が実現します。
推論トークンは出力トークンとして請求されるため、使用コストが増加します。しかし、特に精度が重要な複雑なタスクでは、通常のレスポンス品質を向上させるためその費用を正当化します。OneRouterのドキュメントによれば、推論トークンは、モデルの性能を向上させながら、意思決定プロセスの透明性を提供します。
コストを重視するアプリケーションでは、タスクの複雑さに基づいて努力レベルやトークン予算を調整することで、経費と推論品質をバランスさせることができます。簡単な質問では推論が全く必要ないかもしれませんが、複雑な問題には高い努力の推論が利益をもたらします。
これまでテキストで作業してきましたが、画像や文書を分析する必要がある場合はどうなりますか?チャートについて質問したり、PDFから情報を抽出したり、写真で何が起こっているかを説明したりしたい場合です。ここでマルチモーダルモデルが登場します — これらは同じリクエスト内でテキストと視覚コンテンツの両方を理解できます。
画像をテキストで説明しようとするのではなく、実際の画像を送信し、それについて直接質問することができます。これにより、モデルが実際にどのような情報を扱っているのかを正確に見ることができるため、アプリケーションがはるかに直感的になります。テキストの説明がすべての重要な詳細をキャッチしたかどうかを憶測する必要がありません。
マルチモーダルモデルは、これまで使用していたインターフェイスを通じて、視覚コンテンツを含むための追加のfileオブジェクトを持っているだけで使用できます。ファイルオブジェクトは、OneRouter上のすべてのモデルで機能します。
リクエストに画像をURLまたはbase64エンコーディングを通じて含めることができます。画像がすでにオンラインにある場合、URLアプローチはより簡単です:
import requests import json url = "https://llm.onerouter.pro/v1/chat/completions" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } messages = [ { "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "image_url", "image_url": { "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg" } } ] } ] payload = { "model": "{{MODEL}}", "messages": messages } response = requests.post(url, headers=headers, json=payload) print(response.json()["choices"][0]["message"]["content"])
ローカル画像の場合、base64エンコーディングを使用できます:
import requests import json import base64 from pathlib import Path def encode_image_to_base64(image_path): with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode('utf-8') url = "https://llm.onerouter.pro/v1/chat/completions" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } # Read and encode the image image_path = "path/to/your/image.jpg" base64_image = encode_image_to_base64(image_path) data_url = f"data:image/jpeg;base64,{base64_image}" messages = [ { "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "image_url", "image_url": { "url": data_url } } ] } ] payload = { "model": "{{MODEL}}", "messages": messages } response = requests.post(url, headers=headers, json=payload) print(response.json()["choices"][0]["message"]["content"])
モデルは実際の画像を確認し、それについて具体的な洞察を提供します。単に一般的なレスポンスではなく、実際に見ている内容を分析します。
PDF処理は同じ方法で機能し、文書分析を開きます。レポートについて質問したり、フォームを分析したり、複雑な文書から情報を抽出したりできます:
import requests import json url = "https://llm.onerouter.pro/api/v1/chat/completions" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } messages = [ { "role": "user", "content": [ { "type": "text", "text": "What are the main points in this document?" }, { "type": "file", "file": { "filename": "document.pdf", "file_data": "https://domain.org/file.pdf" } }, ] } ] payload = { "model": "{{MODEL}}", "messages": messages } response = requests.post(url, headers=headers, json=payload) print(response.json())
これは、財務報告書、学術論文、契約、または実際の内容に対するAI分析が必要な任意のPDFに対して優れた効果を発揮します。画像を比較したり、複数の文書を一緒に分析する必要がある場合は、単一のリクエストに複数の添付資料を含めることもできます。
マルチモーダルリクエストは、追加のデータタイプを処理しているため、テキストのみのリクエストよりもコストが高くなります。画像やPDFは、より多くの計算能力を必要とし、それが価格にあらわれます。各モデルの特定のマルチモーダル価格はモデルページで確認できます。
さまざまなモデルは視覚コンテンツに対して異なる強みを持っています。詳細な画像分析に優れているものもあれば、文書理解に優れたものもあります。異なるモデルを試して、特定のニーズや予算に最適なものを見つける必要があります。
実際のアプリケーションを構築する際には、コードが確実に解析できる予測可能なデータフォーマットが必要です。自由形式のテキストレスポンスはチャットインターフェイスに適していますが、特定の情報を抽出する必要があるアプリケーションには適していません。正規表現で解析する必要のある不確実なテキストを取得する代わりに、構造化出力 は、モデルが返すべきフィールドとデータ型の正確なJSONを強制します。これにより、解析エラーが排除され、アプリケーションコードがはるかにシンプルになります。
構造化出力は、次の基本構造を持つresponse_formatパラメータを使用します:
"response_format": { "type": "json_schema", # Always this for structured outputs "json_schema": { "name": "your_schema_name", # Name for your schema "strict": True, # Enforce strict compliance "schema": { # Your actual JSON schema definition goes here } } }
テキストから感情を抽出する完全な例を見てみましょう。これにより、構造化出力が実際にどのように機能するかがわかります:
response = client.chat.completions.create( model="openai/gpt-5-mini", messages=[ {"role": "user", "content": "Analyze the sentiment: 'This movie was absolutely terrible!'"} ], extra_body={ "response_format": { "type": "json_schema", "json_schema": { "name": "sentiment_analysis", "strict": True, "schema": { "type": "object", "properties": { "sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]}, "confidence": {"type": "number"} }, "required": ["sentiment", "confidence"] } } } } ) import json result = json.loads(response.choices[0].message.content) print(result)Powered By
ここで、スキーマ内で何が起こっているのかを見てみましょう:
sentiment: stringフィールドは、enumを使用して3つの特定の値に制限されています。モデルは「positive」、「negative」、または「neutral」以外の何かを返すことはできません
confidence: モデルの信頼度スコアのための数値フィールド
required: 両方のフィールドはレスポンスに存在しなければならず、モデルはそれらをスキップすることはできません
strict: True: スキーマ構造への厳密な遵守を強制します
構造化出力を使用しない場合、「感情は非常に悪い」とか「ネガティブです(95%確信)」のようなレスポンスを得る可能性があります。他の例に対して繰り返すことでリアルタイムデータを生成することができる.
strict: Trueを設定することで、モデルはスキーマに厳密に従うことになります-モデルは構造から逸脱できません。required配列は、レスポンスに存在しなければならないフィールドを指定します。enumを使用して特定の選択肢に値を制限したり、arrayを使用してリストを作成したり、複雑なデータのためにネストされたobjectタイプを利用したりできます。
OneRouterの統一APIを通じて数百のAIモデルにアクセスする方法、最初のリクエストを行う方法、ストリーミング、推論トークン、構造化出力のような機能を実装する方法を学びました。
プラットフォームの自動フォールバックとモデルルーティングにより、個々のプロバイダーが問題に直面している時でも、アプリケーションが信頼性を保ったまま機能します。同じコードパターンを使用して、モデルを比較したり、プロバイダーを切り替えたり、それぞれのタスクに最適なフィットを見つけたりすることができ、複数のAPIキーを管理する必要がなくなります。
シンプルなリクエストで実験を開始し、ニーズが成長するにつれて、徐々により多くの機能を試してみてください。さまざまなタスクに対して異なるモデルをテストし、創造的なライティング、データ分析、推論問題でどれが最も良く機能するかを確認してください。
ここで得た知識は、特定のプロバイダーにロックされないAIアプリケーションを構築するために必要なものであり、新しいモデルや機能が利用可能になるにつれて、柔軟に適応できる自由を与えてくれます。
OneRouter ガイド
By アンドリュー・ジェン •

エンタープライズLLMルーティングの複雑さを管理する

エンタープライズLLMルーティングの複雑さを管理する

AIモデルのトークン使用量を追跡する

AIモデルのトークン使用量を追跡する

OneRouter アンスロポシック クロード API

OneRouter アンスロポシック クロード API