본문으로 건너뛰기

사내 문서 검색 만들기 — 임베딩 API 첫 코드와 한국어 토큰 실측

개발 가이드약 8분 읽기비교표복사 양식점검 카드
핵심 요약8개 절 · 약 8분

사내 규정·매뉴얼 검색을 임베딩으로 만드는 네 단계, 복사해 돌리는 파이썬 코드, 한국어 문서를 색인할 때 실제로 든 토큰과 크레딧을 정리했어요.

읽는 분
사내 규정·매뉴얼 검색을 직접 만드는 개발자
끝나면
예시 문서로 임베딩 검색과 답 생성을 한 번 돌려 보고, 한국어 문서 색인과 질문마다 드는 크레딧을 어림해요.
이 글의 목차 (8개 절)
01

키 하나로 임베딩과 답 생성을 붙여요

사내 규정·매뉴얼 검색은 문서 조각을 임베딩해 두고, 질문과 가장 가까운 조각만 채팅 모델에 넣어 답하게 하면 돼요. 원포트 AI API 키 하나로 https://oneport.kr/v1 에서 임베딩과 답 생성을 같이 불러요. 쓰던 OpenAI SDK 가 있다면 base_url 만 바꾸면 돼요.

원포트가 시험 문서로 재 보니 한글 문서 100만 자를 text-embedding-3-small 로 색인해도 약 18 크레딧을 한 번 사용했어요. 질문이 쌓이면 크레딧은 대부분 답을 만드는 쪽에서 나가요.

1 크레딧 = 부가세 포함 2원어치예요.

혼자 붙여 볼 거라면 /pricing 에서 원포트 AI API 크레딧을 고르고 사면 바로 돌려 볼 수 있어요. 여러 개발자가 쓰거나 세금계산서·보안 검토가 필요한 회사라면 도입 문의로 알려 주세요.

원포트 AI 에서 부르는 텍스트 임베딩 모델
원포트 AI 에서 부르는 텍스트 임베딩 모델
text-embedding-3-small만든 회사OpenAI입력 100만 토큰당 사용(크레딧)18
text-embedding-3-large만든 회사OpenAI입력 100만 토큰당 사용(크레딧)120
text-embedding-ada-002만든 회사OpenAI입력 100만 토큰당 사용(크레딧)92
gemini-embedding-001만든 회사Google입력 100만 토큰당 사용(크레딧)138
gemini-embedding-2만든 회사Google입력 100만 토큰당 사용(크레딧)184

임베딩은 입력 토큰으로만 계산해요. text-embedding-ada-002 는 이전 세대예요. 2026년 10월 기준 /api 표 값이고 바뀔 수 있어요.

02

사내 문서 검색은 네 단계예요

문서와 질문은 같은 임베딩 모델로 받아야 해요. 모델이 다른 벡터끼리는 비교할 수 없어요.

  1. 문서를 쪽·절 단위 조각으로 나눠요.
  2. 조각마다 임베딩을 받아 벡터를 저장해요. 처음 한 번, 그리고 문서가 바뀔 때만 해요.
  3. 질문이 오면 질문도 임베딩해서, 코사인 유사도가 높은 조각 몇 개를 골라요.
  4. 고른 조각만 질문과 함께 채팅 모델에 넣어 답을 받아요.
03

복사해 돌리는 최소 코드

openai 파이썬 패키지를 쓰고, 주소만 원포트로 바꿔요. pip install openai 로 설치하고 환경 변수 ONEPORT_API_KEY 에 키를 넣은 뒤 실행해요. 코드에 키 원문을 적지 않아요. 키가 없으면 구매할 때 받을 메일로 「키 받기」 링크가 와요.

CLI · 설정

사내 문서 검색 최소 코드 (Python)

import math
import os

from openai import OpenAI

client = OpenAI(base_url="https://oneport.kr/v1", api_key=os.environ["ONEPORT_API_KEY"])

EMBED = "text-embedding-3-small"
CHAT = "claude-haiku-5-5"

