콘텐츠로 이동

결정 모델 (Decision Models)

결정 모델(Decision Model)은 자유 형식의 텍스트를 생성하는 대신, 단일 문서나 상태(state)에 대한 정형화된 질문들을 한 번의 추론(forward pass)으로 평가하고 각 질문에 대한 확률 분포를 반환하는 모델입니다.

Continuum Router는 두 가지 방식으로 결정 모델을 지원합니다.

  • 클라이언트 API 제공: POST /v1/decisions (별칭 POST /v1/systemone) 엔드포인트를 통해 외부 클라이언트에 결정 추론 API를 직접 제공합니다.
  • 내부 라우터 소비자(Consumer): 다음 다섯 가지 내부 기능에서 결정 모델을 호출합니다.
    1. 콘텐츠 안전 스크리닝 (가드레일 프로바이더)
    2. 요청 복잡도 및 도메인 분류 (스마트 라우팅 분류기)
    3. 에이전트 도구 호출 안전성 평가 (Action Safety)
    4. 응답 품질 기반 모델 폴백 (fallback.quality_check, 모델 폴백)
    5. 응답 후 품질 지표 계측 (usage.quality_judgment)

결정 모델이 반환하는 confidence는 출력 확률 분포의 집중도를 나타내는 통계치일 뿐, 실제 운영 환경에서의 정답 확률을 보장하지 않습니다. 따라서 차단이나 강제 라우팅(enforce)으로 전환하기 전에 반드시 자체 데이터셋으로 임계값을 보정(calibration)해야 합니다. 이 문서에 수록된 기본 임계값은 모두 저장소에 커밋된 기준 보정 실행에서 도출되었으며, 측정 정확도가 단순 최빈값 기준선(constant-answer baseline)을 넘지 못한 기능은 기본적으로 모니터링 전용(monitor, shadow, advisory) 모드로 동작합니다.

지원 모델 카탈로그

라우터는 네 가지 프로바이더 프로필(generic, typesafe, foundry, llama_cpp)을 통해 System One 프로토콜을 지원하며(프로바이더 프로필과 실험적 미디어 참고), 호스팅 서비스와 자체 호스팅 오픈 웨이트 모델을 아우르는 내장 메타데이터 카탈로그를 제공합니다.

