최근 들어 AI 코딩 에이전트를 사용하지 않는 개발자는 거의 찾아보기 어려울 정도로 AI가 개발자들의 일상에 깊숙이 들어왔다. 다만, 이전에는 도움이 된다 정도였다면 지금은 자신의 전문성이 대체된 것 같아 불안하다는 이야기를 심심치 않게 들을 수 있다. 이런 상황은 안드레이 카파시가 바이브 코딩이라는 용어를 소개한 지 불과 1년 만에 벌어진 일이다.

최근 이 불안에는 이름까지 붙었다. 『Claude Blue - 실리콘밸리 전체가 우울하다』에서 처음 사용된 표현으로 클로드 블루는 AI의 급속한 발전으로 전문성과 경력이 빠르게 대체되는 데서 오는 심리적 우울감을 뜻한다. 기술이 급격히 발전할 때마다 사람들이 불안을 느끼는 것은 어제 오늘 일이 아니지만 이번에는 양상이 좀 다르다. ‘지능’이라는 인간의 고유 영역을 너무나도 급격하게 침범하는 AI에 대한 공포는 이전과는 차원이 다르다.

게다가 용어의 범람도 심각하다. 바이브 코딩, 프롬프트 엔지니어링, 컨텍스트 엔지니어링, 하네스 엔지니어링 등 매일같이 새로운 ‘엔지니어링’이 등장하고 그때마다 뒤쳐지는 듯한 압박이 밀려온다. 조사에 따르면 직장인의 24%가 AI로 인한 정보 과부하 때문에 정신 건강이 악화됐다고 응답했을 정도다.

공포를 극복하는 법

사람은 이해할 수 없는 것 앞에서 공포를 느낀다. 동굴 속에서 정체를 알 수 없는 소리가 들려올 때 우리 조상들이 취할 수 있는 최선의 전략은 도망치는 것이었다. 생존을 위한 합리적인 본능이었지만 현대 사회에서는 이 본능이 역효과를 내는 경우가 많다.

AI가 만들어내는 공포도 같은 구조다. 정체를 알 수 없는 무언가가 엄청난 속도로 발전하고 있고 매일같이 새로운 용어가 쏟아지는데 주변 사람들은 모두 잘 적응하고 있는 것처럼 보인다. 이런 압도감 앞에서 이성적인 판단을 유지하기란 쉽지 않다. 실제로 개발자들 사이에서 치료 상담 사례가 증가하고 있고 수면 장애나 사회적 위축 같은 증상을 호소하는 경우도 늘어나고 있다.

어려운 상황이지만 공포를 극복하는 방법이 하나 있다. 공포를 직접 마주하고 그 정체를 이해하는 것이다. 어둠 속 정체 모를 소리가 무서운 이유는 정체를 모르기 때문이다. 소리의 원인이 바람에 흔들리는 나뭇가지라는 것을 알게 되면 공포는 사라진다. 공포란 대상 자체가 아니라 대상에 대한 무지에서 오는 것이기 때문이다.

당사자는 무섭지만 보고 있는 우리는 웃기다
당사자는 무섭지만 보고 있는 우리는 웃기다

물론 소리의 정체가 항상 나뭇가지인 것은 아니다. 실제로 위험한 동물일 수도 있다. 하지만 그 동물이 무엇인지 알고 있다면 이야기가 달라진다. 곰인지 뱀인지 알면 도망칠지 가만히 있을지 판단할 수 있고 미리 대비할 수도 있다. 정체를 모를 때는 모든 가능성이 위협이지만 정체를 알면 위협의 범위가 명확해지고 그제서야 대응이 가능해진다.

AI에 대한 공포도 다르지 않다. 우리가 두려워하는 것은 AI 그 자체라기보다 AI가 어떻게 동작하는지 모른다는 사실에 가깝다. 무엇인지 모르니까 그것이 할 수 있는 일과 할 수 없는 일의 경계도 보이지 않고 그래서 모든 가능성이 위협으로 느껴진다. 하지만 정체를 이해하고 나면 마법처럼 보이던 것이 기술로 보이기 시작한다. 기술이란 배울 수 있는 것이고 한계가 있는 것이다.

