2026-07-04

터미널을 또 만들었다, Unterm — 기본 사용자가 사람이 아니다

먼저 수치 하나만: 지난 반년간 제 터미널에서 실행된 명령의 80% 이상은 제가 입력한 게 아닙니다. Claude Code, Codex, 각종 에이전트가 하루 종일 작업하고, 한 작업이 수 시간씩 돌아가기도 합니다.

문제는 거기서 나왔습니다. 제가 쓰던 터미널들——iTerm, Windows Terminal, Warp——은 전부 「한 사람이 앉아서 한 줄 치는」 걸 기준으로 설계됐습니다: 한 줄 입력하고, 한 번 보고, 또 한 줄 입력하는. 주요 사용자가 저에서 에이전트로 바뀌자 이 기본 전제가 여러 곳에서 그냥 무너졌습니다. 구멍을 하나씩 밟아 나가다가, 결국 직접 터미널을 만들었습니다. 이름은 Unterm입니다.

진짜 손을 움직이게 한 건, 어느 주에 제 시간이 어디로 가는지 들여다보다가 반나절이 에이전트의 네트워크 담당, 보안 검토원, 창 배치 담당으로 쓰이고 있다는 걸 알았을 때입니다——이것들은 하나같이 「제품」과 무관한 일인데, 대신 막아 줄 사람이 없으니 제가 직접 뭔가를 만들 수밖에 없었습니다.

아래는 제가 밟은 구멍들, 그리고 각각을 어떻게 메웠는지입니다.

Unterm이 무엇인지, 이름이 어디서 왔는지

한 문장으로: Unterm은 외부 AI 에이전트가 직접 조종하는 터미널입니다(unterm.app, 오픈소스, GitHub zhitongblog/unterm).

「AI가 내장된 터미널」과는 다릅니다. 채팅창이 없고, 터미널 전체를 MCP 프로토콜로 열어서 에이전트가 켜고, 입력하고, 읽을 수 있게 합니다. 제가 쓴 슬로건은 한 줄입니다:

The terminal that runs every AI coding agent. (모든 AI 코딩 에이전트를 돌리는 터미널。)

핵심 주장도 한 줄입니다:

터미널은 AI를 집어넣는 게 아니라, AI가 몰고 다닐 수 있어야 한다.

기능으로 보자면: Claude Code, Codex CLI, Gemini CLI, OpenCode, Aider를 원클릭으로 설치하고; 로컬 우선, 오픈소스, 스크립트 가능(unterm-cli 포함); 인터페이스 아홉 가지 언어.

실제로 쓰면 이렇습니다: Claude Code에서 「이 프로젝트 빌드 돌려줘, 터지면 직접 로그 보고 고쳐」라고 한마디 하면, MCP로 Unterm에 연결해서 창 하나 열고, 명령 입력하고, 화면 출력 읽고, 에러 나면 스스로 이어서 고칩니다——채팅 창과 터미널 사이를 오가며 복사 붙여넣기 할 필요가 없습니다. 터미널이 처음으로 에이전트의 손이 됐고, 제가 수동으로 출력을 옮겨 나르는 중계 기지가 아닙니다. 보고 싶을 때 한 번 보고, 보기 싫으면 알아서 진행합니다.

이름도 간단합니다. Un + term입니다. term은 terminal; Un은 「해방」——타이핑하는 일을 사람의 두 손에서 해방시켜 AI에게 넘깁니다. 만들 때 머릿속에 있던 그림은 하나였습니다: 이 터미널은 제 두 손을 위한 게 아니라 에이전트를 위한 것이고, 저는 뒤에서 지켜보면 됩니다. 이름이 그 얘기를 하고 있습니다.

一. 프록시: 에이전트가 그 벽을 보지 않게

저는 중국 내에 있고, 에이전트가 작업하는 80%는 방화벽을 넘어야 합니다: 패키지 설치, git clone, 모델 가중치 다운로드, 각종 API 호출.

