<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Control Plane on jyukki's Blog</title><link>https://jyukki.com/tags/control-plane/</link><description>Recent content in Control Plane on jyukki's Blog</description><generator>Hugo -- 0.147.0</generator><language>ko-kr</language><lastBuildDate>Fri, 08 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jyukki.com/tags/control-plane/index.xml" rel="self" type="application/rss+xml"/><item><title>백엔드 커리큘럼 심화: Control Plane과 Data Plane 분리 운영 플레이북</title><link>https://jyukki.com/learning/deep-dive/deep-dive-control-plane-data-plane-separation-playbook/</link><pubDate>Fri, 08 May 2026 00:00:00 +0000</pubDate><guid>https://jyukki.com/learning/deep-dive/deep-dive-control-plane-data-plane-separation-playbook/</guid><description>서비스 설정, 라우팅, 정책 배포를 담당하는 Control Plane과 실제 요청 처리를 담당하는 Data Plane을 분리할 때의 설계 기준과 장애 대응 기준을 정리합니다.</description><content:encoded><![CDATA[<p>백엔드 시스템이 작을 때는 설정 변경, 라우팅 정책, 인증 규칙, 실제 요청 처리가 한 애플리케이션 안에 섞여 있어도 큰 문제가 없어 보입니다. 관리자 API가 DB 값을 바꾸고, 서버는 그 값을 읽어 요청을 처리합니다. 하지만 트래픽이 커지고 여러 팀이 같은 플랫폼을 쓰기 시작하면 이 구조는 금방 위험해집니다. 정책 변경 하나가 전체 요청 경로를 멈추거나, 관리자 화면 장애가 실서비스 장애로 전파되거나, 잘못된 설정이 모든 인스턴스에 동시에 퍼질 수 있기 때문입니다.</p>
<p>이때 필요한 관점이 <strong>Control Plane</strong>과 <strong>Data Plane</strong> 분리입니다. Control Plane은 설정, 정책, 라우팅 규칙, 배포 의사결정처럼 시스템을 &ldquo;어떻게 동작시킬지&rdquo; 결정합니다. Data Plane은 사용자 요청, 메시지 처리, DB 조회, 파일 전송처럼 실제 트래픽을 &ldquo;지금 처리&quot;합니다. 이 둘을 분리하면 운영 변경을 더 안전하게 만들 수 있지만, 반대로 설정 전파 지연, stale policy, 이중 관측성, 롤백 복잡도가 생깁니다. 이 글은 <a href="/learning/deep-dive/deep-dive-service-mesh-istio/">Service Mesh</a>, <a href="/learning/deep-dive/deep-dive-config-management/">설정 관리</a>, <a href="/learning/deep-dive/deep-dive-feature-flags/">Feature Flag</a>, <a href="/learning/deep-dive/deep-dive-slo-sli-error-budget/">SLO와 Error Budget</a>을 하나의 운영 기준으로 묶어 정리합니다.</p>
<h2 id="이-글에서-얻는-것">이 글에서 얻는 것</h2>
<ul>
<li>Control Plane과 Data Plane을 단순 용어가 아니라 장애 전파 경계로 이해할 수 있습니다.</li>
<li>설정 변경, 라우팅 정책, 권한 정책을 어떤 숫자 기준으로 배포하고 롤백할지 정리할 수 있습니다.</li>
<li>Control Plane 장애가 Data Plane 장애로 번지지 않게 캐시, 버전, 기본값, 관측 지표를 설계하는 방법을 가져갈 수 있습니다.</li>
</ul>
<h2 id="핵심-개념이슈">핵심 개념/이슈</h2>
<h3 id="1-control-plane은-결정하고-data-plane은-처리한다">1) Control Plane은 결정하고, Data Plane은 처리한다</h3>
<p>Control Plane은 시스템의 의사결정 계층입니다. 예를 들어 API Gateway의 라우팅 테이블, 서비스 디스커버리의 엔드포인트 목록, feature flag 상태, rate limit 정책, tenant별 quota, 인증 공개키 배포, 배포 오케스트레이터의 rollout 상태가 여기에 속합니다. Data Plane은 이 결정을 사용해 실제 요청을 처리합니다. HTTP 요청을 라우팅하고, 메시지를 소비하고, DB 쿼리를 실행하고, 파일을 내려주는 경로입니다.</p>
<p>분리 기준은 코드 위치가 아니라 <strong>실패했을 때 누가 영향을 받는가</strong>입니다. 관리자 UI가 죽었는데 기존 사용자 요청까지 실패한다면 분리가 약한 것입니다. 반대로 새 정책 등록은 안 되지만 이미 배포된 정책으로 기존 트래픽이 계속 처리된다면 분리가 잘 된 편입니다.</p>
<p>초기 의사결정 기준은 이렇게 둘 수 있습니다.</p>
<ul>
<li>요청 처리 p95에 직접 들어가는 로직은 Data Plane으로 본다.</li>
<li>사람이 바꾸는 설정, 정책, 승인, 배포 상태는 Control Plane으로 본다.</li>
<li>Control Plane 장애 시 Data Plane은 최소 <strong>30분 이상 기존 정책으로 동작</strong>해야 한다.</li>
<li>정책 전파 지연 허용치는 일반 설정 <strong>1분 이하</strong>, 보안 차단 정책 <strong>10초~30초 이하</strong>로 나눈다.</li>
<li>정책 버전은 모든 요청 로그와 트레이스에 남긴다.</li>
</ul>
<p>핵심은 &ldquo;분리했으니 안전하다&quot;가 아닙니다. Data Plane이 Control Plane에 실시간으로 매번 묻는 구조라면 사실상 분리되지 않은 것입니다.</p>
<h3 id="2-data-plane은-control-plane을-동기-호출하면-안-된다">2) Data Plane은 Control Plane을 동기 호출하면 안 된다</h3>
<p>가장 흔한 사고는 요청마다 Control Plane API를 호출하는 구조입니다. 예를 들어 매 요청마다 중앙 설정 서버에서 rate limit 정책을 읽거나, 인증 서버에서 tenant 권한을 조회하거나, 서비스 디스커버리 API를 실시간으로 호출하면 Control Plane 지연이 곧 사용자 지연이 됩니다. Control Plane 장애가 전체 서비스 장애가 되는 순간입니다.</p>
<p>기본 구조는 로컬 캐시 또는 sidecar/cache agent를 둔 비동기 전파입니다.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>control plane -&gt; policy snapshot/version -&gt; data plane local cache -&gt; request handling
</span></span></code></pre></div><p>운영 기준은 다음처럼 잡을 수 있습니다.</p>
<ul>
<li>Data Plane 요청 경로에서 Control Plane 동기 호출을 금지한다.</li>
<li>로컬 정책 캐시 TTL은 서비스 성격에 따라 <strong>30초~5분</strong>으로 둔다.</li>
<li>마지막 정상 snapshot이 있으면 Control Plane 장애 중에도 계속 사용한다.</li>
<li>snapshot age가 임계값을 넘으면 fail-open과 fail-closed를 정책별로 분리한다.</li>
<li>캐시 갱신 실패율이 <strong>5분 연속 1% 초과</strong>면 Control Plane 경보를 울린다.</li>
</ul>
<p>예외는 있습니다. 결제 승인, 고위험 권한 상승, 계정 정지처럼 최신성이 안전보다 중요한 작업은 fail-closed가 맞습니다. 반대로 상품 목록 조회, 추천, 정적 라우팅처럼 가용성이 우선인 경로는 일정 시간 fail-open이 낫습니다. 이 결정은 <a href="/learning/deep-dive/deep-dive-graceful-degradation-brownout-playbook/">Graceful Degradation</a>과 같은 장애 완화 전략과 연결됩니다.</p>
<h3 id="3-정책은-값이-아니라-버전-있는-산출물로-배포한다">3) 정책은 값이 아니라 버전 있는 산출물로 배포한다</h3>
<p>Control Plane을 운영할 때 설정 테이블의 현재 값만 보면 사고를 추적하기 어렵습니다. 누가, 언제, 어떤 diff로, 어떤 대상에, 몇 퍼센트까지 배포했는지가 남아야 합니다. 특히 라우팅, rate limit, 인증, quota 정책은 코드 배포만큼 위험합니다.</p>
<p>정책 산출물에는 최소한 아래 정보가 필요합니다.</p>
<ul>
<li><code>policy_version</code>: 단조 증가하는 버전 또는 content hash</li>
<li><code>created_by</code>, <code>approved_by</code>, <code>created_at</code></li>
<li>변경 diff와 영향 대상 tenant/service</li>
<li>rollout 단계: 1% → 5% → 25% → 50% → 100%</li>
<li>rollback target version</li>
<li>적용 성공률, 거부율, stale cache 비율</li>
</ul>
<p>숫자 기준은 보수적으로 시작합니다. 전역 라우팅 정책은 1%에서 최소 <strong>10분</strong> 관측하고, error rate가 기준선 대비 <strong>0.2%p 이상 상승</strong>하거나 p95가 <strong>1.2배 초과</strong>하면 중단합니다. tenant별 quota처럼 영향 범위가 좁은 정책은 5% 또는 특정 tenant allowlist부터 시작할 수 있습니다. 보안 차단 정책은 빠른 전파가 중요하지만, 오탐 비용이 크므로 shadow evaluation을 먼저 돌리는 편이 안전합니다.</p>
<h3 id="4-control-plane은-강한-일관성보다-감사-가능성이-더-중요할-때가-많다">4) Control Plane은 강한 일관성보다 감사 가능성이 더 중요할 때가 많다</h3>
<p>Control Plane은 종종 &ldquo;정확히 한 번, 즉시, 모든 곳에&rdquo; 적용되어야 한다고 오해됩니다. 하지만 대부분의 운영 정책은 완전한 즉시 일관성보다 <strong>누가 어떤 결정을 했고 현재 어디까지 적용됐는지 설명 가능</strong>한 것이 더 중요합니다. 설정 전파가 20초 늦는 것보다, 어떤 버전이 어느 인스턴스에 적용됐는지 모르는 상태가 더 위험합니다.</p>
<p>그래서 Control Plane 저장소는 감사 로그와 변경 이력을 우선 설계해야 합니다.</p>
<ul>
<li>변경 요청과 승인 이벤트를 append-only로 남긴다.</li>
<li>현재 상태는 이벤트에서 재구성 가능해야 한다.</li>
<li>Data Plane heartbeat에 적용 중인 policy version을 포함한다.</li>
<li>관리자는 버전별 적용률과 stale instance를 볼 수 있어야 한다.</li>
<li>롤백은 &ldquo;이전 값 입력&quot;이 아니라 &ldquo;검증된 이전 버전으로 되돌리기&quot;여야 한다.</li>
</ul>
<p>이 관점은 <a href="/learning/deep-dive/deep-dive-execution-receipt-operations-playbook/">Execution Receipt 운영 플레이북</a>과도 닿아 있습니다. 운영 변경은 말로 승인했다고 끝나는 것이 아니라, 실행 증거와 적용 범위가 남아야 합니다.</p>
<h2 id="실무-적용">실무 적용</h2>
<p>작게 시작하려면 feature flag나 rate limit 정책부터 분리하는 것이 좋습니다. 둘 다 변경 빈도가 높고, 잘못 바꾸면 바로 사용자 영향이 나며, 동시에 코드 배포와 분리했을 때 이점이 큽니다.</p>
<p>첫 구현은 아래 순서가 안전합니다.</p>
<ol>
<li>정책을 DB row가 아니라 versioned snapshot 파일 또는 테이블로 모델링한다.</li>
<li>Data Plane은 시작 시 마지막 정상 snapshot을 로드하고, 이후 비동기로 갱신한다.</li>
<li>모든 요청 로그에 <code>policy_version</code>, <code>snapshot_age_ms</code>, <code>decision_reason</code>을 남긴다.</li>
<li>Control Plane 변경은 draft → approved → staged → active → rolled_back 상태를 가진다.</li>
<li>rollout은 서비스 전체가 아니라 tenant, region, instance group 단위로 쪼갠다.</li>
</ol>
<p>운영 대시보드는 최소 4개 지표를 봐야 합니다.</p>
<ul>
<li>policy propagation latency p50/p95/p99</li>
<li>stale snapshot 비율</li>
<li>policy decision error rate</li>
<li>policy version별 request/error/latency 분포</li>
</ul>
<p>여기에 <a href="/learning/deep-dive/deep-dive-distributed-tracing-adoption-playbook/">분산 트레이싱</a>을 연결하면 &ldquo;특정 정책 버전에서만 p99가 튄다&quot;는 식의 분석이 가능해집니다.</p>
<h2 id="트레이드오프주의점">트레이드오프/주의점</h2>
<p>분리는 공짜가 아닙니다. Control Plane과 Data Plane을 나누면 운영 변경은 안전해지지만 시스템은 더 복잡해집니다. 정책 모델, 버전 관리, 캐시 무효화, 전파 지연, 롤백 UI, 감사 로그가 모두 필요합니다. 작은 서비스에서 처음부터 거대한 Control Plane을 만들면 배보다 배꼽이 커질 수 있습니다.</p>
<p>실무 판단은 아래처럼 하면 좋습니다.</p>
<ul>
<li>서비스가 1~2개이고 변경자가 소수라면 단순 설정 + 재배포로 충분할 수 있다.</li>
<li>정책 변경이 주 1회 이상이고 장애 영향이 크다면 분리를 검토한다.</li>
<li>tenant별 설정, region별 라우팅, 동적 quota가 필요하면 Control Plane 가치가 커진다.</li>
<li>요청마다 중앙 API를 호출해야만 하는 구조라면 설계를 다시 본다.</li>
<li>보안 정책은 fail-open/fail-closed 기준을 정책별로 문서화한다.</li>
</ul>
<p>가장 위험한 상태는 &ldquo;Control Plane이라고 부르지만 실제로는 단일 장애점인 설정 서버&quot;입니다. 이름이 아니라 장애 시나리오로 검증해야 합니다.</p>
<h2 id="체크리스트-또는-연습">체크리스트 또는 연습</h2>
<p>아래 질문에 답해보면 현재 시스템의 분리 수준을 빠르게 볼 수 있습니다.</p>
<ul>
<li>Control Plane이 10분 동안 장애 나도 기존 사용자 요청은 계속 처리되는가?</li>
<li>Data Plane 요청 경로에서 중앙 설정/정책 API를 동기 호출하는 지점이 있는가?</li>
<li>모든 요청 로그에 정책 버전과 의사결정 이유가 남는가?</li>
<li>정책 변경을 1% 또는 특정 tenant에만 먼저 적용할 수 있는가?</li>
<li>rollback target version이 명확하며 10분 안에 되돌릴 수 있는가?</li>
<li>stale snapshot이 위험한 정책과 허용 가능한 정책을 구분했는가?</li>
<li>보안 차단 정책은 shadow evaluation 또는 dry-run 지표를 거치는가?</li>
</ul>
<p>연습 과제는 간단합니다. 현재 서비스의 feature flag 또는 rate limit 정책 하나를 고르고, &ldquo;Control Plane 변경 이벤트&rdquo;, &ldquo;Data Plane snapshot&rdquo;, &ldquo;요청 로그 필드&rdquo;, &ldquo;롤백 기준&quot;을 한 페이지로 그려보세요. p95 지연 1.2배, error rate 0.2%p, snapshot age 5분 같은 숫자를 넣으면 설계가 훨씬 현실적으로 보입니다.</p>
]]></content:encoded></item><item><title>2026 개발 트렌드: Outside-the-Sandbox Harness, 잘하는 팀은 에이전트의 두뇌와 작업장을 분리한다</title><link>https://jyukki.com/posts/2026-05-03-harness-outside-sandbox-agent-control-plane-trend/</link><pubDate>Sun, 03 May 2026 00:00:00 +0000</pubDate><guid>https://jyukki.com/posts/2026-05-03-harness-outside-sandbox-agent-control-plane-trend/</guid><description>최근 에이전트 운영 논의는 모델 성능보다 하네스 위치로 이동하고 있습니다. 세션 루프를 샌드박스 밖으로 빼는 구조가 왜 주목받는지 실무 기준으로 정리합니다.</description><content:encoded><![CDATA[<p>최근 에이전트 운영 얘기를 보면 주제가 또 한 단계 이동하고 있습니다. 예전에는 프롬프트, 그다음엔 도구 권한, 그다음엔 검증기와 승인 게이트가 중심이었다면, 이제는 <strong>에이전트 루프 자체를 어디서 돌릴 것인가</strong>가 중요한 질문이 됐습니다. 쉽게 말해 모델이 생각하고 정책을 적용하고 메모리를 읽는 하네스를, 실제 코드와 쉘 명령을 실행하는 샌드박스와 같은 곳에 둘 것인지 분리할 것인지가 아키텍처 선택지로 올라온 것입니다.</p>
<p>저는 이 흐름이 <a href="/posts/2026-04-09-harness-engineering-agent-runtime-frame-trend/">Harness Engineering</a>, <a href="/posts/2026-04-11-stateful-sandbox-snapshot-environment-replay-trend/">Stateful Sandbox Snapshot</a>, <a href="/posts/2026-04-13-capability-lease-expiring-agent-permissions-trend/">Capability Lease</a>, <a href="/posts/2026-04-14-execution-receipt-agent-operations-trend/">Execution Receipt</a> 이후에 자연스럽게 나온 다음 단계라고 봅니다. 실행 프레임, 권한, 증거를 따로 보기 시작했다면, 이제 남는 질문은 &ldquo;세션의 두뇌와 작업장을 같은 런타임에 둬야 하나&quot;이기 때문입니다.</p>
<h2 id="이-글에서-얻는-것">이 글에서 얻는 것</h2>
<ul>
<li>왜 최근 에이전트 플랫폼이 하네스를 샌드박스 밖으로 빼는 구조를 검토하는지 이해할 수 있습니다.</li>
<li>단일 사용자 로컬 에이전트와 멀티유저 조직형 에이전트에서 아키텍처 선택 기준이 왜 달라지는지 구분할 수 있습니다.</li>
<li>sandbox resume latency, session durability, shared memory consistency 같은 운영 기준을 어떤 숫자로 시작하면 되는지 감을 잡을 수 있습니다.</li>
<li>이 구조가 단순 보안 미신이 아니라 비용, 내구성, 공유 상태 문제와 연결된다는 점을 설명할 수 있습니다.</li>
</ul>
<h2 id="핵심-개념이슈">핵심 개념/이슈</h2>
<h3 id="1-핵심-분기점은-루프가-샌드박스-안에-사는가다">1) 핵심 분기점은 &ldquo;루프가 샌드박스 안에 사는가&quot;다</h3>
<p>에이전트 시스템은 겉보기보다 비슷합니다. 프롬프트를 보내고, 응답을 받고, 툴을 실행하고, 결과를 다시 넣는 루프가 있습니다. 차이는 그 루프가 어디에서 사는가입니다.</p>
<ul>
<li><strong>Inside-the-Sandbox Harness</strong>: 추론 루프와 툴 실행이 같은 환경에 있다.</li>
<li><strong>Outside-the-Sandbox Harness</strong>: 추론 루프와 정책, 메모리, 승인 상태는 제어 평면에 있고, 실제 명령 실행만 샌드박스로 위임한다.</li>
</ul>
<p>단일 사용자 로컬 환경에서는 첫 번째가 단순하고 빠릅니다. 하지만 조직 단위 운영으로 가면 두 번째가 매력적이기 시작합니다. 샌드박스를 세션 그 자체로 보지 않고, <strong>필요할 때만 붙였다 떼는 실행기</strong>로 볼 수 있기 때문입니다.</p>
<h3 id="2-하네스를-밖으로-빼면-샌드박스가-약해지는-대신-세션이-강해진다">2) 하네스를 밖으로 빼면 샌드박스가 약해지는 대신 세션이 강해진다</h3>
<p>이 구조의 가장 큰 장점은 보통 보안 문장으로만 설명되지만, 실제로는 운영상의 이점이 더 큽니다.</p>
<p>첫째, <strong>자격증명이 샌드박스 안에 남지 않습니다.</strong> LLM API 키, 사용자 토큰, 승인 상태, 조직 메모리 저장소 접근 권한을 제어 평면에 두면, 샌드박스는 코드 읽기와 명령 실행 같은 한정된 책임만 가집니다.</p>
<p>둘째, <strong>샌드박스를 중간에 내려도 세션이 죽지 않습니다.</strong> 세션 루프가 밖에 있으면 샌드박스는 교체 가능한 부품이 됩니다. 이건 <a href="/posts/2026-04-11-stateful-sandbox-snapshot-environment-replay-trend/">Stateful Sandbox Snapshot</a>이 말한 환경 재개 개념과도 이어집니다. 좋은 팀은 샌드박스를 세션과 동일시하지 않고, 세션이 샌드박스를 잠깐 빌리는 구조로 갑니다.</p>
<p>셋째, <strong>idle 시간이 긴 에이전트에 특히 유리합니다.</strong> 실제 워크플로를 보면 모델 추론, 대기, CI 상태 확인, 승인 대기처럼 샌드박스가 필요 없는 구간이 꽤 많습니다. <code>idle_ratio</code>가 <strong>60% 이상</strong>인 세션이라면 샌드박스를 항상 켜 두는 쪽이 오히려 낭비일 수 있습니다.</p>
<h3 id="3-멀티유저가-되면-로컬-파일시스템-가정이-바로-흔들린다">3) 멀티유저가 되면 로컬 파일시스템 가정이 바로 흔들린다</h3>
<p>Outside-the-Sandbox 구조가 본격적으로 필요해지는 순간은 사용자가 늘어날 때입니다. 한 명이 로컬에서 짧게 쓰는 도구는 메모리와 스킬을 파일처럼 다뤄도 문제가 잘 안 드러납니다. 하지만 조직 단위 에이전트는 다릅니다.</p>
<ul>
<li>여러 세션이 같은 메모리를 동시에 읽고 쓴다.</li>
<li>승인 기록과 증거 레코드가 세션 밖에서도 보여야 한다.</li>
<li>같은 팀의 스킬과 운영 규칙이 여러 사용자에게 공유돼야 한다.</li>
<li>세션이 몇 시간 이상 살아서 배포나 재시작을 넘어가야 한다.</li>
</ul>
<p>이 지점부터는 로컬 파일시스템이 아니라 <strong>공유 상태 저장소</strong>가 본체가 됩니다. 그래서 최근 흐름은 read/write/edit 도구는 그대로 유지하되, 경로에 따라 실제 backend를 다르게 라우팅하는 방향으로 갑니다. 에이전트는 파일을 읽는다고 생각하지만, 실제로는 어떤 경로는 샌드박스 파일이고 어떤 경로는 메모리 DB인 식입니다. 이 방향은 <a href="/posts/2026-04-17-agent-handoff-packet-runtime-trend/">Agent Handoff Packet</a>이나 <a href="/posts/2026-04-14-execution-receipt-agent-operations-trend/">Execution Receipt</a>처럼 <strong>세션 외부에서도 이어져야 하는 상태</strong>가 늘어날수록 더 중요해집니다.</p>
<h3 id="4-대신-durable-execution이-갑자기-핵심-문제가-된다">4) 대신 durable execution이 갑자기 핵심 문제가 된다</h3>
<p>하네스를 밖으로 빼는 순간 공짜로 따라오는 것도 있습니다. 바로 세션 내구성 책임입니다. 샌드박스 안에서 루프를 돌리면 프로세스가 곧 세션이지만, 제어 평면으로 빼면 세션은 장시간 실행 함수에 가깝습니다.</p>
<p>그래서 이 구조를 진지하게 운영하려면 아래가 같이 필요합니다.</p>
<ul>
<li>중간 단계 checkpoint</li>
<li>배포 후 재개 가능한 durable execution</li>
<li>sandbox 재할당 후 재수화(rehydrate)</li>
<li>장시간 대기 중 타임아웃, 취소, 승인 상태 관리</li>
</ul>
<p>실무 출발선은 이 정도가 무난합니다.</p>
<ul>
<li><code>session_rehydrate_success_rate</code> <strong>99% 이상</strong></li>
<li><code>sandbox_resume_p95</code> <strong>100ms 이하</strong>면 인터랙티브 체감 유지 가능</li>
<li><code>tool_roundtrip_p95</code>가 baseline 대비 <strong>20% 이상</strong> 늘어나면 구조 재검토</li>
<li>세션 배포 중단/재시작 후 손실 없는 복구율 <strong>100% 목표</strong></li>
</ul>
<p>즉 이 구조는 샌드박스를 약하게 만들지만, 제어 평면은 더 강하게 만들어야 성립합니다.</p>
<h3 id="5-2주-파일럿은-이렇게-설계하는-편이-현실적이다">5) 2주 파일럿은 이렇게 설계하는 편이 현실적이다</h3>
<p>개념을 이해한 뒤 가장 많이 나오는 질문은 &ldquo;그래서 우리 팀은 어디서부터 떼어내야 하나&quot;입니다. 이때 처음부터 전면 재구성을 시도하면 거의 항상 과합니다. 오히려 <strong>승인 기록, 메모리, 실행 증거처럼 세션 바깥에서도 살아 있어야 하는 것</strong> 하나만 골라 파일럿으로 분리하는 편이 훨씬 안정적입니다.</p>
<p>예를 들어 현재 구조가 <code>에이전트 프로세스 + 샌드박스 + 로컬 메모리 파일</code>로 붙어 있다면, 첫 2주는 아래처럼 보는 편이 좋습니다.</p>
<ol>
<li><strong>1주차</strong>: 승인 기록과 실행 receipt만 제어 평면 저장소로 올립니다.</li>
<li><strong>2주차</strong>: 샌드박스는 그대로 두고, 세션 재개 시 승인/증거를 외부 저장소에서 재수화하는 흐름만 검증합니다.</li>
<li>이때 코드 편집 같은 핵심 작업은 그대로 두고, 세션 지속성에만 집중합니다.</li>
</ol>
<p>이 방식의 장점은 실패해도 손실 반경이 작다는 점입니다. 모델 루프, 툴 권한, 파일 편집기까지 한 번에 옮기지 않기 때문에 문제가 생겨도 **&ldquo;승인 저장소만 다시 로컬로 붙이면 원복&rdquo;**이 가능해집니다. 저는 이런 파일럿을 설계할 때 아래 4개 지표를 같이 보길 권합니다.</p>
<ul>
<li><code>resume_without_manual_fix_rate</code>: 사람이 세션을 수동 복구하지 않고 바로 이어진 비율</li>
<li><code>approval_lookup_p95</code>: 승인 상태를 읽어오는 시간</li>
<li><code>receipt_write_failure_rate</code>: 실행 증거 저장 실패율</li>
<li><code>sandbox_detach_success_rate</code>: 샌드박스를 내려도 세션 상태가 유지된 비율</li>
</ul>
<p>핵심은 화려한 분산 구조를 먼저 만들기보다, <strong>현재 세션에서 정말 샌드박스 안에 있을 이유가 없는 책임부터 밖으로 빼는 것</strong>입니다. 이 기준이 서야 이후에 <a href="/posts/2026-04-14-execution-receipt-agent-operations-trend/">Execution Receipt</a>, <a href="/posts/2026-04-29-task-graph-runtime-agent-ops-trend/">Task Graph Runtime</a>, <a href="/posts/2026-04-30-tool-contract-test-agent-runtime-trend/">Tool Contract Test</a> 같은 운영 글과도 자연스럽게 연결됩니다.</p>
<h3 id="6-가장-까다로운-부분은-보안보다-일관성과-우회-경로다">6) 가장 까다로운 부분은 보안보다 일관성과 우회 경로다</h3>
<p>의외로 어려운 부분은 &ldquo;분리하면 더 안전하다&rdquo; 한 줄이 아닙니다. 운영에서는 아래가 더 빨리 아픕니다.</p>
<ul>
<li>두 세션이 같은 메모리를 동시에 수정하면 누가 이겨야 하는가</li>
<li>bash나 셸 명령이 가상화 레이어를 우회하면 어떻게 할 것인가</li>
<li>같은 read/write 인터페이스를 유지하면서 backend 차이를 어떻게 숨길 것인가</li>
<li>세션이 다른 샌드박스로 넘어갈 때 어떤 상태를 복원해야 하는가</li>
</ul>
<p>특히 bash는 구조적 툴 호출이 아니라 우회 경로이기 때문에, 파일 경로 가상화를 뚫고 실제 샌드박스 파일시스템만 보게 만들 수 있습니다. 그래서 Outside-the-Sandbox 구조를 택한 팀은 대개 <strong>가상 네임스페이스 차단 규칙</strong>, <strong>명령 파싱 기반 가드</strong>, <strong>권한 lease 축소</strong>를 같이 둡니다. 이건 <a href="/posts/2026-04-13-capability-lease-expiring-agent-permissions-trend/">Capability Lease</a>가 왜 단순 allowlist보다 좁은 범위와 짧은 TTL을 강조하는지와도 연결됩니다.</p>
<h2 id="실무-적용">실무 적용</h2>
<h3 id="1-어떤-팀이-먼저-검토해야-하나">1) 어떤 팀이 먼저 검토해야 하나</h3>
<p>아래 조건 중 2개 이상이면 분리형 하네스를 한 번은 검토할 가치가 큽니다.</p>
<ul>
<li>조직 단위로 여러 사용자가 같은 에이전트를 쓴다</li>
<li>세션 길이가 자주 <strong>30분 이상</strong>으로 길다</li>
<li>승인, 메모리, 실행 증거를 세션 밖에서도 조회해야 한다</li>
<li>샌드박스가 실제 명령 실행보다 idle 상태로 머무는 시간이 길다</li>
<li>자격증명을 샌드박스에 넣는 구조가 점점 불편해진다</li>
</ul>
<p>반대로 1인용 로컬 에이전트, 짧은 세션, 공유 메모리 없음, read-only 중심 작업이라면 inside 구조가 더 낫습니다. 구조 분리는 목적이 아니라 비용이기 때문입니다.</p>
<h3 id="2-추천-시작-숫자">2) 추천 시작 숫자</h3>
<p>처음부터 완벽한 제어 평면을 만들 필요는 없습니다. 다만 아래 숫자는 먼저 고정하는 편이 좋습니다.</p>
<ul>
<li><code>sandbox_resume_p95</code>: <strong>100ms 이하</strong> 목표</li>
<li><code>idle_ratio</code>: <strong>50~60% 이상</strong>이면 suspend/resume 후보</li>
<li><code>session_rehydrate_success_rate</code>: <strong>99% 이상</strong></li>
<li><code>shared_memory_conflict_rate</code>: 초기에는 <strong>1% 이하</strong>를 목표로 보고, 초과 시 충돌 정책 설계</li>
<li><code>credential_in_sandbox_count</code>: 가능하면 <strong>0</strong> 목표</li>
<li><code>agent_step_loss_after_deploy</code>: <strong>0</strong> 목표</li>
</ul>
<p>이 숫자가 없으면 구조를 바꾼 뒤 좋아졌는지 나빠졌는지 판단하기 어렵습니다.</p>
<h3 id="3-도입-순서">3) 도입 순서</h3>
<p>가장 안전한 순서는 보통 이렇습니다.</p>
<ol>
<li><strong>승인/증거/메모리부터 샌드박스 밖으로 이동</strong></li>
<li>read/write 경로를 가상화할 최소 인터페이스 정리</li>
<li>세션 checkpoint와 재개 흐름 추가</li>
<li>마지막에 sandbox suspend/resume 최적화</li>
</ol>
<p>많은 팀이 4번부터 하고 싶어 하지만, 실제로는 1~3번이 먼저 닫혀야 샌드박스 수명과 세션 수명을 분리할 수 있습니다. 특히 <a href="/posts/2026-04-14-execution-receipt-agent-operations-trend/">Execution Receipt</a>와 <a href="/posts/2026-04-23-review-ops-unified-human-gate-trend/">Review Ops Unified Human Gate</a>까지 붙이려면 승인과 증거는 제어 평면에 있어야 훨씬 다루기 쉽습니다.</p>
<h3 id="4-운영-우선순위">4) 운영 우선순위</h3>
<p>저는 이 구조의 운영 우선순위를 아래 순서로 보는 편이 맞다고 생각합니다.</p>
<ol>
<li>자격증명과 승인 상태를 샌드박스 밖에 둔다</li>
<li>세션이 배포와 장애를 넘어 살아남게 만든다</li>
<li>공유 메모리 일관성을 최소한 설명 가능하게 만든다</li>
<li>sandbox resume 성능을 다듬는다</li>
<li>마지막에 비용 최적화를 한다</li>
</ol>
<p>많은 팀이 4, 5부터 달리다가 1~3을 나중에 갚습니다. 그런데 Outside-the-Sandbox Harness의 진짜 가치는 절약한 컨테이너 비용보다 <strong>설명 가능한 세션 경계</strong>에 있습니다.</p>
<h2 id="트레이드오프주의점">트레이드오프/주의점</h2>
<p>첫째, <strong>분리형 하네스는 구조적으로 더 복잡합니다.</strong> 단일 사용자 로컬 도구라면 그 복잡성이 과할 수 있습니다.</p>
<p>둘째, <strong>shared memory consistency는 생각보다 빨리 아픈 문제입니다.</strong> 마지막 기록 승리(last-writer-wins)로 시작할 수는 있어도, 중요한 운영 메모리까지 같은 규칙으로 두면 나중에 깨질 가능성이 큽니다.</p>
<p>셋째, <strong>bash는 늘 새는 구멍이 됩니다.</strong> 구조화된 read/write는 가상화해도 셸 명령은 우회 가능성이 있어서 별도 가드가 필요합니다.</p>
<p>넷째, <strong>샌드박스를 쉽게 교체할 수 있어도 workspace 재수화 전략이 약하면 체감은 오히려 나빠집니다.</strong> resume이 빨라도 필요한 파일, 캐시, 도구 상태가 제때 안 살아나면 사용자는 더 느리게 느낍니다.</p>
<p>다섯째, <strong>모델 성능이 좋아져도 이 문제는 사라지지 않습니다.</strong> 승인, 권한, 메모리, 내구성은 운영 구조 문제라서 모델 IQ보다 아키텍처 차이가 더 크게 드러납니다.</p>
<h2 id="실패-신호와-롤백-기준">실패 신호와 롤백 기준</h2>
<p>Outside-the-Sandbox Harness를 도입할 때는 &ldquo;이상이 생기면 무엇을 되돌릴지&quot;를 미리 적어 두는 편이 좋습니다. 분리형 구조가 어려운 이유는 장애가 났을 때 샌드박스, 제어 평면, 메모리 저장소 중 어디가 원인인지 한 번에 안 보이기 때문입니다.</p>
<p>제가 실무에서 먼저 적는 롤백 기준은 대체로 아래 4가지입니다.</p>
<ul>
<li><code>sandbox_resume_p95</code>가 파일럿 이전 대비 <strong>20% 이상</strong> 악화되면 suspend/resume 최적화는 보류하고, 세션 분리 범위를 줄입니다.</li>
<li><code>session_rehydrate_success_rate</code>가 <strong>99% 아래</strong>로 떨어지면 즉시 shared memory 확장을 멈추고 승인/증거만 유지합니다.</li>
<li>운영자가 세션 상태를 설명하지 못할 정도로 <strong>source of truth가 두 군데 이상</strong> 생기면, 마지막으로 안정적이었던 저장소를 단일 기준으로 되돌립니다.</li>
<li>bash 우회나 직접 파일 접근 때문에 제어 평면 정책이 반복적으로 무시되면, 경로 가상화보다 먼저 <strong>권한 lease 축소</strong>와 <strong>명령 실행 가드</strong>를 다시 세웁니다.</li>
</ul>
<p>여기서 중요한 건 롤백을 실패로 보지 않는 태도입니다. 오히려 샌드박스 밖 하네스는 작은 단위로 떼어내고, 숫자가 나빠지면 한 단계 되돌리는 식으로 가야 정상입니다. 특히 멀티유저 전환 전에 이 기준이 없으면, 구조가 좋아진 것처럼 보여도 실제로는 운영자가 설명할 수 없는 상태만 늘어날 수 있습니다.</p>
<h2 id="체크리스트-또는-연습">체크리스트 또는 연습</h2>
<h3 id="체크리스트">체크리스트</h3>
<ul>
<li><input disabled="" type="checkbox"> 세션 루프와 툴 실행 환경이 현재 어떻게 결합돼 있는지 그렸다.</li>
<li><input disabled="" type="checkbox"> 승인, 메모리, 증거, 자격증명 중 무엇을 샌드박스 밖으로 먼저 뺄지 우선순위를 정했다.</li>
<li><input disabled="" type="checkbox"> <code>sandbox_resume_p95</code>, <code>session_rehydrate_success_rate</code>, <code>idle_ratio</code>를 측정한다.</li>
<li><input disabled="" type="checkbox"> <code>approval_lookup_p95</code>, <code>receipt_write_failure_rate</code>처럼 제어 평면 지표도 같이 본다.</li>
<li><input disabled="" type="checkbox"> bash 또는 셸 경로 우회를 탐지하거나 제한하는 규칙이 있다.</li>
<li><input disabled="" type="checkbox"> shared memory 충돌 시 정책(last-writer-wins, merge, human gate)을 문서화했다.</li>
<li><input disabled="" type="checkbox"> 세션 배포 중단이나 샌드박스 교체 후 손실 없이 이어지는지 복구 테스트를 했다.</li>
<li><input disabled="" type="checkbox"> 수치가 나빠졌을 때 어느 책임을 다시 샌드박스 안으로 되돌릴지 롤백 순서를 적어 두었다.</li>
</ul>
<h3 id="연습-과제">연습 과제</h3>
<ol>
<li>현재 에이전트 워크플로를 <code>세션 제어 평면</code>과 <code>실행 샌드박스</code>로 나눠 그려 보세요. 어떤 책임이 섞여 있는지 바로 드러날 가능성이 큽니다.</li>
<li>최근 10개 세션을 골라 실제로 샌드박스가 필요한 단계와 필요 없는 단계를 분류해 보세요. idle ratio가 생각보다 높을 수 있습니다.</li>
<li>메모리, 승인, 증거 중 하나를 샌드박스 파일이 아니라 제어 평면 저장소로 올린다고 가정하고, 읽기/쓰기 인터페이스를 어떻게 유지할지 설계해 보세요.</li>
<li>bash 우회, 메모리 충돌, 세션 재개 실패를 각각 1개씩 상정해 runbook 초안을 적어 보세요.</li>
</ol>
<h2 id="관련-글">관련 글</h2>
<ul>
<li><a href="/posts/2026-04-09-harness-engineering-agent-runtime-frame-trend/">Harness Engineering</a></li>
<li><a href="/posts/2026-04-11-stateful-sandbox-snapshot-environment-replay-trend/">Stateful Sandbox Snapshot</a></li>
<li><a href="/posts/2026-04-13-capability-lease-expiring-agent-permissions-trend/">Capability Lease</a></li>
<li><a href="/posts/2026-04-14-execution-receipt-agent-operations-trend/">Execution Receipt</a></li>
<li><a href="/posts/2026-04-17-agent-handoff-packet-runtime-trend/">Agent Handoff Packet</a></li>
<li><a href="/posts/2026-04-23-review-ops-unified-human-gate-trend/">Review Ops Unified Human Gate</a></li>
</ul>
]]></content:encoded></item></channel></rss>