CDSA | 홈페이지 블로그
Editorial · AI 도구론

하네스라는 단어,
한 걸음 더 들어가 보기

용어를 아는 것은 좋은 출발점이다. 다만 그 자리에서 한 걸음만 더 들어가면, 훨씬 또렷하게 보이는 풍경이 있다.

신성진  ·  한국데이터사이언티스트협회 2026. 3. 25

최근 AI 실무 커뮤니티에서 "하네스(harness)"라는 단어가 부쩍 자주 들린다. 에이전트 아키텍처를 말할 때, 프롬프트 엔지니어링의 한계를 지적할 때, 그리고 자연스럽게 — 모델의 바깥 껍데기를 이야기할 때. 새 용어가 생기고 유통되는 것 자체는 반가운 일이다. 현업에서 어떤 현상이 충분히 자주 반복되면 그것에 이름을 붙이는 것이 생산적인 대화를 가능하게 한다.

다만 이름을 얻은 뒤에는 한 걸음 더 들어갈 차례가 온다. 용어만 주고받는 대화는 어느 지점에서부터 실체로부터 멀어지기 때문이다. 나 역시 이 단어를 한참 흘려 듣다가, 어느 날 문득 질문이 막혔다. "그래서 하네스라는 게 내 컴퓨터 어디에 있는 건데?" 개념으로는 얼핏 알 것 같은데, 손으로 가리킬 수가 없었다.

이 글은 그 질문에 답해 보려는 기록이다. 비슷한 지점에서 막혀 있을지 모르는 분들을 염두에 두고, 가능한 한 구체적인 파일과 폴더 단위까지 내려가 정리해 보려 한다. 개념과 실체 사이의 거리를 좁히는 일은 생각보다 짧은 산책이다.

01  /  정의하네스는 "모델을 실제로 돌리는 바깥 껍데기"다

대형 언어 모델 자체는 함수 하나에 가깝다. 텍스트가 들어오면 텍스트를 뱉는다. 그 이상도 이하도 아니다. 파일을 읽지 못하고, 이전 대화를 기억하지 못하고, 웹을 검색하지도 못한다. 우리가 Claude Code나 Cursor에서 목격하는 "지능적인 행동"은 모델 자체의 속성이 아니라, 그 모델을 감싸고 있는 외부 프로그램이 매 턴마다 열심히 부리는 일이다.

그 외부 프로그램이 하네스다. 조금 더 풀어 쓰면, 사용자 입력을 받아 모델에 넘기고, 모델이 "이 툴 써줘"라고 요청하면 진짜로 그 툴을 실행해 결과를 다시 모델에게 돌려주고, 대화 히스토리를 관리하며 이 과정을 반복하는 — 루프 한 덩어리다. 파이썬 파일 하나로도 쓸 수 있다. while 문이 두 개 겹쳐 있으면 된다.

단어의 내력을 짧게 덧붙여 두고 싶다. 영어 harness는 원래 말의 몸에 씌워 고삐를 잡는 마구(馬具)를 뜻한다. 말을 직접 움직이는 건 말 자신이지만, 마구가 없으면 사람이 그 힘을 원하는 방향으로 쓸 수 없다. 머신러닝 연구 쪽에서는 이 비유를 가져와 EleutherAI의 lm-evaluation-harness처럼 모델의 성능을 평가하기 위해 바깥에서 씌우는 프로그램을 하네스라 부르기 시작했고, 최근 에이전트 도구들이 유행하면서 의미가 확장되어 "모델을 감싸 실제로 돌리는 바깥 프로그램" 전반을 가리키게 되었다. 그래서 문맥에 따라 뉘앙스가 조금씩 다를 수 있다는 점만 알아 두면 충분하다.

그러므로 우리가 에이전트 도구를 "만든다"고 할 때 그것은 곧 하네스를 만드는 일이고, 이미 만들어진 에이전트 도구 — Claude Code나 Cursor 같은 것들 — 를 "쓴다"는 것은 곧 남이 만든 하네스 안에서 대화가 돌아간다는 뜻이다.

02  /  구분프롬프트, 컨텍스트, 하네스는 서로 다른 층위다

한 가지 먼저 짚고 가면 좋을 구분이 있다. 세 단어는 비슷해 보이지만 층위가 서로 다르다.