LLM의 정체

간단히 말하자면 LLM은 다음에 올 단어를 예측하는 모델이다. 엄청나게 많은 텍스트를 학습해서 “이 문맥에서 다음에 올 가능성이 가장 높은 단어는 무엇인가”를 계산한다. ChatGPT든 Claude든 Gemini든 핵심 동작 원리는 동일하다. 입력된 텍스트를 바탕으로 다음 토큰을 하나씩 생성해 나간다.

다음 단어를 예측하는 것치고는 너무 똑똑하지 않느냐는 의문이 들 수 있다. 충분한 규모의 데이터와 파라미터로 학습된 모델은 단순한 단어 예측을 넘어 추론이나 번역, 코드 작성까지 해낸다. 하지만 그 모든 능력의 근간에는 여전히 주어진 입력에 대해 가장 적절한 출력을 생성한다는 하나의 원리가 놓여 있다.

그렇다면 우리가 사용하는 LLM 서비스는 이 모델을 어떻게 사용하는 것일까? 겉으로 보기에는 복잡해 보이지만 실제로는 굉장히 단순하다. 그 정체는 바로 HTTP API 호출이다. 모든 LLM 서비스는 같은 패턴으로 동작한다. 클라이언트가 대화 내용을 담은 메시지를 API 서버로 보내면 서버 뒤의 모델이 다음 토큰을 생성하고 그 결과를 스트리밍으로 돌려준다. 우리가 ChatGPT에서 글자가 한 글자씩 나타나는 것을 볼 때 실제로 벌어지고 있는 일이 바로 이것이다.

LLM 서비스의 요청-응답 구조

AI 에이전트의 강력한 코딩 능력도 이 API 호출을 감싸고 있는 것에 불과하다. 메시지를 구성하고 API를 호출하고 응답을 받아 처리한다 이것이 모든 LLM 애플리케이션의 기본 골격이다.

AI 에이전트는 어떻게 똑똑해졌는가

LLM은 강력하지만 분명한 한계가 있다. 모델은 상태를 갖지 않아서 대화를 “기억”하려면 매번 이전 대화 전체를 다시 입력해야 한다. 입력할 수 있는 텍스트 길이에도 제한이 있다. 학습 이후의 정보는 알지 못하고 그럴듯하지만 틀린 내용을 생성하기도 한다. 혼자서는 파일을 읽거나 코드를 실행하는 것도 불가능하다.

이런 한계를 극복하기 위한 것이 AI 에이전트다. 프롬프트 자체를 잘 쓰는 것, 응답을 이용하여 다시 프롬프트를 구성하는 것, LLM이 모르는 지식을 채워주는 등 모든 것은 AI 에이전트가 LLM을 활용하는 방법에 대한 이야기다. 이것이 바로 우리를 괴롭히던 수많은 ‘엔지니어링’이다.

지금부터 LLM을 잘 다루기 위한 방법들이 어떻게 발전해왔는지 시간순으로 살펴보면서 그 공통된 구조를 이해해보자.

좋은 프롬프트에 대한 고민

같은 모델이라도 어떻게 물어보느냐에 따라 결과가 크게 달라진다. 이 사실을 깨닫기 시작하면서 LLM에 보내는 프롬프트를 잘 작성하는 방법에 대한 연구가 시작되었다. 이것을 프롬프트 엔지니어링이라고 부른다.

기본적으로 LLM은 다음에 올 단어를 예측하는 모델이다. 이 말은 곧 입력 텍스트의 문맥이 출력의 방향을 결정한다는 뜻이기도 하다. “한국에 대해 알려줘”라고 보내면 모델은 역사, 문화, 음식, 경제 등 수많은 방향 중 어디로든 갈 수 있다. 다음 토큰의 확률이 여러 후보에 고르게 분산되기 때문이다. 반면 “한국의 수도는”이라고 보내면 다음 토큰이 “서울”일 확률이 압도적으로 높아진다. 문맥이 구체적일수록 모델의 출력이 좁은 범위로 수렴하는 것이다.

