
필자는 ChatGPT가 등장한 이후 좋은 기회를 얻어 『소프트웨어 개발에 ChatGPT 사용하기』(제이펍, 2024), 『프롬프트 엔지니어링의 비밀』(길벗, 2024), 『7가지 프로젝트로 배우는 LLM AI 에이전트 개발』(제이펍, 2025)과 같은 책을 번역하거나 집필할 수 있었다. 그러다 보니 초기의 다소 서툴렀던 모델부터 지금의 놀라울 정도로 고도화된 모델까지 생성형 AI가 변화하는 과정을 비교적 가까운 곳에서 계속 지켜보며 함께 사용해 왔다. 코딩, 프로젝트 생성 및 관리뿐만 아니라 이해 방식을 함께 해 왔다고 말해도 좋겠다.
따라서 이 글은 AI를 처음 만져본 사람이 새로운 기술을 경험하고 느낀 소감이라기보다는 AI와 오랫동안 함께 지내온 사람으로서 그동안의 나날을 한 번 갈무리해 보는 글에 가깝다.
요즘 개발에서 AI를 사용하는 방법에 대한 이야기를 보면 프롬프트 엔지니어링이나 하네스(Harness)에 관한 이야기가 많다.
이 글에서 말하는 하네스는 AI가 프로젝트 안에서 작업할 때 따라야 할 규칙과 맥락, 도구 사용 방식 등을 미리 정의해 두는 장치를 의미하는데, 이 안에 프로젝트의 구조와 코딩 규칙을 정의하고 AI가 해야 할 일과 하지 말아야 할 일을 명시한다. 잘 만들어진 규칙 파일을 제공해 가능한 한 적은 시행착오로 원하는 결과물을 만들어내도록 하는 것이 목적이다.
이러한 방식은 분명 좋은 방법이다. 특히 새로운 프로젝트를 시작할 때는 매우 강력하다. 필자는 이것을 0에서 0.1을 만드는 방법이라고 생각한다. 그런데 이미 만들어진 프로젝트를 0.1에서 1.0으로 발전시키는 과정에서도 이것이 항상 가장 좋은 방법일까? 최근에는 조금 다르게 생각하고 있다.
프롬프트 엔지니어링은 맥락을 압축하는 기술이었다
생성형 AI를 처음 등장했을 때는 대화를 시작할 때마다 AI 모델에게 필요한 정보를 다시 알려주어야 했다. 어떤 프로젝트를 만들고 있는지, 어떤 언어와 프레임워크를 사용하는지, 코딩 규칙은 무엇인지, 이전에 어떤 결정을 내렸는지 AI는 알지 못했다. 좋은 결과를 얻으려면 프로젝트 이해 과정에 필요한 많은 정보를 하나의 프롬프트에 가능한 한 효율적으로 담아야 했다.
그런 관점에서 보면 프롬프트 엔지니어링은 단순히 AI에게 명령을 잘하는 기술이 아니라 AI가 작업을 수행하는 데 필요한 맥락(Context)을 가능한 한 짧고 정확하게 압축해서 전달하는 기술이라고 볼 수 있다.
하네스는 여기에서 한 단계 더 나아간다. 반복적으로 필요한 맥락과 규칙을 파일로 만들어 프로젝트에 고정한다. 새로운 세션을 시작하거나 다른 AI 에이전트가 작업하더라도 동일한 규칙을 적용할 수 있다.
이 방식은 새로운 프로젝트를 만드는 데 특히 효과적이다. 프로젝트의 디렉터리 구조, 명명 규칙, 사용할 기술, 금지할 패턴과 설계 원칙을 미리 정의하면 AI는 처음부터 상당히 완성도 높은 골격을 만들어낼 수 있다. 0에서 0.1까지 가는 속도는 놀라울 정도로 빨라진다.
프로젝트는 0.1부터 변하기 시작한다
문제는 그 다음이다.
실제로 프로젝트를 배포하고 사용자의 손길이 닿기 시작하면 처음에는 생각하지 못했던 것들이 나타난다. 사용자는 개발자가 전혀 예상하지 못한 방법으로 프로그램을 사용한다. 외부 서비스의 API가 바뀌는 경우도 비일비재하다. 호환성을 위해 마음에 들지 않는 코드를 유지해야 할 때도 있다. 처음에는 좋은 설계라고 생각했던 것이 실제 사용에서는 불편하다는 것을 발견하기도 한다.
이처럼 예외가 하나씩 쌓이기 시작하며, 그 예외에는 대부분 나름대로 합당한 이유가 있다. 코드만 보면 이상해 보이는 부분도 몇 달 전의 변경 이력을 알고 보면 의도적인 선택일 수 있다. 반대로 당시에는 타당했던 결정이 지금은 더 이상 필요하지 않을 수도 있다.
이 단계부터 프로젝트는 처음 작성한 명세만으로 설명하기 어려운 존재가 된다. 여기에서 초기의 하네스를 절대적인 규칙처럼 적용하면 이상한 일이 생길 수 있다. 프로젝트를 위해 만든 규칙에 프로젝트를 다시 맞추기 시작하는 것이다.
0에서 0.1을 만들 때는 하네스가 프로젝트를 정의했다. 하지만 0.1에서 1.0으로 가는 과정에서는 실제 프로젝트의 변화가 하네스를 수정해야 한다. 둘의 주도권이 바뀌어야 한다는 뜻이다.
AI에게 프로젝트를 이해시키는 것이 중요한 이유
필자가 최근 들어 AI를 사용하는 방식은 조금 달라졌다.
필자는 AI에게 단순히 코드를 작성하라고 하지 않는다. 그 대신 AI에게 필자가 왜 이런 구조를 선택했는지 설명한다. 어떤 코드는 왜 일부러 그대로 두었는지 설명한다. 비슷해 보이는 두 프로젝트가 왜 서로 다른 코딩 컨벤션을 사용하는지도 이야기한다. AI가 내가 의도하지 않은 방향으로 코드를 수정하면 그것이 왜 잘못되었는지도 설명한다. 반대로 AI가 내 코드에서 이상한 부분을 발견하면 나에게 설명하게 한다.
처음에는 일반적인 방식에 비해 더 많은 시간이 필요하다. 혹자는 이 방식이 쓸데없다고 생각할 수도 있다. 하지만 시간이 지나면서 차이가 생긴다.
AI는 새로운 코드를 볼 때 그 코드 하나만 보지 않게 된다. “이 코드를 어떻게 고칠까요?”에서 끝나는 것이 아니라 다음과 같은 것들을 함께 판단하고 고려하기 시작한다.
- 이 변경이 이 프로젝트에서 왜 필요한가?
- 기존 설계와 충돌하지 않는가?
- 다른 모듈에는 어떤 영향을 주는가?
AI가 코드를 생성하는 도구에서 프로젝트를 이해하는 동반자로 바뀌는 순간이다.
실제로 버그를 찾는 방식도 달라진다
최근 오래 유지해 온 프로젝트의 코드 구조를 AI와 함께 검토하고 있었다. 버그를 찾으려던 것이 아니었다. 다른 프로그램의 코드 구조와 내 프로젝트의 구조가 어떻게 다른지 이야기하면서 몇 개의 클래스를 보여주었을 뿐이다.
그런데 AI가 데이터 모델을 읽다가 서로 다른 두 개의 값을 같은 멤버 변수에 대입하고 있다는 것을 발견했다. 아주 작은 버그였다. 현재 기능에서는 사용하지 않는 값이라 실제 장애도 발생하지 않았다. 그래서 나 역시 약 2년 동안 발견하지 못했다. AI에게 버그를 찾아달라는 특별한 프롬프트를 준 것도 아니었다.
특별한 지시가 없었음에도 프로젝트에서 그 클래스가 어떤 역할을 담당하는지 AI가 이미 이해하고 있었기 때문에 코드를 읽다가 데이터의 관계가 이상하다는 것을 발견한 것이다.
필자는 이런 경험이 단순한 코드 생성보다 훨씬 흥미롭다. 코드를 빨리 만드는 것과 그 코드가 전체 프로젝트 안에서 어떤 의미를 가지는지 이해하는 것은 다른 능력이기 때문이다.
프로젝트를 만든 사람도 모든 것을 기억하지 못한다
프로젝트를 만든 개발자라고 해서 현재 프로젝트의 모든 것을 가장 정확하게 기억하고 있는 것은 아니다. 물론 개발자는 왜 그런 결정을 했는지에 대한 역사와 의도를 알고 있다. 하지만 몇 년 동안 유지보수한 프로젝트라면 오래된 코드의 세부 사항을 모두 기억할 수는 없다. 너무 익숙해서 이상한 부분을 그냥 지나치는 경우도 있다.
반면 프로젝트를 지속적으로 함께 검토해 온 AI는 다른 방식으로 프로젝트를 바라볼 수 있다. 개발자는 의도와 역사를 가지고 있고 AI는 현재 코드베이스에서 발견한 구조와 관계를 가지고 있다. 둘은 항상 일치하지 않는다. 그래서 서로 비교하는 과정이 의미가 있다.
AI가 잘못 이해했다면 개발자가 바로잡는다. AI가 코드와 개발자의 설명 사이에서 모순을 발견했다면 개발자가 다시 확인한다. 결국 개발자의 머릿속에 있는 프로젝트, 실제 코드로 존재하는 프로젝트, AI가 이해하고 있는 프로젝트가 서로를 계속 검증하게 된다.
이제는 이런 방식이 가능해졌다
예전에는 AI를 이렇게 사용하는 것이 현실적으로 어려웠다. 세션이 끝나면 맥락도 함께 사라지는 경우가 많았기 때문이다.
그러나 지금은 상황이 달라지고 있다. 사용자나 프로젝트 단위로 맥락을 지속적으로 유지할 수 있는 기능들이 등장하고 있다. 긴 시간 동안 같은 프로젝트를 함께 다루면서 이전의 결정과 대화를 이어갈 수 있는 환경이 만들어지고 있다.
물론 완벽하지는 않다. AI는 잊기도 하고 잘못 이해하기도 한다. 따라서 반드시 지켜야 할 규칙이나 중요한 제약은 여전히 명시적으로 관리할 필요가 있다. 그렇기에 하네스 역시 여전히 유용하다. 프로젝트 공통 프롬프트도 마찬가지다.
다만 필자는 이제 하네스를 프로젝트 전체를 대신하는 지식으로 보지 않는다. 새로운 AI가 프로젝트에 들어왔을 때 최소한의 방향을 알려주는 부트스트랩이며 반드시 지켜야 할 규칙을 제공하는 가드레일에 가깝다고 생각한다.
그 위에 실제 프로젝트를 함께 경험하면서 쌓이는 맥락이 필요하다.
맥락을 쌓는 데에는 시간이 필요하다
여기에서 한 가지 문제가 생긴다.
특정 모델의 AI를 본격적으로 사용한 지 얼마 되지 않았다면 당연히 축적된 맥락이 부족할 수 밖에 없다. AI는 내가 어떤 방식으로 일하는지 모른다. 무엇을 중요하게 생각하는지, 어떤 선택을 선호하는지, 어떤 방법을 과거에 시도했다가 포기했는지도 모른다. 프로젝트의 역사도 모른다.
그러니 오랫동안 함께 작업한 AI와 같은 수준의 이해를 처음부터 기대하기는 어렵다. 이때 자연스럽게 그 시간을 단축할 수 있는 패스트트랙(Fast Track)을 찾게 된다.
- 어떤 프롬프트를 사용하면 되는가?
- 어떤 규칙 파일을 만들면 되는가?
- 잘 만들어진 하네스 하나만 적용하면 되는 것 아닌가?
물론 그런 방법들은 출발 시간을 상당히 줄여준다. 하지만 이 과정 전체를 건너뛸 수 있는 패스트트랙을 기대한다면 결국 다른 사람에게도 그대로 적용할 수 있는 범용적인 정보와 규칙에 의존하는 결과로 돌아가기 쉽다. 그것이 나쁘다는 뜻은 아니다. 범용 도구가 필요한 작업도 많다.
하지만 나를 이해하는 AI를 원한다면 이야기가 달라진다. 당신의 비서가 당신을 이해하는 데에는 시간이 필요하다. 새로운 짝 프로그래머가 당신의 코드와 판단 방식을 이해하는 데에도 시간이 필요하다. 함께 일하는 동료가 어떤 일을 중요하게 생각하고 어떤 방식으로 문제를 해결하는 사람인지 이해하는 데에도 시간이 필요하다.
장기적인 협업에 필요한 맥락이라는 관점에서는 AI도 크게 다르지 않다.
AI를 단순한 도구가 아니라 비서나 짝 프로그래머 또는 장기적인 동반자로 사용하고 싶다면 AI에게도 당신과 프로젝트를 이해할 시간을 주어야 한다. 그 시간은 낭비가 아니다. 함께 일하고 설명하고 교정하면서 쌓인 맥락은 다음 작업의 출발점이 된다.
처음에는 느려 보였던 방식이 어느 순간부터 매번 처음부터 설명해야 하는 방식보다 훨씬 빠르게 작동하기 시작한다.
AI에게 답을 얻는 것만큼 이해시키는 것도 중요하다
최근 다른 사람들이 AI를 사용하는 모습을 보면서 의외라고 느낀 것이 하나 있다. 생각보다 많은 사람이 AI를 여전히 예전의 검색 엔진처럼 사용한다.
질문한다 → 답을 받는다 → 필요한 코드를 생성한다 → 대화가 끝난다
물론 그것만으로도 충분히 유용하다. 하지만 지금의 AI가 제공하는 기능을 생각하면 조금 아깝다는 생각이 든다.
AI에게 답을 얻는 것만큼 AI에게 나를 이해시키는 것도 중요하다.
여기에서 말하는 ‘나’는 개인적인 정보를 뜻하지 않는다. 내가 만드는 프로젝트의 목적, 중요하게 생각하는 설계 원칙, 과거에 실패했던 방법, 의도적으로 남겨둔 예외, 사용자들이 실제로 프로그램을 사용하는 방식 같은 것들이다.
그리고 이것을 한 번에 완벽한 프롬프트로 작성할 필요도 없다. 함께 작업하면서 설명하면 된다. AI가 잘못 이해하면 고쳐주면 된다. 새로운 결정이 생기면 왜 그렇게 결정했는지 알려주면 된다. 이 과정은 일방적으로 AI에게 정보를 주입하는 것만을 의미하지 않는다.
AI에게 프로젝트를 설명하는 과정은 개발자 자신에게도 일종의 검증 과정이 된다. 당연하다고 생각했던 설계를 설명하다 보면 근거가 약한 결정이 드러날 수 있다. 과거의 판단과 현재 코드가 서로 맞지 않는다는 것을 발견할 수도 있다. AI가 이전 결정과 지금의 구현 사이에서 모순을 찾아낼 수도 있다.
그 순간 AI는 단순히 명령을 수행하는 도구가 아니라 개발자가 자신의 프로젝트를 다시 바라볼 수 있게 만드는 또 하나의 관점이 된다.
0.1을 만드는 AI와 1.0을 만드는 AI
필자는 앞으로 AI를 활용하는 방법이 두 가지 방향으로 조금 더 분명하게 나뉠 것이라고 생각한다.
하나는 잘 정의된 요구사항과 하네스를 이용해 0에서 0.1을 빠르게 만들어내는 AI다. 그리고 다른 하나는 이미 존재하는 프로젝트의 역사와 구조를 이해하면서 0.1을 1.0으로 발전시키는 AI다.
첫 번째 방식에는 좋은 명세와 좋은 프롬프트가 중요하다. 반면 두 번째 방식에는 좋은 맥락과 충분한 시간이 중요하다. 당연한 이야기지만 둘 중 하나가 다른 하나를 대체한다고 생각하지 않는다.
새로운 프로젝트를 시작할 때는 하네스가 매우 강력하다. 이미 운영되고 있는 프로젝트에서 반복적으로 지켜야 하는 규칙을 유지하는 데에도 훌륭한 도구다. 그러나 프로젝트가 성장할수록 규칙으로 표현하기 어려운 맥락도 함께 성장한다.
- 왜 이런 코드가 남아 있는가
- 왜 이번에는 평소와 다른 선택을 했는가
- 왜 비슷한 두 프로젝트에서 서로 다른 해결 방법을 사용했는가
- 사용자가 실제로 어떻게 사용하고 있는가
이런 것들은 파일 하나에 모두 적어 넣는다고 해결되지 않는다. 함께 프로젝트를 경험하면서 이해해야 한다.
지금까지 우리는 AI를 사용하는 방법을 이야기하면서 이런 질문을 많이 해왔다.
- 어떤 프롬프트를 써야 하는가
- 어떤 규칙 파일을 만들어야 하는가
- 어떤 하네스를 씌워야 하는가
이제는 이런 질문도 조금 더 많이 해볼 때가 된 것 같다.
내 AI는 이 프로젝트를 얼마나 이해하고 있는가?
그리고 그 질문에 대한 답은 아마 한 번의 완벽한 프롬프트 안에 있지 않을 것이다.
사람과 사람이 함께 일할 때와 마찬가지로 서로 설명하고 질문하고 틀리고 교정하면서 함께 프로젝트를 만들어온 시간 속에 있을 것이라고 믿는다.