Claude Code나 OpenAI Codex를 쓰다 보면 신기한 순간이 있습니다. 파일을 열고, 코드를 수정하고, 터미널을 실행하면서 스스로 문제를 해결해 나가는 모습이요. 마치 AI가 개발자처럼 “생각하는” 것처럼 보입니다. 그런데 실제로는 놀랍도록 단순한 구조 위에서 작동합니다.

Simon Willison이 연재 중인 “에이전틱 엔지니어링 패턴” 가이드에서 코딩 에이전트의 내부 구조를 체계적으로 설명했습니다. LLM을 매일 쓰는 개발자라면 한 번쯤 짚어둘 만한 내용입니다.
출처: How coding agents work – Simon Willison’s Weblog
에이전트의 정체: LLM + 하네스
코딩 에이전트는 LLM 자체가 아닙니다. Simon Willison의 표현을 빌리면, 에이전트는 LLM을 감싸는 하네스(harness)입니다. LLM에 도구를 추가하고, 보이지 않는 프롬프트로 행동을 지시하고, 툴 호출 결과를 다시 모델에게 돌려주는 소프트웨어 구조입니다.
핵심은 LLM이 본질적으로 텍스트 완성 엔진이라는 점입니다. “the cat sat on the “라는 입력에 “mat”을 붙이는 것과 동일한 원리로, “Python 함수를 작성하면 def download_file(url):”라고 이어나갑니다. 멀티모달 모델도 이미지를 별도로 처리하는 게 아니라, 이미지를 토큰 정수로 변환해 텍스트와 동일하게 처리합니다.
툴 호출이 작동하는 방식
코딩 에이전트의 핵심 기능인 툴 호출은 실제로 프롬프트 안에서 이루어집니다. 흐름을 단순하게 보면 이렇습니다.
- 시스템 프롬프트에 사용 가능한 툴과 호출 형식 정의
- 모델이 응답 대신 툴 호출 텍스트를 출력
- 하네스 소프트웨어가 이를 감지하고 실제 함수를 실행
- 실행 결과를 다시 대화에 추가해 모델에게 전달
- 모델이 결과를 바탕으로 최종 응답 생성
Claude Code나 Codex 같은 에이전트는 이 루프에서 Bash(), Python() 같은 강력한 툴을 제공합니다. 코드를 직접 실행하고 결과를 확인하면서 다음 행동을 결정하는 구조입니다.
LLM은 기억이 없다
한 가지 중요한 특성이 있습니다. LLM은 무상태(stateless)입니다. 매번 프롬프트를 실행할 때마다 빈 슬레이트에서 시작합니다. 에이전트가 대화의 연속성을 유지하려면 매번 전체 대화 이력을 다시 모델에게 넣어줘야 합니다.
대화가 길어질수록 입력 토큰이 늘어나 비용도 올라갑니다. 이를 완화하기 위해 대부분의 제공업체는 캐시 토큰 할인을 제공합니다. 짧은 시간 안에 반복 처리된 토큰 앞부분을 캐시해 저렴하게 처리하는 방식입니다. 코딩 에이전트들이 대화 앞부분의 내용을 최대한 수정하지 않으려 설계되는 이유도 여기 있습니다.
리즈닝: 더 많이 생각하기
2025년 이후 프런티어 모델들에 본격적으로 추가된 리즈닝(추론) 기능은, 모델이 최종 답변 전에 문제를 스스로 검토하는 시간을 갖는 것입니다. 사람이 소리 내어 생각하는 것과 비슷한 효과로, 더 많은 토큰을 소비하는 대신 복잡한 문제에서 정확도가 올라갑니다.
코딩 에이전트에서 리즈닝은 특히 디버깅에 유용합니다. 복잡한 코드 경로를 따라가며 함수 호출 출처를 역추적하는 데 효과적이기 때문입니다. 많은 에이전트들이 리즈닝 강도를 조절하는 옵션을 제공하는 것도 이 때문입니다.
구조는 단순하다
정리하면, 코딩 에이전트의 뼈대는 예상보다 단순합니다. LLM API 위에 툴 루프를 올리는 기본 구조는 수십 줄의 코드로 구현 가능합니다. 그 위에 수백 줄짜리 시스템 프롬프트, 토큰 캐싱 최적화, 리즈닝 제어, 수십 개의 툴 정의가 더해져 Claude Code나 Codex 같은 완성도 높은 에이전트가 됩니다.
Simon Willison은 가이드 말미에서 직접 에이전트를 만들어보는 것을 권합니다. 내부 구조를 이해하는 가장 빠른 방법이라고요. 가이드에는 안티패턴, 코드 품질 관리 등 에이전틱 엔지니어링 전반에 대한 내용도 담겨 있습니다.
참고자료: Agentic Engineering Patterns – Simon Willison’s Weblog

답글 남기기