URL 상태와 AI 모델, 둘 다 '올바른 것을 올바른 곳에' 설계하라

URL 상태와 AI 모델, 둘 다 '올바른 것을 올바른 곳에' 설계하라

nuqs로 URL을 진짜 상태 컨테이너로 만들고, GPT-5.6 3단계 모델 전략으로 비용을 설계하는 두 흐름이 가리키는 하나의 원칙.

nuqs URL 상태 관리 Next.js App Router GPT-5.6 모델 라우팅 Server Component MCP 설계 원칙
광고

좋은 설계는 늘 같은 질문에서 출발한다. 지금 이 값은, 지금 이 곳에 있어야 하는가? 이번 주 두 가지 흐름이 동시에 그 질문을 건드렸다. 하나는 URL을 진짜 상태 컨테이너로 격상시키는 nuqs이고, 다른 하나는 AI 모델을 태스크 복잡도에 따라 3단계로 라우팅하는 GPT-5.6의 구조다. 표면은 전혀 다르지만, 두 흐름이 공유하는 설계 원칙은 놀랍도록 닮아 있다.


nuqs: URL이 상태다

데이터 테이블, 검색 페이지, 필터 목록. 세 종류의 UI는 늘 같은 문제를 공유한다. 사용자가 필터를 적용하고 URL을 복사해서 동료에게 보내면, 동료는 빈 페이지를 마주한다. 필터 상태가 useState 안에 살고 있었기 때문이다. 컴포넌트가 언마운트되는 순간, 상태도 함께 사라진다.

nuqs는 이 문제를 API 레벨에서 해결한다. useState와 동일한 인터페이스로, 상태 컨테이너만 메모리에서 URL로 바꾼다. useQueryState('q')를 쓰는 순간 검색어는 ?q=keyboard로 URL에 박히고, 새로고침해도 살아있고, 공유하면 상대방도 같은 결과를 본다. 개념은 단순하지만 실제 코드에서 이걸 직접 구현하려면 히스토리 조작, 직렬화, 타입 변환까지 손으로 챙겨야 했던 것들을 라이브러리가 통째로 가져간다.

특히 눈에 띄는 건 Server Component 통합이다. createSearchParamsCache를 사용하면 클라이언트의 필터 컴포넌트와 서버의 DB 쿼리가 동일한 파서 정의를 공유한다. shallow: false 옵션 하나로 URL 변경이 실제 서버 재렌더링을 트리거하고, searchParams를 읽는 Server Component가 갱신된 값을 받아간다. App Router의 풀스택 데이터 흐름 안에서 필터 상태가 자연스럽게 순환하는 구조다. dev.to의 nuqs 실사례 아티클을 보면, startTransitionuseQueryStates를 조합해 여러 필터를 원자적으로 업데이트하면서 로딩 피드백까지 자연스럽게 처리하는 패턴이 잘 정리되어 있다.

타입 안전성도 놓치지 않는다. parseAsInteger, parseAsStringEnum, parseAsIsoDate, parseAsArrayOf — URL 파라미터를 문자열로만 다루던 세계에서 타입 시스템이 작동하는 세계로 넘어온다. .withDefault()를 붙이면 파라미터가 없을 때 null 대신 의도한 기본값이 반환된다. URL 상태가 불확실한 외부 입력이 아니라, 예측 가능한 애플리케이션 상태로 다뤄지기 시작하는 지점이다.


GPT-5.6: 모델도 라우팅이다

같은 날 OpenAI가 GPT-5.6을 출시했다. 단일 모델이 아니라 Sol, Terra, Luna 세 개의 티어로 구성된 패밀리다. 스펙은 동일하다. 세 모델 모두 1M 토큰 컨텍스트, 128K 최대 출력, MCP 네이티브 지원을 공유한다. 차이는 비용과 추론 깊이다. Sol은 입력 $5/1M 토큰의 플래그십, Terra는 $2.50의 밸런스드, Luna는 $1.00의 경량 티어다. Sol이 Luna보다 5배 비싸다.

