주소가 세 종류나 필요한 이유 통신 한 번에는 서로 다른 세 가지 식별자가 쓰인다. 같은 서버에 접속하더라도 어느 네트워크의 어느 장치인지(IP), 같은 네트워크 안에서 어느 인터페이스인지(MAC), 그 장치 안의 어느 프로그램인지(포트)를 따로 가리켜야 하기 때문이다. 계층 모델로 보면 이렇게 나뉜다. 식별자 계층 가리키는 대상 형태 IP 주소 인터넷(L3) 네트워크에 연결된 장치 IPv4는 32비트, 점으로 구분한 숫자 네 묶음 MAC 주소 링크(L2) 같은 네트워크 안의 네트워크 인터페이스 48비트 포트 번호 전송(L4) 장치 안에서 동작하는 프로그램/서비스 숫자(총 65,535개) IP 주소 IP 주소는 인터넷 프로토콜이 장치마다 부여하는 고유한 식별 번호 다. 브라우저가 서버에 요청을 보낼 때 요청에 출발지 IP가 들어 있어야 서버가 응답을 돌려보낼 곳을 안다. 도메인 이름을 IP로 바꿔 주는 것은 DNS가 한다. IPv4는 192.0.2.1 처럼 점으로 구분한 숫자 네 묶음이고 32비트라서 약 43억 개의 주소를 만들 수 있다. 기기가 늘면서 부족해져 128비트 형식의 IPv6가 나왔고, 지금은 두 버전이 함께 쓰인다. 할당 방식은 동적 IP 와 고정 IP 로 나뉜다. 대부분의 장치는 ISP가 공유 풀에서 임시로 나눠 주는 동적 IP를 쓴다. 그런데 직접 운영하는 웹 서버나 API 서버가 동적 IP를 쓰면, IP가 바뀔 때 DNS 질의가 실패해서 서비스가 사실상 내려갈 수 있다고 Cloudflare 문서는 설명한다. 그래서 서버에는 고정 주소가 필요하다고 이해했다. MAC 주소와 IP 주소의 차이 이더넷은 케이블 위에서 48비트 주소를 요구하는데, IP처럼 상위 프로토콜의 주소는 길이도 값도 이더넷 주소와 맞지 않는다고 RFC 826은 설명한다. 그래서 둘을 연결하는 변환이 필요해진 것이다. 이더넷 프레임에는 목적지와 출발지 48비트 주소가 들어가고, 이 주소는 고유하고 고정된 값이어야 하는 것으로 정해져 있다. 비교 IP 주소 MAC 주소 길이 32비트(IPv4) 48비트 성격 할당/변경 가능(동적 할당이 흔함) 인터페이스에 고유하고 고정 쓰이는 범위 네트워크 사이를 넘어 전달 같은 네트워크(같은 케이블) 안에서 전달 계층 인터넷(L3) 링크(L2) 정리하면 IP는 네트워크를 넘어 목적지를 찾는 주소 이고, MAC은 같은 네트워크 안에서 다음 장치에 프레임을 넘기는 주소 다. ARP IP 주소는 알지만 MAC 주소를 모를 때 쓰는 것이 ARP(Address Resolution Protocol)다. ARP는 IP 주소를 MAC 주소로 바꿔 주는 프로토콜 이다. RFC 826 기준으로 같은 케이블 위의 두 장치 X와 Y가 통신하는 과정을 정리하면 이렇다. 단계 일어나는 일 1 X가 Y의 IP로 보내려는데 변환 표에 MAC 주소가 없으면, 보내려던 패킷은 일단 버리고(상위 계층이 다시 보낸다고 가정) ARP 요청을 만든다 2 요청에는 X 자신의 MAC/IP와 찾으려는 Y의 IP가 들어가고, 찾는 MAC 칸은 비워 둔다 3 요청은 같은 케이블의 모든 장치에게 브로드캐스트로 전달된다 4 자기 IP가 맞는 Y만 요청을 받아들이고, 자기 MAC을 채워 X에게 직접(브로드캐스트 아님) 응답한다 5 X는 응답으로 Y의 MAC을 변환 표에 기록하고, 이후 같은 목적지는 표를 보고 바로 보낸다 Y도 X의 요청을 받으면서 X의 MAC/IP를 표에 기록한다. 통신은 보통 양방향이라고 보기 때문이다. 이렇게 필요할 때만 물어보는 방식이라 모든 장치가 주기적으로 주소를 방송할 때보다 트래픽이 적다고 RFC는 설명한다. 표에 쌓인 기록이 오래돼 틀어질 수 있어서 만료 처리가 필요하다는 점도 RFC가 짚는다. 포트 번호 IP가 장치를 찾았으면, 그 장치 안에서 어느 프로그램에 데이터를 줄지는 포트 번호 가 정한다. 포트는 운영체제가 관리하는 가상의 접점이고 프로그램/서비스마다 연결된다. 메일과 웹 페이지가 같은 네트워크 연결로 들어와도 서로 다른 포트로 구분해서 처리한다. 하나의 웹 서버에서 HTTPS(443)와 SSH(22)가 동시에 동작할 수 있는 이유가 이것이다. 포트는 전송 계층(L4) 개념이다. TCP/UDP 헤더에 포트 번호를 적는 자리가 있고, IP 헤더에는 목적지 IP만 있고 포트 자리가 없다고 Cloudflare 문서는 설명한다. 포트는 총 65,535개가 있고, 많이 쓰는 것은 아래와 같다. 포트 프로토콜 용도 21 FTP 파일 전송 22 SSH 원격 접속(보안 연결) 25 SMTP 메일 전송 53 DNS 도메인 이름을 IP로 변환 80 HTTP 웹 123 NTP 시간 동기화 443 HTTPS 암호화된 웹 3389 RDP 원격 데스크톱 번호별 전체 목록은 IANA가 관리한다고 한다. 포트는 보안과도 직접 연결된다. 방화벽은 보통 모든 포트를 기본으로 막고, 25/80/443처럼 꼭 필요한 포트만 열어 둔다. RDP의 취약점을 노린 공격이 3389 포트로 들어오기 때문에, 원격 근무가 필요 없다면 이 포트를 막아도 업무에 영향이 적다는 예시가 Cloudflare 문서에 나온다. 한 번의 웹 접속에서 세 주소의 위치 웹 접속 흐름에 대응시키면 전송 계층 헤더에는 서버 프로그램을 가리키는 목적지 포트(HTTPS는 443)가, 인터넷 계층 헤더에는 서버의 IP가, 링크 계층 헤더에는 같은 네트워크의 다음 장치 MAC이 들어간다. 이 중 IP와 포트는 목적지까지 그대로 유지되고, MAC은 구간마다 달라진다고 이해했다. 핵심 복습 키워드 한 줄 정리 IP 주소 네트워크 안의 장치를 가리키는 주소, IPv4는 32비트 네 묶음 동적/고정 IP 대부분 임시 할당, 서버는 고정이 필요 MAC 주소 같은 네트워크 안에서 인터페이스를 가리키는 48비트 주소 IP와 MAC의 차이 IP는 네트워크를 넘는 주소, MAC은 같은 네트워크 안의 주소 ARP IP를 MAC으로 바꿔 줌, 요청은 브로드캐스트/응답은 직접 전달 다른 네트워크로 보낼 때 ARP가 찾는 것은 다음 홉(게이트웨이)의 MAC 포트 번호 장치 안의 프로그램을 가리키는 L4 번호, 총 65,535개 📍 참고 자료 확인일: 2026-10-02 Cloudflare Learning Center - What is my IP address? Cloudflare Learning Center - What is a computer port? RFC 826 - An Ethernet Address Resolution Protocol
서버를 운영하며 쓰는 네 가지 프로토콜 서버를 운영할 때는 원격으로 접속하고, 파일을 주고받고, 시계를 맞추는 일이 반복된다. 이 글의 네 프로토콜은 모두 응용 계층 프로토콜이고 역할이 이렇게 나뉜다. 프로토콜 하는 일 기본 포트(3편 표 기준) 텔넷 원격으로 서버에 명령을 보냄(암호화 없음) 이 글의 문서에서 확인하지 못함 SSH 암호화된 연결로 원격 접속과 파일 전송 22 FTP 클라이언트와 서버 사이 파일 전송 20/21 NTP 컴퓨터 시계 동기화 123 텔넷에서 SSH로 원격 서버를 관리하는 오래된 프로토콜인 텔넷은 관리자의 명령을 누구나 볼 수 있는 형태로 보냈다. Cloudflare 문서는 텔넷이 평문으로 데이터를 보내고, SSH가 텔넷을 사실상 대체 했다고 설명한다. SSH(Secure Shell)는 신뢰할 수 없는 네트워크 위에서 컴퓨터에 안전하게 명령을 보내는 방법이다. 암호화와 인증으로 연결을 보호하기 때문에, 중간에서 가로채도 의미 없는 데이터만 보인다. SSH가 안전한 이유는 공개키 암호화로 인증하고 암호화하기 때문이다. 키는 서로 짝인 두 개로 이루어지는데, 공개키는 누구나 쓸 수 있고 개인키는 소유자만 갖는다. SSH 연결에서는 양쪽이 모두 키 쌍을 갖고 서로를 인증하며, 협상을 마친 뒤에는 둘이 공유하는 대칭키로 데이터를 암호화해서 주고받는다. 서버 쪽 신원만 확인하는 일반적인 HTTPS와 다른 점이다. 그다음 사용자 본인 인증으로 사용자 이름과 비밀번호를 요구하는 경우가 많고, 인증이 끝나면 원격 컴퓨터에서 로컬처럼 명령을 실행할 수 있다. 비교 텔넷 SSH 데이터 평문으로 전송 암호화해서 전송 인증 이 글의 문서에서 확인하지 못함 공개키 암호화 + 사용자 인증 현재 위상 오래된 프로토콜 원격 서버 접속의 표준 SSH는 TCP/IP 위에서 동작하고, 기본 포트는 22번이다. 리눅스와 맥에는 기본으로 들어 있고 윈도에는 클라이언트 설치가 필요할 수 있다. 원격 서버 관리, 파일의 안전한 전송, 개인 네트워크 안의 서비스 접속이 대표적인 용도다. SSH는 터널링(포트 포워딩)도 지원해서, 외부에 열린 서버를 거쳐 사설 네트워크 안의 서버에 접속할 수 있다. SSH의 보안 위험 SSH 접속은 서버에 프로그램을 설치하거나 데이터를 지우고 빼내는 높은 권한이 따라온다. 그래서 공격자 손에 들어가면 위험하다고 Cloudflare 문서는 경고한다. 특히 두 가지를 짚는다. 많은 방화벽이 22번 포트를 열어 두기 때문에 공격자가 이를 타고 내부 네트워크로 들어올 수 있고, SSH 키는 명시적으로 폐기하기 전까지 만료되지 않아서 도난당하면 몇 달에서 몇 년 동안 접근이 유지될 수 있다. 서버가 많은 조직에서는 키 관리가 큰 보안 과제라고도 한다. 클라우드 서버를 운영할 때 가장 먼저 점검할 부분이다. FTP와 안전한 대안 FTP는 클라이언트와 서버 사이에서 파일을 주고받는 프로토콜이다. Cloudflare 문서는 SSH가 FTP 같은 암호화되지 않은 프로토콜보다 안전하다고 설명한다. FTP의 보안 대안으로는 아래 둘이 있다고 AWS 문서에서 확인했다. 프로토콜 설명 SFTP SSH 파일 전송 프로토콜(SSH File Transfer Protocol), SSH 위에서 동작 FTPS FTP에 보안을 더한 프로토콜(File Transfer Protocol Secure) AWS는 이 프로토콜들을 서비스로도 제공한다. AWS Transfer Family는 SFTP/FTPS/FTP/AS2와 웹 브라우저 기반 전송으로 S3나 EFS에 파일을 주고받게 해 주는 완전 관리형 서비스다. 사용자는 OpenSSH, WinSCP, Cyberduck, FileZilla 같은 기존 클라이언트를 그대로 쓸 수 있고, 서버 인프라를 직접 운영할 필요가 없다. FTP와 FTPS의 데이터 연결에는 8192~8200 포트 범위를 쓴다고 문서에 나와 있어서, 방화벽 규칙을 만들 때 이 범위를 확인해야 한다. NTP NTP(Network Time Protocol)는 컴퓨터 시계를 서로 맞추는 프로토콜이고 기본 포트는 123번이다. 시계 동기화는 암호화에도 필수적이다. AWS 문서는 서버 시간이 왜 중요한지를 구체적으로 보여 준다. 시스템 로그의 타임스탬프로 문제가 언제 생겼고 사건이 어떤 순서로 일어났는지 파악하고, AWS CLI나 SDK가 요청에 서명할 때도 시간을 쓴다. 인스턴스의 날짜와 시간이 틀리면 서명 시각과 요청 시각이 어긋나서 AWS가 요청을 거부할 수 있다. 그래서 AWS는 모든 EC2 인스턴스에서 쓸 수 있는 Amazon Time Sync Service를 제공한다. 이 서비스는 각 리전의 위성 연결 시계와 원자시계로 협정 세계시(UTC)를 정확하게 제공하고, 윤초를 시간에 걸쳐 나눠 반영(smearing)한다. 인스턴스에서는 로컬 Amazon Time Sync Service를 쓰는 것을 권장하고, 백업이나 EC2 밖의 리소스에는 time.aws.com 의 공개 서비스를 쓸 수 있다. 핵심 복습 키워드 한 줄 정리 텔넷 평문으로 원격 명령을 보내던 오래된 프로토콜 SSH 공개키 암호화로 인증/암호화하는 원격 접속 표준, 포트 22 SSH 위험 22번 포트가 열려 있고 키가 만료되지 않아 도난 시 장기간 접근 가능 FTP 파일 전송 프로토콜, 암호화되지 않음 SFTP/FTPS FTP의 안전한 대안, SFTP는 SSH 기반 AWS Transfer Family SFTP/FTPS/FTP로 S3/EFS에 파일을 주고받는 관리형 서비스 NTP 시계 동기화 프로토콜, 포트 123 Amazon Time Sync Service EC2에서 쓰는 UTC 기준 시간 동기화 서비스 📍 참고 자료 확인일: 2026-10-03 Cloudflare Learning Center - What is SSH? AWS Docs - What is AWS Transfer Family? AWS Docs - Precision clock and time synchronization on your EC2 instance
1. 정수 카운터에서 왜 소수가 나오나 increase(http_requests_total[1m]) 가 정수 카운터인데도 5.33 을 돌려줬다. 처음엔 부동소수 오차나 버그를 의심했는데, Prometheus 소스 promql/functions.go 의 extrapolatedRate 를 따라가 보니 의도된 동작이었다. 윈도우 안 샘플이 덮지 못한 경계까지의 빈틈을 선형으로 외삽 하기 때문이다. rate() 와 increase() 는 둘 다 이 함수 하나를 부른다. 차이는 마지막에 윈도우 길이(초)로 나누느냐뿐이라, 공식 문서도 increase 를 rate 에 윈도우 초를 곱한 syntactic sugar라고 설명한다. 2. "마지막 − 처음"이라는 오해 흔한 이해는 increase = 마지막 값 − 첫 값 이다. 실제 계산은 그 값(raw)에 배율을 곱한다. factor = (covered + left + right) / covered covered 는 첫 샘플부터 마지막 샘플까지의 시간, left · right 는 윈도우 경계까지 남은 빈틈이다. range selector는 (start, end] 구간이라 왼쪽 경계와 같은 타임스탬프의 샘플은 빠진다는 점도 함께 기억해 둘 만하다. scrape 15초, [1m] 윈도우에서 샘플이 t=5, 20, 35, 50초에 값 100, 101, 103, 104로 찍혔다고 하자. raw는 4, covered는 45초, 빈틈은 왼쪽 5초·오른쪽 10초다. 배율 60/45가 곱해져 결과는 4 × 4/3 ≈ 5.33 이 된다. 윈도우 60초 전체에서 같은 기울기로 늘었으리라 추정한 값이다. increase()는 "관측된 증가량"이 아니라 "윈도우 전체에 대한 추정 증가량"이다. 3. 외삽을 언제 멈추나 무조건 경계까지 늘리면 윈도우 중간에 새로 뜬 파드의 카운터가 크게 부풀려진다. 그래서 두 가지 브레이크가 있다. 첫째, 1.1배 임계 . 평균 샘플 간격 avg = covered / (샘플수 − 1) 을 구하고, 빈틈이 avg × 1.1 이상이면 "있어야 할 자리에 샘플이 없다", 즉 시리즈가 윈도우 안에서 시작하거나 끝났다고 본다. 이때는 경계까지가 아니라 avg / 2 만 외삽한다. 둘째, 카운터의 0점 클램프 (왼쪽만). 카운터는 음수가 될 수 없으므로 기울기로 0이 되는 지점 covered × (첫 값 / raw) 을 역산해, 왼쪽 외삽이 그보다 길어지지 않게 자른다. 빈틈 외삽 거리 < 1.1 × avg 경계까지 전부 ≥ 1.1 × avg avg / 2 카운터의 왼쪽 위 값과 0점까지 거리 중 작은 쪽 중간에 값이 줄면 카운터 리셋으로 보고 직전 값을 raw에 더해 준다. 100 → 110 → 5 → 15라면 raw는 −85 + 110 = 25다. 4. 직접 돌려보기 알고리즘을 Python으로 옮겨 숫자를 확인했다. 소스의 기본 경로(수정자 없는 range selector)만 단순화한 것이다. def extrapolated_increase(samples, range_start, range_end, is_counter=True): """samples: [(t초, 값)] — 이미 (range_start, range_end] 안에 든 것만""" if len(samples) < 2: return None # 간격을 추정할 수 없음 (t0, v0), (tn, vn) = samples[0], samples[-1] raw = vn - v0 for (_, prev), (_, curr) in zip(samples, samples[1:]): if curr < prev: # 카운터 리셋 raw += prev covered = tn - t0 avg = covered / (len(samples) - 1) to_start, to_end = t0 - range_start, range_end - tn if to_start >= avg * 1.1: # 시리즈가 윈도우 안에서 시작 to_start = avg / 2 if is_counter and raw > 0 and v0 >= 0: to_start = min(to_start, covered * (v0 / raw)) # 0 아래로 외삽 금지 if to_end >= avg * 1.1: # 시리즈가 윈도우 안에서 끝남 to_end = avg / 2 return raw * (covered + to_start + to_end) / covered print(extrapolated_increase([(5, 100), (20, 101), (35, 103), (50, 104)], 0, 60)) # 5.33 print(extrapolated_increase([(35, 1), (50, 5)], 0, 60)) # 7.67 print(extrapolated_increase([(30, 100), (60, 103)], 0, 60)) # 6.0 두 번째는 t=35에 태어난 시리즈다. 왼쪽 빈틈 35초는 임계 16.5초를 넘어 7.5초로 줄고, 0점까지 거리 3.75초로 다시 잘린다. 결과 7.67은 t=31.25에 0에서 출발해 t=60까지 기울기 4/15로 늘렸을 때의 값과 같다. 세 번째가 노트에 없던 실패 케이스 다. scrape 30초에 [1m] 윈도우를 쓰면 t=0 샘플이 left-open 경계에 걸려 빠지고 두 개만 남는다. 실제 증가량은 3인데 배율 2가 곱해져 6이 나온다. 샘플이 적을수록 배율과 오차가 같이 커지기 때문에, 윈도우를 scrape 간격의 최소 4배로 잡으라는 권장이 흔히 인용된다. 같은 이유로 [15s] 처럼 샘플이 하나뿐인 윈도우는 결과가 아예 비어 버린다. 5. 정리 rate / increase 는 샘플 사이 증가량(리셋 보정 포함)을 구한 뒤, 경계 빈틈이 평균 간격의 1.1배 미만이면 경계까지, 이상이면 반 간격만 외삽하고, 카운터는 0 아래로 내려가지 않게 자른다. 그래서 소수 결과는 버그가 아니며, 짧은 윈도우에서 오차가 커진다. 히스토그램 버킷에도 같은 rate 가 먼저 적용되므로, histogram_quantile 글 의 결과에도 이 외삽이 그대로 섞인다. 다음에는 최신 main에 들어온 anchored / smoothed 수정자, 즉 외삽 대신 경계 보간을 쓰는 extendedRate 가 이 오차를 어떻게 줄이는지 볼 생각이다. 참고 자료 Prometheus 소스 promql/functions.go — extrapolatedRate , funcRate , funcIncrease (commit e71425d) Prometheus Docs querying/functions.md — rate() , increase() Prometheus Docs querying/basics.md — range vector selector의 구간 정의
DNS가 필요한 이유 인터넷의 모든 컴퓨터는 IP 주소라는 숫자로 서로 통신한다. 사람은 example.com 같은 도메인 이름을 쓰고 브라우저는 IP 주소로 통신하기 때문에, 둘 사이를 연결해 주는 것이 DNS(Domain Name System) 다. DNS는 도메인 이름을 IP 주소로 바꿔 줘서 브라우저가 서버를 찾아 접속하게 한다. 웹 접속 흐름에서 1단계로 나온 바로 그 과정이다. DNS는 53번 포트이다. 조회에 참여하는 서버 웹 페이지 하나를 불러오는 데 DNS 서버 네 종류가 관여한다고 Cloudflare 문서는 설명한다. 서버 하는 일 재귀 리졸버(recursor) 클라이언트의 질의를 받아서 답을 찾아올 때까지 추가 질의를 대신 보낸다 루트 네임서버 이름을 IP로 바꾸는 첫 단계, 더 구체적인 TLD 서버의 위치를 알려 준다 TLD 네임서버 호스트 이름의 마지막 부분(.com 등)을 담당하고, 해당 도메인의 네임서버를 알려 준다 권한 있는(authoritative) 네임서버 레코드를 실제로 갖고 있는 마지막 서버, 요청한 호스트의 IP를 돌려준다 재귀 리졸버는 조회의 시작점에, 권한 있는 네임서버는 끝에 있다고 이해하면 된다. 조회 과정 캐시에 아무것도 없을 때 example.com을 조회하는 과정은 8단계다. 단계 일어나는 일 1 사용자가 브라우저에 example.com을 입력하고, 질의가 재귀 리졸버에 도착한다 2 리졸버가 루트 네임서버에 묻는다 3 루트 서버가 .com TLD 서버의 주소를 알려 준다 4 리졸버가 .com TLD 서버에 묻는다 5 TLD 서버가 example.com의 네임서버 주소를 알려 준다 6 리졸버가 example.com의 네임서버에 묻는다 7 네임서버가 example.com의 IP 주소를 리졸버에 돌려준다 8 리졸버가 브라우저에 IP 주소를 알려 주고, 브라우저는 그 IP로 HTTP 요청을 보낸다 AWS 문서는 같은 과정을 Route 53 기준으로 설명한다. 리졸버는 보통 ISP가 관리하고, TLD 서버는 해당 도메인에 연결된 Route 53 네임서버 네 개의 이름을 알려 준다. 리졸버는 이 네임서버 정보를 캐시하기 때문에 다음에 같은 도메인을 조회할 때는 루트/TLD 단계를 건너뛰고, 이 정보는 보통 이틀 정도 캐시된다. 이후 Route 53 네임서버가 호스티드 존에서 www.example.com 레코드를 찾아 값(예: 웹 서버의 IP)을 돌려준다. 질의의 종류 실제 조회에서는 아래 세 가지 질의가 섞여 쓰인다. 질의 설명 재귀 질의 클라이언트가 리졸버에게 최종 답(또는 오류)을 달라고 요구한다 반복 질의 서버가 아는 만큼의 최선의 답을 주고, 모르면 더 아래 단계 서버를 알려 주는 참조(referral)를 돌려준다. 클라이언트가 그 서버에 다시 묻는다 비재귀 질의 서버가 자기 권한 데이터나 캐시로 바로 답할 수 있을 때 캐시되지 않은 일반적인 조회에는 재귀 질의와 반복 질의가 함께 쓰인다. 사용자 기기가 리졸버에게 보내는 것이 재귀 질의이고, 리졸버가 루트/TLD/권한 서버를 차례로 찾아가는 것이 반복 질의라고 이해했다. 캐시 DNS 결과는 여러 곳에 임시로 저장돼서 조회 단계를 줄인다. 각 레코드는 TTL(time-to-live)이 정한 시간 동안만 캐시된다. 질의가 나가는 순서는 이렇다. 순서 위치 설명 1 브라우저 캐시 DNS 레코드를 요청할 때 가장 먼저 확인하는 곳 2 운영체제 캐시 스텁 리졸버(DNS 클라이언트)가 자기 캐시를 확인한 뒤 없으면 ISP의 재귀 리졸버로 질의한다 3 재귀 리졸버 캐시 저장된 레코드 종류에 따라 단계를 건너뛴다 재귀 리졸버가 A 레코드는 없어도 권한 네임서버의 NS 레코드를 갖고 있으면 그 서버에 바로 묻고, NS 레코드가 없으면 TLD 서버부터, 그것도 없으면 루트 서버부터 묻는다. 캐시가 비워진 직후에만 루트 서버까지 가는 일이 생긴다고 한다. DNS 레코드 DNS 레코드는 권한 있는 DNS 서버에 저장된, 도메인에 대한 정보(어느 IP와 연결되는지, 요청을 어떻게 처리할지)를 담은 지침이다. 모든 레코드에는 TTL이 있어서 DNS 서버가 그 레코드를 얼마나 자주 갱신하는지 나타낸다. 레코드 역할 A 도메인의 IPv4 주소 AAAA 도메인의 IPv6 주소 CNAME 한 도메인을 다른 도메인으로 연결, IP 주소는 제공하지 않음 MX 메일을 메일 서버로 보냄 NS 해당 도메인의 네임서버 TXT 텍스트 메모, 이메일 보안에 자주 사용 SOA 도메인의 관리 정보 PTR 역방향 조회에서 도메인 이름 제공 AWS 문서는 레코드를 이름/유형/값 세 가지로 설명한다. 이름은 도메인이나 서브도메인( www.example.com 등), 유형은 트래픽을 보낼 리소스의 종류(메일 서버면 MX, IPv4 웹 서버면 A), 값은 유형에 맞는 내용(MX면 메일 서버 이름, A면 IPv4 주소)이다. Route 53에는 S3 버킷이나 CloudFront 같은 AWS 리소스로 트래픽을 보내는 별칭(alias) 레코드라는 특수 레코드도 있다. 도메인을 등록하면 같은 이름의 퍼블릭 호스티드 존이 자동으로 만들어지고, 그 안에 레코드를 만들어 라우팅을 정한다. 운영에서 자주 마주치는 상황 동적 IP가 바뀌면 DNS 질의가 실패해 서비스가 내려갈 수 있다고 했는데, 서버에는 고정 주소나 도메인 레코드 관리가 필요하다는 뜻이다. 또 캐시 때문에, 레코드 값을 바꿔도 이전 값을 캐시한 쪽은 TTL이 지날 때까지 이전 값을 쓸 수 있다. (이 부분은 TTL과 캐시 설명에서 이해한 내용) 핵심 복습 키워드 한 줄 정리 DNS 도메인 이름을 IP 주소로 바꿔 주는 시스템 서버 4종 재귀 리졸버, 루트, TLD, 권한 있는 네임서버 조회 순서 리졸버 → 루트 → TLD → 권한 네임서버 → IP 반환 재귀/반복 질의 최종 답을 요구하는 질의 vs 참조를 따라가는 질의 캐시 브라우저 → OS → 재귀 리졸버 순으로 확인, TTL 동안만 유지 주요 레코드 A/AAAA는 IP, CNAME은 별칭, MX는 메일, NS는 네임서버 Route 53 호스티드 존에 레코드를 만들어 트래픽 라우팅, alias로 AWS 리소스 연결 📍 참고 자료 확인일: 2026-10-03 Cloudflare Learning Center - What is DNS? Cloudflare Learning Center - DNS records AWS Docs - How internet traffic is routed to your website or web application (Route 53)
1. 도입 — 거절이 아니라 멈춤 트래픽이 몰리면 클라이언트 로그에 connection refused 가 찍힐 거라고 생각했다. 그런데 실제로 보이는 건 connect() 는 성공했는데 첫 요청이 1초, 3초씩 멈추다가 응답이 오거나 타임아웃 나는 현상이다. 커널 소스를 따라가 보니 원인은 서버의 accept 큐가 넘쳤을 때 커널이 3번째 ACK를 RST 없이 그냥 무시한다 는 데 있었다. 이 글은 listen(fd, backlog) 의 backlog가 실제로 무엇을 세는지에서 시작해, 그 ACK가 어디서 버려지는지까지 따라간 기록이다. 2. backlog는 "완성된 연결" 큐의 길이다 listen(2) man page에 따르면 Linux 2.2부터 backlog는 반쯤 열린(SYN_RECV) 연결이 아니라 핸드셰이크가 끝났지만 아직 accept() 되지 않은 소켓 수의 상한이다. 3-way handshake 자체의 흐름은 TCP 3-way/4-way handshake 글 에서 정리했고, 여기서는 서버 쪽 큐만 본다. listen() 에 넘긴 값은 net.core.somaxconn (5.4부터 기본 4096, 이전은 128)으로 조용히 잘려 sk->sk_max_ack_backlog 에 저장된다. 커널은 이 한 값을 두 관문에 쓴다. 카운터 의미 비교 대상 qlen SYN_RECV 상태 요청 수 ("SYN 큐") sk_max_ack_backlog → 넘으면 syncookie 전환 sk_ack_backlog accept 대기 중인 완성 소켓 수 sk_max_ack_backlog → 넘으면 overflow 헷갈렸던 지점은 tcp_max_syn_backlog 다. 이 sysctl은 syncookies가 꺼져 있을 때 "마지막 1/4은 살아 있음이 입증된 목적지에게만"을 판단할 때만 쓰인다. 기본값( tcp_syncookies=1 )에서 SYN 단계의 실질 임계값은 앱의 backlog다. 그래서 tcp_max_syn_backlog 만 올리는 튜닝은 효과가 없다. 하나 더 있다. 두 비교가 모두 >= 가 아니라 > 라서 실제로는 backlog+1개 까지 들어간다. // include/net/sock.h static inline bool sk_acceptq_is_full(const struct sock *sk) { return READ_ONCE(sk->sk_ack_backlog) > READ_ONCE(sk->sk_max_ack_backlog); } sock.h 에는 " >= 여야 한다고 생각하면 commit 64a146513f8f를 보라"는 주석이 붙어 있다. off-by-one처럼 보이지만 의도적으로 되돌린 결과다. 3. accept 큐가 꽉 찼을 때 — 관문이 두 번 있다 accept 큐가 꽉 찬 상태에서 새 SYN 이 오면 tcp_conn_request() 가 ListenOverflows 를 올리고 SYN 자체를 버린다. 클라이언트는 SYN_SENT에 머물며 SYN을 재전송한다. 이 경우는 connect() 가 늦어질 뿐 성공처럼 보이지는 않는다. 문제는 SYN 시점엔 자리가 있었는데 3번째 ACK가 도착한 시점엔 큐가 찬 경우다. burst에서 여러 핸드셰이크가 동시에 진행되면 이렇게 된다. tcp_check_req() 가 child 소켓을 만들려다 실패하면 이 분기로 간다. // net/ipv4/tcp_minisocks.c — listen_overflow if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_abort_on_overflow)) { inet_rsk(req)->acked = 1; // ACK를 받았다고 표시만 하고 return NULL; // 세그먼트는 버린다 — RST 없음 } 이때 양쪽 상태가 어긋난다. client: SYN-ACK 받음 → ESTABLISHED (connect() 성공, 요청 write) server: request_sock은 SYN_RECV 그대로, child 소켓 없음 └ reqsk 타이머 만료 → SYN-ACK 재전송 → client가 ACK 재전송 → 그때 큐에 자리가 있으면 child 생성 → tcp_synack_retries 횟수를 넘기면 요청 폐기 클라이언트 입장에선 연결이 열렸으니 바로 요청을 보낸다. 그 사이 서버엔 이 연결을 받을 소켓이 없으므로 요청은 처리되지 않는다. 요청 세그먼트도 ACK를 싣고 있어 같은 검사를 다시 거치지만, 큐가 여전히 차 있으면 똑같이 버려진다. 결국 서버의 SYN-ACK 재전송(또는 클라이언트의 데이터 재전송)이 다시 도착했을 때 큐에 자리가 나 있어야 비로소 연결이 서버에 생긴다. 이 재전송 간격은 초기 1초에서 지수적으로 늘어나는 것으로 알려져 있다. "첫 요청이 1초, 3초씩 멈춘다"는 증상이 이 간격과 맞아떨어진다. 타이머 백오프의 일반 원리는 TCP RTO 글 과 같은 구조다. tcp_abort_on_overflow=1 이면 대신 RST를 보내 즉시 실패시킨다. 하지만 ip-sysctl 문서는 기본값 0의 이유를 "burst로 인한 overflow라면 회복된다"고 설명한다. RST로 바꾸면 그 회복 기회를 버리는 셈이다. 4. 직접 확인하기 accept하지 않는 서버를 listen(1) 로 띄우고 연결을 여러 개 붙이면 큐가 차는 걸 볼 수 있다. # backlog_demo.py — listen(1) 후 accept()를 하지 않는 서버 import socket, time s = socket.socket() s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(("127.0.0.1", 9999)) s.listen(1) time.sleep(600) python3 backlog_demo.py & nstat -n # 카운터 기준점 리셋 for i in 1 2 3 4; do (sleep 30 | nc 127.0.0.1 9999 &); done ss -lnt 'sport = :9999' # LISTEN 행: Recv-Q=sk_ack_backlog, Send-Q=sk_max_ack_backlog ss -tan 'dport = :9999' # 클라이언트 상태 nstat -az TcpExtListenOverflows TcpExtListenDrops LISTEN 행의 Send-Q는 1인데 Recv-Q가 2 까지 오르면 backlog+1이 보인다. 순차로 붙였으니 3·4번째는 SYN 단계에서 버려져 SYN-SENT로 남고 ListenOverflows 가 오른다. 3번째 ACK 무시 경로는 핸드셰이크가 동시에 겹쳐야 나와서 이 순차 루프로는 재현이 잘 안 된다. 운영에서는 ListenOverflows 가 증가하는지를 먼저 보는 편이 확실하다. 5. 정리 backlog는 완성된 연결의 큐 길이이고, 이 큐가 넘치면 Linux는 기본적으로 거절하지 않고 침묵한다 — 그래서 증상이 refused가 아니라 수 초짜리 멈춤으로 나타난다. "connect는 되는데 첫 응답이 느리다"면 ss -lnt 의 Recv-Q/Send-Q와 nstat 의 ListenOverflows 부터 보고, 앱의 backlog와 somaxconn 을 함께 올리는 게 순서다. 다음으로 파고들 만한 건 syncookie가 MSS·wscale을 쿠키에 싣는 방식과, 데이터가 올 때까지 child 생성을 미루는 TCP_DEFER_ACCEPT 다. 참고 자료 listen(2) — https://man7.org/linux/man-pages/man2/listen.2.html Linux Documentation/networking/ip-sysctl.rst — tcp_abort_on_overflow , tcp_max_syn_backlog , tcp_syncookies , tcp_synack_retries Linux 커널 소스(torvalds/linux) — include/net/sock.h , net/ipv4/tcp_input.c ( tcp_conn_request ), net/ipv4/tcp_minisocks.c ( tcp_check_req ), net/ipv4/tcp_diag.c
666 h have become one of the most popular forms of entertainment in the modern digital world. What started with simple arcade machines has evolved into a massive industry involving smartphones, computers, gaming consoles, virtual reality, and online communities. Today, millions of players around the world enjoy games not only for fun but also for competition, creativity, storytelling, and social connection. Modern games offer experiences that go far beyond traditional entertainment. Players can explore new worlds, solve complex challenges, build communities, and compete with others across the globe. With advancements in technology, games have become more interactive, realistic, and accessible than ever before. From casual mobile games to competitive esports titles, gaming has created a culture that connects people of different ages and backgrounds. The Evolution of Games The history of gaming shows how technology has changed entertainment over time. Early video games focused on simple mechanics and basic graphics. Classic arcade games introduced millions of people to interactive entertainment, while home consoles later allowed players to enjoy games from their own homes. Today, the gaming industry includes: Mobile games PC games Console games Cloud gaming Virtual reality experiences Online multiplayer platforms Companies such as Sony PlayStation, Microsoft Xbox, Nintendo, Valve Steam, and Epic Games have played major roles in shaping modern gaming culture. Why Games Are Popular Worldwide Games attract millions of players because they offer unique experiences that other forms of entertainment cannot provide. Interactive Experiences Unlike movies or television, games allow players to control the action. Every decision, strategy, and movement can influence the outcome. Players become active participants rather than simply watching a story unfold. Entertainment and Relaxation Many people use games as a way to relax after work, school, or daily responsibilities. Games provide creative environments where players can escape into different worlds and enjoy new challenges. Social Connection Gaming has become a social activity. Online multiplayer games allow players to communicate, cooperate, and compete with people from different countries. Platforms like: Discord Twitch Reddit gaming communities YouTube Gaming help players share experiences and build connections. Different Types of Games The gaming industry offers many genres to match different interests. Action Games Action games focus on fast reactions, challenges, and exciting gameplay. They often include combat, exploration, and adventure elements. Strategy Games Strategy games require planning, decision-making, and resource management. Players must think carefully to achieve their goals. Role-Playing Games (RPGs) RPGs allow players to develop characters, explore detailed worlds, and experience deep storytelling. Sports Games Sports games recreate real-world activities such as football, basketball, racing, and other competitions. Puzzle Games Puzzle games challenge players' problem-solving skills through logic-based tasks and creative challenges. The Growth of Mobile Gaming Mobile gaming has changed the way people access entertainment. Smartphones have made games available to billions of users worldwide. The popularity of mobile games comes from: Easy accessibility Affordable devices Quick gameplay sessions Wide variety of genres Android and iOS platforms provide thousands of games that players can enjoy anywhere. Mobile gaming continues to grow because developers are creating better graphics, smoother controls, and more advanced features. Online Multiplayer Gaming Online gaming has created a new era of global competition and cooperation. Players can now join matches with people from around the world and participate in: Team battles Online tournaments Cooperative missions Competitive challenges Games such as Minecraft, Fortnite, League of Legends, and Call of Duty have built some of the largest gaming communities worldwide. The Importance of Gaming Communities Gaming communities help players learn, connect, and improve their skills. Players often share: Gameplay strategies Reviews Tutorials Game updates Recommendations Online communities have become an important part of gaming culture because they allow players to exchange knowledge and support each other. A strong community can make a game more enjoyable by creating friendships and shared experiences. Technology Changing the Future of Games The future of gaming is being shaped by new technologies. Artificial Intelligence AI is helping developers create smarter characters, better environments, and personalized gameplay experiences. Virtual Reality Virtual reality allows players to enter digital worlds and experience games in more immersive ways. Cloud Gaming Cloud gaming allows users to stream games without needing expensive hardware. This technology is making high-quality gaming more accessible. Advanced Graphics Modern game engines create realistic environments, detailed characters, and cinematic experiences. Benefits of Playing Games When enjoyed responsibly, games can provide several benefits. Improving Problem-Solving Skills Many games require players to analyze situations and develop strategies. Encouraging Creativity Creative games allow players to design, build, and experiment with ideas. Developing Teamwork Multiplayer games encourage communication and cooperation. Improving Decision Making Many games require players to make quick decisions and adapt to changing situations. The Rise of Esports Esports has transformed competitive gaming into a professional industry. Players now compete in international tournaments with large audiences and professional teams. Popular esports games include: League of Legends Dota 2 Counter-Strike Valorant Mobile Legends Streaming platforms like Twitch and YouTube Gaming have helped esports reach millions of viewers worldwide. Responsible Gaming Habits While games provide entertainment and learning opportunities, maintaining balance is important. Healthy gaming habits include: Taking regular breaks Managing screen time Protecting personal information Maintaining balance with daily activities Responsible gaming allows players to enjoy entertainment while maintaining a healthy lifestyle. The Future of Gaming The gaming industry will continue to grow as technology improves. Future games may include more realistic environments, advanced AI systems, improved online experiences, and deeper player customization. Gaming is no longer just a hobby. It has become a global culture that combines technology, creativity, competition, and human connection. Conclusion Games have evolved from simple entertainment into a powerful digital industry that connects millions of people worldwide. They provide opportunities for creativity, competition, learning, and social interaction. With advancements in mobile technology, artificial intelligence, virtual reality, and online platforms, the future of gaming looks more exciting than ever. Whether someone enjoys casual mobile games, competitive esports, or immersive adventures, games continue to offer endless possibilities for entertainment and discovery.
1. Jev란: TypeSafe AI의 System One Model LLM에게 "JSON으로 답해줘"라고 부탁하는 대신, 처음부터 소프트웨어가 쓸 수 있는 판단 을 받아오는 방법이다. 생성형 AI 중심의 시스템에서 벗어나 AI는 판단하고 코드는 통제하는 자동화 아키텍처이다. 판단 전용 모델 문장을 만들지 않는다. 대신 구조가 정해진 판단을 한다. 파싱할 것이 없다. 그리고 확률과 확신도가 함께 온다. department billing confidence 1.00 {billing: 1.00, technical: 0.00, sales: 0.00, other: 0.00} refund 0.98 urgency 2.81 confidence 0.81 기존 LLM은 질문을 던지면 사람의 언어(줄글)로 대답하기 때문에, 프로그램에서 그 결괏값을 활용하려면 필요한 정보만 따로 떼어내는 '파싱(Parsing, 구문 분석)' 작업이 필요하다(예: 텍스트에서 JSON 형태만 추출). 반면, Jev는 문장을 생성하는 대신 처음부터 결괏값을 구조화된 데이터 형태로 반환하므로 번거로운 추출 과정이 필요 없다는 의미이다. LLM은 보통 자신이 내놓은 답변에 대해 얼마나 확신하는지 수치로 알려주지 않는다. 하지만 Jev는 결괏값과 함께 그 판단이 맞을 확률 과 확신도(Confidence)를 구체적인 숫자(예: 0.98, 1.00)로 함께 제공한다. 즉, AI가 낸 답을 '얼마나 믿고 써도 될지'를 개발자가 수치로 파악하고 제어할 수 있다는 뜻이다. (출처: wikidocs ) 기존 LLM은 느리다. 판단이 서로 다르다. 확신의 정도를 알 수 없다. 2. Jev의 장점 → 자신이 모르는 것을 안다 자신이 내놓은 판단이 얼마나 확실한지 (confidence) 수치로 알려준다. → 잘 모르는 것은 시스템에 정확히 신호를 보낸다 → 확신하는 쉬운 문제는 저렴하게 처리한다 → 모르는 문제는 비싼 LLM에게 넘겨서 처리할 수 있다 오해 : LLM을 대체하는 것이 아닌 LLM 앞에 판단 계층을 하나 두는 것이다. (출처: wikidocs ) 💡 중요하게 판단해야 하는 것은 : 이 방식이 이 task에 적합한가이다. 3. LLM은 어떻게 답을 만드는가 다음에 올 토큰을 하나씩 예측해서 이어 붙이는 방식이다. ex) 배고프다 라는 입력을 받으면, 다음에 올 법한 조각을 고르고, 그 결과를 다시 입력에 붙여 그 다음 조각을 고른다 → 문장이 끝날 때까지 이 과정을 반복한다. 그로 인한 영향 출력이 길어질수록 시간이 오래 걸린다. 출력은 언제나 문자열이다 → 출력할 때 JSON 형태로 라는 걸 강제해야 한다. 자유로움이 높아서, 실행할 때마다 답이 다르게 나온다. 특히, 속도와 비용 + 확신도가 가장 큰 문제다. 4. 생성과 결정은 다른 일이다 생성(Generation) 결정(Decision) 답의 범위 정해져 있지 않음 미리 정해져 있음 좋은 답 여러 개일 수 있음 보통 하나 출력 형태 문자열 선택지, 숫자, 참/거짓 길이 길수록 좋을 때도 있음 길이가 의미 없음 사람이 하는 일 읽는다 그대로 실행한다 "이 문서를 요약해줘"는 생성이다. 정답이 하나가 아니고, 여러 요약문이 모두 괜찮을 수 있다. 반면 "이 문의를 billing/technical/sales/other 중 어디로 보낼까"는 결정이다. 답은 넷 중 하나이고, 코드는 그 답을 받아 바로 분기한다. "이건 할랄/하람/마슈부 중에 뭐야?"라고 질문한다. LLM에게 질문했을 때 halal 판단 전용 모델 (Jev) halal 0.90 haram 0.00 mashbooh 0.10 System One Model (Jev) 일반 LLM Reasoning LLM 하는 일 판단 생성 추론 출력 구조화된 값 + 확률 문자열 문자열 + 생각 과정 속도 빠름 보통 느림 어울리는 문제 후보가 정해진 반복 판단 글쓰기, 요약, 대화 수학, 코드, 다단계 문제 함께 쓴다면 다음과 같다. (출처: wikidocs ) ⇒ "작업의 성격과 도구의 성격을 맞추자" 5. Jev 사용법 Jev의 호출 부분 state : 판단의 대상 question : state에 대해 묻는 것 → 질문이 여러 개일 수 있다 result = client.system_one( state="결제가 두 번 됐습니다. 빨리 환불해주세요.", questions={ "department": Choice(criteria={"billing": None, "technical": None, "sales": None, "other": None}), "urgency": Score(criteria=["급하지 않음", "보통", "급함", "매우 급함"]), "refund": Noul(instructions="고객이 환불을 요구하고 있는가?"), }, ) → 이 구조를 기반으로 Jev는 여러 질문을 서로 간섭하지 않게 평가하도록 설계되어 있다. 질문 형태 3가지 / Primitive : 기초적이고 핵심적인 판단 블록들 질문 묻는 것 예 Choice 여러 후보 중 어느 것인가 어느 부서로 보낼까 Noul 그런가, 아닌가 환불을 요구하는가 Score 어느 정도인가 얼마나 급한가 Choice from typesafe_sdk import TypeSafeClient, Choice with TypeSafeClient() as client: result = client.system_one( state="앱이 로그인 화면에서 계속 멈춰요.", questions={ "department": Choice(criteria={ "billing": None, "technical": None, "sales": None, "other": None, }) }, ) answer = result.choices["department"] print(answer.choice) # technical print(answer.confidence) # 1.0 print(answer.probabilities) # {'technical': 1.0, 'billing': 0.0, ...} 필드 내용 choice 확률이 가장 높은 후보의 이름 confidence 그 선택에 대한 확신도, 0에서 1 probabilities 후보 전체의 확률, 합은 1 후보를 잘 나누는 법 후보는 서로 겹치지 않게 만든다. → 반반 상황이 생길 수도 있다. 빠진 후보가 있는지 confidence로 확인한다. Other은 넣되 기대하지 않는다. 후보 개수는 늘려도 느려지지 않는다. Noul : 예/아니오에 대한 확률 from typesafe_sdk import TypeSafeClient, Noul with TypeSafeClient() as client: result = client.system_one( state="전액 환불해주세요", questions={"refund": Noul(instructions="고객이 환불이나 결제 취소를 요구하고 있는가?")}, ) print(result.nouls["refund"].noul) # 0.98 Score : 어느 정도인가를 묻는 질문 후보 대신 순서가 있는 단계 목록을 받는다. from typesafe_sdk import TypeSafeClient, Score with TypeSafeClient() as client: result = client.system_one( state="며칠째 답이 없네요. 확인 부탁드립니다", questions={"sentiment": Score(criteria=["차분함", "약간 불만", "화남", "매우 화남"])}, ) answer = result.scores["sentiment"] print(answer.score) # 0.91 print(answer.confidence) # 0.91 print(answer.legend) # {0: '차분함', 1: '약간 불만', 2: '화남', 3: '매우 화남'} print(answer.probabilities) # {0: 0.09, 1: 0.91, 2: 0.0, 3: 0.0} Jev가 하지 않는 것 문장 생성 (요약/번역/답변) 대화 → 챗봇이 아니다 코드 작성 후보에 없는 답 생성 6. 최신 동향 (2026년 10월 기준) 출시 배경 Jev는 2026년 9월 15일 공개됐고, 같은 날 DCVC가 주도한 4천만 달러 규모의 시드 투자도 함께 발표됐다. TypeSafe AI는 전 OpenAI 연구자 Diogo Almeida가 창업한 스타트업이다. 이름은 비용이 떨어지면 소비가 오히려 늘어난다는 역설을 제시한 경제학자 William Stanley Jevons에서 왔고, System One은 Kahneman이 구분한 빠르고 직관적인 System 1 사고를 가리킨다. 새 아키텍처, 새 샘플러, 그리고 RLCD(Reinforcement Learning for Calibrated Decisions)라는 새 학습 알고리즘으로 만들었다고 밝혔다. 속도와 가격 (회사 발표 수치) 응답 시간은 70~500ms, 가격은 입력 토큰 100만 개당 0.042달러이며 출력은 무료다. 모든 필드를 토큰 하나씩이 아니라 한 번에 만들어내는 병렬 샘플링이 속도의 근거라고 설명한다. → 3장의 "출력이 길어질수록 시간이 오래 걸린다" 문제를 구조적으로 피한 것이다. 접근 경로 현재 공개 버전은 jev-1.13.0이다. TypeSafe API를 직접 쓰려면 대기자 명단을 거쳐야 하지만, Vercel AI Gateway와 Cloudflare Workers AI에서는 대기 없이 쓸 수 있다. OpenRouter에서도 typesafe/jev-1.13이라는 이름으로 호출할 수 있다. 한계: Jev 1.13 jaggedness TypeSafe는 현재 모델의 약점을 정리한 jaggedness 문서를 직접 공개했다. 정리된 실패 유형은 9가지다: 문자 그대로 읽기, 개수 세기, 숫자와 날짜, 간접 참조, 관련 없는 state, 적대적 콘텐츠, 서로 모순되는 기준, 구조적 불변식, 생성. 대표적인 예 개수를 안정적으로 세지 못한다. 그래서 조건에 맞는 항목 수를 셀 때는 코드에서 후보를 하나씩 돌며 각각 질문하고, 답을 직접 더하라고 권한다. 날짜를 순서가 있는 값이 아니라 텍스트로 읽는다. Choice의 선택지 순서가 답에 영향을 주는 경우가 있고, 앞쪽 선택지 쪽으로 기우는 경향이 관찰됐다. state에 관련 없는 내용이 섞이면 정확도가 떨어진다(context rot). 같은 입력에서 논리적으로 동일한 Noul 질문과 Choice 질문이 0.22와 0.01처럼 크게 다른 확률을 반환한 사례도 문서에 나와 있다. "환각이 없다"의 의미 정의한 스키마 밖의 값을 반환하지 않는다는 뜻이지, 틀리지 않는다는 뜻은 아니다. Hacker News에서도 이 점이 크게 지적됐다. 즉 LLM의 실패가 "없는 답을 지어내는 것"이라면, Jev의 실패는 "있는 후보 중 틀린 것을 고르는 것"이다. 입력과 운영 제약 state와 질문 전체를 합친 입력 한도는 64k 토큰이다. Choice 선택지는 최대 255개이고, 데이터는 미국에서 처리되며 미세 조정(fine-tuning)은 불가능하다. 대응 방향 문서의 대응책 대부분은 같은 방향이다: 로직은 코드에 두고, Jev에게는 잘하는 좁은 판단만 맡긴다. 비용이 큰 행동일수록 더 높은 confidence를 요구하고, confidence가 낮은 경우는 사람에게 넘긴다. → 2장의 "모르는 문제는 다른 곳으로 넘긴다"와 같은 구조다. 경쟁 모델 등장: Liquid AI d1 Liquid AI는 9월 29일 첫 결정 모델 d1을 공개했다. d1은 Jev의 세 가지 판단 방식인 Choice, Noul, Score와 호환된다. Hugging Face의 Decision Index 0.2.1에서 d1은 58.9점, Jev 1.13은 57.9점이다. 단, Liquid AI가 직접 돌린 결과다. Liquid AI는 다국어 평가, 프롬프트 인젝션에 대한 견고성, 긴 입력 처리에서 앞선다고 주장한다. 현재 무료 버전(d1:free)으로 쓸 수 있고, 가중치와 파라미터 크기는 아직 공개되지 않았다. 로컬 실행 가능 여부를 묻는 질문에는 가능하게 하겠다고 답했다. → "판단 전용 모델"이 하나의 모델이 아니라 하나의 카테고리로 자리 잡는 중이다. 7. 실습 코드 실습 환경 conda create -n jev python=3.12 -y conda activate jev pip install typesafe-sdk python-dotenv openai 예제 코드 https://github.com/ady95/jev_tutorial 참고 자료 TypeSafe AI 공식 문서: https://docs.typesafe.ai Python SDK: https://github.com/typesafe-ai/typesafe-sdk-python System One Model 발표 글: https://typesafe.ai/blog/introducing-system-one-models-and-jev Jev 1.13 jaggedness: https://docs.typesafe.ai/model-jaggedness/jev-1.13 출처 : https://wikidocs.net/book/21376 Liquid AI, 문장 생성 대신 Jev 호환 API로 분류 / 라우팅 / 점수를 처리하는 결정 모델 d1 공개 A decision-making model, 'd1,' has emerged that surpasses Jev in benchmarks - GIGAZINE What Is Jev AI? TypeSafe's System One Model, and Where It Fits in an Agent Harness - Width.ai Decision models experiments - Baobab Tech