# 예시 규정이에요. 숫자는 지어낸 값이니 실제 문서로 바꿔요.
docs = [
    "연차를 쓰려면 3일 전까지 팀장에게 신청해요.",
    "출장비는 다녀온 뒤 7일 안에 영수증을 붙여 정산해요.",
    "재택근무는 팀장 승인을 받아 주 2일까지 할 수 있어요.",
    "비품은 신청서를 내면 다음 주 월요일에 나눠 줘요.",
]

def embed(texts):
    r = client.embeddings.create(model=EMBED, input=texts)
    return [d.embedding for d in r.data]

def cos(a, b):
    dot = sum(x * y for x, y in zip(a, b))
    return dot / (math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b)))

doc_vecs = embed(docs)  # 색인: 한 번만

question = "출장 다녀오면 정산은 언제까지 해야 해요?"
q_vec = embed([question])[0]  # 질문마다

top = sorted(range(len(docs)), key=lambda i: cos(q_vec, doc_vecs[i]), reverse=True)[:2]
context = "\n".join(docs[i] for i in top)

answer = client.chat.completions.create(
    model=CHAT,
    messages=[
        {"role": "system", "content": "아래 사내 문서만 근거로 답하고, 없으면 모른다고 해요.\n\n" + context},
        {"role": "user", "content": question},
    ],
)
print(answer.choices[0].message.content)
04

한국어 문서는 몇 토큰이 될까

원포트가 시험 문서로 text-embedding-3-small 색인을 돌려 실제 차감 토큰을 쟀어요. 한글이 많은 문서는 대략 1자가 1토큰, 영어 문서는 약 4자가 1토큰이었어요.

다른 임베딩 모델은 토큰 세는 법이 다를 수 있어 이 비율을 옮겨 쓰지 않아요.

원포트 시험 문서로 잰 글자 수와 입력 토큰
원포트 시험 문서로 잰 글자 수와 입력 토큰
한글 절반 문서글자 수26,544자입력 토큰(약)25,400한글 비중47%
한글 위주 짧은 문서글자 수4,808자입력 토큰(약)4,400한글 비중60%
영어 문서글자 수987,531자입력 토큰(약)257,000한글 비중0%

text-embedding-3-small 기준. 한글 비중은 띄어쓰기를 포함한 전체 글자 중 한글의 비율이에요. 표·영어 비중·모델에 따라 달라져요.

05

색인은 한 번, 질문마다 드는 몫이 더 커요

예를 들어 claude-haiku-5-5 는 /api 표에서 입력 100만 토큰당 92 크레딧이라, 고른 조각이 4,000토큰이면 입력만 약 0.37 크레딧을 사용해요. 출력 몫은 답 길이만큼 더해져요. 같은 조각이 질문마다 다시 들어가서, 질문이 쌓일수록 색인보다 이쪽이 커져요.

사내 문서 검색에서 크레딧을 사용하는 곳
사내 문서 검색에서 크레딧을 사용하는 곳
문서 색인대략 입력 토큰문서 글자 수만큼(한글 기준)언제 사용하나처음 한 번 · 문서가 바뀔 때어디에 차감임베딩 모델 입력
질문 임베딩대략 입력 토큰몇십언제 사용하나질문마다어디에 차감임베딩 모델 입력
답 생성대략 입력 토큰고른 조각 + 질문언제 사용하나질문마다어디에 차감채팅 모델 입력·출력
06

조각 크기와 모델 고르기

조각은 고른 모델의 입력 상한보다 넉넉히 작게 잘라요. gemini-embedding-001 은 입력 상한이 2,048토큰이라 다른 세 모델보다 조각을 작게 잘라야 해요.

임베딩 모델을 바꿀 땐 색인을 처음부터 다시 해요. 구글 문서는 gemini-embedding-001 에서 2 로 옮길 때 「you must re-embed all of your existing data」라고 적어요.

임베딩 모델의 기본 차원과 입력 상한
임베딩 모델의 기본 차원과 입력 상한
text-embedding-3-small기본 차원1536입력 상한(토큰)8,192
text-embedding-3-large기본 차원3072입력 상한(토큰)8,192
gemini-embedding-001기본 차원3072입력 상한(토큰)2,048
gemini-embedding-2기본 차원3072입력 상한(토큰)8,192

