원문: Burke Libbey, Javier Moreno, and River, “Under the River (2026)”, Shopify Engineering, 2026-05-28. URL: https://shopify.engineering/under-the-river 이 노트는 단일 소스(Shopify 엔지니어링 블로그)의 핵심을 한국어로 정리한 요약이다. 기존 harness, moc-ai-agents-harness, 2026-07-11-building-the-future-of-agentic-infrastructure와 함께 읽는다.
개요
shopify-river는 Shopify가 사내 Slack에 상주시킨 AI 코딩 에이전트다. 직원들은 공개 채널에서 @river를 멘션해 호출하고, River는 코드를 읽고·테스트를 돌리고·PR을 열고·데이터 웨어하우스를 조회하고·프로덕션 트레이스를 뒤지며, 때로는 “그 패턴은 안 좋다고” 계획에 반박하기도 한다. 핵심 차별점은 River가 돌아가는 인프라(Aquifer)와 “공개에서만 동작한다(no direct messages)“는 철학이다. 모든 세션은 전 직원이 볼 수 있는 공개 Slack 기록이 되고, 이 corpus가 다시 River의 스킬·프롬프트·기본값으로 역류해 들어간다 — “모델 재학습 없이 에이전트가 더 똑똑해진다.”
핵심 아키텍처: Aquifer의 3계층 분리
Shopify가 River를 올려놓은 내부 에이전트 플랫폼 Aquifer는 세 층으로 나뉜다. 가장 결정적인 설계 결정은 harness가 샌드박스 밖에 존재한다는 것이다 — Anthropic 2026-04 “Scaling Managed Agents”의 “뇌를 손에서 분리하라(Decouple the brain from the hands)“가 검증한 경계다.
- Session — Postgres로 뒷받침되는 append-only 이벤트 로그를 가진 영속 정체성. “지금까지 무슨 일이 있었는가”의 정규 진실(canonical truth).
Cells die, sandboxes die, machines die. The conversation doesn't. - Harness — 에이전트 루프(히스토리를 읽고 → 모델 호출 → 도구 인텐트 방출). “재생성 비용이 싸고, 일회용.” 샌드박스 밖에 산다.
- Sandbox — 코드가 실제로 돌아가는 곳(파일시스템·셸·레포·bash·edit·build·test). 일회용; 가끔 따뜻하지만 대개 새 것.
이 경계에서 세 가지 성질이 나온다. 안전(파괴적 명령의 폭반 반경 바깥에 에이전트 루프), 교체 가능성(모델·런타임·언어를 샌드박스를 건드리지 않고 교체), 관측 가능성(전체 의사결정 스트림이 한 곳에서 보인다).
두 개의 근본 베팅 (2024년 초)
River 인프라는 2024년 초의 두 베팅 위에 세워졌다. 둘 다 “인기 있는 결정은 아니었다”고 글은 인정한다.
- 모노레포 회사가 되자 — 전체 코드를
World라는 단일 레포로 통합. 에이전트가 한 워크스페이스를 벗어나지 않고, “프로덕션 로그 한 줄 → 그 원인이 된 커밋”까지 코드베이스 전체를 가로질러 이동할 수 있게 한다. - 모든 것을 Nix로 짓자 — 개발·CI·프로덕션 이미지를 모두 Nix로 구성해 “재현 가능한 단일 기판” 하나로 묶는다.
모노레포 이전은 “고통스러웠다”: CI를 한 자릿수 배로 확장해야 했고, 머지 큐가 load-bearing이 되었고, 빌드 캐시가 하나의 제품이 되었으며, 테스트 인프라는 “모든 변경이 의존성 그래프의 큰 부분을 재컴파일할 수 있다”는 가정 위에서 다시 지어졌다.
Session Cells: 세션 수준에서 “가축, 애완동물 아닌”
세션이 살아나면 session cell이 구체화된다 — 한 호스트 위에서 Go 런타임과 에이전트 하네스를 같은 프로세스 그룹으로 실행하는 일회용 프로세스. idle면 종료되고, 다음 상호작용에서 (아마 다른 호스트의) 새 cell이 떨어진다. 그런데 세션 정체성과 대화 히스토리는 Postgres에 살아 있으므로 사용자는 끊김을 느끼지 못한다. 철학: “세션 수준에서는 애완동물이 아니라 가축(cattle, not pets, at the session level).”
Profiles over platforms: 다음 에이전트는 플랫폼이 아니라 프로필이다
River는 Aquifer 위의 하나의 profile이다. profile은 데이터다 — 시스템 프롬프트·스킬·확장·샌드박스 정책·모델 기본값을 Nix로 만들어 bundle로 배포한다. PR 리뷰도 별도 profile, 헤드리스 “pi” 에이전트 Vanilla도 별도 profile. 새 에이전트 제품을 추가한다는 건 새 플랫폼을 짓는 게 아니라 bundle 하나를 더하는 일이다. 같은 기판 위 세 가지 실행 모드:
- Interactive — River: 영속 세션, 살아있는 사람, 장기
- Automation — PR 리뷰: 영속 세션, 외부 시스템 트리거, 사람 없이도 동작
- Job — CI/배치: 일회용, 프로비저닝→실행→스트리밍→파괴; 샌드박스 평면을 재사용, 세션 로그는 선택
스킬(skills)은 레포 안의 파일로 쓰여진 지식이며, 세션에 필요할 때 로드된다. World에는 스킬·컨벤션·intent document·런북·AGENTS.md·존 지식이 함께 들어 있어, 에이전트가 쓸수록 “복리로 쌓이는 지능층(intelligence layer)“이 된다.
공개 기본(public-by-default): 사적 에이전트의 천장을 넘다
River는 “공개에서만 동작한다. 다이렉트 메시지는 없다.” 이 철학의 근거:
- “사적 에이전트엔 천장이 있다 — 키보드 앞의 그 사람. 공개 에이전트는 그 이후에 오는 모든 세션을 가르친다.”
- 각 엔지니어가 자기만의 사적 에이전트를 돌리면 지식이 세션과 함께 죽고, 에이전트들이 서로 배우지 못한다. River는 모든 상호작용을 공개·영속으로 만들어 이를 해결한다.
- 공개 transcript corpus는 패턴으로 채굴돼 River의 스킬·프롬프트·기본값으로 역류한다.
두 번째 설득력 있는 주장은 “에이전트 친화적 ≈ 인간 친화적” 이다: “에이전트를 위해 바꾼 모든 것은 인간 엔지니어에게도 올바른 것이었다 … 코드베이스를 에이전트가 읽기 쉽게 만드는 일은, 당신이 인간 엔지니어들에게 진 빚(that debt)을 갚는 것일 뿐이다. 에이전트는 그 빚을 보이게 만들 뿐.”
규모 (원문 인용: 최근 30일 윈도우)
- Shopify 전체 병합 PR의 약 1/8이 River 공동저자
- 5,170개 Slack 채널에서 59,918 River 세션
- 세션이 7,000명 이상의 작업에 관여 (Tobi가 5월 초에 포스팅했을 때보다 약 1,200명 증가)
- 해당 기간 병합된 River 공동저자 PR 3,536건
- 세션 중위 길이 19분, 세션당 도구 호출 중위 50회
- 사용량 데이터는 River가 매 세션마다 직접 쓰는
river_sessions도메인 테이블에 저장
에이전트 인프라를 짓는 사람들을 위한 세 우선순위 (원문)
- “뇌를 손에서 분리하라” — 하네스는 샌드박스 안에 살면 안 된다. 이 경계는 나중에 retrofit할 수 없다.
- “에이전트를 구조적으로 멀티플레이어로 만들라” — 에이전트 스레드의 프라이버시는 불이익이다. corpus가 복리 자산이다.
- “다음 에이전트를 플랫폼이 아니라 프로필로 대하라” — 두 번째 에이전트가 두 번째 플랫폼을 강제한다면, 기판이 아직 지어진 게 아니다.
위키·에이전트 설계 관점에서의 메모
- Durable의 단위는 ‘conversation’이지 인프라가 아니다. 2026-06-25-langsmith-engine-agent-traces-durable-memory(트레이스를 지속 가능한 메모리로)와 같은 맥락: 인프라·셀·샌드박스는 일회용이되, 세션 로그는 영속 + append-only(Postgres)로 남긴다.
- 하네스/샌드박스 경계는 self-edit loop 바깥의 안전 경계와 같은 종류다. 2026-07-04-harness-engineering-for-self-improvement가 “evaluator·permission·security boundary는 self-edit loop 밖에 두라”고 한 것과, Shopify가 하네스를 샌드박스 밖에 둔 것은 같은 원리의 다른 표현: “폭반 반경 바깥에 의사결정 루프를.”
- ‘profile = data’ 모델은 스킬/AGENTS.md/런북을 코드베이스 안 ‘지능 파일’로 취급한다. loop-engineering과 code-native-memory의 ‘상태를 파일로 영속화’ 관행의 회사 단위 실증.
- 공개 corpus → 스킬 역류는 자가개선 루프지만, 모델 재학습이 아니라 문맥·스킬 차원의 자가개선. 2026-07-11-skillopt-self-evolving-agent-skills(텍스트 공간에서 스킬 최적화)과 비슷하게 “모델은 그대로 두고 외부 지식을 진화시킨다.”
- 실패 모드 대척점: 이 vault의 Anthropic 좌담(2026-07-11-building-the-future-of-agentic-infrastructure)이 경고한 “하이퍼인디펜던스 + 산발화(sprawl)” 실패 모드에 대해, River의 ‘공개 기본 + 단일 기판’은 그 반대 설계 — “누구나 프라이빗 에이전트를 돌리면 지식이 세션과 죽는다”는 진단의 해답.
관련 노트
- shopify-river — River 엔티티 (Shopify의 Slack 기반 AI 에이전트)
- harness — 에이전트 하네스 개념과 기존 사례
- moc-ai-agents-harness — 하네스 & 자가개선 MOC
- 2026-07-11-building-the-future-of-agentic-infrastructure — Anthropic 좌담에서 Caitlyn이 River를 엔드투엔드 개발 에이전트 사례로 언급
- 2026-07-04-harness-engineering-for-self-improvement — Lilian Weng: 하네스를 RSI의 현실적 경로로 본 정리 (안전 경계를 루프 밖에)
- loop-engineering — 자동화·상태·검증·핸드오프를 얹은 코딩 에이전트 운영 루프
- code-native-memory — 컨텍스트 부패 대안으로 파일·구조화 메모리 기반 지속
- 2026-06-25-langsmith-engine-agent-traces-durable-memory — 트레이스를 durable 메모리로
- 2026-07-11-skillopt-self-evolving-agent-skills — 고정 모델의 외부 스킬을 bounded edit로 최적화