콘텐츠로 이동

9.4. API로 앱 만들기

Backend.AI GO는 단순한 채팅 애플리케이션이 아닙니다. 여러분의 애플리케이션을 구동할 수 있는 완전한 AI API 서버입니다. Continuum Router에 앱을 연결하면, 단일 통합 인터페이스를 통해 로컬 모델(프라이버시와 오프라인 사용)과 클라우드 모델(최첨단 기능)을 모두 활용하는 도구를 만들 수 있습니다.

이 가이드에서는 인기 있는 프로그래밍 언어와 프레임워크를 사용하여 Backend.AI GO의 API를 애플리케이션에 통합하는 방법을 설명합니다.

구축 가능한 것들

Continuum Router의 OpenAI 호환 API는 다양한 애플리케이션 가능성을 열어줍니다:

  • 프라이버시 우선 챗봇: 로컬 모델을 사용하여 민감한 대화를 기기 내에서 유지하는 고객 지원 봇 구축
  • 하이브리드 문서 분석기: 기밀 문서를 Llama로 로컬 처리하고, 복잡한 분석 쿼리는 GPT-5나 Claude와 같은 클라우드 모델로 라우팅
  • 콘텐츠 생성 도구: 사용자가 어떤 모델을 사용할지 제어할 수 있는 작문 어시스턴트, 코드 생성기 또는 창작 도구 제작
  • 연구 플랫폼: 오프라인으로 작동하거나 방화벽 뒤에서 작동해야 하는 학술 또는 데이터 과학 도구 구축
  • 다중 기기 워크플로: 데스크톱에서 Backend.AI GO를 실행하고 휴대폰, 태블릿 또는 기타 기기에서 모델에 액세스

작동 원리

API 라우팅 API 라우팅

graph LR
    A[여러분의 애플리케이션] -->|OpenAI API| B[Continuum Router]
    B -->|라우팅| C[로컬 모델<br/>llama-server]
    B -->|라우팅| D[클라우드 모델<br/>OpenAI/Anthropic/Gemini]
    C -->|응답| B
    D -->|응답| B
    B -->|응답| A
  • 여러분의 애플리케이션이 OpenAI API 형식(채팅 완성, 모델 목록 등)을 사용하여 HTTP 요청을 보냅니다.
  • Continuum Router가 OpenAI 호환 엔드포인트에서 요청을 받아 적절한 백엔드로 라우팅합니다.
  • 요청은 로컬 모델(llama-server 또는 mlx-server를 통해) 또는 클라우드 모델(구성된 API 제공자를 통해)에 의해 처리됩니다.
  • 응답은 OpenAI API 형식으로 라우터를 통해 다시 전달됩니다.

API가 OpenAI 호환이므로, 공식 OpenAI SDK 또는 OpenAI를 지원하는 모든 라이브러리를 사용할 수 있으며, 단순히 base_url 매개변수를 로컬 Backend.AI GO 인스턴스로 변경하기만 하면 됩니다.

사전 준비

시작하기 전에 다음을 확인하세요:

  • Backend.AI GO가 설치되어 실행 중인 상태
  • 최소 하나의 모델이 사용 가능한 상태—Backend.AI GO에서 로드된 로컬 모델 또는 설정된 클라우드 제공자(클라우드 통합 참조)
  • Python 3.9+, Node.js 18+ 또는 HTTP 요청을 만들 수 있는 도구(curl, Postman 등)가 있는 개발 환경

1단계: API 활성화

API 페이지 - 일반 API 페이지 - 일반

Backend.AI GO는 API에 액세스하는 두 가지 방법을 제공합니다:

옵션 A: 내부 API (동일 기기)

내부 API는 Backend.AI GO가 시작될 때 자동으로 실행되며 로컬 기기에서만 액세스할 수 있습니다. 개발 및 테스트에 이상적입니다.

  • 엔드포인트: http://localhost:8000/v1
  • 구성 불필요 — 기본적으로 항상 실행 중
  • 로컬 액세스에 인증 불필요

옵션 B: TCP 서버 (외부 액세스)

TCP 서버는 로컬 네트워크의 다른 기기에서 API에 액세스할 수 있게 합니다. 다음과 같은 경우 활성화하세요:

  • 휴대폰, 태블릿 또는 다른 컴퓨터에서 모델에 액세스
  • 중앙 서버에 Backend.AI GO를 배포하고 여러 클라이언트 기기에서 연결
  • 다중 기기 애플리케이션 구축

