
샌드위치 아키텍처 (The Sandwich Architecture): 확률론적 LLM을 결정론적 코드(Deterministic Code)로
요약
확률론적 LLM의 불확실성을 제어하기 위해 결정론적 코드 레이어로 감싸는 '샌드위치 아키텍처'를 제안합니다. 에이전트가 지식 베이스나 SOP를 무시하는 문제를 해결하기 위해 Pre-hook과 Post-hook을 활용한 구조적 설계를 다룹니다.
핵심 포인트
- LLM의 확률론적 특성으로 인한 에이전트의 지식 검색 누락 문제 지적
- 결정론적 Pre-hook과 Post-hook 레이어를 통한 아키텍처 설계
- 강제적 컨텍스트 주입 및 출력 검증을 위한 Python 코드 구현 방법
- 작업당 세션 분리 및 장면 격리를 통한 에이전트 안정성 강화
샌드위치 아키텍처 (The Sandwich Architecture): 확률론적 LLM을 결정론적 코드(Deterministic Code)로 감싸기
고통스러운 지점 (The Pain) — 에이전트(Agent)에게 지식 베이스(Knowledge base)를 제공하고, 표준 운영 절차(SOPs)를 작성하며, 스킬 팩(Skill pack)을 구축했습니다. 하지만 실행할 때 에이전트는 지식 베이스를 건너뛰고 스스로 추측하거나, SOP 흐름을 완전히 무시합니다. 프롬프트(Prompt)를 튜닝하고 도구(Tools)를 더 많이 추가할수록, 에이전트는 더 많이 "망각"합니다.
학습 내용:
- "에이전트가 검색 여부를 결정하게 두는 것"이 왜 행동의 특이점이 아니라 설계 결함인지
- 샌드위치 아키텍처 (The Sandwich Architecture): 하나의 확률론적 LLM 레이어를 감싸는 두 개의 결정론적 레이어 (Pre-hook 및 Post-hook)
- 강제적 컨텍스트 주입(Context injection), 제약된 추론(Constrained reasoning), 그리고 재시도(Retry)를 통한 출력 검증(Output validation)을 위한 실행 가능한 Python 코드
- 세 가지 추가 강화 조치: 작업당 새로운 세션, 장면 격리(Scene isolation), 그리고 20가지 케이스의 평가 세트(Eval set)
이 문제는 매우 흔해서 별도의 포스트를 작성할 가치가 있습니다. 만약 지식 베이스, 표준 운영 절차(SOP), 그리고 몇 가지 도구를 갖춘 에이전트를 배포했는데, 에이전트가 즉흥적으로 행동하는 것을 본 적이 있다면 이 글이 도움이 될 것입니다.
1. 문제점: 확률의 해변 위에 구축한 당신의 "결정론 (Determinism)"
일반적으로 에이전트에게 제공하는 것은 다음과 같습니다:
- SOP → 시스템 프롬프트(System Prompt)에 작성됨
- 지식 베이스 (Knowledge base) → 도구(Tool)로 노출되어, 에이전트가 이를 쿼리할지 여부를 결정하게 함
- 스킬 팩 (Skill pack) → 에이전트 측에 부착됨
하지만 실행 시, 에이전트는 지식 베이스를 쿼리하는 것을 "망각"하고 SOP를 "따르는 데 실패"합니다. 익숙한 상황인가요?
근본 원인은 멍청한 에이전트가 아닙니다. 잘못된 아키텍처입니다.
LLM은 본질적으로 확률론적 모델(Probabilistic model)입니다. "지식 베이스를 검색해야 하는가?"라는 결정을 확률론적 모델에 맡기는 것은, 충분한 호출이 이루어지는 동안 에이전트가 주의력 이탈(Attention drift), 컨텍스트 오버플로(Context overflow), 또는 검색을 건너뛰게 만드는 "나는 이미 이것을 알고 있다"는 환상에 빠지지 않을 것이라고 도박을 하는 것과 같습니다. 에이전트는 결국 검색을 건너뛸 것입니다. 에이전트가 고장 났기 때문이 아니라, 그것이 확률론적 샘플링(Probabilistic sampling)이 분포의 꼬리 부분(Tail of the distribution)에서 수행하는 방식이기 때문입니다.
그것은 에이전트(Agent)의 잘못이 아닙니다. 당신은 확률론적인 자기 통제(probabilistic self-discipline) 위에 결정론적인 프로세스(deterministic process)를 고정(anchor)해 두었기 때문입니다.

