◆ ESSAY

지난 두 달 동안 내 지식 폴더에는 커밋 518개가 쌓였다. 6월에 230개, 7월에 288개니 하루 여덟 번꼴로 시스템이 바뀐 셈이다.
이 중에 내가 직접 짠 코드는 한 줄도 없다.
1) 비개발자의 개발은 역할 분담이다. 나는 요구하고 판정하고, 클로드가 만들고, 코덱스가 공격한다.
2) 코드를 못 읽으면서 결과물을 믿는 법은 하나뿐이다. 행동을 측정하는 것.
3) 시행착오의 결론은 늘 같았다. 더하기보다 빼기가 시스템을 만든다.
4) 화려한 쪽이 아니라 측정에서 이긴 쪽이 남는다. 채점표까지도 측정 대상이다.
시작은 초라해서, 클로드 코드를 열어 놓고 뭐라고 쳐야 할지 몰라 한참을 앉아 있었다. 결국 친 문장이 이거였다.
"내 지식을 정리해 주는 시스템을 만들어줘. 알아서 잘 만들어줘."
돌아온 건 알아서 잘 만든, 그런데 내가 원한 것과는 다른 물건이었다. 폴더가 생기고 스크립트가 생기고 설명 문서까지 붙어서 그럴듯했는데, 정작 내가 쓰려니까 손이 안 갔다. 내 일하는 방식이 아니었기 때문이다.
AI는 못한 게 아니라 시킨 대로 했고, 시킨 게 문제였다. 이날 배운 게 이 프로젝트 전체를 지배하게 된다. AI에게 위임할 수 없는 유일한 일은 무엇을 원하는지 아는 것이다.
그래서 며칠을 그냥 관찰만 하면서, 하루 동안 내가 AI와 무슨 대화를 하는지 어디서 막히는지 무엇을 반복해서 설명하는지 메모했다. 그 메모가 1화의 그 표가 됐고, 요구가 구체적으로 바뀌자 결과물도 달라지기 시작했다. 몇 번을 반복하고 나서야 방식이 네 단계로 굳어졌다.
첫째, 나는 한국어로 원하는 것을 말한다. 최대한 구체적으로. 여기에 품질의 절반이 걸려 있는데, "검색이 이상해"는 요구가 아니다. "담보금이라고 물었는데 준비금으로 정리해 둔 문서를 못 찾는다. 같은 뜻의 단어를 서로 알아보게 해달라"까지 내려가야 AI가 정확히 움직인다. 문제 현상, 원하는 결과, 지키면 안 되는 것(기존 기능을 깨지 말 것)까지 세 가지를 채우면 실패 확률이 눈에 띄게 준다.
둘째, 클로드가 만든다. 코드를 짜고 파일을 고치고 테스트를 돌리는 동안, 나는 그 과정을 지켜보며 중간중간 방향만 잡는다.
셋째, 코덱스가 공격한다. 클로드가 만든 결과물을 코덱스에게 넘기며 이렇게 시킨다. "이 코드를 공격해 봐. 뚫리는 지점, 잘못된 가정, 놓친 경우를 찾아." 그러면 몇 분 뒤 판정문이 돌아온다. 통과면 통과 사유가, 탈락이면 BLOCK이라는 딱지와 함께 어디가 왜 위험한지 목록이 붙는다.
여기서 걸리는 건 대체로 내가 상상도 못 한 것들이다. 기억에 남는 지적은 이런 것이었다. 저장 도중에 프로그램이 강제 종료되면 문서가 반만 쓰인 채 남는데, 그 반쪽짜리 문서를 시스템이 정상 문서로 착각하고 인덱스에 올린다는 것. 확률은 낮지만 일어나면 내 지식에 조용히 거짓말이 섞인다. 나는 이런 걸 상상할 능력이 없으니, 이런 걸 잡아 주는 게 교차검증의 값어치다.
어떤 기능 하나는 이 검증에서 여덟 번 퇴짜를 맞고 아홉 번째에 통과했다. 솔직히 여덟 번째 BLOCK이 떴을 때는 모니터에 대고 한숨을 쉬었고, 그냥 넘어갈까 하는 유혹도 있었다. 어차피 나 혼자 쓰는 건데 싶어서. 그런데 그 기능이 하필 매일 쓰는 마감 명령이었고, 지나고 보니 지금 제일 믿고 쓰는 기능이 됐다.
이 교차검증을 처음부터 신뢰해서 만든 건 아니고, 초반에는 클로드가 "됐습니다"라고 하면 된 줄 알았다. 그러다 코덱스가 그 결과물을 뒤집는 걸 처음 봤을 때 배웠다. AI의 자신감과 정확성은 별개다. 그날 이후 어느 한쪽의 "됐습니다"는 판정이 아니라 주장 취급이고, 판정은 반대편의 공격을 통과했을 때만 인정된다.
넷째, 둘의 의견이 갈리면 내가 판정한다. 기술 논쟁은 이해 못 해도 판정은 할 수 있어서, 각자의 주장을 비개발자 언어로 다시 설명하게 시킨 다음 내 사용 목적에 맞는 쪽을 고른다.
실제 판정 장면은 이런 식이다. 저장 속도를 높이는 개편을 놓고 클로드는 "지금 방식이 두 배 빠르다"고 하고, 코덱스는 "빠르지만 저장 도중에 끊기면 데이터가 반쪽만 남을 수 있다"고 맞선다. 나는 두 주장을 다 알아듣게 풀어 달라고 한 뒤 이렇게 정리했다. 저장이 몇 초 느린 건 참을 수 있는데, 지식이 반쪽 나는 건 참을 수 없다. 안전 쪽 채택. 속도냐 안전이냐로 갈리면 나는 거의 항상 안전을 고른다. 내 지식이 걸린 시스템이라서 그렇다.
그리고 원칙 하나. 위험한 버튼은 내가 직접 누른다. 배포와 삭제와 외부 공개가 그렇고, AI가 못 누르게 막은 게 아니라 애초에 그 권한을 주지 않는 설계로 갔다. 만드는 건 맡겨도, 책임지는 결정은 사람 몫으로 남겨야 시스템 전체를 믿고 굴릴 수 있다.
같은 회사 AI 둘이 아니라 클로드와 코덱스, 서로 다른 회사의 AI를 쓰는 것도 의도다. 같은 학원 출신끼리는 같은 실수를 하니, 다른 데서 배운 둘을 싸움 붙여야 서로의 빈틈이 보인다. 물론 공짜는 아니어서, 구독을 둘 유지해야 하고 한 기능을 만들 때마다 두 배로 시간이 든다. 그래도 두 달 돌려 본 결론은 이게 남는 장사라는 것이다. 잘못 만든 걸 나중에 발견하면 비용이 훨씬 크니까.
돌아보면 이 프로토콜은 개발 방법이라기보다 일 시키는 방법이다. 신입에게 일을 맡길 때 요구를 명확히 하고, 다른 사람에게 검토를 시키고, 최종 결재는 내가 하는 것과 똑같다. 개발을 배운 게 아니라, 원래 하던 일의 방식을 AI에게 적용했을 뿐이다.
여기서 누구나 하게 되는 질문이 있다. 코드를 못 읽으면 AI가 만든 게 제대로 된 건지 어떻게 아나?
두 달 동안 내가 찾은 답은 이렇다. 코드를 읽는 대신 행동을 측정한다.
개발자는 코드를 읽고 "이 로직이 맞다"를 판단하지만 나는 그걸 못하고, 대신 이렇게 물을 수는 있다. 이 기능을 넣기 전과 후에 검색 정확도가 어떻게 변했나. 저장이 실제로 검색에 걸리나. 일부러 이상한 입력을 넣으면 시스템이 버티나.
그래서 시스템에 두 가지를 먼저 깔았다. 하나는 자동 테스트라, 뭔가를 고칠 때마다 기존 기능들이 여전히 도는지 기계가 확인한다. 다른 하나는 채점표인데(뒤에서 자세히 다룬다), 검색 품질을 점수로 매겨서, 점수가 떨어지는 수정은 아무리 그럴듯해도 되돌린다.
이 둘이 비개발자의 유일한 방어선이다. 코드를 못 읽으니 코드를 믿을 수 없고, 코드를 믿을 수 없으니 결과를 믿어야 하고, 결과를 믿으려면 결과를 재야 한다. 재지 않으면 남는 건 AI의 "됐습니다"뿐인데, 그건 위에서 말했듯 판정이 아니라 주장이다.
처음 설계는 야심찼다. 명령어 같은 것 없이 자연어로 다 되게 하자, 말만 하면 알아서 저장하고 정리하는 시스템을 만들자는 것이었다.
일주일 만에 접었다. "정리해줘"라는 말이 어떤 날은 저장으로, 어떤 날은 요약으로, 어떤 날은 파일 이동으로 해석됐기 때문이다. 심지어 그냥 흘리듯 한 말에 시스템이 성실하게 반응해서 시키지도 않은 정리가 돌아가 있기도 했다. 사람끼리도 "정리해줘"의 뜻이 갈리는데 AI라고 다를 리 없다. 모호한 입력은 모호한 동작을 낳는다.
그래서 명령어를 만들기 시작했는데 이번엔 반대 문제가 터져서, 기능이 생길 때마다 명령어가 하나씩 늘었다. 저장용, 요약용, 점검용, 청소용, 색인용. 어느 순간 명령어 목록을 보다가 현실을 인정했다. 이걸 만든 나조차 다 못 외운다. 비개발자를 위한 시스템이라면서 외울 게 늘어나는 건 방향이 틀렸다는 신호였다.
결국 다섯 개로 잘라냈다. 상태 확인, 저장, 정리, 동기화, 마무리. 끝. 나머지 기능은 전부 이 다섯 개 뒤로 숨겨서, 필요할 때 시스템이 알아서 부르게 했다. 리모컨에 버튼이 수십 개 달려 있어도 실제로 쓰는 건 다섯 개인 것과 같은 이치다. 쓰지 않는 버튼은 없는 것보다 나쁘다. 뭘 눌러야 할지 고민하게 만들기 때문이다.
검색을 더 똑똑하게 만들고 싶던 차에 마침 의미 기반 검색이라는 게 있었다. 단어가 달라도 뜻이 비슷하면 찾아 주는 AI 부품인데, 이거다 싶어서 실제로 모델을 만들어 붙였다.
붙이고 나서 측정했다. 결과는 예상 밖이었다. 단순 키워드 검색보다 못했다.
한국어에서는 '준비금'과 '리저브'가 같은 말이라는 것조차 잡지 못했다. 둘의 유사도 점수가 0.003. 만점이 1이니 사실상 남남 판정이다. 영어권에서 만들어진 가볍고 빠른 의미 모델은 한국어 업무 문서 앞에서 무력했다.
인정하기까지가 오래 걸렸다. AI 검색이라는 말이 주는 기대가 있어서 측정 결과를 보고도 설정을 바꾸면 나아지지 않을까 며칠을 더 만졌지만 나아지지 않았고, 27.9MB짜리 부품은 배포도 못 해 보고 폐기됐다.
대신 훨씬 원시적인 방법을 남겼는데, 같은 뜻의 단어 쌍을 목록으로 관리하는 동의어 사전이다. 담보금과 준비금, 스테이블과 stablecoin. 쓰다가 못 찾는 단어가 나오면 그때그때 쌍을 추가하면 되니 촌스럽다. 그런데 측정에서 이겼고, 덤으로 왜 그 문서가 나왔는지 내가 설명할 수 있게 됐다. 의미 모델은 왜 그런 점수가 나왔는지 아무도 모르는데, 사전은 열어 보면 이유가 적혀 있다.
이날 원칙이 하나 생겼다. 화려한 쪽이 아니라 측정에서 이긴 쪽이 남는다. AI 붙였다고 좋아지는 게 아니라, 측정해서 좋아진 것만 좋아진 거다.
측정 이야기가 나온 김에 하나 더. 검색 품질은 채점표로 관리하는데, 모의고사 문제집이라고 보면 된다. 이 질문에는 이 문서가 나와야 정답, 하는 문항 수십 개를 만들어 두고, 시스템을 고칠 때마다 시험을 치게 해서 점수를 매긴다. 점수가 떨어지면 그 수정은 되돌린다.
어느 날 검색 개편 후에 점수가 0.941에서 0.890으로 뚝 떨어졌는데, 코드를 뒤져도 원인이 안 나왔다. 한참을 추적한 끝에 찾은 범인은 코드가 아니라 문제집이었다.
문제집 하나는 이미 은퇴한 옛 문서를 정답으로 요구하고 있었고, 다른 문제집은 같은 문서를 오답으로 요구하고 있었다. 채점표끼리 싸우고 있었던 것인데, 어느 쪽을 만족시켜도 다른 쪽에서 감점되는 구조라, 시스템은 죄가 없었다. 학생은 공부를 잘하고 있는데 답안지 두 개가 서로 다른 답을 정답이라 우기던 셈이다.
문제집을 고치고, 문제집끼리의 모순을 자동으로 잡아내는 검사까지 추가하고 나서야 점수가 회복됐다. 0.949. 이날 배운 게 크다. AI를 측정으로 다스리려면 그 측정 도구부터 의심해야 한다. 3장에서 측정이 비개발자의 방어선이라고 했는데, 그 방어선도 정기 점검이 필요하다는 걸 여기서 배웠다.
돌아보면 시스템을 키운 결정은 전부 빼기였다.
자연어 만능을 빼고 명령어 다섯 개를 남겼고, 화려한 의미 검색을 빼고 동의어 사전을 남겼고, 틀린 채점표를 빼고 모순 검사를 남겼다. 커밋 518개 중에 기능을 더한 날은 많지만, 시스템이 눈에 띄게 좋아진 날은 대부분 무언가를 버린 날이었다.
이유를 생각해 보면 당연한데, 비개발자는 복잡한 시스템을 통제할 수 없기 때문이다. 부품이 늘수록 어디서 문제가 생겼는지 알 수 없게 되고, 모르는 시스템은 믿을 수 없고, 믿을 수 없는 시스템에는 지식을 맡길 수 없다. 단순함은 취향이 아니라 생존 조건이었다.
비개발자가 두 달 동안 배운 것도 세 문장으로 줄일 수 있다.
정확히 말하기. 검증은 다른 AI에게 시키기. 결정은 내가 하기.