TCP 서버 활성화 대화상자 TCP 서버 활성화 대화상자

외부 액세스를 활성화하려면:

  1. Backend.AI GO의 API 페이지로 이동합니다.
  2. TCP 서버 토글을 활성화합니다.
  3. 표시된 포트 번호를 확인합니다(기본값은 38080).
  4. 기기의 IP 주소를 찾습니다(예: 192.168.1.100).
  5. http://<your-ip>:38080/v1을 기본 URL로 사용합니다.

보안 팁

TCP 서버는 신뢰할 수 있는 로컬 네트워크용으로 설계되었습니다. 네트워크의 모든 기기를 신뢰할 수 있는 경우에만 활성화하세요. 외부 액세스가 있는 프로덕션 배포의 경우 설정 > 네트워크에서 인증을 구성하세요.

포트 구성

OpenAI 호환 API 엔드포인트는 내부 액세스를 위해 항상 포트 8000을 사용합니다. TCP 서버는 외부 액세스를 위해 별도의 구성 가능한 포트(기본값 38080)를 사용합니다. 둘 다 동일한 API를 제공합니다.

2단계: API 확인

애플리케이션과 통합하기 전에 API가 액세스 가능하고 작동하는지 확인하세요.

API 상태 및 타임아웃 API 상태 및 타임아웃

사용 가능한 모델 목록

curl http://localhost:8000/v1/models

예상 응답:

{
  "object": "list",
  "data": [
    {
      "id": "llama-3-8b",
      "object": "model",
      "created": 1704067200,
      "owned_by": "local"
    },
    {
      "id": "gpt-5.1",
      "object": "model",
      "created": 1704067200,
      "owned_by": "openai"
    }
  ]
}

채팅 완성 테스트

curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama-3-8b",
    "messages": [
      {"role": "user", "content": "프랑스의 수도는 어디인가요?"}
    ]
  }'

예상 응답:

{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "created": 1704067200,
  "model": "llama-3-8b",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "프랑스의 수도는 파리입니다."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 15,
    "completion_tokens": 8,
    "total_tokens": 23
  }
}

이러한 응답이 표시되면 API가 올바르게 작동하는 것입니다!

3단계: Python으로 구축하기

Python은 AI 애플리케이션에 가장 인기 있는 언어 중 하나입니다. Backend.AI GO는 공식 OpenAI Python SDK와 완벽하게 작동합니다.

SDK 설치

pip install openai

기본 통합

from openai import OpenAI

# SDK를 로컬 Backend.AI GO 인스턴스로 연결
client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"  # 로컬 액세스에는 인증 선택 사항
)

# 채팅 완성 요청 보내기
response = client.chat.completions.create(
    model="llama-3-8b",  # Backend.AI GO에서 사용 가능한 모든 모델 사용
    messages=[
        {"role": "user", "content": "AI에 관한 하이쿠를 써주세요"}
    ]
)

print(response.choices[0].message.content)
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"
)

# 응답을 토큰 단위로 스트리밍
stream = client.chat.completions.create(
    model="llama-3-8b",
    messages=[
        {"role": "user", "content": "양자 컴퓨팅을 간단하게 설명해주세요"}
    ],
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
from openai import OpenAI
import json

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"
)

# 모델이 호출할 수 있는 함수 정의
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "위치의 현재 날씨 가져오기",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "도시 이름"
                    }
                },
                "required": ["location"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="gpt-5.1",  # 함수 호출은 클라우드 모델에서 가장 잘 작동합니다
    messages=[
        {"role": "user", "content": "파리의 날씨는 어때요?"}
    ],
    tools=tools
)

# 모델이 함수를 호출하려는지 확인
message = response.choices[0].message
if message.tool_calls:
    for tool_call in message.tool_calls:
        function_name = tool_call.function.name
        arguments = json.loads(tool_call.function.arguments)
        print(f"모델이 호출하려는 함수: {function_name}({arguments})")

간단한 챗봇 만들기

from openai import OpenAI

