원문 캡처 · stackone.com
원문 캡처 · stackone.com

StackOne의 Defender는 도구 호출 에이전트가 받은 결과를 세 단계로 검사한다. StackOne은 마지막 단계에서 쓰던 생성형 모델을 질문별 확률만 출력하는 의사결정 모델로 바꾸는 작업을 진행하고 있으며, 현재 초기 테스트를 하고 있다. 이 글은 Hiskias Dingeto가 2026년 10월 15일 공개했다.

Defender의 1단계는 패턴 매칭으로 약 1밀리초가 걸리고, 2단계는 앞선 글에서 다룬 22MB 분류기로 CPU에서 문자열마다 수십 밀리초 안에 점수를 낸다. 기존 3단계는 2단계가 확신하지 못한 결과를 생성형 소형 언어 모델이 읽고 판정하는 방식이었다. 공격 탐지에는 쓸 만했지만 GPU와 호출당 수백 밀리초가 필요해 비용이 컸다. 더 저렴한 모델이라면 2단계로 넘겨진 결과만이 아니라 모든 도구 결과를 살펴볼 수 있다는 구상이다.

의사결정 모델을 택한 이유

이 글에서 말하는 시스템 원(System One) 모델은 텍스트나 JSON 상태와 유형이 정해진 질문을 입력받아, 선택지별 확률이나 척도 점수 또는 예·아니요 확률을 반환한다. 자유로운 문장을 생성하지 않는 것이 특징이다. TypeSafe는 이 용어를 결정만 수행하는 모델을 가리키는 데 쓴다. TypeSafe의 Jev는 9월 15일 공개됐고, Cloudflare는 10월 1일 Apache 2.0 라이선스의 오픈 가중치 모델 Clef와 Clef-flash를 공개했다. 두 모델은 Qwen 기반 모델에 점수 산출 헤드를 추가해 한 번의 순전파로 질문에 답한다. 연구 쪽에서는 Laya가 소형 인코더도 같은 유형의 질문에 답할 수 있음을 보였다. 이 모델들은 프롬프트 인젝션용으로 만들어진 것은 아니지만, 보안 가드의 판정 작업에 맞는 형식이라고 StackOne은 설명한다.

생성형 판정 모델은 공격자가 제어하는 텍스트를 읽고 자유롭게 답한다. 따라서 인젝션에 속아 거부하거나 장황하게 답하거나 파서가 처리하지 못할 출력을 낼 수 있다. 선택지가 정해진 의사결정 모델도 잘못된 선택지에 높은 확률을 줄 수는 있지만, 미리 선언한 출력 외의 방식으로 답하지는 않는다.

또한 생성형 모델이 ‘차단’이나 ‘허용’을 쓰게 하면 사실상 두 단어 중 더 가능성 높은 쪽을 고르는 고정 임계값 0.5가 적용된다. 재학습 때마다 점수 분포가 달라질 수 있다. StackOne은 생성형 모델 판정기를 미세 조정했을 때 학습 데이터의 작은 변화에도 재현율이 크게 움직였지만 순위화 품질은 거의 달라지지 않았다고 밝혔다. 배포별 목표 오탐률에 맞춰 임계값을 정할 수 있도록 확률을 직접 출력하는 모델을 선호했다는 설명이다.

Jev는 첫 시도로 적합해 보였지만 호스팅 API로만 제공됐다. 도구 결과에는 직원 기록, 이메일, CRM 메모가 포함될 수 있고, Defender는 데이터가 이미 처리되고 있는 인프라 안에 머물도록 설계됐다. 모든 결과를 제3자에게 보내는 방식은 앞선 글에서 프런티어 모델 호출을 배제한 이유와 같았다.

StackOne은 형식이 문제에 맞는지 확인하기 위해 OpenRouter를 통해 Jev도 시험했다. 질문은 약 600개의 입력 토큰을 사용하는 한 번의 호출에 들어갔고, Jev의 공개 가격 기준 비용은 0.000025달러였다. 다만 기준을 임시로 설정한 세 행에서 정상적인 도구 출력이 인젝션으로 표시됐으며, 틀린 행에서 가장 높은 확신을 보였다. 세 행만으로 Jev를 평가할 수는 없지만, 도구 입력에 제로샷으로 적용해도 된다고 기대하지 않게 됐다고 StackOne은 밝혔다.

