에이전트 자기개선 하네스 (1/12) — 정적 identity와 런타임 SOUL 분리

문제 — 같은 이름의 두 파일, drift 47%

AI 에이전트의 "인격" 데이터는 두 층으로 나뉩니다. 거의 변하지 않는 정적 정체성(가치, 세계관, 역량 정의)과, 세션마다 업데이트되는 동적 상태(러닝 노트, 관찰 기록, 사용자 insight). 한 파일에 두 층을 섞어두면 편집 주체가 경합하면서 drift가 누적됩니다.

실제로 한 에이전트의 SOUL 정체성 파일이 repo(persona/)와 런타임(hermes-data/) 양쪽에 중복 존재하던 상태에서:

  • 초기 템플릿(repo, 16KB) ↔ 실사용본(런타임, mir self-edit 누적 24KB)
  • 두 파일 차이 47%
  • USER.md는 더 심각 — repo는 정적 프로필, 런타임은 §-구분된 insight 누적본으로 완전히 이질적인 파일

근본 원인은 "한 파일에 두 편집 주체를 두었다"는 점입니다. 관리자 수동 편집과 에이전트 self-edit이 같은 경로를 공유하면 어느 한쪽이 언제나 뒤처지거나 덮어쓰여집니다.

설계 — 편집 주체로 경로를 나누는 하이브리드(C안)

해결책은 두 층을 명시적으로 분리하고 각 층에 authoritative 경로를 하나씩만 두는 것입니다.

정적 identity — repo 단일 소스

경로 역할 편집 주체
persona/ONTOLOGY.md 4-layer identity framework 관리자
persona/VALUES.md 가치 우선순위, 판단 규칙 관리자
persona/BEING.md 기질, 세계관, 비타협 원칙 관리자
persona/CAPABILITIES.md 기술/메타스킬/지식 도메인 관리자
persona/LIFE_PROJECT_PLAN.md 프로젝트 방향성 관리자

동적 슬롯 — 런타임 단일 소스

경로 역할 편집 주체
hermes-data/SOUL.md 실행 중 주입 SOUL 관리자 + mir self-edit
hermes-data/memories/USER.md 사용자 insight 누적 에이전트 memory tool
hermes-data/memories/MEMORY.md 세션 memory 에이전트 memory tool

역사 파일(persona/SOUL.md, persona/USER.md)은 사용 중단 처리. 복사 로직을 담당하던 persona/loader.sh는 deprecate하고 --uninstall 경로만 유지.

구현 — 멱등 일방향 ingest

정적 identity를 memcore(SQLite 기반 curated 메모리)로 흘려보내는 경로는 스크립트 하나로 단순화합니다.

persona/*.md (repo 단일 소스)
       │
       ▼  scripts/persona-ingest.py  (관리자가 명시적 실행)
       │
       ▼
memcore curated
  source_path = "persona/<file>.md"

동작 원칙:

  • 방향: repo → memcore 단방향. 역흐름 없음.
  • 멱등성: DELETE+INSERT 패턴. 재실행 시 prior N rows → inserted N rows, 변화 없음.
  • 추적자: source_path에 고유 경로 기록. 역추적 가능.
  • 청크-row 일치: 파일 내 H2 섹션 수 = curated row 수. 파일 구조와 저장 구조가 1:1 매핑.

자동 훅은 붙이지 않습니다. persona 변경 빈도는 연간 수 회 수준이라 부트마다 ingest할 동기가 없고, 변경 타이밍은 관리자가 직접 판단해야 하는 영역입니다.

검증 — 6축 체크리스트

파일 분리만으로는 "구조적 거버넌스"가 되지 않습니다. 다음 6축이 모두 PASS여야 의미가 있습니다.

  1. 멱등성 — 드라이런 / 실행 / 재실행 모두 같은 row 수
  2. 청크-row 일치 — H2 섹션 수 = curated 수
  3. 추적자 — source_path 고유값이 파일 수와 일치
  4. features-sync 무결성 — memcore wiki와 기존 엔트리 전량 unchanged (drift 없음)
  5. wiki 반영 — 피처 문서 섹션이 curated에 동기화됨
  6. 롤백 경로 — uninstall 스크립트로 역사 파일 복원 가능

6축 중 하나라도 FAIL이면 "그냥 파일 두 곳에 두는 것"과 다를 바 없습니다.

효과 — drift가 발생할 경로 자체의 제거

분리 이후 drift가 발생할 수 있는 경로 자체가 사라집니다. 정적 identity는 repo → memcore 한 방향으로만 흐르고, 런타임 SOUL은 hermes-data/에서 직접 편집됩니다. 두 경로가 교차하지 않기 때문에 "어느 쪽이 최신인가?"라는 질문 자체가 성립하지 않습니다.

부수 효과: 관찰 지점도 명확해집니다. 런타임 SOUL 크기가 토큰 예산을 초과(~8.3K 토큰, 권장 3K의 2.7배)하는 상황은 hermes-data/ 한 곳만 보면 되고, repo 파일의 변경 이력은 git log로 충분합니다. 책임이 나뉘면 모니터링 대상도 나뉩니다.

적용 — 일반화 가능한 패턴

이 분리 패턴은 "관리자 편집과 에이전트 self-edit이 섞이는 모든 설정 파일"에 일반화할 수 있습니다.

  • 시스템 프롬프트 + 러닝 노트 → templates/ (repo) + runtime/notes.md (runtime)
  • 도구 명세 + 도구 사용 통계 → tools/schemas/ (repo) + runtime/usage-log.db (runtime)
  • 에이전트 역할 정의 + 역할 수행 기록 → roles/ (repo) + runtime/role-history.md (runtime)

공통 원칙: 한 파일에 두 편집 주체를 두지 말 것. 편집 주체가 다르면 파일을 다르게 두고, 한 방향으로만 흐르게 설계하면 drift 자체가 발생하지 않습니다.

결론

파일 분리는 사소해 보이지만, 편집 주체가 섞여 있던 구조에서는 결정적 전환입니다. drift 감지·해소 비용이 사라지고, 한쪽에 생긴 문제가 다른 쪽에 전파되지 않습니다. "단일 소스" 원칙은 단순한 문서 정리가 아니라 구조적 격리 장치입니다. 멱등 일방향 ingest + 6축 검증을 동반했을 때만, 분리가 실제 거버넌스로 작동합니다.

참조

  • persona/module.yaml v2.0 — 하이브리드 규칙 + deprecated 섹션
  • scripts/persona-ingest.py — 멱등 ingest 구현
  • docs/operations/features/persona-loader.md — 피처 명세
  • docs/operations/persona-loader-verification-2026-04-21.md — 6축 검증 리포트

시리즈 전체 안내: 시리즈 목차

댓글

이 블로그의 인기 게시물

"LLM 핵심 학습 (1/6) — 기본: 토큰화·임베딩·어텐션·위치 인코딩"

"LLM 핵심 학습 (2/6) — 파인튜닝: LoRA·QLoRA·증류·Adapter"

"ML 기초 학습 (1/9) — 머신러닝과 sklearn: 학습의 좌표계"