콘텐츠로 이동

핵심 용어 정리

Agent 생태계는 빠르게 성장하면서 동일한 개념에 여러 이름이 붙거나, 서로 다른 개념이 같은 이름으로 불리는 경우가 많습니다. Scaffolding과 Harness를 혼용하는 사람도 있고, Framework와 Runtime을 구분하지 않는 경우도 흔합니다.

이 챕터에서는 이후 학습 전반에 걸쳐 사용되는 핵심 용어 6가지를 명확하게 정의합니다.

| 용어 | 정의 | 범위 | 예시 | |---|---|---|---| | Agent | 자율적으로 목표를 추구하며 도구를 사용하는 LLM 기반 시스템 | 개별 실행 단위 | Claude, GPT-4o 기반 코딩 봇 | | Harness | 에이전트 행동을 제약·정보 제공·검증·수정하는 주변 인프라 전체 | 시스템 수준 | 실행 루프 + 검증 + 피드백 | | Scaffolding | 에이전트가 실행되는 코드 구조 (루프, 파싱, 도구 호출) | 코드 수준 | while loop + tool dispatch | | Runtime | 에이전트가 실제로 실행되는 환경 | 인프라 수준 | Docker 컨테이너, sandbox | | Orchestration | 여러 에이전트나 단계를 조율하는 상위 로직 | 조율 수준 | 멀티에이전트 supervisor | | Framework | 에이전트 개발을 위한 라이브러리/도구 모음 | 도구 수준 | LangChain, AutoGen, CrewAI |

에이전트는 단순한 LLM 호출이 아닙니다. 다음 세 가지 조건을 만족해야 에이전트라 부를 수 있습니다:

  1. 자율성: 사람의 매 단계 지시 없이 목표를 향해 스스로 결정
  2. 도구 사용: 외부 시스템(파일, API, 터미널 등)과 상호작용
  3. 다단계 실행: 단일 응답이 아닌 반복적 추론-행동 사이클

단순 LLM 호출과 에이전트의 차이를 코드로 비교하면 명확해집니다:

# 단순 LLM 호출 (에이전트 아님)
# - 한 번 호출하고 끝
# - 외부 시스템 접근 없음
# - 결과가 틀려도 스스로 수정 불가
response = llm.complete("파일을 읽어줘")
print(response) # "파일을 읽는 방법은 open()을 사용하면..."
# 에이전트 (도구 사용 + 반복 실행)
# - 목표 달성 때까지 반복
# - 실제 파일 시스템에 접근
# - 오류 발생 시 다른 방법 시도
state = {"goal": "config.yaml 파일에서 host 값 읽기", "result": None}
while not goal_achieved(state):
thought = llm.reason(state) # "먼저 파일이 존재하는지 확인해야겠다"
action = llm.choose_tool(thought) # tool: read_file, args: "config.yaml"
result = execute_tool(action) # 실제 파일 읽기 실행
state = update_state(result) # 결과를 상태에 반영

이 두 용어는 가장 자주 혼동됩니다.

  • Scaffolding은 에이전트 루프를 구성하는 코드 구조입니다. “어떻게 실행하는가”에 해당합니다.
  • Harness는 그 스캐폴딩을 포함한 모든 주변 인프라입니다. 검증, 피드백, 컨텍스트 관리, 안전장치까지 포함합니다.

스캐폴딩은 하네스의 일부입니다.

Runtime은 에이전트가 실행되는 격리된 환경입니다. 보안과 재현 가능성 측면에서 중요합니다.

# 런타임 예시: Docker 기반 샌드박스
runtime:
image: python:3.12-slim
network: none # 외부 네트워크 차단
memory: 2GB
timeout: 300s
filesystem: ephemeral # 실행 후 초기화

오케스트레이션은 여러 에이전트나 실행 단계를 조율하는 상위 로직입니다. 단일 에이전트 루프가 아닌, 멀티 에이전트 시스템에서 핵심 역할을 합니다.

| 오케스트레이션 패턴 | 설명 | |---|---| | Supervisor | 중앙 에이전트가 하위 에이전트에 태스크 배분 | | Peer-to-Peer | 에이전트 간 직접 핸드오프 | | Hierarchical | 트리 구조의 다단계 위임 |