이에 StackOne은 미세 조정하고 자체 호스팅할 수 있는 ModernBERT 기반 의사결정 모델을 택했다. Jev와 같은 선택·점수·예·아니요 확률 인터페이스를 사용하며, 소형 GPU 한 대에 들어간다. 보류 테스트 데이터에서 제로샷 정확도는 54.5%여서 실제 데이터 경로에 넣기 전 학습이 필요했다.

질문 설계와 학습 결과

단순히 ‘이것은 프롬프트 인젝션인가?’라고 묻는 대신, 도구 결과 안에서 인젝션이 위험해지려면 어떤 특성이 필요한지 세 질문으로 나눴다. 텍스트가 명시적 또는 암묵적으로 에이전트에게 지시하는지, 데이터를 다른 곳으로 보내라고 하는지와 그것이 실행 가능한 지시인지 단순 언급인지, 신원이나 권한을 주장하며 노골적으로 사칭하는지를 각각 세 가지 선택지 중에서 판정하게 했다.

최종 판정은 각 질문에서 가장 위험한 선택지가 얻은 확률 중 최댓값으로 정한다. 동료에게 3분기 수치를 재무팀에 보내 달라고 하는 이메일은 데이터 이동을 언급하지만 사람에게 지시한다. 반면 이메일 본문이 보조자에게 같은 수치를 외부 주소로 전달하라고 하면 두 질문에서 모두 높은 점수를 받을 수 있다. 질문별 결과를 남기면 어떤 항목이 차단을 이끌었는지와 모델의 확신도를 확인할 수 있어, 단일 점수보다 차단 건을 분류하기 쉽다고 StackOne은 설명한다.

처음에는 도구 결과의 구조가 해당 도구에 비해 이례적인지도 묻는 네 번째 질문을 넣었다. 라벨링 교사로 사용한 프런티어 모델 세 개가 이 질문에서 가장 크게 의견이 갈렸다. 제로샷 전이도 가장 나빴고, 미세 조정 뒤에도 네 질문 중 보정이 가장 좋지 않았다. 예상 보정 오차는 0.153으로, 나머지 질문의 0.04~0.05보다 높았다. 구조는 입력 자체에서 더 저렴하게 측정할 수 있어 이 질문을 판정 기준에서 제외했다.

미세 조정은 세 차례 진행했다. 첫 번째는 도구 결과 수천 건에 대해 프런티어 교사 모델 세 개가 질문별로 붙인 라벨을 사용했다. 정확도는 54.5%에서 88.1%로 올랐으며, 질문별 온도 보정으로 보정 오차를 0.04~0.05로 낮췄다. 두 번째에는 BIPIA 형태의 행을 추가했고, 그 절반은 정상 데이터였다. 이 정상 데이터는 BIPIA와 전혀 닮지 않은 입력을 포함해 모델이 전반적으로 성급하게 공격으로 판정하는 경향을 줄였다.

세 번째에는 Detection Isn’t the Hard Part에서 설명한 커넥터 하드 네거티브를 포함한 자체 데이터를 더해 데이터셋을 2.5배로 늘렸다. 처음부터 다시 학습하자 BIPIA AUC가 0.86에서 0.65로 떨어졌다. 재보정으로 해결되지 않았다. 모델이 공격을 정상 텍스트보다 높은 순위에 두지 못해 임계값으로 고칠 수 없었기 때문이다. 추가 데이터는 실제 데이터였고 중복도 제거했지만, 형태가 달랐으며 매 학습 에포크에서 모델이 보는 인젝션 신호의 비중은 이전의 약 40%로 줄었다.

해결책은 처음부터 재학습하는 대신 이전 체크포인트에서 학습을 이어가고, 기존 학습 분할 데이터도 새 행과 함께 다시 사용하는 것이었다. 이 방식으로 BIPIA AUC는 0.86으로 돌아왔고, 오탐 벤치마크의 커넥터 입력은 하나도 공격으로 표시하지 않았다.