def chatbot():
    client = OpenAI(
        base_url="http://localhost:8000/v1",
        api_key="not-needed"
    )

    messages = []
    print("챗봇이 시작되었습니다. 종료하려면 'quit'를 입력하세요.\n")

    while True:
        user_input = input("사용자: ")
        if user_input.lower() == 'quit':
            break

        messages.append({"role": "user", "content": user_input})

        response = client.chat.completions.create(
            model="llama-3-8b",
            messages=messages
        )

        assistant_message = response.choices[0].message.content
        messages.append({"role": "assistant", "content": assistant_message})

        print(f"봇: {assistant_message}\n")

if __name__ == "__main__":
    chatbot()

4단계: JavaScript/TypeScript로 구축하기

웹 애플리케이션과 Node.js 백엔드의 경우 OpenAI JavaScript SDK를 사용하세요.

SDK 설치

npm install openai

기본 통합

import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'http://localhost:8000/v1',
  apiKey: 'not-needed', // 로컬 액세스에는 인증 선택 사항
});

async function chat() {
  const response = await client.chat.completions.create({
    model: 'llama-3-8b',
    messages: [
      { role: 'user', content: 'AI에 관한 하이쿠를 써주세요' }
    ],
  });

  console.log(response.choices[0].message.content);
}

chat();
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'http://localhost:8000/v1',
  apiKey: 'not-needed',
});

async function streamChat() {
  const stream = await client.chat.completions.create({
    model: 'llama-3-8b',
    messages: [
      { role: 'user', content: '양자 컴퓨팅을 간단하게 설명해주세요' }
    ],
    stream: true,
  });

  for await (const chunk of stream) {
    const content = chunk.choices[0]?.delta?.content || '';
    process.stdout.write(content);
  }
}

streamChat();

웹 API 서버 만들기

import express from 'express';
import OpenAI from 'openai';

const app = express();
app.use(express.json());

const client = new OpenAI({
  baseURL: 'http://localhost:8000/v1',
  apiKey: 'not-needed',
});

app.post('/api/chat', async (req, res) => {
  try {
    const { message, model = 'llama-3-8b' } = req.body;

    const response = await client.chat.completions.create({
      model,
      messages: [{ role: 'user', content: message }],
    });

    res.json({
      success: true,
      response: response.choices[0].message.content,
    });
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : 'Unknown error';
    res.status(500).json({
      success: false,
      error: errorMessage,
    });
  }
});

app.listen(3000, () => {
  console.log('서버가 http://localhost:3000에서 실행 중입니다');
});

5단계: curl/REST로 구축하기

테스트, 자동화 스크립트 또는 OpenAI SDK가 없는 언어의 경우 직접 HTTP 요청을 사용할 수 있습니다.

채팅 완성

curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama-3-8b",
    "messages": [
      {"role": "user", "content": "안녕하세요!"}
    ],
    "temperature": 0.7,
    "max_tokens": 100
  }'

스트리밍

curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama-3-8b",
    "messages": [
      {"role": "user", "content": "이야기를 들려주세요"}
    ],
    "stream": true
  }' \
  --no-buffer

모델 목록

curl http://localhost:8000/v1/models

jq를 사용한 JSON 파싱

# 모델 응답만 가져오기
curl -s http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama-3-8b",
    "messages": [{"role": "user", "content": "안녕"}]
  }' | jq -r '.choices[0].message.content'

# 사용 가능한 모든 모델 나열
curl -s http://localhost:8000/v1/models | jq '.data[].id'

하이브리드 워크플로: 로컬 및 클라우드 모델 결합

API 메시 네트워크 토폴로지 API 메시 네트워크 토폴로지

Backend.AI GO의 가장 강력한 기능 중 하나는 동일한 애플리케이션에서 로컬 모델과 클라우드 모델을 혼합할 수 있다는 것입니다. 이를 통해 프라이버시, 비용 및 기능의 균형을 맞추는 하이브리드 워크플로를 구현할 수 있습니다.

예시: 프라이버시 우선 콘텐츠 검열

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"
)

