본문으로 건너뛰기

© 2026 Molayo

Qiita헤드라인2026. 06. 27. 16:52

5계층 하네스와 대규모 컨텍스트 관리로 AI 게임 개발 환경 구축하기

요약

AI 에이전트의 신뢰성을 높이기 위한 '5계층 하네스' 구조와 효율적인 대규모 컨텍스트 관리 전략을 소개합니다. 모델의 추론에 의존하는 메모리와 결정론적인 제어 계층을 분리하여 안정적인 개발 환경을 구축하는 방법을 다룹니다.

핵심 포인트

  • 에이전트는 모델과 하네스(제어 환경)의 결합체로 정의됨
  • 메모리, 도구, 권한, 훅, 관찰 가능성의 5계층 하네스 구조 제안
  • 상주 컨텍스트는 최소화하고 상세 내용은 온디맨드로 추출하는 전략
  • CLAUDE.md를 활용한 얇은 색인 중심의 컨텍스트 관리
    1. 서론
    1. 하네스(Harness)라는 개념
    1. 대규모 컨텍스트 관리 (Layer 1 Memory)
    1. Layer 2 Tools
    1. Layer 3 Permissions
    1. Layer 4 Hooks
    1. Layer 5 Observability
    1. 마치며

최근 「하네스 엔지니어링 (harness engineering)」 이라는 개념을 알게 되어, 자신의 개발 환경을 재검토했습니다. Martin Fowler의 기사에서는 AI 에이전트를 「Agent = Model + Harness (에이전트 = 모델 + 하네스)」 라고 파악합니다. 모델(예: Claude 등의 LLM) 그 자체는 우리가 움직일 수 없지만, 그 주변에 구축하는 "하네스(제어의 발판)"가 얼마나 잘 만들어졌느냐가 에이전트의 신뢰성을 크게 좌우한다는 관점입니다.

본 기사에서는 그 발판을 「5계층 하네스」「대규모 컨텍스트 관리」 라는 두 기둥으로 정비한 이야기를 쓰겠습니다. 주제는 게임 개발이지만, 이 사고방식은 다른 프로젝트에도 이식할 수 있을 것입니다.

하네스(harness)란, 「AI 에이전트가 이 프로젝트에서 올바르고, 안전하며, 반복적으로 동작하기 위한 주변 환경 일체」 를 가리킵니다. 저는 이를 다음 5개 계층으로 나누어 정리했습니다. 각 계층이 결정론적(deterministic, 규칙이나 코드로 기계적으로 작동)인지, 비결정론적(non-deterministic, 모델의 해석을 통해 작동)인지도 병기합니다.

계층역할성질
1. Memory에이전트가 항상 참조하는 문맥 (규약·설계·기억)비결정론적 (모델의 해석을 통해 작동)
...

Martin Fowler의 기사에서는 하네스의 제어를 계산적 (computational = 결정적인 도구)추론적 (inferential = AI의 의미적 판단) 으로 구분합니다. 이 관점으로 보면, 5개 계층 중 비결정론적인 것은 Memory뿐이라는 것을 알 수 있습니다. 문맥은 정적인 텍스트일지라도, 그것을 "지킬 것인가"는 모델의 해석에 맡겨지기 때문입니다. 따라서 "Memory가 '부탁'밖에 할 수 없는 불변 조건을, Hooks와 같은 결정론적인 계층이 기계적으로 지킨다"라는 역할 분담이 효과를 발휘합니다.

AI 에이전트에게 거대한 코드베이스를 다루게 할 때, 단순하게는 "모든 정보를 전달하면 된다"라고 생각하기 쉽지만, 매 세션 반드시 읽어 들여야 하는 정보(상주 컨텍스트)에는 비용이 발생하며, 정보가 늘어날수록 효율이 떨어집니다. 그래서 원칙을 하나 정했습니다.

상주는 얇은 색인만 유지하고, 상세 내용은 필요할 때 읽으러 간다 (온디맨드 추출)

상주 (매번 반드시 읽음): 프로젝트 규약의 허브인 CLAUDE.md

및 기억의 한 줄 색인인 MEMORY.md

온디맨드 (필요할 때만 읽음): docs/ 아래의 상세 문서, 각 디렉토리의 README.md, 기억의 본문

CLAUDE.md는 얇게 유지하며, 기준은 200행 이하로 합니다. 상세 내용은 모두 docs/로 빼내고 링크로 참조합니다. "색인은 상시 / 상세 내용은 요청 시"라는 형태로 효율적인 추출이 가능하도록 합니다.

