Cord: AI 에이전트 트리 조정
Source: Hacker News
다중 에이전트 협업의 도전
AI agents는 single‑task execution에 뛰어납니다: Claude에게 집중된 지시를 주면 바로 수행합니다.
하지만 실제 업무는 거의 단일 작업이 아닙니다. tree of interdependent tasks와 비슷하며, 다음과 같은 특징이 있습니다:
- Dependencies – 이후 단계는 이전 단계의 결과에 의존합니다.
- Parallelism – 여러 하위 작업을 동시에 실행할 수 있습니다.
- Context flow – 전체 워크플로우에 걸쳐 정보가 원활히 공유되어야 합니다.
현재 Multi‑Agent Framework가 놓치는 이유
- Over‑specialization – 보다 넓은 오케스트레이션 과제보다는 고립된 문제에 초점을 맞춥니다.
- Fragmented communication – 에이전트 간 컨텍스트 전달 메커니즘이 제한적입니다.
- Scalability gaps – 복잡한 의존성 그래프와 대규모 병렬 실행을 다루는 데 어려움이 있습니다.
핵심: AI agents의 진정한 잠재력을 발휘하려면 task trees, dependency resolution, parallel execution, context propagation을 관리하는 프레임워크가 필요합니다—단일 작업에 국한된 솔루션이 아니라.
Source: …
What’s Out There
| Framework | Coordination Model | Strengths | Limitations |
|---|---|---|---|
| LangGraph | 상태 머신 그래프 (Python으로 정의된 노드 + 엣지) | • 정밀하고 결정론적인 워크플로 • 고정 파이프라인에 적합 | • 그래프가 정적이라 에이전트가 작업 중에 경로를 변경할 수 없음 • 개발자가 모든 가능한 분해를 미리 예상해야 함 |
| CrewAI | 역할 기반 팀 (예: researcher, analyst, writer) | • 직관적이며 인간 같은 팀 메타포 • 고수준 책임을 할당하기 쉬움 | • 역할이 설계 시점에 고정됨 • 팀이 더 많은 에이전트가 필요하거나 역할을 동적으로 분할해야 함을 스스로 인식할 수 없음 |
| AutoGen | 에이전트들이 대화하며 조정하는 그룹 채팅 | • 매우 유연하고 자생 행동 • 사전 의존성을 선언할 필요 없음 | • 명시적인 구조나 의존성 추적이 없음 • 권한, 스코핑, 타입된 결과가 없음 • 검사하거나 디버깅하기 어려움 |
| OpenAI Swarm | 최소한의 인계 (Agent A → Agent B) | • 경량이며 구현이 간단 | • 선형만 지원 – 병렬성이나 트리 형태 작업 생성이 없음 |
| Claude’s Tool‑Use Loops (Anthropic) | 툴 호출이 포함된 단일 에이전트 루프 | • 순차적 복잡성을 잘 처리 • 툴 기반 파이프라인에 적합 | • 대규모 작업에서 컨텍스트 창 제한에 부딪힘 • 병렬 실행이 없음 – 하나의 에이전트, 하나의 스레드 |
Common Thread
All of these frameworks require the developer to predefine the coordination structure:
- 워크플로 그래프, 에이전트 역할, 인계 패턴이 사전에 결정됩니다.
- 에이전트는 그 경계 내에서만 작동합니다.
Why Does This Matter Now?
Historically, hard‑coding decomposition made sense because early LLMs were unreliable at planning. Today’s models:
- 효과적으로 계획하고 스스로 문제를 하위 문제로 분해할 수 있습니다.
- 하위 작업 간의 의존성을 이해합니다.
- 작업이 한 번에 처리하기에 너무 큰 경우를 인식합니다.
Given these capabilities, the question arises:
왜 우리는 여전히 분해를 하드코딩하고 있는가?
에이전트가 트리를 구축하도록 하라
나는 Cord를 만들었다. 목표를 입력하면 된다:
cord run "Should we migrate our API from REST to GraphQL? Evaluate and recommend."
하나의 에이전트가 실행되어 목표를 읽고, 답변을 내리기 전에 조사가 필요하다고 판단하여 다음과 같은 하위 작업을 만든다:
● #1 [active] GOAL Should we migrate our API from REST to GraphQL?
● #2 [active] SPAWN Audit current REST API surface
● #3 [active] SPAWN Research GraphQL trade‑offs for our stack
○ #4 [pending] ASK How many concurrent users do you serve?
blocked‑by: #2
○ #5 [pending] FORK Comparative analysis
blocked‑by: #3, #4
○ #6 [pending] SPAWN Write migration recommendation
blocked‑by: #5
- 워크플로우가 하드코딩되지 않았다.
- 에이전트가 런타임에 이 구조를 결정했다.
- API 감사(#2)와 GraphQL 조사(#3)를 병렬로 수행했다.
- 인간에게 물어볼 ask 노드(#4)를 만들었다 – 권고안이 규모에 따라 달라지기 때문에, 스스로는 파악할 수 없었다.
- 질문이 감사 결과와 더 의미 있게 연결되도록 #4를 #2에 blocked‑by로 설정했다.
- #5를 fork로 만들어 분석이 지금까지 배운 모든 것을 상속하도록 했다.
- 최종 권고안(#6)을 분석 이후에 순차적으로 배치했다.
실행 추적
✓ #2 [complete] SPAWN Audit current REST API surface
result: 47 endpoints. 12 heavily nested resources...
✓ #3 [complete] SPAWN Research GraphQL trade‑offs
result: Key advantages: reduced over‑fetching...
? How many concurrent users do you serve?
Options: 100K
> 10K‑100K
● #5 [active] FORK Comparative analysis
blocked‑by: #3, #4
- 조사는 병렬로 실행된다.
- 두 작업이 모두 완료되고 질문에 답하면, 분석이 세 가지 결과를 모두 컨텍스트에 포함해 시작된다.
- 그 후 실제 규모와 API 현황에 맞춘 권고안을 생성한다 — 일반적인 GraphQL 블로그 포스트가 아니다.
Spawn vs. Fork
핵심 아이디어: spawn과 fork를 별개의 컨텍스트‑플로우 원시 연산으로 간주합니다.
| 측면 | Spawn | Fork |
|---|---|---|
| 컨텍스트 | 깨끗한 상태에서 시작: 프롬프트와 명시적으로 의존하는 노드들의 결과만 포함합니다. | 완료된 모든 형제 결과를 상속받아, 자식이 이전 작업에 대한 전체 지식을 갖게 합니다. |
| 비유 | 계약자를 고용: “여기 사양이니, 시작해.” | 팀원을 브리핑: “팀이 지금까지 배운 모든 것을 알고 있어.” |
| 비용 | 재시작 비용이 저렴하고, 이해하기 쉽다. | 비용이 더 많이 들지만, 이후 분석이 이전 결과에 기반할 때 필수적이다. |
| 동시성 | 무관함 – 두 경우 모두 병렬이든 순차적이든 실행될 수 있다. 차이는 자식이 무엇을 아는가에 관한 것이며, 실행 순서와는 무관하다. | 무관함 – 두 경우 모두 병렬이든 순차적이든 실행될 수 있다. 차이는 자식이 무엇을 아는가에 관한 것이며, 실행 순서와는 무관하다. |
실제 적용 방법
- 독립적인 연구 작업 →
spawn사용.
에이전트는 최소한의 필요한 컨텍스트만 받으며, 각 작업이 격리되고 재실행하기 쉬워진다. - 이전 작업에 의존하는 분석 →
fork사용.
에이전트는 완료된 모든 형제 결과를 받아, 지금까지 배운 모든 것을 종합할 수 있다.
모델은 스스로 어떤 원시 연산자를 사용할지 결정할 수 있다. 이는 “새롭게 시작”과 “이미 알려진 것을 기반으로 구축”하는 차이를 직관적으로 이해하기 때문이다.
내부 동작
각 에이전트는 MCP 도구를 갖춘 Claude Code CLI 프로세스로 실행되며 공유 SQLite 데이터베이스를 백엔드로 사용합니다.
핵심 MCP 작업
| 작업 | 시그니처 | 설명 |
|---|---|---|
| spawn | spawn(goal, prompt, blocked_by) | 새로운 하위 작업을 생성합니다. |
| fork | fork(goal, prompt, blocked_by) | 부모의 컨텍스트를 상속하는 하위 작업을 생성합니다. |
| ask | ask(question, options) | 사람에게 입력을 요청합니다. |
| complete | complete(result) | 현재 작업을 완료된 것으로 표시합니다. |
| read_tree | read_tree() | 전체 협업 트리를 가져옵니다. |
작동 방식
- 에이전트는 협업 트리에 대해 무관심하며, 위의 도구만 보고 필요에 따라 호출합니다.
- MCP 서버는 프로토콜을 강제합니다: 의존성 해결, 권한 범위 지정, 결과 주입.
ask노드가 준비되면 엔진이 일시 정지하고 터미널에 프롬프트를 표시합니다.- 인간의 답변은 결과로 저장되어 하위 노드의 차단을 해제합니다. 이 모델에서 인간은 트리의 능동적인 참여자이며, 수동적인 관찰자가 아닙니다.
구현 세부 사항
- 대략 500줄의 Python 코드입니다.
- 영속성을 위해 SQLite를, 프로세스 간 통신을 위해 MCP를 사용합니다.
Source: …
The Moment It Clicked
런타임을 작성하기 전에 한 가지 질문에 답해야 했습니다: Claude가 실제로 이것을 이해할 수 있을까?
전체 설계는 에이전트가 한 번도 본 적 없는 협업 도구들을 이해하는 데 달려 있습니다. 만약 spawn과 fork를 구분하지 못하거나 blocked_by를 무시한다면, 프로토콜은 처음부터 실패하게 됩니다.
The Experiment
- Set up a throw‑away MCP server with the five tools.
- Pointed Claude Code at the server.
- Ran 15 tests—no runtime, no engine, just Claude, the tools, and a task.
Test 1 – Decompose a Project
- Prompt: “Decompose this project into subtasks.”
- What Claude did (unprompted):
- Called
read_tree()to inspect the current state. - Created five child nodes with the correct dependency ordering.
- Wrote detailed prompts for each child.
- Called
read_tree()again to verify the nodes were created.
- Called
I hadn’t instructed any of that.
Test 2 – Fork vs. Spawn
- Scenario: independent research tasks and a synthesis step.
- Claude’s choice:
spawnfor the research (contractor‑style work).forkfor the analysis (briefing a team member).
When asked why, Claude gave the exact metaphor from my spec—even though it had never seen the spec.
Results
- 15/15 tests passed.
- Tasks were broken into 3–6 subtasks with correct dependencies.
- Claude asked well‑scoped human questions instead of guessing.
- When it tried to stop a sibling node and was rejected for lack of authority, it didn’t retry or hack around it; it escalated via
ask parent—the intended pattern.
Takeaway
That moment proved the runtime was worth building. The model already understood the protocol; I only needed to construct the surrounding infrastructure.
이것이 아닌 것
This implementation uses Claude Code CLI and SQLite, but the protocol — five primitives, dependency resolution, authority scoping, two‑phase lifecycle — is independent of all that.
- You could implement Cord over Postgres for multi‑machine coordination.
- Over the Claude API directly, without the CLI overhead.
- With multiple LLM providers — GPT for cheap tasks, Claude for complex ones.
- With human workers for some nodes.
The protocol is the contribution. This repo is a proof of concept.
사용해 보기
git clone https://github.com/kimjune01/cord.git
cd cord
uv sync
cord run "your goal here" --budget 2.0
계획 문서를 지정할 수도 있습니다:
cord run plan.md --budget 5.0
루트 에이전트는 마크다운을 읽고 이를 조정 트리로 분해합니다. 계획을 원하는 방식으로 작성하세요—불릿 포인트, 섹션, 서술형 등—그러면 에이전트가 작업 구조, 의존성 및 병렬성을 추론합니다.
참고: Claude Code CLI와 이를 포함하는 구독이 필요합니다.