이 원리를 활용하는 기법들이 여러 가지 연구되어 왔다. “당신은 10년 경력의 시니어 개발자입니다”처럼 역할을 부여하면 모델이 그 역할에 어울리는 어휘와 깊이로 응답하게 된다. 학습 데이터에서 시니어 개발자가 쓴 글 다음에 나올 법한 텍스트를 생성하기 때문이다. 원하는 출력의 예시를 몇 개 보여주는 Few-Shot 기법은 “이런 패턴으로 답해달라”는 문맥을 만들어주는 것이고 “단계별로 생각해보세요”라는 Chain-of-Thought 기법은 중간 추론 과정을 출력하게 함으로써 최종 답의 정확도를 높이는 방법이다. 복잡한 문제를 한 번에 풀라고 하면 실수가 잦지만 단계를 나눠서 풀게 하면 각 단계의 출력이 다음 단계의 문맥이 되어 더 정확한 결과로 이어진다.

프롬프트 기법에 따라 입력의 구성이 달라진다

이름이 어려울 뿐 결국 모델에게 보내는 텍스트를 어떻게 구성하면 원하는 방향으로 출력을 유도할 수 있는가에 대한 이야기다. 프롬프트를 잘 쓰는 것만으로도 인상적인 결과를 얻을 수 있긴 하지만 이것을 실제 제품에 활용하려면 또 다른 문제가 있었다. LLM의 출력이 비결정론적이라는 점이다.

응답에 형식을 입히는 방법

LLM의 출력은 기본적으로 비결정론적이다. “JSON으로 답해줘”라고 프롬프트에 써도 모델은 앞뒤에 설명을 덧붙이거나 잘못된 형식을 출력하기도 했다. 사람이 읽기에는 문제가 없지만 프로그램이 파싱하기에는 치명적이기에 출력에 형식을 입히는 것이 핵심 과제였다.

방법은 다양하게 발전했다. 프롬프트에 원하는 형식을 명시하거나 API 설정으로 JSON 출력을 강제하는 방법이 먼저 나왔고 이후에는 JSON Schema를 지정하면 스키마에 맞는 출력을 보장하는 기능까지 등장했다. 핵심은 모델의 출력을 프로그램이 안정적으로 처리할 수 있는 구조로 만드는 것이었다.

이 아이디어를 더 확장하면 흥미로운 것이 가능해진다. 모델의 출력 형식을 “호출할 함수 이름과 파라미터”로 정하면 어떨까? 예를 들어 사용자가 “서울 날씨 알려줘”라고 물으면 모델이 직접 날씨를 아는 것이 아니라 get_weather(location="서울")이라는 함수 호출을 출력한다. 개발자가 이 함수를 실제로 실행하고 결과를 다시 모델에 넘겨주면 모델이 그 결과를 바탕으로 최종 응답을 생성한다. 이것을 Function Calling이라고 부른다.

모델은 함수 호출을 출력할 뿐이고 실제 실행은 런타임이 담당한다

모델에게 사용 가능한 도구 목록을 프롬프트에 넣어주면 모델이 상황에 맞는 도구를 골라 호출하는 구조다. 도구 정의도 결국 프롬프트에 텍스트로 주입되는 것이고 모델은 그 문맥을 읽고 다음 토큰을 예측할 뿐이다. 그 예측이 도구 호출 형식에 맞으면 런타임이 실제로 실행해주는 방식이다.

이때부터 AI 에이전트가 본격적으로 똑똑해지기 시작했다. 학습되지 않은 정보를 다루는 방법이 생겼고 모델이 직접 할 수 없는 일을 도구로 연결해서 해결할 수 있게 되었다. MCP, RAG 등 외부 지식과 연결하는 방법도 도구 호출의 한 형태로 볼 수 있다.

