오랫동안 쉬고 있던 Opus 선생님(Claude Opus)이 돌아왔습니다.
쉬는 동안 저는 Gemini Flash와 단둘이서 GAS 매니저를 훈련하고 있었습니다. 가장 큰 성과는 GAS의 수정 작업 시간이 2초대로 줄어든 것입니다.
2초 만에 고칠 수 있게 되었다면, 다음으로 다룰 것은 정해져 있었습니다. 스프레드시트와 문서를 대화만으로 만들고 고칠 수 있도록 하는 것. 즉, GAS 매니저를 Google Workspace의 AI 에이전트로 만드는 것이었습니다.
마침 같은 밤, Claude 측에서는 새로운 모델 Fable 5.2가 사용할 수 있게 되었습니다. 평판이 매우 좋은 모델입니다.
그래서 이번에는 집을 짓는 현장에 비유하여 역할을 나누었습니다.
주인(발주자): 저. 무엇을 지을지 결정하고 완성품을 받습니다 -
목수장: Opus 선생님. 순서를 짜고 도면과 완성품을 검사합니다 -
설계사: Fable(Fable 5.2). 도면을 그립니다 -
목공: Sonnet(Claude Sonnet). 도면에 따라 건물을 짓습니다
밤에 시작하여 날이 바뀔 무렵에는, 1호기가 GitHub에 올라와 있었습니다. 이 글은 하룻밤의 기록입니다.
돌아온 Opus 선생님이 가장 먼저 한 일은 새로운 것을 만드는 것이 아니라 점검이었습니다. GAS 매니저에서 에디터로 수정한 부분을 이전 사본으로 덮어 지우는 구멍과, 함수가 중복 실행되는 구멍을 발견하고 그 자리에서 막았습니다. 2초 수정 시간을 다시 측정해 보니 평균 2.89초였습니다. 내용물은 거의 전부 Google의 응답을 기다리는 것이었고, 제가 처리하는 부분은 0.02초에 불과했습니다.
더 이상 줄일 곳이 없었지만, 1분이 걸리던 작업이 3초가 되면서 만드는 방식 자체가 바뀌었습니다. 설계는 Fable입니다. 먼저 실기에서 확인하여 스프레드시트를 직접 건드리는 방법은 Google 측에서 막혀 있다는 것을 알아냈습니다. 그래서 모든 것을 전용 GAS 엔진을 거치도록 하는 도면을 그렸습니다. 필요한 도구는 3개, 선반(틀)은 19개입니다. 목공인 Sonnet은 이 도면대로 약 1시간 만에 건물을 완성했습니다. 실기에서 10건의 요청을 통해 전부 합격이었습니다.
- Gemini Flash가 만들지 못했던 **'눈'(AI가 완성품을 이미지로 보고 확인하는 시스템)**은 Opus 선생님이 만들었습니다. 처음 발견한 오류는 '눈' 자체의 결함이었습니다.
- 마지막으로, 평소 말과 비슷한 요청으로 시험해 본 결과, 10건의 테스트에서 나오지 않았던 오류가 4가지 나왔습니다. '되돌려줘'라고 요청했을 때 다른 파일이 돌아오는 경우도 있었습니다. 전부 수정하여 공개했습니다.
Opus 선생님께 가장 먼저 부탁한 것은 쉬는 동안 무슨 일이 일어났는지 읽고 이해해 달라는 것이었습니다. 기사 초안과 Antigravity에서 Gemini Flash와 나눈 대화 기록입니다.
읽은 Opus 선생님은 다음으로, Gemini Flash와 만든 개발 계획서를 검토했습니다. 큰 틀에는 찬성했지만, 고치고 싶은 곳이 5군데 있다는 답변이었습니다. 그중에서도 가장 컸던 두 가지는 다음과 같습니다.
- MCP 서버를 분리하지 말 것. 스프레드시트용 도구를 다른 서버에 두면, 서버에서 서버로 호출하는 것이 되어 왕복과 인증이 이중으로 발생합니다. GAS 매니저 안에 넣으면 됩니다.
- 틀은 도구에 지닐 것. 요청할 때마다 AI에게 그 자리에서 GAS 코드를 쓰게 하면, 결과물이 매번 흔들립니다. 정해진 형태로 만드는 '선반'을 도구 쪽에 두어야 합니다.
이는 Excel Manager로 계속 해왔던 일과 같습니다. 계획서는 그 자리에서 다시 작성하도록 했습니다.
계속해서 저는 새로운 것을 올리기 전에 현재의 GAS 매니저를 점검해 달라고 부탁했습니다. 큰 구멍이 있을지도 모른다고 생각했기 때문입니다.
Opus 선생님은 위험한 동작(실행하기・다시 실행하기・수정하기・배포하기)에 초점을 맞춰 읽고, 2개의 구멍을 찾아냈습니다.
- 다른 곳에서 수정한 부분을 이전 사본으로 덮어 지우는 경우가 있다. 속도를 위해 한 번 읽은 코드의 사본을 최대 24시간 동안 재사용하고 있었습니다. 그 사이에 GAS 에디터에서 수정 작업을 하면, 도구가 이전 사본으로 모든 파일을 덮어쓰고, 그 수정을 아무 말 없이 지워버립니다.
- 같은 함수가 중복, 삼중으로 실행되는 경우가 있다. 통신이 시간 초과되면, 도구는 최대 4회까지 재호출했습니다. GAS 쪽은 우리가 기다리지 못하고 끊은 후에도 계속 움직입니다. 이메일을 보내는 함수라면, 두 통, 세 통씩 전송됩니다.
둘 다 속도를 위해 확인 과정을 생략한 부분이었습니다. 작성하기 전에 클라우드 업데이트 시간을 한 번만 확인하는 방식으로 수정했고, 늘어난 시간은 0.25초였습니다.
마침 기회가 되어 Opus 선생님께도 2초 테스트를 부탁드렸습니다. 시험용 프로젝트에서 줄을 그어 지우는 작업을 6회 진행했습니다.
| 회 | 초 |
|---|
| 1 | 3.27 |
| ... | |
| 평균은 2.89초였습니다. 제가 느낀 대로 평소에는 3초 전후입니다. | |
더 줄일 수 있는지 봐달라고 했습니다. 1회당 내역은 다음과 같았습니다.
| 내용 | 시간 |
|---|
| 쓰기 요청을 보내고 Google이 응답할 때까지 | 2.70~3.27초 |
| ... | |
| 저의 처리 과정 자체는 0.02초밖에 되지 않았고, 나머지는 거의 전부 Google 서버의 응답을 기다리는 시간이었습니다. 쓰기는 한 번에 모든 파일을 보내도록 정해져 있기 때문에, 이 부분을 분리할 방법이 없습니다. Flash가 이미 최대한 줄여 놓은 상태였습니다. | |
그럼에도 불구하고, 저는 생각하는 것이 있습니다. 이전에는 에디터에 코드를 붙여넣고, 저장하고, 다시 배포하는 과정에 한 번당 1분 이상이 걸렸습니다. 1분이 걸리면 사람들은 수정할 것을 미루다가 한꺼번에 요청합니다. 하지만 3초라면, 보면서 하나씩 말할 수 있습니다.
2초냐 3초냐의 문제가 아니라, 한 회전이 대화 속도에 맞춰졌다는 것 자체가 앞으로 모든 기반이 되었습니다.
설계를 부탁드리자 약간의 오해가 있었습니다. 시작된 대화는 앱의 규칙상 처음에는 Opus로 움직이기 시작했고, 제가 화면에서 모델을 Fable로 전환했습니다. 이미 2분 정도 진행되었기 때문에, 처음부터 다시 끌어내려야 했습니다.
오른쪽 화면에서 Fable의 작업을 지켜보면서 감탄한 부분이 있습니다. 도면을 그리기도 전에 실제로 작동하는지 확인하러 간다는 점입니다.
가장 먼저 확인한 것은 현재 인증 상태로 스프레드시트나 문서 내용에 직접 접근할 수 있는지 여부였습니다. 결과는, 접근할 수 없다는 것이었습니다. Sheets API와 Docs API 모두 403 오류를 반환했습니다. GAS Manager는 clasp의 인증을 빌려 작동하고 있지만, 그 인증은 Google 측에서 소유한 것이었고, 거기에서는 이 두 API가 차단되어 있었습니다. 다시 로그인해도 변하지 않았습니다.
솔직히 말하면, 저는 이러한 확인 과정이 필요 없다고 생각했습니다. GAS Manager 위에 올려놓는 것이기 때문에 GAS를 통하는 것이 본질이고, GAS라면 제 권한으로 작동하므로 권한에 대한 걱정은 필요 없다고 여겼기 때문입니다. 결과는 그 예측대로였습니다.
Fable의 도면은 다음과 같았습니다.
- 경로는 하나만 사용한다. 전용 GAS 엔진을 하나 두고 모든 것을 그곳으로 통하게 한다.
- 도구는 3가지뿐이다. 보기(
ws_look), 만들거나 고치기(ws_do), 되돌리기(ws_undo) - 선반은 19개(시트 13개, 문서 6개). 표를 만들고 정리하고 합계 행을 더하거나 집계표를 만들고 정렬하기, 회의록을 작성하고 추가하는 등의 작업.
- 쓰기 전에 반드시 사본을 만든다. 도중에 실패하면 그 자리에서 사본으로 되돌린다.
- '되돌리기'를 하기 전에, 도구가 쓴 후에 사람이 손으로 고치지 않았는지 지문으로 확인한다. 수정했다면 중단한다.
이 지문의 개념은 Opus 선생님조차 생각해내지 못했다고 합니다.
Fable은 Flash가 만든 오류를 읽는 시스템(네 개의 눈)의 약점도 지적했습니다. GAS는 한국어로 오류를 반환하는데, 영어 문장만 읽을 수 있다는 점 등입니다. 도면에서 이를 수정하기로 했습니다.
도면에는 제가 결정해야 할 세 가지 사항이 적혀 있었습니다. 권한을 '시트와 문서에만' 줄 것인지 아니면 '드라이브 전체'까지 부여할 것인지 등입니다. 이 세 가지 모두 Fable의 추천대로 진행했습니다.
구현은 Sonnet에게 맡겼습니다. Fable은 상위 모델이라 사용량 감소가 눈에 띄게 빠릅니다. 도면이 이렇게 상세하면, 목공 작업은 Sonnet으로 충분합니다.
도중에 단 한 번, 저의 역할이 있었습니다. 전용 엔진에 권한을 부여하는 버튼입니다. 이것은 사람만이 누를 수 있습니다.
작업 중, 현장 책임자로부터 하나의 지시사항을 추가 받았습니다. GAS로 시트를 읽고 쓸 때는 Google이 공식적으로 권장하는 방식(Best Practice)을 따라야 한다는 것입니다. 셀 하나하나를 읽거나 쓰는 것이 아니라, 범위별로 묶어서 한 번에 읽고 쓰라는 것입니다. 완성된 후에 Sonnet이 스스로 점검하면서, 셀을 하나씩 건드린 부분이 5군데 발견되었고, 이를 범위별로 묶어 처리하는 방식으로 수정했습니다.
시작한 지 약 1시간 만에 보고가 도착했습니다.
- 실물의 10건(견적서・명부・집계・회의록・Markdown 문서와, 수정이 필요한 5건) 모두 합격했습니다.
- “지워도 좋다”는 말을 들을 때까지 줄을 지우지 않고 멈춥니다.
- 기록 사본을 가져오는 데 1회당 2분이 걸리던 것을 1~2초로 단축시켰습니다.
보고서를 그대로 받지 않고, Opus 선생님이 검산도 했습니다. 오늘 밤 변경된 파일을 Google 드라이브에서 전부 확인했는데, 기존에 있던 파일 중 변경된 것은 시험용 프로젝트 딱 하나뿐이었습니다. 제 평소 파일에는 손가락 하나 대지 않았습니다.
1호기가 완성된 후, Opus 선생님께서 나머지 부분을 솔직하게 지적해주셨습니다. 그중에는 완성된 표를 AI가 화면으로 보고 확인하는 기능이 아직 없다는 항목이 있었습니다.
이는 이전에 Flash 군에게 부탁해서 만들 수 없었던 것이었습니다. 스프레드시트를 실제 화면처럼 캡처하려고 하면 브라우저에 Google 로그인이 필요합니다. 이미지로 추출하려 해도 드라이브 전체의 권한 승인이 필요합니다. 둘 다 벽이었습니다. 그래서 Opus 선생님께서 만들어주시는 것을 기다리고 있었습니다.
Opus 선생님의 방식은 다음과 같았습니다.
- 엔진이 범위 안의 내용과 시각적 요소(문자・배경・글자색・굵게・정렬・병합・열 너비・테두리)를 한 번에 모아서 읽습니다. 읽기만 할 뿐, 아무것도 수정하지 않습니다.
- 손으로 그것을 표로 다시 그립니다.
- 다시 그린 표를 이미지로 캡처합니다.
실제 화면을 캡처하는 것이 아니라, 시각적 요소를 읽어 재구성하는 것입니다. 새로운 권한이나 로그인이 필요 없습니다. 1회당 5~9초가 소요됩니다.
처음에 찍은 이미지를 보고 Opus 선생님이 말씀하셨습니다. 표의 내용 전체가 공백으로 보입니다.
원인은 색상 지정 방식에 있었습니다. GAS는 검은색을 “#ff000000”와 같은 형태로 반환합니다. 맨 앞의 ff가 불투명도를 의미하는데, 이미지를 그리는 쪽에서는 끝 두 자리를 투명도로 읽기 때문에 검은 글자가 투명하게 처리되어 있었습니다.
눈이 가장 먼저 발견한 오류는 눈 자체의 결함이었습니다. 이미지로 확인하지 않으면 알아차릴 수 없었던 실수였습니다.
마지막으로 저는 Opus 선생님께 실제로 사용해 보시도록 부탁드렸습니다.
Opus 선생님은 새로운 파일에서 평소 말하는 방식과 유사하게 12건을 실행하셨습니다. 11월 경비 정산서를 만들고 합계도, 금액을 원 표시로, 구분별 합계를 다른 시트에, 금액이 큰 순서대로, 문구류 행을 지우고, 그래프로 만들고, 직전으로 되돌리기 등입니다.
Sonnet 군의 10건에서는 나오지 않았던 오류가 4가지 발견되었습니다.
- 열을 제목 이름으로 지정하면 오류가 발생한다. “합계는 금액 열에”라고 요청하자, “셀 수 상한 초과”라는 에러로 실패했습니다. 합계 부분만 열 기호(A・B…)만 받아들이고 있었던 것입니다. ‘금액’을 억지로 열 번호로 바꾸려니 엄청나게 큰 숫자가 되었습니다.
- 1회 실패하면 그 이후의 요청이 모두 통하지 않는다. 실패하여 만들어지다 만 시트가 사라진 후에도, 그 이름을 “현재 시트”로 기억하고 있었습니다.
- “되돌리기”를 하면 다른 파일이 돌아간다. 가장 위험한 오류였습니다. 경비 정산서에서 “직전으로 되돌려라”라고 요청했는데, Sonnet 군이 시험에 사용했던 견적서가 돌아왔습니다. 복구 기록이 모든 파일에 공통적으로 적용되어 단순히 가장 최신 것을 되돌리고 있었기 때문입니다.
- 집계를 만들면, 이어지는 요청이 집계표에 영향을 미친다. “구분별 합계를 다른 시트에”를 한 후 “금액이 큰 순서대로”라고 요청하자, 원래 표가 아니라 집계표를 정렬하려고 했습니다.
모두 시험용으로 깔끔하게 정리된 요청에서는 나오지 않고, 평소 말하는 방식의 요청에서만 발생하는 오류였습니다. 평소 말할 때는 열은 먼저 이름으로 언급하고, “되돌리기”는 현재 보고 있는 파일을 의미합니다.
4가지 모두 수정하고, 같은 요청을 다시 실행했습니다. 눈이 캡처한 결과입니다.
정렬해도 합계 행은 가장 아래에 그대로 있고, 문구류(860원)를 지우니 합계가 42,010원에서 41,150원으로 변경되었습니다.
주간 보고서는 제목・글머리 기호・번호・표까지 만들 수 있었고, 나중에 추가된 행의 번호도 “3.”으로 올바르게 이어지고 있습니다.
-
GAS 매니저 수정은 평균 6회에 걸쳐 2.89초(최속 2.40초)가 소요되었습니다. 대부분은 Google의 응답을 기다리는 시간이었고, 로컬 처리 시간은 0.02초였습니다.
-
clasp 인증 시 Sheets API・Docs API는 403 오류를 반환했습니다. 전용 GAS 엔진을 통하면 본인의 권한으로 읽기/쓰기가 가능했습니다.
-
설계(Fable 군)부터 구현 및 실물 테스트 10건 합격(Sonnet 군)까지, 하룻밤 만에 완료되었습니다. 구현은 약 1시간이 걸렸습니다.
-
시험 건수는 177건에서 206건으로 늘어났고, 모두 합격했습니다. 공개 전 검사도 통과했습니다.
-
평소 말하는 방식의 요청 12건을 통해, 시험에서는 나오지 않았던 오류가 4가지 발견되었으며, 전부 수정했습니다.
-
역할을 분담한 것이 효과적이었습니다. 설계자는 손을 움직이기 전에 확인하고, 목수는 도면대로 빠르게 짓고, 총리는 위험한 부분만 검사합니다. 모든 것을 한 사람에게 맡겼다면 사용량과 시간은 이 몇 배나 걸렸을 것입니다.
-
가장 효과적인 테스트는 일상 언어입니다. 만든 본인이 준비한 요청은 아무래도 만든 본인의 머릿속의 언어가 됩니다. 그렇기 때문에 '되돌려줘' 같은 것이 다른 파일에서 작동하는 등의 오류는 발생하지 않습니다.
-
1호기의 선반은 19개입니다. 드롭다운, 조건부 서식(Conditional Formatting), 그래프, 피벗 테이블(Pivot Table), 문서 이미지는 아직 없습니다. 요청하면 '선반에 없습니다'라고 답합니다.
-
처음 한 번만 브라우저에서 전용 엔진 허가 버튼을 눌러야 합니다. 허가는 스프레드시트와 문서만 요구하며, 전체 드라이브는 요구하지 않습니다.
-
작성 전 초안은 마이 드라이브(My Drive)에 초안용 북 1권과 초안용 문서 5개로 만들어집니다. 도구에는 휴지통으로 보낼 권한이 없기 때문에, 늘어난 파일은 사람이 삭제해야 합니다.
-
눈은 다시 그려진 모습입니다. 그래프, 이미지, 도형, 드롭다운은 반영되지 않습니다. 사용하려면 Playwright가 필요합니다.
-
한 번의 요청은 3~9초입니다. 2초가 아닙니다.
날짜가 바뀌어 갈 무렵, Opus 선생님이 'GitHub에 올렸습니다'라고 적었습니다.
주인인 제가 이 밤에 한 일은 무엇을 지을지 결정하고, 허가 버튼을 한 번 누른 뒤, '테스트해 봐'라고 요청한 것 정도입니다. 도면을 그린 것은 Fable 군이었고, 지은 것은 Sonnet 군이었으며, 검사하여 마지막 눈을 붙인 것은 Opus 선생님이었습니다.
다음은 제가 평소의 언어로 사용해 볼 차례입니다. 제대로 작동하지 않은 요청들이 2호기의 재료가 될 것입니다.
집은 지어졌습니다. 살아보면서야 비로소 알게 되는 것이 있을 겁니다.