코드가 한 줄도 없는 리포가 먼저 정한 것 — agt001 의 계약 우선 멀티에이전트 설계
정리 대상 리포: github.com/kyungsikjeung/agt001
2026-09-21 에 만들어진 리포다. 들어가 보면 실행 파일이 없다. README.md 와
docs/ 아래 마크다운 8개, 합쳐서 1,800여 줄. Dockerfile.backend 와
render.yaml, 워밍업 셸 스크립트 하나가 템플릿으로 들어 있는 게 전부다.
9월 28일 제출인 NVIDIA 해커톤 프로젝트인데, 마감 7일 전에 코드 대신 경계를
먼저 적어 둔 리포다.
읽을 값이 있는 건 그 선택 자체다. 아래는 이 리포가 무엇을 확정해 놓았는지, 그리고 그 확정이 어떤 실패를 막으려고 만들어졌는지 정리한 것이다.
1. 한 줄짜리 채팅이 배포된 앱이 되기까지, 18개 노드
전체 그림은 docs/hackathon/ARCHITECTURE.md 에 있다. 고객이 채팅으로 요구를
말하면, 그게 배포된 웹/안드로이드 앱 링크가 되어 카카오톡으로 돌아온다.
번호가 ①부터 ⑱까지 붙어 있다.
| 구간 | 노드 | 담당 |
|---|---|---|
| 대화·요구 | ② 챗봇 → ③ RAG 사전확인 → ④ 접수 → ⑤ 검증 → ⑥ 질의(옵션 3개+추천) → ⑦ 승인 게이트 → ⑧ 견적+근거 | 팀원 A |
| 디자인·전달 | ⑨ UI 시안 생성 → ⑩ 시안 확인 링크 → ⑪ 카카오링크 전송 | 팀원 B |
| 코드·배포 | ⑫ 스펙 생성 → ⑬ 플래너 → ⑭⑮ 웹·안드로이드 병렬 생성 → ⑯ 빌드 → ⑰ 배포본 | 팀원 C |
| 최종 | ⑱ 사람 최종 검토 | 3명 순번제 |
세 사람이 세 덩어리를 나눠 갖는데, 각자 만드는 건 에이전트다. 즉 이건 “기능을 셋으로 쪼갠” 게 아니라 파이프라인을 셋으로 자른 구조다. 자른 자리가 곧 실패 지점이 된다.
리포는 여기에 REQ 카탈로그를 하나 더 얹어 뒀다(REQUIREMENTS.md, 21일 저녁에
추가됐다). REQ-GATE-001, REQ-REVIEW-001 처럼 요구마다 ID 를 붙이고
담당자·노드 번호를 한 표에 묶는다. 18개 요구가 18개 노드에 1:1 로 걸린다.
2. 자른 자리에 계약을 박아 뒀다 — BND-1 … BND-9
INTEGRATION_STRATEGY.md 의 1절이 이 리포의 핵심이다. 세 사람 사이를 오가는
데이터마다 경계 ID 를 붙이고, contracts/*.schema.json 으로 스키마를 고정한
뒤 예시 JSON 까지 같이 둔다. 그리고 D0 에 세 사람이 그 스키마와 예시에
“서명”(리뷰 완료)하는 걸 첫 번째 통합 체크포인트로 잡았다.
예를 들어 A 가 내보내는 두 계약은 이렇게 생겼다.
BND-2 (A → B): { requirement_id, platform: "web"|"android",
features: [...], quote: {amount, basis} }
BND-3 (A → C): { requirement_id, confirmed_items: [...],
platform, acceptance_criteria: [...] }
규칙이 두 줄 붙어 있다. 둘은 같은 requirement_id 로 동시에 나가야 한다
(B 와 C 가 같은 요구를 다루고 있다는 보장), 그리고 BND-3 는 승인 게이트를
통과하지 않으면 절대 발화되지 않는다. 두 번째 줄에는 “코드 리뷰에서 가장
먼저 확인할 항목”이라는 주석까지 달려 있다.
계약을 바꾸는 절차도 적혀 있다. 변경은 반드시 PR 이고 3명 중 2명 승인, PR 본문에 “왜 바꾸는지” 한 줄과 영향받는 경계 ID 를 적고, 영향받는 사람에게 알린 뒤, 그날 저녁 통합 체크에서 실제로 안 깨졌는지 같이 확인한다. 테스트 전략도 유닛 테스트가 아니라 계약 테스트(“내 출력이 스키마를 만족하는가”)를 1순위에 둔다.
3인 7일짜리 일정에서 커버리지보다 경계가 값지다는 판단인데, 이건 취향이 아니라 산수다. 경계가 깨지면 세 사람이 동시에 멈추고, 유닛 테스트는 그 상황에서 아무것도 알려주지 않는다.
3. D+1 에 가짜로라도 끝까지 한 번 관통시킨다
두 번째 원칙이 워킹 스켈레톤이다. 일정표(D0~D+7)의 D+1 체크포인트가 이것 하나다.
채팅 입력 한 줄 → (가짜)배포 링크까지 전 구간 무중단 실행 (사람 검토는 더미 approved 로 통과)
이 날 A 가 만드는 건 “RAG 고정응답 + 게이트 자동통과” 버전이다. 품질이 아니라 형태가 먼저다. 리스크 표에도 같은 말이 다르게 적혀 있다 — “A 의 게이트/RAG 개발이 지연되어 B/C 가 막힘”의 징후 감지 시점이 D+1 워킹 스켈레톤 실패이고, 폴백은 “고정 응답이라도 스키마를 만족하는 버전을 최우선으로 내놓는다”다.
A 는 파이프라인의 시작점이라 아무도 기다리지 않는 대신, 모두가 A 를 기다린다. 문서가 그 비대칭을 명시적으로 인정하고 병목으로 부른다.
매일 저녁 15분 통합 체크도 규칙으로 박혀 있다. 각자 오늘 만든 걸 스켈레톤에 붙여 한 번 끝까지 돌리고, 실패하면 그 자리에서 “내 코드 vs 상대 계약 위반”을 가른다. 문서의 표현으로는, 이 15분을 생략하는 순간 D+6 에 몰아서 터진다.
4. 사람이 안 보면 전송이 안 되게 구조로 막았다
가장 눈여겨본 대목이다. ⑱ 사람 최종 검토는 보통 “검토 후 전송” 같은 문장으로 끝나고, 바쁘면 건너뛴다. 이 리포는 건너뛸 수 없게 배선을 바꿔 놨다.
- C(코드·배포)는 B 에게 직접 넘기지 않는다. C 의 산출물은 ⑱ 사람 검토로 들어가고, 검토 결과(BND-9)가 나와야 B 의 ⑪ 전송이 발화한다.
- BND-9 의 값이
approved일 때만 전송이 일어난다.rejected면 사유와 함께 재작업으로 되돌아간다. - 배포가 실패해 상태가
failed로 전파돼도 같은 자리에서 막힌다.
즉 검토를 건너뛰려면 계약을 위반해야 한다. 승인 게이트(⑦)도 같은 방식으로 고객 확인을 강제한다 — BND-3 가 게이트 없이는 안 나가므로, 고객이 확인하지 않은 요구는 애초에 개발로 내려가지 않는다.
일정표에는 이 게이트를 운영하는 항목까지 따로 있다. D0 에 검토 체크리스트 3항목 초안, D+4 에 순번표 확정과 실제 반려 케이스 1회 테스트, D+6 리허설에 검토 당번 실참여 + 소요시간 측정. 리스크 표에는 “검토 당번이 자리에 없어 배포본이 전송 직전에서 멈춤”이 한 줄로 올라와 있고, 폴백은 검토 소요시간 상한(예: 5분)을 정하고 넘기면 다음 순번이 받는 규칙이다.
사람을 파이프라인에 넣으면 사람이 병목이 된다는 걸 알고, 그 병목을 없애는 대신 운영 규칙으로 관리하기로 한 선택이다.
5. 못 하는 걸 못 한다고 적어 둔 부분
문서가 좋은 쪽으로 이상한 지점이 두 군데 있다.
참조 리포에 대한 자평. ARCHITECTURE 6-1 절은 참고로 삼은 기존 리포
(hackathon-agent-chatbot)가 로컬 macOS 백엔드 + ngrok 을 발표 시간에만 켜는
구조였고 카카오 연동은 미착수였다고 적는다. 그래서 “고객이 접속했을 때
최종산출물이 동작해야 한다”는 요구를 그 구조로는 만족할 수 없다고
결론 내린다. 자기 전작을 토이라고 부르는 문서는 흔치 않다.
콜드스타트를 없애는 대신 감수한다. 대안 호스팅 3안을 비교한 뒤 Render 무료 플랜을 골랐다. Render 공식 문서 기준으로 무료 웹 서비스는 인바운드 트래픽이 15분간 없으면 잠들고, 다시 깨어나는 데 약 1분이 걸린다1. 이 프로젝트는 GPU 연산을 PaaS 가 아니라 NVIDIA 호스티드 NIM API 가 맡으므로 콜드스타트는 컨테이너 재기동 지연일 뿐 데이터 손실이 아니라는 게 근거다.
그래서 없애는 대신 절차를 만들었다. /health 를 5초 간격으로 5회 때려 200 이
뜨면 끝나는 20줄짜리 warmup.sh 를 발표 10~15분 전에 돌리고, 심사 당일에만
유료 인스턴스로 올렸다가 끝나면 되돌린다. D+6 리허설 항목에 “콜드스타트
워밍업 점검”이 들어 있고, 백업으로 데모 영상도 그날 찍는다.
리스크 표의 다른 줄도 같은 톤이다. 카카오링크 연동이 D+3 까지 안 되면 이메일/ SMS 로 임시 대체하고 발표 스크립트에서 “카카오 연동은 다음 단계”로 솔직히 밝힌다고 적혀 있다.
6. 확정된 기술 선택
6절에 “확정된 사항”으로 못 박힌 것들이다.
- 시안 생성: Figma API 대신 커스텀 HTML/CSS 생성기. 외부 API 의존과 권한 절차를 7일 일정에서 빼려는 선택.
- 전달: 카카오링크. 시안 링크와 최종 배포 링크를 순서대로 보낸다.
- 모바일: React Native.
- RAG:
SRS.md와SPEC.md를 색인 대상으로 두고nemotron-3-embed-1b로 임베딩. 즉 검색 대상이 웹이 아니라 이 파이프라인이 과거에 뱉은 문서다. ③ 사전확인이 “기존 프로젝트와 겹치는가”를 묻는 이유가 여기 있다. - 플래너: NemoClaw 기반 Hermes 에이전트.
- 스택 요구 자체가 NVIDIA NeMo · NIM · Hermes 에이전트로 명시돼 있다2.
마무리 — 이 리포에서 가져갈 것
코드가 없는데도 읽을 게 남는 이유는, 이 문서들이 “무엇을 만들까”가 아니라 “어디서 깨질까”를 적었기 때문이다.
세 사람이 각자 에이전트를 만들면 깨지는 자리는 정해져 있다. 경계의 데이터 모양이 어긋나는 곳, 한 명이 늦어서 둘이 멈추는 곳, 사람이 봐야 하는데 안 보고 지나가는 곳. 이 리포는 그 셋에 각각 JSON Schema3, 워킹 스켈레톤, BND-9 라는 답을 붙여 놓고 시작한다.
결과는 9월 28일에 나온다. 계약이 실제로 안 깨졌는지, 워킹 스켈레톤이 D+1 에 정말 관통했는지는 그때 커밋 로그가 말해 줄 것이다. 지금 확인할 수 있는 건 1,800줄짜리 문서가 무엇을 미리 정했는가까지다.
References
- kyungsikjeung,
agt001— https://github.com/kyungsikjeung/agt001 (본문의 구조·계약·일정·확정사항은 모두 이 리포의README.md,docs/hackathon/ARCHITECTURE.md,INTEGRATION_STRATEGY.md,REQUIREMENTS.md,TEAM_A/B/C_SPEC.md,deployment/RENDER_DEPLOY.md를 2026-09-21 시점main기준으로 읽은 것이다)
-
Render, “Deploy for Free — Spinning down on idle” — https://render.com/docs/free (“Render spins down a Free web service that goes 15 minutes without receiving any inbound traffic… This process takes about one minute.”) ↩
-
NVIDIA, “NVIDIA NIM” 공식 문서 — https://docs.nvidia.com/nim/index.html ↩
-
JSON Schema 공식 사양 — https://json-schema.org/specification ↩