이제 프롬프트를 잘 쓰는 법도 알고 도구도 연결할 수 있게 되었다. 하지만 프롬프트 문구를 조금만 바꿔도 결과가 크게 달라지는 불안정함은 여전했고 모델이 학습하지 않은 정보를 다루는 것도 도구만으로는 충분하지 않았다. 사람들은 점차 프롬프트 자체보다 모델에게 어떤 맥락을 함께 제공하느냐가 결과에 더 큰 영향을 미친다는 사실을 깨닫기 시작했다.

맥락의 중요성을 깨닫다

컨텍스트 엔지니어링은 이런 흐름 속에서 자연스럽게 등장한 개념이다. 프롬프트 엔지니어링이 “어떻게 질문할 것인가”에 대한 이야기라면 컨텍스트 엔지니어링은 “모델이 추론을 시작하기 전에 무엇을 보여줄 것인가”에 대한 이야기다.

왜 이것이 프롬프트와 별개의 문제일까? LLM은 입력 텍스트의 문맥을 바탕으로 출력을 생성한다. 여기서 중요한 것은 입력이 길어질수록 모델이 각 정보에 기울이는 집중력이 떨어진다는 점이다. 사람도 두꺼운 책을 한 번에 읽으면 중간 내용을 놓치기 쉬운 것처럼 LLM도 비슷한 문제를 겪는다. 실제로 긴 입력의 중간에 위치한 정보를 모델이 놓치는 현상이 연구로 확인된 바 있다. 단순히 많이 넣는다고 좋은 것이 아니라 적절한 정보를 적절한 위치에 넣어야 모델이 제대로 활용할 수 있다.

컨텍스트 윈도우 안에 무엇을 넣을 것인가가 핵심이다

컨텍스트는 다양하게 설계할 수 있다. 대화 기록을 그대로 넣을 수도 있지만, 중요한 정보만 요약해서 넣을 수도 있고 모델이 참고해야 할 규칙이나 가이드라인을 구조화된 형태로 넣을 수도 있다. 도구가 필요한 작업이라면 도구의 정의와 사용법을 컨텍스트에 넣어주는 것도 중요하다.

이처럼 시스템 프롬프트, 대화 기록, 구조화된 규칙, 도구 정의 등 모델에게 무엇을 보여줄 것인가를 설계하는 것이 컨텍스트 엔지니어링이다. 그 방법에 따라 같은 모델이라도 전혀 다른 수준의 결과가 나온다.

하지만 컨텍스트 엔지니어링에도 한계가 있다. 컨텍스트를 아무리 잘 구성해도 모델이 그럴듯하지만 틀린 내용을 생성하는 환각 문제는 사라지지 않았고 정보를 너무 많이 넣으면 오히려 정확도가 떨어지기도 했다. 무엇보다 대화가 길어지거나 작업이 복잡해지면 컨텍스트 윈도우가 부족해지는 문제가 있었다. 하나의 거대한 프롬프트에 모든 것을 담으려는 접근에는 물리적인 한계가 있었던 것이다.

프롬프트를 분할하다

하나의 프롬프트로 모든 것을 해결하기 어렵다면 프롬프트를 나누면 된다. 복잡한 작업을 하나의 거대한 프롬프트로 처리하는 대신 작업을 작은 단위로 나눈 프롬프트를 조합하는 방식이다. 예를 들어, 코드 리뷰를 할 때 사용하는 프롬프트, 테스트를 작성할 때 사용하는 프롬프트를 따로 준비하여 필요할 때 사용하는 것이다.

이 아이디어를 더 발전시키면 Function Calling처럼 모델이 상황에 맞는 프롬프트를 선택해서 사용할 수 있게 할 수도 있다. 현재는 이를 보편적으로 스킬(Skill)이라고 부른다.

상황에 맞는 스킬을 골라 컨텍스트에 넣는다

컨텍스트 윈도우를 효율적으로 관리하는 기법들도 같은 맥락에서 이해할 수 있다. Compaction(압축)은 이전 대화에서 핵심만 남기고 나머지는 요약하는 방법이고 Sub-Agent(서브 에이전트)는 작업을 작은 단위로 나누어 각각 독립된 컨텍스트에서 처리한 뒤 결과만 돌려받는 방법이다. 결국 “하나의 거대한 프롬프트” 대신 “여러 개의 작고 집중된 프롬프트”로 나누어 처리한다는 공통된 원리다.