프롬프트
모델에게 한 번 보내는 텍스트. 그냥 문자열이다. "이 문서 요약해줘"가 프롬프트다.
컨텍스트
모델이 한 번의 호출에서 참조하는 전체 입력 덩어리. 시스템 메시지 + 과거 대화 + 현재 질문 + 툴 결과 + 메모리. 200K 토큰이라는 한계를 가진 창문.
하네스
매 턴마다 어떤 컨텍스트를 구성해서 모델에 보낼지, 모델의 응답을 어떻게 처리할지를 결정하는 프로그램. 프롬프트와 컨텍스트는 하네스가 만들어 내는 출력물에 가깝다.

프롬프트가 한 장의 종이라면, 컨텍스트는 그 종이가 담긴 서류철이고, 하네스는 매일 아침 어떤 서류를 꺼내 철할지 결정하는 비서다. 세 층위가 뭉개진 채 대화가 흐를 때 우리가 느끼는 안개는 대개 이 구분이 흐려져서다.

03  /  실체60줄이면 하네스 한 대가 완성된다

말만으로는 부족하니 코드를 보자. 아래는 실제로 돌아가는 파이썬 하네스의 전체다. 저장한 뒤 python my_harness.py를 치면, 그 순간부터 여러분의 손으로 만든 작은 에이전트가 돌아간다. bash 툴 하나만 물려 있어도 "내 다운로드 폴더에 뭐 있어?"라고 물으면 진짜로 ls를 실행해 답한다.

# my_harness.py
import anthropic, subprocess

client = anthropic.Anthropic()

tools = [{
    "name": "run_bash",
    "description": "쉘 명령어 실행",
    "input_schema": {
        "type": "object",
        "properties": {"cmd": {"type": "string"}},
        "required": ["cmd"]
    }
}]

def run_tool(name, args):
    if name == "run_bash":
        return subprocess.run(
            args["cmd"], shell=True,
            capture_output=True, text=True
        ).stdout

messages = []

while True:
    user_input = input("나: ")
    if not user_input: break
    messages.append({"role": "user", "content": user_input})

    while True:
        resp = client.messages.create(
            model="claude-opus-4-6",
            max_tokens=4096,
            tools=tools,
            messages=messages,
        )
        messages.append({"role": "assistant", "content": resp.content})

        if resp.stop_reason != "tool_use":
            print("클로드:", resp.content[-1].text)
            break

        tool_results = []
        for block in resp.content:
            if block.type == "tool_use":
                result = run_tool(block.name, block.input)
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": result,
                })
        messages.append({"role": "user", "content": tool_results})

이것이 하네스의 뼈대다. 바깥 루프는 사람과의 턴을 굴리고, 안쪽 루프는 모델이 툴을 그만 쓸 때까지 모델과 툴 사이를 왕복한다. Claude Code나 Cursor 같은 프로덕션 도구들이 본질적으로 하는 일도 여기서 크게 벗어나지 않는다. 다만 그들은 이 뼈대 주변에 수천, 수만 줄의 관리 레이어를 덧대 놓았을 뿐이다.

04  /  지도그 많은 설정 파일들은 대체 어디에 있는가

여기서 잠깐 궤도를 낮추고 싶다. 개발자가 아닌 분들이 Claude Code를 설치한 뒤 가장 당혹스러워하는 지점이, "분명히 뭔가 설정을 하라는데 그 파일이 어디 있는지 모르겠다"는 것이다. 실은 어려운 이야기가 아니다. 파일과 폴더의 주소만 알면 된다.

핵심 규칙은 단 하나다. Claude Code의 설정 파일은 두 곳에 나뉘어 산다. 하나는 집(컴퓨터 전체)에 있고, 다른 하나는 사무실(지금 작업 중인 프로젝트 폴더)에 있다. 집에 둔 물건은 어느 프로젝트를 열든 따라오고, 사무실에 둔 물건은 그 프로젝트 안에서만 쓰인다.

