AI Agent Engineering / 3
울타리는 무엇으로 만드는가
AI 펜스 엔지니어링의 구현
목차
LLM은 활기찬 황소다. 힘이 넘치고, 어디로든 돌진할 수 있고, 잘 쓰면 엄청난 가치를 만들어낸다. 하지만 그냥 놔두면 밭을 갈아엎는다.
하네스(harness)는 마구다. 고삐를 잡고, 방향을 지시하고, 한 걸음 한 걸음을 통제한다. 펜스(fence)는 울타리다. 목장의 경계를 치고, 그 안에서는 자유롭게 뛰게 한다.
1편에서 나는 마구를 어떻게 설계할지 이야기했다. 에이전트를 함수처럼 분리하고, 오케스트레이터로 조합하는 것. 2편에서는 울타리를 어떻게 선언할지 이야기했다. 경계를 타입처럼 정의하고, 그 안에서 자율을 허용하는 것.
하지만 한 가지 질문이 남아 있다.
울타리는 대체 무엇으로 만드는가. 나무인가, 철조망인가, 전기 울타리인가. 높이는 얼마여야 하고, 간격은 얼마여야 하는가.
이번 글은 그 이야기를 하려고 한다.
지형 — 시스템 프롬프트
사실 울타리를 세우기 전에 먼저 확인해야 할 것이 있다. 목장의 지형이다.
평평한 들판에 풀어놓은 황소와 경사진 언덕에 풀어놓은 황소는, 같은 울타리 안에서도 다르게 움직인다. 지형 자체가 황소의 기본 걸음걸이를 바꾼다.
에이전트 시스템에서 지형은 시스템 프롬프트다.
const systemPrompt = `
너는 보수적인 데이터 분석가다.
- 수치를 인용할 때는 반드시 출처를 명시한다.
- 확신이 없을 때는 추측하지 않고 "불확실"이라고 답한다.
- 결론을 내리기 전에 최소 2개의 교차 확인을 수행한다.
`이것은 검증이 아니라 사전 제약이다. 출력이 나온 뒤에 울타리에 부딪히는 것이 아니라, 출력이 나오기 전에 걸음의 방향 자체를 기울여놓는 것.
지형의 장점은 거의 공짜라는 것이다. 추가 호출도, 평가 모델도, 파싱 단계도 필요 없다. 단점은 효과가 확률적이라는 것. 황소가 경사를 무시하고 올라갈 수도 있다. 지형은 경향을 만들 뿐, 보장하지 않는다.
그래서 지형만으로는 부족하다. 평평한 목장이라도 반드시 울타리가 필요한 것처럼. 하지만 지형을 신경 쓰지 않고 울타리만 세우면, 황소는 계속 울타리를 때린다. 좋은 펜스 설계는 지형에서 시작한다.
나무 울타리 — 스키마 검증
가장 기본적인 울타리는 나무다. 단단하고, 눈에 보이고, 물리적으로 막는다.
에이전트 시스템에서 나무 울타리는 스키마 검증이다. 출력의 형태를 정의하는 것. JSON Schema, Zod, 구조화된 응답 포맷. 에이전트가 무엇을 리턴해야 하는지를 구조로 선언한다.
const AnalysisOutput = z.object({
conclusion: z.string().min(50),
confidence: z.enum(['high', 'medium', 'low']),
sources: z.array(z.string().url()).min(1),
// 교차 검증 수행 여부를 에이전트가 스스로 리포트하게 한다.
// 물론, 거짓말일 수도 있다. 그래서 뒤에 전기 울타리가 필요하다.
crossValidated: z.boolean(),
})황소가 목장 밖으로 나가려 하면 물리적으로 부딪힌다. 스키마에 맞지 않는 출력은 파싱 단계에서 거부된다. 단단하고 예측 가능하다.
하지만 나무 울타리에는 한계가 있다. 유연하지 않다. 목장의 형태를 바꾸려면 울타리를 뜯어내고 다시 박아야 한다. 그리고 더 근본적인 문제가 있다 — 황소가 정말 힘을 주면, 부러질 수 있다.
스키마를 만족하지만 의미적으로 쓰레기인 출력. confidence: 'high'라고 적혀 있지만 실제로는 근거 없는 주장. sources에 URL이 들어있지만 결론과 무관한 링크. 형태는 맞는데 내용이 없는 것.
이것이 나무 울타리의 한계다. 구조는 강제할 수 있지만, 의미는 강제할 수 없다.
철조망 — 권한 시스템
나무 울타리가 출력의 형태를 잡는다면, 철조망은 행동의 범위를 잡는다.
어떤 도구를 호출할 수 있는지. 어떤 데이터에 접근할 수 있는지. 얼마나 쓸 수 있는지. 토큰 한도, API 호출 제한, 비용 상한, 시간 제약. 이것이 권한 시스템이다.
const AgentPermissions = {
allowedTools: ['search', 'analyze', 'summarize'],
blockedTools: ['execute', 'deploy', 'delete'],
maxTokens: 50_000,
maxApiCalls: 20,
budgetLimit: 5.00, // USD
timeoutMinutes: 30,
}황소가 밖을 볼 수는 있지만 넘을 수는 없다. 에이전트가 도구의 존재를 알고 있어도, 권한이 없으면 호출되지 않는다.
철조망은 나무 울타리보다 가볍고 설치가 쉽다. 하지만 고유의 위험이 있다 — 황소가 다칠 수 있다. 권한 부족으로 태스크 자체가 실패하는 경우. 분석에 필요한 데이터에 접근할 수 없어서 에이전트가 빈 손으로 돌아오는 것.
너무 촘촘하면 황소가 움직이지 못하고, 너무 느슨하면 빠져나간다. 철조망의 간격을 조절하는 것이 곧 권한 세분도(permission granularity)다. 그리고 이것은 2편에서 말한 strict 모드의 트레이드오프와 정확히 같은 문제다.
전기 울타리 — 평가 에이전트
나무 울타리는 구조를, 철조망은 범위를 잡는다. 하지만 둘 다 잡지 못하는 것이 있다. 의미다.
전기 울타리는 평가 에이전트(judge model)다. 물리적 장벽이 아니라 피드백이다. 황소가 경계에 가까이 가면 신호를 보낸다. 실제로 넘으려 하면 제재한다.
const qualityGate = {
evaluator: 'claude-sonnet',
criteria: {
factConsistency: { threshold: 7, weight: 0.3 },
goalAlignment: { threshold: 6, weight: 0.3 },
actionability: { threshold: 5, weight: 0.2 },
noHallucination:{ threshold: 8, weight: 0.2 },
},
// 기준 점수 6.5/10을 통과해야 한다.
// (7×0.3) + (6×0.3) + (5×0.2) + (8×0.2) = 6.5
passScore: 6.5,
scale: 10,
onFail: 'block', // block | warn | retry
}나무 울타리나 철조망과 결정적으로 다른 점이 있다. 전기 울타리는 맥락을 이해한다. 같은 위치에서도 상황에 따라 반응 강도가 달라질 수 있다.
출력이 스키마를 만족하고, 권한 범위 안에 있어도, 의미적으로 목표에서 벗어났는지를 판단할 수 있다. confidence: 'high'라고 적혀 있지만 근거가 빈약한 것. 형식적으로 완벽하지만 프로젝트의 골과 정렬되지 않는 것. 나무 울타리가 못 잡는 것을 전기 울타리가 잡는다.
하지만 전기 울타리에도 비용이 있다. 전기가 필요하다. 평가 에이전트를 돌리는 것은 곧 추가 토큰이고, 추가 비용이고, 추가 지연 시간이다. 그리고 전기 울타리 자체가 오작동할 수 있다 — 평가 모델이 좋은 출력을 거부하거나, 나쁜 출력을 통과시키는 경우.
전기 울타리는 가장 강력하지만, 가장 불안정하기도 하다. 이것은 2편에서 말한 "에이전트는 확률적 존재"라는 전제와 맞닿아 있다. 울타리 자체가 확률적이라는 것.
평가자는 누가 평가하는가
나무 울타리는 결정론적이다. 맞거나 틀리거나. 철조망도 결정론적이다. 있거나 없거나. 그런데 전기 울타리는 같은 황소를 두 번 보고 다른 판정을 내릴 수 있다.
실무적으로는 평가자를 여러 개 돌려 분산을 줄이거나, confidence가 낮은 판정을 에스컬레이션하거나, 사람이 주기적으로 샘플을 라벨링해서 평가자 자체의 정확도를 측정한다. 하지만 "평가자를 평가하는 평가자"를 무한히 쌓을 수는 없다. 어느 층에서는 인간이 내려와 "이 정도면 괜찮다"고 선언해야 한다.
전기 울타리는 자기 자신도 확률적이다. 그래서 한 번 세우고 끝나는 장치가 아니라, 계속 측정해야 하는 장치다.
좋은 목장은 한 종류로 만들지 않는다
현실의 목장이 그렇듯, 좋은 울타리는 하나의 재료로 만들지 않는다.
지형을 먼저 본다. 시스템 프롬프트로 황소의 기본 성향을 정한다. 외곽에 나무 울타리를 세운다. 출력의 형태를 잡는다. 위험 구역에 철조망을 두른다. 행동의 범위를 물리적으로 제한한다. 그 안에 전기 울타리를 깔아둔다. 형태와 범위를 모두 통과한 출력이, 의미적으로도 목표에 정렬되어 있는지를 판단한다.
[지형: 시스템 프롬프트]
└─ [나무 울타리: 스키마 검증]
└─ [철조망: 권한 시스템]
└─ [전기 울타리: 평가 에이전트]
└─ 🐂 에이전트의 자율 영역
레이어다. 바깥에서 안으로 갈수록 비용이 올라가고, 판단이 정교해진다.
다만 이 그림은 공간적 은유일 뿐, 실제 작동은 시간적이다.
| 레이어 | 작동 빈도 | 비용 |
|---|---|---|
| 지형 (시스템 프롬프트) | 세션당 1회 | 공짜 |
| 나무 울타리 (스키마) | 매 호출마다 | 수십 ms |
| 철조망 (권한) | 세션 시작에 1회 | 공짜 |
| 전기 울타리 (평가) | 중요 지점에서만 | 수 초, 비쌈 |
같은 출력이 모든 레이어를 한꺼번에 통과하는 것이 아니다. 각 레이어가 서로 다른 빈도로, 서로 다른 지점에서 작동한다. 스키마 검증은 매 tool call마다 반복되고, 권한은 세션 시작에 한 번 설정되어 정적으로 걸려 있고, 평가 에이전트는 최종 판단 같은 특정 지점에서만 돈다.
설계의 기술은 비싼 판단을 최소한의 지점에서만 돌리는 것이다. 모든 출력에 전기 울타리를 물리면 비용이 10배가 된다. 정말 중요한 결정에만 물려야 한다. 펜스 엔지니어링의 절반은 "무엇을 검증할지"이지만, 나머지 절반은 "얼마나 자주 검증할지"다.
목장의 크기는 황소에 달려 있다
여기서 한 가지 더. 울타리의 재료만큼 중요한 것이 목장의 크기다.
어린 송아지에게는 좁은 울타리 안에서 기본적인 행동을 학습시킨다. 성숙한 황소에게는 넓은 목장에서 자율적으로 움직이게 한다.
모델이 약한 영역에서는 울타리를 좁게 친다. 스키마를 촘촘하게, 권한을 최소한으로, 평가를 엄격하게. 모델이 강한 영역에서는 울타리를 넓힌다. 스키마를 유연하게, 권한을 확장하고, 평가 기준을 완화한다.
하나의 시스템 안에서도 영역마다 목장의 크기가 다를 수 있다. 데이터 수집은 좁은 울타리 안에서 정확히, 분석은 넓은 울타리 안에서 자율적으로. 이것은 2편에서 말한 "TypeScript 프로젝트에서 특정 모듈만 any를 허용하는 것"과 같은 구조다.
그리고 시간이 지남에 따라, 목장은 넓어질 수 있다. 모델이 성장하면, 또는 시스템이 충분한 피드백 데이터를 축적하면, 울타리를 한 칸씩 밖으로 옮길 수 있다. 전기 울타리에서 잡히던 것이 이제 잡히지 않는다면, 그것은 울타리를 넓혀도 좋다는 신호다.
목장 주인의 일
궁극적으로 목장 주인이 매일 하는 일은 뭔가.
울타리를 점검하는 것이다.
어디가 느슨해졌는지. 어디가 너무 촘촘한지. 황소가 특정 구역에만 몰려 있지는 않은지. 나무 울타리가 삭아서 부러지려 하지는 않는지. 전기 울타리의 전압이 너무 높아서 황소가 아예 움직이지 않는 것은 아닌지.
펜스 엔지니어링의 마지막 레이어는 울타리 자체를 모니터링하는 것이다. 울타리를 한 번 세우고 끝나는 것이 아니라, 울타리의 상태를 지속적으로 관찰하고 조정하는 것.
이것은 코드에서 타입을 한 번 선언하고 끝이 아닌 것과 같다. 요구사항이 바뀌면 타입도 바뀌어야 한다. 시스템이 성장하면 인터페이스도 진화해야 한다. 울타리도 마찬가지다. 정적인 울타리는 결국 시스템의 병목이 된다.
세 편을 관통하는 것
1편에서 나는 에이전트를 함수에 비유했다. 관심사를 분리하고, 조합하고, 오케스트레이션하는 것. 하네스 엔지니어링의 핵심은 구조화다.
2편에서 나는 울타리를 타입에 비유했다. 경계를 선언하고, 계약을 정의하고, 자율의 범위를 설정하는 것. 펜스 엔지니어링의 핵심은 선언이다.
3편에서 나는 울타리를 목장에 비유했다. 지형, 나무, 철조망, 전기 울타리. 각 레이어의 역할과 한계, 그리고 비용. 펜스의 구현은 재료의 선택이고, 재료의 선택은 트레이드오프의 연속이다.
세 편을 관통하는 것은 결국 하나다. 이것은 AI만의 새로운 문제가 아니라, 소프트웨어 엔지니어링이라는 오래된 문제의 확장이다.
함수를 잘 쪼개는 감각이 에이전트를 잘 분리하는 감각이 되고, 타입을 잘 선언하는 감각이 경계를 잘 설계하는 감각이 되고, 시스템을 잘 운영하는 감각이 울타리를 잘 점검하는 감각이 된다.
한 가지 정직하게 인정할 것이 있다.
지금 에이전트 시스템을 만드는 사람들이 실제로 보내는 시간의 대부분은, 황소를 뛰게 하는 데가 아니라 울타리를 고치는 데 쓰인다. 새 도구를 추가할 때마다 스키마를 다시 짜고, 권한 테이블을 업데이트하고, 평가 기준을 조정한다. 목장 주인이라기보다 울타리 수리공에 가깝다.
이것이 현재 에이전트 엔지니어링의 현실이다. 그리고 당분간 이 비율은 뒤집히지 않을 것 같다.
그래서 펜스 엔지니어링은 "울타리가 필요 없어지는 날을 위한 준비"가 아니라, 울타리를 계속 다듬어가는 일 자체를 전문성으로 인정하는 것에서 출발해야 한다. 그 위에서 —
울타리가 잘 설계된 목장의 특징은 하나다. 황소가 울타리를 의식하지 않는다는 것이다.