이렇게 프롬프트를 잘 쓰고 도구를 연결하고 맥락을 설계하고 작업을 분할하는 것까지 할 수 있게 된다. 하지만 여전히 해결되지 않는 문제가 있었다. 모델이 잘못된 방향으로 가고 있을 때 이를 감지하고 바로잡는 것은 프롬프트만으로는 할 수 없다.

하네스를 채우다

프롬프트를 잘 쓰고 도구를 연결하고 맥락을 설계하고 작업을 분할하는 것까지 왔다. 하지만 AI 에이전트가 파일을 수정하고 코드를 실행하고 여러 단계에 걸쳐 작업을 수행하는 시대가 되면서 새로운 문제가 떠올랐다. 모델이 잘못된 코드를 작성했을 때 누가 이를 감지하는가? 도구 호출이 실패했을 때 어떻게 복구하는가? 에이전트가 엉뚱한 방향으로 가고 있을 때 어떻게 바로잡는가?

하네스(Harness)라는 단어는 원래 말에게 씌우는 마구(馬具)를 뜻한다. 말의 힘을 사람이 원하는 방향으로 제어하기 위한 장치다. AI 에이전트에서의 하네스도 비슷하다. 모델이라는 힘을 안전하고 유용한 방향으로 제어하기 위한 실행 환경 전체를 가리킨다. “Agent = Model + Harness”라는 공식으로 표현하기도 하는데 하네스는 모델 자체를 제외한 모든 것이다.

그렇다면 하네스에는 무엇을 채워야 할까? API 호출의 관점에서 보면 API를 언제 어떤 조건으로 몇 번 호출할 것인가를 제어하는 루프인데 이 루프를 채우는 것들은 크게 두 가지로 나뉜다.

첫 번째는 가이드다. 에이전트가 행동하기 전에 방향을 잡아주는 것이다. 프로젝트의 코딩 컨벤션 문서나 아키텍처 설명을 제공하거나 타입 정의나 API 문서를 참조할 수 있게 해주는 것이 여기에 해당한다. 시스템 프롬프트나 CLAUDE.md 같은 파일에 프로젝트 규칙을 적어두는 것이 대표적인 예시다. 마구로 치면 말이 가야 할 방향을 잡아주는 고삐에 가깝다.

두 번째는 센서다. 에이전트가 행동한 후에 결과를 검증하는 것이다. 코드를 작성한 뒤 자동으로 린터를 돌리거나 테스트를 실행해서 문제가 있으면 에이전트에게 다시 알려주는 식이다. 에이전트는 이 피드백을 바탕으로 코드를 수정하고 다시 테스트를 돌린다. 말이 잘못된 길로 가려 할 때 당기는 고삐와 같다. 가이드만 있고 센서가 없으면 에이전트는 규칙은 알지만 자기가 제대로 했는지 확인할 수 없고 센서만 있고 가이드가 없으면 같은 실수를 반복하게 된다.

하네스는 가이드와 센서로 모델의 행동을 제어한다

이와 관련하여 랄프 루프(Ralph Loop)라는 재미있는 기법도 있다. 심슨 가족의 캐릭터 랄프 위검1에서 이름을 따왔는데 에이전트가 작업을 끝냈다고 선언해도 완료 기준을 충족하지 못하면 같은 프롬프트를 다시 주입해서 계속 반복시키는 방식이다. 진행 상황은 컨텍스트 윈도우가 아니라 파일 시스템과 git 히스토리에 저장되기 때문에 매 반복마다 새로운 컨텍스트로 시작해도 이전 작업을 이어갈 수 있다. 멍청할 정도로 끈질기게 반복하면 결국 성공한다는 철학인데 실제로 놀라운 결과를 보여주면서 화제가 되기도 했다.

완료 기준을 충족할 때까지 같은 프롬프트를 반복 주입한다

