커스텀 LLM 연결하기

이 문서는 로컬 또는 자체 호스팅한 LLM 서버를 vox.ai에 연결하는 전체 과정을 설명합니다. 예시는 OpenAI gpt-4.1-mini를 사용하지만, 베이스 URL만 바꾸면 어떤 호환 서버에도 동일한 방식으로 적용할 수 있습니다.

사전 준비물

  • vox.ai 계정과 대시보드 접근 권한
  • OpenAI API Key (또는 호환 LLM 서버의 키)
  • Python 또는 Node.js 실행 환경
  • Ngrok(선택) – 로컬 서버를 외부에서 접근 가능하도록 터널링

1. 로컬 LLM 프록시 서버 실행

아래 두 가지 예시 중 하나를 선택해 실행하세요. 엔드포인트 규격은 POST /chat/completions 입니다.
import os, json
from typing import Optional, List, Dict, Any, Union, AsyncGenerator, Literal
from pydantic import BaseModel, Field
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from openai import AsyncOpenAI

app = FastAPI()
client = AsyncOpenAI(
    api_key=os.getenv("OPENAI_API_KEY"),
    # base_url=os.getenv("LLM_BASE_URL"),  # 커스텀 엔드포인트 사용 시
)

class ChatCompletionRequest(BaseModel):
    model: str
    messages: List[Dict[str, Any]]
    temperature: Optional[float] = Field(default=1.0, ge=0, le=2)
    max_tokens: Optional[int] = None
    stream: Optional[bool] = True
    tools: Optional[List[Dict[str, Any]]] = None
    tool_choice: Optional[Union[Literal["auto", "none", "required"], Dict[str, Any]]] = None

async def generate_streaming_response(stream) -> AsyncGenerator[str, None]:
    async for chunk in stream:
        yield f"data: {chunk.model_dump_json()}\n\n"
    yield "data: [DONE]\n\n"

@app.post("/chat/completions")
async def chat_completions(request: ChatCompletionRequest):
    response = await client.chat.completions.create(**request.model_dump(exclude_none=True))
    if request.stream:
        return StreamingResponse(generate_streaming_response(response), media_type="text/event-stream")
    return response.model_dump()

응답 형식 예시

  • 스트리밍(SSE)일 때: data: {chunk...}\n\n 형식으로 여러 청크가 전달되고 마지막에 data: [DONE] 이 전송됩니다.
  • 비스트리밍일 때: OpenAI Chat Completions 응답 JSON과 동일한 형태의 단일 객체가 반환됩니다.

실행 및 공개

  1. 서버 실행: Python 또는 Node 예제를 실행합니다.
  2. Ngrok 공개: 예) ngrok http 8000 → 발급된 퍼블릭 URL을 복사합니다.

2. vox.ai 대시보드에서 커스텀 LLM 설정

  1. 에이전트의 모델 설정으로 이동합니다.
  2. 모델 선택에서 “Custom”을 선택합니다.
  3. “추가”를 눌러 모델 이름과 Base URL을 입력합니다. 예: https://xxxx.ngrok-free.app/ vox.ai 커스텀 LLM 설정 화면
  4. 저장한 후, 해당 모델을 선택하여 에이전트를 연결합니다.

3. 요청/응답 플로우 이해하기

  1. vox.ai가 POST /chat/completions로 대화 문맥과 메타데이터를 보냅니다.
  2. 로컬 서버가 요청을 받아 OpenAI(또는 커스텀 LLM) API로 프록시합니다.
  3. 모델 응답을 스트리밍(SSE) 또는 전체 응답으로 전달합니다.
  4. vox.ai는 받은 응답을 통화/대화 인터페이스에 표시합니다.