1인 토이 프로젝트 개발을 오래 해왔다. 아이디어가 떠오르면 바로 만들었고, 혼자 설계하고, 혼자 구현하고, 혼자 배포했다. 문제는 “혼자”라는 단어에 있다. 혼자 만들면 제품에는 오롯이 내 관점만 들어간다. 내가 필요하다고 생각하는 기능, 내가 좋다고 생각한 방식에 갇히게 된다. 아무도 “그게 정말 필요해?”, “사용자가 잘 쓸 수 있어?”라고 지적하지 않는다.
결과적으로 나만 이해하는 제품이 탄생하고, 아무도 쓰지 않는다.
AI로 생산성이 올라간 뒤에는 이 문제가 더 커졌다. 예전에는 토이 프로젝트 하나를 망치는 데도 시간이 걸렸다. 이제는 더 빠르게 만들고, 더 빠르게 망칠 수 있다. 내 컴퓨터에는 그렇게 만들어진 프로젝트 시체 더미가 쌓여가고 있었다.
AI에게 리뷰를 받아도 문제가 완전히 해결되지는 않았다. 내가 강한 어조로 말하면 AI는 대체로 그 방향을 따라온다. 그게 좋은 방식이든 나쁜 방식이든 상관없이 말이다. AI는 내가 별도로 지시하지 않으면 내 관점과 내 생각을 더 그럴듯하게 강화해버릴 수 있다.
그래서 처음에는 이런 생각을 했다.
혼자 개발한다고 혼자 생각할 필요는 없지 않을까?
처음에는 AI에게 팀을 만들어주고 싶었다
bmad-method 라는 프로젝트를 봤다. AI에게 역할을 부여해서 팀처럼 일하게 만드는 전략이다. 팀에서 일하면 여러 사람의 관점을 들을 수 있다. 함께 고민하면 내가 생각하지 못한 부분을 발견할 수 있고, 제품도 조금 더 견고해진다.
다만 내가 토이 프로젝트에 적용하기에는 구조가 조금 무겁게 느껴졌다. 설정해야 할 것이 많고, 내가 원하는 것보다 훨씬 큰 시스템처럼 보였다.
내가 원한 것은 단순했다.
내 생각을 그대로 밀어붙이지 않기
제품, 일정, UX, 프론트엔드, 백엔드 관점에서 질문받기
빠르게 실행하되, 무작정 구현만 하지 않기
프로젝트 맥락을 다음 세션에도 유지하기
그래서 이를 아주 간소화한 형태로 Team Conor를 만들었다.
npx team-conor이 한 줄이면 Claude Code에 가상의 팀이 설정된다.
이름 | 역할 | 한마디 |
|---|---|---|
스티브 | 제품 전략 | "왜 이게 필요해?" |
엘런 | 실행 PM | "언제 끝나?" |
마르코 | UX 디자이너 | "사용자가 3초 안에 이해해?" |
유나 | 프론트엔드 아키텍트 | "리렌더링 몇 번 일어나요?" |
빅토르 | 백엔드 아키텍트 | "100만 유저면 어떻게 돼요?" |
지금 돌아보면 이건 단순한 제품 소개라기보다, 내가 AI를 쓰는 방식을 바꿔보려는 첫 번째 실험에 가까웠다. AI에게 더 많은 코드를 쓰게 하는 것보다, 내 생각을 다른 관점에서 다시 보게 만드는 장치가 필요했다.
도움이 됐던 것은 역할극이 아니라 질문의 분리였다
체크리스트로 리뷰한다
“코드가 좋습니다” 같은 단순한 칭찬은 별 도움이 되지 않는다. 각 페르소나는 자기 영역의 체크리스트로 코드를 검토하도록 했다.
유나: 이 컴포넌트 봤는데...
- [ ] useEffect 의존성 배열에 user 빠져있어요
- [ ] 이 상태는 서버 컴포넌트로 올릴 수 있어요
- [x] 타입은 잘 되어있네요중요한 건 AI가 “좋다/나쁘다”를 말하는 것이 아니라, 어떤 기준으로 보고 있는지 드러내는 것이었다. 기준이 보이면 나도 반박하거나 수정할 수 있다.
안티패턴을 잡아낸다
각 페르소나에는 자기 영역에서 자주 발생하는 실수 패턴을 넣었다. 빅토르는 “트랜잭션 없는 다중 쓰기”, “N+1 쿼리”, “에러 삼키기” 같은 백엔드 안티패턴을 감지한다. 마르코는 “로딩 상태 누락”, “색상만으로 정보 전달” 같은 UX 안티패턴을 잡아낸다.
빅토르: 이거 N+1 쿼리예요. 루프 안에서 DB 호출하고 있네요.
→ JOIN 쿼리나 DataLoader 패턴으로 대체하는 게 맞습니다.이 방식의 장점은 조언이 추상적으로 흐르지 않는다는 점이었다. “사용성을 개선하세요”가 아니라, “사용자가 어디서 막히는지”, “어떤 상태가 빠졌는지”를 묻게 만들 수 있었다.
관점끼리 충돌하게 한다
가장 재미있었던 부분은 한 역할이 다른 역할을 호출하게 만든 것이다. 마르코가 사용성 문제를 보면 유나에게 성능 관점을 묻게 하고, 스티브가 기능 범위가 커진다고 판단하면 엘런에게 스코프를 줄이게 하는 식이다.
물론 이것이 실제 팀을 대체한다는 뜻은 아니다. 실제 팀에는 책임, 갈등, 이해관계, 오래 쌓인 맥락이 있다. AI 페르소나는 그런 것을 그대로 재현하지 못한다. 다만 혼자 개발할 때 내가 놓치기 쉬운 질문을 분리해서 던지게 만드는 데는 도움이 됐다.






