Programming
-
목업은 약속이고, 런타임 스크린샷은 증거다AI Agent 2026. 8. 7. 21:00
“비슷해 보여요”라는 말로는 화면을 닫을 수 없었습니다.처음엔 저도 그 말을 자주 썼습니다.목업을 보고 구현했고, 코드 리뷰에서 대충 맞아 보였고, 테스트도 통과했습니다.그러면 완료라고 생각했습니다.근데 실제 화면을 옆에 놓고 보니 달랐습니다.간격이 달랐고, 폰트가 달랐고, 어떤 상태는 아예 캡처되지 않았습니다.가장 무서웠던 건 1px 차이가 아니었습니다.거짓 PASS였습니다.증거에는 층이 있었습니다디자인 작업을 하면서 뒤늦게 배운 게 있습니다.모든 증거가 같은 주장을 닫지 않습니다.목업은 “이렇게 만들자”는 약속입니다.프로토타입 캡처는 “프로토타입은 이렇게 보인다”는 증거입니다.프로덕션 라우트 스크린샷은 “실제 앱에서 이렇게 보인다”는 증거입니다.실기기 캡처는 “이 기기에서도 이렇게 보인다”는 증거입니..
-
서브에이전트에게 일을 맡길 때 꼭 적는 여섯 줄AI Agent 2026. 8. 7. 09:00
서브에이전트 아홉 개를 한꺼번에 돌리면 빨라질 줄 알았습니다.절반은 맞았습니다.실제로 빨라집니다.그런데 경계를 안 나누면 빨라진 만큼 수습도 빨라집니다.같은 파일을 서로 고치고, 한쪽은 dry-run이라고 했는데 파일이 생기고, 다른 한쪽은 “완료”라고 했는데 diff가 없습니다.처음엔 에이전트가 덜 똑똑해서 그런 줄 알았습니다.아니었습니다.제가 일을 애매하게 줬습니다.“조사해줘”는 너무 넓었습니다초기에는 이렇게 시켰습니다.이 부분 전체 조사해서 문제 있으면 고쳐줘.사람에게도 넓은 요청입니다.에이전트에게는 더 위험합니다.어디까지 읽어야 하는지, 어떤 파일을 건드려도 되는지, 커밋해도 되는지, 어떤 형식으로 돌아와야 하는지 전부 추측해야 합니다.추측이 많으면 결과가 흔들립니다.어떤 에이전트는 너무 많이 고..
-
fallback을 지우자 버그가 말하기 시작했다AI Agent 2026. 8. 6. 21:00
빈 값이 조용히 0으로 바뀌고 있었습니다.처음엔 친절한 코드라고 생각했습니다.데이터가 없으면 화면이 깨지지 않게 기본값을 넣어주는 코드.사용자는 빨간 에러 대신 숫자를 봅니다.제품은 덜 불안해 보입니다.근데 그 0이 너무 잘생겨서 문제였습니다.누가 봐도 정상 값처럼 보였습니다.에러가 안 보이면 버그도 안 보였습니다처음엔 fallback이 안전장치라고 믿었습니다.value ??0items ??[]label ??"기본"작은 UI에서는 유용합니다.로딩 중에 빈 배열을 보여주거나, 선택 값이 없을 때 placeholder를 두는 건 괜찮습니다.문제는 그 값이 “데이터 계약”을 대신할 때입니다.어떤 화면에서 숫자가 0으로 나왔습니다.사용자는 변화가 없다고 읽었습니다.개발자는 에러가 없으니 정상이라고 봤습니다.하지..
-
동시성 제한은 일을 늦게 하려는 게 아니라 시스템을 끝까지 살리려는 장치입니다AI Agent 2026. 8. 6. 17:00
작업 1개가 1초 걸린다고 해서 1,000개를 동시에 실행하면 1초에 끝날 것 같지만 실제로는 그렇지 않습니다.DB 커넥션, CPU, 파일 핸들, 외부 API 제한이 먼저 막힙니다.어느 순간부터 동시성은 속도가 아니라 혼잡을 만듭니다.제한은 병목 앞에 둡니다동시성 제한은 무작정 전체 작업 수를 줄이는 게 아닙니다.진짜로 약한 자원 앞에 둡니다.DB 쓰기가 약하면 DB 쓰기 직전에, 외부 API 제한이 문제면 호출 직전에, 이미지 변환이 CPU를 먹으면 워커 풀 앞에 둡니다.병목을 모르면 제한도 엉뚱한 곳에 걸립니다.세마포어는 가장 단순한 시작점입니다한 프로세스 안에서는 세마포어나 워커 풀로 동시에 실행되는 작업 수를 제한할 수 있습니다.여러 서버가 함께 움직이면 큐, 토큰 버킷, DB 기반 락 같은 도구..
-
API 계약은 엔드포인트 주소가 아니라 서로 기대하는 입력과 출력입니다AI Agent 2026. 8. 6. 13:00
/users/1이라는 주소가 그대로여도 응답 필드가 사라지거나 타입이 바뀌면 클라이언트는 깨질 수 있습니다.상태 코드 의미가 바뀌어도 마찬가지입니다.API 계약은 주소가 아니라 입력, 출력, 오류, 시간 제한, 정렬, 페이지네이션까지 포함합니다.클라이언트는 문서가 아니라 실제 응답에 맞춰집니다문서에는 optional이라고 적혀 있어도 클라이언트가 매번 값이 있다고 믿고 만들었으면 사실상 required가 됩니다.반대로 서버가 쓰지 말라고 한 필드를 클라이언트가 이미 쓰고 있을 수도 있습니다.계약은 문서와 코드 사이의 합의입니다.그래서 실제 사용 로그와 타입 검사가 같이 필요합니다.깨지는 변경과 안 깨지는 변경을 구분합니다응답에 새 필드를 추가하는 건 대체로 안전합니다.필드를 삭제하거나 타입을 바꾸거나 e..
-
관측 가능성은 로그를 많이 남기는 일이 아니라 질문에 답할 수 있게 만드는 일입니다AI Agent 2026. 8. 6. 09:00
언제부터 느려졌는지, 어떤 사용자에게만 생기는지, 어느 API에서 막히는지, 배포와 관련이 있는지.관측 가능성은 이 질문에 답하기 위한 준비입니다.로그를 많이 찍는다고 자동으로 답이 나오지는 않습니다.로그는 사건을, 메트릭은 추세를, 트레이스는 경로를 봅니다로그는 한 요청에서 무슨 일이 있었는지 보여줍니다.메트릭은 에러율, 지연 시간, 큐 길이처럼 시간에 따른 변화를 보여줍니다.트레이스는 하나의 요청이 여러 서비스와 DB를 지나간 경로를 보여줍니다.셋 중 하나만 있으면 질문이 반쯤만 닫힙니다.요청 ID 하나가 조사를 짧게 만듭니다모든 로그에 request_id나 trace_id가 남으면 검색이 달라집니다.사용자가 보낸 오류 시각과 ID를 기준으로 관련 로그를 모을 수 있고, 그 요청이 어느 내부 호출에서..
-
SSOT는 문서가 아니라 삭제 작업이었다AI Agent 2026. 8. 6. 09:00
같은 표가 세 군데에 있었습니다.처음엔 편했습니다.한 문서는 기획자가 보고, 한 문서는 개발자가 보고, 한 문서는 에이전트가 읽었습니다.각자 필요한 말투로 정리돼 있으니 좋아 보였습니다.문제는 셋이 동시에 조금씩 달라졌다는 점입니다.어느 문서에는 주간 요약, 다른 문서에는 주간 리포트, 또 다른 곳에는 7일 요약이라고 적혀 있었습니다.셋 다 같은 기능을 가리키는 것 같았지만, 구현하는 사람 입장에서는 같은지 다른지 알 수 없었습니다.그때 저는 SSOT를 “정본 문서를 하나 더 잘 쓰는 일”이라고 생각했습니다.틀렸습니다.SSOT는 나머지를 지우는 일이었습니다.링크가 아니라 복사가 문제였습니다처음엔 새 정본을 만들었습니다.이 문서가 최종입니다.여기만 보세요.이렇게 적었습니다.그런데 예전 문서들은 그대로 남아..
-
큐는 비동기 처리 도구이기 전에 실패를 보관하는 장소입니다AI Agent 2026. 8. 5. 21:00
무거운 작업을 큐로 보내면 API 응답은 빨라집니다.사용자는 바로 “접수됨”을 봅니다.하지만 작업이 사라진 건 아닙니다.위치만 바뀌었습니다.큐는 느린 일을 뒤로 미루는 도구이면서, 실패한 일을 잃어버리지 않게 붙잡는 장소입니다.한 번만 처리된다는 말은 대개 위험합니다많은 큐 시스템은 적어도 한 번 전달을 기본으로 생각하는 편이 안전합니다.소비자가 처리 후 ACK를 보내기 전에 죽으면 같은 메시지가 다시 올 수 있습니다.그래서 소비자 로직은 중복 처리에 강해야 합니다.멱등성 키, 처리 로그, 유니크 제약이 여기서 다시 등장합니다.재시도는 친절하지만 폭주할 수 있습니다실패한 작업을 바로 재시도하면 일시적인 장애에는 도움이 됩니다.하지만 외부 API가 죽어 있는데 모든 작업이 즉시 재시도되면 장애를 더 키웁니..