Photon: 처음부터 구축하는 검색 및 랭킹 엔진
전용 데이터 형식, 배치 읽기, 인덱스 구축과 쿼리 서빙의 분리가 AI 네이티브 검색을 개선하는 방법.
소개
Perplexity의 AI 네이티브 검색 스택은 후보 페이지를 검색하고 랭킹을 매겨, 모델이 답변의 근거를 마련할 수 있도록 가장 관련성 높은 콘텐츠를 표출합니다. 원래 이 단계는 당사 시스템에 맞게 수정한 오픈 소스 엔진에서 실행되었습니다. 그러나 인덱스와 워크로드가 증가함에 따라 기존 서드파티 플랫폼 내에서 해결할 수 없는 비용, 테일 레이턴시, 노드 복구 시간의 한계에 부딪혔습니다.
이러한 과제를 극복하기 위해 당사는 새로운 자체 검색 및 랭킹 엔진인 Photon을 구축했습니다. 이는 페이지 레코드를 서빙하기 위한 분산 키-값 저장소인 CobbleDB 및 Search API에서 그랬던 것처럼 AI 우선 검색 인프라를 처음부터 구축하는 당사의 접근 방식을 이어갑니다.
Photon은 컴팩트한 데이터 형식을 사용하여 각 쿼리에 필요한 부분만 읽고 디코딩하며, 배치 인식 캐싱과 비동기 읽기를 통해 디스크 액세스를 줄이고 대기 시간을 겹쳐서 처리합니다. 인덱스 구축은 쿼리 서빙과 별개로 실행되며, 한 번에 하나의 서빙 그룹을 업데이트하고 라이브 쿼리를 라우팅하기 전에 캐시를 워밍업합니다.
Photon은 이제 검색 파이프라인을 구동하며, Search API용 새 빠른 프리셋의 기반이기도 합니다. 이 프리셋은 p50에서 160ms, p95에서 230ms의 단일 검색 호출 레이턴시를 제공합니다. 6개의 공개 벤치마크 전반에서, 빠른 프리셋은 기본 프리셋과 비교 가능한 종합 태스크 품질을 유지하면서 태스크당 예상 모델 및 검색 비용을 68% 절감했습니다. 개발자들이 이러한 개선 사항을 활용할 수 있도록 오늘 이 프리셋을 출시합니다.
검색 및 랭킹 엔진의 요구사항
각 쿼리에 대해 검색 및 랭킹 엔진은 크고 분산된 인덱스를 검색하여 검색 스택의 레이턴시 예산 내에서 관련 페이지의 소규모 세트를 선택하고 정렬합니다. 또한 시스템은 작업이 라이브 쿼리를 느리게 만들지 않도록 하면서, 새 페이지가 도착하고 기존 페이지가 변경됨에 따라 인덱스를 최신 상태로 유지해야 합니다.
당사는 여러 오픈 소스 옵션을 평가하여 초기 니즈를 충족하는 성숙하고 범용적인 검색 및 랭킹 엔진을 선택했습니다. 그 후 이를 당사 아키텍처와 워크로드에 맞춰 조정하여 프로덕션 규모에서 안정적인 레이턴시와 처리량을 유지했습니다.
이전 시스템이 미흡했던 부분
우리는 증가하는 인덱스에 엔진을 맞추기 위해 자체 포크를 유지 관리했으나, 주요 한계들을 해결하려면 플랫폼의 많은 부분을 재설계해야 하는 경우가 점차 늘어났습니다. 근본적인 아키텍처 변경 없이는 해결하기 어려운 몇 가지 제약 사항이 있었습니다.
1. 스케일링 비용. 우리가 저장하는 문서의 수와 검색하고 랭킹을 매겨야 하는 문서별 데이터의 양은 시간이 지남에 따라 증가해 왔습니다. 이러한 스케일링은 하드웨어, 특히 사용 가능한 RAM 양에 압박을 주었습니다. 비용을 통제하기 위해 더 컴팩트한 데이터 표현과, 메모리에 유지할 것과 요청 시 디스크에서 읽을 것을 세밀하게 제어할 수 있는 방법이 필요했습니다.
2. 저조한 테일 레이턴시. 프로덕션 트래픽에서 구 시스템의 p99 응답 시간은 약 800ms였습니다. 데이터셋이 사용 가능한 RAM을 초과하여 mlock을 사용해 메모리에 완전히 유지할 수 없었습니다. 비상주 데이터에 액세스하면 주요 페이지 폴트가 발생할 수 있으며, 운영 체제가 디스크에서 읽는 동안 쿼리 실행이 중단되었습니다.
또한 엔진은 메인 디스크 인덱스를 메모리에서 플러시된 더 작은 인덱스와 주기적으로 병합했습니다. 이 디스크 인덱스 융합 과정에서 페이지 폴트 수는 훨씬 더 높아져 10~15분 동안 p99 레이턴시가 약 1.2초에 달했습니다. 캐시가 워밍업됨에 따라 페이지 폴트 빈도와 레이턴시가 모두 감소했으며, 이는 콜드 읽기가 스파이크의 주요 원인임을 시사했습니다. 데이터를 미리 로드하고 인덱스를 워밍업하는 것은 스파이크를 줄였지만 높은 테일 레이턴시를 적절히 해결하지는 못했습니다.
3. 긴 복구 및 동기화. 이전 시스템에서는 추가 클러스터를 배포하고 데이터를 동기화하는 데 일주일 이상이 걸릴 수 있었습니다. 추가 데이터 복사본을 보관할 노드 그룹을 추가하거나 노드 장애에서 복구할 때도 동기화가 필요했습니다. 복구 중에는 부분적인 검색 응답의 비율이 높아져 최종 답변 품질 점수가 낮아졌습니다.
궁극적으로 우리는 포크를 계속 수정하고 유지 관리하는 것보다 처음부터 새로 구축하는 것이 더 간단하고 비용 효율적이라는 결론을 내렸습니다. 이전 시스템을 운영한 경험을 바탕으로, 소규모 엔지니어링 팀이 지속적인 코딩 에이전트 무리와 협력하여 Photon을 구축했습니다.
검색 스택에서 Photon의 위치
Photon은 두 가지 주요 워크플로우, 즉 검색 요청 서빙과 처리 파이프라인으로부터의 업데이트 수정을 위해 설계되었습니다.
상위 레벨 검색 서비스의 요청은 로드 밸런서를 통해 Photon 브로커에 도달합니다. 브로커는 샤드 그룹을 선택하고 각 샤드로 요청을 전달하며, 타임아웃을 모니터링하고 필요할 때 추가 요청을 발행합니다.
각 샤드는 검색, 초기 랭킹, 2단계 랭킹을 수행한 다음 최상의 후보를 브로커에 반환합니다. 브로커는 이러한 후보를 단일 랭킹 리스트로 결합하고 관련 샤드에서 선택된 페이지에 대한 주요 문서 필드를 가져옵니다. 그런 다음 이 결과를 상위 레벨 검색 서비스에 반환하고, 서비스는 에이전트가 근거 있는 답변을 생성하는 데 필요한 페이지 콘텐츠를 수집합니다.
인덱스 업데이트는 별도의 경로를 따릅니다. 퍼블리싱 레이어인 Pillar가 데이터를 준비하여 YTsaurus 테이블에 저장합니다. 인덱서는 이러한 테이블을 샤드가 검색에 로드할 수 있는 인덱스 구조로 변환합니다. 컨트롤러는 데이터 준비, 인덱스 구축, 그리고 새로운 인덱스 버전의 서빙 그룹 배포를 조정합니다. 라이브 트래픽을 처리하기 전에 각 샤드는 실제 검색 쿼리를 재생하여 캐시를 워밍업합니다.
워크플로우에 맞춘 Photon 설계
세 가지 설계 선택 덕분에 Photon은 당사의 워크로드에 매우 적합합니다. 즉, 컴팩트한 데이터 표현, 캐싱 및 비동기 디스크 읽기, 그리고 인덱스 업데이트와 쿼리 서빙의 분리입니다.
검색 및 랭킹을 위한 데이터 표현
검색과 랭킹은 문서 데이터에 다르게 액세스합니다. 렉시컬 검색은 쿼리 텀으로 시작하여 이를 포함하는 문서를 찾습니다. 그 후 랭킹에는 텀 빈도와 위치를 포함하여 선택된 각 문서에 대한 상세한 정보가 필요합니다.
Photon은 이러한 액세스 패턴을 지원하기 위해 상호 보완적인 두 가지 표현을 사용합니다. 역인덱스는 후보 선택을 지원하기 위해 포스팅 리스트라고 불리는 각 텀에 대한 일치 문서 리스트를 저장합니다. 별도의 문서별 레코드는 랭킹에 필요한 데이터를 제공합니다. 또한 고정된 작업 예산 내에서 선택을 개선하기 위해 포스팅 리스트의 저장 및 순회 방식도 최적화합니다.
전용 데이터 표현을 통해 핵심 데이터를 보다 효율적으로 저장할 수 있습니다. 더 컴팩트한 역인덱스는 쿼리당 읽거나 이동하는 데이터의 양을 줄여 불필요한 I/O 작업을 없애고 레이턴시를 개선합니다. 또한 이러한 형식을 사용하면 리스트를 완전히 디코딩하지 않고도 문서가 리스트에 나타나는지 확인할 수 있으며, 이는 당사의 순회 로직이 고정된 예산 하에서 쿼리가 수행하는 작업량을 제어하는 데 의존하는 속성입니다. 문서별 레코드를 최적화하면 랭킹을 위해 문서당 더 많은 데이터를 저장할 수동시에, 이전 시스템과 관련된 스케일링 비용을 줄일 수 있습니다.
역인덱스
각 텀에 대해 역인덱스는 포스팅 리스트를 저장합니다. 이 리스트는 소수의 문서에서 수백만 개에 이르기까지 다양하므로 모든 리스트에 잘 맞는 단일 형식은 없습니다. Photon은 텀을 포함하는 문서의 수를 기준으로 형식을 선택합니다.
짧은 리스트는 단일 페이지 내에 들어가며 블록 테이블이 필요 없는 인라인 표현을 사용합니다. 인라인 형식에 맞지 않는 긴 리스트는 고정된 범위의 문서 식별자를 다루는 블록으로 나뉩니다. 각 블록의 표현은 밀도에 따라 달라지며, 희소 블록은 문서 ID 오프셋의 정렬된 배열을 저장하고, 밀집 블록은 비트맵을 사용합니다. 희소 블록은 갤러핑 검색을 사용하여 리스트의 영역을 건너뛰기 위해 점점 더 큰 단계로 전진합니다. 밀집 블록은 문서에 해당하는 비트를 조회하여 멤버십을 확인할 수 있게 합니다.
텀의 쿼리 빈도는 디스크에서 포스팅 리스트가 배치되는 위치를 결정합니다. 자주 쿼리되는 리스트는 서로 가깝게 저장되어 핫 데이터를 더 작은 스토리지 영역에 집중시킵니다. 각 리스트 내에서 문서는 별도의 유용성 신호에 따라 정렬되므로 더 유망한 후보가 더 일찍 발견됩니다.
작업 예산 내에서 리스트 순회하기
후보 선택에는 잠재적으로 관련 있는 문서를 찾기 위해 포스팅 리스트를 순회하는 작업이 필요합니다. 모든 리스트를 빠짐없이 스캔하는 것은 비용이 많이 들므로, Photon은 다른 리스트의 일치 항목을 여전히 고려하면서 일부 리스트만 순회하는 WAND 유사 알고리즘을 사용합니다.
알고리즘은 리스트를 두 그룹으로 나눕니다. 드라이빙 리스트는 순회를 진행하고 후보 문서를 제안합니다. 프로브 리스트는 해당 후보의 점수에 기여하지만 후보 자체를 생성하지는 않습니다.
후보 점수 산정은 가중치가 부여된 쿼리 텀 커버리지와 빈도 기여도를 결합하며, 문서 길이 정규화 및 반복된 텀으로부터 얻는 이득에 대한 상한을 적용합니다. Photon은 먼저 배열과 비트맵에서 텀의 존재 여부를 확인하여 각 후보의 최대 가능한 점수 범위를 제한합니다. 선택 임계값을 충족할 수 있는 후보에 대해서만 정확한 텀 빈도를 읽습니다.
그런 다음 선택은 다음 세 단계로 진행됩니다.
- 순회 (Traversal): 엄격한 쿼리 커버리지 요구사항으로 시작합니다. 후보가 너무 적게 발견되면 완화된 요구사항으로 반복합니다.
- 유지 (Retention): 후보는 커버리지와 빈도를 결합한 점수를 사용하여 바운디드 세트 내에 유지됩니다. 수집된 상위 후보가 개선됨에 따라 승인 임계값이 상승합니다.
- 최종 선택: 이번 패스의 최종 결과는 빈도 점수를 바탕으로 유지된 세트 중에서 선택됩니다. 각 필드는 자체 패스를 실행하며, 결과는 필드 가중치를 사용하여 병합됩니다.
알고리즘은 추가적인 랭킹에 사용될 관련 문서의 후보 셋을 생성합니다.
Docblob
후보 페이지가 선택된 후 랭킹 단계에서는 텀 빈도, 필드 커버리지, 발생 위치 및 근접성이 필요합니다. 역인덱스를 통해 이 데이터를 얻으려면 여러 텀-document 쌍에 걸쳐 분산된 액세스가 필요합니다. Photon에서는 텀 빈도, 텀이 나타난 필드, 문서 내 발생 위치를 포함하는 docblob이라는 컴팩트한 문서별 레코드를 저장합니다. 결과적으로 후보 랭킹에는 문서당 단 한 번의 조회만 필요합니다.
이 형식은 필요한 것 이상으로 디코딩하는 것을 피하도록 구축되었습니다. docblob 내에서 필드는 텍스트 분석기별로 그룹화됩니다. 각 그룹은 Elias-Fano로 인코딩된 정렬된 텀 리스트를 저장하므로, 전체 리스트를 먼저 확장하지 않고도 쿼리 텀을 직접 조회할 수 있습니다. 필드 마스크는 텀이 발생한 위치를 표시하고, 빈도 카운트는 발생 빈도를 추적하며, 실제 위치는 위치 차분으로 인코딩된 텀-필드 쌍별 별도의 블록에 존재합니다. 실제로 일치한 텀의 블록만 디코딩되고 레코드의 나머지 모든 부분은 압축된 형식으로 유지됩니다.
이러한 선택적 디코딩을 통해 docblob은 비례적인 비용 증가 없이 문서당 더 많은 데이터를 저장할 수 있습니다. 랭킹은 전체 레코드가 아닌 일치하는 텀과 관련된 부분만 다루기 때문에, 레코드가 커져도 조회당 더 많은 작업이 강제되지 않습니다.
배치 읽기 및 메모리 작업
더 효율적인 데이터 표현을 사용하더라도 다른 리소스보다 RAM이 먼저 고갈되기 때문에 디스크에 저장된 데이터에 자주 액세스해야 합니다. Photon은 비동기 디스크 읽기와 배치 읽기에 최적화된 캐시를 사용하여 이러한 액세스 속도를 높이고 요청당 대기 시간을 줄입니다. 이는 이전 시스템에 비해 테일 레이턴시의 상당한 개선에 기여합니다.
디스크 대기 시간 겹침
랭킹을 위해서는 파일의 다른 부분에 위치한 백 개 문서의 피처를 가져와야 합니다. 이전 시스템은 메모리 포인터를 통해 읽을 수 있도록 파일을 가상 주소 공간으로 매핑하기 위해 mmap을 사용했습니다. 그러나 메모리에 없는 페이지에 액세스하려면 여전히 디스크 읽기가 필요했습니다. 스레드는 계산을 계속하기 전에 데이터가 준비될 때까지 기다려야 했으며, 프로세스가 콜드 레코드를 순차적으로 읽어야 할 때 이 대기 시간이 누적되었습니다.
Photon은 레코드 오프셋을 사전에 알 수 있다는 점을 활용하여 여러 읽기 작업을 한 번에 제출할 수 있습니다. 이는 리액터가 관리합니다. 전용 작업자 스레드는 io_uring을 통해 배치 단위로 제출하고 읽은 데이터를 호출 코드로 전달합니다. 각 스레드는 고유한 io_uring을 유지 관리하며, 배치는 부하가 가장 적은 리액터로 전송됩니다. 사전 등록된 파일 디스크립터와 버퍼 풀은 반복적인 읽기의 오버헤드를 줄여줍니다. 이러한 비동기 실행을 통해 여러 작업에 대한 대기 시간이 겹치게 되어 테일 레이턴시가 감소합니다.
드라이브 액세스 횟수 줄이기
읽기를 제출하기 전에 Photon은 인메모리 캐시에서 전체 배치를 확인합니다. 누락된 레코드에 대한 요청만 디스크로 이동하며, 읽은 데이터로 캐시가 채워집니다.
캐시는 일괄 읽기를 위해 설계되었습니다. 구체적인 내용은 다음과 같습니다:
- 히트 시 별도의 할당이 없습니다. 대신 데이터는 호출 코드가 사전에 준비한 버퍼로 복사됩니다.
- 독자에 의한 락 획득이 없습니다. 대신 데이터 버전을 확인하고 쓰기 작업과 충돌할 경우 재시도합니다.
- 이 엔진은 모든 읽기마다 공유 LRU 리스트를 업데이트할 것을 요구하는 대신 CLOCK 축출을 사용합니다.
- 이 엔진은 CPU 캐시 프리페칭을 사용하여 다가오는 레코드의 메타데이터와 데이터를 사전에 요청합니다.
이러한 최적화는 우리가 중요하게 생각하는 워크로드의 성능을 저해하지 않으면서 레이턴시를 줄여줍니다.
서빙과 별도로 인덱스 구축 및 업데이트하기
Photon에서는 인덱스 구축과 쿼리 서빙이 서로 다른 노드에서 실행됩니다. 인덱서는 데이터를 준비된 스토리지 구조로 변환하고, 서빙 노드는 이를 읽어 검색과 랭킹을 수행합니다. 결과적으로 인덱스 구축은 검색 쿼리와 CPU를 두고 경쟁하지 않으며, 이러한 작업에 대한 리소스는 독립적으로 확장할 수 있습니다.
이 분리는 이전 구현에 존재했던 복구 및 동기화 병목 현상을 해결합니다. 인덱스 구축이 쿼리를 서빙하던 동일한 클러스터 내부에서 실행되었기 때문에, 실패한 노드를 복구하거나 새로운 데이터 복사본을 추가하는 것은 문서를 제자리에서 다시 색인화해야 함을 의미할 수 있으며, 이 과정은 수일이 소요되고 복구 중 부분적인 응답을 증가시켰습니다. Photon은 이러한 결합을 제거합니다. 인덱서는 서빙 노드와 독립적으로 버전화되어 서빙 준비가 완료된 인덱스 구조를 생성하는 분산 작업으로 실행되므로, 다음 버전의 인덱스를 구축하는 작업이 더 이상 라이브 트래픽과 경합하지 않습니다.
준비 및 분산 구축
빌드는 활성 인덱스용 문서를 선택하고 소스 내보내기를 생성하는 것으로 시작됩니다. 컨트롤러는 소스 버전, 입력 테이블, 예상 샤드 수를 기록합니다. YTsaurus의 MapReduce 작업은 텍스트, 메타데이터, 프래그먼트, 피처, 사전 계산된 임베딩을 샤드별로 분할된 버전화된 테이블로 준비합니다. 각 인덱서는 준비된 테이블을 스트리밍하고, 샤드용 구조를 구축하며, 텍스트 세그먼트를 병합합니다. 준비된 인덱스는 구성 요소에 대한 설명과 함께 오브젝트 스토리지에 업로드됩니다.
샤드 수와 동시에 실행되는 인덱서 수는 독립적으로 설정되므로 빌드가 여러 웨이브로 실행되거나 더 많은 머신을 할당하여 병렬로 작업할 수 있습니다. 분산 준비와 병렬 인덱서를 통해 전체 웹 인덱스를 한 자리 수 시간 만에 구축할 수 있으며, 이는 이전 시스템에 비해 크게 개선된 점입니다.
새 버전 배포
배포 전에 컨트롤러는 새 인덱스가 준비되었는지 확인합니다. 데이터가 불완전한 경우 배포가 자동으로 차단됩니다.
서빙 그룹이 여러 개인 경우 컨트롤러는 한 번에 하나씩 업데이트합니다. 먼저 브로커 라우팅에서 그룹을 제거하고 새 인덱스 버전에서 시작하도록 합니다. 요청을 서빙하기 전에 샤드는 검색 로그를 기반으로 한 별도의 워밍업 단계를 거치며, 이는 초기 상태를 미리 채워 실제 트래픽으로의 전환을 더 원활하게 만듭니다. 워밍업 후 컨트롤러는 인덱스 상태와 준비 상태를 확인한 다음 그룹을 라우팅으로 복귀시킵니다. 다른 그룹은 이 시간 동안 계속 요청을 서빙합니다. 운영 상태가 지속되므로 재시작으로 인해 빌드가 처음부터 다시 시작되지 않으며, 컨트롤러는 이미 진행 중인 준비 작업에 다시 부착하거나, 준비된 결과를 재사용하거나, 저장된 단계부터 중단된 교체를 계속할 수 있습니다.
데이터 업데이트 시간은 검색 버티컬에 따라 다릅니다. 신선도 요구사항이 높은 버티컬의 경우 문서 전달에 한 자리 수 분이 소요됩니다. 데이터의 추가 복사본은 약 30분 만에 배포할 수 있으며, 소스 문서를 다시 색인화하지 않고도 준비된 인덱스가 로드되어 샤드에 부착됩니다.
검색 스택 내의 마이그레이션 및 검증
당사의 첫 번째 목표는 응답 시간을 단축하면서 기능과 검색 품질을 유지하는 엔진으로 구 시스템을 교체하는 것이었습니다. 당사는 라이브 트래픽으로 넘어가기 전에 재현 가능한 부하 테스트와 오프라인 품질 평가부터 시작하여 단계별로 Photon을 검증했습니다. Photon은 이제 프로덕션 검색 스택에서 검색 및 랭킹을 구동하며, 구 시스템보다 실질적으로 더 낮은 응답 시간을 제공합니다.
부하 테스트 및 평가
성능 테스트를 위해 당사는 설정 가능한 도달 빈도로 검색 로그의 쿼리를 재생하는 부상 테스트 도구를 구축했습니다. 이 도구는 실행 전반의 결과를 비교하고 관찰된 성능 차이가 일관성이 있는지 평가하기 위해 통계적 검정을 적용합니다. 별도로, 품질 저하 여부를 확인하기 위해 내부 오프라인 평가 시스템의 동일한 데이터셋에서 Photon과 구 시스템을 평가했습니다.
이러한 검사 후, 섀도우 트래픽을 사용하여 두 엔진 모두에 라이브 쿼리를 동시에 전송했습니다. 이를 통해 사용자에게 서비스를 제공하는 엔진을 변경하기 전에 프로덕션 워크로드에서 성능과 결과를 비교할 수 있었습니다. 그런 다음 소수의 사용자 하위 집합에 대해 Photon을 활성화하고 롤아웃을 점진적으로 확장하여 전체 과정에서 품질과 성능을 모니터링했습니다. 첫 번째 버전은 품질 저하 없이 인수 테스트를 통과했으며, Photon이 모든 프로덕션 트래픽을 처리할 때까지 롤아웃을 계속했습니다.
프로덕션에서 측정된 개선 사항
프로덕션 워크로드에서 p99 응답 시간은 구 시스템의 약 800ms에서 Photon의 약 65ms로 떨어졌습니다. 이 측정치는 Photon 내부의 모든 단계를 다루지만 상위 레벨 검색 스택의 후속 단계는 제외합니다. 또한 이전에 인덱스 버전 전환과 연관되었던 레이턴시 스파이크가 더 이상 관찰되지 않습니다.
Photon은 문서당 약 2.5배 더 많은 데이터를 저장하면서도 구 시스템의 콘텐츠 노드보다 약 20% 더 적은 동등 서빙 기계를 사용합니다. 마이그레이션 후, 당사는 이 추가 데이터를 사용하여 구 시스템을 뛰어넘는 수준으로 랭킹 품질을 개선했습니다.
또한 Photon은 메모리에 유지되어야 하는 데이터의 양을 줄입니다. mlock을 사용하여 동일한 Photon 데이터셋을 RAM에 고정하면 Photon이 현재 사용하는 것의 추정치 4.6배에 달하는 상주 메모리가 필요하게 됩니다.
빠른 Search API 프리셋 평가
또한 레이턴시 민감형 워크플로우를 위해 설계된 Search API용 새 빠른 프리셋의 기반으로 Photon을 사용했습니다. 당사의 측정에 따르면 빠른 프리셋의 단일 검색 호출 레이턴시는 p50에서 160ms, p95에서 230ms이며, 보고된 테일 백분위수는 다르지만 다른 Search API 제공사의 자체 보고 수치보다 낮거나 비슷합니다.
우리는 WideSearch, BrowseComp, DSQA, FRAMES, SEAL-0, SEAL-Hard 등 6개의 에이전트 벤치마크에서 빠른 프리셋을 평가했습니다. 이러한 평가 전반에서 이 프리셋은 테스트된 구성 중에서 가장 낮은 예상 총 모델-플러스-검색 비용과 가장 높은 종합 태스크 점수를 기록했습니다.
빠른 프리셋은 에이전트 워크플로우에 최적화된 랭킹과 Photon을 결합하여 훨씬 낮은 비용으로 기본 프리셋과 비교 가능한 성능을 제공합니다. 그러나 광범위한 검색 품질 측면에서 절충안이 존재합니다. 빠른 프리셋은 기본 프리셋보다 랭킹에 더 적은 연산량을 사용합니다. 롱테일 쿼리, 광범위한 커버리지, 결과 다양성을 다루는 내부 벤치마크에서 이 프리셋은 관련성 점수가 0.24포인트 낮고 답변 가용성은 약 3퍼센트 포인트 낮습니다. 모델 자체의 추론과 지식이 이러한 차이를 보완하는 데 도움이 될 수 있으므로, 이는 에이전트 워크플로우를 위한 합리적인 절충안이라고 생각합니다.
일상적인 에이전트 태스크에는 빠른 프리셋을 권장합니다. 시간적 제약이 덜한 더 까다롭거나 모호한 질문의 경우, 기본 프리셋은 더 강력한 품질을 제공하여 더 높은 레이턴시와 비용을 정당화합니다.
결론
우리는 검색 스택을 Rust 기반의 자체 인프라로 꾸준히 이전하고 있습니다. 오픈 소스 엔진을 맞춤형 검색 및 랭킹 엔진인 Photon으로 교체하는 것은 그 최신 단계입니다. Photon을 통해 데이터 표현, 읽기 구성 방식, 새 인덱스 배포 방식을 완전히 제어할 수 있으며, 이를 통해 각 레이어를 워크로드에 맞게 최적화할 수 있습니다.
Photon은 Perplexity 제품 전반에서 더 빠른 검색을 가능하게 했으며 Search API의 새로운 빠른 프리셋을 위한 기반을 제공합니다. 마이그레이션 이후 p99 검색 및 랭킹 레이턴시는 약 800ms에서 65ms로 떨어졌습니다. 또한 컴팩트한 데이터 형식을 통해 문서당 2.5배 더 많은 데이터를 저장할 수 있게 되어, 검색 및 랭킹이 더 풍부한 문서 정보에 액세스할 수 있게 되었습니다.
빠른 프리셋은 p50에서 160ms, p95에서 230ms의 단일 검색 호출 레이턴시를 제공합니다. 평가된 6개의 에이전트 벤치마크 전반에서, 이 프리셋은 기본 프리셋과 비교하여 태스크당 예상되는 모델 및 검색 비용을 68% 절감하는 동시에 유사한 종합 태스크 품질을 유지했습니다. 이러한 결과는 Perplexity의 제품과 API를 사용하여 구축하는 개발자 모두를 위해 검색 워크로드에 맞춰 설계된 인프라의 실질적인 이점을 보여줍니다.
우리는 Photon의 성능과 스토리지 효율성을 계속 개선하고 있습니다. 우리의 목표는 워크로드가 증가함에도 검색 속도를 유지하면서 동일한 하드웨어에서 더 큰 인덱스와 더 풍부한 문서 데이터를 지원하는 것입니다.
인용
@online{perplexity2026Photon,
author = {{Perplexity} and Maksim Morozov and Bogdan Savko and Ruslan Kovalev and Aleksei Bykov and Artur Zayats and Denis Bykov and Nikita Kireev and Jarrod Bryan and Claire Beamer and Jeremy Yang},
title = {{Photon: Building a retrieval and ranking engine from scratch}},
date = {2026-09-24},
url = {https://www.perplexity.ai/hub/blog/photon}
}