Part I · CHAPTER 01

뇌와 몸: 에이전트의 해부학

하네스라는 얇은 껍데기

ChatGPT에 질문하는 것과 코딩 에이전트(Claude Code, Codex 등)가 코드를 짜고 고치는 것은 체감이 완전히 달라요. 같은 LLM인데 왜 다를까요?

순수한 LLM: 손발 없는 뇌

가장 단순한 LLM 사용은 이렇게 생겼어요.

[프롬프트] --> ( LLM ) --> [텍스트 응답]

정교한 두뇌지만 완전히 무력해요.

  • 파일을 스스로 열어보지 못해요.
  • 터미널 명령을 실행할 수 없어요.
  • 이전 대화를 기억하지 못해요 (매번 컨텍스트를 다시 넣어야 해요).
  • 웹을 검색할 수 없어요.

비유하자면 수술실에 누워 있는 환자와 같아요. 시각·청각·언어 능력은 멀쩡한데, 사지가 묶여 있죠. 누가 뭔가를 입에 가져다 대 주지 않으면, 본인은 한 발자국도 움직일 수 없어요.

[!NOTE] "그런데 제 ChatGPT는 저를 기억하던데요?" ChatGPT의 기억 기능은 LLM이 스스로 기억하는 게 아니에요. 대화가 끝날 때 하네스가 중요한 내용을 별도로 저장해 두었다가, 다음 대화를 시작할 때 프롬프트에 몰래 끼워 넣는 방식이에요. LLM 자체는 여전히 그 순간 입력된 컨텍스트만 봐요. 깜짝 사실: ChatGPT 본체는 사실상 매번 처음 만난 사람처럼 출발하고, 책상 위에 미리 올려둔 메모지를 슬쩍 본 다음 "아, 그 분이시죠" 하는 트릭이에요.

생각은 할 수 있지만, 아무것도 할 수 없어요. 그래서 진짜 "에이전트"가 되려면 몸이 필요해요.

에이전트: LLM에 몸을 붙이다

에이전트(Agent) 는 LLM에 "몸"을 붙인 것이에요. 이 몸에 해당하는 것이 하네스(harness) 예요.

하네스(harness) 란: 원래는 말에 씌우는 마구(馬具). 소프트웨어 맥락에서는 LLM이 외부 세계와 상호작용할 수 있게 감싸주는 실행 환경 — 도구 호출 인터페이스, 반복 루프, 파일 I/O, 안전 장치가 한 덩어리로 묶여 있어요.

flowchart LR User["사용자 입력(User Input)"] subgraph Harness["하네스(Harness)"] LLM["LLM"] Tools["파일/셸/웹/DB(File/Shell/Web/DB)"] LLM -->|"도구 호출(Tool Call)"| Tools Tools -->|"도구 결과(Tool Result)"| LLM end User --> LLM

하네스가 제공하는 것:

  • 도구 호출: LLM이 "파일 읽어줘", "이 명령 실행해줘"를 구조화된 형식으로 내놓으면, 하네스가 실행 후 결과를 돌려줌
  • 반복 루프: "코드 짜기 → 실행 → 에러 → 수정"을 LLM이 스스로 반복할 수 있게 구동
  • 상태 관리: 세션 동안의 파일 수정, 실행 기록 추적
  • 안전 장치: 위험한 명령 차단, 사용자 승인 요청

도구 호출의 실제: 주문서를 쓰는 뇌

이 메커니즘의 핵심을 한 문장으로 압축하면 — LLM은 텍스트만 출력해요. 파일을 직접 열거나 명령을 직접 실행하는 코드가 LLM 안에 있는 게 아니에요.

비유로 풀면 — LLM을 "주문서를 쓸 수 있는 관리자"로 생각해 보세요. 이 관리자는 직접 창고에 가지 않아요. "창고 3번 선반 A-4 박스 가져다줘"라고 적힌 메모를 써요. 창고 직원(하네스)이 그 메모를 읽고 실제로 가져와서 "A-4 박스 내용물: 나사 50개, 볼트 20개"라고 보고해요. 관리자는 그 보고를 읽고 다음 지시를 내려요.

비유에는 한계가 있어요. 실제 LLM이 "주문서를 쓰는" 행위는 사람의 의식적 결정과 달라요. 모델은 다음에 올 토큰을 확률 분포로 뽑을 뿐이고, 도구 호출 형식은 학습 과정에서 그 확률 분포에 굳어진 패턴이에요. 즉 "관리자가 의도적으로 주문서를 쓰는" 게 아니라, "주문서가 나올 자리에 주문서가 나오도록 훈련되어 있다"가 더 정확해요. 그렇긴 해도 외부에서 보는 흐름은 비유 그대로예요.

실제 도구 호출 루프는 이렇게 동작해요.

sequenceDiagram participant LLM participant Harness as 하네스(Harness) LLM->>Harness: { "tool": "Read", "path": "src/main.py" } Note over LLM: "src/main.py를 확인해야겠다" Harness->>LLM: 파일 내용 (컨텍스트에 삽입) Note over LLM: "17번째 줄에 버그. 수정이 필요하다" LLM->>Harness: { "tool": "Edit", "file": "src/main.py", ... } Harness->>LLM: 수정 완료 보고 Note over LLM: "수정 완료. 테스트를 돌려보자" LLM->>Harness: { "tool": "Bash", "command": "pytest" } Harness->>LLM: 테스트 결과 Note over LLM: "전부 통과. 완료." LLM-->>LLM: 사용자에게 최종 응답

사용자는 최종 응답 한 줄만 봐요. 그 사이에 수십 번의 도구 호출 루프가 오갔을 수 있어요. 위 다이어그램에서 "Tool Call" 화살표가 내려가고 "Tool Result"가 올라오는 것이 이 루프예요.

어떤 도구를 붙이느냐에 따라 에이전트의 능력이 결정돼요. 파일 읽기·수정, 셸 명령 실행, 웹 검색, DB 조회 — 하네스에 등록된 것이라면 무엇이든 LLM이 주문서를 써서 호출할 수 있어요.

LLM은 뇌, 하네스는 몸. Claude Code, Codex, Cursor, Aider, Roo Code — 겉모습이 달라도 개념은 동일해요. 이 뼈대를 잡고 있으면 도구가 무엇이든 판단 기준이 흔들리지 않아요.