Screen Play

벤치마크 · 리스트 추출

F1 0.92, row당 $0, LLM 호출 0회.

ScreenPlay의 discover_list는 실제 운영 중인 SaaS 사이트 50곳에서 구조화된 레코드 리스트 — 채용공고·블로그·고객사례·체인지로그 — 를 휴리스틱만으로 추출합니다. LLM 없음, row당 $0, 매 실행 byte-identical.

사람-검증 결과 — 50개 사이트 / 108개 채점 태스크

0.921micro-F1
0.967정밀도(precision)
0.879재현율(recall)
$0.00row당 비용 (강제)
0LLM 호출
42완벽 태스크 (F1 = 1.00)

휴리스틱-only, 결정적(매 실행 byte-identical), gold 사람-검증 완료(139 / 139).

한 줄. 셀렉터 없음.

CSS 셀렉터도, XPath도, 사이트별 파싱 코드도 없습니다. 원하는 필드만 선언하면 엔진이 리스트를 찾아 레코드별 한 행씩 반환 — 모든 사이트에서 같은 호출.

items = page.discover_list({title, location, url})

이게 추출기의 전부입니다. 위의 0.92 F1 숫자는 이 한 줄을 50개 사이트에 그대로 돌린 결과입니다.

실제 출력 — stripe.com/jobs (64 / 64 추출, F1 = 1.00):

titlelocationurl
Account Executive - Enterprise, GrowerSouth San Francisco HQstripe.com/jobs/listing/account-executive-enterprise-grower/7993151
Account Executive, Commercial Hunter (Japanese fluency)Tokyostripe.com/jobs/listing/account-executive-commercial-hunter-japanese-fluency/7789539
Account Executive, Cross Border ChinaSingaporestripe.com/jobs/listing/account-executive-cross-border-china/7893199
Account Executive, Enterprise - GrowerNew Yorkstripe.com/jobs/listing/account-executive-enterprise-grower/7997555

유스케이스별

태스크 종류별 micro 평균 정밀도 / 재현율 / F1.

유스케이스정밀도재현율F1태스크
채용공고0.9990.9600.97924
제품 업데이트0.9780.9600.96912
블로그0.9730.8340.89846
고객사례0.8610.7840.82126

이 숫자를 얻은 과정

먼저 gold를 사람-검증(엔진 불변 — 큐레이션은 gold만 바꿈)하고, 그 다음 벤치가 찾아낸 엔진 픽스 1건을 반영했습니다. 모든 단계는 zero-regression 검증 + 2회 byte-identical.

단계micro-F1정밀도재현율채점
원본 candidate gold (검증 0건)0.90230.95840.8524116
+ gold 큐레이션·검증 (139/139)0.91940.96620.8769108
+ query-facet 픽스 (F14)0.92100.96680.8793108

이 숫자를 신뢰하게 만드는 방법론

$0 / 결정성 강제

채점 하니스는 API 키를 빈 값으로 export — LLM이 몰래 돌 수 없어 숫자가 진짜로 무료이고 재현 가능합니다. 예측은 매 실행 byte-identical(MD5로 검증).

사람-검증 gold

139개 gold 전부 문서화된 재현 가능한 큐레이터로 verified:true 처리. 실제 데이터를 삭제할 뻔한 솔깃한 규칙 2개는 측정으로 기각.

정직한 skip, 숨기지 않음

35개 태스크는 정적 DOM에 레코드별 URL이 없음(JS/크로스-호스트 ATS 보드, 클라이언트 렌더 로고 그리드). 커버리지를 부풀리려 버리지 않고 skip으로 기록.

zero-regression 원칙

모든 엔진 변경은 새 baseline 대비 태스크별 점수를 전부 diff하고, byte-identical 예측을 위해 2회 재실행한 뒤에만 머지.

WebLists와 비교 — 단, 주의사항

WebLists는 공개된 리스트 추출 벤치마크로, 보고된 SOTA(LLM 에이전트)가 약 31% 재현율입니다. ScreenPlay의 결정적·LLM-없는 추출기는 자체 코퍼스에서 88% 재현율에 도달합니다.

이건 사과-대-사과 비교가 아닙니다:

  • 태스크 셋이 다름 — 우리 50개 사이트는 dev-tool/SaaS로, WebLists의 오픈 웹보다 좁은 범위.
  • 우리 gold는 자체 사람-검증(투명하지만 우리 것)으로, 독립 제3자 셋이 아님.
  • 우리는 frozen 스냅샷을 채점 — 라이브 안티봇/하이드레이션 문제와 분리된 '추출 품질'.
  • 리더보드 주장이 아니라 자릿수 수준의 sanity 체크.

강제 함수로서의 벤치마크

더 어려운 사이트 배치마다 다음 실제 버그가 드러났고, 각 픽스는 zero-regression 검증되어 집계를 끌어올렸습니다.

F7 — 크로스-호스트 ATS & 택소노미 facet

채용 페이지는 Greenhouse/Ashby를 임베드하므로 실제 채용 링크는 절대 크로스-호스트 URL; 블로그의 /tag/* facet 리스트는 글 리스트와 똑같이 생김. 엔진이 크로스-호스트 ATS id를 구제하고 택소노미 facet에는 coherence를 거부하도록 학습.

F12 — 분할 리스트 union (0.78 → 0.89)

부서별로 쪼개진 채용 리스트, 월별로 페이징된 체인지로그는 fragment 하나만 잡힘. 전역 class-signature union이 전체 리스트를 후보로 제안(coherence + LCA chrome 페널티 + distinct-URL 비율로 게이팅).

F13 — 마케팅 메가메뉴

product/solutions 내비는 레코드 리스트처럼 coherent해서 콘텐츠를 이김. 지배적 부모가 content 단어 없는 마케팅-내비 섹션일 때 coherence 구제를 거부 — 전체 gold 코퍼스로 검증.

F14 — query-facet 칩

datadog 카드는 실제 /blog/<slug> 링크 앞에 /blog/search/?tag= 칩을 노출; path 기반 가드가 놓침. non-facet 우선 규칙이 search-view query-facet도 건너뛰게 해 datadog-blog 0 → 0.76 회복.

정직한 한계

  • gold는 우리가 큐레이션 — 투명하고 재현 가능하지만 독립 제3자 gold는 아님.
  • frozen 스냅샷은 추출 품질을 재며 라이브 견고성이 아님(안티봇·하이드레이션·로그인 게이트는 여기서 제외 — ScreenPlay의 다른 부분이 처리).
  • 일부 리스트는 캡처된 DOM보다 큼; 그건 재현율을 제한하며 쫓지 않고 기록.
  • 범위는 dev-tool/SaaS 50개 사이트, 4개 유스케이스; 오픈 웹 일반화는 미검증.
  • 몇몇 어려운 태스크는 낮게 남고 오버핏 대신 정직한 skip으로 기록: 로고-only 고객 그리드(비전 필요), 멀티-parent 블로그, 콘텐츠-탐지 갭.

실전에 투입하기

엔진을 라이선스하거나, 크롤링을 함께 진행하세요. 전체 화이트페이퍼 — 방법론, 원본 vs 큐레이션 숫자, 모든 finding, 재현 명령 — 는 엔진과 함께 제공됩니다.