dev.to

RevCheck, compare the cars you want before you buy your next daily driver

중고차 두 대를 비교하는 RevCheck

RevCheck는 불가리아의 중고차 매물 사이트 mobile.bg와 cars.bg에서 매물 두 개를 읽어 사진, 시세, 엔진별 점검 항목을 비교합니다. Gemma 4, DeepSeek V4 Pro, TabPFN을 각 작업에 나눠 쓰고 규칙 기반 검사를 결합해 어느 차를 보러 갈지 제안합니다. 개발 과정에서는 이미지 오독과 환각을 코드로 제한하고, 40초 요청 제한을 피하도록 비교 과정을 여러 요청으로 나눴습니다.

에디터 노트

매물 비교의 신뢰도를 좌우하는 부분은 모델 성능보다 모델이 잘못 읽었을 때 피해를 어디서 차단하느냐입니다. 계기판 오독을 사기 단정으로 연결한 사례 뒤에 경고 조건을 코드로 옮긴 점은 구체적인 개선입니다. 사진 수와 VIN, 주행거리 이상 여부도 규칙으로 처리해 모델의 단정을 줄였습니다. 다만 예상 가격은 요청 당시 약 50개 비교 매물에 기대고, 엔진 코드는 연식에 따라 달라질 수 있어 확정값이 아닌 추정으로 다룹니다. 리콜도 모델 생성에서 제외하고 VIN 확인으로 넘깁니다. 따라서 RevCheck의 판정은 방문할 매물을 좁히는 비교 자료이며, 현장 점검이나 정확한 제조사 이력 조회까지 대신하지는 않습니다. 작성자가 제시한 무료 제공과 딜러 구독 구상은 비용을 낮게 유지해야 한다는 설계 설명과 맞닿아 있지만 실제 운영 비용이나 수요 수치는 제시하지 않습니다.

AI 요약

RevCheck는 mobile.bg와 cars.bg의 중고차 매물 링크 두 개를 입력받아 비교 보고서를 만드는 도구입니다. 매물 사진에서 차체 색상과 흠집, 패널 차이, 장비를 확인하고 판매자가 적은 설명과 사진이 어긋나는지도 살핍니다. 비슷한 연식과 차체, 연료, 엔진 출력의 매물을 찾아 각 차의 시장 내 가격 위치를 계산하고, 비교 매물로 TabPFN 3.5를 요청 중 학습해 예상 가격 범위를 냅니다. 엔진 코드와 자주 확인할 문제는 DeepSeek V4 Pro가 정리하며, 마지막으로 Gemma 4가 결과를 종합해 어느 차를 보러 갈지와 판매자에게 물을 질문을 씁니다. 영어와 불가리아어 보고서를 지원합니다.

구성과 데이터 처리

프런트엔드는 GitHub Pages의 정적 페이지이며, 백엔드는 DigitalOcean Function과 Cloudflare Worker로 구성합니다. 사용자가 시작 요청을 보내면 Cloudflare Turnstile 검사를 거쳐 두 매물 링크에 묶인 3분짜리 서명 티켓을 받습니다. 이후 차마다 하나씩 요청해 병렬 처리하고, 마지막 요청에서 비교 결과를 만듭니다. 매물 사이트가 DigitalOcean 요청을 차단하고 브라우저의 교차 출처 요청도 허용하지 않아, Worker가 매물 페이지와 검색 결과를 가져옵니다. Worker는 RevCheck 이름을 밝히는 User-Agent를 쓰며, 공유 비밀값을 요구하고 mobile.bg와 cars.bg 주소만 허용합니다. 사이트가 차단하면 중단하겠다는 방침도 적었습니다.

모델과 규칙 기반 검사

사진 분석에는 이미지마다 Gemma 4를 사용하며 한 번에 최대 8장을 보내고 여러 묶음은 병렬로 확인합니다. 엔진별 약점은 DeepSeek V4 Pro가 정리합니다. 개발자는 같은 차를 네 개의 오픈 모델에 넣어 비교했고, 두 모델은 유효하지 않은 JSON을 반환했으며 나머지 중 DeepSeek만 변속기 문제를 언급했다고 설명합니다. 가격 범위는 비교 매물 약 50개를 요청 안에서 학습하는 TabPFN 3.5로 계산합니다. 모델이 판단하면 위험한 항목은 코드가 처리합니다. VIN 누락, 연간 주행거리의 이상치, 사진 수, 미국·캐나다 수입 여부를 규칙으로 확인합니다. 보고서에 들어가는 매물 데이터도 허용된 필드와 크기 제한에 맞춰 다시 구성하며, 사진 주소는 두 사이트의 이미지 서버로 제한합니다.

오작동에서 바꾼 점

초기 버전은 계기판 사진의 104,677km를 266,777km로 읽고 판매자를 주행거리 조작범이라고 판단했습니다. 이후 모델은 계기판 숫자를 읽고 판독이 명확한지 표시하게 바꿨습니다. 주행거리 차이가 15%를 넘고 판독도 명확할 때만 코드가 직접 확인하라는 경고를 냅니다. 모델 프롬프트에서 사기 혐의 같은 단정도 금지했습니다. 사진이 10장인 매물에 실내 사진 두 장만 본 모델이 사진이 부족하다고 한 사례도 있었습니다. 사진 개수 판정은 모델에서 코드로 옮겼습니다.

차체 유형 검색에서는 키릴 문자와 모양이 같은 라틴 문자를 구분하지 못해 쿠페 매물 조건이 빠졌습니다. 두 문자를 정규화해 비교하도록 수정하고 해당 문자열을 테스트에 추가했습니다. 제조사 리콜을 생성하게 했을 때 DeepSeek가 N52 엔진과 관련한 VANOS 볼트 캠페인을 잘못 언급한 뒤에는 리콜 정보를 모델이 만들지 않게 했습니다. 대신 VIN으로 딜러에게 진행 중인 캠페인을 확인하라고 안내하고, 연식 중 엔진이 바뀌는 경우에는 가능한 엔진 코드를 나열하되 확정 표현을 쓰지 않도록 했습니다.

배포와 시간 제한

사진 분석과 시세 계산, 엔진 정보 조회를 한 요청에서 모두 처리하면 전체 비교가 33~45초 걸렸습니다. DigitalOcean 웹 게이트웨이는 함수 제한 시간과 별개로 40초에 202 응답을 반환했습니다. 그래서 시작 요청, 차량별 요청 두 개, 최종 판정 요청으로 처리 단계를 나눴습니다. 각 차의 결과가 먼저 화면에 나타나고 비교 판정은 나중에 추가됩니다. 작성자는 26개 테스트를 포함했고 프레임워크와 데이터베이스, npm 의존성 없이 구현했다고 설명합니다.

비용과 다음 작업

한 번 비교할 때 모델 호출은 6~8회 발생합니다. 작성자는 선불 추론 잔액과 자동 충전 비활성화로 비용 상한을 두며, 하루 몇 회는 무료로 제공하고 차량을 많이 비교하는 딜러와 소규모 판매자에게 월 요금을 받는 방안을 제시합니다. 다음 작업으로 BMW VIN을 통한 정확한 엔진 정보와 캠페인 확인, mobile.bg와 cars.bg의 공식 접근 협의, 독일 중고차 가격과 수입 비용 비교를 들었습니다.

원문: dev.to / 번역·요약: Trawling