채팅 및 LLM
Schift는 두 가지 채팅 인터페이스를 제공합니다:
POST /v1/chat/completions— 직접 모델 호출을 위한 OpenAI 호환 LLM 프록시.POST /v1/chat— 답변 생성 전 버킷(bucket)에서 컨텍스트를 검색하는 버킷 기반 RAG 채팅.
설정된 공급자(provider) 키를 통해 조직에서 사용 가능한 모델을 목록화하려면 GET /v1/models를 사용하세요.
모든 채팅 경로는 Bearer 토큰으로 전달되는 Schift API 키가 필요합니다.
주의: 응답 생성은 폐쇄 실패(fail-closed) 방식입니다. 조직은
provider_configs에 명시적인 공급자 키가 구성되어 있어야 합니다. Schift는 응답 생성 시 플랫폼 관리 키로 폴퓨(fallback)하지 않으며, 키가 없으면403을 반환합니다.
POST /v1/chat/completions
섹션 제목: “POST /v1/chat/completions”OpenAI 호환 채팅 완성(chat completions) 엔드포인트입니다. Schift는 요청을 설정된 공급자(provider)(OpenAI, Google, Anthropic 등)로 라우팅하고 OpenAI 형식으로 응답을 반환합니다.
요청 본문
섹션 제목: “요청 본문”| 이름 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
model | string | 예 | — | 모델 ID입니다. 예: gpt-4o 또는 claude-3-sonnet. |
messages | object[] | 예 | — | OpenAI 형식의 채팅 메시지입니다. 각 객체는 role과 content를 가집니다. |
temperature | float | 아니오 | — | 샘플링 온도입니다. 일반적으로 0.0에서 2.0 사이입니다. |
max_tokens | integer | 아니오 | — | 생성할 최대 토큰 수입니다. |
top_p | float | 아니오 | — | 핵 샘플링(nucleus sampling) 매개변수입니다. |
stream | boolean | 아니오 | false | Server-Sent Events 스트림을 반환합니다. |
stop | string[] | 아니오 | — | 생성을 중단하는 중지 시퀀스입니다. |
요청 예시
섹션 제목: “요청 예시”curl -X POST ${API_BASE_URL:-https://api.schift.io}/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -d '{ "model": "gpt-4o", "messages": [ {"role": "user", "content": "Explain embedding model migration in one paragraph."} ] }'응답 예시
섹션 제목: “응답 예시”{ "id": "chatcmpl-abc123", "object": "chat.completion", "created": 1710000000, "model": "gpt-4o", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Embedding model migration is the process of moving document representations..." }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 18, "completion_tokens": 42, "total_tokens": 60 }}스트리밍
섹션 제목: “스트리밍”OpenAI 호환 델타(delta) 형식으로 각 이벤트에 완성 조각을 포함하여 Server-Sent Events를 수신하려면 "stream": true로 설정하세요.
curl -X POST ${API_BASE_URL:-https://api.schift.io}/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -d '{ "model": "gpt-4o", "messages": [{"role": "user", "content": "Hello"}], "stream": true }'오류 예시
섹션 제목: “오류 예시”// 402 Payment Required{ "allowed": false, "reason": "quota_exceeded"}// 402 Insufficient credits{ "error": "insufficient_credits", "balance": 0, "estimated_cost": 120, "estimated_cost_usd": 0.0012}// 403 Provider key required{ "detail": { "error": "PROVIDER_KEY_REQUIRED", "provider_access": "missing", "message": "No provider key configured for response generation. If nothing was given, the response would not be made." }}// 403 Plan or credit limit{ "detail": "Upgrade your plan to continue"}// 502 Provider unavailable{ "detail": "LLM provider temporarily unavailable"}// 503 Service not configured{ "detail": "LLM service not configured"}GET /v1/models
섹션 제목: “GET /v1/models”조직의 설정된 공급자 키를 통해 사용 가능한 LLM 모델을 목록화합니다.
요청 예시
섹션 제목: “요청 예시”curl -G ${API_BASE_URL:-https://api.schift.io}/v1/models \ -H "Authorization: Bearer $SCHIFT_API_KEY"응답 예시
섹션 제목: “응답 예시”{ "object": "list", "data": [ { "id": "gpt-4o", "object": "model", "owned_by": "openai" }, { "id": "claude-3-sonnet", "object": "model", "owned_by": "anthropic" } ]}POST /v1/chat
섹션 제목: “POST /v1/chat”버킷(bucket) 기반 RAG 채팅입니다. Schift는 요청된 버킷을 검색하고, 검색 컨텍스트를 조합한 뒤, 결과에 근거한 답변을 생성합니다.
참고: 이 엔드포인트는 호출자가 제어하는 시스템 프롬프트(system prompt)를 허용하지 않습니다. 비어 있지 않은
system_prompt값은400을 반환합니다. 서버는 RAG 지시문을 조합하고 검색된 텍스트를 신뢰할 수 없는 증거로 처리합니다.
요청 본문
섹션 제목: “요청 본문”| 이름 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
bucket_id | string | 예 | — | 컨텍스트를 검색할 버킷(bucket)입니다. |
message | string | 예 | — | 사용자 질문 또는 프롬프트입니다. 비어 있어서는 안 됩니다. |
history | object[] | 아니오 | [] | 이전 대화 턴(turn)입니다. 각 객체는 role과 content를 가집니다. |
model | string | 아니오 | gemini-2.5-flash-lite | 생성에 사용되는 모델입니다. |
top_k | integer | 아니오 | 7 | 포함할 검색 결과 수입니다(1에서 50 사이). |
access_mode | string | 아니오 | auto | 검색 접근 정책입니다: auto, internal, 또는 external. raw는 플랫폼 관리자(platform-admin) 진단용으로 예약되어 있으며 일반 호출자에게는 거부됩니다. |
stream | boolean | 아니오 | true | SSE를 통해 청크(chunk)를 스트리밍합니다. |
system_prompt | string | 아니오 | null | 더 이상 사용되지 않는 호환성 필드입니다. 비어 있지 않은 값은 거부됩니다. |
temperature | float | 아니오 | — | 샘플링 온도입니다. |
max_tokens | integer | 아니오 | — | 최대 출력 토큰 수입니다. |
debug | boolean | 아니오 | false | SSE에 파이프라인 디버그 이벤트를 포함합니다. 플랫폼 관리자(platform-admin) 호출자만 디버그 출력을 받습니다. |
요청 예시
섹션 제목: “요청 예시”curl -X POST ${API_BASE_URL:-https://api.schift.io}/v1/chat \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -d '{ "bucket_id": "bucket_123", "message": "What changed in Q4?", "top_k": 7, "access_mode": "auto", "stream": false }'응답 예시
섹션 제목: “응답 예시”{ "reply": "Q4 revenue increased after the new product launch.", "sources": [ { "id": "doc-42", "score": 0.92, "text": "Quarterly report excerpt ...", "bucket_id": "bucket_123" } ], "model": "gemini-2.5-flash-lite", "search_id": "search_abc123", "degraded": false, "warnings": []}응답 필드
섹션 제목: “응답 필드”| 이름 | 타입 | 설명 |
|---|---|---|
reply | string | 검색된 버킷 컨텍스트에 근거한 생성된 답변입니다. |
sources | object[] | 근거(grounding)에 사용된 검색된 컨텍스트 조각입니다. |
sources[].id | string | 소스 문서 또는 청크(chunk) 식별자입니다. |
sources[].score | number | 소스에 대한 검색 점수입니다. |
sources[].text | string | 소스 텍스트 발췌입니다. |
sources[].bucket_id | string | null | 사용 가능할 때의 버킷 식별자입니다. |
model | string | 생성에 사용된 모델입니다. |
search_id | string | null | 지원, 재생(replay), 또는 피드백용 검색 추적 ID입니다. |
degraded | boolean | 검색 또는 생성이 저하된 경로를 사용했는지 나타냅니다. |
warnings | object[] | 구조화된 검색 또는 품질 경고입니다. 해당 사항이 없을 때는 비어 있습니다. |
stream이 true이면 응답은 SSE 이벤트 스트림입니다. 플랫폼 관리자(platform-admin) 요청에 대해 debug가 허용되면 진단 이벤트에 pipeline_debug가 포함될 수 있습니다. 일반 호출자는 디버그 출력을 사용할 수 없는 것으로 처리해야 합니다.
오류 예시
섹션 제목: “오류 예시”// 400 Rejected system prompt{ "detail": "client-supplied system_prompt is not accepted"}// 403 Provider key required{ "detail": { "error": "PROVIDER_KEY_REQUIRED", "provider_access": "missing", "message": "No provider key configured for response generation. If nothing was given, the response would not be made." }}// 400 Raw access mode rejected{ "detail": "access_mode 'raw' is not allowed for this caller"}// 404 Bucket not found{ "detail": "Bucket 'bucket_123' not found"}과금 및 귀속
섹션 제목: “과금 및 귀속”두 채팅 인터페이스 모두에서 Schift는 토큰 사용량과 LLM 비용 로그를 기록합니다. 성공적인 응답 생성은 provider_source를 유지합니다:
- 조직에서 구성한 공급자 키를 사용할 때
provider_source = "byok"입니다.
채팅 완성은 토큰별로 과금됩니다. 초과 지출을 방지하기 위해 각 요청 전에 사전 비용 추정(preflight cost estimate)이 수행되며, BYOK가 아닌 플랫폼 사용에 대해서는 크레딧이 차감됩니다. RAG 채팅 사용량도 동일한 과금 경로를 통해 기록됩니다.
각 엔드포인트 사용 시기
섹션 제목: “각 엔드포인트 사용 시기”| 목적 | 엔드포인트 |
|---|---|
| 검색 없이 일반적인 OpenAI 호환 LLM 호출 | POST /v1/chat/completions |
| Schift 버킷(bucket)에 근거한 답변 생성 | POST /v1/chat |
| 버킷 컨텍스트와 인용(citation)만 검색 | POST /v2/buckets/\{bucket_id\}/search |