집 — 컴퓨터 홈 폴더 (한 번 설치하면 늘 거기 있음)
~/.claude/
Claude Code를 설치하면 홈 폴더에 자동으로 생기는 숨김 폴더다. 여기에 대화 기록, 전역 설정, 전역 메모리가 전부 모인다. 앞의 ~는 내 홈 폴더를 뜻하고, 점(.)으로 시작하니 평소에는 파일 탐색기에 안 보인다.
~/.claude/settings.json
Claude Code 자체의 전역 설정. API 키, 기본 모델, 권한 기본값 같은 것들이 들어간다. 한 번 설정해 두면 모든 프로젝트에 적용된다.
~/.claude/CLAUDE.md
모든 프로젝트에서 공통으로 불러오는 전역 메모리. "나는 한글 답변을 선호한다", "나는 파이썬을 쓴다" 같은 본인 취향을 여기에 적어 두면, 새 프로젝트를 열 때마다 Claude가 자동으로 읽는다.
~/.claude.json
MCP 서버 목록이나 세션 정보 같은 내부 상태를 보관하는 파일. 보통 직접 건드릴 일은 없다.
사무실 — 프로젝트 폴더 (이 작업에서만 적용됨)
./CLAUDE.md
지금 작업 중인 프로젝트 폴더의 최상단에 두는 프로젝트 메모리. "이 프로젝트는 Next.js 14 기반이다", "테이블명은 snake_case를 쓴다", "민감 정보는 절대 커밋하지 말 것"처럼 그 프로젝트에만 해당하는 규칙을 담는다. Claude Code는 세션을 시작할 때 이 파일을 자동으로 읽어 시스템 프롬프트 앞에 붙인다.
./.claude/
프로젝트 전용 설정 폴더. 이 프로젝트에서만 쓸 슬래시 명령어, 로컬 MCP 설정, 서브에이전트 정의 같은 것을 넣는다. 홈 폴더의 ~/.claude/와 이름은 같지만 전혀 다른 폴더다. 전자는 프로젝트 전용, 후자는 컴퓨터 전체에 공통.
./.claude/settings.json
이 프로젝트에서만 적용되는 설정. 팀원들과 공유해도 좋은 기본값(예: 특정 명령어 사전 승인)을 여기에 둔다.
./package.json
사실 이 파일은 Claude Code의 것이 아니다. Node.js 프로젝트라면 누구나 갖고 있는 프로젝트 명세서로, 이 폴더가 무엇에 의존하는지(어떤 외부 라이브러리를 쓰는지)를 적어 둔 파일이다. 내용물은 프로젝트마다 다르고, Claude Code와는 무관하게 존재한다. 다만 Claude Code가 작업할 때 이 파일을 읽어 프로젝트의 성격을 파악하는 데 참고는 한다.

정리하면 이렇다. 홈 폴더의 ~/.claude/는 "어디서든 적용되는 내 취향"을 담는 서랍이고, 프로젝트 폴더의 ./.claude/./CLAUDE.md는 "이 작업에서만 쓸 규칙"을 담는 서랍이다. 이 두 서랍의 차이를 구분하는 순간, 문서에 등장하는 경로 이름들이 훨씬 덜 무서워진다.

05  /  관리 레이어프로덕션 하네스에 실제로 붙어 있는 것들

다시 하네스의 몸통으로 돌아가자. 60줄짜리 뼈대 주변에 실제로 어떤 살이 붙어 있는지, 하나씩 뜯어 보면 각각은 의외로 소박하다. 다만 소박한 것들이 모이면 꽤 두툼해진다.

컨텍스트 윈도우 관리

모델은 한 번에 200K 토큰 정도밖에 받을 수 없다. 실제 세션은 몇 시간씩 가고, 파일 수십 개를 읽고, 명령어 결과가 수백 줄씩 쌓인다. 그래서 하네스는 매 턴마다 토큰 수를 재고, 한계의 80% 즈음이 되면 옛 메시지를 모델에게 다시 넘겨 요약시킨 뒤 원본을 요약본으로 교체한다. Claude Code의 /compact가 이 동작이다. 마법이 아니라 "요약해줘"를 자동으로 한 번 더 호출하는 것이다.

다만 이 요약 과정이 생각보다 섬세하다. 대화 도중에 모델이 어떤 툴을 호출했다면, 그 '호출(tool_use)'과 '결과(tool_result)'는 반드시 쌍으로 붙어 있어야 한다. 한쪽만 잘라내면 API가 "호출에 대응하는 결과가 없다"며 통째로 거절해 버리기 때문이다. 그래서 요약을 할 때 하네스는 이런 쌍을 건드리지 않도록 조심해야 하고, 어떤 메시지는 요약하고 어떤 메시지는 원본 그대로 남길지 나름의 규칙을 갖는다. "옛 메시지 요약해서 교체"라는 한 줄이 실제로는 이런 자잘한 판단들의 연쇄다.

