요약
Rivet은 에이전트마다 무거운 샌드박스 대신 S3에 상태를 두는 가벼운 액터를 붙입니다.
Rivet은 와이 콤비네이터 2023년 겨울 기수로, 원래 멀티플레이 게임 서버 인프라를 만들었습니다. 그때 만든 액터(메모리 속 상태와 저장소를 함께 가진 가벼운 작업 단위)를 에이전트 실행 기반으로 오픈소스 공개했습니다.
왜 중요한가
- 에이전트는 대부분 쉬고 있는데도 하나마다 샌드박스를 띄우면 메모리와 기동 시간이 낭비된다는 문제 제기입니다.
- Cloudflare Durable Objects와 비슷한 모델을 직접 설치해 쓸 수 있고, 메모리 128MB·저장소 10GB 같은 제한도 없습니다.
핵심 내용
- 액터는 에이전트나 세션마다 하나씩 두며, 쉬면 잠들었다가 다음 요청에 상태를 그대로 안고 깨어납니다.
- 액터 하나는 메모리 약 72KB, 기동 시간 4.99ms(p99, 가장 느린 1% 제외)로, 샌드박스의 512MiB, 1.7초와 비교했습니다.
- 에이전트 루프는 액터에 두고, 코드 실행이 필요할 때만 도구로 샌드박스를 부르는 구조를 권합니다.
- 필수 의존성은 S3 하나뿐이라 러스트 바이너리 하나로 직접 설치할 수 있습니다.
작성자 설명
Rivet을 만드는 네이선과 니컬러스입니다. 게임 인프라를 만들 때 Postgres가 못 버티는 처리량을 다루려고 액터를 만들었고, 월간 사용자 수천만 명을 감당했습니다.
Amp는 Cloudflare Durable Objects의 제약 탓에 출시하지 못하다가 주말 사이에 Rivet으로 옮겨 왔습니다.
예전엔 FoundationDB를 썼지만, 대화 기록 같은 큰 데이터가 쌓이면서 S3로 바꿨습니다. 쓰기는 가용 영역 3곳 중 2곳의 SSD에 기록되면 완료로 보고, S3에는 뒤에서 묶어 올립니다. 그래서 EBS gp3보다 10배 싸면서도 SSD 속도를 냅니다.
HN 반응
- 여러 이용자가 액터와 에이전트의 차이도, 무슨 문제를 푸는지도 모르겠다며 벤치마크보다 사용 사례를 먼저 보여 달라고 했습니다.
- Durable Objects에서 옮겨 와 만족했다는 경험담과 함께, 잠들 때 진행 중이던 요청이나 도구 결과가 사라지지 않느냐는 질문이 나왔습니다.
저는 에이전트 분야를 깊이 아는 사람은 아니고 과학 컴퓨팅과 분산 컴퓨팅 쪽 일을 많이 하는데, 이 부분이 눈에 확 들어왔습니다. 주로 클라우드 서비스 쪽 기능인 것 같습니다만, 백엔드에서 S3와 깔끔하게 연동되는 진짜 POSIX 호환 파일시스템이 나온다면 아주 흥미로운 제품일 겁니다(오픈소스라면 더더욱요).
여담인데, 이름을 보고 눈을 세 번이나 비볐습니다. Rivet이 저희 쪽에서 오래 돌아가는 작업 큐 서비스의 내부 이름이거든요. 이름 센스가 좋으시네요.
S3를 파일시스템처럼 쓰는 방법은 많습니다. FUSE도 그중 하나고요. 이제는 AWS가 서비스로도 제공합니다.
그런 것들은 fsevents나 inotify 같은 기능을 실제로는 제공하지 못합니다. 예를 들어 git을 돌리거나 뭔가를 빌드해야 한다면 작동하지 않을 겁니다.
이런 말 하는 사람이 되고 싶진 않지만, celld도 본질적으로 똑같은 일을 하지 않나요? 다른 노드에 영속화되거나 S3에 저장될 때까지 기다리는데, 정말 큰 문제가 생기지 않는 한 사실상 항상 다른 노드로 먼저 복제가 될 거예요. (솔직히 예전에는 노드 1개에만 복제돼도 저장된 것으로 쳤고, 그 노드가 죽으면 데이터를 잃을 수 있었던 걸로 기억해요. 지금은 2개로 바뀐 것 같고, 적어도 그 버그는 등록돼 있어요. 아마 celld의 쓰기 시간이 그렇게 낮았던 이유였겠지만, 지속 가능한 방식은 아니었나 봐요)
어쨌든 상태를 가진 서버리스 선택지가 늘어나는 건 반갑습니다. 저는 아무래도 클라우드플레어 쪽 사람들이 만드는 걸 더 좋아하긴 하지만요 :)
저는 celld를 잘 모르지만, 제가 알기로는 완전한 POSIX 파일시스템은 아닙니다. 저희는 동적으로 생성하고 질의하는 duckdb와 netcdf 파일을 많이 다루는데, celld는 더 가벼운 저장소용이고 객체가 SQLite 파일 안에 들어 있는 것으로 보입니다.
제가 완전히 잘못 알고 있을 수도 있지만, 지금 이해하고 있는 바는 그렇습니다.
Rivet 정말 멋져요. 저희 인프라에서 Cloudflare Durable Object로 돌리던 부분이 자기들만의 동화 나라에 살고 있었는데, 이걸 VPC 안의 나머지 인프라와 같은 곳으로 옮겼어요. 아주 쾌적한 경험이었습니다.
아직 Rivet v3는 써볼 기회가 없었는데 곧 해보고 싶네요.
좋게 봐주셔서 감사합니다. 업그레이드하시면 v3 사용 후기를 저희 Discord에 꼭 남겨 주세요!
동화 나라요?
저희 나머지 인프라는 AWS와 Vercel인데, CF DO 쪽만 따로 떨어진 이상한 공간에 있어서 별도로 관리하고 신경 써야 했거든요.
긴 에이전트 워크플로를 돌리다가 겪은 일이 하나 있습니다. 휴면/재개는 훌륭하지만, 도구 실행 결과가 영속 스냅샷에 들어 있지 않으면 문제가 됩니다. 액터가 SQLite만 가지고 깨어났는데 직전 턴의 도구 페이로드가 메모리(혹은 임시 파일)에만 있었다면, 다음 단계는 그럴듯하게 자신 있는 척 이어 나가는 이야기를 지어냅니다. 그래서 저희는 일시 중지 전에 마지막 도구 입출력이 대화와 같은 영속 저장소에 기록되어 있지 않으면 "재개"를 안전하지 않은 것으로 취급하게 됐습니다. 밀도 수치보다 중요한 건, 그 증거가 빠져 있을 때 깨어난 쪽이 충분한 내용을 복원해서 계속 진행을 거부할 수 있느냐입니다.
아키텍처가 마음에 듭니다. 저는 에이전트가 다루는 저장소로 SQLite의 열렬한 팬이 되어 가고 있어요. Cloudflare D1도 선택지로 검토해 보셨는지 궁금합니다. 저는 에이전트가 SQLite 데이터베이스를 돌릴 수 있게 해주는 간단한 mcp를 만들었는데, 특히 Claude에서 예약 실행되는 에이전트들이 기록해 둬야 할 게 있을 때 유용하더라고요. https://getairdash.com 써보고 싶은 분은 써보세요(무료이고, cloudflare는 아주아주 저렴합니다).
몇 분씩 걸리는 에이전트 턴 도중에 도구 호출이 끼어 있을 때 휴면이 어떻게 동작하는지 궁금합니다. 액터가 깨어나면 대화 상태는 SQLite 스냅샷뿐인가요, 아니면 진행 중인 턴을 위해 메모리에 따뜻한 버퍼를 따로 유지하나요? 또 WebSocket 클라이언트가 붙어 있는 코딩 에이전트 유형의 워크로드를 기준으로, 호스트당 액터 수 같은 대략적인 밀도 수치도 알고 싶습니다.
흥미로운 아키텍처네요. 에이전트의 턴을 전용 VM을 띄우는 대신 SQLite/S3 계층 저장소를 바탕으로 한 영속적인 경량 액터로 다루는 건 지연 시간과 비용 면에서 아주 일리가 있습니다.
임의의 셸 실행이나 로컬 컴파일러 도구가 반드시 필요한 워크플로(예: 테스트를 돌리는 코딩 에이전트)에서는, 부수 효과가 있는 실행만 임시 러너에 맡기고 상태를 가진 액터는 오래 살려 두는 구도를 생각하고 계신가요? 아니면 Rivet은 주로 API/도구 호출형 에이전트에 초점을 맞추고 있나요?
분산 액터는 그래프 알고리즘을 돌리기에도 좋은 플랫폼입니다. 저희는 대규모 그래프에서 페이지랭크와 클러스터링 알고리즘을 돌리고 그 결과에 cypher 질의를 지원하기 위한 기반으로 Rivet을 검토하고 있습니다.
https://github.com/orgs/Latentpedia/discussions/4
관련 연구입니다.
https://sigmodrecord.org/publications/sigmodRecord/1712/pdfs/05_systems_Spyropoulos.pdf
https://arxiv.org/abs/2301.01395
액터 모델을 쓰지 않고도 대규모 병렬을 구현한 사례입니다. https://gnosh.ai/swarm.html
어느 쪽 접근이 언제 더 적합할지 궁금하네요. 사실 두 방식이 함께 동작하는 것도 상상이 됩니다.
오늘 이 분야로 가출원 특허 두 건을 냈습니다. gno.land 위에서 만들어 보시고 이야기 나눠 봅시다. 시너지가 보입니다.
저한테 어려운 부분은 에이전트에게 코드를 쓰게 하는 게 아니었습니다. 오래 도는 에이전트 여러 개를 몇 시간마다 쿼터를 다 태우지 않고 계속 살려 두는 게 문제였어요. 일시 중지/재개와 비용 추적을 제가 직접 만들지 않아도 된다면 큰 도움이 되겠네요.
이 분야에 꽤 깊이 몸담은 사람인데도 여러분이 뭘 하는지 모르겠습니다. 웹사이트가 기술 벤치마크보다 해결하려는 문제를 먼저 내세우면 좋겠습니다.
그리고 액터와 에이전트가 뭐가 다른지도 잘 모르겠어요. 에이전트를 액터라고 부르는 사람은 본 적이 없고, 작은 스타트업이 그 용어로 인식을 선점하기는 어려울 거라고 봅니다.
저도 같은 말을 하려고 들어왔어요. 저는 컴퓨터공학 박사이고, 스타트업 일을 하면서 새 아키텍처나 도구를 얼마든지 써볼 수 있는 사람이라 이 제품의 대상 독자일 텐데요.
"Rivet ( https://rivet.dev ) – a fast, high-density, and scalable orchestrator for agentic workloads using the actor model"(액터 모델을 사용하는, 빠르고 고밀도이며 확장 가능한 에이전트 워크로드용 오케스트레이터)를 읽고 "무슨 말인지 하나도 모르겠는데, 어쨌든 백엔드 서비스를 만드는 새로운 방식 같은 건가??" 싶었습니다.
저는 이제 설명을 읽고도 뭔지 모르겠으면 내 잘못이 아니라고 생각할 나이가 됐어요.
저도 Rivet이 정확히 뭘 하는지에 대해서는 아마 별로 앞서 있지 않을 거예요. 저는 쓰려는 물건에 직접 부딪쳐 가며 배우는 편인데, 지금까지는 읽기만 했거든요.
"액터"는 확립된 컴퓨터공학 용어에서 온 말이고 [1], 액터 안에 에이전트를 넣는다는 발상은 원리적으로 말이 됩니다.
이 스레드의 다른 분들 말씀처럼 README에 사용 사례가 몇 가지 있으면, 직접 부딪쳐 볼 만한 물건인지 판단하는 데 도움이 될 것 같아요.
[1] https://en.wikipedia.org/wiki/Actor_model
휴면은 액터가 유휴 상태인지 어떻게 판단하나요? 제 에이전트 런타임에서는 액터가 XS에서 돌아갑니다. 메시지는 큐에 쌓이고 현재 핸들러가 반환된 뒤에야 처리되므로, 동기 핸들러가 중간에 잘리는 일은 없습니다. 하지만 핸들러가 비동기 호출(예: HTTP 요청)을 기다리는 동안에는 다른 메시지가 처리됩니다. 그래서 "처리 중인 메시지가 없다"가 "진행 중인 게 없다"와 같은 뜻은 아닙니다. Rivet은 처리 중인 요청이 남아 있는 액터도 휴면시키나요? 그렇다면 응답이 돌아왔을 때는 어떻게 되나요?
안녕하세요 Nathan! 정말 훌륭한 제품을 만드셨고, 기술도 아주 탄탄해 보입니다. 사용 사례별 튜토리얼과 how-to 가이드가 더 있으면, 이 제품이 잘 맞는 용도로 사람들이 찾아서 쓰게 될 것 같아요. 멀티 에이전트 시스템, 코드 리뷰 에이전트, 소프트웨어 팩토리 같은 것들이요.
요즘은 그 어느 때보다 사서 쓰기보다 직접 만드는 쪽을 택하는 사람이 많습니다. 이 제품이 "지루한" 부분을 대신 처리해 줘서 팀이 둘 중 하나를 고르지 않아도 되고, 자기 사업만의 고유한 부분에 집중할 수 있다는 점을 강조하셔야 해요.
안녕하세요 Nathan! Rivet은 Playflow 시절부터 기억하고 있어요. 그때는 게임 서버 오케스트레이션을 하셨죠. 이렇게 성장한 모습을 보니 좋네요!
claude code, codex 같은 에이전트를 agent-os 안에서 완전히 돌려 보신 적 있나요? 사용 사례를 좀 더 정확히 이해하려는 거예요. 참고로 저는 최근에 claude code, codex 등을 위해 임시 리눅스 VM을 띄우는 파이프라인을 직접 만들었는데, 작업이 끝나면 자원은 풀리고 상태는 항상 유지되는 방식이에요. agent-os도 기본 발상은 이와 거의 비슷한가요?
그리고 S3 기반으로 바뀐 걸 보니 celld에서 이루어진 작업이 많이 떠오르네요. 셀프 호스팅할 수 있는 durable object가 더 많아지는 건 좋은 일입니다.
게임 하던 시절이 벌써 까마득하네요. 연락 주셔서 감사합니다!
(claude code, codex 같은 에이전트를 agent-os 안에서 완전히 돌려 보신 적 있나요?)
전부 agentOS 안에서 돌아가게 만들어 봤습니다. 하지만 에이전트 루프는 agentOS 밖에서 돌리고 도구로 노출하는 쪽이 더 나은 아키텍처라는 걸 알게 됐습니다. 에이전트를 샌드박스 안에서 돌리면 신뢰 경계와 피해 범위 때문에 곤란해져요.
또 Claude Code 인스턴스를 개별로 띄우는 메모리 오버헤드는 터무니없어서, 에이전트는 도구를 쓰는 단일 프로세스에서 돌리는 편이 낫습니다.
여기에 좀 더 자세히 적었습니다. https://rivet.dev/blog/2026-07-27-run-your-harness-outside-the-sandbox/
(그리고 S3 기반으로 바뀐 걸 보니 celld에서 이루어진 작업이 많이 떠오르네요. 셀프 호스팅할 수 있는 durable object가 더 많아지는 건 좋은 일입니다.)
감사합니다!
Rivet은 대부분의 S3 기반 데이터베이스와 아키텍처가 많이 다릅니다. 액터마다 객체를 하나씩 두는 방식은 비용과 성능 면에서 확장이 잘 안 돼서, 대신 SSD 계층형 스토리지 엔진을 만들었습니다. https://rivet.dev/changelog/2026-10-26-introducing-rivet-3-0-preview/#warp-drive-bottomless-storage-with-the-speed-of-an-ssd
한번 써보시면 Discord로 연락 주세요. 오랜만에 이야기 나누면 재밌겠네요. https://rivet.dev/discord
출시 축하드립니다! Rivet 괜찮아 보이네요. 꼭 써보겠습니다.
(샌드박스는 비싸고, 대부분 놀고 있고, 시작이 느립니다.)
샌드박스 스타트업 상당수는 동의하지 않을 텐데요. 이를 뒷받침할 수치가 있나요?
감사합니다! 써보시면 후기를 들려 주세요. https://rivet.dev/discord
(샌드박스 스타트업 상당수는 동의하지 않을 텐데요. 이를 뒷받침할 수치가 있나요?)
모든 경우에 맞는 정답은 없지만, 대부분의 에이전트 워크로드에는 Rivet의 이점이 잘 맞는다고 봅니다. 샌드박스가 사라질 거라고는 생각하지 않지만, 워크로드마다 특화된 아키텍처로 옮겨 갈 거라고 생각합니다.
비용 면에서는, RL 같은 용도에서 비용을 아끼려고 Rivet 도구를 쓰는 F500 기업들이 있습니다.
콜드 스타트는 사용 사례에 따라 크게 다르고, 모든 경우에 맞는 정답은 없습니다. 벤치마크는 Compute SDK 샌드박스 벤치마크에서 가져온 것이고, 자세한 내용은 여기 있습니다. https://rivet.dev/docs/benchmarking/
상태 영속화를 SQLite 선행 기록(write-ahead) 방식으로 하고 이를 S3로 계층화한 건, 원시 객체 스토리지의 지연 시간-비용 함정에 대한 아주 깔끔한 해법입니다. 이렇게 액터 상태를 분리했을 때 운영상 가장 큰 이점은, 에이전트 실행이 턴 도중 타임아웃되었을 때 좀비 락이 생기지 않는다는 점입니다. 일괄 쓰기가 아직 S3로 내려가는 중인데 액터에 네트워크 파티션이 생기면 스플릿 브레인 펜싱은 어떻게 처리하는지 궁금합니다.
저희도 같은 문제를 겪었어요. 내부적으로는 just-bash와 손에 잡히는 파일시스템으로 흉내 냈습니다. 프로덕션에서는 에이전트 생태계를 조사한 뒤 DO로 갔는데, 그 뒤로 실제 트레이드오프가 있는 두 갈래(@cloudflare/agents 또는 think 대 @cloudflare/computer)로 나뉘었습니다. Rivet의 S3 구성은 저희에게 훨씬 잘 맞아 보여서, 다음 프로젝트에서 써보고 싶어요.
어떻게 되는지 알려 주세요! 저희는 Discord에서 활발히 활동하고 있습니다. https://rivet.dev/discord
저희는 기존 x86 샌드박스와 함께, Durable Objects와 비슷한 경량 샌드박싱 접근법도 크게 믿고 있습니다.
여기서 쓴 액터 모델 접근이 마음에 듭니다. 유휴 에이전트를 휴면시키면서 상태는 S3에 영속적으로 두는 건 비용 면에서 큰 이득이에요.
다만 Rivet이 폭주 루프 문제를 어떻게 다루는지 궁금합니다. 오래 사는 액터들이 서로 메시지를 주고받다 보면, 단순한 상태 버그 하나로 똑같은 페이로드를 끝없이 핑퐁하게 될 수 있습니다.
액터가 계속 살아서 응답하니(200을 돌려주니) 인프라는 멀쩡해 보이는데, 정작 개발자의 OpenAI 청구서는 뒤에서 폭발하고 있는 거죠.
루프 감지는 Rivet 위에서 만드는 개발자에게 전적으로 맡기나요, 아니면 순환 상태에 빠진 액터를 죽이는 오케스트레이터 차원의 기본 차단 장치가 있나요?
에이전트가 어떤 식으로든 에이전트 작업을 하려면 샌드박스 런타임이 필요하지 않나요? "샌드박스는 너무 느리다"고 하실 때, 에이전트 상태를 되찾으려고 샌드박스를 부팅해야 하는 걸 말씀하시는 건가요? 상태/메모리/컨텍스트와 런타임 환경이 Rivet에서는 별개의 개념이라는 건가요?
(저는 전문 개발자지만 오케스트레이션은 해본 적이 없어서, 기본적인 사고 모형 관점에서 이해해 보려는 겁니다)