원라우터 가이드

원라우터: 실용적인 예제가 포함된 가이드

원라우터 가이드
원라우터 가이드
원라우터 가이드
날짜

2025. 12. 21.

저자

앤드류 젱

여러 AI 공급자 API를 관리하는 것은 빠르게 압도적이 될 수 있습니다. 각 공급자는 다른 인증 방법, 가격 모델 및 API 사양을 가지고 있습니다. 개발자는 다양한 모델에 접근하기 위해 OpenAI, Anthropic, Google 및 기타 플랫폼 간에 전환하는 데 무수한 시간을 낭비합니다.

OneRouter는 수십 개의 공급자로부터 250개 이상의 모델에 연결할 수 있는 통합 API를 제공함으로써 이러한 복잡성을 해결합니다. 단일 API 키와 일관된 인터페이스를 사용하여 GPT-5, Claude 4, Gemini 2.5 Pro 및 수백 개의 다른 모델에 접근할 수 있습니다. 이 플랫폼은 자동 대체, 비용 관리 및 공급자 라우팅을 배경에서 처리합니다.

이 튜토리얼에서는 OneRouter에 대해 알아야 할 모든 것을 설명합니다. 첫 번째 API 호출을 설정하는 것부터 구조화된 출력과 같은 고급 기능을 구현하는 방법까지 다룹니다. 이 튜토리얼의 끝에서, 귀하는 단일 공급자에 고착되지 않는 신뢰할 수 있는 애플리케이션을 만드는 방법을 배우게 될 것입니다.


OneRouter란 무엇입니까? 

OneRouter는 단일 엔드포인트를 통해 수십 개의 공급자로부터 250개 이상의 AI 모델에 접근할 수 있는 통합 API 플랫폼입니다. OpenAI, Anthropic, Google, Meta 등과 같은 각각의 API 키를 관리하는 대신, 하나의 키를 사용하여 전체 모델 카탈로그에 접근할 수 있습니다.

이 플랫폼은 스마트 라우터 역할을 하며, 요청을 적절한 공급자에게 보내면서 인증, 청구 및 오류 처리를 관리합니다. 이 접근 방식은 여러 AI 공급자를 사용할 때 발생하는 몇 가지 두통을 해결합니다.


OneRouter가 해결하는 문제

여러 AI 공급자와 함께 작업하는 것은 빠르게 혼란스러워질 수 있습니다. 각각 고유한 API 형식, 로그인 프로세스 및 청구 시스템을 가지고 있습니다. 결국 각 서비스에 대해 별도의 코드를 유지 관리하게 되어 개발 속도가 느려지고 새로운 모델 테스트가 어려워집니다.

공급자가 다운되거나 요금 제한에 도달하면 상황은 더 나빠집니다. 귀하의 앱이 고장나고, 기다릴 수밖에 없는 상황이 발생합니다. 비슷한 모델에 대해 어떤 공급자가 가장 좋은 가격을 제공하는지 파악하는 것도 여러 플랫폼에서 수동으로 비용을 추적해야 함을 의미합니다.

가장 큰 문제는 하나의 공급자에 고착되는 것입니다. 특정 API 주위에 모든 것을 구축할 때, 나중에 더 나은 모델이나 더 저렴한 옵션으로 전환하는 것이 대규모 프로젝트가 됩니다.


OneRouter는 이를 어떻게 해결합니까?

OneRouter는 연결된 기능 세트로 이러한 문제를 해결합니다:

  • 하나의 API 키로 250개 이상의 모델에 접근

  • 첫 번째 선택이 실패할 때 백업 공급자로 자동 전환 가능

  • 모든 모델에 대한 나란히 가격 비교로 비용을 즉시 비교

  • 기존 OpenAI 코드와 작동 — 단지 엔드포인트 URL을 변경

  • 가장 빠른 제공자에게 요청을 라우팅하는 실시간 모니터링

이 요소들이 함께 작동하여 AI 개발을 더 원활하고 신뢰할 수 있게 만듭니다.


누가 OneRouter를 사용해야 하나요?