def moderate_and_respond(user_message: str) -> str:
    # 1단계: 프라이버시를 위해 로컬에서 콘텐츠 확인
    moderation_prompt = f"""이 메시지의 정책 위반 여부를 분석하세요:

    메시지: {user_message}

    '안전함' 또는 '안전하지 않음'으로만 응답하세요."""

    moderation = client.chat.completions.create(
        model="llama-3-8b",  # 민감한 데이터에는 로컬 모델 사용
        messages=[{"role": "user", "content": moderation_prompt}]
    )

    if "안전하지 않음" in moderation.choices[0].message.content:
        return "해당 요청에 응답할 수 없습니다."

    # 2단계: 안전하면 클라우드 모델을 사용하여 고품질 응답 생성
    response = client.chat.completions.create(
        model="gpt-5.1",  # 더 나은 품질을 위해 클라우드 모델 사용
        messages=[{"role": "user", "content": user_message}]
    )

    return response.choices[0].message.content

# 사용
result = moderate_and_respond("양자 컴퓨팅에 대해 알려주세요")
print(result)

예시: 비용 최적화

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"
)

def smart_completion(prompt: str, complexity: str = "low") -> str:
    """
    복잡도에 따라 로컬 또는 클라우드 모델로 요청 라우팅
    """
    if complexity == "low":
        # 간단한 작업에는 무료 로컬 모델 사용
        model = "llama-3-8b"
    elif complexity == "medium":
        # 중간 복잡도에는 빠른 클라우드 모델 사용
        model = "gpt-5.1-mini"
    else:
        # 필요한 경우에만 강력한 클라우드 모델 사용
        model = "gpt-5.1"

    response = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": prompt}]
    )

    return response.choices[0].message.content

# 간단한 쿼리 - 로컬 모델 사용 (무료)
print(smart_completion("2+2는 얼마인가요?", complexity="low"))

# 복잡한 쿼리 - 클라우드 모델 사용 (유료)
print(smart_completion("양자 컴퓨팅이 암호학에 미치는 영향을 분석하세요", complexity="high"))

예시: 대체 전략

from openai import OpenAI
import httpx

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed",
    timeout=httpx.Timeout(10.0, connect=5.0)  # 총 10초, 연결 5초
)

def resilient_completion(prompt: str) -> str:
    """
    로컬 모델을 먼저 시도하고, 사용할 수 없으면 클라우드로 대체
    """
    models_to_try = [
        "llama-3-8b",      # 로컬 모델을 먼저 시도
        "gpt-5.1",         # 로컬 실패 시 클라우드로 대체
    ]

    for model in models_to_try:
        try:
            response = client.chat.completions.create(
                model=model,
                messages=[{"role": "user", "content": prompt}]
            )
            return response.choices[0].message.content
        except Exception as e:
            print(f"모델 {model} 실패: {e}")
            continue

    return "모든 모델을 사용할 수 없습니다. 나중에 다시 시도해주세요."

result = resilient_completion("신경망을 설명해주세요")
print(result)

문제 해결

문제 해결 방법
Connection refused Backend.AI GO가 실행 중인지 확인하세요. 내부 API가 활성화되어 있는지(포트 8000) 또는 외부 액세스를 위해 TCP 서버가 활성화되어 있는지 확인하세요.
Model not found 모델 이름이 Backend.AI GO의 모델 페이지에 나열된 것과 정확히 일치하는지 확인하세요. 로컬 모델의 경우 모델이 로드되어 있는지 확인하세요. 클라우드 모델의 경우 클라우드 통합에서 제공자가 구성되어 있는지 확인하세요.
응답이 느린 경우 로컬 모델은 하드웨어에 따라 다릅니다. 더 작은 모델을 사용하거나, 엔진 설정에서 GPU 가속을 활성화하거나, 더 빠른 응답을 위해 클라우드 모델을 사용하세요.
인증 오류 설정 > 네트워크에서 인증을 활성화한 경우 Authorization 헤더에 구성된 API 키를 전달하세요: Bearer your-api-key. 인증 없는 로컬 액세스의 경우 api_key="not-needed"로 설정하세요.
스트리밍이 작동하지 않는 경우 HTTP 클라이언트가 스트리밍을 지원하고 응답을 버퍼링하지 않는지 확인하세요. curl에서는 --no-buffer를 사용하세요. Python에서는 즉시 스트림을 반복하세요.
외부 액세스가 작동하지 않는 경우 API 페이지에서 TCP 서버가 활성화되어 있는지 확인하세요. 방화벽이 구성된 포트에서 연결을 허용하는지 확인하세요. localhost가 아닌 기기의 로컬 IP 주소(예: 192.168.1.100)를 사용하세요.

관련 페이지