흥미로운 건 이 구조가 단순한 가격 정책이 아니라는 점이다. dev.to에 게재된 MCP 서버 테스팅 실사례에서 저자는 한 주 동안 세 모델을 동일한 MCP 서버에 교차로 테스트한 결과를 공유한다. 핵심 발견은 명확하다. Luna로 시작하고, 필요할 때만 올라가라. 단순 읽기 작업이나 스모크 테스트는 Luna로 충분하고, 8단계 이상의 의존적 체이닝이나 쓰기 작업을 포함한 복잡한 에이전트 플랜은 Sol이 필요하다. Terra는 그 사이 대부분의 실무 자동화를 커버한다.

GPT-5.6의 또 다른 핵심은 Programmatic Tool Calling이다. 기존 MCP 루프는 툴 호출마다 모델로 왕복했다. 10번 호출이면 10번의 비싼 턴이 발생했다. GPT-5.6은 툴 체이닝 로직을 JavaScript 스크립트로 작성해 격리된 V8 샌드박스에서 일괄 실행한다. OpenAI가 보고한 토큰 절감은 38~63.5%. 단순히 빠른 게 아니라, 에이전트 루프의 비용 구조 자체가 바뀌는 변화다.


두 흐름이 말하는 하나의 원칙

nuqs와 GPT-5.6 3단계 전략은 서로 다른 도메인에서 같은 설계 감각을 드러낸다. 상태는 그 상태를 소비하는 가장 넓은 범위에 두어야 한다. 필터 상태가 컴포넌트 메모리에 갇혀 있으면, 그것을 필요로 하는 URL 공유와 서버 렌더링은 불가능하다. URL에 두는 순간, 컴포넌트·서버·브라우저 히스토리가 동시에 같은 진실을 본다.

모델 선택도 마찬가지다. 모든 태스크를 Sol로 처리하면 비용 구조가 망가진다. 모든 태스크를 Luna에 맡기면 복잡한 플랜이 중간에 무너진다. 태스크의 복잡도를 읽고, 거기에 맞는 모델 티어로 라우팅하는 것 — 이건 단순한 비용 절감 전술이 아니라 시스템 설계의 문제다. 어떤 판단이 어느 레이어에서 이뤄져야 하는지를 명확히 정의하지 않으면, 속도와 비용 중 하나는 반드시 무너진다.

두 도구가 공통으로 요구하는 것은 결국 명시성이다. nuqs는 파서를 정의하게 만든다. URL에 무엇이 들어가고, 어떤 타입으로 읽히고, 기본값이 무엇인지를 코드로 선언해야 한다. GPT-5.6도 마찬가지다. 어떤 워크플로우가 어느 티어에 속하는지를 팀이 명시적으로 결정하지 않으면, 기본값은 늘 가장 비싼 모델이 된다.


전망: 라우팅 레이어가 경쟁력이 된다

nuqs가 보여주는 방향은 App Router 생태계의 다음 단계와 맞닿아 있다. Partial Prerendering이 안착되면 동일한 페이지에서 정적 셸과 동적 스트림이 분리된다. 그 경계에서 URL 상태는 서버와 클라이언트 사이의 유일한 동기화 채널이 된다. URL 상태 설계를 지금 정밀하게 가져가지 않으면, PPR 전환 시점에 상태 불일치가 조용히 터질 것이다.

GPT-5.6의 3단계 구조는 앞으로 더 세분화될 가능성이 높다. 비용과 추론 깊이의 트레이드오프를 태스크 단위로 자동 라우팅하는 오케스트레이션 레이어 — 이것이 에이전트 인프라의 다음 경쟁 지점이다. 이미 여러 프레임워크가 모델 폴백과 라우팅 로직을 추상화하기 시작했고, nuqs가 URL 파서를 추상화한 것처럼 모델 선택도 선언적 설정으로 수렴할 것이다.

두 도구를 동시에 바라보면 하나의 문장이 남는다. 올바른 상태를 올바른 곳에, 올바른 모델을 올바른 태스크에. 설계의 본질은 언제나 같다. 지금 이 값이, 지금 이 자리에 있어야 하는 이유를 설명할 수 있는가.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요