페르소나는 토큰 낭비일까?
스티브는 “첫 아이폰 프로덕트 비저너리”, 엘런은 “스페이스X 초기 멤버”, 마르코는 “도널드 노먼의 수제자”, 빅토르는 “Rust 초기 기여자”, 유나는 “크롬 브라우저 초기 개발팀 출신” 이라는 설정을 두고 있었다.
처음에는 이런 배경이 상황극처럼 보일 수 있다고 생각했다. 하지만 어느 정도는 행동 원칙을 고정하는 앵커로도 작동했다. 예를 들어 빅토르가 “Rust 초기 기여자”라는 설정을 가지면, 타입 시스템으로 버그를 줄이는 방향의 리뷰를 더 일관되게 하게 된다.
다만 지금은 이 방식을 조금 더 조심해서 본다. 배경 설정은 도움이 되지만, 너무 많아지면 AI가 역할극의 말투에 갇힐 수 있다. 중요한 것은 화려한 캐릭터가 아니라, 어떤 기준으로 판단하게 만들 것인가였다.
솔직한 한계
컨텍스트가 많아지면 성능이 떨어질 수 있다. 5개 페르소나의 체크리스트와 안티패턴이 전부 컨텍스트에 올라가면, AI가 여러 관점을 동시에 의식하면서 어느 쪽으로도 날카롭지 못한 “합의형 피드백”을 줄 가능성이 있다.
이 문제를 완전히 해결한 것은 아니지만, 몇 가지로 완화하려고 했다.
페르소나는 이름으로 호출해야 활성화된다. 항상 5명이 동시에 말하는 구조가 아니다.
체크리스트라는 레일이 있기 때문에 “뭉뚱그려진 조언”이 나오기 어렵다.
다른 역할을 호출하는 조건을 명시해서, 관련 없는 페르소나가 끼어드는 노이즈를 줄인다.
그래도 하나의 AI에게 하나의 역할만 맡기는 것보다 결과가 떨어지는 순간은 있을 수 있다. 이건 트레이드오프였다. 대신 혼자서는 놓치기 쉬운 질문을 여러 방향에서 받을 수 있었다.
Memory 시스템
AI는 세션이 끝나면 많은 것을 잊어버린다. 다음 세션에서 같은 설명을 반복하는 것만큼 비효율적인 것도 없다.
그래서 .conor/memory/ 디렉토리에 프로젝트 컨텍스트를 기록하게 했다.
summary.md: 핵심 컨텍스트project.md: 기술 스택, 아키텍처, 컨벤션decisions.md: 왜 이 기술을 선택했는지learnings.md: 발견한 패턴, 해결한 버그
지금 돌아보면 이 부분은 이후의 작업 방식으로 꽤 이어졌다. 처음에는 Team Conor 안에서 프로젝트 메모리를 관리하려고 했고, 나중에는 더 넓은 개인 위키와 문서 구조를 고민하게 됐다. AI가 기억해야 할 맥락은 결국 나도 읽고 관리할 수 있어야 한다는 생각으로 이어졌다.
지금은 그대로 쓰고 있지 않다
솔직히 말하면, Team Conor를 지금도 그대로 쓰고 있지는 않다. 정신 차려보니 바퀴를 또 만들고 있었고, 이후에는 Superpowers 같은 더 잘 만들어진 도구를 보기 시작했다.
하지만 이 실험이 의미 없었다고 생각하지는 않는다. 이 실험을 하면서 내가 원한 것이 무엇인지 더 분명해졌기 때문이다. 나는 AI에게 단순히 더 많은 코드를 쓰게 하고 싶었던 것이 아니었다. 혼자 개발할 때 내 확신이 너무 쉽게 굳어지는 것을 막고 싶었다.
결국 중요한 것은 가상의 팀 이름이 아니었다. 내가 만든 생각을 다른 관점에서 다시 보게 만드는 장치가 필요했다. 혼자 개발한다고 혼자 생각할 필요는 없다. AI를 잘 쓰는 일은 더 많은 코드를 더 빨리 쓰는 일이 아니라, 내 확신을 더 잘 의심하게 만드는 구조를 만드는 일일지도 모른다.
