ChatGPT Generated
멀티 에이전트 얘기를 할 때 사람들은 보통 런타임 이름부터 나열한다.
Claude Code, Gemini CLI, Codex, Cursor, opencode 같은 것들. 그리고 자연스럽게 이런 그림을 상상한다. 좋은 에이전트를 여러 개 띄워두고, 필요할 때 번갈아 호출하면 생산성이 크게 올라갈 것이라고.
하지만 실제로 운영해보면 금방 다른 사실이 드러난다. 문제는 “어떤 런타임이 더 똑똑한가”가 아니라, 이 여러 런타임을 어떤 질서 안에서 움직이게 할 것인가다. 같은 파일을 동시에 수정하면 충돌이 나고, 이미 정리된 결론을 각자가 다시 탐색하면 비용이 커지며, 규약 문서가 여러 군데 흩어져 있으면 같은 저장소를 서로 다르게 해석한다. 첨부한 초안이 짚었듯 핵심은 툴을 더 붙이는 것이 아니라 역할, 문서, 권한, handoff를 어떻게 고정할 것인가에 있다.
그래서 나는 이 구조를 이렇게 보는 편이 맞다고 생각한다.
opencode와 GSD는 “또 하나의 worker”가 아니라 control plane이다.
Claude Code, Gemini CLI, Codex는 그 control plane 아래에서 움직이는 실행 runtime이다.
이 관점이 중요하다. 왜냐하면 opencode는 원래 여러 provider와 모델을 연결할 수 있는 AI coding agent이고, terminal/desktop/IDE extension 형태로 쓰이며 provider 설정도 열려 있다. 다시 말해 “여러 모델을 수용하는 인터페이스”로서의 성격이 강하다. (OpenCode)
반면 GSD는 자신을 meta-prompting, context engineering, spec-driven development framework라고 설명한다. 즉, 특정 모델 하나의 성능을 높이는 도구라기보다 긴 세션과 복잡한 작업을 망가지지 않게 운영하는 계층에 가깝다. (Get Shit Done)
이 둘을 합치면 그림이 바뀐다.
중심은 더 이상 “Claude를 쓸까, Codex를 쓸까, Gemini를 쓸까”가 아니다.
중심은 **“어떤 작업을 어떤 문서 구조로 정의하고, 어떤 runtime에게 어떤 write surface만 허용할 것인가”**가 된다.
1. control plane이 먼저고, runtime은 그 다음이다
첨부한 글의 핵심 문장은 아주 명확하다.
규칙은 한 군데에만 두고, 상태는 채팅이 아니라 문서로 남기고, 병렬화는 툴 기준이 아니라 write scope 기준으로 하며, canonical decision과 execution trace를 분리해야 한다는 것이다. 그렇지 않으면 멀티 에이전트는 협업이 아니라 경쟁이 된다.
이 네 줄은 사실 control plane의 정의다.
좋은 control plane은 “에이전트를 많이 호출하는 시스템”이 아니다.
좋은 control plane은 적어도 다음 네 가지를 보장한다.
첫째, 규약의 원본이 하나여야 한다.
둘째, 작업 상태가 문서로 복구 가능해야 한다.
셋째, 병렬 실행 단위가 runtime 이름이 아니라 write scope여야 한다.
넷째, 공용 의사결정 문서와 실행 로그를 분리해야 한다.
이 구조를 먼저 세우고 나면 Claude Code, Gemini CLI, Codex는 각자 다른 “지능”이라기보다, 서로 다른 execution backend로 취급할 수 있다. 즉, 주인공은 runtime이 아니라 운영 계층이다.
2. opencode는 worker가 아니라 dispatch layer로 두는 편이 낫다
opencode를 단순히 또 하나의 agent로 보는 시각도 가능하다. 하지만 실전에서는 그보다 dispatch layer로 쓰는 편이 더 자연스럽다.
왜냐하면 opencode는 provider를 광범위하게 지원하고, 로컬 모델과 외부 provider까지 연결할 수 있으며, OpenAI-compatible provider까지 커스텀 설정으로 넣을 수 있다. 즉 특정 벤더에 매이지 않는 쪽의 성격이 강하다. (OpenCode)
이 말은 곧, opencode를 “나도 코드를 고치는 한 명의 worker”로 쓰는 것보다, 현재 작업을 어떤 모델/런타임으로 보낼지 결정하고, 필요한 문맥을 조립해 넘기는 쪽에 더 잘 맞는다는 뜻이다.
예를 들어 이런 식이다.
•
opencode: 작업 분류, 문맥 조립, 런타임 선택, dispatch
•
GSD: phase 정의, spec/plan/verify 구조 유지, context rot 방지
•
Claude Code: review / policy / subagent orchestration
•
Codex: 큰 코드 변경, 패치 생성, repo 이해, 수정 실행
•
Gemini CLI: 탐색, 로그 해석, 대안 제시, second opinion
이 구조에서는 opencode가 직접 모든 일을 해결하려 들지 않는다.
대신 “이번 작업은 구현보다 검증이 중요하다”, “이번 작업은 plan을 먼저 고정해야 한다”, “이번 작업은 Codex가 patch를 만들고 Claude Code가 검토하는 편이 낫다” 같은 교통정리를 맡는다.
즉 opencode의 가치는 문제를 직접 푸는 데만 있지 않고, 여러 runtime이 같은 control plane 아래에서 일하도록 만드는 데 있다.
3. GSD는 runtime 위에 올라가는 운영 프로토콜이다
GSD를 그냥 “Claude Code용 프롬프트 팩”처럼 보는 것은 너무 좁다. 공식 문서는 GSD를 Claude Code, OpenCode, Gemini CLI, Codex를 위한 framework라고 설명하고, meta-prompting, context engineering, multi-agent orchestration, spec-driven development를 전면에 내세운다. (Get Shit Done)
또 GitHub README도 GSD를 Claude Code 중심의 spec-driven development system으로 설명하지만, 최근 문서와 생태계에서는 이미 여러 runtime을 겨냥한 운영 층으로 확장되고 있다. (GitHub)
특히 “One Codebase, Three Runtimes” 글이 흥미로운데, 여기서는 단일 코드베이스에서 Claude Code, OpenCode, Gemini CLI를 대상으로 install-time conversion을 수행한다고 설명한다. 명령, agent, tool reference, hook을 runtime별로 변환하고, OpenCode 쪽은 별도의 permission 구성을 자동으로 맞춘다고 한다. (Medium)
이 지점이 시사하는 바는 꽤 크다. GSD는 단순한 prompt template이 아니라, 서로 다른 runtime 위에서도 같은 운영 철학을 유지하려는 번역 계층이라는 것이다.
즉, GSD의 본질은 모델을 바꾸는 것이 아니라 작업 흐름을 보존하는 것이다.
4. shared context의 중심은 채팅창이 아니라 docs/<job>/여야 한다
첨부 초안에서 가장 중요한 부분 중 하나는 shared context가 대화가 아니라 docs/<job>/라는 주장이다. 작업은 index, material, plan, report-progress, report-output 같은 파일 묶음으로 정리되고, 여러 agent는 같은 채팅을 공유하는 것이 아니라 같은 문서 구조를 읽으며 일한다는 것이다.
이건 아주 강력한 발상이다.
왜냐하면 runtime은 바뀌어도 문서 구조는 바뀌지 않기 때문이다.
Claude Code는 subagent와 훅을 통해 작업을 쪼개고 특정 이벤트에서 후처리를 걸 수 있다. 공식 문서에 따르면 subagent는 별도 context window와 도구 권한을 가진 specialized AI assistant이고, hooks는 PreToolUse, PostToolUse, SessionStart, SubagentStop 같은 이벤트에 명령을 걸 수 있다. (Claude API Docs)
Codex 쪽도 로컬에서 코드 읽기·수정·실행을 하는 coding agent이며, 반복 작업을 줄이기 위한 skills 개념이 계속 강화되고 있다. (OpenAI Help Center)
하지만 이 모든 기능을 묶어주는 공통 기반은 채팅 세션이 아니라 문서 기반 state다.
문서 기반 state를 쓰면 좋은 점은 단순하다.
세션이 끊겨도 복구가 쉽고, runtime이 바뀌어도 handoff가 유지되며, 최종적으로 사람이 검토할 때도 근거가 남는다. 이 순간부터 멀티 에이전트는 프롬프트 요령이 아니라 작업 기록 시스템이 된다.
5. runtime별 역할보다 write scope가 더 중요하다
멀티 에이전트를 말할 때 흔히 이렇게 나눈다.
Codex는 구현.
Claude는 리뷰.
Gemini는 조사.
이 분리는 어느 정도 유효하지만, 첨부 초안이 강조하듯 진짜 병렬화 기준은 툴이 아니라 write scope여야 한다.
예를 들어 실제 운영에서는 이렇게 나누는 편이 더 강하다.
•
lane A: 특정 shard 처리
•
lane B: schema QC
•
lane C: export preparation
•
lane D: monitoring / verification
•
conductor lane: canonical docs 통합
즉, “누가 더 똑똑한가”보다 “누가 어디까지 쓸 수 있는가”가 먼저다.
Claude Code든 Codex든 Gemini CLI든, 자기 lane의 packet과 write_outputs만 만지게 하면 충돌이 크게 줄어든다. 반대로 똑같은 repo 전체를 다 읽고 다 쓰게 하면 모델이 아무리 좋아도 결국 서로 꼬인다.
그래서 control plane은 worker를 “모델명”으로 관리하는 것이 아니라, packet + ownership + write scope로 관리해야 한다.
6. canonical docs와 execution trace를 분리해야 다른 runtime을 안전하게 부릴 수 있다
첨부 글에서 또 하나 아주 중요한 포인트는 canonical docs와 execution trace의 분리다. docs/<job>/...는 공식 판단과 handoff를 남기는 공간이고, tmp/<job>/lanes/...는 lane별 상태와 임시 메모와 로그를 남기는 공간이다.
이 분리가 왜 중요하냐면, Claude Code·Gemini CLI·Codex 같은 runtime은 모두 “일단 많이 시도해보는” 경향이 있기 때문이다. 그 결과를 곧바로 공용 문서에 쓰게 하면 전체 시스템이 금방 지저분해진다.
그래서 더 나은 방식은 이렇다.
•
worker runtime은 tmp/ 아래 자기 lane에만 쓴다.
•
conductor만 docs/<job>/를 업데이트한다.
•
최종 판단은 항상 느리게, 의식적으로 canonical docs에 반영한다.
이 구조가 있으면 worker는 빨리 움직일 수 있고, control plane은 안정적으로 남는다.
속도와 안정성을 같은 파일에서 동시에 해결하려 하지 않고, 두 층으로 분리해서 해결하는 것이다.
7. “opencode + GSD → other runtime” 구조의 장점
이제 핵심 그림은 비교적 선명하다.
User / Operator
↓
GSD phase model + docs/<job> + packets
↓
OpenCode dispatch / provider abstraction / context assembly
↓
Claude Code | Codex | Gemini CLI
↓
tmp/<job>/lanes/*
↓
Conductor merges into docs/<job>/*
Plain Text
복사
이 구조의 장점은 적지 않다.
첫째, runtime 교체 비용이 낮다.
Codex 대신 다른 executor를 붙여도, Claude Code 대신 다른 reviewer를 붙여도, control plane이 유지되면 전체 구조는 그대로 간다.
둘째, 문맥 손실에 강하다.
GSD의 핵심 문제의식인 context rot를, runtime 자체의 기억력에 기대지 않고 문서 구조와 phase discipline으로 완화할 수 있다. (Get Shit Done)
셋째, 권한 설계가 쉬워진다.
Claude Code는 hooks와 subagents로, OpenCode는 permission/config 체계로, 각 runtime은 서로 다른 방식으로 제어되지만, control plane이 먼저 있으면 결국 다 “누가 무엇을 읽고 쓸 수 있는가” 문제로 환원된다. (Claude API Docs)
넷째, 사람이 최종 통제권을 잃지 않는다.
Cursor든 git diff든 최종 검토 지점은 여전히 사람 쪽에 둘 수 있다. AI는 lane을 처리하지만, canonical decision은 control plane과 사람의 합의로 남는다.
8. “딸깍”은 runtime 자동호출이 아니라 control plane 실행이어야 한다
많은 사람이 원하는 것은 버튼 하나로 Claude Code, Gemini CLI, Codex가 알아서 협업하는 그림이다.
그런데 잘 되는 자동화는 대체로 “문제를 해결하는 버튼”이 아니라 control plane을 실행하는 버튼이다.
버튼이 해야 할 일은 이런 쪽이다.
1.
docs/<job>/ scaffold 생성
2.
spec / plan / packet 생성
3.
OpenCode가 runtime dispatch
4.
각 runtime이 자기 lane 실행
5.
tmp/ 수집
6.
conductor가 canonical docs 갱신
7.
최종 검토를 위해 Cursor 또는 diff open
이 흐름은 겉보기엔 덜 화려하지만, 실제로는 훨씬 잘 버틴다.
왜냐하면 자동화의 중심이 magic이 아니라 절차의 재현성에 있기 때문이다.
9. 결론: 여러 runtime을 쓰는 것이 아니라, 여러 runtime을 통치해야 한다
멀티 에이전트의 본질은 런타임을 많이 띄우는 데 있지 않다.
그건 어디까지나 표면이다.
진짜 본질은, 첨부 글이 강조한 것처럼 규칙의 원본을 하나로 두고, 상태를 문서로 남기고, 병렬화 기준을 write scope로 바꾸고, canonical docs와 execution trace를 분리하는 데 있다.
그 위에 opencode와 GSD를 올리면, 이 둘은 단순한 도구가 아니라 통치 계층이 된다.
그리고 Claude Code, Gemini CLI, Codex는 그 아래에서 돌아가는 실행 runtime이 된다.
이 관점으로 보면 멀티 에이전트는 “어떤 모델이 제일 좋냐”는 취향의 문제가 아니라,
어떤 control plane이 런타임들을 팀처럼 움직이게 만드느냐의 문제가 된다.
좋은 시스템에서는 에이전트가 많아질수록 chaos가 커지지 않는다.
오히려 control plane이 더 빛난다.
References
[3] GSD (Get Shit Done). (n.d.). Official documentation. https://gsd-build-get-shit-done.mintlify.app/
[4] Glittercowboy. (n.d.). Get Shit Done (GSD) repository. GitHub. https://github.com/glittercowboy/get-shit-done
[5] Hightower, R. (n.d.). One codebase, three runtimes: How GSD targets Claude Code, OpenCode, and Gemini CLI. Medium. https://medium.com/%40richardhightower/one-codebase-three-runtimes-how-gsd-targets-claude-code-opencode-and-gemini-cli-29c98cfe96c6
[8] OpenAI. (n.d.). OpenAI Codex CLI getting started. https://help.openai.com/en/articles/11096431-openai-codex-ci-getting-started