샌드위치 아키텍처 (The Sandwich Architecture): 결정론적 코드(deterministic code)가 양쪽에서 확률론적 LLM을 감싸는 것 — 이것이 핵심 비결입니다.
2. 해결책: 샌드위치 아키텍처 (The Sandwich Architecture) — 확률론적 LLM을 감싸는 결정론적 코드
2024년에서 2026년 사이, 업계는 하나의 핵심적인 합의점에 도달했습니다. Anthropic, LangChain, OpenAI, 그리고 Google의 실무자들은 계속해서 동일한 점을 강조하고 있습니다:
프로세스가 고정된 비즈니스 시나리오의 경우, 모든 것을 스스로 결정하는 완전 자율형 에이전트(fully autonomous Agent)를 구축하지 마십시오. 인지적 결정 지점(cognitive decision points)에서만 LLM을 호출하는, 결정론적 코드(deterministic code)에 의해 구동되는 시스템을 구축하십시오.
이것이 바로 **샌드위치 아키텍처 (Sandwich Architecture)**입니다. 즉, 두 개의 결정론적 코드 레이어가 한 개의 확률론적 LLM 추론 레이어를 샌드위치처럼 감싸는 구조입니다.
+-----------------------------------------------------------------+
| PRE-HOOK | DETERMINISTIC CODE |
| load_sop . vector_db.search . inject into prompt |
...
에이전트가 반드시 알아야 하는(know) 모든 것은 에이전트가 생각하기 전에 코드를 통해 주입됩니다. 에이전트가 생산하는(produces) 모든 것은 에이전트가 답변한 후에 코드를 통해 검증됩니다. 확률론적 모델에게 남겨진 유일한 역할은 그 사이의 추론(reasoning)이며, 바로 이 지점에서 확률론적 특성이 실제로 도움이 됩니다.
상단 레이어: Pre-hook — 에이전트에게 객관식 시험을 치르게 하지 마십시오
잘못된 접근 방식: 지식 베이스(knowledge base)를 도구(Tool)로 노출하고, 에이전트가 자신의 루프 안에서 이를 호출할지 여부를 스스로 결정하게 하는 것입니다. 검색(retrieve) 여부에 대한 결정이 20가지 선택지 중 하나가 되어버리며, 에이전트는 이를 놓치게 됩니다.
올바른 접근 방식: 작업이 에이전트에게 도달하기 전에, 코드가 강제로 지식 베이스를 검색하여 그 결과를 시스템 프롬프트(System Prompt)에 직접 주입합니다. 에이전트에게는 선택권이 주어지지 않습니다.
def prepare_context(scene_id, task_data):
# 1. 항상 이 장면(scene)에 대한 SOP를 가져옵니다
sop = load_sop(scene_id)
...
✅ 프로덕션 검증 완료: 저는 매일 정확히 이 코드를 실행합니다. 에이전트가 "눈을 뜨는" 순간, SOP와 지식은 이미 그 앞의 테이블 위에 놓여 있습니다. "질의를 해야 할까?"라는 선택지는 존재하지 않습니다. 에이전트가 존재하기도 전에 그 질문 자체가 제거되었기 때문입니다.
🩸 함정 (Pitfall): 저의 첫 번째 버전은 지식 베이스(Knowledge Base)를 도구(Tool)로 노출하여 에이전트가 직접 호출할 수 있게 했습니다. 첫 주에는 괜찮았습니다. 하지만 2주 차부터 에이전트는 검색(Retrieval) 과정을 점점 더 자주 건너뛰기 시작했습니다. 강제 주입(Forced Injection) 방식으로 전환한 후에야 이 문제는 완전히 사라졌습니다.
💼 가치 (Value): "검색 여부"가 객관식 질문에서 필수 단계로 변합니다. 실행률이 99%가 아닌 100%가 됩니다.
🧠 인지적 업그레이드 (Cognitive upgrade): 에이전트를 상용화하기 위한 제1원칙 — 선택권을 확률에 맡기지 마십시오.
중간 계층: 추론 계층 (Reasoning Layer, 에이전트) — 추론만 하되, 결정하지 마라
이 계층은 여러분이 이미 가지고 있는 에이전트와 같지만, 세 가지 제약 조건이 추가됩니다:
def run_agent(scene_id, task_data):
context = prepare_context(scene_id, task_data)
...
Temperature 0.1. 프로덕션 환경에서 Temperature(온도)는 0.1 이하여야 합니다. 0.7은 시를 쓰기 위한 것이지, 비즈니스 태스크를 처리하기 위한 것이 아닙니다. 엔트로피(Entropy)가 추가될 때마다 출력값이 SOP에서 벗어날 기회가 생깁니다.
도구 화이트리스트 (Tool whitelist). 각 장면(scene)은 해당 장면에 필요한 도구만을 마운트합니다. 만약 장면 A에 search_web이 필요하지 않다면, 도구 세트에서 물리적으로 제거하십시오. 선택지가 적을수록 잘못된 길로 빠질 확률도 줄어듭니다.
최대 턴 수 (Max turns). 루프(Loop)에 엄격한 상한선을 설정하여 에이전트가 재시도 사이클 내에서 영원히 회전할 수 없도록 합니다.
하단 계층: 포스트 훅 (Post-hook) — 완료될 때까지 종료 불가
에이전트가 출력을 마쳤다고 해서 태스크가 완료된 것은 아닙니다. 코드 계층에서 출력이 규정을 준수하는지 확인합니다:
def validate_and_retry(scene_id, task_data, max_retries=3):
for attempt in range(max_retries):
# 에이전트 실행
...

