SNA가 뭔가요?
SNA의 역할, 해결하는 문제, 적합한 사용처를 정리합니다.
SNA (Skills-Native Application)는 에이전트 런타임 위에 제품을 만들기 위한 SDK입니다. 앱이 LLM API를 직접 호출하는 대신 작은 서버에 요청하면, 그 서버가 Claude Code, Codex, OpenCode 프로세스를 관리합니다. SNA는 세 런타임을 하나의 정규화된 API로 다룹니다.
SNA가 왜 시작되었는지는 출발점 에 짧게 적어 두었습니다.
구조
your app
│
│ HTTP (request/response, ordering)
│ WS (live events, fanout)
▼
SNA server ──spawn──► claude-code | codex | opencode
│
▼
SQLite (canonical history)서버 하나를 띄우고 세션을 한 개 이상 엽니다. 각 세션에서는 실제
CLI 바이너리(claude, codex, opencode)가 자식 프로세스로 spawn됩니다.
SNA는 각 런타임의 이벤트, 히스토리, 권한 모델을 같은 형태로 맞추기 때문에
앱 코드가 런타임별 분기로 흩어지지 않습니다.
용어 기준: 공개 문서에서는 Claude Code, Codex, OpenCode 같은 실행 대상을
런타임이라고 부릅니다. 다만 기존 SDK 호환성을 위해 API 필드명
provider, providerOptions, modelProvider는 그대로 유지합니다.
어떤 문제를 푸는지
공식 LLM API는 무상태 completion에는 잘 맞습니다. 하지만 제품이 다음 요구를 갖는 순간 구현이 복잡해집니다.
- 툴, 파일 편집, 승인이 있는 장기 실행 에이전트: 결국 Claude Code나 Codex의 루프를 직접 재구현하게 됩니다.
- 같은 에이전트를 다른 런타임으로 전환: 코드 편집은 Claude, 이미지 생성은 Codex, 비용 최적화는 OpenCode처럼 나누고 싶어도, 런타임을 바꿀 때마다 통합 코드를 다시 써야 합니다.
- 런타임 교체에도 이어지는 대화 히스토리: 네이티브 포맷들이 서로 호환되지 않기 때문에, 하나의 런타임에 묶이거나 교체할 때마다 맥락을 잃게 됩니다.
- 사용자에게 같은 모양으로 보이는 권한 흐름: Claude의 PreToolUse 훅과 Codex의 JSON-RPC 승인은 프로토콜과 UX가 서로 다릅니다.
SNA는 "실제 CLI를 그대로 사용한다" 는 방향으로 이 문제를 풉니다. CLI들은 이미 어려운 일(툴 디스패치, 샌드박싱, 권한 게이팅, 히스토리)을 처리합니다. SNA는 이를 감싸서 하나의 앱 코드베이스가 세 런타임 모두에서 동작하게 합니다.
모델 API나 SDK로 직접 만들면 안 되나요?
모델 API와 벤더 SDK는 무상태 모델 호출에는 좋은 계층입니다. 하지만 그 자체가 에이전트 런타임은 아닙니다. API 위에 직접 만들면 제품이 API 키 관리, 툴 오케스트레이션 루프, 승인 UX, 파일 편집 처리, 스트리밍 이벤트 모양, 재시도, 히스토리 포맷을 직접 책임져야 합니다.
SNA는 다른 경로를 택합니다. 각 런타임이 제공하는 agentic CLI harness를 오케스트레이션합니다. 이 harness는 모델을 만든 회사들이 자기 모델과 가장 잘 맞도록 다듬어 둔 실행 계층입니다. 컨텍스트를 어떻게 준비할지, 툴을 어떻게 호출할지, 권한을 어떻게 물어볼지, 샌드박스 경계를 어떻게 지킬지, 긴 작업을 어떻게 이어갈지가 이미 들어 있습니다. SNA는 그 harness를 버리지 않고, 앱이 보는 API만 하나의 형태로 정규화합니다.
| 직접 API / SDK 통합 | SNA |
|---|---|
| 앱이 보통 모델 API 키를 수집, 저장, 프록시해야 합니다. | 호스트에서 인증된 CLI를 실행하고 SNA가 그 로컬 런타임을 제어합니다. |
| 에이전트 루프를 직접 만들어야 합니다. | 모델별 루프는 runtime CLI harness가 담당합니다. |
| 히스토리 로드, 프롬프트 재전송, 캐시 설정을 직접 구현해야 합니다. | 같은 SNA 세션을 이어가기만 하면 됩니다. SNA가 런타임 네이티브 대화/thread를 유지하고, 필요할 때만 정규화 히스토리에서 재개합니다. |
| 툴 호출, 승인, 파일 편집, 스트리밍 이벤트를 런타임마다 따로 맞춰야 합니다. | SNA가 하나의 세션, 이벤트, 권한 프로토콜로 노출합니다. |
| 런타임을 바꾸면 통합 코드를 다시 쓰거나 히스토리를 잃기 쉽습니다. | SNA가 정규화된 session block에서 runtime-native history를 재구성합니다. |
SNA도 실행 환경에는 CLI 설치와 인증이 필요합니다. 차이는 제품이 낮은 수준의 completion API 위에서 각 모델 벤더의 agent harness를 다시 만들 필요가 없다는 점입니다.
무엇을 받게 되는지
- 하나의 정규화된 대화 모델. 메시지는 두 축을 가진 평탄한 블록으로
저장됩니다:
actor(user/assistant/system) ×kind(text/thinking/tool_use/tool_result/status/error). 런타임 네이티브 포맷은 필요할 때 여기서 파생됩니다. 설계 배경은 Actor와 kind 에 있습니다. - 캐시 친화적인 세션 연속성. 일반적인 흐름에서는 같은 SNA 세션에
다음 턴을
agent.send로 보내면 됩니다. SNA가 활성 런타임의 네이티브 대화/thread를 유지하고, 프로세스를 다시 만들어야 할 때만 정규화 히스토리에서 재개합니다. 앱이 대화를 이어가기 위해 히스토리를 다시 로드하거나 프롬프트를 재전송하거나 캐시 키를 직접 설정할 필요가 없습니다. - 3계층 어트리뷰션. 모든 블록이
provider(런타임),modelProvider(벤더),model(슬러그)을 기록합니다. 세션 도중 무엇을 바꿔도 각 블록의 출처가 보존됩니다. - 정규화된 이벤트 프로토콜. WebSocket 또는 SSE 위 15가지 이벤트
타입:
assistant_delta,tool_use,permission_needed,complete등. - 정규화된 권한 흐름. 하나의 API가 Claude의 PreToolUse 훅과 Codex의 JSON-RPC 승인 양쪽을 모두 노출합니다. 앱의 승인 다이얼로그는 런타임에 따라 바뀌지 않습니다.
- 재시작 없이 런타임 제어. 스레드 도중 모델, 권한 모드, 작업 디렉토리를 바꿀 수 있습니다. Restart와 resume이 정규화 블록에서 런타임 네이티브 히스토리를 재구성합니다.
- 일급 단발 API.
completion()과runOnce()는 세션 관리 없이 단발 호출을 처리합니다. 자동완성이나 채팅 이름 짓기처럼 짧은 단일 프롬프트 작업에 적합하며, 스트리밍 콜백도 옵션으로 사용할 수 있습니다.
누구를 위한 것
- 에이전트 CLI 위에 채팅/코파일럿을 올리는 제품 빌더. SNA는 앱과 런타임 사이의 경계입니다. 앱은 UI를 맡고, SNA는 런타임 연결을 맡습니다.
- 멀티 런타임 앱. Claude Code, Codex, OpenCode 사이에서 사용자가 고르게 하거나 자동 라우팅하고 싶지만, 런타임별로 통합 코드를 쪼개고 싶지 않은 경우.
- Electron / 데스크톱 앱. 에이전트를 로컬에 임베드합니다. 런처가 서버를 자식 프로세스로 fork하고, asar-unpacked 경로 처리, 네이티브 바인딩 위치 찾기까지 합니다.
무엇이 아닌지
- 호스팅된 LLM 엔드포인트가 아닙니다. SNA는 자신이 도는 호스트에서 실제 CLI를 spawn합니다. 바이너리와 인증 정보는 사용자가 제공합니다.
- 에이전트 프레임워크가 아닙니다. 에이전트를 어떻게 만들지 알려주지 않습니다. 그 역할은 Claude Code / Codex / OpenCode가 담당하며, SNA는 앱이 해당 런타임을 제어할 수 있게 해주는 계층입니다.
- 하위 CLI 동작을 숨기는 래퍼가 아닙니다. Claude Code가 파일을 편집하면 실제 편집이 보입니다. Codex가 이미지를 생성하면 실제 파일 경로를 받습니다. SNA는 형태를 정규화하지만 의미를 바꾸지는 않습니다.
SNA를 Zed의 Agent Client Protocol과 비교한다면 SNA와 ACP 를 같이 보세요.
다음 행선지
5분짜리 실습은 시작하기 에 있습니다. 서버를 부팅하고, 세션을 열고, 프롬프트를 보내고, 이벤트를 확인하는 흐름을 다룹니다. 그 다음에는 핵심 모델 에서 세션 모델, 정규화 히스토리, 런타임을 이어서 보세요. 와이어 레퍼런스는 API Spec 에 정리되어 있습니다.