AI 코딩 에이전트를 위한 서명된 핸드오프(handoff) 프로토콜 구축하기
요약
AI 코딩 에이전트의 사용량 제한 발생 시 컨텍스트 손실을 방지하기 위한 'Relay' 프로토콜을 소개합니다. Relay는 에이전트 간의 작업 상태를 안전하게 스냅샷하고 서명된 계약 형태로 전달하여 연속성을 보장합니다.
핵심 포인트
- 에이전트 사용량 제한 시 컨텍스트 증발 문제 해결
- Go 기반 데몬을 통한 실시간 할당량 모니터링 및 안전한 일시 중지
- Git 커밋과 스냅샷을 활용한 작업 상태 보존
- HMAC-SHA256 서명을 통한 데이터 무결성 및 보안 검증
AI 코딩 에이전트를 위한 서명된 핸드오프(handoff) 프로토콜 구축하기
만약 두 개 이상의 AI 코딩 에이전트를 실행한다면, 다음과 같은 상황을 겪게 될 것입니다. Claude Code(또는 Codex, 혹은 그 무엇이든)가 작업에 깊이 몰입해 있다가 사용량 제한(usage limit)에 걸리는 순간, 그가 알고 있던 모든 것이 증발해 버립니다. 계획, 절반쯤 완료된 편집, "이 마이그레이션은 다시 하지 마세요"라는 컨텍스트까지 말이죠. 당신은 다음 도구에 요약본을 수동으로 붙여넣으며 아무것도 잊지 않았기를 기도해야 합니다.
저는 이런 상황에 지쳐 Relay를 구축했습니다. Relay는 당신이 실행하는 어떤 에이전트 앞에서도 동작하는 Go 데몬(daemon)으로, 핸드오프(handoff)를 수동 마이그레이션이 아닌 하나의 프로토콜(protocol)로 취급합니다.
홍보가 아닌 메커니즘
에이전트가 한계에 부딪혔을 때 실제로 일어나는 일은 다음과 같습니다.
1. 위반(breach) 감지. Relay는 활성화된 프로바이더(provider)의 할당량(quota)을 실시간으로 모니터링합니다 (사용 가능한 경우 프록시 헤더(proxy header), 그렇지 않으면 세션 파일(session file), 최후의 수단으로는 요청 횟수 계산을 사용). 사용량이 임계값을 넘으면, 429 에러를 기다리지 않습니다.
2. 안전한 일시 중지 요청. 어댑터(adapter)에 안전한 지점(safe point)을 요청합니다. 이는 보통 커밋(commit) 직후이며, 편집 중간에는 절대 수행되지 않습니다. 이것은 타임아웃을 추측하는 것이 아니라 실제 핸드셰이크(handshake)입니다:
go type AdapterContract interface { Capability() ProviderCapability Run(ctx, opts RunOptions, ch chan<- AgentEvent) error AwaitSafePauseWindow(ctx, breachReason string) (SafePoint, error) ForceStop() error }
3. 스냅샷(Snapshot). 전용 세션 워크트리(worktree) 브랜치에 git 커밋을 생성합니다. 당신의 메인 트리는 절대 건드리지 않으며, 에이전트는 .relay/sessions/<id>/에서 작업합니다.
4. 지속 계약(continuation contract) 구축 및 서명. 이것이 실제 전송 단위입니다: 원래의 프롬프트(prompt), 계획, 남은 작업, 내려진 결정, 발견된 제약 조건, SHA-256이 포함된 수정된 파일들, 그리고 진행 중인 코드의 잘린 스니펫(snippet)들입니다. 다음 에이전트가 읽을 수 있도록 Markdown으로 직렬화(serialized)하고, 기계 검증을 위해 JSON으로 직렬화하며, 프로젝트 로컬 키를 사용하여 HMAC-SHA256으로 서명합니다:
`
{
"contractId": "c-abc123",
"taskGoal": "orders 서비스에 환불 흐름 추가",
"nextAction": "POST /orders/:id/refund 구현",
"doNotRedo": ["migration 0042 적용됨"],
"inFlightCode": [{"path": "orders/refund.go", "snippet": "func Refund(... // 생략"}],
"signature": "hex(HMAC-SHA256(canonical JSON, signing-key))"
}
`
5. 전송 및 검증 (Dispatch and verify). 다음 에이전트(다른 모델, 다른 계정, 다른 제공자 등 사용 가능한 무엇이든)는 주입된 계약(contract)을 시스템 컨텍스트(system context)로 전달받습니다. 이 에이전트는 계약 내의 어떤 정보도 신뢰하기 전에 서명(signature)을 먼저 읽습니다. 변조되거나 위조된 계약은 조용히 수락되는 대신 거부됩니다.
6. 재개 (Resume). 하트비트(heartbeat)를 통해 새로운 에이전트가 작업을 이어받았음을 확인하며, 이 모든 과정은 작은 유한 상태 머신(FSM, Finite State Machine) 내의 하나의 상태 전이(RUNNING → PAUSING → SNAPSHOTTED → ENVELOPE_BUILT → DISPATCHED → RESUMING → RUNNING)로 이루어집니다. 각 단계 이전에 디스크에 내구적으로 기록되므로, 핸드오프(handoff) 도중 충돌(crash)이 발생하더라도 재시작 시 중단된 지점부터 바로 재개할 수 있습니다.
이것이 가능하게 하는 것들
핸드오프가 단순한 기대가 아닌 실제 프로토콜이 되면, 다음과 같은 몇 가지 사항들이 가능해집니다:
relay detect: 사용자의 머신에서 이미 실행 중인 Claude Code, Codex, Copilot, Cursor, Cline, Continue 또는 Antigravity 세션을 찾아내고(프로세스 스캔 및 각 도구의 자체 디스크 트랜스크립트 형식 읽기), 실행 중인 세션 하나를 다른 제공자(provider)로 옮길 수 있습니다.- 계정 인식 장애 조치 (Account-aware failover): 다른 제공자로 넘어가기 전에, 하나의 Claude 로그인이 소진되면 다른 로그인을 통해 작업을 재개합니다. 두 번째 로그인으로 해결할 수 있는 문제에 대해 벤더 간(cross-vendor) 핸드오프를 사용하는 것보다 비용이 저렴합니다.
- 소모율 예측 기능이 있는 할당량 지갑 (A quota wallet with burn-rate forecasting): 이를 통해 핸드오프가 429(Too Many Requests) 에러에 반응하는 대신, 한계에 도달하기 전에 트리거될 수 있습니다.
- 멀티 에이전트 파이프라인 (Multi-agent pipelines): 각 노드가 작업의 한 부분을 수행하는 에이전트인 DAG(Directed Acyclic Graph) 구조로, 각 단계는 폴백 제공자(fallback providers)와 승인 명령(acceptance commands)에 의해 제어됩니다.
이것이 아닌 것
이것은 또 다른 에이전트가 아닙니다. 스스로 코드를 작성하지도 않습니다. 이것은 여러분이 이미 사용 중인 에이전트들의 하단에 위치하는 레이어(layer)이며, 에이전트들보다 더 똑똑해지려고 명시적으로 시도하지 않습니다. 그저 에이전트들의 한계 때문에 여러분이 이미 비용을 지불한 컨텍스트(context)를 잃게 되는 것을 거부할 뿐입니다.
Go 데몬(daemon), Rust 데스크톱 앱 (egui), TUI, 단일 바이너리(one binary)로 구성됩니다. Apache-2.0 라이선스입니다. 아직 초기 단계이며, 지난 몇 주 동안 탐지/채택, 할당량 지갑(quota wallet), 그리고 파이프라인(pipelines)이 모두 출시되었기에 아직 다듬어지지 않은 부분이 많습니다. 여러분에게 어떤 부분이 문제를 일으키는지 진심으로 알고 싶습니다.
bash
curl -fsSL https://raw.githubusercontent.com/dbisina/relay/main/scripts/install.sh | bash
relay init && relay run "add a refund flow to the orders service"
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기