-
에이전트의 다섯 가지 본질 — 루프·도구·맥락·정지·신뢰IT 2026. 6. 6. 21:00
에이전트라는 단어가 지금 코딩 도구 시장을 뒤덮고 있다. Claude Code, Codex, Antigravity처럼 성숙한 도구들을 나란히 놓아 보면 표면은 달라 보이지만, 안을 들여다보면 같은 구조로 수렴한다. 어느 도구가 더 낫냐는 비교보다 중요한 질문이 있다 — 에이전트라는 구조 자체의 본질이 무엇인가.
이 글은 그 본질을 다섯 가지 핵심 요소로 해부한다. 루프, 도구, 맥락, 정지 조건, 신뢰 경계 — 이 다섯이 모두 갖춰져야 에이전트이고, 하나라도 빠지면 에이전트처럼 보이는 챗봇이거나, 통제할 수 없는 자동화 스크립트다.
① 루프 — 에이전트를 에이전트로 만드는 한 가지
챗봇과 에이전트를 가르는 가장 단순하고 핵심적인 차이는 루프다. 챗봇은 단방향이다. 사람이 입력을 주면 LLM이 텍스트를 생성하고 끝난다. 결과가 맞는지 틀린지, 목표가 달성됐는지 아닌지를 판단하는 건 사람의 몫이다. 에이전트는 다르다. 목표를 받으면 관찰→계획→행동→검증의 단계를 묶어 루프를 돌린다. 검증에서 목표가 달성됐으면 루프를 나오고, 아니면 다시 관찰부터 시작한다.
다이어그램 설명. 왼쪽 챗봇은 목표→LLM→답변의 직선 흐름이다. 한 번으로 끝난다. 오른쪽 에이전트는 관찰→계획→행동→검증이 닫힌 루프를 이루고, 검증에서 성공이 확인될 때만 루프를 나온다(초록 화살표). 핵심은 행동 이후 검증이 있다는 것 — 에이전트는 자기 행동의 결과를 스스로 확인하고 방향을 조정한다.
루프가 왜 중요한지는 "없으면"을 생각하면 분명해진다. 코드 버그를 고쳐달라는 요청을 받았다고 하자. 챗봇은 코드를 텍스트로 받아 수정된 코드를 반환한다 — 거기서 끝이다. 수정이 실제로 버그를 고쳤는지는 알 수 없다. 에이전트는 수정 후 테스트를 실행한다. 테스트가 실패하면 실패 이유를 관찰하고 다시 계획한다. 이 루프를 테스트가 통과할 때까지 반복한다. 같은 목표를 받아도 신뢰할 수 있는 결과를 얻는 구조가 근본적으로 다르다.
② 도구 — 세계에 닿는 손
루프가 있어도 도구가 없으면 에이전트는 텍스트 안에 갇혀 있다. LLM은 언어 모델이다 — 파일을 실제로 읽거나, 명령을 실행하거나, API를 호출하는 능력이 기본 내장되어 있지 않다. 이 행동들을 가능하게 하는 것이 도구(tool)다. 도구 없는 루프는 현실 세계에 아무 영향도 미치지 못하는 독백이다.
도구의 의미를 구체적으로 이해하려면 "없을 때"를 상상해 보면 된다. 코드베이스에서 특정 함수가 어디에 쓰이는지 알고 싶다면? 도구 없는 LLM은 사람이 복사해서 붙여 넣어 준 내용에서만 답할 수 있다. 파일을 읽는 도구가 있으면 LLM이 직접 파일을 열고, grep으로 용례를 찾고, 연관 파일로 이동한다. 그 차이가 "AI에게 대신 물어보는 것"과 "AI가 직접 조사하는 것"의 차이다. 루프가 에이전트를 자율적으로 만든다면, 도구는 에이전트를 현실적으로 만든다.
어떤 도구를 어떻게 노출하느냐는 에이전트 설계의 핵심 변수다. 도구가 많을수록 에이전트의 능력 범위가 넓어지지만, 매 루프마다 컨텍스트에 적재해야 할 도구 정의(이름·인자·설명)도 늘어난다. 이게 다음에서 다룰 맥락 문제와 직접 연결된다.
③ 맥락 — 에이전트의 유일한 작업 기억
에이전트가 매 루프마다 "무엇을 보고 판단하는가"를 결정하는 것이 맥락 창(context window)이다. 시스템 지침, 도구 정의, 이전 루프의 결과, 현재 파일 내용 — 에이전트가 판단에 쓰는 모든 정보가 이 창 안에 있어야 한다. 창에 없는 것은 에이전트에게 존재하지 않는 것과 같다.
문제는 이 창이 유한하다는 점이다. 백만 토큰짜리 대형 창도 마찬가지다. 수십만 줄 코드베이스, 수십 번의 루프 기록, 수백 개의 도구 정의는 어떤 창이든 결국 채운다. 루프가 반복될수록 이전 루프의 결과가 누적되면서 여유 공간이 줄어든다. 창이 꽉 차면 LLM은 가장 먼저 들어온 내용부터 잘라낸다 — 그게 바로 시스템 지침과 목표 정의다. 에이전트가 자기가 무엇을 해야 하는지, 어떤 규칙을 지켜야 하는지를 잊기 시작한다.
다이어그램 설명. 위 막대는 루프 초기 맥락 창이다. 지침(파랑)·도구 정의(보라)는 항상 자리를 차지하고, 이전 루프 결과(노랑)와 현재 파일(회색)이 그 뒤를 채운다. 여유 공간이 넉넉하다. 아래 막대는 루프를 4회 반복한 후다. 이전 결과 누적이 창의 절반을 차지하고, 여유 공간이 거의 사라졌다(빨간 ⚠). 이 상태에서 다음 루프가 돌면 초반 지침이 밀려나기 시작한다.
그래서 맥락 관리는 에이전트 설계에서 가장 실용적인 공학 문제다. 핵심 원칙은 하나 — 지금 이 루프에 꼭 필요한 것만 창에 넣고, 나머지는 파일이나 데이터베이스에 두고 필요할 때만 꺼낸다. 도구 정의를 전부 적재하지 않고 이번 작업에 필요한 것 몇 개만 꺼내 쓰는 것, 긴 이전 결과 대신 요약만 보관하는 것, 긴 파일을 통째로 넣지 않고 관련 부분만 발췌하는 것 — 모두 같은 원리의 변주다. 맥락을 잘 설계하면 에이전트가 길고 복잡한 작업을 끝까지 수행한다. 방치하면 루프 몇 번 만에 목표를 잃고 헤맨다. "에이전트가 무능하다"는 체감의 상당 부분은 사실 맥락 관리 설계의 실패다.
④ 정지 조건 — 언제 충분한가
루프에는 탈출 조건이 있어야 한다. 당연한 말처럼 들리지만, 정지 조건을 제대로 설계하는 것은 생각보다 어렵다. 단순한 경우는 명확하다 — 테스트가 통과하면 완료. 어려운 경우가 문제다. "이 코드베이스를 이해하기 쉽게 리팩터링해 달라." 완료가 언제인가? 에이전트가 어떻게 알 수 있는가?
목표가 모호하거나, 성공 기준이 없거나, 완료를 판단하는 도구가 없으면 에이전트는 두 가지 나쁜 방향 중 하나로 간다. 조기 종료(이 정도면 됐겠지)이거나 무한 루프(더 개선할 수 있을 것 같아서 계속 시도)다. 어느 쪽도 원하는 결과가 아니다. 설계하지 않은 정지는 예측 불가능한 정지다.
# ── 정지 조건 없는 루프: 예측 불가능 ── def run_agent(goal): while True: obs = observe() plan = llm.plan(obs, goal) result = act(plan) if is_done(result, goal): # 성공 시 탈출 return result # 실패 시 → 한계 없이 영원히 반복 # ── 정지 조건 + 에스컬레이션: 예측 가능 ── MAX_ATTEMPTS = 10 def run_agent(goal): last_result = None for attempt in range(MAX_ATTEMPTS): # 반복 한계 명시 context = build_context( observe(), history=summarize(last_result), # 이전 결과 요약 보관 (맥락 관리) goal=goal, ) plan = llm.plan(context) last_result = act(plan) if is_done(last_result, goal): # 명확한 완료 기준 return last_result if is_stuck(last_result, attempt): # 같은 실수 반복 감지 → 조기 탈출 break return escalate_to_human(goal, last_result) # 한계 초과 → 사람에게 넘김코드 설명. 위 패턴과 아래 패턴의 차이는 세 가지다.
MAX_ATTEMPTS로 반복 한계를 명시한다.is_stuck으로 같은 실수를 반복하는 것을 감지해 조기에 탈출한다.escalate_to_human으로 한계 초과 시 사람에게 넘긴다. 추가로summarize(last_result)는 ③에서 다룬 맥락 관리 — 이전 결과를 통째로 보관하지 않고 요약만 창에 남긴다. 정지 조건과 맥락 관리는 이렇게 코드 한 줄에서 함께 보인다.반복 한계는 최소 방어선이다. 더 중요한 건 완료를 판단하는 기준이 에이전트에게 주어져 있느냐다. 이상적으로는 도구를 통해 검증 가능한 성공 조건이 있어야 한다 — 테스트 통과, 린트 0건, 특정 파일 존재 등. 검증할 수단이 없을 때야말로 에이전트 설계가 가장 취약해지는 지점이다.
⑤ 신뢰 경계 — 자율성의 설계 문제
에이전트는 실제 세계에 행동한다. 파일을 삭제하고, 코드를 배포하고, 메시지를 전송하고, 데이터베이스를 수정한다. 이 행동들은 되돌리기 어렵거나 불가능할 수 있다. 그래서 에이전트 설계에서 빠지기 쉬운 중요한 질문이 있다 — 어디까지 자율로 두고, 어디서 사람의 확인을 받아야 하는가?
이 선을 신뢰 경계(trust boundary)라 부른다. 신뢰 경계는 에이전트의 능력 문제가 아니라 설계 철학의 문제다. LLM은 확신을 갖고 틀릴 수 있다 — confidence와 correctness가 일치하지 않는다. "이 파일은 지워도 된다"고 자신 있게 말하면서 실제로는 지우면 안 되는 파일일 수 있다. 그래서 행동의 비가역성과 영향 범위를 기준으로 경계를 긋는 것이 실용적이다.
행동 유형 비가역성 영향 범위 권장 파일 읽기·검색·git log 없음 로컬 읽기 자율 파일 수정·git commit 낮음 (git reset으로 복구) 로컬만 자율 패키지 설치·서비스 재시작 중간 로컬만 자율 git push·외부 API 호출 중간 외부 영향 확인 권장 파일 삭제 (rm) 높음 로컬 영구 손실 확인 필수 대량 삭제·프로덕션 배포 매우 높음 외부·되돌리기 불가 명시 승인 표 설명. 기준은 두 축이다 — 되돌릴 수 있는가(비가역성), 그리고 나 이외의 시스템이나 사람에게 영향을 미치는가(영향 범위). 두 축 모두 낮으면 자율로, 하나라도 높으면 확인을 거치게 설계한다. 신뢰 경계를 너무 좁게 그으면 에이전트가 매 단계 사람에게 묻는 고비용 챗봇이 된다. 너무 넓게 그으면 사고가 났을 때 되돌리기 어렵다. 정답은 없고 명시적 결정만 있다.
다섯 요소의 교차점이 에이전트다
루프가 없으면 챗봇이다. 도구가 없으면 독백하는 언어 모델이다. 맥락 관리가 없으면 방향을 잃는다. 정지 조건이 없으면 예측 불가능하다. 신뢰 경계가 없으면 통제할 수 없다. 이 다섯은 각자 독립적이지 않다 — 루프가 돌수록 맥락이 차고, 맥락이 차면 정지 조건이 더 중요해지고, 정지가 실패하면 신뢰 경계가 마지막 방어선이 된다. 서로 맞물려 있다.
에이전트라는 말이 범람하는 지금, 어떤 시스템이 진짜 에이전트인지를 확인하는 잣대는 이 다섯이다. 도구 호출 하나 추가했다고 에이전트가 되는 것이 아니다. 루프를 돌리고, 도구로 세계와 상호작용하고, 맥락을 관리하고, 스스로 멈출 줄 알고, 사람이 어디서 개입할 수 있는지 설계된 시스템 — 그게 에이전트다.
이 글은 생성형 AI의 도움을 받아 작성되었습니다. 원본 자료를 기반으로 AI가 초안을 생성하고, 작성자가 검토·편집하였습니다.
'IT' 카테고리의 다른 글
오픈소스 에이전트 OpenCode는 세상을 어떻게 관찰하는가? — 로컬 에이전트의 관찰 엔진 분석 (0) 2026.06.08 에이전트 루프의 파수꾼, 검증(Verification) — 행동의 결과를 평가하고 멈추는 법 (0) 2026.06.07 에이전트 루프의 실행력, 행동(Action) — 생각에서 변화로 나아가는 도구 호출 (0) 2026.06.07 에이전트 루프의 나침반, 계획(Planning) — 복잡함을 나눌 때 시작되는 문제 해결 (0) 2026.06.06 에이전트 루프의 첫 단추, 관찰(Observation) — 세상의 상태를 맥락으로 번역하기 (0) 2026.06.06 내 코드 위키를 남의 코딩 에이전트가 쓰게 하려면 — SKILL.md 한 장으론 부족하다 (0) 2026.06.05 생성된 위키 문서에서 틀린 줄을 발견했다 — 고치지 말고, 입력을 바꿔라 (0) 2026.06.05 같은 사실도 신뢰 레벨이 다르다 — 코드 위키의 Trust Gradient (0) 2026.06.04 불필요한 껍데기 걸러내기 — vulture를 이용한 데드 코드 탐지 및 지식 정제 (0) 2026.06.04 코드의 어두운 구석을 드러내기 — radon을 통한 순환 복잡도 지표 수집 (0) 2026.06.04