RAG Lab
PageIndex와 Schift를 같은 문서로 돌려보며 배운 것
PageIndex OSS와 Schift full path를 같은 질의, 같은 top_k 기준으로 비교했다. 품질, 검색 시간, 추정 비용을 함께 보니 문서 구조 검색을 어디에 넣어야 하는지 분명해졌다.
긴 문서를 검색할 때, 단순히 chunk embedding만 보는 방식은 자주 부족합니다.
문서는 순서가 있고, 페이지가 있고, 섹션이 있고, 앞뒤 문맥이 있습니다. 그래서 PageIndex가 말하는 문제의식은 꽤 타당합니다. 긴 문서를 flat chunks로만 보지 말고, 문서 구조를 따라가며 필요한 페이지 범위를 열어야 한다는 이야기입니다.
우리도 비슷한 방향을 보고 있었습니다. Schift는 결국 vector search만 하는 엔진이 아니라, graph와 문서 구조까지 이어지는 retrieval layer가 되어야 하기 때문입니다.
그래서 이번에는 PageIndex OSS를 직접 돌려보고, 같은 fixture에서 Schift full path와 비교했습니다. 기준은 단순하게 잡았습니다.
- PageIndex OSS
- Schift full path
- 같은 문서
- 같은 질의
top_k=5- 품질뿐 아니라 검색 시간과 추정 비용까지 비교
이 글은 “Schift가 PageIndex보다 전부 낫다”는 이야기가 아닙니다.
오히려 반대에 가깝습니다. PageIndex가 잘 잡은 문제의식은 맞습니다. 긴 문서는 구조가 있고, 검색은 그 구조를 봐야 합니다.
다만 제품으로 반복 질의를 처리하려면 구조 신호를 어디에 넣을지가 중요합니다. query마다 긴 문서 tree를 LLM prompt로 다시 태우는 방식과, ingest/index 단계에서 구조 신호를 싸게 재사용하는 방식은 비용 구조가 완전히 다릅니다.
결론
PageIndex OSS는 법률 fixture에서 정확도는 이겼습니다. 하지만 query마다 문서 tree 구조를 LLM prompt로 넣어 검색하기 때문에 검색 시간이 길고, 반복 질의 비용도 커집니다.
Schift full path는 법률 fixture에서는 정확도에서 졌지만, 검색 시간은 훨씬 짧고 query-time 비용도 작았습니다. 강의자료와 회계 리포트 fixture에서는 Schift가 더 안정적이었습니다.
| Suite | Method | Quality | Avg search time | Est. query cost | Est. index cost |
|---|---|---|---|---|---|
legal | PageIndex OSS | doc_hit@5 1.0000 | 5.96s/query | $0.0023-$0.0029/query | $0.01-$0.03/corpus |
legal | Schift full path | doc_hit@5 0.8333 | 0.64s/query | $0.00005-$0.0003/query | $0.001-$0.005/corpus |
lecture-econ | PageIndex OSS | run failed | n/a | likely higher than legal | likely higher than legal |
lecture-econ | Schift full path | evidence@5 0.9167 | 1.49s/query | $0.00005-$0.0005/query | $0.003-$0.015/corpus |
accounting | PageIndex OSS | n/a | n/a | n/a | n/a |
accounting | Schift full path | evidence@5 0.8000 | 1.13s/query | $0.00005-$0.0005/query | $0.006-$0.030/corpus |
숫자로만 보면 한 줄입니다.
PageIndex OSS는 legal 품질은 이겼지만, Schift full path는 legal에서 9.3배 빨랐고 query-time 비용도 훨씬 낮았습니다.
이 차이는 단순한 최적화 차이가 아니라 제품 설계 차이입니다. 검색이 한두 번 끝나는 실험이면 LLM tree navigation도 괜찮습니다. 하지만 업무 제품에서는 같은 문서 집합에 대해 수십, 수백 번 질의합니다. 그때는 query마다 구조 전체를 다시 읽는 방식보다, 구조 신호를 index와 retrieval policy 안에 넣는 편이 더 지속 가능합니다.
어떻게 비교했나
Schift 쪽은 live API를 탔습니다.
문서를 collection에 넣고, schift-embed-1로 임베딩하고, engine search와 hybrid/rerank path를 거쳤습니다. 즉 단순 local script가 아니라 Schift가 실제로 제공하는 검색 경로에 가까운 full path입니다.
PageIndex 쪽은 OSS repo를 clone해서 self-hosted runner로 돌렸습니다. 문서를 PageIndex workspace에 index하고, query마다 tree structure를 LLM에 넣어 관련 page range를 선택하게 했습니다.
비교는 완벽하지 않습니다. PageIndex OSS는 legal에서는 정상 실행됐지만, lecture-econ PDF에서는 목차와 page offset 처리 중 인덱서가 실패했습니다. accounting fixture는 원본 PDF가 없고 기존 chunk metadata만 있어서 PageIndex OSS 입력 조건과 맞지 않았습니다.
그래서 public-facing 비교에서 proxy 결과는 PageIndex라고 부르지 않았습니다. 표에는 PageIndex OSS가 실제로 돈 구간만 PageIndex OSS로 표시했습니다.
이 제한은 중요합니다. 이 글은 PageIndex 전체 제품군이나 모든 page-aware retrieval 방법에 대한 판정이 아닙니다. 우리가 직접 실행한 OSS path와 Schift full path를, 우리가 가진 fixture에서 비교한 기록입니다.
비용은 어떻게 추정했나
PageIndex runner는 OpenAI usage를 결과 파일에 저장하지 않습니다. Schift bakeoff도 내부 billing counter를 결과에 쓰지 않습니다. 그래서 비용은 청구서가 아니라 추정치입니다.
가정은 이렇게 뒀습니다.
- PageIndex OSS runner는
gpt-4o-mini로 index/retrieval을 수행했습니다. gpt-4o-mini가격은 input$0.15 / 1M tokens, output$0.60 / 1M tokens기준으로 계산했습니다.- PageIndex legal retrieval prompt는 query당 약 52.7k characters였습니다.
- 이를 대략 13k-17.6k input tokens/query로 잡았습니다.
- output은 page range JSON이라 상대적으로 작게 잡았습니다.
- Schift 비용은 query embedding, engine search, rerank, ingest embedding의 내부 COGS 범위로 추정했습니다.
이 추정에서 중요한 것은 소수점 네 자리 자체가 아닙니다. 비용 구조입니다.
PageIndex는 query마다 문서 구조를 LLM에게 다시 보여줍니다. 문서가 길어지고, 문서 수가 늘고, query가 반복될수록 prompt 비용이 계속 붙습니다.
Schift는 ingest 때 embedding과 index build 비용을 먼저 냅니다. query-time에는 query embedding, engine search, rerank만 수행합니다. 반복 검색이 많은 제품에서는 이 차이가 큽니다.
PageIndex-style context를 Schift에 붙이면?
당연히 해봤습니다.
Schift 검색 결과에 PageIndex식 이웃 chunk 확장을 붙여서 rerank 전에 candidate로 섞었습니다. 결과는 좋지 않았습니다.
| Suite | Method | Quality | Avg search time | Est. query cost |
|---|---|---|---|---|
lecture-econ | Schift + PageIndex-style context | evidence@5 0.8333 | 1.41s/query | $0.00006-$0.0006/query |
accounting | Schift + PageIndex-style context | evidence@5 0.8000 | 2.12s/query | $0.00008-$0.0008/query |
lecture-econ에서는 품질이 떨어졌고, accounting에서는 품질이 같았지만 더 느려졌습니다.
이유는 단순합니다. 이웃 chunk를 top-k candidate로 섞으면, 이미 강한 seed 주변의 chunk들이 reranker 입력을 오염시킬 수 있습니다. 필요한 것은 “후보를 더 많이 넣는 것”이 아니라 “선택된 hit의 주변 맥락을 답변용 context로 붙이는 것”에 가깝습니다.
그래서 결론은 PageIndex-style을 버리자는 것이 아닙니다. 붙이는 위치가 다릅니다.
- 나쁜 방식: pre-rerank candidate expansion
- 좋은 방향: post-retrieval attached context
먼저 Schift가 seed hit를 고르고, 그 뒤에 해당 hit의 앞뒤 page/chunk/section을 attached context로 붙이는 구조가 맞습니다. Graph로 이어지는 retrieval도 이 방향입니다.
우리가 가져갈 것
PageIndex의 핵심 장점은 “chunk를 더 길게 잡자”가 아닙니다.
문서 구조를 검색 과정에 명시적으로 넣는 것입니다. 특히 법률 문서처럼 page range, section, 사건 구조가 중요한 데이터에서는 이 장점이 분명합니다.
다만 제품 경로에서는 query마다 LLM tree retrieval을 그대로 태우기 어렵습니다. 비용과 latency가 너무 빠르게 커집니다.
Schift 쪽에서 가져갈 방향은 이렇습니다.
- 기본 검색은 Schift full path로 유지합니다.
- 구조가 강한 문서에서는 section/page/graph signal을 ranking feature로 추가합니다.
- 이웃 chunk는 candidate로 경쟁시키지 않고, 선택된 hit에 attached context로 붙입니다.
- 품질 개선이 확인되는 corpus에서만 opt-in mode로 제공합니다.
이번 실험의 결론은 꽤 실용적입니다.
PageIndex OSS는 legal quality benchmark에서 이겼습니다. 하지만 Schift full path는 훨씬 빠르고 싸며, lecture/accounting workload에서는 더 안정적이었습니다. PageIndex식 구조 검색은 도입할 가치가 있지만, 그대로 query-time LLM tree navigation을 복사하는 방식은 아닙니다.
우리가 원하는 방향은 PageIndex를 베끼는 것이 아니라, Schift engine의 graph/vector/keyword path 안에 구조 신호를 싸고 빠르게 녹이는 것입니다.
RAG 제품에서 중요한 것은 “검색 아이디어가 멋진가”만이 아닙니다.
같은 문서에 대해 반복 질의할 때 빠르게 유지되는가, 비용이 예측 가능한가, 실패한 PDF나 불완전한 metadata에서도 graceful하게 동작하는가가 더 중요합니다.
Schift는 그 방향으로 가고 있습니다.
RAG Lab 구독
schift 만들면서 직접 굴린 RAG 실험 일지. 매주 새 실험이 올라옵니다.