다양한 유형의 사용자가 이 통합 접근 방식의 가치를 얻습니다:

  • 개발자는 어디에서나 계정을 설정하지 않고 새로운 모델을 시도할 수 있어 실험이 더 빨라집니다.

  • 기업 팀은 공급자가 실패할 때 자동 백업을 통해 필요한 가동 시간을 확보합니다.

  • 예산을 고려하는 사용자는 스프레드시트 수학 없이 필요에 맞는 가장 저렴한 옵션을 찾을 수 있습니다.

  • 연구원은 계정 설정 오버헤드 없이 최첨단 모델에 즉시 접근할 수 있습니다.

이제 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에서 첫 번째 API 호출하기

OneRouter를 시작하는 것은 이전에 OpenAI SDK를 사용해본 경험이 있다면 매우 간단합니다. 한 줄의 코드만 변경하면 여러 공급자에서 수백 개의 모델에 접근하게 됩니다.


첫 번째 요청 및 설정

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

마법은 두 군데에서 일어납니다.

  • 첫째, 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
       ]
   }   
)

이를 통해 가능할 때 프리미엄 품질과 견고한 성능을 보장하며, 마지막 수단으로 보장된 가용성을 확보합니다. 콘텐츠 조정 정책도 공급자마다 다르기 때문에 체인을 다양화하면 민감한 주제에 대한 더 나은 커버리지를 제공합니다.


대체 체인을 위한 모델 찾기

모델 페이지 를 통해 공급자와 능력에 따라 필터링하여 체인을 구축할 수 있습니다. 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를 추가합니다. 응답은 모델이 생성하는 청크를 산출하는 반복자(iterable)가 됩니다:

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 애플리케이션에서 훨씬 더 반응을 느끼고 몰입할 수 있도록 만듭니다.


OneRouter에서 추론 토큰 처리하기

일부 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**

모델은 최종 답변과 이 결론에 이르게 된 내부 추론을 모두 보여줍니다. 이중 출력은 모델이 문제에 올바르게 접근했는지 이해하는 데 도움이 됩니다.


추론 강도 조절

모델이 응답에서 얼마나 많은 추론 노력을 기울이는지를 두 가지 방법으로 조절할 수 있습니다. effort 매개변수는 OpenAI의 o-series와 함께 작동하며, max_tokens 설정에 따라 특정 토큰 비율에 해당하는 수준을 사용합니다:

  • "effort": "xhigh" - 최대 토큰의 가장 큰 부분을 추론에 할당합니다 (약 95%)

  • "effort": "high" - 추론을 위한 많은 부분을 할당합니다 (약 80%)

  • "effort": "medium" - 중간 정도의 부분을 할당합니다 (약 50%)

  • "effort": "low" - 비교적 작은 부분을 할당합니다 (약 20%)

  • "effort": "minimal" - 훨씬 더 작은 부분을 할당합니다 (약 10%)

  • "effort": "none" - 추론을 완전히 비활성화합니다

직접적인 토큰 할당을 지원하는 모델의 경우, 예를 들면 Anthropic 모델에서는 정확한 추론 예산을 지정할 수 있습니다:

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의 문서에 따르면, 추론 토큰은 모델의 성능을 향상시키는 데 도움이 되며 결정 과정의 투명성을 제공합니다.

비용에 민감한 애플리케이션에서는 작업 복잡도에 따라 노력 수준이나 토큰 예산을 조정하여 추론 품질과 비용의 균형을 맞출 수 있습니다. 간단한 질문에 대해서는 추론이 필요하지 않을 수 있으며, 반면에 복잡한 문제는 고수준의 추론이 유리합니다.


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 문서 처리하기

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: 세 가지 특정 값을 제한하는 문자열 필드입니다. 모델은 "positive", "negative" 또는 "neutral" 외 다른 값을 반환할 수 없습니다.

  • confidence: 모델의 신뢰도 점수를 위한 숫자 필드입니다.

  • required: 두 필드 모두 응답에 존재해야 하며 - 모델은 이를 생략할 수 없습니다.

  • strict: True: 스키마 구조를 엄격하게 강제합니다.

구조화된 출력을 설정하면 모델은

