(4/5) 하네스 연결 — 로컬 모델을 에이전트 CLI 에 물리기
- 왜, 그리고 무엇을 갖춰야 하나 — 3층 구조와 손익분기
- 모델 고르기 — 어떤 오픈웨이트가 코딩 에이전트급인가
- 하드웨어와 서빙 — GPU·VRAM·양자화·vLLM 로 띄우기
- 하네스 연결 — 로컬 모델을 에이전트 CLI 에 물리기 ← 지금 글
- "완벽히 동일"의 조건 — 검증·남는 갭·하이브리드 운영
Summary
3편에서 로컬 모델을 GPU 에 올리고 http://your-gpu-host:8000/v1 이라는 두뇌 주소를 얻었어요. 그런데 이 엔드포인트는 아직 “질문하면 답하는” 챗봇일 뿐이에요. 파일을 읽지도, 고치지도, 테스트를 돌리지도 못하죠.
여기에 손발을 달아 진짜 코딩 에이전트로 만드는 게 하네스예요. 이번 편에서는 오픈소스 에이전트 CLI 를 골라, 우리 로컬 엔드포인트에 연결하고, 툴과 MCP 까지 살려서 실제로 파일을 고치게 만들어봅니다.
💡 이 글에서 다루는 것
- 하네스가 하는 일 — 에이전트 루프 다시 보기
- 오픈 하네스 지형 — 어떤 CLI 들이 있나
- 두 갈래 연결: 호환 엔드포인트를 그대로 받기 vs 프록시로 변환
- base_url 설정 실전 예시
- 툴 콜과 MCP 를 그대로 살리기
- 로컬 모델 특유의 하네스 함정과 대처
1. 하네스가 하는 일 — 에이전트 루프
먼저 하네스가 정확히 뭘 하는지 다시 짚을게요. 상용이든 오픈이든 코딩 에이전트의 심장은 에이전트 루프예요.
1) 모델에게 "쓸 수 있는 도구 목록 + 현재 상황"을 준다
2) 모델이 "이 도구를 이런 인자로 불러줘" (툴 콜) 를 뱉는다
3) 하네스가 그 도구를 실제로 실행한다 (파일 읽기·수정·bash·검색)
4) 실행 결과를 다시 모델에 먹인다
5) 작업이 끝날 때까지 2~4 반복
여기서 중요한 건, 모델은 도구를 직접 실행하지 않는다는 거예요. 모델은 “이걸 해줘”라고 요청만 하고, 실제 파일 편집·명령 실행은 하네스가 합니다. 그래서 하네스를 갈아끼워도 두뇌(모델)만 같으면 방향이 유지되고, 반대로 하네스의 완성도(편집 정확도·검색·안전장치)가 사용 경험을 크게 좌우해요.
2. 오픈 하네스 지형
Claude Code·Codex 자리를 채울 오픈소스 대안은 생각보다 많아요. 성격만 크게 갈라볼게요.
| 갈래 | 성격 | 연결 방식 |
|---|---|---|
| 터미널 CLI | 셸에서 도는 에이전트 | base_url 지정 |
| 에디터 확장 | VS Code 등에 붙는 패널 | base_url 지정 |
| 페어 프로그래머 | 커밋 단위로 협업 | base_url 지정 |
- 터미널 CLI 형 — Claude Code·Codex 처럼 셸에서 도는 에이전트예요. 오픈소스 Codex CLI, OpenCode, Goose 같은 도구들이 여기 있고, 대부분 모델 공급자(base_url)를 바꿔 끼울 수 있어요.
- 에디터 확장 형 — Cline, Roo Code, Continue 처럼 VS Code 패널로 붙는 방식이에요. GUI 를 선호하는 팀에 잘 맞고, 역시 커스텀 엔드포인트를 받아요.
- 페어 프로그래머 형 — Aider 처럼 git 커밋 단위로 협업하는 CLI 예요. 변경을 자동 커밋해줘서 되돌리기 쉽고, OpenAI 호환 엔드포인트를 그대로 받습니다.
💡 정답은 없어요. 지금 쓰던 워크플로우(터미널이냐 에디터냐)에 가장 가까운 걸 고르는 게 “완벽히 동일한 방향”에 제일 가까워요. 실제로는 팀원마다 취향이 갈려서, 하나의 로컬 엔드포인트에 여러 하네스를 동시에 붙이는 구성이 흔해요.
3. 두 갈래 연결 전략
로컬 엔드포인트에 하네스를 붙이는 길은 크게 둘이에요. 내가 쓰려는 CLI 가 어떤 API 방언을 말하느냐로 갈려요.
- (A) OpenAI 호환을 그대로 받는 하네스 — 대다수가 여기예요.
base_url만 우리 vLLM 주소로 바꾸면 끝. 3편에서 vLLM 이 OpenAI 호환으로 떠줬으니 곧바로 물려요. - (B) 특정 벤더 전용 하네스 — 특정 상용 API 방언에만 맞춰진 CLI 도 있어요. 이럴 땐 중간에 프록시를 하나 세워, 그 방언을 OpenAI 형식으로 번역해 우리 vLLM 으로 넘겨요.
LiteLLM같은 프록시가 이 변환 계층 역할을 합니다.
(A) 하네스 ──OpenAI 방언──▶ vLLM (:8000/v1) # 바로 연결
(B) 하네스 ──벤더 방언──▶ 프록시 ──OpenAI 방언──▶ vLLM # 번역 한 겹
✅ 그래서 “지금 쓰던 그 CLI 를 꼭 써야 한다”는 제약이 있어도 길이 있어요. 호환되면 (A)로 바로, 아니면 (B)로 프록시 한 겹. 두 경우 다 최종 목적지는 우리 로컬 vLLM 이에요.
4. base_url 설정 실전
가장 흔한 (A) 경로부터 볼게요. 대부분의 하네스는 환경변수나 설정 파일로 엔드포인트를 받아요. 로컬 서빙이라 API 키는 실제로 검증 안 하니 아무 값이나 넣어도 돼요.
가장 단순한 환경변수 방식이에요.
# 로컬 vLLM 을 OpenAI 공급자로 지정
export OPENAI_API_BASE="http://your-gpu-host:8000/v1"
export OPENAI_API_KEY="dummy-onprem" # 로컬이라 검증 안 함, 아무 값
페어 프로그래머형(Aider)이라면 플래그로 바로 물려요.
aider --openai-api-base http://your-gpu-host:8000/v1 \
--openai-api-key dummy-onprem \
--model openai/local-coder
터미널 CLI 형은 설정 파일에 공급자를 등록하는 방식이 많아요. 예를 들면 이런 모양이에요.
# 에이전트 CLI 설정 (예시)
[model_providers.local]
name = "local vLLM"
base_url = "http://your-gpu-host:8000/v1"
wire_api = "chat"
[profiles.onprem]
model = "local-coder" # 3편의 --served-model-name
model_provider = "local"
(B) 프록시 경로면, 프록시를 먼저 띄우고 하네스가 프록시 주소를 벤더 엔드포인트로 보게 해요.
# 프록시가 벤더 방언을 받아 vLLM 으로 번역해 넘김
export <VENDOR>_BASE_URL="http://your-proxy-host:4000"
export <VENDOR>_API_KEY="dummy-onprem"
핵심은 어느 경로든 “모델 이름 = 3편에서 준 local-coder, 주소 = 우리 로컬” 로 맞추는 거예요. 이게 맞으면 하네스는 상대가 클라우드인지 사내 GPU 인지 신경 쓰지 않아요.
5. 툴 콜과 MCP 를 그대로 살리기
에이전트가 파일을 고치려면 툴 콜이 살아 있어야 해요. 다행히 vLLM 은 OpenAI 형식의 함수 호출(tool calling) 을 지원해서, 하네스가 도구 목록을 넘기면 로컬 모델이 “이 도구를 이 인자로” 를 구조화된 형식으로 뱉어줍니다.
여기서 챙길 게 하나 있어요. 모델마다 툴 콜을 표현하는 내부 형식(채팅 템플릿·파서)이 조금씩 달라서, 서빙 쪽에서 해당 모델용 툴 파서를 켜줘야 형식이 안 깨져요. vLLM 에선 이런 옵션들이에요.
vllm serve <coder-moe> \
... \
--enable-auto-tool-choice \
--tool-call-parser <모델에_맞는_파서>
그리고 MCP(Model Context Protocol) — 사내 위키·이슈 트래커·DB 조회 같은 도구를 붙여 쓰던 MCP 서버가 있다면, 그건 모델과 무관한 계층이라 그대로 재사용돼요. 하네스가 MCP 를 지원하면, 두뇌만 로컬로 갈아끼우고 MCP 도구들은 하나도 안 건드려도 됩니다.
💡 이게 “완벽히 동일한 방향”의 큰 조각이에요. 도구 생태계(파일 편집·검색·MCP)는 하네스에 속하고 모델에 안 묶여요. 그래서 모델을 로컬로 내려도 지금 쓰던 도구들이 대부분 그대로 따라옵니다. 갈아끼우는 건 오직 두뇌 하나예요.
6. 로컬 모델 특유의 함정과 대처
상용 API 는 이런 걸 알아서 처리해줬지만, 직접 서빙하면 우리가 챙겨야 하는 지점들이 있어요. 실사용에서 자주 밟는 것들만 정리할게요.
| 증상 | 원인 | 대처 |
|---|---|---|
| 툴 콜이 자꾸 깨짐 | 툴 파서 미설정 | 모델 맞는 파서 켜기 |
| 앞 내용을 잊음 | 컨텍스트 창 초과 | max-model-len·요약 |
| 답이 이상하게 잘림 | 템플릿 불일치 | 채팅 템플릿 점검 |
| 팀 붙자 느려짐 | KV 캐시 포화 | 3편 동시성 튜닝 |
- 툴 콜 깨짐 — 가장 흔해요. 5장의 툴 파서를 모델에 맞게 켜주면 대개 해결돼요. 그래도 불안정하면 그 모델은 에이전트용으로 티어가 부족한 신호(2편 기준)일 수 있어요.
- 채팅 템플릿 불일치 — 로컬 모델은 프롬프트를 감싸는 템플릿이 모델마다 달라요. 안 맞으면 답이 이상하게 잘리거나 역할이 꼬여요. 서빙 시 그 모델의 공식 채팅 템플릿을 쓰는지 확인하세요.
- 컨텍스트·동시성 — 3편에서 다룬 KV 캐시 이야기가 여기서도 그대로 나타나요. 큰 저장소를 다룰수록, 팀이 동시에 붙을수록 이 튜닝이 사용 경험을 좌우해요.
✅ 여기까지 오면 3층이 다 초록불이에요. 로컬 모델(2편) → GPU 서빙(3편) → 오픈 하네스(4편) 가 이어져, 사내 GPU 위에서 파일을 고치는 코딩 에이전트가 실제로 굴러갑니다.
두뇌·손발이 다 붙었으니, 마지막으로 남은 질문은 하나예요. “그래서 이게 정말 클라우드랑 똑같은가?” 이걸 검증하는 법과, 그래도 남는 갭을 다음 편에서 솔직하게 정리할게요.
일단 오늘은 여기까지…..
다음 글에서는 1편에서 세운 여섯 조건을 실제로 검증하는 법과, 로컬만으론 안 되는 부분을 하이브리드로 메우는 현실적인 운영을 다뤄볼게요.
← 이전 글: (3/5) 하드웨어와 서빙 — GPU·VRAM·양자화·vLLM 로 모델 띄우기 | 다음 글 →: (5/5) “완벽히 동일”의 조건 — 검증·남는 갭·하이브리드 운영