CLAUDE.md를 리포지토리 루트에 두면 모든 세션에서 자동으로 읽어 들입니다. 여기에는 "어기면 즉시 망가지는 불변 조건"과 "매번 사용하는 절차"만을 적고, 그 외에는 한 줄 요약 + 링크로 docs/에 위임합니다. 저의 구성은 다음과 같습니다.

0. 리포지토리 지도
1. 빌드와 검증
2. 인코딩
...

상세 문서는 docs/에 두며, 역할별로 디렉토리를 나누었습니다. "현황 (architecture)", "이유 (adr)", "작성법 (conventions)"을 나누어 두면, 에이전트가 목적에 따라 필요한 선반만 열 수 있습니다. 실제 구성은 다음과 같습니다.

docs/
├── architecture/ # 현재 어떻게 되어 있는가 (현상 시스템 해설)
│ ├── overview.md
...

각 파일은 얇은 CLAUDE.md에서 링크되어 있으며, 에이전트는 필요한 것만 읽으러 갑니다.

ADR (Architecture Decision Record)은 "하나의 중요한 설계 판단을 배경·결정·결과의 3가지 점으로 남기는 짧은 문서"로, 코멘트에 적으면 흘러가 버리는 "판단의 이유"를 여기에 고정합니다.

conventions/에는 명명·코멘트·배치 규약을, src/

각 디렉터리에는 「역할·포함 내용·관련 사항」을 적은 README.md를 배치하여 에이전트의 기준을 통일하고 있습니다.

CLAUDE.md가 Git에 올라가는 공유 컨텍스트(Context)라면, 기억(Memory)은 세션을 넘나들며 유지되는 개인적인 컨텍스트입니다. 작업상의 선호도나 기획의 뼈대를 여기에 남기며, MEMORY.md가 한 줄 색인 역할을 하고 본문은 필요할 때 확장됩니다.

상주 파일(CLAUDE.md / MEMORY.md)이 비대해지면 본말전도이므로, 크기를 정기적으로 점검하고 비대해질 것 같으면 분할하거나 가지치기를 합니다.

자주 사용하는 작업은 슬래시 커맨드(Slash Command)로 만들었습니다. 가장 효과적인 것은 빌드입니다. 전체 빌드를 수행하는 /build와 단일 파일만 빠르게 구문 검사(Syntax Check)하는 /build-file.claude/commands/에 배치했습니다.

커맨드 파일은 프론트매터(Frontmatter, description) + 지시문 + 실행 커맨드로 구성됩니다. .claude/commands/build.md는 다음과 같은 형태입니다.

---
description: Debug/x64에서 전체 빌드를 수행하고 C4828/C4819를 제외한 error 및 warning Cxxxx만 표시한다
---
...

본체 빌드 커맨드(기존의 경고 노이즈인 C4828/C4819를 제외하고 포착)는 다음과 같습니다.

& "C:\Program Files\Microsoft Visual Studio\18\Community\MSBuild\Current\Bin\MSBuild.exe" `
"D:\DirectX11GameProjects\ActionGame3D\ActionGame3D.vcxproj" `
/p:Configuration=Debug /p:Platform=x64 /m /nologo /v:minimal /t:Build |
...

/build-file/t:Build/t:ClCompile /p:SelectedFiles="src\…\X.cpp"로 교체한 것으로, 단일 파일을 실제 프로젝트 설정 그대로 약 4초 만에 구문 검사할 수 있습니다. 매번 커맨드를 조합해야 하는 번거로움과 조합 실수를 없애줍니다.

허가(Permission) 설정은 그대로 두면 자동으로 계속 쌓입니다(제 경우에는 100건 이상 쌓여 있어서, 솔직히 무엇을 허가했는지 스스로도 파악하지 못하고 있었습니다). 이를 정리하기 위해 실제 세션 기록(Transcript)을 분석하여 빈번하게 발생하는 읽기 전용 커맨드만 추출하고, 커밋하는 쪽의 .claude/settings.json에 다시 정리했습니다.

