[Glossary] 루프 엔진 완벽 정리
한 줄 요약: 루프 엔진(Loop Engine)이란, AI 에이전트가 주어진 목표를 달성할 때까지 “생각(Thought) → 행동(Action) → 관찰(Observation)” 사이클을 자율적으로 반복 실행하도록 조율하는 에이전트 실행 메커니즘이다.
1. 루프 엔진이란 무엇인가?
체스 AI를 생각해 보세요. “이기기”라는 목표를 향해 상황 분석 → 수 선택 → 결과 관찰의 사이클을 게임이 끝날 때까지 반복합니다. 루프 엔진은 AI 에이전트가 복잡한 작업을 수행할 때 이 사이클을 관리합니다.
루프 엔진은 에이전틱 AI의 심장부입니다. 에이전트가 무한루프에 빠지지 않도록 제어하고, 목표 달성 여부를 판단하며, 적절한 시점에 인간의 확인을 요청합니다.
루프 엔진의 핵심 질문:
- 목표가 달성되었는가?
- 다음에 무엇을 해야 하는가?
- 언제 멈춰야 하는가?
패러다임의 전환: “에이전트에게 프롬프트”에서 “루프를 설계”로
개발자 도구 전문 블로거 Addy Osmani는 그의 글 Loop Engineering에서, 루프 엔진을 다루는 실무가 최근 루프 엔지니어링(Loop Engineering)이라는 별도의 실천 분야로 확장되고 있다고 짚었습니다. 예전에는 사용자가 매번 프롬프트를 입력해 에이전트를 움직였다면, 이제는 “에이전트를 반복 실행시키는 시스템 자체”를 설계하는 방식으로 무게중심이 옮겨가고 있다는 것입니다.
“에이전트에 프롬프트하지 말고, 에이전트에 프롬프트하는 루프를 설계하라.” — Peter Steinberger
“이제 나는 Claude에 프롬프트하지 않는다. 나는 루프를 돈다. 내 일은 루프를 작성하는 것이다.” — Boris Cherny, Claude Code 총괄
즉 루프 엔진은 단일 대화 안에서 Thought-Action-Observation을 반복하는 실행기일 뿐 아니라, 그 루프 자체를 언제·어떻게 돌릴지 설계하는 상위 시스템으로 개념이 넓어지고 있습니다.
2. 핵심 개념 이해하기
ReAct 루프 (가장 기본적인 패턴)
사용자 목표: "파이썬 프로젝트의 모든 테스트를 통과시켜줘"
Iteration 1:
Thought: 먼저 현재 테스트 결과를 확인해야 한다.
Action: bash("pytest tests/")
Observation: "5 failed, 3 passed"
Iteration 2:
Thought: test_auth.py가 실패했다. 코드를 읽어봐야겠다.
Action: read_file("src/auth.py")
Observation: "토큰 만료 처리 누락 발견"
Iteration 3:
Thought: 토큰 만료 로직을 추가해야 한다.
Action: edit_file("src/auth.py", ...)
Observation: "파일 수정 완료"
Iteration 4:
Thought: 다시 테스트를 실행해보자.
Action: bash("pytest tests/")
Observation: "8 passed, 0 failed"
Thought: 목표 달성! 모든 테스트 통과.
Final Answer: 5개 실패 테스트를 모두 수정했습니다.
루프 엔진 제어 메커니즘
| 메커니즘 | 역할 | 예시 |
|---|---|---|
| 최대 반복 횟수 | 무한루프 방지 | max_iterations=20 |
| 목표 달성 판단 | 언제 멈출지 결정 | “테스트 100% 통과 시” |
| 에러 감지 | 반복 실패 처리 | 3회 연속 실패 시 중단 |
| 타임아웃 | 시간 제한 | timeout=300s |
| Human-in-the-loop | 확인 요청 | 파일 삭제 전 승인 요청 |
루프를 구성하는 6가지 요소
단발성 ReAct 루프를 넘어, Codex·Claude Code 같은 실무 도구는 루프를 지속 가능하게 만들기 위해 아래 6가지 구성 요소를 조합합니다. Addy Osmani는 이 중 앞의 5가지를 루프의 뼈대로, 여섯 번째인 메모리를 “잊혀진 6번째 요소”로 꼽습니다.
| 구성 요소 | 역할 | 실제 구현 예시 |
|---|---|---|
| Automations | 루프의 심장. 일정 주기로 자동 발동해 스스로 작업을 분류(triage) | Codex의 Automations 탭 / Claude Code의 /loop 명령, cron 스케줄링, GitHub Actions 연동 |
| Worktrees | 여러 에이전트가 동시에 작업할 때 파일 충돌을 방지하는 병렬 격리 | git worktree 기반, 같은 히스토리를 공유하되 별도 브랜치·디렉터리에서 독립 작동 |
| Skills | 매 세션 같은 컨텍스트를 반복 설명하는 낭비 제거, “의도의 반복 비용”을 외부화 | SKILL.md 폴더(지시문·메타데이터·참조 자료), $skill-name 또는 /skills로 호출 |
| Plugins·Connectors | MCP 기반 커넥터로 루프가 실제 환경(이슈 트래커, DB, API, Slack)과 상호작용 | PR 생성 → 티켓 연결 → CI 통과 시 채널 알림까지 자동화 |
| Sub-agents | 코드 작성과 검증을 분리하는 Maker-Checker 모델 | Codex의 .codex/agents/ TOML 정의 / Claude Code의 .claude/agents/, 에이전트 팀 구성 |
| Memory | 실행 사이의 상태를 대화 컨텍스트가 아닌 디스크에 저장 | Markdown 상태 파일, Linear 보드 등 외부 저장소 |
Sub-agent를 별도로 두는 이유는 명확합니다. 코드를 작성한 모델은 자신의 산출물을 지나치게 관대하게 평가하는 경향이 있기 때문에, 작성자와 검증자를 분리해야 신뢰할 수 있는 완료 판단이 가능합니다.
메모리에 대해서는 다음 원칙이 강조됩니다.
“모델은 실행 사이에 모든 것을 잊는다. 그러므로 메모리는 컨텍스트가 아니라 디스크에 있어야 한다.”
디스크에 기록된 상태(완료된 작업, 다음 작업, 진행 상황)가 있어야 다음 루프 실행이 멈춘 지점부터 이어갈 수 있습니다. 이는 계층적 메모리나 세션 관리 개념과 직접 맞닿아 있습니다.
3. 실무 적용 예시
커스텀 루프 엔진 구현입니다.
import anthropic
from typing import Callable, Any
class AgentLoopEngine:
def __init__(
self,
tools: list[dict],
tool_executors: dict[str, Callable],
max_iterations: int = 20,
system_prompt: str = "당신은 유능한 AI 에이전트입니다."
):
self.client = anthropic.Anthropic()
self.tools = tools
self.tool_executors = tool_executors
self.max_iterations = max_iterations
self.system_prompt = system_prompt
def run(self, goal: str) -> str:
"""목표를 향해 에이전트 루프를 실행합니다."""
messages = [{"role": "user", "content": goal}]
iteration = 0
while iteration < self.max_iterations:
iteration += 1
print(f"\n[반복 {iteration}/{self.max_iterations}]")
# LLM 추론
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=4096,
system=self.system_prompt,
tools=self.tools,
messages=messages
)
messages.append({"role": "assistant", "content": response.content})
# 종료 조건: 도구 호출 없이 텍스트만 반환
if response.stop_reason == "end_turn":
final_text = next(
(b.text for b in response.content if hasattr(b, "text")), ""
)
print(f"[완료] {iteration}번 반복 후 목표 달성")
return final_text
# 도구 실행
if response.stop_reason == "tool_use":
tool_results = []
for block in response.content:
if block.type == "tool_use":
tool_name = block.name
tool_input = block.input
print(f" → 도구 실행: {tool_name}({tool_input})")
executor = self.tool_executors.get(tool_name)
if executor:
result = executor(**tool_input)
print(f" ← 결과: {str(result)[:100]}")
else:
result = f"오류: {tool_name} 도구를 찾을 수 없음"
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result)
})
messages.append({"role": "user", "content": tool_results})
return f"최대 반복 횟수({self.max_iterations}) 초과 — 목표를 완료하지 못했습니다."
# 사용 예시
import subprocess, os
engine = AgentLoopEngine(
tools=[
{
"name": "bash",
"description": "쉘 명령어 실행",
"input_schema": {
"type": "object",
"properties": {"command": {"type": "string"}},
"required": ["command"]
}
}
],
tool_executors={
"bash": lambda command: subprocess.run(
command, shell=True, capture_output=True, text=True
).stdout or subprocess.run(command, shell=True, capture_output=True, text=True).stderr
}
)
result = engine.run("현재 디렉토리의 Python 파일 목록을 확인하고 개수를 알려줘")
print(result)
6가지 요소가 조합된 실제 운영 루프
앞서 설명한 6가지 요소가 실제로는 아래처럼 하나의 순환 구조로 맞물려 돌아갑니다.
1. Automation이 매일 아침 실행
↓
2. Triage Skill 호출 (CI 실패, 이슈, 커밋 분석)
↓
3. 항목별 Worktree 생성 (병렬 격리)
↓
4. Sub-agent 1: 초안 작성 → Sub-agent 2: 검증 (Maker-Checker)
↓
5. Connector: PR 생성, 이슈 트래커 티켓 갱신, Slack 채널 알림
↓
6. Memory(상태 파일)에 진행 상황 저장 → 다음 날 루프가 이어서 재개
4. 루프 엔진 vs 유사 개념 비교
| 구분 | 루프 엔진 | 단일 LLM 호출 | RPA |
|---|---|---|---|
| 반복 처리 | ✅ 자율 반복 | ❌ 1회 | ✅ 스크립트 반복 |
| 자율성 | ✅ 동적 결정 | ❌ | ❌ 고정 흐름 |
| 목표 지향 | ✅ | ❌ | 부분 |
| 예외 처리 | ✅ 적응적 | ❌ | 제한적 |
| 종료 조건 | AI가 판단 | 없음 | 개발자 정의 |
5. 루프 엔진의 한계와 주의점
루프 엔진이 자동화하는 것은 “반복 실행”이지, 판단의 정확성이나 코드에 대한 이해까지 대신해주지는 않습니다. Addy Osmani는 루프 엔지니어링을 도입할 때 특히 아래 세 가지를 경계해야 한다고 강조합니다.
- 검증은 여전히 인간의 책임입니다. 무인 루프는 무인으로 실수도 저지릅니다. 검증을 맡는 서브에이전트 역시 완료를 “증명”하는 것이 아니라 “주장”할 뿐이므로, 결과를 그대로 신뢰해서는 안 됩니다.
- 이해는 방치하면 썩습니다(Comprehension Debt). 루프가 직접 작성하지 않은 코드를 더 빠르게 출시할수록, 코드의 존재와 그것에 대한 팀의 이해 사이의 간극은 오히려 더 빠르게 벌어집니다.
- 편안한 자세는 위험합니다(Cognitive Surrender). 자동화에 익숙해질수록 판단 능력을 잃을 위험이 커집니다. 같은 루프라도 사용자의 의도에 따라 정반대의 결과를 낳을 수 있습니다.
여기에 더해 토큰 비용 관리(token-rich vs token-poor 전략)와 직접 검증-루프 의존 사이의 균형도 실무에서 놓치기 쉬운 부분입니다. 루프는 일을 “쉽게” 만들어 주는 도구가 아니라, 엔지니어가 개입해야 할 지점(leverage point)을 옮겨줄 뿐입니다.
6. 마치며
루프 엔진은 에이전틱 AI를 가능하게 하는 핵심 메커니즘입니다. 초기에는 Thought-Action-Observation을 반복하는 단순한 실행기였지만, 이제는 Automations·Worktrees·Skills·Plugins·Sub-agents·Memory라는 6가지 요소가 맞물린 하나의 시스템, 즉 “루프 엔지니어링”의 대상으로 진화하고 있습니다.
“루프를 만들되, 그저 시작 버튼을 누르는 사람이 아니라 엔지니어로 남을 사람처럼 만들 것.” — Addy Osmani
효과적인 루프 엔진은 에이전트가 목표에 집중하면서도 무한루프, 반복 실패, 예산 초과를 방지합니다. 게임 루프(Game Loop)와 개념이 유사하며, 휴먼 인 더 루프(Human-in-the-Loop)와 결합하면 안전한 자율 에이전트를 구축할 수 있습니다.
참고 자료
- ReAct 논문: Synergizing Reasoning and Acting in Language Models — 루프 엔진의 기반 ReAct 패턴 논문
- LangGraph 에이전트 루프 — 그래프 기반 에이전트 루프 구현
- Loop Engineering: Designing systems that prompt agents — Addy Osmani — 루프 엔지니어링의 6가지 구성 요소와 한계를 정리한 원문
- GeekNews: 루프 엔지니어링 토론 — 위 아티클에 대한 국내 개발자 커뮤니티 논의
함께 읽으면 좋은 용어
이 개념과 함께 알아두면 이해가 깊어지는 관련 용어들입니다.
댓글 남기기