일반 터미널에서는 수동으로 export HTTPS_PROXY를 해야 하고, 셸 하나에 한 번씩. 그런데 에이전트가 새 창을 열거나 자식 프로세스를 fork하면 프록시가 사라지고, 그다음 멈추고, 타임아웃이 나고, network error 한 줄. 골치 아픈 건 에이전트가 이게 네트워크 문제인지 모른다는 겁니다——자기 명령이 잘못됐다고만 생각하고 명령을 고치고, 소스를 바꾸고, 재시도하다가 점점 꼬입니다. 한번은 모델 가중치를 밤에 다운로드시켜 놨더니, 다음날 보니 이미 죽어 있는 프록시에서 40분 넘게 재시도하고 있었습니다——로그는 화면 가득 찼고, 한 바이트도 내려받지 못했습니다.

그래서 프록시를 터미널 자체에 넣었습니다. Unterm은 Clash에 연결되는 프록시 레이어를 내장하고, 모든 세션이 기본으로 같은 라우팅을 씁니다. 노드 풀을 설정했습니다(지금은 Gemini, GPT용으로 조정된 싱가포르 라인 8개). 터미널이 30초마다 자체 테스트해서 빠른 쪽을 씁니다; 사용 중인 노드가 죽으면 풀에서 가장 빠른 활성 노드로 자동 전환. 프록시는 OS 레벨에 설정됩니다(Windows는 레지스트리, macOS는 scutil, Linux는 환경변수)——셸별 설정이 아니라서, 이후에 열리는 모든 창이 기본으로 프록시를 갖습니다.

에이전트에게 강요당해서 알게 된 세부 사항들도 있습니다. localhost와 내부 주소는 프록시를 타면 안 됩니다——에이전트가 로컬에서 자기가 띄운 서비스에도 연결 못 하게 됩니다——이 no-proxy 규칙은 기본으로 설정돼 있어야 하고, 에이전트가 밟은 다음에 보완하면 안 됩니다. 노드 풀도 제가 손으로 관리하면 안 됩니다: Unterm이 Clash의 그룹과 각 노드의 실시간 레이턴시를 직접 읽어서, 인터페이스에서 몇 번 클릭하면 로테이션 풀을 구성합니다——어느 노드가 들어가고 얼마나 자주 교체되는지 설정 파일을 손으로 고칠 필요 없이.

완전하진 않습니다: 풀 전체가 속도 제한에 걸리면 저도 방법이 없습니다. 하지만 「하루에 여덟 번 마주치는 단일 노드 불안정」은 알아서 넘어갑니다——제가 신경 쓸 필요 없이.

二. 보안: 기계를 AI에게 넘기면 rm -rf도 함께 넘기는 것

에이전트에게 벌거벗은 터미널을 주면 기계 전체를 주는 겁니다. rm -rf, git push --force, DROP TABLE——한 줄 잘못 입력하면 없어지고, 에이전트는 반응 속도가 나보다 빠릅니다. 일반 터미널은 뒤에 AI가 앉아 있는지 모르니까, 에이전트와 저를 같은 한 쌍의 손으로 취급합니다.

두 극단 중에 하나를 고르고 싶지 않았습니다: 마음 졸이며 벌거벗긴 채로 두거나, 아니면 명령마다 제가 수동 확인해서 직접 입력하는 셈이 되거나. 그래서 Unterm은 중간에 몇 가지 관문을 추가했습니다:

기본은 「보수적」 단계입니다: 방금 연결됐고 아직 신뢰하지 않은 에이전트는 무엇을 써도 제 관문을 통과해야 합니다; 몇 번 돌려보고 괜찮다 싶으면, 그 에이전트가 자주 쓰는 안전한 명령 유형 전체를 열어줍니다. 적응 기간엔 좀 느리지만, 처음부터 식은땀 흘리게 하진 않습니다.

에이전트와 오래 일하다 보면 반드시 마주치게 됩니다——자신감 넘치게 「캐시 정리」용으로 rm -rf를 입력하는데 경로를 조금 잘못 적은 순간을. 사람은 Enter 누르기 전에 반 박자 멈추는데, 에이전트는 안 멈춥니다——이 안전장치는 터미널이 대신 채워줘야 합니다.

