화면은 여전히 아름다워지고 있다. 그런데 그걸 보는 게 눈이 없는 것들이다
Apple은 올해 WWDC에서 두 가지 이야기를 동시에 했다. 하나는 Liquid Glass, 새로운 투명도 슬라이더, 더 정교한 엣지 처리—화면을 더 아름답게 만드는 이야기였다. 다른 하나는 App Intents, View Annotations API, 그리고 Anthropic·Google·OpenAI의 코딩 에이전트가 MCP로 연결된 Xcode—화면을 보지 않고도 앱을 조작할 수 있게 만드는 이야기였다. 아무도 "UI는 끝났다"고 말하지 않았지만, 두 메시지를 나란히 놓으면 방향은 분명하다. 프론트엔드의 '정문'이 바뀌고 있다.
상태의 주인이 둘이면, 반드시 어긋나는 순간이 온다
기계가 읽는 인터페이스 이야기를 하기 전에, 먼저 사람이 읽는 인터페이스조차 제대로 설계하고 있는지 짚어볼 필요가 있다. velog에 올라온 사례가 이 지점을 정확하게 찌른다. 이슈 검색 페이지에서 프로젝트·저장소·검색어를 조합해 결과를 보다가 새로고침을 누르면—전부 초기화된다. 주소를 복사해 동료에게 보내면—받은 사람은 내가 보던 화면이 아니라 기본값 화면을 본다. 뒤로가기를 누르면 URL은 이전 검색으로 돌아가는데 화면은 그대로다. 버그처럼 보이지만 QA를 돌리면 "기능"은 전부 통과한다. 무너지는 건 기능이 아니라 사용자의 실제 사용 흐름이기 때문이다.
원인을 파고들면 구조 문제다. 검색 조건 상태가 Zustand 스토어에도 있고 URL에도 있었다. 주인이 둘이면 반드시 어긋나는 순간이 온다. 스토어를 갱신하고 URL 갱신을 빼먹은 경로 하나, URL은 바뀌었는데 스토어가 따라가지 않는 뒤로가기 하나—동기화 코드는 늘어나는데 버그는 줄지 않는 구조다. 해법은 동기화를 더 잘하는 게 아니라 사본을 없애는 것이다. 이 사례가 도달한 결론은 상태를 두 층으로 나누는 것이었다. 조건 폼의 현재 값은 로컬 state가 소유하는 '초안'이고, 검색 실행 순간—사용자가 "이 조건으로 검색해줘"라고 확정하는 순간—조건 세트 전체가 URL에 커밋된다. 결과 화면은 URL만 읽어서 그린다. 흐름이 한 방향 순환이 된다: 초안(로컬) → 커밋(URL) → 초안 재초기화(URL → 로컬).
이 설계가 중요한 이유는 단순히 버그 수정이 아니다. URL이 상태의 단일 진실 공급원이 될 때, 그 화면은 공유 가능하고 복원 가능하고 히스토리를 갖는다. 사람이 링크를 복사해 보내도, 북마크를 열어도, 뒤로가기를 눌러도 화면과 주소가 같은 말을 한다. 그리고 여기서 한 발 더 나아가면—에이전트도 URL 하나로 그 화면에 정확히 진입할 수 있다.
기계가 읽는 인터페이스: llms.txt보다 더 근본적인 질문
dev.to에 올라온 글은 이 흐름을 더 직접적으로 다룬다. 결제 회사에서 MCP 서버를 만들어 에이전트가 대시보드를 열지 않고도 결제 조회와 환불 처리를 할 수 있게 한 경험—그 작업을 하고 나서 깨달은 것은 "정성껏 설계한 대시보드가 제품이 아니었다. 기계가 읽을 수 있는 깔끔한 버전이 제품이었다"는 것이다. Siri, Copilot, Claude—고객이 어떤 에이전트를 쓰든, 그 에이전트는 히어로 애니메이션에 관심 없다. 당신의 서비스가 무엇을 할 수 있는지 이해하고, 그것을 실행할 수 있는지에만 관심 있다.
이 맥락에서 llms.txt 붐이 일었다. 마크다운으로 구조화된 텍스트를 제공하면 에이전트가 읽는 토큰이 절반 이하로 줄고, 어떤 팀은 10배 효율을 보고한다는 것도 사실이다. 하지만 같은 글이 솔직하게 인정한다—주요 AI 크롤러(OpenAI, Google, Anthropic)는 llms.txt를 대부분 가져가지 않는다. 30만 도메인 연구에서 AI 인용에 측정 가능한 차이가 없었다. 오늘 llms.txt가 실제로 값어치를 하는 곳은 Cursor, Claude Code, GitHub Copilot 같은 코딩 에이전트와 문서 사이트다. 가치를 얻는 팀들은 이걸 마케팅이 아니라 배관으로 취급한다. 그 태도 차이가 전부다.
그렇다면 진짜 질문은 이거다. 에이전트가 당신 제품의 핵심 태스크를 스크린샷 없이 처음부터 끝까지 완료할 수 있는가? 이걸 테스트로 만들어야 한다. "신규 엔지니어가 5분 안에 전체 스택을 실행할 수 있는가"와 같은 급의 first-class 테스트로. 이 테스트를 통과하려면 세 가지가 필요하다: 모든 중요한 서피스에 에이전트가 소비할 수 있는 깔끔한 텍스트 표현, 페이지 상단의 2~3줄짜리 요약(사람에게도 에이전트에게도 동시에 작동한다), 그리고 콘텐츠가 아닌 동사—"환불해줘", "예약해줘", "지난달 보여줘" 같은 실행 가능한 액션의 노출.
브라우저 네이티브 시맨틱 서치: 사람과 기계를 동시에 만족시키는 UX 기술
이 맥락에서 흥미로운 기술 사례가 하나 있다. dev.to에 소개된 altor-vec—HNSW 벡터 서치를 54KB WASM으로 컴파일해 백엔드 없이 브라우저에서 시맨틱 서치를 구현한 프로젝트다. Fuse.js가 "이 문자열이 저 문자열처럼 생겼는가"를 묻는다면, 이 접근은 "이 의미가 저 의미와 가까운가"를 묻는다. "cancel my plan"을 검색해도 "end your subscription" 문서를 찾아준다.
기술적 구조는 간단하다. 빌드 타임에 Hugging Face의 all-MiniLM-L6-v2 모델로 문서 임베딩을 생성해 HNSW 인덱스로 직렬화하고, CDN에 정적 파일로 올린다. 런타임엔 54KB WASM 모듈과 ~23MB 임베딩 모델을 로드해 쿼리당 1ms 미만의 검색을 브라우저에서 수행한다. 서버 없음, API 키 없음, 쿼리당 비용 없음. 성능 숫자는 실제적이다—10K 벡터 기준 p95 쿼리 타임 1ms 미만, Chrome 기준.
이 기술이 '사람과 에이전트 모두를 위한 프론트엔드'라는 주제에 연결되는 이유가 있다. 시맨틱 서치는 단순히 검색 UX 개선이 아니다. 문서와 콘텐츠를 의미 단위로 구조화하는 작업—임베딩 인덱스를 만드는 작업—은 에이전트가 콘텐츠를 이해하는 방식과 본질적으로 같다. 빌드 타임에 의미 구조를 명시적으로 생성해두는 것, 그게 사람에겐 더 나은 검색 경험이고 에이전트에겐 더 읽기 쉬운 컨텍스트가 된다. 물론 트레이드오프는 있다—수백만 문서엔 서버가 필요하고, 실시간 업데이트 콘텐츠엔 맞지 않는다. 하지만 문서 사이트, 내부 툴, 마케팅 사이트처럼 배포 단위로 업데이트되는 환경엔 지금 당장 쓸 수 있다.
프론트엔드 설계의 새 기준: 에이전트 테스트를 통과하는 구조
세 가지 흐름을 묶으면 하나의 설계 원칙이 나온다. 상태의 주인을 명확히 하고, 기계가 읽을 수 있는 표현을 first-class output으로 만들고, 의미 구조를 빌드 타임에 생성하라. 이 세 가지는 사실 사람을 위한 UX 원칙이기도 하다. URL이 상태를 소유할 때 화면은 공유 가능해지고, 요약과 액션이 명시적일 때 사람도 더 빠르게 파악하며, 시맨틱 서치는 사람의 자연어 쿼리를 더 잘 이해한다.
UI가 강등됐다고 해서 UI가 중요하지 않다는 뜻이 아니다. Apple이 WWDC에서 보여준 것처럼, 화면을 더 아름답게 만드는 작업과 화면 없이도 작동하게 만드는 작업은 모순이 아니다. 그게 지금 우리가 있는 곳이다. 진짜 질문은 하나다—에이전트가 새 유저라면, 눈이 없는 것에게 당신의 제품은 어떻게 보이는가?