참고로 랄프 루프가 화제가 되면서 하네스와 랄프 루프를 동일시하는 경우도 생겼는데 이 둘은 같은 것이 아니다. 하네스는 모델을 둘러싼 실행 환경 전체를 설계하는 넓은 개념이고 랄프 루프는 그 안에서 사용할 수 있는 하나의 반복 패턴에 가깝다. 가이드와 센서를 갖추고 도구를 연결하고 상태를 관리하는 것이 하네스이고 랄프 루프는 그런 하네스 위에서 돌아가는 전략 중 하나다.

이러한 하네스를 잘 설계하는 것을 하네스 엔지니어링이라 부른다. 물론 한계는 있다. 에이전트에게는 사람이 가진 직관이나 조직의 암묵적 지식이 없기 때문에 하네스로 보완해야 하는데 그 하네스 자체가 복잡해지면 관리가 어려워지는 딜레마도 있다.

그래서 결국 중요한 것은

여기까지 읽으면서 눈치챈 사람도 있겠지만 지금까지 이야기한 모든 것에는 하나의 공통점이 있다. 프롬프트를 잘 쓰는 것도 출력에 형식을 입히는 것도 맥락을 설계하는 것도 작업을 분할하는 것도 하네스를 채우는 것도 결국 LLM API에 프롬프트를 전달하고 응답을 받는 과정을 잘하기 위한 방법이라는 점이다.

그런데 생각해보면 이것은 우리가 이미 잘해왔던 일이다. 개발자라면 외부 API를 호출하고 응답을 파싱하고 에러를 처리하고 결과를 가공해서 사용자에게 보여주는 것은 수도 없이 해왔을 것이다. LLM 위에서 벌어지는 모든 일도 이 익숙한 패턴 위에 놓여 있다. 결코 어려운 것이 아니다.

이것은 AI 에이전트를 사용하는 사람에게도 직접 에이전트를 만드는 개발자에게도 동일하게 적용된다. 어떤 도구를 쓰든 결국 하고 있는 일은 모델에게 적절한 입력을 구성해서 보내고 응답을 받아 처리하는 것이다.

FOMO에서 벗어나기

여기까지 읽었다면 LLM과 AI 에이전트가 어떻게 동작하는지 어느 정도 감이 잡혔을 것이다. 하지만 그럼에도 불구하고 여전히 불안할 수 있다. 왜 그럴까?

우리 주변에는 FOMO를 유발하는 사람들이 있기 때문이다. “이걸 안 배우면 뒤처진다”고 겁을 주고 매일 세상이 뒤집힌 것처럼 이야기하는 콘텐츠, 새로운 도구가 나올 때마다 “게임 체인저”라고 외치고 어제 배운 것이 오늘 쓸모없어진 것처럼 말하는 콘텐츠를 계속 접하다 보면 우리는 마치 아무것도 모르는 것처럼 느끼거나 사용하고 있더라도 제대로 사용하지 못하고 있는 것처럼 느끼게 된다.

FOMO를 느끼지 않는 좋은 방법 하나는 FOMO 유발자들이 실제로 AI를 이용해서 무엇을 해결했는지를 살펴보는 것이다. 대부분은 “AI로 이걸 10분 만에 만들었다”류의 이야기다. 하지만 빠르게 무언가를 만드는 것은 문제를 해결한 것이 아니라 과정을 압축한 것에 불과하다. 일을 했다는 것은 “무엇을 했는가”이지 “얼마나 빨리 했는가”가 아니다. 속도에 현혹되어 정작 중요한 질문을 놓치지 않도록 주의할 필요가 있다.

그렇기 때문에 우리가 올바른 정보를 수용하는 능력을 기르는 것이 더 중요하다. 이 글에서 LLM의 동작 원리와 AI 에이전트의 구조를 이야기한 것도 그런 맥락이다. 본질을 이해하고 있으면 새로운 정보를 접했을 때 침착하게 자신의 지식에 대입해볼 수 있다. 이것이 정말 새로운 패러다임인지 아니면 기존 개념의 변형인지, 나에게 필요한 정보인지 아닌지, 사실인지 과장인지를 스스로 판단할 수 있게 된다.