프롬프트 캐싱

한 가지 더 챙겨 두면 좋은 개념이 있다. Claude API에는 프롬프트 캐싱이라는 기능이 있다. 매 호출마다 앞부분 — 시스템 메시지, 긴 문서, 툴 정의 같은 것 — 이 거의 동일하다면, 그 부분을 서버 쪽에 캐시해 두고 다음 호출에서는 "그 부분은 다시 계산하지 말고 캐시에서 꺼내"라고 지시할 수 있다. 잘 쓰면 속도가 빨라지고 비용이 상당히 줄어든다.

다만 캐시 표시를 어디에 붙이느냐에 따라 효과가 천차만별이다. 변하지 않는 부분의 끝 지점에 정확히 걸어 두어야 하는데, 경계를 잘못 잡으면 캐시가 매 호출마다 깨져서 오히려 느려지고 비싸진다. 프로덕션 하네스의 숨은 노력 중 상당 부분이 "어디에서 잘라야 캐시가 최대한 살아남을까"를 고민하는 일이다.

장기기억

모델은 대화가 끝나면 전부 잊는다. 그래서 "기억"은 전적으로 하네스가 디스크에 파일로 저장하는 방식으로 구현된다. 앞서 본 CLAUDE.md, ~/.claude/CLAUDE.md, 세션 JSON 파일이 모두 그 구체물이다. 하네스는 세션을 시작할 때 이런 파일을 읽어 시스템 프롬프트 앞에 붙인다. claude.ai의 메모리 기능도 기본 원리는 같다. 별도 저장소에 사용자별 사실 목록을 두고, 대화 시작 시 관련된 것만 골라 컨텍스트에 주입한다. 기본형의 장기기억은 결국 파일을 읽어 프롬프트 앞에 붙이는 일이다.

다만 이 방식은 장기기억의 가장 단순한 형태라는 점을 덧붙여 두고 싶다. 반복 작업이 많아지고 누적된 지식의 양이 커지면, 파일 한 덩어리를 통째로 붙이는 방식만으로는 버티기 어려운 순간이 온다. 파일이 수만 자를 넘기면 매 호출마다 그 전체를 컨텍스트에 붙이기엔 너무 무겁고, 정작 지금 필요한 정보는 그 안의 몇 줄뿐이기 때문이다.

그래서 요즘 나오는 에이전트 도구들은 한 단계 더 들어간 방식을 함께 쓴다. 기억을 파일 한 덩어리로 두지 않고, 로컬 스토리지나 외부 메모리 서비스 — Mem0, Zep, Letta, Graphiti 같은 것들 — 에 지식 그래프(knowledge graph) 형태로 쪼개 저장하는 것이다. 사람과 프로젝트, 개념과 마감일, 사건과 결론 사이의 관계를 노드와 엣지로 구조화해 두고, 대화 중에는 그 그래프를 탐색해 관련된 노드만 골라 꺼낸다. 벡터 임베딩 기반의 검색(RAG)도 같은 계열의 접근이다. 긴 문서를 토막 내 임베딩해 저장해 두고, 현재 질문과 의미적으로 가까운 조각만 골라 맥락에 주입한다.

앞서 본 CLAUDE.md 방식과 이 방식의 결정적인 차이는 선택적 회상의 유무다. 파일 방식은 전체를 통째로 읽어 붙이기 때문에 "모든 것을 기억하되 매번 전부 꺼낸다." 반면 지식 그래프 방식은 엄청나게 많은 정보를 저장해 두고도, 매 턴마다 꼭 필요한 조각만 꺼내 붙인다. 후자가 훨씬 많은 양을 "기억"할 수 있는 이유가 여기에 있다. 개인이 오랜 기간 쌓은 작업 히스토리나 조직의 지식 자산처럼 규모가 큰 기억을 다룰 때, 파일 방식으로는 한계가 분명하기에 사람들은 이 구조화된 저장소 쪽으로 옮겨 간다.

