저렴한 LLM 릴레이(Relay)가 모델을 바꿔치기하고 있을지도 모릅니다. 이를 잡아내는 방법
요약
저렴한 LLM API 릴레이 서비스가 플래그십 모델 대신 저렴하거나 성능이 낮은 모델로 바꿔치기하는 사기 행위를 식별하는 검증 방법을 소개합니다. 모델의 자기 보고에 의존하지 않고 능력과 동작을 측정하여 모델 교체, 과도한 양자화, 컨텍스트 절단 등을 잡아내는 플레이북을 다룹니다.
핵심 포인트
- 모델의 자기 보고(Self-report)는 시스템 프롬프트로 쉽게 조작 가능함
- 모델 교체, 과도한 양자화, 컨텍스트 절단, 무단 폴백 등 4가지 주요 속임수 주의
- 모델의 실제 능력과 동작(Capability and behavior)을 측정하여 검증해야 함
- 토크나이저 지문 등 행동적 지문을 결합하여 다각도로 분석 필요
만약 당신이 저렴한 "GPT / Claude / DeepSeek" API 릴레이(Relay)를 통해 모델 액세스 권한을 구매한다면, 가격 페이지에는 아무도 적어두지 않은 신뢰의 문제가 발생합니다. 일부 릴레이는 플래그십(Flagship) 모델 가격을 청구하면서, 몰래 더 작거나 양자화(Quantized)된, 또는 컨텍스트가 축소(Context-truncated)된 모델로 바꿔치기합니다. 정말 고약한 점은 타이밍입니다. 첫날에는 잘 작동하다가, 당신이 확인을 멈춘 지 몇 주가 지난 후에 성능이 저하되곤 합니다.
이 글은 제가 게이트웨이(Gateway)를 평가하기 시작했을 때 존재했으면 좋았을 검증 플레이북(Verification playbook)입니다. 이 방법은 OpenAI 또는 Anthropic 호환 엔드포인트(Endpoint)라면 무엇이든 적용 가능하며, 마지막에는 이 모든 과정을 자동화하는 작은 오픈 소스 도구가 소개되어 있습니다.
사전 공개: 저는 이러한 게이트웨이 중 하나인 daoxe에서 일하고 있습니다. 제가 검증 방법을 작성하는 이유는 저희를 포함하여 어떠한 제공업체라도 테스트할 수 있도록 하기 위함입니다. 검증 도구는 그것을 만든 사람조차 기꺼이 지적할 수 있을 때에만 유용합니다.
작동하지 않는 단 하나의 확인 방법
가장 뻔한 방법은 엔드포인트에 _"당신은 어떤 모델인가요?"_라고 묻는 것입니다.
그럴 필요 없습니다. 그 답변은 시스템 프롬프트(System prompt)나 파인튜닝(Fine-tune)에서 나오며, 양방향 모두에서 매우 쉽게 속일 수 있습니다(Trivially spoofable). 7B 모델을 제공하는 릴레이가 하루 종일 "저는 GPT-4급 모델입니다"라고 출력할 수 있으며, 실제 플래그십 모델은 다른 이름으로 자신을 부르도록 지시받을 수도 있습니다. 자기 보고(Self-report)는 연극에 불과합니다.
당신은 모델이 스스로에 대해 주장하는 것이 아니라, **능력과 동작(Capability and behavior)**을 테스트해야 합니다. 그리고 반드시 _측정(Measure)_해야 합니다. 단 한 번의 요청으로는 아무것도 알 수 없습니다. 온도(Temperature), 샘플링(Sampling), 라우팅(Routing) 등이 모두 노이즈를 추가하기 때문입니다.
당신이 실제로 방어해야 할 네 가지 속임수
마진(Margin)이 박할 때, 부정직한 릴레이는 다음과 같은 행위를 할 수 있습니다:
- 모델 교체 (Substitute the model). 당신은 플래그십(Flagship) 모델을 요청했지만, 그들은 더 저렴한 모델을 제공하고 비용은 플래그십 모델로 청구합니다.
- 과도한 양자화 (Serve heavy quantization). 모델 이름은 동일하지만, 가중치(Weights)를 공격적으로 양자화하여 추론(Reasoning) 능력이 눈에 띄게 저하됩니다.
- 컨텍스트 절단 (Truncate your context). 토큰을 아끼기 위해 컨텍스트 윈도우(Context window)를 몰래 제한하며, 이로 인해 긴 컨텍스트 작업이 조용히 실패하게 됩니다.
- 고지 없는 폴백 (Fall back without telling you). 상위(Upstream) 모델에 속도 제한(Rate-limit)이 걸리면, 그들은 사용 가능한 아무 모델로나 경로를 변경하고 이를 전혀 알리지 않습니다.
이 각각의 행위는 '행동적(Behavioral)' 지문을 남깁니다. 이를 읽어내는 방법은 다음과 같습니다.
이를 실제로 잡아내는 다섯 가지 신호
이 중 어느 하나도 단독으로는 무엇을 증명할 수 없습니다. 하지만 이들이 결합되면, 당신을 안심시키거나 혹은 더 자세히 조사해야 할 이유를 제공합니다.
1. 토크나이저 지문 (Tokenizer fingerprint)
모델 제품군(Model families)마다 서로 다른 토크나이저(Tokenizer)를 사용하며, 토크나이저는 서버가 보고하는 usage.prompt_tokens를 통해 유출됩니다. 숫자 나열, 공백, CJK(한중일), 이모지, 코드, URL, 혼합 유니코드 등 정교하게 제작된 문자열 세트를 보내고 각 문자열이 몇 개의 토큰을 소모하는지 기록하십시오. 요청당 고정된 채팅 템플릿(Chat-template) 오버헤드를 상쇄하기 위해, 델타(Delta) 값을 측정하십시오: tokens(anchor + probe) − tokens(anchor).
- 최선의 경우 (참조 모델 없음): 동일한 모델 ID를 제공한다고 신뢰할 수 있는 엔드포인트(Endpoint)와 해당 토큰 벡터를 비교하십시오. 벡터가 다르다는 것은 토크나이저가 다르다는 것을 의미하며, 이는 곧 모델 제품군이 다르다는 것을 의미합니다. 이는 신뢰도가 높은(High-confidence) 신호입니다.
- 단일 엔드포인트: 알려진 토크나이저 테이블(예: OpenAI의
cl100k_base/o200k_base)과 벡터를 대조하여 분류하십시오. 만약 주장하는 모델 제품군에 공개된 참조 모델이 없다면(Claude, Gemini 등...), 정직한 답변은 '결론을 내릴 수 없음(Inconclusive)'입니다. 추측하지 말고 차이(Diff)를 사용하십시오.
2. 능력 하한선 (Capability floor)
2. 능력 하한선 (Capability floor)
이미 알고 있는 객관적으로 확인 가능한 정답이 있는 몇 가지 작업들을 활용하십시오: 다단계 산술(multi-step arithmetic), 문자열 뒤집기(string reversal), 문자 수 세기(character counting), 그리고 엄격한 JSON 형식 테스트(strict-JSON format test) 등이 있습니다. 이러한 작업들은 모든 풀 티어(full-tier) 모델에게는 사소한 수준입니다. 성능이 저하되었거나 심하게 양자화(quantized)된 대체 모델은 이러한 작업에서 실수할 가능성이 더 높습니다. 성공보다는 _실패(failure)_에 더 큰 가중치를 두십시오. 쉬운 작업을 통과하는 것은 증거로서 가치가 낮지만, 하한선(floor) 작업을 실패하는 "플래그십(flagship)" 모델은 반드시 문제를 제기할 가치가 있습니다.
3. Long-context recall (the needle)
결정론적인(deterministic) 채우기 텍스트(filler text)를 생성하고, 그 중간에 고유한 암호(passphrase)를 숨긴 뒤, 여러 컨텍스트 길이(context lengths)에 걸쳐 엔드포인트(endpoint)에 이를 다시 읽어달라고 요청하십시오. 당신이 직접 바늘(needle)을 배치했기 때문에, 항상 정답을 알고 있습니다 (외부 키가 필요하지 않습니다). 짧은 컨텍스트에서는 작동하지만 긴 컨텍스트에서 작동하지 않는 회상(Recall) 능력은 **조용한 컨텍스트 절단(silent context truncation)**의 전형적인 특징입니다.
4. 안정성 및 성능 (Stability & performance)
temperature=0 설정에서 하나의 고정된 프롬프트를 N번 반복 실행하고, 출력의 결정론(determinism), 서버가 보고하는 model 필드와 system_fingerprint의 안정성, 그리고 **p50/p95 지연 시간(latency) 및 에러율(error rate)**을 확인하십시오. 동일한 호출에 대해 서로 다른 model 값을 보고하거나 매우 다른 출력을 내놓는 서버는 서로 다른 백엔드(backends)를 통해 사용자를 라우팅(routing)하고 있을 수 있습니다.
5. 자기 보고 (Self-report) (의도적으로 낮은 가중치 부여)
모델에게 자신의 이름을 묻고 주장하는 내용과 비교해 보십시오. 하지만 모델의 확신(confidence) 수준은 **낮음(low)**으로 제한해야 합니다. 왜냐하면 양방향 모두로 속임수(spoofable)가 가능하기 때문입니다. 이 방법은 부재(absence) 자체가 눈에 띌 수 있기 때문에 포함하는 것일 뿐, 결론을 내리는 결정적인 근거로 사용해서는 안 됩니다.
신호를 신뢰할 수 있게 만드는 설계 규칙
temperature=0, 고정된max_tokens, 고정된 시스템 프롬프트(system prompt) — 무작위성을 제거하십시오.- 눈대중이 아닌 측정(Measure, don't eyeball) — 반복 실행하고 백분위수(percentiles)를 기록하십시오.
- 가능할 때마다 신뢰할 수 있는 참조 대상(reference)과 차이(Diff)를 비교하십시오. 이것이 가장 강력한 조치입니다.
- 정기적으로 재실행하십시오. 조용한 성능 저하(Silent degradation)는 출시 당일의 문제가 아니라 시계열(time-series) 문제입니다.
수동으로 수행하기 (60초 버전)
도구 없이도 시작할 수 있습니다. 파라미터(parameters)를 고정하고 두 엔드포인트에 동일한 탐침(probe)을 발사하십시오:
# 귀하의 릴레이 (relay)
curl -s -w '\n%{time_total}s\n' https://your-relay.example/v1/chat/completions \
-H "Authorization: Bearer $RELAY_KEY" -H "Content-Type: application/json" \
...
usage.prompt_tokens, 답변 품질, 그리고 지연 시간(latency)을 관찰하십시오. 이를 몇 번 반복하십시오. 차이(divergence)가 발견된다면, 그것이 당신이 파헤쳐야 할 첫 번째 실마리입니다.
자동화하기: 오픈 소스 탐침 (probe)
매주 이 테스트 세트를 수동으로 실행하는 것은 지루한 일이므로, 이를 대신 수행해 주는 작은 오픈 소스 CLI인 **llm-honesty-probe**가 있습니다. 주목할 만한 설계 목표는 다음과 같습니다:
- 런타임 의존성 제로 (Zero runtime dependencies). 순수 파이썬 표준 라이브러리(Python standard library)만 사용합니다.
pip install할 것도 없고, 감사(audit)해야 할 락파일(lockfile)도 없습니다. 실행하기 전에 클론(clone)하여 코드를 읽어보십시오. - 귀하의 키는 절대 출력, 로그 기록 또는 저장되지 않습니다. 키는 오직 환경 변수(environment variable)로부터만 읽어옵니다 (셸 히스토리(shell history)에 남지 않도록 의도적으로
--key플래그를 만들지 않았습니다). 또한 모든 출력 라인은 레드액션(redaction, 비식별화) 레이어를 통과합니다. - 공급자 중립적 (Provider-neutral). 허용 목록(allow-list), "선호하는" 엔드포인트, 텔레메트리(telemetry)가 없습니다. 공식 API와 모든 릴레이를 동일하게 취급합니다.
git clone https://github.com/seven7763/llm-honesty-probe
cd llm-honesty-probe
python3 -m llm_honesty_probe --self-test # 내장된 모의(mock)를 대상으로 실행하며, 키가 필요하지 않습니다.
...
출력 결과는 각 신호에 대해 [OK] (일관됨), [!!] (의심스러움), 또는 [--] (결론을 내릴 수 없음)를 표시하며, 각각의 신뢰 수준(confidence level)을 함께 제공합니다. --json --out report.json을 사용하여 cron/CI를 통해 시간에 따른 결과의 차이(diff)를 비교하십시오. 성능 저하는 출시 당일이 아니라 드리프트(drift, 편차)의 형태로 나타나기 때문에, 이것이 이 도구의 핵심 목적입니다.
한계점을 진지하게 읽어보십시오
정직성 도구의 성능을 과장하는 것은 그 목적을 저해합니다. 따라서 솔직하게 말씀드리자면:
- 이것들은 신호(signals)일 뿐, 증거가 아닙니다. 여기 있는 그 어떤 것도 제공업체가 어떤 가중치(weights)를 실행하는지 암호학적으로 입증하지는 못합니다. 토크나이저(tokenizer)를 미러링하고, 성능(capability)을 일치시키며, 컨텍스트(context)를 유지하고, 안정성을 유지하는 제공업체는 실질적인 관점에서 당신에게 해당 모델을 제공하고 있는 것이지만, 외부에서는 그 의도를 증명할 수 없습니다.
- 프로브(probe) 세트가 작고 알려져 있습니다. 이 정확한 프로브들에 대해 특수 처리를 하는 제공업체라면 단일 엔드포인트 실행을 속일 수 있습니다. 그렇기 때문에 가장 강력한 모드는 **당신이 직접 제어하는 차분 분석(differential diff)**입니다.
- "의심스러운" 현상에는 무고한 설명이 있을 수 있습니다. 당신이 요청한 것이 작은 모델이라면 그것이 '정답'일 수 있고, 짧은 컨텍스트 제한은 모델의 실제 한계일 수 있으며, 인프라의 차이는 지연 시간(latency)을 변화시킬 수 있습니다. 모호함을 해소하기 위해
--compare를 사용하십시오. - 실제 하드웨어에서
temperature=0은 완벽하게 결정론적(deterministic)이지 않으므로, 결정론적 신호의 신뢰도는 의도적으로 낮게 설정되었습니다.
깨끗한 실행 결과는 보증이 아닌 '안심할 수 있는 요소'로 간주하십시오. 경고 신호는 유죄 판결이 아닌 '더 자세히 살펴봐야 할 이유'로 간주하십시오.
제공업체 입장에서의 "정직함"이란 무엇인가
제가 주저 없이 이 글을 게시할 수 있는 이유는 검증 가능성(verifiability) 자체가 핵심 제안이기 때문입니다. 사용할 가치가 있는 게이트웨이는 다음과 같아야 합니다:
- 벤치마크 가능해야 함 (Benchmarkable). 당신이 이를 통해 벤치마크를 수행하는 것에 대해 개의치 않아야 합니다. (만약 벤치마크를 요청했을 때 제공업체가 회피한다면, 그것이 바로 답입니다.)
- 사용 중인 프로토콜에서 네이티브로 작동해야 함. OpenAI Chat Completions뿐만 아니라 Anthropic Messages도 지원하여, 단순히 OpenAI 형태뿐만 아니라 Claude Code가 제대로 작동해야 합니다.
- 하나의 키로 여러 모델 사용 가능 (One key, many models), 계정 범위의
/v1/models를 제공하여 당신이 보는 것이 곧 호출할 수 있는 모델이어야 합니다. - 비용과 상태에 대해 투명해야 함 (Transparent on cost and status) — 항목별 사용량(itemized usage)을 제공하며, 결제와 관련된 숨겨진 사항이 없어야 합니다.
daoxe는 바로 그 점을 중심으로 구축되었습니다: OpenAI 호환 베이스 URL (https://daoxe.com/v1), Claude Code를 위한 네이티브 Anthropic Messages 지원, 여러 모델에 걸친 하나의 통합 키, 그리고 신뢰하기보다는 검증하도록(verified rather than trusted) 설계된 구조를 갖추고 있습니다. 중국 본토에서는 사용할 수 없습니다. 제 말을 그대로 믿지 마세요. — 이 프로브(probe)를 사용하여 현재 사용 중인 서비스와 비교해 보시기 바랍니다. 만약 daoxe가 이러한 검증을 통과하지 못한다면, 그것은 저희가 받고자 하는 버그 리포트가 될 것입니다.
보완 도구: llm-gateway-benchmark는 "이 엔드포인트가 빠르고 저렴한가?"(성공률, p50/p95, 100만 토큰당 비용)에 답합니다. 이 도구는 "이것이 실제로 주장하는 그 모델인가?"에 답합니다. 두 도구는 경쟁 관계가 아닌 상호 보완적인 관계입니다.
요약 (TL;DR)
- 모델에게 자신이 무엇인지 묻지 마세요. 능력(capability)과 동작(behavior)을 테스트하세요.
- 다섯 가지 신호: 토크나이저 지문(tokenizer fingerprint), 능력 하한선(capability floor), 긴 문맥 내 바늘 찾기(long-context needle), 안정성, 그리고 (낮은 가중치의) 자기 보고(self-report).
temperature=0으로 고정하고, 백분위수(percentiles)를 측정하며, **기준점(reference)과 비교(diff)**하고, 매주 재실행하세요.- 이것은 증거가 아닌 신호(signals)입니다. 하지만 지금 당신에게 부족한 것은 바로 그 신호입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기