여러 AI 공급자 API를 관리하는 것은 빠르게 압도적이 될 수 있습니다. 각 공급자는 다른 인증 방법, 가격 모델 및 API 사양을 가지고 있습니다. 개발자는 다양한 모델에 접근하기 위해 OpenAI, Anthropic, Google 및 기타 플랫폼 간에 전환하는 데 무수한 시간을 낭비합니다.

OneRouter는 수십 개의 공급자로부터 250개 이상의 모델에 연결할 수 있는 통합 API를 제공함으로써 이러한 복잡성을 해결합니다. 단일 API 키와 일관된 인터페이스를 사용하여 GPT-5, Claude 4, Gemini 2.5 Pro 및 수백 개의 다른 모델에 접근할 수 있습니다. 이 플랫폼은 자동 대체, 비용 관리 및 공급자 라우팅을 배경에서 처리합니다.

이 튜토리얼에서는 OneRouter에 대해 알아야 할 모든 것을 설명합니다. 첫 번째 API 호출을 설정하는 것부터 구조화된 출력과 같은 고급 기능을 구현하는 방법까지 다룹니다. 이 튜토리얼의 끝에서, 귀하는 단일 공급자에 고착되지 않는 신뢰할 수 있는 애플리케이션을 만드는 방법을 배우게 될 것입니다.


OneRouter란 무엇입니까? 

OneRouter는 단일 엔드포인트를 통해 수십 개의 공급자로부터 250개 이상의 AI 모델에 접근할 수 있는 통합 API 플랫폼입니다. OpenAI, Anthropic, Google, Meta 등과 같은 각각의 API 키를 관리하는 대신, 하나의 키를 사용하여 전체 모델 카탈로그에 접근할 수 있습니다.

이 플랫폼은 스마트 라우터 역할을 하며, 요청을 적절한 공급자에게 보내면서 인증, 청구 및 오류 처리를 관리합니다. 이 접근 방식은 여러 AI 공급자를 사용할 때 발생하는 몇 가지 두통을 해결합니다.


OneRouter가 해결하는 문제

여러 AI 공급자와 함께 작업하는 것은 빠르게 혼란스러워질 수 있습니다. 각각 고유한 API 형식, 로그인 프로세스 및 청구 시스템을 가지고 있습니다. 결국 각 서비스에 대해 별도의 코드를 유지 관리하게 되어 개발 속도가 느려지고 새로운 모델 테스트가 어려워집니다.

공급자가 다운되거나 요금 제한에 도달하면 상황은 더 나빠집니다. 귀하의 앱이 고장나고, 기다릴 수밖에 없는 상황이 발생합니다. 비슷한 모델에 대해 어떤 공급자가 가장 좋은 가격을 제공하는지 파악하는 것도 여러 플랫폼에서 수동으로 비용을 추적해야 함을 의미합니다.

가장 큰 문제는 하나의 공급자에 고착되는 것입니다. 특정 API 주위에 모든 것을 구축할 때, 나중에 더 나은 모델이나 더 저렴한 옵션으로 전환하는 것이 대규모 프로젝트가 됩니다.


OneRouter는 이를 어떻게 해결합니까?

OneRouter는 연결된 기능 세트로 이러한 문제를 해결합니다:

  • 하나의 API 키로 250개 이상의 모델에 접근

  • 첫 번째 선택이 실패할 때 백업 공급자로 자동 전환 가능

  • 모든 모델에 대한 나란히 가격 비교로 비용을 즉시 비교

  • 기존 OpenAI 코드와 작동 — 단지 엔드포인트 URL을 변경

  • 가장 빠른 제공자에게 요청을 라우팅하는 실시간 모니터링

이 요소들이 함께 작동하여 AI 개발을 더 원활하고 신뢰할 수 있게 만듭니다.


누가 OneRouter를 사용해야 하나요?

다양한 유형의 사용자가 이 통합 접근 방식의 가치를 얻습니다:

  • 개발자는 어디에서나 계정을 설정하지 않고 새로운 모델을 시도할 수 있어 실험이 더 빨라집니다.

  • 기업 팀은 공급자가 실패할 때 자동 백업을 통해 필요한 가동 시간을 확보합니다.

  • 예산을 고려하는 사용자는 스프레드시트 수학 없이 필요에 맞는 가장 저렴한 옵션을 찾을 수 있습니다.

  • 연구원은 계정 설정 오버헤드 없이 최첨단 모델에 즉시 접근할 수 있습니다.