모델 / 계열 카탈로그 ID 및 체크포인트 실행 환경 (protocol) 지원 기능 및 제약 사항
TypeSafe Jev 1.13 jev-1.13.0 (jev-latest 별칭) TypeSafe 호스팅 (https://api.typesafe.ai/v1/systemone, protocol: typesafe) decisions. 입력 토큰 백만 개당 $0.042, 출력 무료. 요청 64k / 상태+질문 32k 컨텍스트 (typesafe_long_context: true 설정 시 262k). 실험적 이미지 에셋 선택 지원(typesafe_images: true). box 미지원.
TypeSafe Jev 1.14 jev-1.14.0 (jev-preview 별칭) TypeSafe 호스팅 (https://api.typesafe.ai/v1/systemone, protocol: typesafe) decisions. Jev 1.13과 동일한 요금 및 컨텍스트 한도에 더해, typesafe_images: true 설정 시 실험적 이미지 에셋과 box 영역 검출 질문을 지원합니다.
Microsoft-Decision-1 microsoft-decision-1 (Foundry 배포 이름으로 호출) Azure AI Foundry (<resource>/providers/microsoft/v1/systemone, protocol: foundry) decisions. 최대 32K 입력 토큰의 텍스트/JSON 입력, noul, choice, score 질문 지원. api-key (auth: api_key / auto) 또는 Entra Bearer 토큰(auth: entra) 인증.
Laya laya (convaiinnovations/laya, ggml-org/Laya-GGUF) 자체 호스팅 (laya-serve 또는 llama-server, protocol: generic / llama_cpp) decisions. 단일 번들에 세 가지 인코더 체크포인트 포함: english (ModernBERT-large, 512 토큰), multilingual (mmBERT-base, 1,024 토큰), typed-decisions. 기본 laya-serve는 문자 체계(script)를 감지해 english 또는 multilingual로 자동 라우팅합니다.
Kev kev-0.8b, kev-4b (jaredpalmer/kev-0.8b, jaredpalmer/kev-4b, ggml-org/Kev-4B-GGUF) 자체 호스팅 (kev.serve 또는 llama-server, protocol: generic / llama_cpp) decisions. Qwen3.5 베이스 모델 위에 LoRA 어댑터와 포인터 헤드 및 내장 온도(temperature) 스케일링을 결합한 모델입니다. Apple Silicon(MLX) 또는 llama.cpp(GGUF)에서 실행됩니다.
Julia-1 & lev julia-1 (SupersonicLabs/Julia-1, ggml-org/Julia-1-GGUF), lev (interfaze-ai/lev, ggml-org/lev-GGUF) 자체 호스팅 (llama-server, protocol: llama_cpp / generic) decisions (텍스트 전용).
OpenJev openjev (openjev/openjev, ggml-org/OpenJev-GGUF) 자체 호스팅 (llama-server, protocol: llama_cpp) decisions, 이미지 입력 지원. choice 선택지가 최대 52개로 제한됩니다(커스텀 배포 별칭 사용 시 model_family: openjev 지정 필요).
Clef & pplx-decider v1.2 clef (Cloudflare/clef, ggml-org/Clef-GGUF), pplx-decider-v1.2 (perplexity-ai/pplx-decider-v1.2) 자체 호스팅 (llama-server, protocol: llama_cpp) decisions, 이미지 입력 지원. Clef는 질문들을 독립적으로 평가하지 않고 결합하여 평가합니다.
Bespoke Nimble 9B v3 bespoke-nimble-9b-v3 (bespokelabs/Bespoke-Nimble-9B-v3, ggml-org/Bespoke-Nimble-9B-v3-GGUF) 자체 호스팅 (llama-server, protocol: llama_cpp / generic) decisions (choice 및 noul).
vLLM SR Decision 2.0 decision-2.0-{eos-0.8b,kai-0.6b,lux-9b,nox-4b,sol-2b,vega-27b} (vllm-sr/Decision-2.0-*) 자체 호스팅 (llama-server, protocol: llama_cpp / generic) decisions (텍스트 전용). 정규화 엔트로피(normalized-entropy) 기반 confidence를 사용합니다.
vLLM SR d3 d3, d3-{edge,lite,nano,mini,flash} (vllm-sr/d3*, ggml-org/vllm-d3*-GGUF) 자체 호스팅 (llama-server, protocol: llama_cpp) decisions, 이미지/비디오 입력 지원. model_family: vllm_d3 설정(또는 모델 ID 자동 매칭) 시 state: null을 허용합니다.
Liquid AI d1 d1-3b (LiquidAI/d1-3B, LiquidAI/d1-3B-GGUF), d1-omni-600m (LiquidAI/d1-omni-600M, LiquidAI/d1-omni-600M-GGUF) 자체 호스팅 (llama-server, protocol: llama_cpp) decisions. d1-3b는 이미지 입력(model_family: lfm2_d1), d1-omni-600m은 이미지 및 오디오 입력(model_family: lfm2_d1_omni)을 지원하며, 두 모델 모두 state: null을 허용합니다.
IBM Granite Switch 4.1 granite-switch-4.1-8b, granite-switch-4.1-30b (ibm-granite/granite-switch-4.1-*) 자체 호스팅 (llama-server, protocol: llama_cpp) chat 및 decisions 이중 기능, 오디오 입력 지원. 네이티브 결정 추론과 명시적으로 설정된 일반 텍스트 생성에 모두 사용할 수 있습니다.

와이어 프로토콜

POST /v1/decisions (또는 POST /v1/systemone) 요청은 model, 평가 대상 문서인 state(문자열, JSON 객체, JSON 배열, 또는 지원되는 llama_cpp 계열의 경우 null), 그리고 questions 맵을 받습니다. 각 질문은 다음 네 가지 타입 중 하나를 사용합니다.

  • noul: 주어진 명제가 참일 확률(0.0~1.0)을 구하는 이진 판정 질문입니다. 선택적으로 criteria: {"true": ..., "false": ...}를 지정할 수 있습니다.
  • choice: 1~255개의 이름 붙은 선택지(OpenJev는 1~52개)에 대한 확률 분포를 구하며, 최댓값 선택지인 choice, 각 선택지의 probabilities, 선택적 confidence를 반환합니다.
  • score: 순서가 있는 등급(generic, foundry, llama_cpp는 2~10개 등급, typesafe는 1~10개 등급)에 대한 확률 분포를 구하며, 확률 가중 평균 인덱스인 score, 선택적 legend, probabilities, 선택적 confidence를 반환합니다.
  • box: 정규화된 바운딩 박스 좌표(0.0~1.0 범위의 box: {top, bottom, left, right} 및 선택적 confidence)를 반환하며, protocol: typesafe에서 typesafe_images: true와 jev-1.14.0 (jev-preview)을 함께 설정했을 때 사용할 수 있습니다.
{
  "model": "jev-latest",
  "state": {"request": "Write a Rust function that parses a CSV file", "message_count": 1},
  "questions": {
    "domain": {
      "type": "choice",
      "instructions": "What domain does `request` belong to?",
      "criteria": {"general": "...", "code": "...", "reasoning": "..."}
    },
    "complexity": {
      "type": "score",
      "instructions": "How hard is `request`?",
      "criteria": ["trivial", "simple", "moderate", "complex", "expert"]
    }
  }
}

응답에는 요청한 질문 ID별 결과, 실제 처리에 사용된 model 이름, 그리고 usage.input_tokens와 usage.output_tokens가 포함됩니다.

내부 소비자 (Internal Consumers)

Continuum Router는 다음 다섯 가지 내부 기능에서 결정 모델을 호출합니다.

소비자 설정 경로 질의 항목 응답 활용 방식 기본 모드
가드레일 프로바이더 guardrails.providers[].type: systemone 라우터 카테고리 9종(violence, hate_speech, sexual_content, self_harm, harassment, dangerous, jailbreak, pii, profanity) 각각의 noul 질문 + 4단계 severity score 질문 p >= category_thresholds[c]이면 차단(Block), 그 외 p >= review_threshold이면 플래그(Flag, 단 severity >= 2이면 차단으로 격상) mode: monitor
스마트 라우팅 분류기 smart_routing.classifier.method: system_one / hybrid_system_one, 또는 rule / llm / hybrid에서 shadow: true 5단계 complexity (score), 6개 도메인 domain (choice) min(confidence) >= min_confidence이면 결정 모델 결과를 사용하고, 미달 시 규칙 분류기(또는 hybrid_system_one에서는 LLM 분류기)로 폴백 method: rule (섀도 모드는 선택 사항)
Action Safety safeguards.action_safety.evaluator: systemone action (choice: approve / confirm / block), irreversible (noul), injected_instruction (noul) probabilities.block 또는 injected_instruction >= deny_threshold이면 Deny, action == approve이면서 confidence >= min_confidence 및 probabilities.approve >= allow_threshold를 만족하면 Allow, 그 외에는 Indeterminate mode: advisory
응답 품질 폴백 fallback.quality_check 마지막 사용자 메시지와 완료된 비스트리밍 채팅 응답에 대해 answered, refusal, truncated (noul) 질의 1 - answered, refusal, truncated 중 하나라도 threshold 이상이면 폴백 체인의 다음 모델로 재시도 비활성화 (활성화 시 기본값은 mode: shadow)
사용량 품질 판정 usage.quality_judgment 제공된 채팅 응답에 대해 answered, refusal (noul) 질의 + 요청에 문자가 있으면 language_match, include_tool_results: true이고 현재 턴에 도구 결과가 있으면 grounded 추가 질의 클라이언트 응답은 변경하지 않고, 컨트롤 플레인 사용량 레코드에 확률(베이시스 포인트 단위)과 judge_model을 기록하여 Hub에서 비교 분석에 활용 비활성화

각 기능의 상세 설정은 가드레일, System One 분류기, Claude Code 연동, 모델 폴백 문서를 참고하십시오.

결정 호출의 사용량 계측

내부 소비자가 업스트림 서버로 보낸 모든 결정 호출(재시도 포함)은 상위 요청에 연결된 별도의 사용량 레코드로 기록되며, 소비자별로 다음과 같은 purpose 값을 갖습니다.

  • guardrail: System One 가드레일 프로바이더
  • classifier: 스마트 라우팅 분류기
  • action_safety: Action Safety 평가기
  • quality_judgment: usage.quality_judgment 및 fallback.quality_check
  • client: 클라이언트가 직접 호출한 POST /v1/decisions 요청 (아키텍처 문서의 라우터 시작 호출 섹션 참고)

대상 블록의 count_toward_budgets 설정은 smart_routing_system_one_classifier_input_tokens_total 메트릭의 counted 레이블에만 영향을 줍니다.

사용량 품질 판정 (usage.quality_judgment)

usage.quality_judgment는 클라이언트에게 반환된 채팅 응답(비스트리밍 및 스트리밍 모두 포함)을 백그라운드에서 평가하고, 그 확률값(베이시스 포인트 단위)과 판정에 사용된 judge_model을 컨트롤 플레인 사용량 레코드에 첨부합니다. 클라이언트 응답 경로를 지연시키거나 수정하지 않으면서, Continuum Hub에서 모델별·API 키별·실험군별 응답 품질을 비교할 수 있게 해 줍니다.

비동기 실행과 late / skipped 집계 규칙

  • 비차단 백그라운드 실행: 품질 판정은 응답이 끝난 뒤 별도의 비동기 태스크에서 실행되므로, 사용량 집계나 Hub 배치 전송을 블로킹하지 않습니다.
  • late 판정 드롭: 사용량 레코드가 포함된 업로드 배치가 이미 확정(seal)된 뒤에 완료된 판정은 late로 집계되고 버려집니다. 응답이 느린 판정일수록 배치 마감 시각을 넘길 가능성이 높으므로, late 비율이 높으면 빠른 요청 위주로 품질 점수가 편향될 수 있습니다. late 비율을 줄이려면 control_plane.usage_push_interval_secs 주기를 늘리거나 지연 시간이 짧은 자체 호스팅 결정 모델을 사용하십시오.
  • 스트리밍 샘플링: 스트리밍 응답은 입력 가드레일 직후 샘플링 여부를 결정하고, 스트림 종료 시점의 사용량 레코드가 생성되는 즉시 판정을 시작합니다. 메모리에는 클라이언트가 실제로 수신한 텍스트의 앞부분과 뒷부분만 max_reply_bytes 한도 내에서 유지하며, 추론(reasoning) 토큰은 포함하지 않습니다.
  • 통합 stream 레이블: 모든 판정 결과 메트릭(usage_quality_judgments_total)에는 stream="true" 또는 stream="false" 레이블이 기록됩니다.

라우트별 평가 대상 추출 및 제외(skipped) 규칙

라우트 평가되는 사용자 입력 평가되는 어시스턴트 응답 제외(skipped) 또는 미평가 조건
/v1/chat/completions (responses_only 브리지 포함) 마지막 사용자 메시지 (max_request_bytes 기준 앞/뒤 절단). 도구 결과는 include_tool_results: true일 때만 포함. 버퍼링된 응답 텍스트 또는 스트리밍 응답 텍스트의 앞/뒤 일부 (max_reply_bytes 한도). 추론(reasoning) 텍스트는 제외. 입력 가드레일에서 차단된 요청(샘플링 제외), 출력 가드레일이 차단한 응답, 출력 가드레일이 마스킹하거나 중단한 스트리밍 응답, 스트림 도중 폴백 홉이 발생해 두 생성이 이어 붙은 응답, 스트림 오류/타임아웃, 스트림 종료 전 클라이언트 연결 종료, disaggregated_serving 및 Dynamo shim 경유 요청, 네이티브 Anthropic/Gemini/Bedrock 또는 Unix 소켓을 통한 스트리밍 채팅, 스트리밍 응답 캐시 재생. (단, 버퍼링된 응답이 출력 가드레일에 의해 마스킹된 경우에는 클라이언트가 받은 마스킹된 텍스트를 기준으로 판정합니다.)
/anthropic/v1/messages (네이티브 HTTP/Unix, Bedrock mantle/runtime/converse, OpenAI/Gemini 변환, responses_only 등 모든 백엔드 경로) tool_result가 없고 <system-reminder> 블록을 제외한 본문이 비어 있지 않은 마지막 role: user 메시지. 최상위 system 필드와 role: system 메시지는 읽지 않으며, tool_result 내용은 include_tool_results: true일 때만 포함. 클라이언트가 수신한 text 블록들을 이어 붙인 텍스트 (thinking 블록은 제외). stop_reason: max_tokens 응답은 정상 판정. tool_use 또는 server_tool_use 블록을 포함한 응답, stop_reason: pause_turn, 스트림 error 이벤트 발생 또는 스트림 종료 전 클라이언트 이탈, web_search_20250305 서버 도구 에뮬레이션, 응답 캐시 히트.
/v1/responses (OpenAI/Azure 패스스루, responses_only, Chat/Anthropic/Gemini 변환 등 모든 전략) 하니스 주입 텍스트(<system-reminder>, <user_instructions>, <environment_context>, # AGENTS.md instructions)를 제외하고 본문이 남아 있는 현재 요청 input 내의 마지막 사용자 메시지(또는 단일 text 아이템). previous_response_id 연쇄 요청도 저장된 이전 이력이 아닌 현재 요청의 input만 사용. instructions, system, developer, 추론 아이템은 읽지 않으며 function_call_output은 include_tool_results: true일 때만 포함. message 아이템의 output_text 파트들을 이어 붙인 텍스트(텍스트가 없으면 refusal 파트). 스트리밍 응답은 종료 이벤트(response.completed 또는 response.incomplete)에서 추출. status: incomplete(예: max_output_tokens)은 정상 판정. input에 function_call_output 아이템만 있는 요청, 마지막 사용자 턴 뒤에 item_reference가 있는 요청, function_call·custom_tool_call·computer_call·local_shell_call 아이템을 포함한 응답, status: failed 또는 cancelled, 응답 캐시 히트, /v1/responses/compact.
그 외 라우트 해당 없음 해당 없음 /v1/completions는 평가하지 않습니다.

전체 설정 구문은 전체 설정 예제의 usage 블록을 참고하십시오.

fallback.quality_check와의 결정 호출 공유

비스트리밍 /v1/chat/completions 요청에서 다음 세 가지 조건이 모두 충족되면, fallback.quality_check와 usage.quality_judgment는 결정 모델을 두 번 호출하지 않고 한 번의 호출 결과를 공유합니다.

  1. 두 기능이 모두 활성화되어 있고 동일한 target 블록을 지정한 경우
  2. 두 기능의 max_request_bytes 및 max_reply_bytes 설정값이 동일한 경우
  3. 현재 요청이 usage.quality_judgment로 도구 결과를 보내지 않는 경우 (include_tool_results: false이거나 현재 턴에 도구 결과가 없는 경우)

호출 공유 시 동작 방식은 다음과 같습니다.

  • fallback.quality_check가 초기 응답을 검사할 때 answered, refusal, truncated와 함께 language_match(해당되는 경우)를 동일한 요청에 포함해 질의합니다. 이때 language_match 응답이 누락되거나 형식이 잘못되더라도 폴백 판정 자체는 실패하지 않습니다.
  • 초기 응답이 품질 검사를 통과해 그대로 반환되면, usage.quality_judgment는 별도의 호출이나 max_in_flight 슬롯을 소비하지 않고 즉시 해당 응답 확률을 재사용합니다. 핸들러가 반환되는 시점에 이미 판정값이 준비되어 있으므로 late 누락도 발생하지 않습니다.
  • 만약 공유 호출 응답에서 사용량 판정에 필요한 일부 질문의 답이 빠졌다면, usage.quality_judgment는 누락된 질문만 별도로 재질의하여 병합합니다(단, 재질의에서 다른 judge_model이 반환되면 invalid로 처리하고 버립니다).
  • fallback.quality_check가 품질 미달로 판단해 다음 폴백 모델로 홉(hop)한 경우, usage.quality_judgment는 추가 호출 없이 skipped로 기록합니다.
  • 폴백 체인에 다음 후보가 없거나 예산 소진·호출 실패 등으로 fallback.quality_check가 실행되지 않은 경우에는 usage.quality_judgment가 평소처럼 독립적인 백그라운드 호출을 수행합니다.
  • 공유된 호출은 systemone_requests_total{consumer="fallback_quality"}로 집계되며, usage_quality_judgments_total{outcome}에는 샘플링된 요청당 하나의 결과가 그대로 기록됩니다.

클라이언트 결정 엔드포인트 제공 (/v1/decisions)

클라이언트는 라우터의 API 키 인증, 스코프, 속도 제한, 예산, 폴백 체인 정책 아래에서 POST /v1/decisions (별칭 POST /v1/systemone)를 직접 호출할 수 있습니다.

  • 네이티브 전달: 요청한 model이 decisions.targets[]에 등록되어 있으면 해당 System One 서버로 요청을 직접 전달합니다.
  • 채팅 모델 에뮬레이션: decisions.targets[]에 없는 모델 이름은 일반 채팅 모델에서 강제 도구 호출(emit_decision)을 통해 에뮬레이션됩니다. 에뮬레이션 응답은 원-핫(one-hot) 확률 분포를 반환하고 confidence를 생략하며, 호출자가 네이티브 확률 분포와 구분할 수 있도록 emulated: true를 표시합니다.

이 엔드포인트는 순수 프록시/에뮬레이터로 동작하며 라우터 내부 소비자의 임계값을 적용하지 않습니다. 자세한 요청/응답 스키마는 API 레퍼런스를 참고하십시오.

데이터 외부 전송(Egress) 및 운영 시 주의 사항

  • 데이터 외부 전송(Egress): 모든 결정 호출은 요청에서 추출한 텍스트로 state 객체를 구성해 전송합니다.
    • 가드레일: 마지막 사용자 턴과 길이 제한이 적용된 최근 대화 이력(history_turns, max_turn_bytes).
    • 스마트 라우팅 분류기: 마지막 사용자 메시지와 시스템 프롬프트 앞부분 200자. /v1/chat/completions에서는 섀도 모드를 포함해 항상 입력 가드레일 단계 이후에 분류기 state를 구성하므로, 차단된 프롬프트는 전송되지 않고 마스킹된 프롬프트는 마스킹된 상태로 전송됩니다.
    • Action Safety: 실행하려는 도구 이름, 전체 인자(arguments), 사용자의 최신 지시문.
    • 응답 품질 폴백 및 사용량 품질 판정: 앞/뒤 길이 제한이 적용된 마지막 사용자 메시지와 어시스턴트 응답(usage.quality_judgment는 include_tool_results: true일 때만 현재 턴의 도구 결과를 추가).
    • 프롬프트나 응답 데이터를 외부 서드파티(예: 호스팅 TypeSafe Jev)로 전송할 수 없는 환경에서는 모든 소비자의 대상을 자체 호스팅 서버로 지정해야 합니다.
  • 적대적 공격에 대한 한계: 결정 모델은 빠른 1차 스크리닝 및 관측 신호용 도구이며, 단독으로 적대적 탈옥 공격을 방어하는 용도가 아닙니다. 가드레일 보정 코퍼스 측정에서도 기본 Laya 체크포인트는 0.5 임계값 기준 대부분의 카테고리에서 단순 최빈값 기준선 이하의 점수를 기록했고, 비라틴 문자 텍스트를 높은 신뢰도로 오분류하는 경향을 보였습니다. enforce 경로에서는 결정 모델을 단독 차단기로 쓰지 말고 Llama Guard나 Qwen3Guard 같은 전용 안전 모델과 함께 배치하십시오.
  • 언어 및 문자 체계(Script) 민감도: Laya의 english 체크포인트는 한글 등 비라틴 문자를 읽지 못합니다. 기본 laya-serve는 비라틴 문자 입력을 multilingual 체크포인트로 보내는데, 이 체크포인트는 영어와 한국어 라우팅 정확도가 상대적으로 낮습니다. 운영 적용 전에 반드시 영어(en), 한국어(ko), 비라틴(non_latin) 슬라이스를 각각 분리해 측정하십시오.

결정 모델 적합성 가이드

질문 유형 결정 모델 사용 권장 여부 이유
state 안에 판단 근거가 명확히 존재하는 닫힌 기준 (예: "이 도구 호출이 작업 디렉터리 밖의 파일을 수정하는가?", "코드 작성 요청인가?") 권장 (Yes) 결정 모델이 학습된 본래 목적에 부합하며, 정답 레이블과 대조해 임계값을 객관적으로 보정할 수 있습니다.
고정된 카테고리 목록에 대한 모니터링 및 검토 큐 분류 권장 (monitor 모드) 출력이 확률값이므로 자체 트래픽 보정을 거쳐 플래그(검토) 구간과 차단 구간을 유연하게 설정할 수 있습니다.
열린 평가 기준 (예: "이 답변이 전반적으로 훌륭하고 유용한가?") 비권장 (No) 참/거짓을 가를 명확한 기준이 없으므로 일반 채팅 LLM 심사 모델(LLM-as-a-Judge)이나 사람의 평가가 적합합니다.
다단계 인과관계 추론 (예: "이전 턴의 도구 실행 결과 때문에 이번 호출이 발생했는가?") 비권장 (No) 결정 모델의 state는 단일 단계만 담으므로, Action Safety 평가기는 현재 제안된 단일 행동만 평가합니다.
다른 생성 모델의 실패 예측 (예: "모델 X가 이 프롬프트에 틀린 답을 낼 것인가?") 비권장 (No) 결정 모델은 타 모델의 능력 한계를 알 수 있는 신호를 갖고 있지 않습니다. 대신 프롬프트 자체의 복잡도와 도메인을 분류하십시오.

프로바이더 프로필과 실험적 미디어

각 System One 대상 블록에서는 모델 별칭과 무관하게 protocol 필드(generic, typesafe, foundry, llama_cpp)로 와이어 프로필을 명시적으로 선택합니다.

  • generic (기본값): 텍스트 전용 System One 기본 계약입니다.
  • typesafe: TypeSafe의 구조화된 질문 스키마와 선택적 기능 헤더(typesafe_images, typesafe_long_context)를 활성화합니다.
  • foundry: Azure AI Foundry의 프로바이더 경로(/providers/microsoft/v1/systemone)와 배포 이름 체계를 사용합니다.
  • llama_cpp: llama-server의 인라인 멀티모달 데이터 URL 및 모델 계열별 제약(model_family)을 활성화합니다.
decisions:
  enabled: true
  targets:
    - name: jev
      protocol: typesafe
      endpoint: https://api.typesafe.ai/v1/systemone
      api_key_env: TYPESAFE_API_KEY
      model: jev-1.14.0
      typesafe_images: false         # JSON assets 및 Box 질문 사용 시 true
      typesafe_long_context: false   # 장문 컨텍스트 개별 옵트인
    - name: microsoft-decision
      protocol: foundry
      endpoint: https://RESOURCE.services.ai.azure.com
      auth: api_key                 # auto 설정 시에도 Foundry는 api-key를 선택함
      api_key_env: AZURE_FOUNDRY_API_KEY
      model: support-decisions      # 카탈로그 별칭이 아닌 Foundry 배포 이름
    - name: local-decision
      protocol: llama_cpp
      endpoint: http://127.0.0.1:8080/v1/systemone
      model: local-decision
      model_family: generic         # openjev 지정 시 52개 choice 상한 적용

대상 설정 레퍼런스 (SystemOneTargetConfig)

decisions.targets[], guardrails.providers[].systemone, smart_routing.classifier.system_one, safeguards.action_safety.systemone, fallback.quality_check.target, usage.quality_judgment.target은 모두 아래의 동일한 대상 스키마를 공유합니다.

필드 타입 기본값 설명
endpoint string 미설정 결정 엔드포인트의 전체 HTTP(S) URL (backend와 동시 사용 불가). URL 내에 자격 증명, 쿼리 문자열, 프래그먼트를 포함할 수 없습니다. generic, typesafe, llama_cpp 프로필은 allow_custom_endpoint_path: true가 아닌 한 경로가 /v1/systemone으로 끝나야 합니다. foundry 프로필은 리소스 루트, /providers/microsoft, /providers/microsoft/v1, /providers/microsoft/v1/systemone을 모두 /providers/microsoft/v1/systemone으로 정규화합니다.
backend string 미설정 auth.type: api_key 또는 basic과 http(s) URL로 설정된 자체 호스팅 backends[] 항목의 이름 (vllm, sglang, tensorrt-llm, ollama, lmstudio, llamacpp, mlxcel, generic, continuumrouter). endpoint 및 api_key_env와 함께 쓸 수 없으며, protocol: foundry에서는 지원하지 않습니다.
protocol string generic 와이어 프로필: generic, typesafe, foundry, llama_cpp.
auth string auto 인라인 endpoint 대상의 인증 방식: auto(foundry는 api_key, 그 외에는 bearer), bearer, api_key(api-key: <secret> 헤더, foundry 전용), entra(api_key_env의 토큰을 Authorization: Bearer <token>으로 전송, foundry 전용). backend 참조 시에는 반드시 auto여야 합니다.
api_key_env string 미설정 인라인 endpoint에 사용할 시크릿/토큰이 담긴 환경 변수 이름(실제 시크릿 값을 직접 적지 않음). backend 설정 시에는 사용할 수 없습니다.
model string typesafe / *.typesafe.ai는 jev-latest, 그 외에는 미설정 요청 본문에 담아 보낼 모델 또는 배포 ID. protocol: foundry에서는 필수이며 운영자의 Foundry 배포 이름이어야 합니다.
model_family string generic protocol: llama_cpp에서 커스텀 배포 별칭 뒤에 실제 체크포인트 계열을 명시할 때 사용: generic, openjev(choice 52개 상한), lfm2_d1, lfm2_d1_omni, vllm_d3(마지막 세 계열은 state: null 허용). llama_cpp 외의 프로필에서는 거부됩니다.
typesafe_images boolean false protocol: typesafe 필요. 최상위 JSON assets 맵을 허용하고 TypeSafe-Danger-Zone-Images: true 헤더를 전송합니다. box 질문을 쓰려면 model도 jev-1.14.0 또는 jev-preview여야 합니다.
typesafe_long_context boolean false protocol: typesafe 필요. TypeSafe-Danger-Zone-Long-Context: true 헤더를 전송하여 TypeSafe 컨텍스트 한도를 64k/32k에서 262k로 확장합니다.
max_questions integer 64 네이티브 결정 호출당 최대 질문 개수 (1~256).
max_state_bytes integer 16384 내부 소비자의 직렬화된 state 최대 크기 (256~1048576 바이트).
max_media_bytes integer 4194304 요청당 디코딩된 인라인 미디어의 총 바이트 한도 (1~16777216 바이트, 기본값 4 MiB, 최대 16 MiB. 공개 /v1/decisions 경로에서는 2 MiB JSON 본문 상한도 함께 적용됨).
timeout_ms integer 1500 1회 재시도를 포함한 호출당 전체 제한 시간 (100~60000 밀리초).
max_concurrent integer 32 해당 대상으로 동시에 보낼 수 있는 최대 진행 중 결정 호출 수 (1~1024).
count_toward_budgets boolean false smart_routing_system_one_classifier_input_tokens_total 메트릭의 counted 레이블 값을 제어합니다.
allow_custom_endpoint_path boolean false Foundry가 아닌 프로필에서 /v1/systemone으로 끝나지 않는 커스텀 인라인 endpoint 경로를 허용합니다.

프로바이더 프로필 비교

프로필 엔드포인트 및 전송 규칙 인증 헤더 질문 및 스키마 규칙 미디어 및 특수 state
generic /v1/systemone으로 끝나는 http(s) URL (또는 backend: 참조) Authorization: Bearer <key> (또는 백엔드 인증 설정) 문자열 instructions 필수, choice 1~255개, score 2~10개 등급 텍스트/JSON state만 허용 (null 상태 및 미디어 필드 거부)
typesafe typesafe.ai 및 하위 도메인은 https:// 필수 (커스텀 게이트웨이는 스킴 유지) Authorization: Bearer <key> + 선택적 TypeSafe-Danger-Zone-Images: true / TypeSafe-Danger-Zone-Long-Context: true 구조화된 값(string/object/array), null, 생략된 instructions·noul 기준·choice 설명·score 등급 보존, score 1~10개 등급, jev-1.14.0 / jev-preview에서 box 지원 typesafe_images: true일 때 최상위 base64 이미지 assets 맵 지원
foundry 인라인 endpoint 전용 (루프백 localhost, 127/8, ::1 외에는 https:// 필수), /providers/microsoft/v1/systemone으로 정규화 api-key: <key> (auth: api_key 또는 auto) 또는 Authorization: Bearer <token> (auth: entra) 구조화된 값/null/생략 필드 보존, choice 1~255개, score 2~10개 등급, 명시적 model 배포 이름 필수 텍스트/JSON state만 허용
llama_cpp /v1/systemone으로 끝나는 http(s) URL (또는 backend: 참조) Authorization: Bearer <key> (또는 백엔드 인증 설정) 구조화된 값/null/생략 필드 보존, choice 1~255개 (openjev는 1~52개), score 2~10개 등급 최상위 files / images 데이터 URL 배열 또는 멀티모달 메시지 state(이미지/오디오 데이터 URL) 지원, lfm2_d1·lfm2_d1_omni·vllm_d3는 state: null 허용

프로필별 세부 규칙 및 요청 예시

Foundry 인증 및 전송 규칙

  • 엔드포인트 정규화: 리소스 루트, /providers/microsoft, /providers/microsoft/v1, /providers/microsoft/v1/systemone은 모두 /providers/microsoft/v1/systemone으로 정규화됩니다. Foundry 프로필은 인라인 endpoint만 허용하며 backend: 참조는 거부합니다. 원격 엔드포인트는 반드시 HTTPS를 사용해야 하며, HTTP는 로컬 개발 및 테스트용 루프백 호스트(localhost, 127.0.0.0/8, ::1)에서만 허용됩니다.
  • Entra 토큰 수명 주기: auth: entra는 클라이언트를 생성할 때 api_key_env 환경 변수에서 외부 발급 Entra 토큰을 읽어 Bearer 헤더로 전송합니다. 라우터가 직접 토큰을 발급받거나 자동 갱신하지 않으며, 만료된 토큰으로 인한 HTTP 401/403 응답은 재시도하지 않고 즉시 실패 처리합니다.

페이로드 크기 제한 및 TypeSafe box / assets

  • 구조적 안전 한도: 개별 문자열 필드는 최대 8 KiB, JSON 중첩 깊이는 최대 64단계, score 등급은 최대 10개로 제한됩니다. 공개 엔드포인트(/v1/decisions)는 압축되지 않은 JSON을 최대 2 MiB까지 허용하며, 멀티파트 요청이나 압축된 요청 본문은 HTTP 415로 거부합니다.
  • TypeSafe 이미지 및 box: typesafe_images: true를 설정하면 인라인 assets 맵을 사용할 수 있고 TypeSafe-Danger-Zone-Images: true 헤더가 전송됩니다. box 질문은 여기에 더해 model이 jev-1.14.0 또는 jev-preview로 명시되어야 합니다. 운영자가 비활성화한 기능을 클라이언트가 임의 헤더를 보내 활성화할 수는 없습니다.
{
  "model": "jev",
  "state": {"photo": "asset-photo-1"},
  "assets": {
    "asset-photo-1": {
      "type": "image",
      "format": "png",
      "data_base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
    }
  },
  "questions": {
    "location": {
      "type": "box",
      "instructions": "Locate the red rectangle in photo."
    }
  }
}

box 응답은 0.0~1.0으로 정규화된 좌표(top, bottom, left, right)와 선택적 confidence를 반환합니다.

{
  "model": "jev-1.14.0",
  "answers": {
    "location": {
      "type": "box",
      "box": {"top": 0.12, "bottom": 0.64, "left": 0.2, "right": 0.85},
      "confidence": 0.91
    }
  },
  "usage": {"input_tokens": 310, "output_tokens": 12}
}

llama.cpp 멀티모달 입력

protocol: llama_cpp는 max_media_bytes(기본값 4 MiB, 최대 16 MiB) 한도 내에서 인라인 files/images 데이터 URL 또는 이미지/오디오 데이터 URL이 포함된 멀티모달 메시지 state를 허용합니다. 외부 http(s) 미디어 URL이나 로컬 파일 시스템 경로, 네이티브 비디오 전송은 거부됩니다.

{
  "model": "local-decision",
  "state": "Does this receipt show a total above $50?",
  "images": [
    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
  ],
  "questions": {
    "over_fifty": {"type": "noul", "instructions": "Is the receipt total above $50?"}
  }
}

모델 탐색, 폴백 및 사용량 회계

  • 모델 탐색 (/v1/models): 모델 페처는 TypeSafe의 GET /v1/models 응답 형식과 llama.cpp의 architecture.output_modalities 배열을 모두 정규화합니다. output_modalities에 "decisions"가 있으면 decisions 기능을 부여하고, Granite Switch 4.1처럼 "text"와 "decisions"를 모두 광고하는 모델에는 chat과 decisions 기능을 모두 유지합니다.
  • 폴백 및 에뮬레이션 검증: 모든 폴백 홉마다 프로필 호환성을 검사합니다. 이미지 에셋, state: null, box 질문을 포함한 요청은 호환되지 않는 프로필이나 텍스트 전용 채팅 에뮬레이션으로 폴백할 수 없습니다. 카탈로그에서 decisions 전용인 모델은 반드시 네이티브 대상이 설정되어야 하며 채팅 에뮬레이션으로 대체되지 않습니다.
  • 토큰 회계: 프로바이더의 출력 토큰 단가가 무료($0)이더라도 응답과 통계에는 반환된 input_tokens와 output_tokens가 모두 그대로 기록되며, 요금 계산 단계에서만 출력 단가 0원이 적용됩니다. 응답에 confidence가 없을 때 임의의 값을 만들어내지 않으며, confidence를 요구하는 내부 소비자는 보수적으로 폴백합니다.

스마트 라우팅 분류기 단계적 도입 (Rollout)

스마트 라우팅 분류기는 smart_routing.classifier.system_one 아래에서 동일한 프로바이더 프로필을 사용합니다. 실제 라우팅 결정을 넘기기 전에 안전하게 검증하려면 method: rule(또는 llm / hybrid)을 유지한 채 shadow: true로 시작하십시오.

# TypeSafe Jev (보정된 특정 버전을 고정)
smart_routing:
  classifier:
    method: rule
    system_one:
      shadow: true
      protocol: typesafe
      endpoint: https://api.typesafe.ai/v1/systemone
      api_key_env: TYPESAFE_API_KEY
      model: jev-1.14.0
# Microsoft-Decision-1 (model에는 Foundry 리소스의 배포 이름 지정)
smart_routing:
  classifier:
    method: rule
    system_one:
      shadow: true
      protocol: foundry
      endpoint: https://RESOURCE.services.ai.azure.com
      auth: api_key
      api_key_env: AZURE_FOUNDRY_API_KEY
      model: support-decisions
# 네이티브 llama.cpp (서버에 설정된 모델 별칭 지정)
smart_routing:
  classifier:
    method: rule
    system_one:
      shadow: true
      protocol: llama_cpp
      endpoint: http://127.0.0.1:8080/v1/systemone
      model: kev-local

주요 동작 규칙:

  • 섀도 측정: 섀도 모드는 실제 생성 모델 선택을 바꾸지 않으면서 활성 분류기와의 일치율(smart_routing_shadow_agreement_total{field, agree}), 지연 시간, 토큰 사용량(purpose: classifier)을 기록합니다.
  • 결정론적 폴백: method: system_one에서 응답 실패, 타임아웃, confidence 누락, 또는 min(confidence) < min_confidence가 발생하면 규칙 분류기 결과로 폴백합니다. method: hybrid_system_one에서는 신뢰도가 낮을 때 설정된 LLM 분류기를 먼저 시도하고, 그마저 실패하면 규칙 분류기 결과를 사용합니다.
  • 생성 후보 풀 필터링: text/chat 기능 없이 decisions만 지원하는 모델은 티어 프로필에 이름을 올리더라도 생성 후보 풀에서 자동 제외되며, GET /admin/smart-routing/status의 excluded_incompatible_models에 별도로 집계됩니다.
  • 캐시 무효화: 분류기 캐시 키에는 상태 텍스트, 대상 프로필, 요청 모델, 질문 묶음, 백엔드 토폴로지 세대(cache_target_identity)가 모두 포함되므로, 백엔드 비활성화나 자격 증명 회전 시 이전 캐시가 자동으로 무효화됩니다.

자체 트래픽에서 결정 모델 보정하기

결정 모델이 보고하는 confidence는 보정되지 않은 분포 집중도 통계치이므로, 운영 트래픽에서 enforce나 실제 라우팅을 켜기 전에 아래 절차에 따라 자체 코퍼스와 엔드포인트를 대상으로 보정을 수행해야 합니다.

1. 엔드포인트 기동

기본 설정인 make calibrate-systemone은 deploy/docker-compose.systemone.yml에 정의된 자체 호스팅 CPU laya-serve 컨테이너(Laya 체크포인트 3종 사전 로드, 127.0.0.1:8000 바인딩)를 자동으로 띄웁니다.

특정 Laya 체크포인트 하나만 고정해서 측정하거나 Kev 서버를 측정하려면 직접 엔드포인트를 먼저 기동하십시오.

# 단일 Laya 체크포인트 고정 실행 (기본 laya-serve는 문자 체계로 자동 라우팅함)
uv run --no-project --with 'laya-serve[inference]==0.1.1' \
  python scripts/systemone/laya_pinned_serve.py --checkpoint english --device cpu --port 8011

# Kev 서버 실행 (Apple Silicon에서는 MLX 자동 사용)
git clone https://github.com/jaredpalmer/kev && cd kev
uv sync --extra serve && uv run python -m kev.serve --run jaredpalmer/kev-0.8b --port 8008

2. 보정 실행

# 기본 compose 서비스(CPU)를 대상으로 세 소비자 전체 보정 및 임계값 도출
make calibrate-systemone

# 가장 작은 라우팅 코퍼스(200행)만 실행
SYSTEMONE_CONSUMERS=routing make calibrate-systemone

# 다른 엔드포인트를 대상으로 실행 (API 키는 SYSTEMONE_API_KEY_ENV에 지정한 환경 변수에서 읽음)
SYSTEMONE_ENDPOINT=http://127.0.0.1:8008/v1/systemone SYSTEMONE_RUN_LABEL=kev-0.8b \
SYSTEMONE_MODEL=kev-latest SYSTEMONE_CHECKPOINT=jaredpalmer/kev-0.8b \
SYSTEMONE_CHECKPOINT_REVISION=54f4f8777356cd5bbbb6c6919c657f26e6f2f6d8 \
  make calibrate-systemone

make calibrate-systemone은 scripts/systemone/calibrate-compose.sh를 통해 tests/systemone_calibration_test.rs의 소비자별 보정 테스트를 실행하고, 원시 응답과 도출된 임계값(derived.json)을 tests/fixtures/systemone/calibration/<date>/<label>/(또는 SYSTEMONE_REPORT_DIR)에 기록합니다. 동시성, 타임아웃, 실행 행 수는 SYSTEMONE_CONCURRENCY(기본값 1), SYSTEMONE_TIMEOUT_SECS(기본값 120), SYSTEMONE_LIMIT 환경 변수로 조절할 수 있습니다.

전체 코퍼스를 돌리지 않고 실제 엔드포인트의 최소 연동만 빠르게 확인하려면 다음 스모크 테스트를 실행하십시오.

SYSTEMONE_SMOKE_ENDPOINT=http://127.0.0.1:8000/v1/systemone \
SYSTEMONE_SMOKE_MODEL=laya-english \
SYSTEMONE_SMOKE_PROFILE=generic \
  cargo test --test systemone live_smoke_test::configured_native_endpoint_answers_a_text_decision -- --ignored --exact

3. 임계값 도출 규칙

tests/systemone_support/derive.rs는 고정된 격자(grid)를 탐색하여 최소 근거 요건을 만족하는 보수적인 임계값을 도출하며, 요건을 충족하지 못하면 벤더 기본값을 유지합니다.

  • 가드레일 category_thresholds.<c> (차단): 양성 레이블이 최소 5개 이상이고 예측된 차단이 최소 3건 이상일 때, 차단 정밀도(precision)가 0.90 이상에 도달하는 0.50..=0.95(간격 0.05) 구간 내 최소 임계값.
  • 가드레일 review_threshold (플래그): 비안전 행에 대한 행 단위 재현율(recall)을 0.90 이상으로 유지하는 0.05..=0.50 구간 내 최대 임계값.
  • 분류기 min_confidence: 0.00..=1.00 구간에서 system_one -> rule 폴백 체인의 domain 및 complexity 평균 정확도를 극대화하는 임계값(동률 시 더 높은 임계값 선택). 어떤 임계값에서도 규칙 분류기 단독 정확도를 넘지 못하면 값을 도출하지 않습니다.
  • Action Safety: action 선택 정확도가 최빈값 기준선을 넘는 경우에만 도출합니다. deny_threshold는 최소 3건 이상의 거부에서 거부 정밀도 0.90을 달성하는 0.30..=0.95 내 최소값이며, allow_threshold와 min_confidence는 block 레이블 오허용 0건, 허용 정밀도 0.95 이상, 최소 5건 이상 허용 조건에서 허용 건수를 극대화하는 조합입니다.

제공 기본값

아래 기본값은 기준 실행인 2026-09-24/laya-serve-compose-cpu(CPU 환경의 기본 laya-serve 0.1.1, Laya 번들 리비전 55cf4c4ebb4e, all 슬라이스)에서 도출되었습니다. tests/systemone_calibration_test.rs의 shipped_defaults_match_the_reference_run_and_the_docs 테스트가 라이브러리 상수와 영문/국문 문서의 이 표가 일치하는지 자동으로 검증합니다.

설정 기본값 출처
guardrail.review_threshold 0.40 laya-serve-compose-cpu에서 도출: 0.40에서 행 재현율 0.913 (기존 0.35)
guardrail.category_thresholds.violence 0.75 laya-serve-compose-cpu에서 도출: 0.75에서 차단 정밀도 0.90 도달 (기존 0.70)
guardrail.category_thresholds.hate_speech 0.70 vendor 값: 실행에서 차단 정밀도가 0.90에 도달하지 않음
guardrail.category_thresholds.sexual_content 0.70 vendor 값: 양성 레이블 4개로 최소 요건인 5개 미만
guardrail.category_thresholds.self_harm 0.70 vendor 값: 실행에서 차단 정밀도가 0.90에 도달하지 않음
guardrail.category_thresholds.harassment 0.70 vendor 값: 실행에서 차단 정밀도가 0.90에 도달하지 않음
guardrail.category_thresholds.dangerous 0.70 vendor 값: 실행에서 차단 정밀도가 0.90에 도달하지 않음
guardrail.category_thresholds.jailbreak 0.70 vendor 값: 실행에서 차단 정밀도가 0.90에 도달하지 않음
guardrail.category_thresholds.pii 0.70 vendor 값: 실행에서 차단 정밀도가 0.90에 도달하지 않음
guardrail.category_thresholds.profanity 0.70 vendor 값: 실행에서 차단 정밀도가 0.90에 도달하지 않음
classifier.min_confidence 0.15 laya-serve-compose-cpu에서 도출: 0.15에서 체인 정확도 0.510, 0.5에서 0.460, 규칙 단독 0.475 (기존 0.5)
action_safety.allow_threshold 0.85 vendor 값: action 정확도 0.319가 기준선 0.440 미만이어서 도출 값 없음
action_safety.deny_threshold 0.60 vendor 값: action 정확도 0.319가 기준선 0.440 미만이어서 도출 값 없음
action_safety.min_confidence 0.6 vendor 값: action 정확도 0.319가 기준선 0.440 미만이어서 도출 값 없음

각 항목은 guardrails.providers[].options.review_threshold, guardrails.providers[].category_thresholds, smart_routing.classifier.system_one.min_confidence, safeguards.action_safety.systemone.{allow_threshold, deny_threshold, min_confidence}에 대응하며, 설정 파일에 명시한 값이 항상 우선합니다.

모니터 전용 판정

기준 실행(laya-serve-compose-cpu)에서 측정 정확도가 최빈값 기준선 이하인 기능이나 언어 슬라이스는 임계값과 관계없이 모니터링 전용 모드를 기본값으로 유지합니다.

  • 가드레일 (모든 슬라이스에서 mode: monitor 권장): 도출된 기본값에서도 정상(clean) 행의 70.8%가 플래그 또는 차단되며(all 슬라이스, 차단 정밀도 0.652), 한국어(ko)와 비라틴(non_latin) 슬라이스에서는 정상 행의 92% 이상이 플래그됩니다. 기본값인 mode: monitor를 유지하고 카테고리별 점수를 보조 관측 신호로 활용하십시오.
  • 스마트 라우팅 분류기 (한국어/비라틴 트래픽은 shadow: true 권장): 전체(all) 및 영어(en) 슬라이스에서는 min_confidence: 0.15를 적용한 system_one + rule 체인이 규칙 분류기 단독보다 높은 정확도를 보입니다(en: 0.628 대 0.544, all: 0.510 대 0.475). 반면 한국어(ko: 0.405 대 0.487)와 비라틴(non_latin: 0.418 대 0.428) 슬라이스에서는 Laya가 규칙 분류기를 넘지 못하므로, 한국어 비중이 높은 환경에서는 한국어 성능이 검증된 모델(예: kev-0.8b, 한국어 체인 정확도 0.639)을 쓰지 않는 한 method: rule과 shadow: true를 유지하는 것이 안전합니다.
  • Action Safety (mode: advisory 권장): tool_calls.jsonl에서 action 정확도가 0.319로 최빈값 기준선(0.440)에 미치지 못하므로 기본값인 mode: advisory를 유지하십시오.
  • 미측정 대상 및 소비자: 호스팅 TypeSafe Jev, Microsoft-Decision-1, kev-4b, 그리고 fallback.quality_check(기본 임계값 0.8, mode: shadow)는 오프라인 기준 실행에 포함되지 않았습니다. 운영 적용 전에 반드시 대상 엔드포인트에서 직접 보정을 수행하고, jev-latest처럼 예고 없이 갱신되는 별칭 대신 명시적 버전(jev-1.14.0 등)을 고정하십시오.

결과 (2026-09-24)

아래 요약 표는 tests/fixtures/systemone/calibration/2026-09-24/에 커밋된 세 코퍼스의 실행 결과에서 생성되었습니다.

  • guardrail.jsonl: 총 244행 (실제 재생 223행: 영어 111행, 한국어 66행, 비라틴 106행)
  • routing.jsonl: 총 200행 (영어 90행, 한국어 79행, 비라틴 104행)
  • tool_calls.jsonl: 총 207행 (영어)

질문별 상세 Brier 점수, ECE, AUROC 및 슬라이스별 전체 표를 원시 JSON에서 다시 출력하려면 python3 scripts/systemone/results_tables.py 2026-09-24를 실행하십시오.

평가 엔드포인트

실행 체크포인트 리비전 서버 디바이스 해석된 model
kev-0.8b jaredpalmer/kev-0.8b (Qwen/Qwen3.5-0.8B-Base 기반 LoRA, T=2.41) 54f4f8777356 kev.serve (62c9183) Apple M4 Pro (mps, bf16) kev-latest
laya-auto convaiinnovations/laya (자동 스크립트 라우팅) 55cf4c4ebb4e laya-serve==0.1.1 (laya 0.3.20) Apple M4 Pro (mps) laya-auto@55cf4c4ebb4e
laya-english convaiinnovations/laya (english) 55cf4c4ebb4e laya-serve==0.1.1 (laya_pinned_serve.py) Apple M4 Pro (mps) laya-english@55cf4c4ebb4e
laya-multilingual convaiinnovations/laya (multilingual) 55cf4c4ebb4e laya-serve==0.1.1 (laya_pinned_serve.py) Apple M4 Pro (mps) laya-multilingual@55cf4c4ebb4e
laya-serve-compose-cpu convaiinnovations/laya (자동 스크립트 라우팅) 55cf4c4ebb4e deploy/docker-compose.systemone.yml CPU (동시성 1) laya-english
laya-typed-decisions convaiinnovations/laya (typed-decisions) 55cf4c4ebb4e laya-serve==0.1.1 (laya_pinned_serve.py) Apple M4 Pro (mps) laya-typed-decisions@55cf4c4ebb4e

소비자별 지연 시간 및 입력 토큰 요약

실행 가드레일 p50 / p95 (ms) 가드레일 입력 토큰 라우팅 p50 / p95 (ms) 라우팅 입력 토큰 Action Safety p50 / p95 (ms) Action Safety 입력 토큰
kev-0.8b 235.2 / 319.1 679 84.3 / 160.2 351 83.2 / 145.6 308
laya-auto 189.2 / 263.3 1081 47.0 / 61.3 341 63.3 / 77.7 280
laya-english 238.6 / 332.8 1222 61.7 / 72.1 409 62.6 / 75.8 280
laya-multilingual 92.9 / 115.1 1079 33.4 / 45.8 341 31.2 / 39.2 298
laya-serve-compose-cpu 786.2 / 1734.9 1081 291.3 / 579.6 341 256.8 / 469.9 280
laya-typed-decisions 242.5 / 322.7 1222 62.3 / 74.1 409 62.2 / 73.8 280

라우팅 섀도 비교

언어 슬라이스별로 측정한 System One 단독 정확도, 규칙 분류기 단독 정확도, 두 분류기 간 일치율(smart_routing_shadow_agreement_total), 그리고 system_one -> rule 폴백 체인의 결합 정확도입니다.

실행 슬라이스 행 수 System One (도메인 / 복잡도) 규칙 (도메인 / 복잡도) 일치율 (도메인 / 복잡도) 0.5에서의 체인 도출 하한 도출 하한에서의 체인
kev-0.8b all 200 0.700 / 0.525 0.440 / 0.510 0.370 / 0.420 0.600 0.25 0.618
kev-0.8b en 90 0.722 / 0.511 0.556 / 0.533 0.511 / 0.378 0.633 0.65 0.656
kev-0.8b ko 79 0.671 / 0.557 0.430 / 0.544 0.304 / 0.506 0.614 0.25 0.639
kev-0.8b non_latin 104 0.673 / 0.538 0.356 / 0.500 0.250 / 0.462 0.587 0.25 0.625
laya-auto all 200 0.610 / 0.390 0.440 / 0.510 0.410 / 0.475 0.460 0.15 0.510
laya-auto en 90 0.722 / 0.489 0.556 / 0.533 0.511 / 0.533 0.539 0.15 0.628
laya-auto ko 79 0.519 / 0.291 0.430 / 0.544 0.392 / 0.443 0.462 없음 (규칙 우세) 해당 없음
laya-auto non_latin 104 0.538 / 0.298 0.356 / 0.500 0.346 / 0.423 0.409 없음 (규칙 우세) 해당 없음
laya-english all 200 0.595 / 0.460 0.440 / 0.510 0.390 / 0.470 0.478 0.15 0.535
laya-english en 90 0.722 / 0.489 0.556 / 0.533 0.511 / 0.533 0.539 0.15 0.628
laya-english ko 79 0.456 / 0.443 0.430 / 0.544 0.342 / 0.468 0.500 0.50 0.500
laya-english non_latin 104 0.500 / 0.433 0.356 / 0.500 0.288 / 0.433 0.438 0.05 0.476
laya-multilingual all 200 0.550 / 0.345 0.440 / 0.510 0.350 / 0.460 0.450 없음 (규칙 우세) 해당 없음
laya-multilingual en 90 0.589 / 0.400 0.556 / 0.533 0.378 / 0.489 0.517 없음 (규칙 우세) 해당 없음
laya-multilingual ko 79 0.519 / 0.291 0.430 / 0.544 0.392 / 0.443 0.462 없음 (규칙 우세) 해당 없음
laya-multilingual non_latin 104 0.538 / 0.298 0.356 / 0.500 0.346 / 0.423 0.409 없음 (규칙 우세) 해당 없음
laya-serve-compose-cpu all 200 0.610 / 0.390 0.440 / 0.510 0.410 / 0.475 0.460 0.15 0.510
laya-serve-compose-cpu en 90 0.722 / 0.489 0.556 / 0.533 0.511 / 0.533 0.539 0.15 0.628
laya-serve-compose-cpu ko 79 0.519 / 0.291 0.430 / 0.544 0.392 / 0.443 0.462 없음 (규칙 우세) 해당 없음
laya-serve-compose-cpu non_latin 104 0.538 / 0.298 0.356 / 0.500 0.346 / 0.423 0.409 없음 (규칙 우세) 해당 없음
laya-typed-decisions all 200 0.580 / 0.375 0.440 / 0.510 0.355 / 0.360 0.475 0.10 0.490
laya-typed-decisions en 90 0.756 / 0.422 0.556 / 0.533 0.533 / 0.433 0.544 0.10 0.600
laya-typed-decisions ko 79 0.430 / 0.342 0.430 / 0.544 0.241 / 0.392 0.487 없음 (규칙 우세) 해당 없음
laya-typed-decisions non_latin 104 0.442 / 0.337 0.356 / 0.500 0.202 / 0.317 0.428 없음 (규칙 우세) 해당 없음