지난 1년 동안은 누구를 만나든 AI에 대한 이야기가 빠지지 않았다. 최근들어 달라진 점으로 지난 몇 달 동안은 AI가 무엇을 해결해줄 수 있을지, 앞으로 어떤 기술이 나올지에 대한 이야기였다면 지금은 AI에 대한 불안과 공포에 대한 이야기가 주를 이루고 있다. 특히 개발자들 사이에서는 AI로 인해 자신의 전문성이 빠르게 대체될 수 있다는 우려가 크다. 이런 상황은 안드레이 카파시가 바이브 코딩이라는 용어를 소개한 지 불과 1년 만에 벌어진 일이다. AI 코딩 에이전트인 Claude Code가 개발자들 사이에 거대한 불안을 만들어내고 있는 것이다.
최근 이 불안에는 이름까지 붙었다. 『Claude Blue - 실리콘밸리 전체가 우울하다』에서 처음 사용된 표현으로 클로드 블루는 AI의 급속한 발전으로 전문성과 경력이 빠르게 대체되는 데서 오는 심리적 우울감을 뜻한다. 최전선의 엔지니어들조차 자신의 가치가 줄어들 것을 실감하고 있다는 것이다. 기술이 급격히 발전할 때마다 사람들이 불안을 느끼는 것은 어제 오늘 일이 아니지만 이번에는 양상이 좀 다르다. ‘지능’이라는 인간의 고유 영역을 너무나도 급격하게 침범하는 AI에 대한 공포는 이전과는 차원이 다르다.
게다가 용어의 범람도 심각하다. 바이브 코딩, 프롬프트 엔지니어링, 컨텍스트 엔지니어링, 하네스 엔지니어링 등 매일같이 새로운 ‘엔지니어링’이 등장하고 그때마다 뒤쳐지는 듯한 압박이 밀려온다. 조사에 따르면 직장인의 24%가 AI로 인한 정보 과부하 때문에 정신 건강이 악화됐다고 응답했을 정도다.
이와 관련하여 또 다른 재미있는 통계가 있다. 95%의 근로자가 AI 활용을 과장하고 있다고 한다. 온 세상이 AI를 완벽하게 마스터한 것처럼 보이지만 실제로는 대부분이 허세에 가깝다는 뜻이다. 우리가 느끼는 FOMO는 허상 위에 세워진 환상인 셈인데 아이러니하게도 그 환상이 만들어내는 공포만큼은 진짜다.
공포를 극복하는 법
사람은 이해할 수 없는 것 앞에서 공포를 느낀다. 동굴 속에서 정체를 알 수 없는 소리가 들려올 때 우리 조상들이 취할 수 있는 최선의 전략은 도망치는 것이었다. 생존을 위한 합리적인 본능이었지만 현대 사회에서는 이 본능이 역효과를 내는 경우가 많다.
AI가 만들어내는 공포도 같은 구조다. 정체를 알 수 없는 무언가가 엄청난 속도로 발전하고 있고 매일같이 새로운 용어가 쏟아지는데 주변 사람들은 모두 잘 적응하고 있는 것처럼 보인다. 이런 압도감 앞에서 이성적인 판단을 유지하기란 쉽지 않다. 해외 보도에 따르면 AI 업계 종사자들 사이에서 치료 상담 사례가 실제로 증가하고 있고 수면 장애나 사회적 위축 같은 증상을 호소하는 경우도 늘어나고 있다.
공포에 대한 반응은 보통 둘 중 하나다. “나는 AI 안 써도 괜찮아”라고 자신을 설득하며 회피하거나 반대로 모든 AI 도구를 닥치는 대로 시도하다가 번아웃에 빠지거나. 접근 방식은 정반대지만 공포에 휘둘리고 있다는 점에서는 둘 다 마찬가지다.
그런데 공포를 극복하는 방법이 하나 있다. 공포를 직접 마주하고 그 정체를 이해하는 것이다. 어둠 속 정체 모를 소리가 무서운 이유는 ‘정체를 모르기’ 때문이다. 소리의 원인이 바람에 흔들리는 나뭇가지라는 것을 알게 되면 공포는 사라진다. 공포란 대상 자체가 아니라 대상에 대한 무지에서 오는 것이기 때문이다.