우리는 무엇을 해야하는가

여기까지 읽은 사람 중에 내용을 완전히 이해한 사람도 있을 것이고 여전히 막연한 사람도 있을 것이다. 어느 쪽이든 괜찮다. 다만 내용을 이해했더라도 여전히 두려울 수 있다. 정체를 알았는데도 불안이 남는다면 그것은 AI 자체에 대한 공포가 아니라 “그래서 나는 어떻게 행동해야 하는가”를 모르기 때문일 가능성이 높다.

솔직히 말하면 꼭 무언가를 해야 할 필요는 없다. 정말 중요한 것은 문제 해결 관점이다. AI가 내 문제에 도움되지 않는다면 그냥 지금 하던 대로 인생을 살면 된다. AI가 궁금하다면 소식을 따라가면서 그 본질이 무엇인지 이해하면 되고 업무에 AI가 필요해지면 그때 이용하면 된다. 결국 도구일 뿐이다. 필요하면 쓰고 필요 없으면 안 쓰면 그만이다. 망치가 발명됐다고 해서 모든 사람이 망치를 들어야 하는 것은 아니지 않은가.

게다가 AI에 대한 기대치도 사람마다 다르다. 가벼운 개인용 도구를 만들어보는 것만으로 신기해하는 사람도 있고 코드를 대신 짜주는 것에 만족하는 사람도 있고 엔터프라이즈 환경에서는 아직 부족하다고 느끼는 사람도 있다. 어느 쪽이든 자기 기대치에 맞게 판단하면 된다.

그래도 뭔가 해보고 싶다면 ChatGPT나 Claude에 아무거나 물어보는 것부터 시작해도 좋다. 프롬프트를 이렇게 저렇게 바꿔가면서 결과가 달라지는 것을 직접 체험해보면 이 글에서 설명한 것들이 머리가 아닌 몸으로 이해되기 시작한다. 거기서 한 걸음 더 나아가고 싶다면 간단한 에이전트를 직접 만들어보는 것도 추천한다. API 키를 발급받고 프롬프트를 구성해서 호출하고 응답을 받아보는 경험은 이 글에서 이야기한 모든 개념을 한 번에 체감하게 해준다. 필자도 이전에 에이전트를 만드는 방법에 대해 쓴 적이 있으니 관심이 있다면 참고해도 좋겠다.

앞으로도 새로운 용어는 계속 나올 것이다. 하지만 이 글에서 다룬 구조를 이해하고 있다면 새로운 용어가 등장해도 “이건 프롬프트를 잘 쓰는 이야기인가, 맥락을 설계하는 이야기인가, 하네스를 채우는 이야기인가”하고 자리를 잡아줄 수 있다. 용어에 휘둘리는 대신 본질을 보는 눈이 생기는 것이다.

마치며

물론 이것만으로 모든 불안이 사라지지는 않을 것이다. AI가 우리의 직업을 어떻게 바꿀지 5년 후 개발자의 역할이 어떻게 달라질지는 솔직히 아무도 모른다. 하지만 정체를 아는 것과 정체를 모르는 것 사이에는 큰 차이가 있다. 공포의 안개 속을 헤매는 것과 안개가 걷힌 뒤 앞에 놓인 길을 바라보는 것은 같은 상황이 아니다.

그래도 여전히 두려울 수 있다. 필자 또한 AI라는 축제 속에 소외된 것처럼 느껴졌고 수년간 쌓아온 전문성이 무너진 것 같아 우울이 찾아왔을 때가 있었다. 이 때 필자의 여자친구가 해준 이야기가 있다. “세상이 우리 모르게 훌쩍 떠나버리는 것처럼 보이지만 우리도 세상의 일부니까 분명 같이 데려가줄 거야.” 세상이 아무리 빠르게 변해도 우리는 그 세상 밖에 서 있는 것이 아니다. 변화의 한복판에 이미 함께 서 있다.

  1. 랄프 위검(Ralph Wiggum)은 심슨 가족의 캐릭터로 멍청한 아이로 묘사된다.