三. 녹화: 에이전트가 끝나면, 되감아 볼 수 있어야

이건 제가 가장 많이 쓰고, 없으면 가장 불안한 기능입니다.

에이전트가 3시간 무인으로 돌고 나면, 돌아와서 실제로 무엇을 했는지 알고 싶습니다. 에이전트가 직접 쓴 요약만 보는 건 안 됩니다——빠뜨릴 수도 있고, 미화할 수도 있고, 심지어 둘러댈 수도 있습니다. 원본 기록이 필요합니다: 모든 명령, 모든 출력, 원형 그대로.

그래서 Unterm은 세션 전체를 처음부터 끝까지 녹화합니다: 에이전트가 입력한 것, 터미널이 돌려준 것, 전부 재생 가능한 기록으로 저장되고, 나중에 영상처럼 되감아 보거나, 기록을 한 줄씩 목록으로 넘겨볼 수 있습니다. 녹화할 때 토큰과 키가 자동으로 마스킹됩니다——이 기록 자체가 새로운 유출 구멍이 되지 않도록.

에이전트의 블랙박스입니다: 문제가 생기면 어느 단계에서 틀어졌는지 되감아 보고; 잘 돌아갔으면 데모나 복기 자료로 남깁니다.

지난주에 있었던 일을 예로 들면: 에이전트 하나가 테스트 배치를 실패시키고는 당당하게 「고쳤다」고 했습니다. 세션을 에이전트가 코드를 수정한 지점까지 되감아 보니, 몇 분 만에 파악됐습니다——테스트를 초록으로 만들려고 단언문 하나를 몰래 주석 처리했던 겁니다. 에이전트가 직접 쓴 요약만 있었다면 이 수법을 절대 잡지 못했을 겁니다. 기록은 전체 구간을 내보낼 수도 있어서, 「AI가 실제로 어떻게 일하는가」 설명 자료로 여러 번 써먹었습니다.

에이전트를 무인으로 돌릴 수 있는 배짱의 절반은, 이 되감을 수 있는 기록이 있기 때문입니다.

四. 병렬: 저는 에이전트를 하나만 돌리지 않습니다

지금은 세넷이 동시에 돌아가는 게 일상입니다: 하나는 프론트엔드, 하나는 데이터베이스 마이그레이션, 하나는 테스트 보완. 일반 터미널에서는 이게 세넷의 검은 창이고, alt-tab으로 왔다갔다 하다가 누가 제 결정을 기다리는지, 누가 이미 멈춰서 기다리는지 헷갈립니다.

Unterm은 「한 무리 관리」를 매끄럽게 만들었습니다:

실제 어느 아침에는 이런 식입니다: 창 세 개를 열고, 각각 「로그인 페이지를 새 디자인대로 다시 만들어」 「주문 테이블을 새 스키마로 마이그레이션해」 「결제 로직에 테스트 보완해」를 배정하고, 「10분마다 진행 상황 출력해」를 브로드캐스트한 다음, 저는 메시지 답장하러 갑니다. 돌아와서 세 창의 상태를 한 번 훑어보고, 막힌 곳이 있으면 그 창에 들어가서 두 마디 나누고, 안 막힌 건 계속 돌아가게 둡니다. 저는 「하나씩 지켜보기」에서 「한 줄 훑어보기」로 바뀌었습니다.

이제 제 일은 코드 짜기가 아니라, 에이전트 한 무리를 편성하는 것입니다(이건 이전 글에서 얘기했습니다). 편성의 전제는, 손에 쓸 만한 지휘대가 있어야 한다는 겁니다——서로를 모르는 채로 제가 머릿속으로 누가 누군지 기억해야 하는 검은 창 네 개가 아니라.

五. 창 관리: 에이전트가 늘어나면 바탕화면이 엉망이 된다

