거대한 soul.md가 필요하다고 생각했지만, 52단어짜리 파일이 더 효과적이었습니다
요약
에이전트의 성능을 높이기 위해 거대한 페르소나 파일(soul.md)을 사용하는 대신, 짧은 페르소나와 외부 메모리 아키텍처를 결합하는 것이 더 효과적임을 설명합니다. 상태 저장과 검색(retrieval) 중심의 설계가 에이전트의 연속성을 보장합니다.
핵심 포인트
- 거대한 시스템 프롬프트는 에이전트의 유용성을 떨어뜨릴 수 있음
- 짧은 페르소나, 결정론적 상태 저장, 관련 컨텍스트 검색의 조합이 핵심
- LanceDB와 같은 도구를 활용한 외부 메모리 아키텍처 구축 권장
- 프롬프트 연극보다 데이터 기반의 상태 관리가 에이전트 연속성에 중요
저는 더 나은 에이전트(agent) 행동이 더 큰 soul.md에서 나온다고 생각하곤 했습니다.
여러분도 그 파일을 아실 겁니다:
- 말투 규칙 (tone rules)
- 성격 규칙 (personality rules)
- 예외 사례 (edge cases)
- 가치관 (values)
- 배경 이야기 (backstory)
- 워크플로우 선호도 (workflow preferences)
- 정말 중요하다고 확신하는 사소하고 이상한 주의사항들
처음에는 "그저 몇 가지 메모"로 시작하지만, 결국 매 실행마다 주입되는 1,500단어짜리 선언문이 되어버립니다.
저도 그런 버전을 만들어 본 적이 있습니다. 한동안은 똑똑하게 느껴지죠.
그러다 에이전트가 더 순종적으로 변하면서 오히려 유용성은 떨어지기 시작합니다.
에이전트가 실제 상태(state)보다 자신의 페르소나(persona)를 더 잘 보호하기 시작하는 것입니다.
몇몇 OpenClaw 스레드를 살펴본 후, 저는 더 나은 패턴이 훨씬 더 단순하다는 것을 깨달았습니다:
- 아주 작은
soul.md - 정전 상태(canonical state)를 위한 마크다운 (markdown) 저장 파일
- LanceDB와 같은 도구를 활용한 검색 (retrieval)
이 설정은 거대한 프롬프트(prompt)만큼 화려하지는 않습니다. 하지만 더 잘 작동합니다.
거대 프롬프트 신화를 깨뜨린 댓글
soul을 작성하는 것에 관한 r/openclaw 스레드에서 한 댓글 작성자가 이렇게 말했습니다:
AI에게 쓰게 하세요. 또한 그것은 거의 중요하지 않습니다. 에이전트와 메모리(memory) 파일가 중요합니다.
페르소나 파일을 다듬기 위해 몇 시간을 보낸 사람에게는 무례한 문장일 수 있습니다.
상황은 더 심각합니다.
또 다른 사용자는 자신의 soul.md가 단 52단어뿐이며, 1월부터 그 에이전트와 함께 작업해 왔다고 말했습니다.
단 52단어입니다.
그 정도면 역할과 말투를 정의하기에는 충분합니다. 하지만 그 파일이 데이터베이스(database), CRM, 런북(runbook), 그리고 자서전 역할을 동시에 수행하는 것처럼 꾸미기에는 부족합니다.
이는 제가 실제 에이전트 설정에서 계속 보고 있는 것과 일치합니다:
- 짧은 페르소나 (persona)
- 결정론적 저장 상태 (deterministic saved state)
- 관련 컨텍스트를 위한 검색 (retrieval)
그 반대가 아닙니다.
제가 찾은 최고의 사례: OpenClaw 던전 마스터 (Dungeon Master)
가장 명확한 증거는 누군가가 던전 마스터 에이전트를 구축한 또 다른 OpenClaw 스레드에서 나왔습니다.
중요했던 것은 더 나은 soul.md가 아니었습니다.
그것은 아키텍처(architecture)였습니다:
- 하드 세이브(hard saves)를 위한 구조화된 디렉토리 레이아웃
- 메모리 코어(memory-core)로서의 로컬 LanceDB 벡터 검색
- D&D 5e SRD의 로컬 마크다운 (markdown) 사본
그것이 중요한 차이점입니다.
에이전트가 "기억"했던 것은 프롬프트가 시적이었기 때문이 아니었습니다.
그것은 상태 (state)가 프롬프트 외부에 존재했고, 검색 (retrieval)이 오직 관련 있는 것들만 가져왔기 때문에 기억할 수 있었던 것입니다.
이는 실제 사용 환경에서 살아남아야 하는 에이전트들에게 훨씬 더 나은 설계입니다.
당신의 에이전트가 캠페인을 운영하든, 지원 요청을 분류 (triage)하든, Discord 운영을 처리하든, 혹은 하루 종일 n8n 워크플로우 (workflow)를 실행하든, 연속성 (continuity)은 대개 프롬프트 연극 (prompt theater)이 아닌 메모리 아키텍처 (memory architecture)에서 옵니다.
거대한 프롬프트가 성능이 저하되는 이유
비대해진 시스템 프롬프트 (system prompt)는 한 곳에서 모든 문제를 해결하려고 시도합니다:
- 페르소나 (personality)
- 정책 (policy)
- 메모리 (memory)
- 워크플로우 규칙 (workflow rules)
- 예시 (examples)
- 특수 사례 (special cases)
- 역사적 맥락 (historical context)
그래서 모든 요청이 동일한 거대한 지침 블록 (instruction block)을 끌고 다니게 됩니다.
이는 몇 가지 문제를 일으킵니다:
- 매 실행 시 더 많은 토큰 (tokens) 소모
- 지침 충돌 (instruction conflicts) 가능성 증가
- 디버깅 (debugging)의 어려움
- 프롬프트 희석 (prompt dilution) 심화
- 작은 모델들이 더 빠르게 흐릿해짐 (mushy)
이는 마치 함수가 회사 전체의 위키 (wiki)를 포함하고 있는 글로벌 설정 (global config) 객체에 의존하게 만드는 것과 같습니다.
기술적으로는 가능하지만, 추론 (reasoning)하기에는 최악입니다.
더 깔끔한 분리: 페르소나, 상태, 검색
제가 권장하는 분리 방식은 다음과 같습니다.
1. soul.md는 정체성을 담당합니다
짧게 유지하세요.
50~150단어 정도를 생각하세요.
예시:
당신은 실용적인 코딩 에이전트입니다.
간결하고 구체적이어야 하며, 불확실성에 대해 솔직해야 합니다.
이론을 세우는 것보다 결과물을 내놓는 것을 선호합니다.
...
그것으로 충분합니다.
이는 메모리를 저장하는 척하지 않으면서 역할과 행동을 정의합니다.
2. 마크다운 (markdown) 파일은 표준 상태 (canonical state)를 담당합니다
여기에 사실 관계를 넣으세요.
예시:
campaign_state.md
customer_context.md
decisions_log.md
...
이것들이 당신의 진실의 원천 (source of truth)입니다.
예시:
# customer_context.md
- 고객: Acme Health
...
이는 동일한 사실들을 거대한 프롬프트 안에 파묻어 두는 것보다 검사하기가 훨씬 쉽습니다.
3. 검색 (retrieval)은 모호한 회상을 담당합니다
에이전트가 모든 맥락이 아닌 관련 맥락이 필요할 때 LanceDB나 다른 검색 레이어 (retrieval layer)를 사용하세요.
그것은 다음을 의미합니다:
- 더 작은 프롬프트
- 반복되는 짐 (baggage) 감소
- 필요할 때 더 나은 회상 (recall)
- 메모리가 이상해질 때 더 쉬운 디버깅
개념적으로:
query = "What did we decide about Slack webhook retries for Acme Health?"
results = memory.search(query, top_k=3)
context = "\n\n".join([r.text for r in results])
이것은 모든 대화 단계마다 고객의 전체 이력을 주입하는 것보다 훨씬 깔끔합니다.
실제 적용 모습
간단한 에이전트 워크스페이스 (agent workspace)는 다음과 같을 수 있습니다:
agent/
├── soul.md
├── state/
...
그리고 요청 파이프라인 (request pipeline)은 다음과 같을 수 있습니다:
1. soul.md 로드
2. 이 작업에 필요한 특정 상태 (state) 파일 로드
3. LanceDB에서 관련 메모리 청크 (memory chunks) 쿼리
...
이것은 "느낌(vibe)이 좋아질 때까지 지시사항을 계속 추가하기"보다 훨씬 더 유지보수가 용이합니다.
프롬프트 캐싱 (Prompt caching)이 도움이 되긴 하지만, 잘못된 설계를 해결해주지는 않습니다
이 지점에서 사람들이 부주의해집니다.
네, 프롬프트 캐싱 (prompt caching)은 유용합니다.
OpenAI는 길고 재사용되는 접두사 (prefixes)에 대해 프롬프트 캐싱을 지원합니다. Anthropic 또한 프롬프트 캐싱을 제공하며, 반복되는 긴 프롬프트에 대해 상당한 지연 시간 (latency) 및 비용 절감 효과를 보여줍니다.
그것은 사실입니다.
하지만 캐싱은 거대한 프롬프트로 인해 발생하는 실제 문제들을 해결하지 못합니다:
- 충돌하는 지시사항 (conflicting instructions)
- 과도하게 스크립트화된 동작 (over-scripted behavior)
- 열악한 검색 설계 (poor retrieval design)
- 디버깅하기 어려운 실패
- 너무 많은 접두사 (prefix)로 인해 과부하가 걸리는 작은 모델들
저렴해진 비대함 (bloat)도 결국은 비대함일 뿐입니다.
만약 당신의 전체 에이전트 전략이 영원히 동일한 괴물 같은 프롬프트를 보내는 것에 의존하고 있다면, 캐싱은 비용과 지연 시간을 줄여줄 수는 있습니다. 하지만 그것이 아키텍처 (architecture)를 우아하게 만들어주지는 않습니다.
수많은 자동화 (automations)를 실행하는 팀에게는 이 차이가 매우 중요합니다.
채팅 데모보다 자동화에서 이것이 더 중요한 이유
일회성 채팅을 실행하는 경우라면 프롬프트 비대화 (prompt bloat)는 짜증 나는 정도에 그칩니다.
하지만 다음과 같은 환경 내부에서 에이전트를 실행한다면:
n8n- Make
- Zapier
- OpenClaw
- 커스텀 워커 (custom workers)
- Slack 봇
- Discord 봇
프롬프트 비대화는 운영상의 문제 (operational problem)가 됩니다.
서비스 제공업체가 상쇄해주지 않는 한, 매 실행마다 불필요한 컨텍스트 (context)에 대한 비용을 지불해야 합니다. 모든 핸드오프 (handoff)는 추론하기 더 어려워집니다. 모든 실패는 거대한 접두사 (prefix) 내부에서 수행하는 포렌식 (forensic) 작업으로 변합니다.
이것이 바로 예측 가능한 컴퓨팅 (predictable compute)이 중요한 이유입니다.
하루 종일 실행되는 에이전트 (agents)를 구축할 때는, 프롬프트 텍스트 한 조각을 더 추가하는 것이 비용 대비 가치가 있는지 끊임없이 고민하기보다 아키텍처 (architecture)와 신뢰성 (reliability)을 최적화하는 데 집중해야 합니다.
이것이 바로 Standard Compute가 이러한 종류의 워크로드 (workload)에 흥미로운 적합성을 갖는 이유이기도 합니다. Standard Compute는 고정된 월간 가격으로 OpenAI 호환 API를 제공하므로, 토큰당 지출 (per-token spend)을 일일이 관리하지 않고도 에이전트 중심의 워크플로우를 실행할 수 있습니다. 덕분에 매 단계마다 가장 저렴한 프롬프트를 찾는 대신, 적절한 메모리 설계 (memory design)를 선택하기가 훨씬 쉬워집니다.
패턴을 살펴본 후 나의 순위
| 접근 방식 | 가장 적합한 용도 |
|---|---|
| LanceDB 검색 (retrieval) | 의미론적 회상 (semantic recall), RAG, 에이전트 메모리, 더 작은 프롬프트 |
| ... |
나의 실제 승자들:
- 연속성 (continuity)에 최고: 마크다운 (markdown) 하드 세이브 (hard saves)
- 회상 (recall)에 최고: LanceDB
- 스타일 (style)에 최고: 짧은
soul.md - 시간을 낭비하기 가장 쉬운 것: 거대한 페르소나 (persona) 파일
만약 단 하나만 남겨야 한다면, 나는 하드 세이브 파일을 남길 것입니다.
상태 (State)가 자기 신화 (self-mythology)를 이깁니다.
각 계층에 무엇을 넣을 것인가
soul.md는 부끄러울 정도로 짧게 유지하라
좋은 내용:
- 역할 (role)
- 어조 (tone)
- 몇 가지 제약 사항 (constraints)
- 한두 개의 우선순위 (priorities)
나쁜 내용:
- 전체 고객 이력 (customer history)
- 모든 워크플로우의 예외 케이스 (edge case)
- 로그 (logs)
- 인벤토리 (inventories)
- 프로젝트 상태 (project state)
- 모델에게 필요 없는 감정적 배경 이야기 (emotional backstory)
사실은 마크다운에 넣어라
명시적으로 변경되기 전까지 사실이어야 하는 것들은 마크다운 파일에 사용하세요.
예시:
# decisions_log.md
- 2026-07-10: Slack 웹훅 (webhook) 재시도 횟수를 3회로 유지.
...
모호한 메모리는 검색 (retrieval)에 넣어라
다음과 같은 용도로 검색을 사용하세요:
- 이전 대화 내용 (prior conversations)
- 의미론적으로 관련된 사건 (semantically related incidents)
- 유사한 고객 문제 (similar customer issues)
- 매번 주입하기에는 너무 큰 문서 (docs)
이것이 바로 LanceDB가 빛을 발하는 지점입니다.
더 작은 모델일수록 더 큰 혜ประโยชน์를 얻는다
더 저렴하거나 작은 모델을 사용하고 있다면 이 점은 매우 중요합니다.
Claude Opus 4.6 또는 GPT-5.4는 어느 정도의 프롬프트 남용 (prompt abuse)을 흡수할 수 있습니다.
하지만 더 작은 Qwen 또는 Llama 변체 (variants)들은 대개 그렇지 못합니다.
“이 모델은 별로다”라는 많은 의견들은 사실 “이 에이전트가 너무 많은 프롬프트 쓰레기(prompt junk)를 끌고 다닌다”는 뜻인 경우가 많습니다.
에이전트 워크플로 (agent workflows)를 위한 최적의 저렴한 모델을 평가하고 있다면, 다음 항목들로 테스트해 보세요:
- 아주 작은 페르소나 (tiny persona)
- 명시적인 상태 파일 (explicit state files)
- 검색 기반 메모리 (retrieval-based memory)
그런 다음, 동일한 모델을 1,500단어 분량의 시스템 프롬프트 (system prompt) 환경에서 사용했을 때와 비교해 보세요.
그러면 병목 현상 (bottleneck)이 모델이 아니라 아키텍처 (architecture)였다는 사실을 발견하게 될 수도 있습니다.
이런 에이전트를 디버깅하는 방법
제가 이 설정을 좋아하는 이유 중 하나는 검사할 수 있는 계층 (layers)이 제공된다는 점입니다.
에이전트가 실패한다면, 다음 순서대로 확인해 보세요:
- 정전 상태 (canonical state)가 잘못되었는가?
- 검색 (retrieval)이 관련 없는 청크 (chunks)를 가져오고 있는가?
- 페르소나 (persona)가 너무 제한적이거나 너무 모호한가?
- 워크플로 (workflow)가 새로운 사실을 유지 (persist)하는 데 실패했는가?
특히 OpenClaw에서는 내장된 명령어가 도움이 됩니다:
openclaw status
openclaw status --all
openclaw status --deep
...
이것은 거대한 프롬프트를 수정하며 분위기 (vibe)가 바뀌기를 바라는 것보다 훨씬 더 나은 디버깅 루프 (debugging loop)입니다.
실질적인 시사점
진짜 질문은 이것이 아닙:
“내 soul.md는 얼마나 상세해야 하는가?”
진짜 질문은 이것입니다:
“메모리 (memory)는 실제로 어디에 존재해야 하는가?”
저의 답변은 다음과 같습니다:
- 정체성 (identity)은
soul.md에 - 진실 (truth)은 마크다운 (markdown)에
- 회상 (recall)은 검색 (retrieval)에
이렇게 하면 실행하기 쉽고, 디버깅하기 쉬우며, 자동화 (automations) 전반에 걸쳐 확장 (scale)하기 쉬운 에이전트를 가질 수 있습니다.
그리고 이러한 자동화를 지속적으로 실행하고 있다면, 고정 비용 컴퓨팅 (flat-cost compute)이 실질적인 이점이 됩니다. 토큰당 과금 (Per-token billing) 방식은 사람들을 이상한 프롬프트 타협으로 내몰지만, 예측 가능한 월간 가격 책정은 실제로 작동하는 방식에 최적화할 수 있게 해줍니다.
만약 여전히 2,000단어짜리 soul.md를 쓰고 싶은 유혹을 느낀다면, 먼저 이것을 시도해 보세요:
52단어만 작성하세요.
그리고 남은 노력은 상태 (state)와 검색 (retrieval)에 쏟으세요.
진정한 메모리는 보통 그곳에서 나오기 때문입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기