물론 소리의 정체가 항상 나뭇가지인 것은 아니다. 실제로 위험한 동물일 수도 있다. 하지만 그 동물이 무엇인지 알고 있다면 이야기가 달라진다. 곰인지 뱀인지 알면 도망칠지 가만히 있을지 판단할 수 있고 미리 대비할 수도 있다. 정체를 모를 때는 모든 가능성이 위협이지만 정체를 알면 위협의 범위가 명확해지고 그제서야 대응이 가능해진다.
AI에 대한 공포도 다르지 않다. 우리가 두려워하는 것은 AI 그 자체라기보다 AI가 어떻게 동작하는지 모른다는 사실에 가깝다. 무엇인지 모르니까 그것이 할 수 있는 일과 할 수 없는 일의 경계도 보이지 않고 그래서 모든 가능성이 위협으로 느껴진다. 하지만 정체를 이해하고 나면 마법처럼 보이던 것이 기술로 보이기 시작한다. 기술이란 배울 수 있는 것이고 한계가 있는 것이다.
그렇다면 이제 공포와 직접 마주해보자. 더 이상 도망치거나 눈을 감지 말고 우리를 이토록 불안하게 만드는 그것을 정면으로 들여다보자. LLM이란 도대체 무엇이고 어떻게 동작하며 그 위에서 돌아가는 수많은 용어들의 정체는 무엇일까?
LLM의 정체
LLM을 이해하기 위해 트랜스포머 아키텍처의 수학적 원리나 어텐션 메커니즘의 행렬 연산까지 파고들 필요는 전혀 없다. 우리에게 필요한 것은 LLM이 무엇을 하는지 이해하는 것이지 그것이 내부적으로 어떻게 동작하는지를 이해하는 것이 아니다.
LLM은 다음에 올 단어를 예측하는 모델이다. 엄청나게 많은 텍스트를 학습해서 “이 문맥에서 다음에 올 가능성이 가장 높은 단어는 무엇인가”를 계산한다. ChatGPT든 Claude든 Gemini든 핵심 동작 원리는 동일하다. 입력된 텍스트를 바탕으로 다음 토큰을 하나씩 생성해 나간다.
“다음 단어를 예측하는 것치고는 너무 똑똑하지 않느냐”는 의문이 들 수 있다. 맞는 말이다. 충분한 규모의 데이터와 파라미터로 학습된 모델은 단순한 단어 예측을 넘어 추론이나 번역, 코드 작성까지 해낸다. 하지만 그 모든 능력의 근간에는 여전히 “주어진 입력에 대해 가장 적절한 출력을 생성한다”는 하나의 원리가 놓여 있다.
그렇다면 우리가 사용하는 ChatGPT, Claude, Gemini 같은 서비스는 이 모델을 어떻게 사용하는 것일까? 겉으로 보기에는 복잡해 보이지만 내부 구조는 굉장히 단순하다. 그 정체는 바로 HTTP API 호출이다. 모든 LLM 서비스는 같은 패턴으로 동작한다. 클라이언트가 대화 내용을 담은 메시지를 API 서버로 보내면 서버 뒤의 모델이 다음 토큰을 생성하고 그 결과를 스트리밍으로 돌려준다. 우리가 ChatGPT에서 글자가 한 글자씩 나타나는 것을 볼 때 실제로 벌어지고 있는 일이 바로 이것이다.
Codex나 Claude Code의 강력한 코딩 능력도 이 API 호출을 감싸고 있는 것에 불과하다. 메시지를 구성하고 API를 호출하고 응답을 받아 처리한다. 이것이 모든 LLM 애플리케이션의 기본 골격이다.
하지만 이 단순한 구조에는 한계가 있다. 모델은 상태를 갖지 않아서 대화를 “기억”하려면 매번 이전 대화 전체를 다시 입력해야 한다. 입력할 수 있는 텍스트 길이에도 제한이 있다. 학습 이후의 정보는 알지 못하고 그럴듯하지만 틀린 내용을 생성하기도 한다. 혼자서는 파일을 읽거나 코드를 실행하는 것도 불가능하다.
이런 한계를 극복하기 위해 다양한 방법들이 나타났다. 우리를 괴롭히던 수많은 ‘엔지니어링’이 바로 그것이다.
모든 것은 프롬프트로 시작한다
앞서 살펴본 한계들을 다시 떠올려보자. 상태가 없고 입력 길이에 제한이 있고 혼자서는 외부와 상호작용도 못한다. 이런 한계를 안고서 어떻게 ChatGPT나 Claude Code 같은 제품이 만들어질 수 있었을까? 결국 모든 것은 프롬프트에서 시작한다. LLM에게 전달되는 모든 것은 입력 토큰이다. 도구 정의도 외부 문서도 이전 대화 기록도 모델 입장에서는 전부 프롬프트의 일부다. 이 사실을 알고 나면 AI 에이전트와 관련된 수많은 용어들이 결국 같은 뿌리에서 뻗어나온 가지라는 것을 이해할 수 있다.
좋은 프롬프트에 대한 고민
같은 모델이라도 어떻게 물어보느냐에 따라 결과가 크게 달라진다. 사람들이 이 사실을 깨닫기 시작하면서 API에 보내는 메시지를 잘 작성하는 방법에 대한 연구가 시작되었다.
LLM은 다음에 올 단어를 예측하는 모델이다. 이 말은 곧 입력 텍스트의 문맥이 출력의 방향을 결정한다는 뜻이기도 하다. “한국에 대해 알려줘”라고 보내면 모델은 역사, 문화, 음식, 경제 등 수많은 방향 중 어디로든 갈 수 있다. 다음 토큰의 확률이 여러 후보에 고르게 분산되기 때문이다. 반면 “한국의 수도는”이라고 보내면 다음 토큰이 “서울”일 확률이 압도적으로 높아진다. 문맥이 구체적일수록 모델의 출력이 좁은 범위로 수렴하는 것이다.
이 원리를 활용하는 기법들이 여러 가지 연구되어 왔다. “당신은 10년 경력의 시니어 개발자입니다”처럼 역할을 부여하면 모델이 그 역할에 어울리는 어휘와 깊이로 응답하게 된다. 학습 데이터에서 시니어 개발자가 쓴 글 다음에 나올 법한 텍스트를 생성하기 때문이다. 원하는 출력의 예시를 몇 개 보여주는 Few-Shot 기법은 “이런 패턴으로 답해달라”는 문맥을 만들어주는 것이고 “단계별로 생각해보세요”라는 Chain-of-Thought 기법은 중간 추론 과정을 출력하게 함으로써 최종 답의 정확도를 높이는 방법이다. 복잡한 문제를 한 번에 풀라고 하면 실수가 잦지만 단계를 나눠서 풀게 하면 각 단계의 출력이 다음 단계의 문맥이 되어 더 정확한 결과로 이어진다.
이름이 어려울 뿐 결국 모델에게 보내는 텍스트를 어떻게 구성하면 원하는 방향으로 출력을 유도할 수 있는가에 대한 이야기다. API 호출의 관점에서 보면 messages 배열 안의 content 필드를 어떻게 채울 것인가의 문제다. 이를 어떻게 할까에 대한 공학적 접근을 프롬프트 엔지니어링이라 부른다.
프롬프트를 잘 쓰는 것만으로도 인상적인 결과를 얻을 수 있지만 이것을 실제 제품에 활용하려면 또 다른 문제가 있었다. LLM의 출력이 비결정론적이라는 점이다.
답변에 형식을 입히는 방법
LLM의 출력은 기본적으로 비결정론적이다. “JSON으로 답해줘”라고 프롬프트에 써도 모델은 앞뒤에 설명을 덧붙이거나 잘못된 형식을 출력하기도 했다. 사람이 읽기에는 문제가 없지만 프로그램이 파싱하기에는 치명적이었다. 이 출력에 형식을 입히는 것이 핵심 과제였다.
방법은 다양하게 발전했다. 프롬프트에 원하는 형식을 명시하거나 API 설정으로 JSON 출력을 강제하는 방법이 먼저 나왔고 이후에는 JSON Schema를 지정하면 스키마에 맞는 출력을 보장하는 기능까지 등장했다. 핵심은 모델의 출력을 프로그램이 안정적으로 처리할 수 있는 구조로 만드는 것이었다.
이 아이디어를 더 확장하면 흥미로운 것이 가능해진다. 모델의 출력 형식을 “호출할 함수 이름과 파라미터”로 정하면 어떨까? 예를 들어 사용자가 “서울 날씨 알려줘”라고 물으면 모델이 직접 날씨를 아는 것이 아니라 get_weather(location="서울")이라는 함수 호출을 출력한다. 개발자가 이 함수를 실제로 실행하고 결과를 다시 모델에 넘겨주면 모델이 그 결과를 바탕으로 최종 응답을 생성한다. 이것이 Function Calling이고 지금은 Tool Use라고 부르는 것의 시작이다.
모델에게 사용 가능한 도구 목록을 프롬프트에 넣어주면 모델이 상황에 맞는 도구를 골라 호출하는 구조다. 도구 정의도 결국 프롬프트에 텍스트로 주입되는 것이고 모델은 그 문맥을 읽고 다음 토큰을 예측할 뿐이다. 그 예측이 도구 호출 형식에 맞으면 런타임이 실제로 실행해주는 방식이다.
그런데 도구가 늘어나면서 새로운 문제가 생겼다. LLM 제공사마다 Tool Use의 API 형식이 달랐기 때문에 도구를 하나 만들면 OpenAI용, Anthropic용, Google용으로 각각 어댑터를 작성해야 했다. 이 문제를 해결하기 위해 Anthropic이 2024년 말에 MCP(Model Context Protocol)라는 표준 프로토콜을 공개했다. USB-C가 다양한 기기 연결을 하나의 규격으로 통일한 것처럼 LLM과 외부 도구 사이의 연결을 표준화한 것이다. 이후 OpenAI와 Google 등도 MCP 지원을 발표하면서 사실상 업계 표준으로 자리잡는 흐름이다.
정리하면 “LLM 출력을 믿을 수 없다”에서 시작해서 “형식을 강제하자” → “도구도 호출하게 하자” → “도구 연결을 표준화하자”로 이어지는 자연스러운 흐름이다. 이 모든 것이 프롬프트라는 동일한 메커니즘 위에서 동작한다는 점이 중요하다.
이제 프롬프트를 잘 쓰는 법도 알고 도구도 연결할 수 있게 되었다. 하지만 프롬프트 문구를 조금만 바꿔도 결과가 크게 달라지는 불안정함은 여전했고 모델이 학습하지 않은 정보를 다루는 것도 도구만으로는 충분하지 않았다. 사람들은 점차 프롬프트 자체보다 모델에게 어떤 맥락을 함께 제공하느냐가 결과에 더 큰 영향을 미친다는 사실을 깨닫기 시작했다.
맥락의 중요성을 깨닫다
컨텍스트 엔지니어링은 이런 흐름 속에서 자연스럽게 등장한 개념이다. 안드레이 카파시는 이 개념을 지지하면서 이런 비유를 들었다.
“LLM은 CPU와 같고, 컨텍스트 윈도우는 RAM(작업 메모리)과 같다.”
프롬프트 엔지니어링이 “어떻게 질문할 것인가”에 대한 이야기라면 컨텍스트 엔지니어링은 “모델이 추론을 시작하기 전에 무엇을 보여줄 것인가”에 대한 이야기다. 카파시의 비유를 빌리자면 운영체제가 RAM에 적재할 데이터를 신중하게 골라야 하듯이 개발자는 컨텍스트 윈도우에 채울 정보를 신중하게 골라야 한다.
왜 이것이 프롬프트와 별개의 문제일까? LLM은 입력 텍스트의 문맥을 바탕으로 출력을 생성한다고 했다. 여기서 중요한 것은 입력이 길어질수록 모델이 각 정보에 기울이는 집중력이 떨어진다는 점이다. 사람도 두꺼운 책을 한 번에 읽으면 중간 내용을 놓치기 쉬운 것처럼 LLM도 비슷한 문제를 겪는다. 실제로 긴 입력의 중간에 위치한 정보를 모델이 놓치는 현상이 연구로 확인된 바 있다. 단순히 많이 넣는다고 좋은 것이 아니라 적절한 정보를 적절한 위치에 넣어야 모델이 제대로 활용할 수 있다.
API 호출의 관점에서 보면 messages 배열 전체를 어떻게 구성할 것인가의 문제인데 그 방법은 다양하다.
몇 가지 대표적인 사례를 들어보자.
예를 들어 모델에게 “당신은 코드 리뷰 전문가입니다. 보안 취약점을 우선적으로 확인하세요”와 같은 시스템 프롬프트를 매 요청마다 함께 전달하면 모델이 일관된 역할과 규칙 아래서 응답하게 만들 수 있다. 모델은 상태를 갖지 않기 때문에 이전에 무슨 이야기를 했는지 기억하지 못하는데 이전 대화 기록을 매번 함께 넣어주면 맥락을 유지할 수 있다. ChatGPT에서 이전에 한 말을 기억하는 것처럼 보이는 이유가 바로 이것이다. 매 요청마다 이전 대화 전체가 API에 함께 전달되고 있는 것이다.
프롬프트 자체를 구조화하는 것도 중요한 방법이다. “반드시 한국어로 답하고 200자 이내로 작성해줘. 코드 예시를 포함하되 외부 라이브러리는 사용하지 마”처럼 규칙과 제약 조건을 명시하면 모델의 출력 범위가 좁혀진다. XML 태그나 마크다운 헤더로 입력의 각 부분을 구분해주면 모델이 어떤 정보가 지시이고 어떤 정보가 참고 자료인지 더 잘 구별하게 된다.
이처럼 시스템 프롬프트, 대화 기록, 구조화된 규칙, 도구 정의 등 모델에게 무엇을 보여줄 것인가를 설계하는 것이 컨텍스트 엔지니어링이다. 그 방법에 따라 같은 모델이라도 전혀 다른 수준의 결과가 나온다.
하지만 컨텍스트 엔지니어링에도 한계가 드러났다. 컨텍스트를 아무리 잘 구성해도 모델이 그럴듯하지만 틀린 내용을 생성하는 환각 문제는 사라지지 않았고 정보를 너무 많이 넣으면 오히려 정확도가 떨어지기도 했다. 무엇보다 대화가 길어지거나 작업이 복잡해지면 컨텍스트 윈도우가 부족해지는 문제가 있었다. 하나의 거대한 프롬프트에 모든 것을 담으려는 접근에는 물리적인 한계가 있었던 것이다.
프롬프트를 분할하다
하나의 프롬프트로 모든 것을 해결하기 어렵다면 프롬프트를 나누면 된다. 복잡한 작업을 하나의 거대한 프롬프트로 처리하는 대신 작업을 작은 단위로 나누고 각 단위마다 독립된 프롬프트를 구성하는 방식이다.
예를 들어 “이 코드베이스를 분석하고 버그를 찾아서 수정해줘”라는 요청을 하나의 프롬프트로 처리하려면 코드 전체를 컨텍스트에 넣어야 하고 그러면 윈도우가 부족하거나 집중력이 떨어진다. 대신 “먼저 파일 구조를 파악해줘” → “이 파일에서 버그를 찾아줘” → “찾은 버그를 수정해줘”처럼 단계별로 나누면 각 단계에서는 필요한 정보만 컨텍스트에 넣으면 된다. 이전 단계의 결과를 요약해서 다음 단계의 프롬프트에 포함시키면 맥락도 유지된다.
이 아이디어를 더 발전시키면 작업의 종류에 따라 아예 다른 프롬프트를 미리 준비해둘 수 있다. “코드 리뷰를 할 때는 이 프롬프트를 써라” “테스트를 작성할 때는 이 프롬프트를 써라”처럼 용도별로 프롬프트를 분리해두는 것이다. Claude Code에서는 이것을 스킬(Skill)이라 부르고 다른 도구에서는 커스텀 모드나 페르소나 같은 이름으로 제공한다. 이름은 다르지만 본질은 같다. 상황에 맞는 프롬프트를 골라 쓰는 것이다. 생각해보면 상황에 맞는 스킬을 찾아서 맥락에 넣는 것은 앞서 설명한 도구를 선택하는 것과 크게 다르지 않다.
컨텍스트 윈도우를 효율적으로 관리하는 기법들도 같은 맥락에서 이해할 수 있다. Compaction(압축)은 이전 대화에서 핵심만 남기고 나머지는 요약하는 방법이고 Sub-Agent(서브 에이전트)는 작업을 작은 단위로 나누어 각각 독립된 컨텍스트에서 처리한 뒤 결과만 돌려받는 방법이다. 결국 “하나의 거대한 프롬프트” 대신 “여러 개의 작고 집중된 프롬프트”로 나누어 처리한다는 공통된 원리다.
여기까지 오면 프롬프트를 잘 쓰고 도구를 연결하고 맥락을 설계하고 작업을 분할하는 것까지 할 수 있게 된다. 하지만 여전히 해결되지 않는 문제가 있었다. 모델이 잘못된 방향으로 가고 있을 때 이를 감지하고 바로잡는 것은 프롬프트만으로는 할 수 없다.
하네스를 채우다
프롬프트를 잘 쓰고 도구를 연결하고 맥락을 설계하고 작업을 분할하는 것까지 왔다. 하지만 AI 에이전트가 파일을 수정하고 코드를 실행하고 여러 단계에 걸쳐 작업을 수행하는 시대가 되면서 새로운 문제가 떠올랐다. 모델이 잘못된 코드를 작성했을 때 누가 이를 감지하는가? 도구 호출이 실패했을 때 어떻게 복구하는가? 에이전트가 엉뚱한 방향으로 가고 있을 때 어떻게 바로잡는가?
하네스(Harness)라는 단어는 원래 말에게 씌우는 마구(馬具)를 뜻한다. 말의 힘을 사람이 원하는 방향으로 제어하기 위한 장치다. AI 에이전트에서의 하네스도 비슷하다. 모델이라는 강력한 힘을 안전하고 유용한 방향으로 제어하기 위한 실행 환경 전체를 가리킨다. “Agent = Model + Harness”라는 공식으로 표현하기도 하는데 하네스는 모델 자체를 제외한 모든 것이다. 같은 모델이라도 하네스를 어떻게 채우느냐에 따라 성과가 크게 달라지며 이 분야에서는 “에이전트가 어려운 것이 아니라 하네스가 어렵다”는 말이 나올 정도다.
그렇다면 하네스에는 무엇을 채워야 할까? API 호출의 관점에서 보면 API를 언제 어떤 조건으로 몇 번 호출할 것인가를 제어하는 루프인데 이 루프를 채우는 것들은 크게 두 가지로 나뉜다.
첫 번째는 가이드다. 에이전트가 행동하기 전에 방향을 잡아주는 것이다. 프로젝트의 코딩 컨벤션 문서나 아키텍처 설명을 제공하거나 타입 정의나 API 문서를 참조할 수 있게 해주는 것이 여기에 해당한다. Claude Code에서 CLAUDE.md 파일에 프로젝트 규칙을 적어두는 것이 대표적인 예시다. 마구로 치면 말이 가야 할 방향을 잡아주는 고삐에 가깝다.
두 번째는 센서다. 에이전트가 행동한 후에 결과를 검증하는 것이다. 코드를 작성한 뒤 자동으로 린터를 돌리거나 테스트를 실행해서 문제가 있으면 에이전트에게 다시 알려주는 식이다. 에이전트는 이 피드백을 바탕으로 코드를 수정하고 다시 테스트를 돌린다. 말이 잘못된 길로 가려 할 때 당기는 고삐와 같다. 가이드만 있고 센서가 없으면 에이전트는 규칙은 알지만 자기가 제대로 했는지 확인할 수 없고 센서만 있고 가이드가 없으면 같은 실수를 반복하게 된다.
Anthropic이 장시간 실행 에이전트를 연구하면서 발견한 것도 이 맥락에서 흥미롭다. 에이전트에게 큰 작업을 한 번에 맡기면 컨텍스트가 소진되면서 품질이 떨어진다. 대신 작업을 작은 단위로 나누고 각 단위마다 진행 상황을 파일에 기록하게 한 뒤 새로운 컨텍스트에서 이어서 작업하게 하면 훨씬 안정적인 결과가 나왔다. 이것이 가능한 이유는 하네스가 에이전트의 작업 상태를 외부에서 추적하고 관리하기 때문이다.
이와 관련하여 랄프 루프(Ralph Loop)라는 재미있는 기법도 있다. 심슨 가족의 캐릭터 랄프 위검이 “I’m helping!”을 외치며 끈질기게 나서는 것에서 이름을 따왔는데 에이전트가 작업을 끝냈다고 선언해도 완료 기준을 충족하지 못하면 같은 프롬프트를 다시 주입해서 계속 반복시키는 방식이다. 진행 상황은 컨텍스트 윈도우가 아니라 파일 시스템과 git 히스토리에 저장되기 때문에 매 반복마다 새로운 컨텍스트로 시작해도 이전 작업을 이어갈 수 있다. 멍청할 정도로 끈질기게 반복하면 결국 성공한다는 철학인데 실제로 놀라운 결과를 보여주면서 화제가 되기도 했다.
참고로 랄프 루프가 화제가 되면서 하네스와 랄프 루프를 동일시하는 경우도 생겼는데 이 둘은 같은 것이 아니다. 하네스는 모델을 둘러싼 실행 환경 전체를 설계하는 넓은 개념이고 랄프 루프는 그 안에서 사용할 수 있는 하나의 반복 패턴에 가깝다. 가이드와 센서를 갖추고 도구를 연결하고 상태를 관리하는 것이 하네스이고 랄프 루프는 그런 하네스 위에서 돌아가는 전략 중 하나다.
이러한 하네스를 잘 설계하는 것을 하네스 엔지니어링이라 부른다. 물론 한계는 있다. 각 단계의 성공률이 95%라고 해도 20단계를 거치면 전체 성공률은 36%로 떨어진다. 에이전트에게는 사람이 가진 직관이나 조직의 암묵적 지식이 없기 때문에 하네스로 보완해야 하는데 그 하네스 자체가 복잡해지면 관리가 어려워지는 딜레마도 있다.
그래서 결국 중요한 것은
여기까지 읽으면서 눈치챈 사람도 있겠지만 지금까지 이야기한 모든 것에는 하나의 공통점이 있다. 프롬프트를 잘 쓰는 것도 출력에 형식을 입히는 것도 맥락을 설계하는 것도 작업을 분할하는 것도 하네스를 채우는 것도 결국 API에 프롬프트를 전달하고 응답을 받는 과정을 잘하기 위한 방법이라는 점이다.
본질은 API 호출이다. 용어가 다르고 범위가 다르고 접근하는 층위가 다를 뿐 모두 같은 뿌리에서 뻗어나온 가지다. 이것은 Claude Code나 ChatGPT 같은 AI 에이전트를 사용하는 사람에게도 직접 에이전트를 만드는 개발자에게도 동일하게 적용된다. 어떤 도구를 쓰든 결국 하고 있는 일은 모델에게 적절한 입력을 구성해서 보내고 응답을 받아 처리하는 것이다.
우리는 무엇을 해야하는가
여기까지 읽은 사람 중에 내용을 완전히 이해한 사람도 있을 것이고 여전히 막연한 사람도 있을 것이다. 어느 쪽이든 괜찮다. 다만 내용을 이해했더라도 여전히 두려울 수 있다. 정체를 알았는데도 불안이 남는다면 그것은 AI 자체에 대한 공포가 아니라 “그래서 나는 어떻게 행동해야 하는가”를 모르기 때문일 가능성이 높다.
솔직히 말하면 꼭 무언가를 해야 할 필요는 없다. 그냥 지금 하던 대로 인생을 살면 된다. AI가 궁금하다면 소식을 따라가면서 그 본질이 무엇인지 이해하면 되고 업무에 AI가 필요해지면 그때 이용하면 된다. 결국 도구일 뿐이다. 필요하면 쓰고 필요 없으면 안 쓰면 그만이다. 망치가 발명됐다고 해서 모든 사람이 망치를 들어야 하는 것은 아니지 않은가.
그래도 뭔가 해보고 싶다면 ChatGPT나 Claude에 아무거나 물어보는 것부터 시작해도 좋다. 프롬프트를 이렇게 저렇게 바꿔가면서 결과가 달라지는 것을 직접 체험해보면 이 글에서 설명한 것들이 머리가 아닌 몸으로 이해되기 시작한다. 거기서 한 걸음 더 나아가고 싶다면 간단한 에이전트를 직접 만들어보는 것도 추천한다. API 키를 발급받고 프롬프트를 구성해서 호출하고 응답을 받아보는 경험은 이 글에서 이야기한 모든 개념을 한 번에 체감하게 해준다. 필자도 이전에 에이전트를 만드는 방법에 대해 쓴 적이 있으니 관심이 있다면 참고해도 좋겠다.
중요한 것은 FOMO에 휘둘리지 않는 것이다. 주변이 아무리 소란스러워도 자기 속도로 이해하고 자기 필요에 따라 판단하면 된다. AI를 완벽하게 마스터하지 못했다고 해서 뒤처지는 것이 아니다. 정체를 알고 있다는 것만으로도 이미 대부분의 사람보다 앞서 있다.
그리고 앞으로도 새로운 용어는 계속 나올 것이다. 하지만 이 글에서 다룬 구조를 이해하고 있다면 새로운 용어가 등장해도 “이건 프롬프트를 잘 쓰는 이야기인가, 맥락을 설계하는 이야기인가, 하네스를 채우는 이야기인가”하고 자리를 잡아줄 수 있다. 용어에 휘둘리는 대신 본질을 보는 눈이 생기는 것이다.
마치며
이 글에서 이야기하고 싶었던 것은 하나다. LLM과 에이전트는 API 호출을 기반으로 동작하고 우리를 괴롭히는 수많은 ‘엔지니어링’은 그 API 호출을 잘 하기 위한 다양한 관점에 불과하다. 이 구조를 이해하고 나면 새로운 용어가 등장하더라도 “이건 API 호출의 이 부분을 다루는 이야기구나”하고 나름의 자리를 잡아줄 수 있게 된다. 미지의 공포가 아니라 이해 가능한 기술이 되는 것이다.
물론 이것만으로 모든 불안이 사라지지는 않을 것이다. AI가 우리의 직업을 어떻게 바꿀지 5년 후 개발자의 역할이 어떻게 달라질지는 솔직히 아무도 모른다. 하지만 정체를 아는 것과 정체를 모르는 것 사이에는 큰 차이가 있다. 공포의 안개 속을 헤매는 것과 안개가 걷힌 뒤 앞에 놓인 길을 바라보는 것은 같은 상황이 아니다.
그래도 여전히 두렵다면 필자의 여자친구가 해준 이야기를 나누고 싶다. “세상이 우리 모르게 훌쩍 떠나버리는 것처럼 보이지만 우리도 세상의 일부니까 분명 같이 데려가줄 거야.” 세상이 아무리 빠르게 변해도 우리는 그 세상 밖에 서 있는 것이 아니다. 변화의 한복판에 이미 함께 서 있다.