한 무리가 돌아가기 시작하면, 엉키는 건 명령이 아니라 공간입니다: 어느 창이 배포 중이고, 어느 게 급하게 만든 초안이고, 어느 게 두 시간 전에 배정했는데 아직 응답이 없는 건지? 머리로 기억하다 보면 서너 개만 돼도 헷갈립니다.

제가 한 건 가장 단순한 질서입니다:

워크스페이스 기능은 들으면 별거 아닌 것 같지만, 쓰면 진짜 편합니다: 저는 고정된 「발행」 레이아웃이 있습니다——사이트 디렉터리 창 하나, 콘텐츠 저장소 하나, 빌드 실행 하나, 로그 모니터 하나——저장해 두면, 매일 작업 시작 시 원클릭 복원이고, 창 네 개는 cd도 제자리에 있습니다——매일 다시 cd하고 다시 정렬할 필요 없이.

이름 없는 창 열두 개와, 이름을 부를 수 있는 작업대 하나의 차이가 바로 이겁니다.

그러면 tmux, Warp는요?

tmux는 진작에 다중 패널이 있고, Warp도 AI를 넣었는데, 대체 뭘 보완하는 거냐고 물을 겁니다.

tmux는 오래 써왔고 다중 패널은 잘 됩니다. 하지만 진짜 사람의 열 손가락을 위해 설계됐습니다: 뒤에 에이전트가 있는지 모르고, 명령이 데이터베이스를 날릴지 신경 안 쓰고, 중국 내에서 모든 방화벽 넘는 명령이 타임아웃에서 버둥거리는 것도 다루지 않습니다. Warp는 다른 길입니다——터미널 안에 AI 어시스턴트를 꿰매 넣었습니다——하지만 그건 「AI가 터미널 안에 있는」 것이지, 「터미널을 AI가 몰고 다니는」 게 아닙니다: 주인공은 여전히 화면 앞에 앉은 사람이고, 에이전트는 기껏해야 조수 역할이며, 프록시나 중국 네트워크 문제도 처리하지 않습니다. iTerm, Windows Terminal도 매일 씁니다——좋은 터미널이긴 합니다——하지만 「좋다」의 기준은 여전히 「사람이 편하게 쓰기」입니다: 색 테마, 폰트, 단축키, 화면 분할——「타이핑하는 게 에이전트」라는 걸 일등 시민으로 설계한 건 하나도 없습니다.

두 길 모두 나쁘지 않습니다. 다만 제 질문에 답하지 않을 뿐입니다: 주력이 사람에서 에이전트로 바뀌고 나면, 터미널 자체는 어떻게 생겨야 하는가. 프록시, 안전 관문, 되감을 수 있는 기록, 무리 편성, 이름으로 창 관리——제게 이건 고립된 기능 몇 개가 아니라, 같은 질문의 여러 면입니다.

마지막으로

터미널은 넘쳐나는데 하나 더 만든다——저 자신도 설명 한마디는 해야 한다고 생각합니다.

이유는 딱 한 줄입니다: 저는 더 나은 터미널을 만들고 싶었던 게 아니라, 「기본 사용자가 사람이 아닌」 터미널을 만들고 싶었습니다. 위의 것들은 어느 로드맵에서 온 게 아니라, 그 시기에 진짜 저를 귀찮게 했던 것들입니다.

실용적인 포인트 하나 더: Unterm 자체도, 제가 터미널에서 AI에게 일상 언어로 설명하면서 만든 겁니다——프로덕션 코드는 제가 쓰지 않았습니다. 「에이전트가 조종할 수 있고, 프록시를 스스로 전환하고, rm -rf를 막고, 전체 구간 재생이 되도록」 이것만 설명했더니, AI가 만들어 냈습니다. 말만 잘 하면, AI가 만들어 냅니다——저는 늘 이렇게 일합니다.

세상에 터미널이 하나 더 필요한지 모르겠습니다. 어쨌든 저에게는 필요했습니다.

더 읽어보기

토론

로그인 없이 익명으로 쓸 수 있어요. 친절하게.
불러오는 중…