-
프런트엔드 AX 설계기 6편 - done은 직관으로 정하는 상태가 아니다AI 엔지니어링 2026. 7. 17. 17:51728x90반응형
에이전트에게 일곱 번째 task를 맡긴 참이었다. 구현 도중 에이전트가 두 번째 task —이미
done으로 닫아둔— 의 설계가 틀렸다는 걸 스스로 드러냈다. 나는 잠깐 멈췄다. 상태 판에는 분명done이라 적혀 있는데, 그done은 더 이상 사실이 아니었다. 팀에 AI 보조 개발을 들이면 이 장면을 반드시 만난다. 사람이 혼자 짤 때보다 에이전트는 더 자주, 더 빨리 앞선 결정을 무너뜨린다(빈도는 내 운영 관찰이지 벤치마크는 아니다 — 추정으로 읽어달라). 그런데 내가 쓰던 상태 도구에는 그 상황을 적을 칸이 없었다.이 글은 그 뒤로
done이라는 상태를 다시 설계한 작업기다. 두 군데가 나를 물었다.done에서 나오는 쪽과, 애초에done으로 들어가는 쪽. 두 번 다 내 직관이 틀렸고, 두 번 다 작은 측정이 그걸 바로잡았다. (2026년 중반 기준 워크플로이고 도구 동작은 자주 바뀌니, 규칙보다 개념을 가져가시길.)상태는 한 방향으로만 흐르지 않았다
내 spec/task 상태는 여느 이슈 트래커처럼 한 방향이었다.
specification → planned → in-progress → done, 한번done이면 끝. 이 모델은 "완료된 일은 완료된 채로 남는다"는 가정 위에 서 있다. 사람만 일할 땐 그럭저럭 버텼는데, 에이전트가 들어오자 그 가정이 자꾸 깨졌다.
그래서 방향을 하나 더 텄다.
done → in-progress → planned로 거꾸로 가는 경로를 상태 머신의 정식 시민으로 넣은 것이다. 무효화된 작업을 억지로done에 남겨두거나 전혀 새 task로 갈아 끼우는 대신, 상태 자체가 "아직 할 일이 남았다"를 정직하게 말하게 만드는 게 목표였다.되돌릴 땐 가장 앞선 규칙 하나만 적용했다
거꾸로 갈 때 spec의 상태를 어디까지 내릴지가 관건이었다. 규칙을 여러 갈래로 흩뿌리면 상태가 모호해진다. 그래서 위에서부터 가장 먼저 들어맞는 규칙 하나만 적용하도록 못 박았다.

어떤 task가
pending으로 되돌아갔는데(rework) 다른 task 중in-progress가 하나라도 있으면 spec은in-progress로 내린다.in-progress인 게 하나도 없으면planned까지 내린다. 무효화된 게 원래부터pending이던 task 뿐이라면 spec은 움직이지 않는다. 진행도가 높은 쪽부터 평가해 내려오니 결과가 늘 하나로 떨어졌고, 역전의 바닥은planned였다 —specification까지는 내려가지 않는다.처음엔 무효화된 task를 그냥
done인 채로 두고 "나중에 고치자"는 메모만 붙였다. 그게 대시보드를 거짓말쟁이로 만들었다. 다음 실행에서 에이전트는 그done을 믿고 잘못된 전제로 코드를 짰다. 그래서 규칙을 이렇게 바꿨다. 되돌아온 task는 상태를 되돌리고,rework_required로 표식 하고, 딸린 작업을depends_on으로 추적한다. 아래는 그렇게 정착한 task 문서의 머리말이다. 그대로 복사해 쓸 수 있다.# task 문서 frontmatter — 무효화되어 되돌아온 상태 --- task: 2 title: 토큰 갱신 처리 status: pending # done에서 되돌림 rework_required: true # 되돌아온 작업이라는 표식 — 항상 pending과 짝 depends_on: [1] # 이 task가 흔들리면 함께 봐야 할 하위 작업 ---# 상위 spec frontmatter — 규칙에 따라 함께 역전 --- feature: auth-refresh status: in-progress # 다른 task가 in-progress라 여기까지만 내림 ---되돌림은 한 층에서 멈추지 않았다
재미있는 일은 한 계층 위에서 벌어졌다. 여러 spec을 묶는 큰 작업 단위를 initiative라 부르자(예: 플랫폼 재작성). 모든 슬라이스가
done이 되면 initiative도done으로 닫히고 파일이 아카이브 폴더로 넘어간다. 그런데 그 안의 spec 하나가 되돌려져 "전부 완료" 선이 깨지면 어떻게 될까.
토큰 로직 한 줄을 되돌린 작은 rework가 세 계층을 거슬러 올라갔다. task가
done에서pending으로, spec이done에서in-progress로, 그리고 아카이브 됐던 initiative가 다시active로 되살아났다. 파일은 아카이브 폴더에서 원래 자리로 옮겨지고 문서 안의 상대 경로 링크까지 다시 계산됐다. 상태 머신이 한 층에서만 양방향인 게 아니라 되돌림이 위로 전파된다는 것 — 이게 이 설계에서 내가 가장 마음에 든 부분이다.한 가지 함정도 여기서 배웠다. spec과 실제 코드가 어긋났는지 검증하는 단계는 반드시
done으로 닫기 전에 돌려야 한다. 일단 아카이브로 넘어간 spec에서는 그 검증이 스스로 건너뛰기 때문에, 사후에 돌리면 아무것도 못 잡는다. 완료 정리도 자동으로 하지 않고 사용자에게 물어보게 뒀다 — 배포나 후속 작업이 남아 있으면 거절할 수 있어야 하니까.그런데 done은 애초에 누가 내주나
여기까지가
done에서 나오는 쪽 이야기다. 그러다 반대편이 눈에 들어왔다. 애초에 작업이done으로 들어가는 문은 누가 지키나. 에이전트가 짠 코드를 내가 다 읽을 수는 없으니, 나는 AI가 AI의 코드를 리뷰해 통과·실패를 가르는 게이트를 뒀다. 이른바 LLM-as-judge(모델이 심판을 보는 방식)다.
첫 실수는 코드를 짠 모델에게 그대로 채점을 시킨 것이었다. 자기 출력에는 후하다. self-preference bias라 부르는 이 편향 때문에 게이트는 늘 초록불만 켰다. 그래서 코드를 짠 쪽(writer)과 리뷰하는 쪽(evaluator)을 아예 다른 호출로 분리했다. 초기 분리 실험에선 결함을 잡아내는 recall이 대략 두 배가 됐다(초기 측정치라 방향성으로 본다). 중요한 건 점수를 손보는 게 아니라 "누가 평가하느냐"를 바꾸는 구조였다.
관점을 늘릴수록 좋다는 건 착각이었다
리뷰를 한 번에 죽 보는 대신, 서로 다른 관점(lens)으로 나눠 보고 합치기로 했다. 여기서 "관점은 많을수록 안전하다"는 직관이 자연스럽게 올라온다. 재보니 아니었다.