이제 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에서 첫 번째 API 호출하기

OneRouter를 시작하는 것은 이전에 OpenAI SDK를 사용해본 경험이 있다면 매우 간단합니다. 한 줄의 코드만 변경하면 여러 공급자에서 수백 개의 모델에 접근하게 됩니다.


첫 번째 요청 및 설정

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

마법은 두 군데에서 일어납니다.

  • 첫째, 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
       ]
   }   
)

이를 통해 가능할 때 프리미엄 품질과 견고한 성능을 보장하며, 마지막 수단으로 보장된 가용성을 확보합니다. 콘텐츠 조정 정책도 공급자마다 다르기 때문에 체인을 다양화하면 민감한 주제에 대한 더 나은 커버리지를 제공합니다.


대체 체인을 위한 모델 찾기

모델 페이지 를 통해 공급자와 능력에 따라 필터링하여 체인을 구축할 수 있습니다. 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를 추가합니다. 응답은 모델이 생성하는 청크를 산출하는 반복자(iterable)가 됩니다:

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 애플리케이션에서 훨씬 더 반응을 느끼고 몰입할 수 있도록 만듭니다.


OneRouter에서 추론 토큰 처리하기

일부 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**

모델은 최종 답변과 이 결론에 이르게 된 내부 추론을 모두 보여줍니다. 이중 출력은 모델이 문제에 올바르게 접근했는지 이해하는 데 도움이 됩니다.


추론 강도 조절

모델이 응답에서 얼마나 많은 추론 노력을 기울이는지를 두 가지 방법으로 조절할 수 있습니다. effort 매개변수는 OpenAI의 o-series와 함께 작동하며, max_tokens 설정에 따라 특정 토큰 비율에 해당하는 수준을 사용합니다:

  • "effort": "xhigh" - 최대 토큰의 가장 큰 부분을 추론에 할당합니다 (약 95%)

  • "effort": "high" - 추론을 위한 많은 부분을 할당합니다 (약 80%)

  • "effort": "medium" - 중간 정도의 부분을 할당합니다 (약 50%)

  • "effort": "low" - 비교적 작은 부분을 할당합니다 (약 20%)

  • "effort": "minimal" - 훨씬 더 작은 부분을 할당합니다 (약 10%)

  • "effort": "none" - 추론을 완전히 비활성화합니다

직접적인 토큰 할당을 지원하는 모델의 경우, 예를 들면 Anthropic 모델에서는 정확한 추론 예산을 지정할 수 있습니다:

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의 문서에 따르면, 추론 토큰은 모델의 성능을 향상시키는 데 도움이 되며 결정 과정의 투명성을 제공합니다.

비용에 민감한 애플리케이션에서는 작업 복잡도에 따라 노력 수준이나 토큰 예산을 조정하여 추론 품질과 비용의 균형을 맞출 수 있습니다. 간단한 질문에 대해서는 추론이 필요하지 않을 수 있으며, 반면에 복잡한 문제는 고수준의 추론이 유리합니다.


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 문서 처리하기

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: 세 가지 특정 값을 제한하는 문자열 필드입니다. 모델은 "positive", "negative" 또는 "neutral" 외 다른 값을 반환할 수 없습니다.

  • confidence: 모델의 신뢰도 점수를 위한 숫자 필드입니다.

  • required: 두 필드 모두 응답에 존재해야 하며 - 모델은 이를 생략할 수 없습니다.

  • strict: True: 스키마 구조를 엄격하게 강제합니다.

구조화된 출력을 설정하면 모델은

원라우터: 실용적인 예제가 포함된 가이드

원라우터 가이드

By 앤드류 젱

제한 없이 확장합니다

단 몇 줄의 코드로 OneRouter를 원활하게 통합하고 무한한 AI 파워를 활용하세요.

제한 없이 확장합니다

단 몇 줄의 코드로 OneRouter를 원활하게 통합하고 무한한 AI 파워를 활용하세요.

제한 없이 확장합니다

단 몇 줄의 코드로 OneRouter를 원활하게 통합하고 무한한 AI 파워를 활용하세요.