글의 범위를 먼저 분명히 해둔다. 이 글은 구체적인 명령어 파일이나 에이전트 정의를 공개하지 않는다. 대신 파이프라인을 만들며 배운 원칙과, 그 원칙을 Lemuel Mall에 적용하지 않은 이유를 정리한다. 도구를 가지고 있다는 것과 그것을 쓴다는 것은 다르고, 시니어의 판단은 대개 후자에서 드러난다.
1. 15개 에이전트를 만들어두고, 프론트에는 안 썼다
내 로컬에는 .claude/commands/ 디렉토리가 하나 있다. 그 안에 15개 남짓한 에이전트 정의 파일이 쌓여있다. PM, BA, Architect, Backend, QA, DevOps 같은 소프트웨어 개발 조직의 역할 구분을 그대로 본뜬 구성이다. 이 파이프라인은 ASAT 같은 다른 개인 프로젝트에서 실제로 돌려왔다.
그런데 Lemuel Mall 프론트를 만들 때 이 파이프라인을 쓰지 않았다. 가진 도구를 안 썼다는 뜻이다. 쓰지 않았다는 사실 자체보다, 왜 안 썼는지를 언어화할 수 있다는 것이 이 글을 쓰게 된 이유다.
Anthropic의 Claude Code 공식 문서에는 이런 문장이 있다. "가장 효과적인 워크플로우는 과도한 엔지니어링을 피합니다. 단순한 제어 루프가 멀티 에이전트 시스템을 능가합니다." 처음 이 문장을 읽었을 때는 동의하지 못했다. 파이프라인을 공들여 만들어본 사람에게 저 문장은 도구 부정처럼 들린다. Lemuel Mall 프론트를 마치고 나서야 저 문장이 다르게 읽혔다. 도구 부정이 아니라 판단 촉구였다.
2. 왜 파이프라인을 만들었나 — 다른 프로젝트에서의 맥락
파이프라인이 필요했던 이유부터 정리해야 Lemuel Mall에서 안 쓴 이유가 설명된다.
혼자 하는 사이드 프로젝트에는 흔히 세 가지 결핍이 있다. 요구사항을 외부에서 가져다주는 사람이 없고, 아키텍처 결정을 두고 토론할 상대가 없고, 리뷰해줄 동료가 없다. 9년 동안 팀 안에서 일하며 당연하게 여겼던 역할들이 혼자가 되는 순간 모두 공백이 된다. 이 공백을 혼자서 메우려면 자기 자신이 역할을 바꿔가며 수행해야 하는데, 사람은 그게 잘 안 된다. 방금 아키텍트로 결정한 것을 개발자가 되어 반박하기 어렵고, 개발자로 쓴 코드를 QA가 되어 의심하기 어렵다.
역할 기반 에이전트 분리가 이 공백을 일부 메꿔준다. 같은 Claude에게 서로 다른 맥락과 책임을 심으면, 한 머리에서 나올 수 없는 종류의 반박과 의심이 생긴다. Anthropic 문서가 다른 곳에서 권하는 Writer/Reviewer 패턴 — 한 Claude가 코드를 쓰고, 새 컨텍스트를 가진 다른 Claude가 그 코드를 리뷰하는 패턴 — 의 확장판인 셈이다. 리뷰어가 쓴 사람에게 편향되지 않는 것이 핵심이다.
그래서 파이프라인을 만들었다. PM 에이전트는 요구사항의 외부화를, Architect 에이전트는 구조적 토론을, QA 에이전트는 편향 없는 검증을 대신한다. 15개쯤 되는 이유는 하나의 역할을 더 잘게 쪼갠 결과다. 예컨대 Backend 역할 하나에도 데이터 모델링, API 설계, 테스트 작성이 나뉜다.
이 구조는 요구사항이 모호하고, 결정의 여지가 넓고, 피드백 루프가 느린 프로젝트에서 작동한다. ASAT가 그런 프로젝트였다. 청각 공간 적응 훈련이라는 도메인이 내게 낯설었고, 헥사고날 아키텍처와 JSpecify/NullAway 같은 구조적 결정이 결과물을 크게 좌우했으며, 혼자 개발하니 리뷰가 없었다. 세 결핍이 다 있었다. 파이프라인이 값어치를 했다.
3. Lemuel Mall 프론트에서는 왜 안 썼나
Lemuel Mall 프론트는 세 결핍 중 어느 것도 심하지 않았다.
첫째, 요구사항이 외부에 있었다. 강의를 따라 만든 Spring AI 백엔드가 이미 API 스펙을 확정해둔 상태였다. /search, /ask, /chat 같은 엔드포인트와 요청/응답 포맷이 정해져 있고, SSE 스트리밍의 이벤트 형식도 결정되어 있었다. PM 에이전트가 할 일이 없었다. 요구사항을 외부화해줄 외부가 이미 존재했다.
둘째, 기술 결정의 여지가 좁았다. 프론트 스택은 React로 정했고, 스트리밍 수신은 fetch의 ReadableStream으로, 상태 관리는 컴포넌트 로컬 상태와 간단한 커스텀 훅 수준으로 가기로 했다. 아키텍트 에이전트에게 물을 거시적 결정이 많지 않았다. SPA냐 SSR이냐, 상태 관리 라이브러리를 뭘 쓸 것이냐 같은 논쟁은 사이드 프로젝트 규모에서 과한 토론이었다.
셋째, 피드백 루프가 이미 타이트했다. 프론트 작업의 결과는 브라우저에서 즉시 확인된다. 리렌더링이 느려지면 눈에 보이고, 스트리밍이 끊기면 화면이 멈춘다. QA 에이전트가 검증하기 전에 내가 먼저 본다. 에이전트 한 번을 거치는 것은 시간으로 치면 몇십 초, 맥락을 정리해 전달하는 비용을 합치면 몇 분이다. 브라우저에서 3초 만에 확인되는 일을 에이전트에 맡기는 건 이득이 아니라 손해다.
세 조건을 한 줄로 정리하면 이렇게 된다. 요구사항이 외부에 있고, 결정의 여지가 좁고, 피드백 루프가 타이트한 프로젝트에서는 파이프라인이 오버헤드다. 거꾸로 말하면, 이 세 조건 중 둘 이상이 뒤집히는 순간 파이프라인이 필요해진다. ASAT에서는 셋 다 뒤집혀 있었고, Lemuel Mall 프론트에서는 셋 다 성립했다.
이 판단은 글로 쓰고 나서야 명확해진 것이지, 작업하던 당시에는 직관적으로 결정했다. 파이프라인을 꺼내려다가 "이건 그냥 대화하면서 짜는 게 빠르겠다"는 감각이 먼저 왔다. 9년간 쌓인 감각이 파이프라인을 쓸지 말지를 판단하게 해준 셈이다. 그 감각을 언어화하는 과정이 이 글이다.
4. 그래서 프론트에서 Claude를 어떻게 썼나
파이프라인 없이 Claude와 일한다는 것은 결국 단일 세션에서 왕복 대화를 한다는 뜻이다. 그 대화를 생산적으로 만드는 것은 에이전트 템플릿이 아니라 무엇을 맡기고 무엇을 직접 하느냐의 경계였다.
내가 Claude에게 맡긴 것은 주로 의사결정이 명확한 영역의 구현 속도였다. 문서에 이미 답이 있는 API 사용법, 보일러플레이트 성격의 컴포넌트 뼈대, 반복적인 에러 처리 블록, 공식 권장 패턴을 따라 작성하는 훅 구조. 이런 작업은 내가 해도 결과물이 같고 속도만 다르다. Claude가 빠르다. 내 역할은 생성된 결과를 읽고 내 스타일과 프로젝트 규칙에 맞추는 것이었다.
맡기지 않은 것은 도메인 판단이 섞인 결정이었다. 스트리밍 응답을 어느 간격으로 뭉쳐서 렌더링할지, 로딩 상태를 몇 단계로 쪼갤지, 자연어 응답과 상품 그리드를 어떻게 배치할지. 이런 결정은 내가 이커머스 맥락에서 9년간 쌓아온 감각과 직접적으로 연결된다. Claude에게 물으면 일반론을 얻지만, 일반론은 내 프로젝트 맥락에서 정답이 아닌 경우가 많다. 이 영역에서는 Claude를 결정자로 쓰지 않고 반박자로 썼다. 내가 결정한 방향을 설명하고 "이 결정의 맹점이 뭐냐"를 물었다. 결정권은 내가 쥐고, 반박은 맡긴다. 이게 내가 찾은 가장 생산적인 경계였다.
다른 한 축은 맥락의 크기였다. 작은 맥락에서 답할 수 있는 질문은 Claude에게 빠르게 맡긴다. 예를 들어 특정 함수의 타입 정의, 특정 훅의 정확한 호출 순서. 반면 프로젝트 전반의 흐름을 알아야 답할 수 있는 질문 — 이 컴포넌트를 어디에 둬야 하는지, 이 상태를 어디서 관리해야 하는지 — 은 내가 잡는다. 맥락을 Claude에게 옮기는 비용이 직접 결정하는 비용보다 큰 경우가 많기 때문이다. 파이프라인이 필요한 프로젝트는 이 맥락 전달 비용을 역할 분리로 구조화해서 상각하지만, 작은 프론트 작업에서는 그 구조화 자체가 낭비다.
결국 파이프라인을 쓸지 말지는 맥락 전달의 한계 비용이 어디서 끊기는가의 문제였다. 맥락이 클수록 파이프라인이 상각을 해주고, 맥락이 작을수록 직접 대화가 빠르다. Lemuel Mall 프론트는 후자였다.
5. 가진 도구를 안 쓰기로 결정하는 것
도구를 만드는 것은 노력이 드는 일이고, 만든 도구를 안 쓰기로 결정하는 것은 그보다 더 드문 일이다. 사람은 자기가 만든 것을 쓰고 싶어한다. 매몰 비용이 판단을 흐린다.
9년차로 살아오면서 배운 것 중 하나는, 시니어의 일은 도구를 만드는 데서 끝나지 않고 도구를 언제 꺼낼지를 판단하는 데까지 이어진다는 것이다. 파이프라인을 만들었다는 사실은 단순 역량이다. 그 파이프라인을 어떤 프로젝트에 적용하고 어떤 프로젝트에 적용하지 않을지를 판단할 수 있다는 것이 시니어 역량이다. 이 두 역량은 다르게 길러지고, 다르게 증명된다.
이번 시리즈를 쓰면서 가장 정리가 되는 부분이 이 지점이다. 나는 파이프라인을 가지고 있고, 한편으로 그걸 쓰지 않기로 한 판단도 가지고 있다. 1편에서 강의로 백엔드를 완주했다고 밝혔듯, 이번 편에서도 파이프라인을 안 썼다고 밝힌다. 정직하게 드러내는 것이 오히려 판단의 근거를 보여주는 방식이다.
다음 편에서는 파이프라인을 실제로 쓴 다른 프로젝트의 회고로 넘어간다. Lemuel Mall이 "안 쓴 이유"를 정리한 글이라면, 다음 글은 "썼을 때 어땠는지"의 이야기가 된다. 두 편이 합쳐져야 파이프라인에 대한 내 입장이 완결된다.
'Software > Maker(Spring & Python & node)' 카테고리의 다른 글
| 에이전트가 나 대신 토론할 때 — ASAT에서 만난 파이프라인의 진짜 가치 (0) | 2026.04.22 |
|---|---|
| 반복 산출물 생성을 AI에 맡긴 기록 — 무엇을 넘길 수 있고 무엇은 넘길 수 없었나 (1) | 2026.04.22 |
| 쇼핑몰 검색이 자연어를 못 알아듣는 문제 — Spring AI와 pgvector로 붙여본 RAG (0) | 2026.04.22 |
| 바이브 코딩 유의점과 파인튜닝이 필요한 상황 (0) | 2026.04.22 |
| Java 17은 왜 Kotlin과 잘 맞고, Java 25에서는 무엇을 다시 점검해야 할까 (0) | 2026.04.21 |