2026년 1월 15일 목요일

Gemini CLI와 Antigravity를 격리 환경에서 실행하기

코딩 에이전트를 본격적으로 쓰겠다 결심하면서 가장 신경 쓰였던 부분이 격리였다.

에이전트가 모든 행위에 내 검수를 거치게 하면 판단 주체가 내가 되어야 하고 그만큼 내 인지 부하도 높아지고 응답이 금방금방 생성되다 보니 계속 지켜보면서 딸깍딸깍만 해줘야 하는 상황이 된다. 여러모로 별로 좋은 상황이 아니다.

에이전트가 모든 행위에 내 검수를 거치지 않게 하면, 많은 부분이 해소된다. 다만 판단기준이 되는 GEMINI.md 파일 같은 걸 잘 줘야 하고 코드랍시고 이상한 아무말이나 쏟아내지 않도록 LSP 같은 걸 붙여서 최소한 뭐가 잘못됐는지 검사하고 알아서 고칠 수 있는 반복 경로를 만들어주기라도 해야한다.

하지만 코딩 에이전트가 내 검수를 거치지 않은 상태에서 무슨 짓을 할지 사실 예측할 수 없는 일이다. 유명한 농담이었던 rm -rf / 명령을 실제로 저질러버릴 수도 있는 거니까. (물론 특정 명령만은 검수를 꼭 받도록 하는 설정도 있다)

 

그래서 격리 또한 반드시 필요하다고 느꼈다. 통상 이런 걸 모래상자(sandbox) 안에서 놀게 만든다고 표현하고, 그래서 당연히 gemini cli sandbox 키워드로 검색했고, 이미 지원되는 방법이 있어서 적용했다. 문서가 풍성하지도 않고 사실 공식 배포된 코드가 이미지 빌드 기능을 누락하고 있어서 진행이 아주 매끄럽진 않았다. 차라리 SSH로 텅빈 가상머신을 만들어서 원격 접속하면 기술적으로는 단순해질 거였지만 GPU 장치가 있는 호스트에서 가상머신을 굴리기엔 애매하고 마음에 들지도 않아서 컨테이너를 고집했다.

샌드박스 개념 자체는 이미 알고 있는 도커로 좀 매만져주면 되는 수준이었고, npm으로 설치한 gemini cli 버전에 따라 도커 이미지의 태그를 맞춰주면 그걸 가져다 샌드박스로 쓴다는 점을 인지하고 나서는 그냥 이리저리 샌드박스 안에 필요한 환경을 갖춰나가면 됐다.

Antigravity는 Gemini CLI와는 또 달랐다. 처음엔 어느 수준까지 격리를 할 수 있는지, 그런 걸 지원하긴 하는지 정보가 없어서 많은 걸 찾아봐야 했다. Gemini CLI의 샌드박스를 어느 정도 갖추고 나니 반중력에도 어떻게 격리를 해야 할지 이해할만큼의 정보가 모였다.

Dev Container는 Antigravity의 기반이 된 VS Code에서 지원하는 기능이다. 그래서 Antigravity에도 기본적으로 존재하긴 하고 쓸 수도 있는데 어딘가 하나씩 모자란 느낌이라 구글에서 이걸 빼려고 했던 건지 아니면 그냥 우연히 다른 것뿐인지 잘 모르겠다. 도커로 치자면 docker-compose.yml 비슷한 성격이라고 할 수 있을 devcontainer.json 파일을 만져주면 된다.

 

사실 샌드박스도 데브컨테이너도 스펙을 바닥부터 이해하고 0바이트부터 파일을 작성하진 않았다. 정보를 취합하는 과정에서 웹의 제미니한테 물어보기도 하고 시중에 보이는 프로젝트에 얼핏 저런 파일이 있으면 가져다가 제미니한테 먹여서 이 파일을 이런저런 조건에 맞게 바꿔달라고도 했다. 그 결과물을 빌드해서 써보고 안 되는 거 있으면 고치는 시행착오를 반복했다. 어느 정도 경험이 쌓이고 나서는 맨 처음 받았던 초안이 엉망이란 걸 알고 역시 생성형은 믿을 수 없단 걸 절감했다. 특히 Antigravity는 더 까다로워서, 창 전체가 컨테이너 안에서 열리는 개념이 되다보니 창이 다 떴는데 설정창이 안 끝나고 멈춰있는 등의 현상이 있어서 로그를 받아다 제미니한테 다시 먹여서 물어보는 과정을 몇 번 거쳐야 했다. 모든 해결책을 다 이해하고 적용한 건 아니었지만 어쨌든 결과는 점차 개선되었다.

