라이브를 실험장으로 쓰지 마라
품앗이가 AI와 함께 일하며 남긴 실패 기록을 다른 조직이 다시 쓸 수 있게 옮긴 글입니다. 묶음 전체는 AI가 「됐다」고 할 때에서 볼 수 있습니다.
요지
라이브는 사람들이 지금 쓰고 있는 화면과 서비스입니다. 그 자리는 처음 실행해 보는 곳이 아닙니다. 내 컴퓨터나 미리보기 주소에서 검증을 끝내고, 라이브에서는 한 번 확인만 합니다. 라이브에서 문제가 나면 그 위에 조치를 얹지 말고 먼저 되돌립니다. 이 노드는 라이브를 실험장으로 썼다가 넘어진 자리 여덟 가지를 적습니다.
1. 라이브가 첫 실행이면 매번 두 번 배포한다
우리 기록에 따르면 나흘 동안 돌린 화면 검증 102회 가운데 77회가 배포한 뒤 라이브에서 처음 돌았습니다. 그때마다 라이브에서 오류가 나고, 고치고, 다시 배포하고, 다시 확인하는 한 바퀴가 생겼습니다. 「매번 두 번 배포한다」는 불만의 원인은 배포를 맡은 쪽이 아니라 돌려 보지 않고 넘긴 코드였습니다.
「오류가 안 나는 코딩」은 조심한다고 되는 일이 아닙니다. 사람도 AI도 돌려 보지 않은 코드는 틀립니다. 바꿔야 하는 것은 의지가 아니라 넘기기 전에 브라우저를 여는 단계입니다.
그래서 순서를 이렇게 바꿨습니다. 코드를 짠 쪽이 자기 컴퓨터에서 페이지를 띄워 검증을 통과시키고, 그 명령과 통과 결과 한 줄을 인계문에 붙여 넘깁니다. 로그인이나 입력 양식이 얽혀 내 컴퓨터에서 끝까지 못 돌리는 페이지는 미리보기 주소에서 검증합니다. 우리가 쓰는 호스팅은 작업 갈래를 올리면 미리보기 주소가 자동으로 생기는데, 그 기능이 이미 켜져 있었는데도 쓰지 않고 있었습니다. 라이브 확인은 마지막에 한 번만 합니다.
라이브에서만 보이는 문제도 분명히 있습니다. 캐시가 옛 화면을 내주는 일이 그렇습니다. 그래서 라이브 확인을 없애지 않고 한 번으로 줄인 것입니다.
미리보기에도 함정이 있는데, 미리보기 화면도 대개 같은 라이브 데이터베이스를 봅니다. 미리보기에서는 화면이 뜨는지까지만 보고, 제출 버튼은 누르지 않습니다. 미리보기 주소는 검색에 잡히지 않을 뿐 링크만 알면 누구나 열 수 있으므로 실제 개인정보를 넣지 않습니다.
2. 안 되면 되돌리기가 먼저, 고칠 때는 한 번에 하나
라이브에서 원인을 하나 찾을 때마다 검증 없이 조치를 하나씩 얹다가, 원래 없던 증상 세 개를 새로 만든 기록이 있습니다. 두 번째 조치가 첫 번째 조치의 결과를 가려서 무엇이 효과가 있었는지도 알 수 없게 됐습니다.
되돌릴 지점을 댈 수 없으면 손대지 않습니다. 「되돌리기 완료」도 브라우저로 확인하기 전에는 완료가 아닙니다. 그 사례에서는 되돌린 판에 괄호 하나가 남아 화면이 여전히 죽어 있었습니다. 문제가 생겼을 때 사용자에게 시크릿 창으로 열어 보라는 식의 우회를 시키지 않습니다.
깨진 판에서 검사가 실제로 FAIL을 내는지 보는 시험도 라이브 자리에서 하지 않고, 따로 띄운 자리에서 합니다.
3. 라이브 서비스를 바꾸기 전에 품질부터
응답 속도가 다섯 배 빨라진다는 결과에 끌려, 실제로 쓰이고 있던 챗봇을 세 번 멈추고 새 방식으로 바꾼 일이 있습니다. 바꾼 뒤에야 답의 품질이 무너진 것을 알았고, 되돌리는 명령마저 제대로 전달되지 않았습니다.
실험은 따로 띄운 자리에서 품질과 속도를 둘 다 잽니다. 둘 다 통과하면 짧게 전환하고, 되돌릴 길을 먼저 확보해 둡니다. 명령을 「보냈다」와 그것이 「됐다」는 다른 말이므로 전환 뒤에 따로 확인합니다.
4. 화면 검사가 운영 데이터베이스에 실제로 쓴다
입력 양식의 제출 과정을 검사하려고 데이터베이스 연결을 가짜로 바꿔 끼웠는데, 그 바꿔치기가 오류 없이 조용히 실패해서 운영 표에 시험용 한 줄이 실제로 들어간 일이 있습니다. 마침 그 표가 비어 있던 때라 피해는 없었지만, 운이 좋았을 뿐입니다.
그 뒤로 지키는 처방은 둘인데, 먼저 프로그램 안의 연결을 바꿔 끼우지 말고 네트워크 단에서 요청을 가로챕니다. 그리고 쓰기가 일어날 수 있는 검사 앞뒤로 대상 표의 건수를 찍어 늘어난 줄이 0인지 확인합니다. 내 컴퓨터에서 띄운 페이지라도 데이터베이스 주소는 운영을 가리키고 있다는 점을 기억합니다.
5. 막은 것이 안전장치라면 고칠 것은 내 계획이다
오래 걸리는 점검 연습이 자동 복구 감시 장치에 두 번 끊기자, AI가 감시 장치에 예외 표시를 넣자고 제안한 일이 있습니다. 그런데 그 감시 장치는 실제 상황에서 해야 할 일을 정확히 한 것이었습니다.
안전장치를 무르게 하기 전에, 그 장치가 막으려던 사고가 무엇인지 소리 내어 말해 봅니다. 사람이 깜빡하고 지우지 않으면 그대로 남는 표시나 설정에 안전 기능의 예외를 걸지 않습니다.
6. 날짜와 수량의 경계값은 실제로 돌려 본다
한 협동조합의 출퇴근 기록 화면에서 한 달 조회 범위의 끝을 31일로 고정해 두었습니다. 31일이 있는 달에 만들어서 17일 동안 아무 문제가 없었는데, 다음 달 1일이 되자 직원 25명 전원이 출퇴근을 기록하지 못했습니다.
날짜와 수량을 다루는 코드는 30일 달, 2월, 연말, 0, 빈 값을 실제로 넣어 돌려 보기 전에는 완료라고 말하지 않습니다. 월말은 계산하지 말고 「다음 달 1일보다 앞」처럼 비교로 처리합니다.
7. 눈으로 보는 결과물은 그려서 본다
좌표를 손으로 잡아 그린 막대그래프가 음수 좌표 때문에 화면 밖으로 잘려 비례가 무너진 일이 있습니다. 오류도 없었고 결론도 우연히 맞아 보여서 그대로 지나갈 뻔했습니다. 그려 본 화면을 찍어 보기 전에는 완료가 아니고, 좌표가 음수로 나오면 그것 자체를 경고로 봅니다.
글자를 키운 슬라이드가 다음 쪽으로 흘러 넘쳐 20장이 23쪽이 된 일도 있습니다. 슬라이드를 PDF로 뽑으면 첫 검사는 쪽수가 장수와 같은지입니다. 영상은 길이와 형식이 아니라 장면을 몇 장 뽑아 봅니다. 우리 기록에는 엉뚱한 외국 매장과 가짜 한글이 나온 영상이 있었습니다. 결과물을 볼 때는 보고 싶은 것만 보지 말고 내용, 배치, 여백, 글자 크기, 전체 인상을 차례로 봅니다.
빌드가 통과했다고 화면이 제대로 그려진 것은 아닙니다. 화면 없이 도는 브라우저는 3D 그래픽이나 화면 높이에 맞춘 배치를 제대로 재지 못하므로, 실제 브라우저나 크기를 고정한 캡처로 봅니다. 글자가 조금씩 이어서 나오는 응답은 명령줄에서 보인다고 끝난 것이 아닙니다. 줄바꿈 형식 차이 때문에 명령줄에서는 멀쩡했지만 실제 화면에서는 「응답 없음」으로 나온 일이 있습니다. 실제로 그 응답을 읽는 화면에서 확인합니다.
8. 실패를 크게 말하게 만든다
작업을 시작할 때 자료를 최신으로 맞추는 장치가 오류를 버리고 무조건 「최신화 완료」를 찍는 바람에, 12일 동안 최신이 아닌 채로 일한 기록이 있습니다. 상태 보고는 실제 결과에 따라 달라져야 합니다. 실패하면 원인 원문과 무엇이 막고 있는지를 보여 주고, 성공도 「새 변경 3개」처럼 구체적으로 말하게 만듭니다. 드러나기까지 오래 걸리는 고장일수록 크게 말해야 합니다.
기계가 쓰는 기록 대장에 사람이 손으로 성공을 적어 넣지 않습니다. 일을 넘겨주는 통로가 5주 동안 죽어 있었는데, 사람이 옮겨 적은 성공 기록이 그것을 가렸습니다. 꼭 손으로 적어야 하면 누가 적었는지 밝힙니다. 통로는 쓸 때만이 아니라 주기적으로 살아 있는지 확인합니다.
서비스 코드를 고친 뒤 재시작을 빠뜨려, 옛 코드가 나흘 더 돌며 같은 문제를 다시 낸 일도 있습니다. 고친 코드와 지금 도는 코드가 같은지 확인합니다.
처방 정리
- 코드를 짠 쪽이 자기 컴퓨터나 미리보기에서 검증하고, 통과 결과 한 줄을 인계문에 붙인다.
- 미리보기도 라이브 데이터베이스를 볼 수 있으니 제출은 누르지 않는다.
- 라이브에서 문제가 나면 되돌리기가 먼저이고, 고칠 때는 한 번에 하나씩 확인하며 고친다.
- 쓰기가 일어날 수 있는 검사 앞뒤로 표의 건수를 찍는다.
- 날짜 코드는 30일 달, 2월, 연말을 넣어 돌려 본다.
- 상태 보고는 결과에 따라 달라지게 만든다.
도구 메모
- 로컬 검증: 작은 웹 서버로 페이지를 띄우고 헤드리스 브라우저로 열어 페이지 오류 0건을 확인한다. 입력 양식이 있으면 값 채우기와 버튼 누르기까지 시킨다.
- 쓰기 검사: 브라우저 자동화 도구의 네트워크 가로채기 기능으로 데이터베이스 요청을 막고, 검사 전후 건수를 비교한다.
- PDF: 장수와 쪽수를 비교한다.