AI 코딩 에이전트를 지휘하는 법 2: 터미널에서 통제력을 만드는 프롬프트 하네스
AI 에이전트는 잘 쓰면 진짜 신세계인데, 방심하는 순간 바로 산으로 간다(경험담이다).
이전 글에서는 “좋은 모델, 좋은 프롬프트, 충분한 컨텍스트”만으로는 AI 코딩 에이전트를 제대로 통제하기 어렵다는 이야기를 풀었다. 에이전트가 직접 파일을 읽고, 코드를 뜯어고치고, 테스트까지 돌리는 순간부터는 상태 관리, 샌드박싱, 체크포인팅 같은 시스템 레이어가 필수라는 결론이었다.
그런데 전편을 쓰고 나니 현실적인 현타가 왔다. “아니, 그건 프레임워크나 런타임 플랫폼 만드는 사람들 얘기잖아?” 정작 터미널에서 Claude Code나 Opencode 띄워놓고 삽질하는 일반 유저 입장에선 당장 뭘 어떻게 해야 하느냐가 진짜 본질적인 질문이었다. 나 역시 도구를 가져다 쓰는 개발자일 뿐이지, AI 런타임 스타트업을 차릴 생각은 추호도 없으니까.
이번 글은 그 현실적인 고민에 대한 답이다. 전편의 시스템 개념을 실전으로 끌고 내려와서, 웹 채팅창 유저와 터미널 에이전트 유저가 각각 어떻게 주도권을 쥐고 에이전트를 굴려야 하는지 정리해본다.
“하지만 난 그냥 LLM 쓰는 평범한 유저일 뿐인데”
질문은 단순했다.
“LLM 서비스를 사용하는 유저로서는 model + prompt + context 이외의 것을 고려해서 개발을 이어가기는 쉽지 않은 거 아니야?”
솔직히 이게 내 진짜 속마음이었다. 컨텍스트 프루닝, 상태 관리, 샌드박싱 같은 말은 거창하고 멋있지만, 당장 내 손에 쥐어진 건 채팅창 하나뿐 아닌가. 말은 실리콘밸리 아키텍트인데 현실은 복사-붙여넣기 노가다인 상황이다.
Gemini의 답변은 예상보다 훨씬 실용적이었다. 시스템을 직접 구축할 수 없다면, 그 엔지니어링 개념을 사용 패턴(Usage Pattern)으로 번역해서 습관화하면 된다는 거였다.
1. ‘수동 RAG’와 컨텍스트 다이어트
프로젝트 폴더 전체를 압축해서 던지거나, 관련 있어 보이는 코드를 모조리 긁어서 붙여넣는 방식은 십중팔구 망한다. 너무 뻔한 이야기 같지만, 막상 코딩하다 보면 귀찮아서 다 때려 넣는 실수를 반복한다. Gemini가 제안한 핵심은 의도적인 결핍이었다.
“지금 A 파일의 라우팅 로직을 고칠 건데, 이 로직은 B 파일의 인터페이스만 참조해. 딱 이 2개 파일 코드만 줄 테니 여기서만 생각해.”
이렇게 컨텍스트를 극단적으로 좁혀서 먹여주는 방식이다. 개발자가 직접 인간 RAG 파이프라인 노릇을 하는 셈이다. 듣고 보니 프로젝트 전체를 열어놓고 “알아서 센스 있게 짜줘”라고 했던 내 게으름이 문제였다. 모델이 멍청해서가 아니라, 소화불량에 걸릴 만큼 쓰레기 컨텍스트를 쑤셔 넣은 탓이었다.
2. 채팅방(Session) 분리 = 강제 메모리 포맷
웹 기반 LLM을 쓸 때 가장 흔히 저지르는 실수가 채팅방 하나에서 프로젝트 완성을 보려는 욕심이다. 대화가 길어질수록 모델은 과거의 버그 코드, 버린 아키텍처, 헛소리했던 기록까지 다시 곱씹기 시작한다. 전편에서 말한 Lost in the Middle의 전형적인 증상이다.
해결책은 기능 단위로 세션을 칼같이 자르는 거다. 회원가입 UI 작업이 끝났다면 그 채팅방은 미련 없이 닫아버려라. 새 창을 열고 “이미 완성된 UI 코드는 이거야. 이제 이걸 바탕으로 DB 연결 로직만 짜자”라고 새 판을 깔아주는 게 훨씬 똑똑하게 일한다. 지나간 대화 기록 아까워하다가 프로젝트 전체가 안드로메다로 간다(내 뼈아픈 경험담이다).
3. 마스터 문서로 상태 유지
세션을 자꾸 쪼개다 보면 큰 그림을 놓치기 십상이다. 그래서 룰북.txt, 아키텍처_설계.md, PLAN.md 같은 마스터 문서를 하나 파두고, 기술 스택, 네이밍 컨벤션, 절대 하면 안 되는 짓, 현재 진행 상황을 딱딱 정리해두는 게 좋다. 새 채팅을 켤 때마다 이 마스터 문서부터 툭 던져주면 된다. 전편에서 강조한 State as a File을 유저 레벨에서 수동으로 구현하는 방법이다.
4. 프롬프트로 작업 강제 분할 (마이크로 청킹)
“장바구니 기능 만들어줘”라고 통째로 던지는 건 “제발 버그 좀 내줘”라고 비는 것과 같다. 작업 단위를 쪼개서 통제해야 한다.
“장바구니 기능을 만들 건데, 절대 한 번에 전체 코드 짜지 마. 먼저 데이터 인터페이스만 짜서 나한테 보여줘. 내가 ‘OK’ 사인을 주면 그때 다음 로직으로 넘어가.”
핵심은 프롬프트 자체에 브레이크(Check-point)를 거는 거다. 한 방에 완성본을 받으려는 조급함을 버리고, 단계별 승인을 전제로 프롬프트를 설계하면 에이전트의 탈선을 기가 막히게 막을 수 있다. 조금 귀찮아 보여도, 코드 꼬여서 밤새 롤백하는 것보단 백만 배 낫다.
“하지만 난 터미널에서 Claude Code를 굴리고 있는데?”
대화의 판도가 확 바뀐 건 여기서부터다. 지금까지는 웹 채팅창 유저 기준이었지만, 나는 실제로 Claude Code와 Opencode 같은 터미널 기반 에이전트를 메인으로 돌리고 있었다. 이건 복붙의 영역이 아니다.
이 이야기를 꺼내자 Gemini의 조언도 완전히 레벨업했다. 터미널 에이전트는 파일 시스템과 쉘에 직접 접근할 수 있기 때문에, 웹 유저와는 비교도 안 될 만큼 막강한 통제권을 쥘 수 있다. 전편의 엔지니어링 개념을 실제 쉘 명령어와 파일, 자동화 검증 루프로 직결할 수 있다는 뜻이다. 물론 그만큼 사고 쳤을 때의 파괴력도 상상을 초월한다(프로덕션 DB를 날려 먹을 수도 있다).
정리해보면 터미널 환경에선 다음 4가지가 생명줄이다.
1. .claudesignore로 눈 가리기
터미널 에이전트는 권한만 주어지면 신나서 프로젝트 전체를 이 잡듯이 뒤진다. 빌드 아티팩트, 로그 파일, 수 메가바이트짜리 JSON 더미까지 닥치는 대로 긁어모은다. 토큰은 토큰대로 살살 녹고, 모델 머릿속은 잡탕죽이 된다.
.gitignore처럼 에이전트의 시야를 가리는 설정 파일(.claudesignore 등)을 아주 빡빡하게 걸어둬야 한다. 더 무식하지만 확실한 꿀팁도 있다. 프로젝트 루트가 아니라, 오늘 손댈 모듈의 하위 디렉터리로 직접 cd로 이동해서 에이전트를 실행하는 거다. 물리적인 작업 반경 자체를 가둬버리면 헛짓거리할 확률이 확 줄어든다.
2. 터미널 명령어와 결합한 자동 검증 루프
터미널 에이전트의 진짜 무기는 스스로 명령어를 때릴 수 있다는 점이다. 이걸 활용하면 테스트와 피드백 루프를 프롬프트 안에 박아 넣을 수 있다.
// ❌ 단순 지시
"회원가입 정규식 로직 수정해줘"
// ✅ 오케스트레이션 지시
"1. auth.ts 파일의 이메일 정규식 로직을 수정해.
2. 수정 끝나면 터미널에서 npm run test:auth를 실행해.
3. 테스트가 터지면 에러 로그 읽고 통과할 때까지 스스로 코드를 고쳐."
이렇게 던지면 에이전트는 코드 수정 → 테스트 실행 → 에러 분석 → 재수정이라는 자기 수정(Self-Correction) 루프를 자율적으로 돈다. 전편에서 말한 ‘자동화된 피드백 루프’가 터미널에서 현실이 되는 순간이다. 보고 있으면 흐뭇함이 차오른다.
3. CLI에 특화된 PLAN.md 트리거링
웹에서는 마스터 문서를 일일이 복사해서 붙여넣어야 했지만, 터미널에서는 파일 읽기 자체를 프롬프트 첫 줄에 박아버리면 그만이다.
"먼저 cat PLAN.md를 때려서 현재 진행 상황부터 확인해.
그리고 아직 체크 안 된 가장 첫 번째 작업만 수행해."
이렇게 시작하면 에이전트가 작업 전에 스스로 프로젝트 컨텍스트를 동기화한다. 세션이 끊겼다 다시 붙어도 흔들리지 않고, 사람도 똑같은 잔소리를 반복할 필요가 없다. State as a File의 완벽한 실전 구현이다.
4. Git Alias로 강박적 안전망 깔기
터미널 에이전트가 환각에 빠져 엄한 파일을 난도질하는 건 진짜 공포다. 실제 내 로컬 디스크의 파일들이 실시간으로 갈려 나가기 때문이다. 그래서 쉘 설정(.zshrc)에 아래 같은 alias를 걸어두는 건 선택이 아니라 필수다.
alias wip="git add . && git commit -m 'wip: before agent run'"
에이전트한테 마이크를 넘기기 전에 무조건 wip 한 방 찍고 시작하는 거다. 첫 번째 글에서 다룬 “Git 기반 체크포인팅”의 생활화다. 이걸 안 해뒀다가 피눈물 흘리며 커밋 로그 뒤진 적이 한두 번이 아니라, 이제는 거의 종교적 의식처럼 손가락이 먼저 반응한다(내 멘탈은 소중하니까).
“그럼 프롬프트는 어떻게 짜야 해?”
여기서부터가 가장 실용적인 파트였다. 상태 관리도 알겠고 터미널 팁도 알겠는데, 결국 매 순간 에이전트에게 날리는 프롬프트 뼈대를 어떻게 짜야 하는가가 남는다. 요즘 유행하는 하네스(Harness) 방식이 진짜 효과가 있는지도 궁금했다.
Gemini의 명쾌한 한 줄 요약:
챗봇에게는 ‘페르소나’가 중요하지만, 터미널 에이전트에게는 ‘운영 통제권(Operational Guardrails)’이 전부다.
“너는 구글 10년 차 시니어 개발자야” 같은 오글거리는 페르소나는 웹 챗봇에서나 써먹는 거다. 쉘 권한을 쥐고 있는 터미널 에이전트에겐 구체적인 행동 규칙과 제약조건이 훨씬 중요하다. 정리하면 3가지 전략이다.
1. 허세 가득한 페르소나 대신 행동 규칙 못 박기
❌ "너는 React 시니어 프론트엔드 개발자야.
깔끔하고 유지보수하기 좋은 코드를 작성해 줘."
✅ "너는 TDD를 엄격하게 준수하는 개발자야.
[규칙 1] 코드 건드리기 전에 무조건 기존 테스트가 돌아가는지 npm test로 먼저 확인해.
[규칙 2] 새 함수를 만들 때는 비즈니스 로직 파일이 아니라
.test.ts 파일에 실패하는 테스트부터 먼저 짜."
역할을 행동 규칙으로 번역하는 게 핵심이다. “시니어처럼 짜줘”라고 하면 에이전트가 신나서 프로젝트 전체를 지 맘대로 리팩토링하는 대참사가 일어난다(시니어라는 단어는 위험하다).
2. 체인 하네스 구조화
프롬프트를 [상황] -> [목표] -> [제약조건] -> [행동지침] 순서로 와꾸를 짜는 방식이다.
[Context]
우리는 현재 src/auth 폴더의 로그인 로직을 개선 중이야.
PLAN.md에 정의된 2단계 작업을 할 차례야.
[Objective]
login.ts 파일의 비밀번호 암호화 방식을
기존 SHA-256에서 bcrypt로 마이그레이션해.
[Constraints]
1. src/auth 외부의 폴더나 파일은 절대 손대지 마.
2. 패키지 설치가 필요하면 npm 대신 반드시 yarn을 써.
3. 한 번에 전체 코드를 다 작성하지 마.
[Action Plan]
1. 먼저 변경할 설계 방향을 3줄 이내로 요약해서 내 승인부터 받아.
2. 내가 승인하면 그때 코드를 수정해.
3. 수정 끝나면 yarn lint 돌려서 포맷팅 에러 없는지 스스로 검증해.
Constraints(제약조건)가 핵심이다. 에이전트의 활동 범위를 울타리 쳐두는 게 막연한 역할 부여보다 결과물 퀄리티를 수십 배 끌어올린다. 자유를 주면 코드가 창의적이 되는 게 아니라 대형 사고가 터진다.
3. 무한 루프 차단용 브레이크 프롬프트
터미널 에이전트 써본 사람치고 “에러 발생 -> 헛소리 수정 -> 더 큰 에러 -> 멘붕” 루프 안 겪어본 사람 없을 거다. 이걸 막으려면 프롬프트 꼬리에 브레이크를 걸어야 한다.
“만약 터미널 명령어를 돌렸는데 에러가 터지면, 그 즉시 모든 동작을 멈춰. 에러 로그 분석해서 원인을 딱 1문장으로 요약하고, 네가 생각한 해결책 2가지를 나한테 보고한 뒤 기다려. 내 허락 없이 절대 혼자서 코드 다시 고치지 마.”
이 한 문장만 달아줘도 에이전트의 급발진을 90% 이상 예방할 수 있다. 에이전트에게 필요한 건 ‘폭주할 자유’가 아니라 ‘멈춰 서서 보고할 의무’다. 사람도 그렇고 AI도 그렇다. 멈출 줄 아는 게 진짜 실력이다.
대화 2를 마치며
전편이 “상태 관리가 왜 필요한가”에 대한 이론이었다면, 이번 글은 그 상태 관리를 내 손가락의 실전 습관으로 어떻게 녹여낼 것인가를 다뤘다.
- 웹 채팅 유저 -> 수동 RAG, 세션 쪼개기, 마스터 문서 투척으로 시스템 통제를 흉내 낸다.
- 터미널 유저 ->
.claudesignore,PLAN.md파이프라인, Git alias로 훨씬 강력한 통제권을 쥔다. - 프롬프트 하네스 -> 어쭙잖은 페르소나 버리고 [상황-목표-제약-지침] 구조와 브레이크 프롬프트로 가드레일을 친다.
결국 핵심은 “어떻게 하면 좋은 질문을 던질까”가 아니다. “어떻게 하면 에이전트가 딴짓 못 하게 작업 환경을 가둬둘까”다. 전편에서 이야기한 오케스트레이터의 역할이 바로 이것이다.
다음 고민도 자연스럽게 이어진다. 이런 하네스 프롬프트와 룰 설정을 매번 귀찮게 손으로 치지 않고, 도구와 스크립트로 자동화할 수는 없을까? 에이전트가 늘 정해진 가드레일 안에서만 얌전히 일하게 만드는 시스템 구축.
이 부분은 다음 글에서 더 딥하게 파고들어 볼 생각이다. 점점 판이 커지는 것 같지만, 원래 이런 엔지니어링 삽질이 제일 재밌는 법이다(아님 말고).