그리고 이틀 정도 지나고 나니 드디어 꽤 안정적이라고 할만한 격리 환경이 만들어졌다. 호스트의 도커에 직접 접근할 수 있고 이런저런 개발 도구도 갖춰져 있다. 호스트에 만들어 둔 GEMINI.md 파일도 인식해서 규칙으로 삼는다. git 커밋은 되는데 아직 git push로 깃허브에 접속하는 건 열어주지 않았다.

보안과 격리 강화를 생각하면 분명 손 볼 구석이 남아있긴 하다. 하지만 이건 차차 개선할 수 있는 일이겠고.

 

이제 자동화도 격리도 해결되었다. 문제는 제미니 구독이 부여하는 사용량이 아주 넉넉하진 않더라는 것. 그냥저냥 채팅으로 몇 마디 물어보고 답을 받아서 손으로 적용하는 정도로 쓸 때는 체감하지 못 했는데 로컬 코드를 인식하게 하고 쉘 명령을 직접 실행해서 그 결과를 보고 뭐가 잘못된 건지 파악해서 스스로 고치게 하는 방식으로 일을 시켜놓으면 몇 시간 가지 않아서 할당량을 다 쓰고 다른 모델로 바꾸겠다는 안내가 뜨고, 또 얼마 안 있어 모든 모델을 다 썼으며 다음 몇 시에 초기화된다는 경고를 만나게 된다.

Gemini CLI와 Antigravity의 사용량 계산이 따로 되는 것 같고 검색에서도 대체로 그렇게 답이 나오는 걸 보면 둘을 번갈아 가며 쓸 필요가 있다. 실제로도 양쪽을 설정하면서 써보니 CLI의 부족한 화면으로 열심히 뭔가 잔뜩 작업하게 하는 건 초기에 유의미할 것 같고, Antigravity에서 편집창에 계획이 뜨고 그걸 한 줄씩 읽고 코멘트를 달아서 약간 다듬고 또 다듬어진 계획을 평가하고 그 끝에서야 실행하고 실행 결과가 어떤지도 편집창에 떠서 그걸 차분히 읽어보는 방식은 어느 정도 틀이 잡힌 다음에 미세조정을 할 때 좋다고 느꼈다.

안정된 .gemini와 .devcontainer 디렉토리는 바로 깃허브에 올려놨다. 종종 깃허브에 dotfiles라는 이름으로 각종 설정파일 모아둔 걸 보면 굳이 저렇게까지 해야하나 싶었는데 꼭 필요한 일이라는 걸 절감했다. 이 설정이 갑자기 없어지고 새로 만들어야 한다면 꽤 번거롭기도 하겠고, 이 개발환경은 개선하고 축적하면 장기적으로 도움이 되기도 할 것이다. 

 

한편으론 아쉬운 점도 있다. 전반적으로 문서가 부족하고, CLI에 샌드박스 빌드 기능이 빠진 채 배포되어서 깃허브 이슈로 올라와 있는 것도 그렇고, CLI이 샌드박스를 자체적으로 구현했다는 부분도 초기화 방식을 뜯어보면 덕지덕지 이어붙인 느낌이 있다. 찾다보니 Claude Code는 자체 샌드박스도 있지만 도커의 샌드박스 기능을 사용해서 쓰는 걸 안내하는 문서도 있었다. 제미니도 도커 샌드박스 기능이 되는지 한 번 해봐도 좋을 것 같다.

 

https://geminicli.com/docs/cli/sandbox/ 

https://code.visualstudio.com/docs/devcontainers/containers 

https://code.claude.com/docs/en/sandboxing

https://docs.docker.com/ai/sandboxes/claude-code/