쿼리(Query) 및 검색(Search)
Query & Search API를 사용하면 버킷(bucket)에 자연어(natural-language) 질문을 던지고, 출처 인용(citation)이 포함된 답변용 컨텍스트(context)를 받을 수 있습니다. Schift는 임베딩(embedding), 하이브리드 검색(hybrid retrieval), 메타데이터 필터링(metadata filtering), 재정렬(reranking), 컨텍스트 패킹(context packing), 인용 형식화(citation formatting)까지 전체 검색(retrieval) 파이프라인을 관리합니다.
이 엔드포인트(endpoint)는 사용자 대면 검색, 에이전트 컨텍스트(context) 조립, 버킷(bucket) 콘텐츠에서 인용이 포함된 답변이 필요한 모든 통합(integration)에 사용하세요.
API 버전(Versions)
섹션 제목: “API 버전(Versions)”| 버전 | 상태 | 설명 |
|---|---|---|
v2 | 현재(Current) | context와 citations를 포함하는 사용자 중심 검색입니다. 모든 신규 통합(integration)에 사용하세요. |
v1 | 폐기 예정(Deprecated) | POST /v1/query, POST /v1/collections/\{name\}/search, POST /v1/buckets/\{bucket_id\}/search. 기존 클라이언트만을 위해 유지됩니다. |
참고: v1 검색 엔드포인트는
Deprecation,Sunset,Warning헤더와 v2 후속 엔드포인트를 가리키는Link헤더를 반환합니다.
POST /v2/buckets/{bucket_id}/search
섹션 제목: “POST /v2/buckets/{bucket_id}/search”버킷(bucket)에 질문을 던지고 인용(citation)이 포함된 답변용 컨텍스트(context)를 반환합니다.
경로 매개변수(Path parameters)
섹션 제목: “경로 매개변수(Path parameters)”| 이름 | 타입 | 설명 |
|---|---|---|
bucket_id | string | 검색할 버킷(bucket)의 UUID 또는 슬러그(slug). |
요청 본문(Request body)
섹션 제목: “요청 본문(Request body)”| 필드 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
query | string | 예 | — | 자연어(natural-language) 질문. 최대 8,192자. |
top_k | integer | 아니오 | 8 | 반환할 인용 문단(passage)의 최대 개수. |
context_budget | integer | 아니오 | 2000 | 토큰 단위의 대략적인 최대 컨텍스트(context) 크기. |
filters | object | 아니오 | null | 후보 청크(candidate chunks)에 적용할 메타데이터 필터(metadata filters). |
options.rerank.enabled | boolean | 아니오 | true | 컨텍스트(context) 조립 전 후보 문단(passage)의 순서를 다시 매깁니다. |
options.rerank.top_k | integer | 아니오 | null | 재정렬(rerank)할 후보 문단(passage)의 개수. |
options.instructions.task | string | 아니오 | null | 검색 지침 프리셋: retrieval_query, retrieval_document, semantic_similarity, question_answering, clustering, classification, code_retrieval. |
요청 예시
섹션 제목: “요청 예시”curl -X POST ${API_BASE_URL:-https://api.schift.io}/v2/buckets/product-docs/search \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "What changed in the enterprise plan?", "top_k": 8, "context_budget": 4000, "filters": {"status": "published"}, "options": { "rerank": {"enabled": true, "top_k": 20}, "instructions": {"task": "retrieval_query"} } }'응답(Response)
섹션 제목: “응답(Response)”| 필드 | 타입 | 설명 |
|---|---|---|
status | string | 버킷(bucket)이 컨텍스트(context)를 반환했다면 ready, 그렇지 않으면 empty. |
operational_status | string | ready, empty, indexing, degraded 중 하나. |
bucket_id | string | 검색된 버킷(bucket). |
query | string | 검색된 질문. |
context | string | 버킷(bucket) 콘텐츠에서 조립한 [1]과 같은 번호 인용이 포함된 답변용 컨텍스트(context). |
citations | array | 반환된 컨텍스트(context)의 출처 참조. |
citations[].index | integer | context에서 사용된 인용(citation) 번호. |
citations[].document_id | string | 해당 문단(passage)을 뒷받침하는 문서(document). |
citations[].source_id | string | 사용 가능한 경우 업로드된 소스(source) 또는 파일 ID. |
citations[].title | string | 사람이 읽을 수 있는 소스(source) 제목. |
citations[].source_url | string | 사용 가능한 경우 소스 URL. |
citations[].page | integer | string | 소스(source) 내 페이지 또는 위치. |
citations[].section | string | 사용 가능한 경우 섹션 제목. |
warnings | array | 준비 상태, 검색(retrieval), 품질 관련 경고. |
warnings[].code | string | 안정적인 기계 판독 가능 경고 코드. |
warnings[].message | string | 사람이 읽을 수 있는 경고 메시지. |
warnings[].severity | string | warning 또는 error. |
인덱스 상태 참조
섹션 제목: “인덱스 상태 참조”operational_status 는 질의가 아니라 버킷의 상태입니다.
| 값 | 의미 | 대응 |
|---|---|---|
ready | 인덱스가 원본과 일치합니다. | 없음. |
empty | 아직 검색 가능한 내용이 없습니다. | 문서를 올리거나 첫 색인이 끝나기를 기다립니다. |
indexing | 색인이 진행 중이라 커버리지가 아직 늘고 있습니다. | 나중에 재시도합니다. 지금 결과도 유효하지만 불완전합니다. |
degraded | 인덱스와 원본이 어긋났습니다. 어느 방향인지는 warnings 를 봅니다. | warnings[].details 의 repair 값을 따릅니다. |
warnings[].code 는 안정적인 값이고 전체 목록은 다음과 같습니다.
| 코드 | 의미 | details.repair |
|---|---|---|
INDEX_DRIFT_DETECTED | 벡터가 원본 청크보다 적습니다. 일부 내용이 검색되지 않습니다. 유실은 아닙니다. | chunk_backfill_required |
INDEX_SUPERSEDED_VECTORS | 현재 세대와 함께 옛 세대 청크가 색인돼 있습니다. 없어진 내용은 없고, 중복이 랭킹을 두고 경쟁합니다. 재업로드로는 사라지지 않습니다 — 세대가 하나 더 쌓입니다. | generation_sweep_required |
INDEX_ORPHAN_VECTORS | 원본 행이 없어진 벡터가 남아 있습니다. 사라진 내용이 검색될 수 있습니다. | orphan_sweep_required |
warnings[].details 에는 코드의 근거가 되는 실측값이 들어갑니다 —
sql_chunks(현재 논리 청크), sql_chunk_rows(옛 세대를 포함한 저장된 청크 행 전체),
engine_vectors(살아 있는 색인 벡터), 그리고 코드가 지목하는 개수입니다.
sql_chunk_rows − sql_chunks 가 옛 세대 수, engine_vectors − sql_chunk_rows 가
고아 수입니다. engine_vectors 를 sql_chunks 와 직접 빼면 문제가 과장됩니다 —
둘은 단위가 다릅니다.
두 sweep 모두 운영자 작업입니다. 재업로드로는 어느 쪽도 해소되지 않으니, 버킷 ID 를 지원팀에 알려 주십시오.
응답 예시
섹션 제목: “응답 예시”{ "status": "ready", "operational_status": "ready", "bucket_id": "product-docs", "query": "What changed in the enterprise plan?", "context": "[1] Enterprise seats now include advanced audit logging. [2] The monthly seat limit was removed for annual contracts.", "citations": [ { "index": 1, "document_id": "doc_042", "source_id": "upload_123", "title": "Pricing Notes", "source_url": null, "page": 4, "section": "Enterprise", "score": 0.91 }, { "index": 2, "document_id": "doc_055", "source_id": "upload_124", "title": "Contract Terms", "source_url": null, "page": 2, "section": null, "score": 0.87 } ], "warnings": []}오류 예시
섹션 제목: “오류 예시”// 400 Bad Request — invalid filter{ "detail": "Invalid filter: unsupported operator"}// 400 Bad Request — unsupported knowledge-search filter key{ "error": "unsupported_knowledge_search_filter", "message": "Knowledge search filters must use validated user metadata or documented system filter keys.", "invalid_keys": ["internal_tag"]}// 402 Payment Required{ "allowed": false, "reason": "quota_exceeded"}// 403 Forbidden{ "detail": "Search quota unavailable. Upgrade your plan."}// 404 Not Found{ "detail": "Bucket 'product-docs' not found"}GET /v2/buckets/{bucket_id}/search/status
섹션 제목: “GET /v2/buckets/{bucket_id}/search/status”사용자 트래픽을 본격적으로 보내기 전에 버킷(bucket)에 검색 가능한 콘텐츠가 있는지 확인합니다.
경로 매개변수(Path parameters)
섹션 제목: “경로 매개변수(Path parameters)”| 이름 | 타입 | 설명 |
|---|---|---|
bucket_id | string | 확인할 버킷(bucket)의 UUID 또는 슬러그(slug). |
요청 예시
섹션 제목: “요청 예시”curl ${API_BASE_URL:-https://api.schift.io}/v2/buckets/product-docs/search/status \ -H "Authorization: Bearer $SCHIFT_API_KEY"응답(Response)
섹션 제목: “응답(Response)”| 필드 | 타입 | 설명 |
|---|---|---|
status | string | 버킷(bucket)에 검색 가능한 콘텐츠가 있으면 ready, 그렇지 않으면 empty. |
operational_status | string | ready, empty, indexing, degraded 중 하나. |
bucket_id | string | 확인된 버킷(bucket). |
indexed_count | integer | null | 검색 가능한 콘텐츠 항목의 개수. |
document_count | integer | null | 이 버킷(bucket)의 문서(document) 개수. |
pending_job_count | integer | null | 아직 준비 중인 문서(document) 개수. |
failed_job_count | integer | null | 관리가 필요한 문서(document) 개수. |
last_indexed_at | string | null | 콘텐츠가 마지막으로 검색 가능해진 시각. |
backfill_required | boolean | 기존 문서(document)의 준비가 필요한지 여부. |
응답 예시
섹션 제목: “응답 예시”{ "status": "ready", "operational_status": "ready", "bucket_id": "product-docs", "indexed_count": 1240, "document_count": 42, "pending_job_count": 0, "failed_job_count": 0, "last_indexed_at": "2026-06-18T09:12:34Z", "backfill_required": false}레거시 v1 엔드포인트
섹션 제목: “레거시 v1 엔드포인트”다음 엔드포인트는 폐기 예정(deprecated)이며 신규 통합(integration)에서 사용하지 마세요:
POST /v1/queryPOST /v1/collections/\{name\}/searchPOST /v1/buckets/\{bucket_id\}/search
이 경로는 더 낮은 수준의 검색(retrieval) 메커니즘을 노출합니다. v2는 지식 검색(knowledge-search) 제품 API 뒤에 해당 복잡성을 의도적으로 숨깁니다.