다만 한 가지는 바뀌지 않는다. 지식 그래프든 벡터 검색이든, 꺼낸 결과는 결국 텍스트로 변환되어 컨텍스트 창에 주입된다는 점이다. 모델은 여전히 "한 번에 입력받는 텍스트"밖에 참조할 수 없기 때문이다. 그래서 장기기억의 진짜 싸움은 "어떻게 저장하느냐"보다 "매 순간 무엇을 골라 꺼내느냐"에 있다. 저장은 하네스 바깥의 데이터베이스나 메모리 서비스가 맡더라도, 꺼낸 결과를 어떻게 추려 프롬프트에 얹을지 결정하는 것은 다시 하네스의 일이다. 바깥 저장소는 도서관이고, 하네스는 그 도서관에서 오늘 필요한 몇 페이지만 골라 책상 위에 올려 주는 사서인 셈이다.

슬래시 명령어

/compact, /clear, /model 같은 명령어는 모델에게 가지 않는다. 하네스가 사용자 입력을 모델로 보내기 직전에 가로채서 자체적으로 처리한다. 루프 안의 간단한 if 분기 하나다. 사용자 정의 슬래시 명령어(.claude/commands/ 폴더의 md 파일)도 마찬가지다. 해당 파일 내용을 읽어 유저 메시지처럼 꾸며 모델에 전달하는 매크로에 가깝다.

MCP (Model Context Protocol)

툴을 하네스 코드에 하드코딩해 두면, 새 툴을 추가할 때마다 프로그램 자체를 고쳐야 한다. 이 문제를 해결하기 위해 툴 목록을 외부 프로세스(MCP 서버)에게 동적으로 물어오는 규격이 만들어졌다. 하네스는 시작할 때 설정된 MCP 서버들을 자식 프로세스로 띄우고, "너 무슨 툴 갖고 있어?"를 물어 받은 목록을 자신의 기존 툴 배열에 합쳐 모델에게 제공한다. 모델 입장에서는 네이티브 툴인지 MCP 툴인지 구분할 수 없다. 그저 툴 이름이 늘어났을 뿐이다.

Skills

MCP가 "새로운 툴"을 꽂는 방식이라면, Skills는 "기존 툴로 어떻게 작업할지에 대한 레시피"를 모델에게 건네는 방식이다. 구현은 훨씬 가볍다. 특정 폴더에 SKILL.md라는 마크다운 매뉴얼을 깔아두면, 하네스는 세션 시작 시 그 이름과 설명만 시스템 프롬프트에 주입한다. 사용자가 "워드 문서 만들어줘"라고 하면 모델이 "아, docx 스킬이 있었지" 하고 스스로 그 SKILL.md를 view 툴로 읽어 지침을 따른다. 별도 프로세스도, 특별한 프로토콜도 없다. 그저 마크다운 파일이다.

스트리밍과 복구

stream=True로 호출하면 모델의 응답이 완성되기를 기다리지 않고, 토큰이 만들어지는 대로 화면에 흘려 보낸다. 터미널에서 답변이 한 글자씩 찍히는 그 연출이 이것이다. 다만 스트리밍은 중간에 끊길 수 있다. 네트워크가 불안정하거나, 툴 호출이 도중에 잘리거나, API가 속도 제한(rate limit)을 걸거나. 이럴 때 하네스는 그냥 에러를 띄우고 끝내지 않는다. 몇 초 기다렸다가 다시 시도하고(재시도 로직), 툴 호출이 중간에 끊겼으면 완결된 지점까지 되돌린다. 사용자 눈에는 보이지 않지만, 루프의 안쪽에는 이런 복구 코드가 꽤 두툼하게 깔려 있다.

그 외 자잘하지만 중요한 일들

이 레이어들 중 어느 하나도 "개념적인" 것이 없다. 모두 코드로 구현되어 디스크 어딘가에 파일로 존재하는 구체물이다. 그리고 각각은 놀라울 만큼 소박한 아이디어에서 출발한다. 뼈대가 60줄이라는 말은 "60줄로 프로덕션 품질을 낼 수 있다"는 뜻은 아니다. Claude Code나 Cursor 같은 도구가 몇 시간짜리 세션을 버티게 만드는 힘은 결국 이런 관리 레이어 하나하나를 튼튼하게 만든 엔지니어링의 누적이다. 다만 그 누적이 어떤 신비로운 비법에서 오는 것이 아니라, 이해할 수 있는 작은 조각들의 합이라는 점이 이 글에서 전하고 싶은 이야기다.

