
Claude Code, Codex, Gemini CLI 같은 AI 코딩 에이전트가 늘어나면서 이런 생각을 한 번쯤 하게 되죠. "노트에 할 일만 적어두면 에이전트들이 알아서 개발하고, 테스트하고, 결과만 가져다주면 좋겠다."
저도 그런 구조를 직접 만들어봤어요. 마크다운 노트를 작업 요청서로 쓰고, 파일 감시기가 노트를 읽어 에이전트를 실행하고, 실행 결과를 다시 문서로 남기는 방식이었죠. 결론부터 말하면, 사람이 노트만 쓰면 나머지가 전부 자동으로 굴러가는 그림은 생각만큼 잘 되지 않았어요. 그래도 만드는 과정에서 정리한 설계 원칙 중에는 다른 자동화에도 그대로 쓸 수 있는 것들이 꽤 있었어요. 이번 글에서는 그 부분만 추려볼게요.
사람은 처음과 끝에만 개입해요#
전체 흐름은 세 단계로 나눴어요.
- 씨앗 심기 — 사람이 노트에 아이디어나 요구사항을 적어요. 마크다운 한 장이 곧 작업 요청이에요
- 키우기 — 에이전트가 역할별로 작업을 수행해요
- 수확하기 — 테스트를 통과한 결과물을 사람이 검토하고, 승인하면 완료 처리해요
핵심은 사람이 개입하는 지점을 시작과 끝 두 군데로 못 박는 것이에요. 중간 과정에 사람이 자꾸 끼어들면 자동화의 의미가 줄어들고, 반대로 끝에 승인 단계가 없으면 검증되지 않은 결과물이 그대로 흘러가거든요.
역할은 이렇게 나눠볼 수 있어요.
| 역할 | 하는 일 |
|---|---|
| PM | 노트를 분석해서 요구사항 문서로 구조화하고 작업을 쪼개요 |
| 개발 | 요구사항을 바탕으로 코드와 유닛 테스트를 작성해요 |
| QA | 테스트를 실행하고 결과 리포트를 남겨요 |
| 배포 | 빌드하고 스토어 제출까지 이어가요 |
QA에서 실패하면 결과를 다시 개발 단계로 돌려보내는 루프를 넣어두는 게 좋아요. 한 번에 통과하는 경우가 생각보다 드물거든요.
실행 조건은 frontmatter로 좁혀요#
파일 감시기가 노트를 보는 순간 바로 에이전트를 실행하면 곤란해요. 쓰다 만 노트, 메모용 노트까지 전부 작업으로 취급되니까요. 그래서 frontmatter 조건을 모두 만족할 때만 실행하도록 했어요.
---
type: task # 작업 문서인지
status: APPROVED # 사람이 승인했는지
dispatch: true # 지금 실행해도 되는지
---세 조건을 모두 만족해야만 에이전트에게 넘어가요. status: APPROVED는 사람의 승인 게이트 역할을 하고, dispatch: true는 "승인은 했지만 아직 돌리지 마"를 표현할 수 있게 해줘요. 승인과 실행 시점을 분리해두면 생각보다 쓸모가 많아요.
같은 문서가 두 번 실행되지 않게 해요#
파일 감시 방식은 저장할 때마다 이벤트가 발생해요. 노트를 조금만 고쳐도 같은 작업이 또 실행될 수 있죠. 그래서 실행 이력을 DB에 남기고, 이미 실행한 작업은 건너뛰는 중복 실행 방지가 꼭 필요해요.
저는 SQLite에 이 정도 테이블을 뒀어요.
- tasks — 노트에서 만들어진 작업과 현재 상태
- agent_runs — 어떤 에이전트가 언제 실행됐고 결과가 어땠는지
- events — 파일 변경, 작업 생성, 에이전트 시작/종료, QA 통과 같은 전체 활동 로그
특히 events 테이블처럼 모든 활동을 시간순으로 남겨두면, 뭔가 이상하게 돌았을 때 어디서 꼬였는지 거슬러 올라가기 쉬워요.
실패도 문서로 남겨요#
에이전트 실행이 실패하면 로그만 남기고 끝내지 않고, QA 문서를 자동으로 만들어서 docs/qa/ 같은 폴더에 남기도록 했어요. 실패가 다시 하나의 작업 문서가 되는 거예요.
같은 방식으로 Sentry 같은 에러 모니터링 서비스의 webhook을 받아서 QA 문서나 핫픽스 문서를 자동으로 만드는 분기도 넣을 수 있어요. 이렇게 하면 사람이 직접 쓴 요청이든, 실패든, 운영 중 에러든 모두 같은 형식의 문서로 들어오게 돼요. 처리하는 쪽은 입력이 어디서 왔는지 신경 쓸 필요가 없어지죠.
코어는 CLI, 화면은 읽기 전용 뷰어로 나눠요#
칸반 보드나 실행 로그를 보고 싶어서 대시보드를 붙이고 싶어지는데, 이때 구조를 이렇게 나눴어요.
- CLI가 코어 — 파일 감시, 에이전트 실행, DB 쓰기 같은 로직은 전부 CLI에 둬요
- 대시보드는 읽기 전용 — CLI가 만든 SQLite 파일을 읽어서 보여주기만 해요
- 독립 실행 — 대시보드 없이 CLI만으로 완전히 동작해요
이렇게 나누면 대시보드가 깨져도 자동화는 계속 돌아가요. 화면 쪽 코드가 핵심 로직을 건드릴 일도 없고요. 둘이 같은 DB 파일을 공유하니까 별도 API 서버를 만들 필요도 없어요.
명령어도 흐름에 맞춰 단순하게 잡았어요.
tool seed <노트경로> # 노트를 작업으로 등록
tool grow <task-id> # 에이전트 실행
tool status # 전체 작업 현황
tool harvest <task-id> # 결과 승인
tool harvest --reject <id> # 거부하면 다시 실행 단계로
tool watch <볼트경로> # 볼트를 감시해서 자동 등록완전 자동화가 잘 안 된 이유#
설계 원칙은 쓸 만했지만, 노트만 쓰면 끝나는 그림은 끝내 나오지 않았어요. 이유는 크게 세 가지였어요.
- 결과 품질 — 노트 한 장에 담긴 맥락만으로는 에이전트가 원하는 결과를 내기 어려웠어요. 결국 사람이 결과물을 계속 고쳐야 했고, "끝에서만 개입한다"는 전제가 무너졌죠
- 관리 부담 — frontmatter 상태를 바꾸고, 자동으로 생긴 QA 문서를 정리하는 일이 오히려 늘어났어요. 일을 줄이려고 만든 구조가 새로운 일을 만든 셈이에요
- 파이프라인 유지보수 — 파일 감시기, DB, 대시보드처럼 자동화 도구 자체를 관리하는 비용이 생각보다 컸어요. 정작 만들려던 제품보다 파이프라인을 손보는 시간이 길어지기도 했어요
그래서 이 원칙들은 "전부 자동화"보다는, 사람이 중간에 확인하는 걸 전제로 한 작은 자동화에 붙일 때 더 잘 맞아요.
정리하면#
마크다운 노트로 에이전트 작업을 자동화할 때 챙길 것들은 이렇게 요약할 수 있어요.
- 사람의 개입 지점을 시작과 끝 두 곳으로 고정해요
- 실행 조건은 frontmatter로 좁히고, 승인과 실행 시점을 분리해요
- 실행 이력을 남겨서 같은 작업이 두 번 돌지 않게 해요
- 실패와 운영 에러도 같은 형식의 문서로 돌려보내요
- 로직은 CLI에, 화면은 읽기 전용 뷰어로 분리해요
완전 자동 파이프라인은 기대만큼 굴러가지 않았지만, 이 원칙들은 규모가 작은 자동화에도 그대로 적용돼요. 노트 기반으로 뭔가를 자동화하고 있다면, 실행 조건과 중복 실행 방지부터 먼저 점검해보세요.
Don't ruin the present with the ruined past.
— Ellen Gilchrist