각 패턴의 흐름을 의사 코드로 나타내면 다음과 같습니다:

# Supervisor 패턴
supervisor.receive(task)
→ subtasks = supervisor.decompose(task)
→ for each subtask:
agent = supervisor.assign(subtask) # 적합한 에이전트 선택
result = agent.run(subtask)
supervisor.collect(result)
→ final = supervisor.synthesize(results)
# Peer-to-Peer 패턴
agent_A.run(task)
→ if needs_code_review:
agent_A.handoff(agent_B, context) # 직접 전달
agent_B.run(review_task)
agent_B.handoff(agent_A, feedback) # 피드백 반환

프레임워크는 에이전트를 만들기 위한 도구 상자입니다. 어떤 프레임워크를 선택하느냐에 따라 코드 구조, 디버깅 방식, 멀티에이전트 구성 방법이 달라집니다.

| 프레임워크 | 핵심 개념 | 강점 | 주의점 | |---|---|---|---| | LangGraph | 상태 기계(Graph) 기반 워크플로 | 실행 흐름 시각화, 복잡한 루프 제어 | 초기 학습 곡선 높음 | | CrewAI | Role 기반 에이전트 팀 | 에이전트 역할 분리가 직관적 | 세밀한 제어가 어려울 수 있음 | | AutoGen | 에이전트 간 대화(Conversation) 중심 | 멀티에이전트 토론 구성 용이 | 대화 관리 비용 높음 | | Mastra | TypeScript 네이티브, 워크플로 + 에이전트 통합 | JS/TS 생태계 친화적 | Python 대비 라이브러리 생태계 좁음 |

실제 논의에서 자주 등장하는 혼동 패턴과 올바른 구분을 정리합니다.

“LangChain을 에이전트로 사용한다”

  • 잘못된 표현: LangChain은 에이전트가 아니라 프레임워크입니다.
  • 올바른 표현: “LangChain 프레임워크를 사용해 에이전트를 구현한다”

“GPT-4o가 도구를 호출한다”

  • 부정확한 표현: GPT-4o 모델 자체는 텍스트를 생성할 뿐입니다.
  • 올바른 표현: “GPT-4o의 출력을 파싱해서 스캐폴딩이 도구를 호출한다”

“에이전트에 메모리를 추가한다”

  • 모호한 표현: 메모리가 에이전트 내부인지 하네스 인프라인지 불명확합니다.
  • 올바른 표현: “하네스의 컨텍스트 관리 레이어에 장기 메모리를 추가한다”

“Docker 컨테이너가 에이전트를 실행한다”

  • 혼동 포인트: Docker는 런타임이지 하네스나 스캐폴딩이 아닙니다.
  • 올바른 이해: 런타임(Docker) 위에서 스캐폴딩(코드 루프)이 동작하고, 그 전체를 하네스가 감쌉니다.

다음 시나리오를 읽고, 각 구성 요소가 어떤 용어에 해당하는지 직접 분류해 보세요.

시나리오: GitHub 이슈를 자동으로 처리하는 시스템을 만든다. 이 시스템은 이슈를 읽고, 관련 코드를 검색하고, 수정 PR을 생성한다. 실행은 격리된 환경에서 이루어지며, 결과물은 사람이 검토한 뒤 병합 여부를 결정한다.

  1. “이슈를 읽고, 코드를 검색하고, PR을 생성하는 주체”는 무엇인가?
  2. “격리된 환경”은 어떤 용어에 해당하는가?
  3. “사람의 검토 + 병합 여부 결정”을 자동화하려면 어떤 구성 요소를 설계해야 하는가?
  4. CrewAI를 사용해 구현한다면, CrewAI는 어떤 용어에 해당하는가?

용어를 정확히 구분하면 설계 결정을 더 명확하게 내릴 수 있습니다. “프레임워크를 바꿔야 하는가”와 “하네스를 개선해야 하는가”는 완전히 다른 질문입니다. 이후 챕터에서 각 개념을 심화 학습하며 이 용어들을 반복적으로 사용합니다.