임베딩
Schift는 단일 엔드포인트(endpoint) 세트를 통해 여러 공급자(OpenAI, Google, Voyage, Cloudflare, HuggingFace 등)로 프록시하는 통합 임베딩 API를 제공합니다. 모든 임베딩은 Schift의 정규 투영(Canonical Projection) 레이어를 통과하므로, 모델을 전환하거나 차원을 줄여도 데이터를 다시 임베딩할 필요가 없습니다.
활성 임베딩 엔드포인트는 Authorization 헤더에 Bearer 토큰이 필요합니다. 종료된 POST /v1/embed는 인증 전에 410 Gone 마이그레이션 응답을 반환합니다:
Authorization: Bearer sch_xxxxxxxxxxxxxxxxxxxxAPI 키(key)는 Schift 대시보드의 설정 > API 키에서 관리합니다.
지원 모델
섹션 제목: “지원 모델”| 모델(model) | 공급자(provider) | 기본 차원(default dimension) | 최대 토큰(max tokens) | 가변 차원(variable dimensions) |
|---|---|---|---|---|
schift-embed-1-small | Schift (auto) | 1024 | 8,192 | Yes |
openai/text-embedding-3-small | OpenAI | 1536 | 8,191 | Yes |
openai/text-embedding-3-large | OpenAI | 3072 | 8,191 | Yes |
google/gemini-embedding-001 | 3072 | 8,191 | Yes | |
google/gemini-embedding-002 | 3072 | 8,191 | Yes | |
voyage/voyage-4-large | Voyage AI | 1024 | 32,000 | Yes |
voyage/voyage-4 | Voyage AI | 1024 | 32,000 | Yes |
voyage/voyage-4-lite | Voyage AI | 1024 | 32,000 | Yes |
dragonkue/bge-m3-ko | HuggingFace | 1024 | 8,192 | No |
jinaai/jina-embeddings-v3 | HuggingFace | 1024 | 8,194 | Yes |
sbintuitions/sarashina-embedding-v2-1b | HuggingFace | 1792 | 8,192 | No |
schift-embed-1-small은 자동 라우팅 별칭(auto-routed alias)입니다. Schift는 입력 언어에 따라 최적의 기본 모델을 선택하고, 그 결과를 정규 투영(Canonical Projection) 레이어를 통과시킵니다. 해석된 모델(resolved model)은 모든 응답의 model 필드에 반환됩니다.
참고:
schift-embed-1-small을 사용할 때는@cf/qwen/qwen3-embedding-0.6b와 같은 내부(internal) 백엔드 별칭(backend alias)이 해석된 모델로 반환될 수 있습니다.
Task types
섹션 제목: “Task types”임베딩 엔드포인트는 선택적으로 task_type을 받아 임베딩이 어떻게 사용될지 Schift에 알려줍니다. 이 값은 instruction-aware(지시어 인식) 모델에는 그대로 전달되거나, 접두사(prefix) 스타일 모델의 경우 내부 접두사로 변환됩니다.
task_type | 사용 사례 |
|---|---|
retrieval_query | 검색 쿼리 임베딩 |
retrieval_document | 문서 임베딩 |
semantic_similarity | 의미적 유사도 비교 |
question_answering | 질문-응답 검색 |
clustering | 클러스터링(clustering) 또는 주제 그룹화 |
classification | 분류(classification) |
code_retrieval | 코드 검색 |
contradiction | 모순 또는 반대 증거 검색 |
factcheck | 팩트체크(fact-checking) 증거 검색 |
POST /v1/embed
섹션 제목: “POST /v1/embed”종료됨. 이 엔드포인트는 더 이상 임베딩을 실행하지 않습니다. 인증, 할당량 확인, 공급자 라우팅 또는 과금 전에 항상
410 Gone을 반환합니다.POST /v1/embeddings를 사용하세요.
마이그레이션 응답
섹션 제목: “마이그레이션 응답”curl https://api.schift.io/v1/embed \ -H "Content-Type: application/json" \ -d '{"text": "hello"}'{ "error": { "code": "endpoint_retired", "message": "POST /v1/embed has been retired. Use POST /v1/embeddings.", "details": { "successor": {"method": "POST", "path": "/v1/embeddings"} } }, "request_id": "req_..."}POST /v1/embed/batch
섹션 제목: “POST /v1/embed/batch”사용 중단 예정 — Sunset 2026-08-03. 후속 엔드포인트는
string[]형식의input을 받는POST /v1/embeddings입니다. 현재는 정상 동작하며Deprecation/Sunset/Link응답 헤더로만 사용 중단 예정을 알립니다.
동기식 일괄 임베딩. 하나의 요청에 최대 100개의 텍스트를 처리합니다. 더 많은 입력이 필요하면 POST /v1/embed/jobs를 사용하세요.
요청 본문
섹션 제목: “요청 본문”| 매개변수 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
texts | string[] | Yes | — | 임베딩할 텍스트 목록(최대 100개). |
model | string | No | 조직 라우팅 설정 | 카탈로그의 모델 ID. |
dimensions | integer | No | 모델 기본값 | 출력 차원. |
task_type | string | No | — | 임베딩 의도. |
응답 필드
섹션 제목: “응답 필드”| 필드 | 타입 | 설명 |
|---|---|---|
embeddings | number[][] | 입력 텍스트별 임베딩 벡터 목록. |
model | string | 사용된 모델. |
dimensions | integer | 출력 차원. |
usage.tokens | integer | 모든 텍스트의 총 토큰 수. |
usage.count | integer | 임베딩된 텍스트 수. |
요청 예시
섹션 제목: “요청 예시”curl https://api.schift.io/v1/embed/batch \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -d '{ "texts": [ "The Mediterranean diet emphasizes fish, olive oil, and vegetables.", "Photosynthesis converts light energy into chemical energy.", "Shakespeare wrote Hamlet and A Midsummer Night'"'"'s Dream." ], "model": "voyage/voyage-4-large" }'응답 예시
섹션 제목: “응답 예시”{ "embeddings": [ [-0.01225, 0.00207, 0.03060], [0.00898, -0.00298, 0.01546], [-0.06297, -0.04777, -0.10113] ], "model": "voyage/voyage-4-large", "dimensions": 1024, "usage": {"tokens": 38, "count": 3}}POST /v1/embed/jobs
섹션 제목: “POST /v1/embed/jobs”비동기식 대량 임베딩 작업(bulk embedding job)을 생성합니다. 이 엔드포인트는 101개에서 10,000개의 텍스트에 사용하세요.
요청 본문
섹션 제목: “요청 본문”| 매개변수 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
texts | string[] | Yes | — | 임베딩할 텍스트 목록(최대 10,000개). |
model | string | No | 조직 라우팅 설정 | 카탈로그의 모델 ID. |
dimensions | integer | No | 모델 기본값 | 출력 차원. |
task_type | string | No | — | 임베딩 의도. |
응답 필드
섹션 제목: “응답 필드”| 필드 | 타입 | 설명 |
|---|---|---|
id | string | 대량 임베딩 작업 ID. |
status | string | 초기 상태(queued). |
model | string | 작업에 선택된 모델. |
usage.tokens | integer | 모든 텍스트의 유효성이 검사된 총 토큰 수. |
usage.count | integer | 제출된 텍스트 수. |
chunk_size | integer | 워커(worker) 청크 크기(현재 100). |
요청 예시
섹션 제목: “요청 예시”curl https://api.schift.io/v1/embed/jobs \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -d '{ "texts": ["doc 1", "doc 2", "doc 3"], "model": "schift-embed-1-small", "task_type": "retrieval_document" }'응답 예시
섹션 제목: “응답 예시”{ "id": "job_123", "status": "queued", "model": "schift-embed-1-small", "usage": {"tokens": 6, "count": 3}, "chunk_size": 100}GET /v1/embed/jobs/{job_id}
섹션 제목: “GET /v1/embed/jobs/{job_id}”대량 임베딩 작업의 상태와 메타데이터를 조회합니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 매개변수 | 타입 | 설명 |
|---|---|---|
job_id | string | 대량 임베딩 작업 ID. |
작업 상태 수명 주기
섹션 제목: “작업 상태 수명 주기”| 상태(status) | 의미 |
|---|---|
queued | 작업이 생성되어 워커를 기다리는 중. |
embedding | 워커가 텍스트 청크를 임베딩하는 중. |
indexing | 결과를 준비하고 저장하는 중. |
ready | 결과를 조회할 수 있음. |
failed | 작업 실패. |
cancelled | 처리 전에 작업이 취소됨. |
요청 예시
섹션 제목: “요청 예시”curl https://api.schift.io/v1/embed/jobs/job_123 \ -H "Authorization: Bearer $SCHIFT_API_KEY"응답 예시
섹션 제목: “응답 예시”{ "id": "job_123", "status": "ready", "org_id": "org_abc", "metadata": { "mode": "embed_bulk", "model": "schift-embed-1-small", "dimensions": null, "task_type": "retrieval_document", "input_count": 3, "chunk_size": 100, "token_count": 6, "completed_count": 3 }}POST /v1/embed/jobs/{job_id}/cancel
섹션 제목: “POST /v1/embed/jobs/{job_id}/cancel”대기 중인 대량 임베딩 작업을 취소합니다. queued 상태의 작업만 취소할 수 있습니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 매개변수 | 타입 | 설명 |
|---|---|---|
job_id | string | 대량 임베딩 작업 ID. |
요청 예시
섹션 제목: “요청 예시”curl -X POST https://api.schift.io/v1/embed/jobs/job_123/cancel \ -H "Authorization: Bearer $SCHIFT_API_KEY"응답 예시
섹션 제목: “응답 예시”{ "status": "cancelled"}GET /v1/embed/jobs/{job_id}/result
섹션 제목: “GET /v1/embed/jobs/{job_id}/result”완료된 대량 임베딩 작업의 페이지 매김(paginated) 결과를 조회합니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 매개변수 | 타입 | 설명 |
|---|---|---|
job_id | string | 대량 임베딩 작업 ID. |
쿼리 매개변수
섹션 제목: “쿼리 매개변수”| 매개변수 | 타입 | 기본값 | 설명 |
|---|---|---|---|
offset | integer | 0 | 건너뛸 결과 수. |
limit | integer | 100 | 반환할 최대 결과 수(최대 1,000). |
응답 필드
섹션 제목: “응답 필드”| 필드 | 타입 | 설명 |
|---|---|---|
object | string | 항상 list. |
data | object[] | 페이지 매김된 임베딩 결과 항목. |
model | string | 결과에 사용된 모델. |
dimensions | integer | 출력 차원. |
usage.count | integer | 총 임베딩된 항목 수. |
pagination.offset | integer | 요청된 offset. |
pagination.limit | integer | 요청된 limit. |
pagination.returned | integer | 이 페이지에 반환된 항목 수. |
pagination.total | integer | 총 결과 항목 수. |
pagination.has_more | boolean | 추가 페이지가 있는지 여부. |
요청 예시
섹션 제목: “요청 예시”curl "https://api.schift.io/v1/embed/jobs/job_123/result?offset=0&limit=100" \ -H "Authorization: Bearer $SCHIFT_API_KEY"응답 예시
섹션 제목: “응답 예시”{ "object": "list", "data": [ {"object": "embedding", "index": 0, "embedding": [-0.01225, 0.00207]}, {"object": "embedding", "index": 1, "embedding": [0.00898, -0.00298]}, {"object": "embedding", "index": 2, "embedding": [-0.06297, -0.04777]} ], "model": "schift-embed-1-small", "dimensions": 1024, "usage": {"count": 3}, "pagination": { "offset": 0, "limit": 100, "returned": 3, "total": 3, "has_more": false }}POST /v1/embed/image
섹션 제목: “POST /v1/embed/image”이미지를 임베딩합니다. 먼저 비전-언어 모델(vision-language model)로 텍스트를 추출한 다음, 추출된 텍스트를 임베딩합니다. 요청당 최대 20개의 base64 인코딩(base64-encoded) 이미지를 받습니다.
요청 본문
섹션 제목: “요청 본문”| 매개변수 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
images | string[] | Yes | — | base64 인코딩된 이미지 데이터. |
model | string | No | 조직 라우팅 설정 | 카탈로그의 모델 ID. |
dimensions | integer | No | 모델 기본값 | 출력 차원. |
응답 필드
섹션 제목: “응답 필드”| 필드 | 타입 | 설명 |
|---|---|---|
embeddings | number[][] | 이미지별 임베딩 벡터 목록. |
model | string | 사용된 모델. |
dimensions | integer | 출력 차원. |
usage.image_count | integer | 처리된 이미지 수. |
usage.tokens | integer | 총 소비 토큰 수. |
요청 예시
섹션 제목: “요청 예시”curl https://api.schift.io/v1/embed/image \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -d '{ "images": ["iVBORw0KGgoAAAANSUhEUg..."], "model": "openai/text-embedding-3-large" }'응답 예시
섹션 제목: “응답 예시”{ "embeddings": [[-0.01225, 0.00207, 0.03060]], "model": "openai/text-embedding-3-large", "dimensions": 3072, "usage": {"image_count": 1, "tokens": 14}}POST /v1/embeddings
섹션 제목: “POST /v1/embeddings”정식 임베딩 엔드포인트입니다. 문자열 입력에 대해 OpenAI의 /v1/embeddings와 동일한 input 형식과 호환 응답 형식을 사용합니다. 종료된 /v1/embed를 대체하며, /v1/embed/batch는 하위 호환성을 위해 당분간 제공됩니다.
참고: 입력이 100개를 초과하면 대신
POST /v1/embed/jobs를 사용하세요.
요청 본문
섹션 제목: “요청 본문”| 매개변수 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
input | string | string[] | Yes | — | 임베딩할 텍스트 또는 텍스트 목록. |
model | string | No | 조직 라우팅 설정 | 카탈로그의 모델 ID. |
dimensions | integer | No | 모델 기본값 | 출력 차원. |
task_type | string | No | — | Schift 확장: 임베딩 의도. |
encoding_format | string | No | — | 호환성을 위해 허용되며, 현재 사용되지 않음. |
user | string | No | — | 호환성을 위해 허용되며, 현재 사용되지 않음. |
응답 필드
섹션 제목: “응답 필드”| 필드 | 타입 | 설명 |
|---|---|---|
object | string | 항상 list. |
data | object[] | object, index, embedding을 포함하는 임베딩 객체. |
model | string | 사용된 모델. |
usage.prompt_tokens | integer | 총 소비 토큰 수. |
usage.total_tokens | integer | 총 소비 토큰 수. |
요청 예시
섹션 제목: “요청 예시”curl https://api.schift.io/v1/embeddings \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -d '{ "input": "Schift enables seamless embedding model migration.", "model": "openai/text-embedding-3-large" }'응답 예시
섹션 제목: “응답 예시”{ "object": "list", "data": [ { "object": "embedding", "index": 0, "embedding": [-0.01225, 0.00207, 0.03060] } ], "model": "openai/text-embedding-3-large", "usage": { "prompt_tokens": 8, "total_tokens": 8 }}정규 투영
섹션 제목: “정규 투영”Schift가 반환하는 모든 임베딩은 공유된 정규 잠재 공간(shared canonical latent space)으로 투영(projection)됩니다. 이를 통해 다음이 가능합니다:
- 재임베딩(re-embedding) 없는 모델 전환. 벡터 저장소를 건드리지 않고 OpenAI에서 Voyage로 이동할 수 있습니다.
- 교차 모델 검색(cross-model search). 한 모델의 쿼리 벡터로 다른 모델로 임베딩된 문서를 검색할 수 있습니다.
- 차원 축소(dimension reduction). 소스 모델의 고유 차원과 관계없이 원하는 출력 차원을 요청할 수 있습니다.
투영은 투명하게(transparently) 발생합니다. API를 평소처럼 호출하면 Schift가 나머지를 처리합니다.
라우팅 및 장애 복구
섹션 제목: “라우팅 및 장애 복구”조직에서 기본 임베딩 모델과 선택적 폰백(fallback)을 설정할 수 있습니다. 장애 복구 모드(failover mode)가 활성화되면, 기본 공급자를 사용할 수 없을 때 Schift가 자동으로 폰백 모델로 재시도합니다.
기본값을 설정하려면 라우팅 엔드포인트를 사용하세요:
curl -X PUT https://api.schift.io/v1/routing \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -d '{ "primary": "openai/text-embedding-3-large", "fallback": "voyage/voyage-4-large", "mode": "fallback" }'활성 임베딩 엔드포인트의 성공 응답에는 model 필드가 포함되므로, 어떤 모델이 사용되었는지 확인할 수 있습니다.
속도 제한 및 할당량
섹션 제목: “속도 제한 및 할당량”속도 제한(rate limit)은 조직별로 적용됩니다. 사용량은 실시간으로 추적됩니다. 임베딩 엔드포인트에서 다음 축(axis)을 확인합니다:
| 엔드포인트(endpoint) | 할당량 축(quota axis) |
|---|---|
POST /v1/embed/batch | embed_batch |
POST /v1/embed/image | embed_image |
POST /v1/embed/jobs | embed_batch |
POST /v1/embeddings | embed 또는 embed_batch |
현재 사용량은 다음으로 조회합니다:
curl https://api.schift.io/v1/usage/summary \ -H "Authorization: Bearer $SCHIFT_API_KEY"대량 임베딩 작업(bulk embed job)의 우선순위(priority)는 조직의 요금제에 따라 결정됩니다:
| 요금제 | 우선순위 |
|---|---|
| Enterprise | 0 |
| Business | 1 |
| Pro / Paid / Starter | 2 |
| Free | 3 |
낮은 숫자가 먼저 처리됩니다.
오류 코드
섹션 제목: “오류 코드”일반 오류
섹션 제목: “일반 오류”| 상태(status) | 의미 |
|---|---|
400 | 잘못된 요청(bad request) — 알 수 없는 모델, 잘못된 차원, 빈 입력, 또는 토큰 제한 초과. |
401 | 유효하지 않거나 만료된 API 키. |
402 | 크레딧 부족(insufficient credits) 또는 할당량 초과. |
403 | 요금제에서 사용 불가능한 기능 또는 자격 한도 도달. |
502 | 상위 임베딩 공급자 실패(기본 및 폰백 모두). |
대량 작업 오류
섹션 제목: “대량 작업 오류”| 엔드포인트 | 상태 | 의미 |
|---|---|---|
POST /v1/embed/batch | 400 | 동기 요청에 100개를 초과하는 텍스트. POST /v1/embed/jobs를 사용하세요. |
POST /v1/embed/jobs | 400 | 빈 텍스트, 10,000개를 초과하는 텍스트, 또는 텍스트가 모델의 max_tokens를 초과. |
GET /v1/embed/jobs/\{job_id\} | 404 | 작업을 찾을 수 없거나 다른 조직에 속함. |
POST /v1/embed/jobs/\{job_id\}/cancel | 400 | 작업이 이미 처리 중이거나 완료됨. |
POST /v1/embed/jobs/\{job_id\}/cancel | 409 | 작업이 더 이상 대기 중이 아님. |
GET /v1/embed/jobs/\{job_id\}/result | 404 | 작업 또는 결과를 찾을 수 없음. |
GET /v1/embed/jobs/\{job_id\}/result | 409 | 결과가 아직 준비되지 않음. |