06  /  오해"하네스 프롬프트"라는 말을 들었다면

이 글을 쓰던 중 주변에서 한 가지 질문을 받았다. "하네스 프롬프트라는 말을 어디서 들었는데, 이미 만들어진 에이전트 도구에 내가 만든 하네스를 프롬프트로 주입하면 그 도구가 내 하네스를 참고해서 작동한다는 뜻인가?" 실은 나도 이 말을 들을 때마다 조금씩 걸려 있었기에, 이번 기회에 정리해 두려 한다.

먼저 단호하게 말해 두면, "하네스 프롬프트"는 업계 표준 용어가 아니다. 현장에서 간혹 쓰이기는 하지만 화자마다 가리키는 바가 다르고, 대개는 서로 다른 세 가지를 뭉뚱그린 채 말하는 경우다. 세 가지를 구분해 두면 그 말이 들려올 때 곧바로 초점을 맞출 수 있다.

첫 번째 해석은 하네스 제작자가 도구 내부에 박아 둔 시스템 프롬프트를 가리키는 쓰임이다. Claude Code나 Cursor는 각자 수천 줄짜리 내부 지시문을 갖고 있고, 그것이 모델의 기본 성격과 행동 양식을 결정한다. 이걸 두고 "Claude Code의 하네스 프롬프트"라 부른다면 말은 된다. 다만 이건 사용자가 건드릴 수 있는 것이 아니라 도구 쪽에 박혀 있는 것이다.

두 번째 해석은 사용자가 일반 모델에게 "너는 이제부터 계획을 세우고, 툴을 호출하고, 결과를 보고 다시 계획하라"고 지시하는 프롬프트를 가리키는 쓰임이다. ReAct 패턴이라 부르는 기법이 대표적이다. 이것도 누군가는 "하네스 프롬프트"라 부를 수 있지만, 엄밀히는 하네스를 흉내 내게 만드는 프롬프트 기법에 가깝다. 외부에서 실제로 툴을 실행시키는 주체가 없기 때문에, 루프처럼 보여도 진짜 루프가 돌지는 않는다.

세 번째 해석은 앞선 질문자의 해석이다. "내가 만든 하네스를 기존 도구에 프롬프트로 주입해서 그 도구가 내 하네스를 참고해 작동하게 한다." 기술적으로 말하면 이 구도는 성립하지 않는다. 프롬프트는 텍스트이고, 하네스는 프로그램이다. 두 가지는 서로 다른 층위에 산다. Claude Code에게 "내가 만든 파이썬 하네스 코드를 보고 그 방식대로 작동해 줘"라고 아무리 텍스트를 넣어도, Claude Code는 여전히 자신의 while 루프를 돌린다. 그 텍스트는 그저 참고 자료로만 읽힐 뿐, 실행 구조 자체는 바뀌지 않는다.

그래서 "하네스 프롬프트"라는 말을 들었을 때 화자를 나무라기보다는, 조용히 한 가지만 되물어 보면 좋다. "지금 말씀하시는 게 도구 내부에 박힌 시스템 프롬프트를 뜻하시는 건가요, 아니면 모델에게 에이전트처럼 행동하라고 지시하는 ReAct 스타일 프롬프트를 뜻하시는 건가요?" 대개는 이 질문만으로 대화의 해상도가 한 단계 올라간다. 그리고 대답이 막힌다면, 그건 말하는 사람도 아직 정리가 끝나지 않은 상태라는 뜻이다.

07  /  확장내 손으로 하네스를 짓는다면

이 글을 여기까지 읽었다면, 자연스럽게 반대 방향의 질문이 떠오를 수 있다. "그러면 나는 Claude Code나 Cursor를 쓰지 않고, 내 용도에 맞는 내 하네스를 직접 만들 수도 있는가?" 결론부터 말하면 가능하다. 그리고 생각보다 가깝게 있다.