이어 학습한 모델은 보정도 다시 확인해야 했다. 새 모델에 맞춘 온도는 2.2~4.8로 이전 값의 대략 두 배였고, 이를 전부 적용하면 내부 벤치마크 재현율이 72%에서 33%로 떨어졌다. 보정량의 4분의 1만 적용하는 T' = 1 + 0.25 × (T − 1) 방식은 재현율 손실 없이 오탐 감소 효과 대부분을 유지했다. StackOne은 이어서 미세 조정할 때마다 온도를 다시 맞추고 보정 오차뿐 아니라 재현율도 확인하라고 권했다.

추론 속도 개선과 현재 상태

첫 배포는 L4에서 초당 8건을 처리했다. 배치 경로에서 자동 혼합 정밀도(autocast)를 건너뛰는 버그를 고쳐 모델을 fp32 대신 다른 정밀도로 실행하자 처리량은 초당 18.5건이 됐다. Jev 계열 의사결정 모델용 vllm-jev 엔진으로 바꾼 뒤에는 약 33건에 도달했다. 같은 GPU에서 TensorRT도 시험했지만 초당 28.5건에 그쳤다. 프로파일링 결과 병목은 vLLM 스케줄러가 아니라 패딩이었다. 길이가 다른 도구 결과를 배치로 묶으면 모든 행을 가장 긴 입력에 맞춰야 해, 요청마다 패딩 비용이 개별 실행보다 커질 수 있다. vLLM은 토큰을 묶어 패딩 비용을 내지 않았다.

요청 자체를 분석하자 더 큰 낭비도 드러났다. 질문마다 별도의 행을 만들어 도구 결과를 질문 수만큼 인코딩했고, 요청당 1,004개 토큰 중 70%가 세 번 반복되는 동일한 상태 텍스트였다. 세 질문의 헤드와 상태 텍스트 한 벌을 하나의 시퀀스에 묶어 요청 길이를 536토큰으로 줄였다.

입력 형식이 바뀌어 모델도 다시 학습해야 했다. 기존 교사 라벨로 재학습한 모델은 AUC가 1포인트 이내로 유지됐지만, 오탐률 1~2%에서 재현율이 11~14포인트 낮아졌다. 기존 모델의 출력 분포로 묶음 입력 모델을 증류하자 추적하는 모든 AUC에서 기존 모델과 같거나 더 나은 결과를 냈다. 오탐률 1%에서 BIPIA 재현율은 유지됐고 AgentDojo에서는 올랐다.

torch.compile, bf16 가중치, 패딩을 약 6%로 제한하는 64토큰 길이 구간을 적용한 묶음 입력 모델은 L4 한 대에서 초당 55.9건을 처리했고, 요청당 GPU 시간은 16ms였다. 같은 카드의 vllm-jev보다 1.7배 빠르며, 구형 T4에서도 초당 36건을 처리했다. StackOne은 증류와 기존 데이터 재사용이 이전 모델이 학습한 함수를 보존하기 때문에 효과가 있었다고 설명했다. 새 라벨만으로는 목표를 설명할 뿐, 모델이 다른 방식으로 그 목표에 도달하는 것을 막지 못한다는 것이다.

StackOne은 현재 의사결정 모델을 Defender의 3단계 인터페이스 뒤에서 초기 시험 중이다. 교체 전에 결과가 반복 학습에서도 유지되는지 확인하고, 공개하지 않은 데이터에서 차단 임계값을 정할 계획이다. 아직 해결하지 못한 주요 문제는 긴 도구 결과로, 더 긴 문맥 창이나 입력을 나눠 읽는 방법이 필요하다.

Defender에서는 3단계 기능을 Deep Scan으로 제공한다. 모델에 관심이 있으면 Deep Scan 접근 요청 양식에서 원하는 실행 위치를 알릴 수 있다. Defender는 오픈소스 저장소로 공개돼 있으며, 3단계는 Tier3Provider 인터페이스를 통해 연결한다. 따라서 자체 판정 모델이나 다른 방식을 사용할 수 있다.