관점을 1개에서 2개로 늘릴 때 recall이 확 올랐고, 2개에서 무릎이 꺾여 3개부터는 거의 평평했다. 정직하게 덧붙이면, 처음 방향성 측정에선 더 큰 폭이 나왔지만 표본이 얇았다(thin-n). 조작된 정답 세트로 통제해 다시 재니 recall은 81%에서 88%로, +7pp였다(pooled 기준, 변별이 필요한 fixture에선 +10pp). 직관만 틀리는 게 아니라 통제 없는 측정도 과장한다는 걸 이때 배웠다 — 그래서 헤드라인 숫자는 통제값으로 잡는다.
비용 걱정도 빗나갔다. "관점 2개면 단가도 2배, 게이트가 4배 비싸지는 것 아니냐"라고 지레 겁먹었는데, 실측은 동률이었다. 관점 패널이 한 번의 호출 안에서 돌기 때문에 모델 호출 수 자체가 그대로였다. 비용을 "관점 수"가 아니라 "호출 수"로 세는 순간 사라지는 걱정이었고, 이것도 재보기 전엔 안 보였다.
verdict가 흔들리자 그다음이 무너졌다
마지막으로 게이트의 출력 자체를 손봤다. 관점 패널로 프레이밍을 바꾸자, 사소한 diff를 통과(PASS)가 아니라 "평가 불능(N/A)"으로 밀어내는 회귀가 생겼다. 게이트가 조용히 무력화된 것이다. 다행히 미리 만들어둔 골든 세트가 이 회귀를 잡아냈고, "발견된 문제가 없으면 PASS, N/A는 정말 평가가 불가능할 때만"으로 verdict의 의미를 못 박아 고쳤다. 정밀도를 조이는 손잡이도 발견 개수의 상한이 아니라 확신 임계(confidence-floor)여야 한다는 걸 이 과정에서 정리했다. 게이트가 내보내는 신호가 흔들리면, 그 신호를 읽는 다음 단계 — 바로
done으로 들어가는 그 문 — 가 통째로 오염되기 때문이다.정리하며
done은 종착역이 아니라 양방향 상태다. 무효화되면 task에서 spec으로, initiative까지 거꾸로 전파된다. 그리고done을 내주는 리뷰 게이트의 손잡이 — 누가 평가하는가, 관점을 몇 개 보는가, 비용을 무엇으로 세는가, verdict가 무슨 뜻인가 — 는 감이 아니라 측정으로 잡아야 한다. 두 경계 모두 순진한 직관은 틀렸고, 작은 측정 한 번이 그걸 바로잡았다.당장 할 일은 가볍다. 지금 쓰는 task 템플릿에
rework_required한 줄과 역방향 규칙 세 줄을 넣고, 리뷰 게이트가 있다면 관점을 하나 더 켜기 전에 작은 골든 세트로 recall이 정말 오르는지 딱 한 번만 재보라.결국
done도 verdict도, 사람의 의도와 에이전트 사이에 놓인 인터페이스다. 그 인터페이스를 상태로 모델링하고 정합하게 유지하는 일은 화면을 다루든 에이전트를 다루든 프런트엔드가 늘 해온 그 craft다. 표면이 하나 늘었을 뿐이다.2026.06.26 - [AI 엔지니어링] - 프런트엔드 AX 설계기 5편 - 테스트를 지워 초록불을 만드는 AI
반응형'AI 엔지니어링' 카테고리의 다른 글
프런트엔드 AX 설계기 5편 - 테스트를 지워 초록불을 만드는 AI (0) 2026.07.06 프런트엔드 AX 설계기 4편 - LLM-as-judge는 왜 "다른 에이전트"가 채점해야 하는가 (0) 2026.07.03 프런트엔드 AX 설계기 3편 — `done` 경계를 측정으로 설계한 이야기 (0) 2026.07.01 프런트엔드 AX 설계기 2편 — 에이전트를 '자율 실행'에서 '명시적 동의'로 (0) 2026.06.26 프런트엔드 AX 설계기 1편 — AI 에이전트 설정을 4개 레이어로 쪼갠 이유 (0) 2026.06.24