앞서 본 60줄짜리 파이썬 루프가 가장 짧은 출발점이다. 여기에 파일 편집 툴 몇 개, 히스토리 저장, 간단한 권한 확인 정도를 덧붙이면 500줄 안쪽에서 "내 컴퓨터에서 실제로 돌아가는 CLI 하네스"가 완성된다. 이미 이 방향으로 만들어진 오픈소스가 여럿 있다. Aider는 파이썬 CLI 하네스고, Open Interpreter는 로컬 코드 실행에 특화된 하네스고, Cline과 Continue는 VSCode 확장 형태의 하네스다. 전부 개인 혹은 소규모 팀이 만들었다. "개인이 만들기에는 너무 거대한 일"이 결코 아니라는 뜻이다.

현실적인 선택지를 정리하면 대체로 다섯 갈래다.

여기서 중요한 관점 하나를 덧붙이고 싶다. 하네스를 직접 만든다는 말은 "Claude Code를 완전히 대체할 무언가를 만든다"는 뜻이 아니다. 프로덕션 품질로 가려면 앞서 본 관리 레이어들 — 컨텍스트 압축, 프롬프트 캐싱, 스트리밍 복구, 권한 게이트, 서브에이전트 — 을 모두 직접 구현해야 하는데, 이건 개인이 단기간에 따라잡을 수 있는 수준이 아니다. 그럴 필요도 없다.

대신 현실적인 길은 "내 반복 작업에 꼭 맞는 작은 전용 하네스"를 만드는 것이다. 공공기관 보고서 자동화 전용, 강의 슬라이드 생성 전용, 견적서/제안서 초안 전용 — 이런 식으로 도메인이 좁고 분명한 하네스는 일반 도구보다 오히려 더 잘 돌아간다. 일반 도구는 모든 작업을 조금씩 할 줄 알아야 하지만, 전용 하네스는 내 한 가지 작업만 아주 잘하면 되기 때문이다. 필요한 툴만 정확히 달아 두고, 그 작업에만 해당하는 규칙을 시스템 프롬프트에 박고, 완성된 결과를 내 폴더 구조 그대로 떨어뜨리면 된다.

이 관점에서 보면 하네스는 멀리 있는 엔지니어링이 아니라 가까운 생산 수단이다. 이미 내가 하고 있는 반복 작업이 있고, 그 작업의 모양을 가장 잘 아는 사람이 나라면, 그 작업에 꼭 맞는 루프를 씌울 권리도 결국 내게 있다. 남이 만든 일반 도구에 내 작업을 맞추는 것이 아니라, 내 작업에 맞는 작은 도구를 내 손으로 짓는 것 — 그 방향의 문은 지금도 열려 있다.


08  /  마무리용어에서 한 걸음, 실체로

다시 처음으로 돌아가 보자. 하네스라는 단어를 아는 것은 좋다. 새로운 어휘는 언제나 우리 사고의 해상도를 높인다. 다만 용어에서 멈추면 보이지 않는 것들이 있다. 그것이 어떤 파일로 내 컴퓨터 어느 폴더에 살고 있는지, 어떤 루프가 매 초 무엇을 반복하고 있는지, 어떤 부분이 진짜 어렵고 어떤 부분이 생각보다 소박한지, 그리고 내가 직접 만든다면 어디서부터 시작해야 하는지 — 이런 것들은 한 걸음 더 들어가야만 보인다.

이 글이 그 한 걸음의 지도가 되었으면 한다. 다음에 누군가 "하네스가 어쩌고"를 이야기할 때, 우리는 이제 머릿속에 구체적인 while 루프 하나를 그릴 수 있다. ~/.claude/CLAUDE.md./.claude/settings.json이 어디 있는 어떤 파일인지 알고, 요약 압축이 어떤 순간에 트리거되는지 알며, 프롬프트 캐싱이 왜 경계선을 잘 잡아야 하는지 알고, MCP가 왜 별도 프로세스인지 알며, Skills가 그저 마크다운 파일임을 안다. "하네스 프롬프트"라는 말을 들으면 어느 층위를 묻고 있는지 되물을 줄 알고, 나아가 내 용도에 맞는 작은 하네스 하나를 내 손으로 시작해 볼 마음까지 낼 수 있다. 그 정도면 충분하다.

용어를 아는 것은 출발점이고, 실체를 아는 것은 산책의 끝이 아니라 그다음 질문으로 넘어갈 자격이다. 부디 함께 그다음 질문으로 가 보자.