사후 처리 게이트(Post-hook gate): 도구 호출(tool calls) 검증 → 출력(output) 검증 → 재시도(최대 3회) → 사람에게 에스컬레이션(escalate).
✅ 프로덕션 환경에서 검증됨: 이것은 제 시스템의 handoff_to_yuanbao.py 모듈에 적용된 로직입니다. 제가 발행하는 모든 기사는 외부로 나가기 전 정확히 이 게이트를 통과합니다.
🩸 함정(Pitfall): 초기 버전은
모든 상황(scene)을 처리하는 하나의 "슈퍼 에이전트 (super Agent)"를 만들지 마세요. 단일 에이전트의 폭발 반경 (blast radius)이 커질수록, 에이전트가 이탈 (drift)할 수 있는 방법도 많아집니다.
잘못된 접근 방식: 하나의 에이전트 + 10개의 상황을 위한 SOP + 20개의 도구.
올바른 접근 방식:
라우터 (Router) -> 상황을 감지 -> 해당 상황 전용 에이전트로 배정
전용 에이전트는 해당 상황의 SOP + 최소한의 도구 세트만 보유
세 개의 도구를 가진 특정 상황 전용 에이전트는 20곳이 아닌 3곳에서만 실패합니다. 격리 (Containment)는 하나의 기능입니다.
단계 3: 평가 세트 (Eval Set) 구축하기
20개의 전형적인 작업이면 충분합니다. 프롬프트, 도구, 또는 SOP를 변경할 때마다 평가 세트를 실행하여 에이전트가 여전히 SOP를 따르는지 확인하세요. 이는 어렵지 않습니다. 제 툴킷에 있는 evals_writing.py와 동일한 개념입니다. 즉, 고정된 입력 세트, 요구되는 행동의 체크리스트, 그리고 사례별 통과/실패 판정이 있는 것입니다.
4. 당신은 현재 어디에 있는가
당신은 더 이상 프롬프트를 계속 수정하고, 에이전트에 도구를 덧붙이며, 에이전트가 스스로 SOP를 지키며 자제하기를 바라는 디버거가 아닙니다. 당신은 확률론적 LLM을 결정론적 코드 (deterministic code)로 감싸는 시스템 설계자가 되어가고 있습니다.
- 지식 베이스 (knowledge base)는 에이전트가 쿼리하는 용도가 아닙니다. 코드가 에이전트를 대신해 쿼리하고 그 결과를 에이전트의 입에 직접 넣어줍니다.
- SOP는 에이전트가 읽는 용도가 아닙니다. 코드가 에이전트가 실제로 이를 실행했는지 확인합니다.
- 루프 (Loop)는 에이전트가 자유롭게 돌아다니는 공간이 아닙니다. 코드가 에이전트가 올바른 궤도에 있는지 계속 재확인하게 만듭니다.
기억하세요: "망각" 문제의 90%는 모델의 자제력이 아니라 아키텍처에 의해 해결됩니다.
핵심 요약 — 엔티티 (Entities): Hermes Agent, Harness Engineering, Loop Engineering. 가치 (Value): 에이전트 상용화, SOP 프로세스 강화, 결정론적 아키텍처. 인지 (Cognition): 프롬프트 튜닝에서 샌드위치 아키텍처로 — 확률론적 LLM을 감싸는 결정론적 코드.
저자 소개: Wu Ji (无记) — 에이전트 엔지니어링 (Agent engineering), 루프 엔지니어링 (Loop Engineering), 디지털 전환에 집중하는 AI 및 디지털화 실무자. 실용적이고 직접적인 튜토리얼 — 따라 하기만 하면 바로 작동합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기