동시 실행 큐
며칠 전에 QA Agent를 멀티 에이전트 구조로 바꾸면서 병렬 실행을 도입했다.
오늘은 그 병렬 실행을 제어하는 인프라를 만든 날이었다.
동시 실행 큐랑 hard stop을 구현하고 서버를 ARM64로 옮기면서 버그도 잡았다.
병렬로 에이전트를 돌리려면 누가 언제 실행될지 조율하는 큐가 필요하다.
그냥 동시에 다
띄우면 리소스가 부족해지고, 순서를 잘못 잡으면 의존성이 꼬인다.
그래서 동시 실행 큐 시스템을 만들었다.
큐가 케이스를 받아서 병렬로 실행 가능한 만큼만 꺼내서 돌린다.
한 Executor가 끝나면 다음 케이스를 꺼내서 할당한다.
동시에 너무 많이 돌지 않게 제어하는 게 핵심이다.
이 큐는 DAG 스케줄러랑 맞물려서 돌아간다.
Planner가 의존성 그래프를 짜면, 큐가 의존성을 만족하면서 최대한 병렬로 돌릴 수 있는 케이스를 찾아서 실행한다.
hard stop
큐와 함께 실행을 강제로 멈추는 기능도 만들었다.
hard stop이다.
병렬로 여러 에이전트를 돌리다
보면, 문제가 생겼을 때 전체를 멈춰야 할 때가 있다.
한 Executor가 무한 루프에 빠졌거나, 브라우저가 응답하지 않거나, 전체 실행을 포기해야 하는 상황이다.
이때 실행을 강제로 중단할 수 있어야 한다.
근데 그냥 멈추기만 하면 안 된다.
중간 결과를 잃어버리면 안 되니까, 멈출 때까지 실행된 결과는 보존해야 한다.
hard stop은 실행을 멈추되 상태를 보존하는 방식으로 설계했다.
이 hard stop은 Inspector 설계랑 이어진다. Inspector가 막힌 케이스를 분석할 때, 실행을 멈추되 중간 상태를 보존해야 분석이 가능하다.
멈추고 처음부터 다시 시작하면 왜 막혔는지 단서가 날아간다.
hard stop도 같은 원리로 설계했다.
Graviton 마이그레이션
알파 서버를 ARM64 Graviton 인스턴스로 옮겼다.
비용 절감이 목적이었다.
서버는 세 단계를 거쳤다.
처음엔 t3.medium으로 시작했다가 리소스가 부족해서 t3.xlarge로 올렸다.
그리고 최종적으로 Graviton 기반인 t4g.xlarge로 옮겼다.
ARM 프로세서가 동급 x86 대비 가성비가 좋아서 장기 운영 비용을 낮출 수 있었다.
근데 ARM으로 옮기니까 호환성 문제가 터졌다.
Chromium이랑 여러 의존성 바이너리가 ARM을 바로 지원하지 않았다.
그래서 마이그레이션하면서 버그를 꽤 많이 잡아야 했다.
배포는 SSH가 아니라 AWS SSM Run Command로 돌린다.
VPN 내부망을 통해서 접근한다.
도커 컨테이너로 운영하고 도커 컴포즈로 빌드하면서 배포한다.
ARM 이미지를 빌드해야 하니까 빌드 과정도 손을 봐야 했다.
이 마이그레이션에서 드러난 버그 중 일부는 다음 날로 이어졌다. 특히 Chromium 좀비 프로세스 문제가 있었는데, 프로세스 종료 신호 처리를 개선해서 근본적으로 잡는 작업이 다음 날 이어졌다.
마이그레이션하면서 드러난 문제를 그날 다
잡지 못하고 며칠에 걸쳐 정리한 셈이다.
qa-sheet-writer 프롬프트 개선
실행 인프라 외에 시트 작성 에이전트 프롬프트도 다듬었다.
이틀 전에 시작한 작업의 연장이다.
자동 테스트가 불가능한 케이스를 식별하는 기준을 더 명확히 했다.
그리고 memo 필드에 뭘 남길지 지침을 정했는데, 이번에는 방향을 잡았다.
memo는 엔지니어뿐 아니라 기획자도 읽는 문서다.
그러니까 기술 디테일에 치우치지 않고 의사결정에 쓸 수 있는 요약이 들어가야 한다.
기획자 중심으로 memo를 쓰는 지침을 세운 거다.
이 케이스가 왜 자동화 대상이 아닌지, 사람이 확인하려면 뭘 봐야 하는지를 기획자가 읽고 바로 이해할 수 있게 적는다.
마무리
병렬 실행을 도입하고 나니까, 그 병렬 실행을 제어하는 인프라가 필수였다.
큐 없이 그냥 동시에 돌리면 리소스가 터지고, 멈춤 장치 없이 돌리면 문제가 생겼을 때 대응이 안 된다.
오늘 그 두 가지를 만들었다.
그리고 더 싼 인프라로 옮기면서 비용을 줄였다.
ARM 마이그레이션은 호환성 버그를 동반했지만 장기적으로는 비용 절감 효과가 크다.
마이그레이션 과정에서 드러난 버그는 며칠에 걸쳐 정리했다.
이날 작업은 QA Agent 알파 안정화 스프린트의 중간점이었다.
병렬 실행 큐를 만들고 더 싼 인프라로 옮기고 산출물 품질을 다듬는 세 가지가 하나의 흐름으로 이어졌다.