{
"permissions": {
"allow": [
...

포인트는 안전한 방향으로 설정하는 것입니다. Get-ChildItem이나 Test-Path와 같은 읽기 전용은 허가하더라도, Remove-Item과 같은 파괴적인 명령이나 임의 코드를 실행할 수 있는 python / Add-Type의 와일드카드는 절대로 허가하지 않도록 했습니다.

훅(Hooks)은 도구 실행 전후에 자동 처리를 끼워 넣는 메커니즘입니다. 저는 여기서 인코딩 자동 보정을 도입했습니다.

제 프로젝트에는 「C++은 UTF-8 BOM 포함, HLSL은 BOM 미포함 필수(BOM이 있으면 D3DCompile에서 X3000 에러 발생)」라는 불변 조건이 있습니다. 그런데 에이전트가 파일을 작성하면 기본적으로 BOM이 붙지 않아, 새로 생성된 C++ 파일이 규약 위반이 된다는 것을 실측을 통해 확인했습니다.

그래서 PostToolUse(쓰기 작업 후) 훅을 .claude/settings.json에 추가하고 보정 스크립트를 실행하도록 했습니다.

{
"hooks": {
"PostToolUse": [
...

호출되는 fix-encoding.ps1은 stdin으로 전달되는 JSON으로부터 대상 파일을 받아 확장자를 확인한 뒤, BOM을 추가하거나 제거합니다.

# PostToolUse hook: C++는 UTF-8 BOM 포함 / HLSL은 BOM 미포함으로 보정 (비차단형)
$ErrorActionPreference = 'SilentlyContinue'
try { $j = [Console]::In.ReadToEnd() | ConvertFrom-Json } catch { exit 0 }
...

작성 직후에 조용히 올바른 인코딩으로 수정해 줍니다 (실제 운영 버전에서는 보정했다는 사실을 additionalContext로 보고하게 하여, 사이런트(silent)한 쓰기 작업을 가시화하고 있습니다).

훅(Hook)은 도구 실행 후에 파일을 다시 쓰기 때문에, 에이전트의 파일 상태 추적과 간섭이 일어나지 않는지 주의가 필요합니다. 저는 차단(Blocking)하지 않는 PostToolUse를 선택하였고, 스크립트 단독 동작(C++ → BOM 추가, HLSL → BOM 제거)을 모의 입력으로 검증한 뒤 상용화했습니다. 어기면 즉시 망가지는 규약은 사람의 주의력이 아니라 이 계층에서 기계적으로 지키게 하는 것이 안전하다고 생각합니다.

마지막으로 관측 가능성(Observability)에 대해 말씀드리자면, 이는 사실 거의 기존 메커니즘만으로도 충분합니다. Claude Code는 세션의 트랜스크립트(Transcript)를 JSONL로 전부 기록하고 있으며, 어떤 도구를 어떻게 호출했는지는 나중에 집계할 수 있습니다.

이 부분은 JSON 설정이라기보다 환경 변수를 통해 제어하며, 메트릭(Metrics)을 보고 싶을 때만 OpenTelemetry의 익스포트(Export)를 활성화합니다.

$env:CLAUDE_CODE_ENABLE_TELEMETRY = "1"
$env:OTEL_METRICS_EXPORTER = "otlp"
$env:OTEL_LOGS_EXPORTER = "otlp"
...

불필요하게 중복되는 감사 로그(Audit log)는 추가하지 않고, "트랜스크립트 읽는 법"과 이 OTEL 절차만을 문서화했습니다.

효과적이었던 설계 판단을 3가지로 요약하면 다음과 같습니다.

  • 상주 정보는 가볍게, 상세 정보는 온디맨드(On-demand)로. 매번 읽어야 하는 문맥은 인덱스(CLAUDE.md / MEMORY.md)로만 제한하고, 상세 내용은 docs/에서 필요할 때 찾아본다. 이것이 대규모 컨텍스트(Large Context)를 붕괴시키지 않는 핵심이었습니다.
  • 문서는 실제 코드로 검증한다. AI에게 전달하는 문맥일수록 그럴듯한 오류를 섞지 않는 것이 중요합니다.
  • 불변 조건은 하네스(Harness)로 기계적으로 지킨다. 인코딩처럼 어기면 즉시 망가지는 규약은 인간(이나 AI)의 주의력에 의존하지 않고, 훅(Hook)을 통해 자동으로 보정하게 한다.

"5계층 하네스"는 어디까지나 분류를 위한 도구이며, AI 에이전트를 이 프로젝트 고유의 상황에 맞춰 올바르게 작동시키기 위한 발판을 만드는 작업입니다. 이는 한 번 만들고 끝내는 것이 아니라, 요구사항과 어긋나면 업데이트하고 필요하다면 능동적으로 내용을 추가해 나가는 운영 방식으로 가져갈 것입니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0