text-embedding-3 두 모델은 dimensions 로 차원을 줄일 수 있어요. 출처: OpenAI 임베딩 가이드 · Google Gemini API 임베딩 문서, 2026년 10월 기준.

07

막힐 때

KeyError: 'ONEPORT_API_KEY' 가 나요

원인·확인
코드를 실행한 터미널에 환경 변수 ONEPORT_API_KEY 가 없어요.
해결 방법
같은 터미널에서 환경 변수에 키를 넣고 다시 실행해요.

401 「API 키가 없어요.」가 와요

원인·확인
환경 변수 ONEPORT_API_KEY 가 비어 있어요.
해결 방법
환경 변수에 키 전체를 넣어요.

401 「유효하지 않거나 폐기됐거나 기한이 지난 키예요.」가 와요

원인·확인
키 일부만 들어갔거나, 폐기됐거나 기한이 지난 키예요.
해결 방법
키 원문 전체를 다시 넣어요. 원문을 잃었거나 기한이 지났다면 새 키를 만들어요.

400 「… 은(는) 글 모델이에요. 임베딩 문으로는 부를 수 없어요」가 와요

원인·확인
EMBED 자리에 채팅 모델 id 를 넣었어요.
해결 방법
EMBED 에는 /api 표 임베딩 줄의 id 를, CHAT 에는 글 모델 id 를 넣어요.

404 「지원하지 않는 모델이에요」가 와요

원인·확인
모델 id 에 오타가 있어요.
해결 방법
GET /v1/models 에서 id 를 복사해 그대로 넣어요.

402 「크레딧이 부족해요.」가 와요

원인·확인
지갑 잔액이 모자라요. 한 번에 많이 보내면 잔액보다 큰 금액을 먼저 잡아 둬서 날 수 있어요.
해결 방법
한 번에 보내는 조각 수를 줄이거나 크레딧을 채워요.

403 model_not_in_plan 이 와요

원인·확인
산 크레딧으로 부를 수 없는 회사의 모델이에요.
해결 방법
키를 넣고 GET /v1/models 를 부르면 이 키로 부를 수 있는 모델만 나와요. 그 안에서 골라요.

429 key_limit_exceeded 나 group_limit_exceeded 가 와요

원인·확인
키의 한도나, 키가 붙은 그룹의 상한에 닿았어요. 그룹이 닫혀도 group_limit_exceeded 가 와요.
해결 방법
GET /v1/key 로 이 키의 이번 달·오늘 남은 한도를 봐요. 더 필요하면 키를 만든 관리자나 스페이스 관리자에게 말해 주세요.
08

팀과 회사에서 쓸 때

색인을 돌리는 배치와 서비스가 쓰는 키를 따로 만들고, 키마다 한 달 한도를 걸어 둬요. 색인이 키 한도에 닿아도 서비스 키는 그대로 써요. 다만 지갑 잔액은 두 키가 같이 쓰니 큰 색인 전에 잔액을 봐요. 같은 그룹에 붙인 키라면 그룹 상한도 같이 써요.

원포트는 임베딩·채팅으로 보낸 요청 본문을 남기지 않고 사용량만 기록해요. 각 AI 회사 쪽 처리는 그 회사 정책을 따라요. 만든 벡터와 조각 원문은 직접 둔 저장소에 남으니, 그 저장소의 접근 권한을 정해 두세요.

여러 개발자의 키·한도, 견적·세금계산서, 보안 검토 질문까지 한 번에 정하려면 도입 문의의 「필요한 것」에서 「API」를 골라 남겨 주세요. 늦어도 다음 영업일 안에 연락드려요.

자주 묻는 질문

벡터DB 가 꼭 있어야 하나요?

처음엔 없어도 돼요. 이 글 코드처럼 벡터를 메모리나 파일에 두고 코사인으로 골라도 돌아가요. 조각이 많아져 고르는 시간이 길어지면 그때 벡터 검색을 하는 저장소를 붙여요.

출처와 확인일

함께 보면 좋은 글과 도움말

← 블로그 전체 목록 보기