
이 글은 만들고 측정하고 개선하는 작업을 반복하며, 다음 날에도 사람의 감독 없이 이어서 실행하는 에이전트를 위한 프롬프트 패턴을 다룬다. 여러 차례의 작업에 걸쳐 프롬프트를 키우면서도 모순을 줄이고, 에이전트가 승인 없이 실행할 반복 작업을 맡기며, 실제 사용에 맞춰 인터페이스를 조정하는 방법 등을 연재한다.
이 패턴은 에이전트가 오랜 시간 자율적으로 일하도록 프롬프트를 작성하는 사람을 대상으로 한다. 글쓴이는 Claude Code용 프롬프트를 만들어 에이전트에게 맡기고, 여러 세션에 걸쳐 몇 시간씩 작업하게 한다. 다음 세션이 작업을 이어가는 데 필요한 정보를 프롬프트에 담아야 하므로, 프롬프트를 자주 고친다. 이 패턴을 사용하기 전에는 수정할 때마다 프롬프트가 길어지고 일관성이 떨어졌다. 효과는 반복 작업의 두 번째 주기부터 쌓이므로, 한 번만 쓰는 프롬프트에서는 얻을 것이 많지 않다.
글쓴이의 딸은 친구들과 연락하기 위해 휴대전화가 필요할 나이가 됐다. 글쓴이는 알림, 무한 스크롤, 참여도를 높이도록 조정된 알고리즘이 사람들의 추론 능력과 집중력을 떨어뜨린다고 판단해 딸에게 Light Phone을 줬다. 이 전화기로 딸은 문자 메시지를 보내고 사진을 찍고 음악을 들을 수 있으며, 글쓴이는 최신 스마트폰이 일으킨다고 보는 ‘인지적 서비스 거부 공격’을 피할 수 있다고 설명한다.
딸이 AI로 무언가를 만드는 법도 배워야 한다고 생각해 Omarchy 워크스테이션을 마련했다. 하지만 AI 학습용 컴퓨터만 두는 것은 채소만 먹이는 식단과 비슷하다고 느꼈다. 재미도 필요하다는 것이다. 글쓴이는 Quake가 자신의 성장 과정에 큰 영향을 줬으며, TCP/IP 네트워킹을 배우고 해킹과 보안에 관심을 갖게 된 계기였다고 말한다. 딸에게도 같은 일이 일어날 수 있다고 생각해 친구들과 함께할 Quake 서버를 만들기로 했다.
이 프로젝트는 게임 서버, Mac·Linux·모바일 브라우저에서 실행되는 멀티플레이어 클라이언트, 그리고 밤의 경기 내용을 스포츠 하이라이트 프로그램처럼 정리한 일일 요약을 제공한다. 요약에는 다음 날 아침 가족이 함께 검토할 경기별 시상 내용도 들어간다. 글쓴이는 서버를 운영하려면 매일 몇 가지 Linux 명령어를 연습할 만한 동기가 생기길 바랐다. 또 가족이 의존하는 여러 서비스를 이미 실행 중인 홈 서버에서 에이전트가 시스템 전체를 만들고 운영하며 계속 개선하게 하고 싶었다.
이 연재의 각 패턴은 보통 프롬프트 한두 문단에 해당하는 작은 기법이다. 가치는 여러 패턴을 함께 적용할 때 생긴다. 글쓴이는 이를 복리처럼 생산성이 점차 빨라지는 효과로 설명한다. 성공한 실험을 반영한 구축 계획은 다음 재구축을 개선하고, 혼란을 일으킨 지시를 기록하면 다음 주의 프롬프트가 더 명확해진다. 반복 주기마다 에이전트는 이전보다 나은 기반에서 시작한다.
첫 글은 프롬프트 자체를 키우는 방법을 다룬다. 글쓴이는 에이전트 프롬프트를 한 번에 완성할 수 없었고, 빠진 조건을 발견할 때마다 전체를 다시 쓰면 이미 잘 작동하던 규칙까지 깨졌다. 구축 과정은 여덟 차례 반복됐다. 공유 서버에서의 sudo 명령, iPad 지원, 게임 중 아이들과 대화하는 LLM 등 미리 계획하지 못한 요구 사항이 매번 나타났다. 글쓴이는 프롬프트를 다시 쓰는 대신 요구 사항마다 새 섹션을 추가했다.
목표 충돌을 다루는 방법
목표는 프롬프트 맨 위에 우선순위 순서로 적는다. 글쓴이는 다음과 같이 구축 목표를 정했다.
1. Protect existing services. Every service on this host keeps running exactly as it runs today. A Quake feature that risks an existing service gets dropped or redesigned. 2. Working LAN Quake. Quake clients on the LAN connect and play fun sessions. 3. Game modes. Deathmatch and Quake Team Fortress work. 4. Web app. A local web app serves players and the operator. 5. Creativity. The experience produces stories the family retells later.
프롬프트의 각 규칙 섹션은 어떤 우선순위를 지키는 규칙인지 밝힌다. 상시 규칙 섹션은 “각 규칙은 작업 중 우선순위 1을 지키기 위해 존재한다”는 문장으로 시작한다. 세 차례 뒤에 특권 모델 섹션을 추가했을 때도 다른 서비스가 중요한 이유를 다시 설명하지 않고 우선순위 1을 참조했다.
목표가 여러 곳에서 각기 다른 말로 제시되면 에이전트는 어느 목표를 우선할지 판단하기 어렵다. 예를 들어 QuakeWorld 기본 포트인 27500을 다른 서비스가 이미 사용하고 있다고 하자. 네트워크 섹션은 플레이어가 접속해야 한다고 하고, 안전 섹션은 기존 서비스를 계속 실행해야 한다고 한다. 우선순위 없이 각 섹션이 자체 목표만 설명하면 에이전트는 충돌을 해결할 기준이 없어 다른 서비스를 중지해 포트를 비울 수 있다. 프롬프트가 커지면서 목표를 조금씩 다르게 다시 쓰면, 섹션마다 어느 목표가 우선인지 달라질 수도 있다.
글쓴이는 목표를 한 번만 적고 순위를 매긴 뒤 각 규칙 섹션이 해당 우선순위를 가리키도록 했다. 충돌이 생기면 에이전트는 우선순위 숫자를 비교해 숫자가 더 낮은 규칙을 따른다. 포트 사례에서는 기존 서비스를 지키는 우선순위 1이 Quake 실행 목표인 우선순위 2보다 앞선다. 따라서 에이전트는 다른 서비스는 그대로 두고 비어 있는 포트를 선택한다. 이후 섹션은 목표를 다시 풀어 쓰지 않고 우선순위만 참조하므로 목표마다 표현이 하나로 유지된다.
다른 프롬프트에도 적용할 수 있는 원칙은 목표의 순위를 한곳에서 한 번 정하고, 모든 규칙이 그 순위를 가리키게 하는 것이다. 순위는 목표가 충돌할 때 에이전트가 질문 없이 적용할 기준이 된다. 목표를 한 가지 표현으로 유지하면 새 섹션이 기존 목표를 다르게 정의하는 일도 줄어든다.
요구 사항마다 섹션 추가하기
새 요구 사항이 생기면 기존 섹션은 그대로 두고, 해당 요구 사항을 다루는 제목 섹션을 추가한다. 글쓴이의 프롬프트는 우선순위, 상시 규칙, 구축 단계별 주제를 각 제목으로 나눈 마크다운 파일이다. 기존 파일에서 다루지 않은 요구 사항은 각각 새 섹션으로 만들었다.
- 2차 반복: 일부 단계에 다른 서비스에 피해를 줄 수 있는
sudo가 필요해져Privilege Model and Change Control을 추가했다. - 3차 반복: 호스트에서 실행되는 Claude Code가 플레이 중 콘텐츠를 생성할 수 있어
Phase 4B: LLM-Powered Live Experiences를 추가했다. - 4차 반복: iPad와 iPhone 플레이어가 접속할 방법이 필요해
Research topic 10, iPad and iPhone play를 추가했다. - 5차 반복: 터치 조작을 여러 차례 조금씩 조정해야 해
Phase 5B: Apple Device UI Fast Loop을 추가했다. - 6차 반복: 직전 세션을 정리하는 일일 페이지가 필요해
Phase 4C: The Chronicler Agent를 추가했다. - 7차 반복: 대부분의 작업에 더 저렴한 모델을 쓰고 싶어
Orchestration and Model Tiers를 추가했다.
iPad 요구 사항을 반영하려고 프롬프트를 다시 썼다면 서버, 클라이언트, 테스트 섹션을 한꺼번에 수정해야 했을 것이다. 그러면 오랫동안 조정해 고품질 결과를 얻던 지침을 잃을 수 있었다고 글쓴이는 설명한다.
대신 iPad 요구 사항을 독립된 조사 주제로 추가하고 서버·클라이언트·테스트 섹션은 그대로 뒀다. 새 섹션이 기존 프롬프트에서 이름 붙여 다루지 않던 항목을 참조하려면 먼저 그 항목을 정의해야 했다. 특권 모델에서는 ‘내 프로젝트에만 영향을 주는 명령’과 ‘서버 전체에 영향을 주는 명령’을 구분하기 위해 권한 등급을 정의했다. 기능 전환에는 기능 목록이 필요해 기능 매니페스트 파일을 만들었다. 작업 중단 뒤 재개할 때 진행 상황을 확인하도록 STATE/ 디렉터리를 만들었다. 이후 섹션은 이 항목들을 다시 설명하는 대신 권한 등급, 기능 매니페스트, STATE/ 디렉터리를 이름으로 참조한다.
새 섹션이 여기저기 흩어진 설명만으로 존재하는 대상을 참조해야 한다면, 그 대상에 이름을 붙이고 파일을 만든다. 이름을 붙인 항목은 이후 섹션이 다시 정의하지 않고 참조할 수 있는 안정적인 기준점이 된다.
새 섹션을 구축·테스트·파일 목록에 연결하기
새 섹션을 쓴 뒤에는 프롬프트의 세 곳도 수정한다. 에이전트는 계획 내용 목록을 보고 무엇을 만들지, 인수 기준을 보고 무엇을 테스트할지, 디렉터리 구조를 보고 파일을 어디에 둘지 판단한다.
flowchart LR P[Unanticipated problem] --> S[New prompt section] S --> A1[Build plan contents] S --> A2[Acceptance criteria] S --> A3[Directory layout] A1 --> B[Agent decides what to build] A2 --> T[Agent decides what to test] A3 --> F[Agent decides where files go]
iPad 지원을 추가할 때는 iPad 조사 섹션을 새로 만들고, 계획 내용 목록·인수 기준·디렉터리 구조도 함께 수정했다.
계획 내용:
- Client bundle contents and install flow for Linux, plus the chosen iPad and iPhone path: browser client hosting and transport bridge, or native app build and install procedure, including any local TLS setup and the per-device onboarding steps.
인수 기준:
- An iPad and an iPhone each complete the documented onboarding and join the same match as a Linux client, with playable frame rate and working touch or controller input.
디렉터리 구조:
ios-ui/ # Apple device UI configs, envelope, tests, telemetry, fast-loop log
에이전트는 계획 내용 목록과 인수 기준에 iPad가 모두 들어 있을 때에만 iPad 지원을 만들고 테스트한다. 계획 내용 목록은 만들 항목을, 인수 기준은 테스트할 항목을 정한다. iPad 조사 섹션만 추가했다면 에이전트는 iPad 선택지를 조사하고 권고안을 작성한 뒤, Linux 전용 서버만 구축하고 테스트했을 것이다.
따라서 새 요구 사항은 그것을 다루는 섹션에만 두지 말고 계획 내용 목록, 인수 기준, 디렉터리 구조에도 추가해야 한다. 글쓴이는 프롬프트를 키울 때마다 이 세 곳을 점검 항목으로 삼는다.
단계별 산출물 파일 지정하기
글쓴이는 프롬프트의 각 단계 끝에 그 단계에서 만들어야 할 파일을 나열하는 Artifact 줄을 둔다. 에이전트는 다음 파일이 생기면 탐색 단계를 완료한 것으로 처리한다.
Artifact: STATE/discovery.md, STATE/storage-decision.md, STATE/blog-howto.md, STATE/healthcheck.sh, STATE/baseline-health.md
이 파일들은 해당 단계의 문서이므로 에이전트가 이미 만든 작업 결과를 기록한다. 작업이 중단된 뒤 새 에이전트 세션이 이어서 시작할 때 확인하는 지점으로도 쓰인다.
모호한 요구 사항의 해석 기록하기
요구 사항이 두 가지로 해석될 수 있다면 프롬프트를 작성하는 사람이 한 가지 해석을 프롬프트에 적고, 요구 사항을 낸 사람에게 어떤 해석을 택했는지 알린다. 글쓴이는 마지막 방문 다음 날 볼 수 있는 일일 요약 페이지를 요청했다. 이 표현은 누구든 방문한 다음 날을 뜻할 수도 있고, 특정 아이가 방문한 다음 날을 뜻할 수도 있었다. 글쓴이와 함께 프롬프트를 작성하던 Claude는 누구든 방문한 다음 날로 해석해 게시 규칙에 적었고, 같은 답변에서 그 선택을 알렸다. 잘못된 해석을 바로잡는 데는 메시지 한 번이면 됐을 것이다. 반대로 에이전트가 일주일 동안 틀린 일정으로 게시한 뒤 수정하려면, 페이지가 잘못된 날에 나타난 이유를 로그에서 찾아야 했을 것이다.
다음 프로젝트에서 달리할 점
글쓴이는 프롬프트가 이미 커지는 과정에서 이런 방법을 정리했다. 다음 프로젝트는 첫 초안부터 이 방법을 적용하면 매번 수정하는 비용을 줄일 수 있다고 말한다.
첫 초안에 계획 내용 목록, 인수 기준, 디렉터리 구조 제목을 빈 상태로 넣을 것이다. 제목이 없으면 새 요구 사항을 구축·테스트·파일 목록에 연결해야 한다는 점을 기억에 의존하게 된다. 연결이 빠진 섹션은 에이전트가 조사만 하고 실제로 만들지 않는 결과로 이어질 수 있다. 처음부터 세 제목을 만들고 섹션을 추가할 때마다 각 제목 아래에 한 줄씩 적으면 새 요구 사항을 작성하는 단계에서 구축, 테스트, 파일 배치까지 연결할 수 있다.
우선순위 목록을 가장 먼저 쓰고, 각 규칙이 어떤 우선순위를 지키는지 밝히게 할 것이다. 뒷받침하는 우선순위가 없는 규칙은 다른 규칙과 충돌할 때 얼마나 중요한지 에이전트가 판단하기 어렵게 한다. 순위가 없는 규칙은 프롬프트를 길게 만들면서도 명확하게 하지는 못한다. 우선순위 목록을 먼저 작성하고 규칙을 추가하기 전에 해당 규칙이 지키는 우선순위 번호를 첫 문장에 적는다. 맞는 우선순위가 없다면 규칙이 불필요하거나 목록에 목표가 빠진 것이므로 먼저 우선순위 목록을 고친다.
모호한 요구 사항에 대해 선택한 해석을 날짜와 함께 프롬프트 저장소에 기록할 것이다. 대화에서 정한 해석은 기억에서 사라질 수 있다. 몇 달 뒤 에이전트가 예상 밖의 행동을 했을 때, 승인했지만 잊은 해석을 따르는 것인지 실수인지 알아야 한다. 프롬프트 옆에 INTERPRETATIONS.md 파일을 만들고 날짜, 원래 요구 사항의 문구, 선택한 해석, 배제한 대안, 해당 해석을 반영한 프롬프트 섹션을 기록한다. 에이전트의 행동이 예상 밖일 때는 이 파일부터 확인한다.
요약
장기 실행 에이전트용 프롬프트는 요구 사항을 하나씩 더하며 커진다. 글쓴이는 여덟 차례의 변경 과정에서 프롬프트의 일관성을 유지하기 위해 목표의 우선순위를 정하고, 새 요구 사항마다 섹션을 추가하며, 계획 내용·인수 기준·디렉터리 구조에 연결했다. 각 단계가 만들 파일을 지정하고, 모호한 요구 사항의 해석은 실행 전에 확인하는 것도 권한다.
연재의 다음 글에서는 에이전트가 실행 중인 컴퓨터를 손상하지 않도록 지키는 방법을 다룬다.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요