효과적인 AI 에이전트 구축하기

ko생성일: 2025. 6. 17.갱신일: 2025. 7. 10.

효과적인 AI 에이전트를 만드는 방법에 대한 실제적 가이드. 단순하면서도 조합 가능한 패턴을 활용해 신뢰할 수 있고 유지보수 가능한 에이전트 시스템을 만드는 방법을 제시합니다.

효과적인 AI 에이전트 구축하기

Anthropic 엔지니어링

지난 1년간 우리는 다양한 산업 분야의 수십 개 팀과 함께 대형 언어 모델(LLM) 기반 에이전트를 구축하며 협업해 왔습니다. 가장 성공적인 구현 사례들은 복잡한 프레임워크나 특화된 라이브러리를 사용하는 대신, 단순하면서도 조합 가능한 패턴을 사용하는 곳이 많았습니다.

이 게시물에서는 우리가 고객과 협업하며, 그리고 직접 에이전트를 구축하면서 얻은 인사이트를 공유하고, 개발자들이 효과적인 에이전트를 만드는 데 도움이 될 실제적인 조언을 제시합니다.

에이전트란 무엇인가?

"에이전트"라는 용어는 여러 방식으로 정의될 수 있습니다. 일부 고객들은 에이전트를 오랜 시간 동안 독립적으로 작동하며 다양한 도구를 통해 복잡한 작업을 스스로 해결하는 완전 자율 시스템으로 간주합니다. 또 다른 고객들은 미리 정의된 워크플로우를 따르는 처방적인 구현을 에이전트라 부르기도 합니다. Anthropic에서는 이 모든 변형을 에이전틱 시스템으로 분류하지만, 워크플로우에이전트 사이에 중요한 구조적 구분을 둡니다:

  • 워크플로우: LLM과 도구가 미리 정의된 코드 경로를 통해 오케스트레이션되는 시스템
  • 에이전트: LLM이 자기 주도적으로 프로세스와 도구 사용을 동적으로 결정하고, 과업 수행 방식을 스스로 통제하는 시스템

아래에서는 두 종류의 에이전틱 시스템을 자세히 살펴보겠습니다. 부록 1(“실전의 에이전트”)에서는 고객들이 이러한 시스템에서 특별한 가치를 발견한 두 가지 도메인을 소개합니다.

언제(그리고 언제 아닌지) 에이전트를 써야 할까

LLM을 활용한 애플리케이션을 구축할 때, 가능한 가장 단순한 솔루션을 찾고, 필요할 때에만 복잡성을 높이길 권장합니다. 즉, 반드시 에이전틱 시스템을 만들지 않아도 된다는 의미입니다. 에이전틱 시스템은 종종 대기시간과 비용을 더 많이 쓰는 대신 더 나은 과업 수행력을 제공합니다. 언제 이 트레이드오프가 적절한지도 고려해야 합니다.

더 복잡한 구성이 필요하다면, 워크플로우는 잘 정의된 작업에 예측 가능성과 일관성을 제공하고, 에이전트는 대규모로 유연성과 모델 기반 의사결정이 필요할 때 더 적합합니다. 그러나 많은 애플리케이션에서는 리트리벌 및 인컨텍스트 예시를 곁들인 단일 LLM 호출만으로 충분한 경우가 많습니다.

프레임워크를 언제, 어떻게 쓸 것인가

에이전틱 시스템 구현을 쉽게 해주는 다양한 프레임워크들이 존재합니다. 예를 들어:

이런 프레임워크들은 LLM 호출, 도구 정의 및 파싱, 호출 연결과 같은 표준 저수준 작업들을 단순화하여 쉽게 시작할 수 있게 해줍니다. 하지만 추가적인 추상화 계층이 쌓여 실제 프롬프트와 응답이 가려져 디버깅이 어려워질 수 있고, 단순한 설정으로 충분할 때 복잡성을 무의미하게 끌어올릴 유혹에 빠질 수 있습니다.

개발자들에게는 LLM API를 직접 활용하며 시작해볼 것을 추천합니다. 많은 패턴들은 몇 줄의 코드로 구현 가능합니다. 프레임워크를 사용할 경우에도, 내부 코드에 대한 충분한 이해를 갖추십시오. 내부 동작에 대한 오해는 고객 오류의 공통 원인입니다.

몇 가지 샘플 구현은 Anthropic Cookbook에서 확인해주세요.

빌딩 블록, 워크플로우, 그리고 에이전트

이 섹션에서는 실제 프로덕션 환경에서 접한 대표적인 에이전틱 시스템 패턴을 살펴봅니다. 가장 기본적인 빌딩 블록인 ‘강화된 LLM’에서 시작해, 단순한 조합형 워크플로우에서 보다 복잡한 자율적 에이전트로 점진적으로 발전시켜 나가겠습니다.

빌딩 블록: 강화된 LLM

에이전틱 시스템의 가장 기본적인 형태는 리트리벌, 도구, 메모리 등의 기능으로 강화된 LLM입니다. 최신 모델들은 이러한 능력을 능동적으로 사용하여, 검색 쿼리 생성, 적합한 도구 선정, 유지해야 할 정보 판단 등이 가능합니다.

이미지 1

강화된 LLM

구현 시 두 가지 핵심 포인트에 중점을 둘 것을 권장합니다: 1) 이러한 기능을 구체적 사용 사례에 맞게 커스터마이즈할 것, 2) LLM이 쉽게 접근 가능한 명확하고 잘 문서화된 인터페이스를 제공할 것. 구현 방식은 다양하지만, 최근 공개한 Model Context Protocol을 활용하면, 단순한 클라이언트 구현만으로 서드파티 도구 생태계와 연동할 수 있습니다.

이후 설명에서는 모든 LLM 호출이 이처럼 강화된 기능에 접근 가능하다고 가정합니다.

워크플로우: 프롬프트 체이닝

프롬프트 체이닝은 하나의 작업을 일련의 단계로 분해해, 각 단계의 LLM 호출이 이전 결과를 처리하는 방식입니다. 중간 단계마다 프로그래밍적 체크(아래 다이어그램의 "gate" 참조)를 추가해 프로세스 진행 상태를 검증할 수 있습니다.

이미지 2

프롬프트 체이닝 워크플로우

언제 사용할까: 과업이 명확하게 고정된 하위 작업으로 쉽게 쪼갤 수 있을 때 적합합니다. 각 LLM 호출에 더 쉬운 작업만 할당해, 정확도를 높이는 대신 대기 시간을 감수하는 방식입니다.

예시:

  • 마케팅 문구 작성 후 다른 언어로 번역
  • 문서 개요 작성 → 기준 충족 여부 체크 → 전체 문서 작성

워크플로우: 라우팅

라우팅은 입력을 분류한 뒤 특화된 후속 작업에 배정하는 워크플로우입니다. 이 방식은 관심사 분리와 특화된 프롬프트 제작에 유리합니다. 라우팅 없이 한 종류 입력에 최적화하면, 다른 입력 처리 성능이 나빠질 수 있습니다.

이미지 3

라우팅 워크플로우

언제 사용할까: 뚜렷한 하위 카테고리별로 따로 처리해야 할 복잡한 과업에 적합합니다. 분류는 LLM이나 전통적 모델/알고리즘 모두 가능합니다.

예시:

  • 고객센터 문의 유형별(일반, 환불, 기술지원 등)로 후속 절차, 프롬프트, 도구 다르게 쓰기
  • 쉬운 질문은 소형 모델(Claude 3.5 Haiku), 어려운 질문은 대형 모델(Claude 3.5 Sonnet)에 라우팅해 비용·속도 최적화

워크플로우: 병렬화

LLM이 동시에 여러 하위 작업을 처리하고, 결과는 프로그램적으로 통합할 수 있습니다. 이 패턴은 크게 두 가지 변형이 있습니다:

  • 섹셔닝(sectioning): 작업을 독립적인 여러 하위 작업으로 나누고 병렬로 처리
  • 투표(voting): 동일한 작업을 여러 번 실행, 다양한 결과 집계

이미지 4

병렬화 워크플로우

언제 사용할까: 하위 작업을 분할해 속도를 높이거나, 다양한 관점/시도를 활용해 신뢰도 높은 결과가 필요할 때 적합합니다. 복잡한 과업의 여러 요소를 각기 다른 LLM 호출로 나눠 집중 처리하면 보통 성능이 향상됩니다.

예시:

  • 섹셔닝:
    • 사용자 쿼리 응답용 LLM과 부적절 발화 탐지용 LLM을 별도로 실행(통합 처리보다 성능 우수)
    • 각 평가 포인트별로 분리해 LLM 자동 평가(evals) 진행
  • 투표:
    • 코드 취약점 탐지 시 여러 프롬프트로 동시 검사 & 이슈 발견 시 플래깅
    • 콘텐츠 부적절성 판단 시 다양한 프롬프트&조건으로 평가, 오탐/누락 밸런싱

워크플로우: 오케스트레이터-워커(Orchestrator-Worker)

이 패턴은 중앙 LLM(오케스트레이터)이 작업을 동적으로 분해하고, 각 워커 LLM에게 분배 후 결과를 종합합니다.

이미지 5

오케스트레이터-워커 워크플로우

언제 사용할까: 필요한 하위 작업을 예측할 수 없는 복잡한 작업(예: 어떤 파일을 얼마나, 어떻게 수정해야 하는지가 입력마다 달라지는 코딩 작업)에 적합합니다. 병렬화와 구조적으로 비슷해 보여도, 병렬화가 미리 정의된 하위 작업에 쓰인 반면 이 패턴은 오케스트레이터가 입력에 따라 실시간으로 하위 작업을 정의합니다.

예시:

  • 매번 여러 파일을 복합적으로 수정하는 코딩 자동화
  • 다양한 출처에서 정보 수집 및 정리하는 검색·분석 작업

워크플로우: 평가자-최적화기(Evaluator-Optimizer)

한 LLM 호출이 답변을, 다른 LLM 호출이 평가와 피드백을 제공하는 반복 루프 방식입니다.

이미지 6

평가자-최적화기 워크플로우

언제 사용할까: 평가 기준이 명확하고, 반복 개선이 실질적 가치를 제공한다면 효과적입니다. 사람이 피드백을 줬을 때 답변이 명확히 개선되거나, LLM이 그러한 피드백을 충분히 제공할 수 있다면 특히 유용합니다. 이는 인간이 집중해서 문서를 다듬는 반복적 글쓰기 과정과 유사합니다.

예시:

  • 뉘앙스가 중요한 문학 번역(원 번역에서 놓쳤던 부분을 평가자가 비평사항 제공)
  • 여러 번의 검색·분석을 요구하는 복합 탐색 과업(추가 검색 필요 여부 평가자가 결정)

에이전트

최근 생산 환경에서는 LLM의 이해·추론·기획·도구 활용·회복력 등 여러 능력 고도화로 에이전트가 활발히 구현되고 있습니다. 에이전트는 사용자 명령이나 인터랙티브 대화로 시작합니다. 과업이 명확해지면, 자체적으로 계획을 세우고 작업을 진행하며 필요 시 사용자에게 추가 정보를 요청하거나 중간 평가를 받기도 합니다. 작업 중에는 각 단계마다 환경에서 실제 결과(도구 호출, 코드 실행 등)의 “그라운드 트루스”를 얻어 피드백으로 삼는 것이 중요합니다. 진행 도중 체크포인트마다 또는 장애 발생 시 사용자 피드백을 받기도 하며, 임무 완료 혹은 최대 반복 횟수 등 중단 조건에 따라 종료되는 경우도 많습니다.

에이전트가 다루는 과업은 복잡할 수 있지만, 구현 자체는 의외로 간단한 경우가 많습니다. 본질적으로 LLM이 루프 내에서 환경 피드백에 따라 도구를 활용하는 구조이기 때문입니다. 도구 구성이면서 문서화도 명확하고 일관되게 만드는 것이 매우 중요합니다(부록 2 ‘프롬프트 엔지니어링: 도구 만들기’에서 상세 설명).

이미지 7

자율 에이전트

언제 사용할까: 해결 과정 단계 수를 예측·고정할 수 없는 오픈엔디드 과업, 복잡한 경로를 하드코딩하기 힘든 문제에 적합합니다. LLM이 다수 턴을 독립 실행할 것이며, 그 의사결정에 최소한의 신뢰가 있어야 합니다. 자율성이 높은 만큼 대규모 신뢰 환경에서 과업을 확장하는 데 적합합니다.

자율적 에이전트는 더 많은 비용, 오류 누적 가능성도 크므로, 샌드박스 환경에서 충분히 테스트하고 보호장치를 마련할 것을 권장합니다.

활용 예시: 우리 구현 사례에서 발췌:

  • 작업 설명을 바탕으로 여러 파일을 수정하는 SWE-bench 과제용 코딩 에이전트
  • Claude가 실제 컴퓨터를 사용해 과업을 해결하는 참고 구현 예시

이미지 8

코딩 에이전트의 상위 흐름

패턴 조합 및 커스터마이징

위에서 소개한 빌딩 블록들은 이런 방식으로만 써야 한다는 "처방"이 아닙니다. 일반적으로 사용되는 패턴일 뿐, 개발자 상황에 맞추어 조합하고 변형할 수 있습니다. LLM 기능에서 성공의 핵심은 성능을 측정하며 구현을 반복적으로 개선하는 데 있다는 점을 다시 한번 강조합니다. 복잡성은 실질적으로 성과 개선에 기여할 때에만 추가해야 합니다.

요약

LLM 활용의 성공 비결은 가장 복잡한 시스템을 만드는 것이 아니라 _필요에 맞는 올바른 시스템_을 만드는 것에 있습니다. 간단한 프롬프트에서 시작해, 종합적인 평가로 최적화하고, 더 단순한 방법이 부족할 때만 다단계 에이전틱 시스템을 추가하세요.

에이전트 구현 시 우리는 세 가지 원칙을 따릅니다:

  1. 단순성 유지: 에이전트 디자인을 단순하게 만드세요.
  2. 투명성 강조: 에이전트의 계획·추론 과정을 명시적으로 드러내세요.
  3. 도구(행동) 인터페이스 문서화 및 테스트: ACI(에이전트-컴퓨터 인터페이스) 설계를 꼼꼼히 하세요.

프레임워크는 빠른 시작에 도움이 되지만, 실제 프로덕션 단계에선 추상화 계층을 덜어내고 기본 빌딩 블록으로 만드는 것을 주저하지 마세요. 이러한 원칙을 따르면 신뢰할 수 있고 유지보수 가능한 강력한 에이전트를 만들 수 있습니다.

감사의 글

Erik Schluntz, Barry Zhang이 작성. 본 글은 Anthropic에서 에이전트 빌딩 경험과 소중한 고객 인사이트를 바탕으로 집필되었습니다.

부록 1: 실전의 에이전트

고객사와의 협업을 통해 에이전트 패턴이 실질적 가치를 창출하는 두 분야가 특히 유망하다는 것을 확인했습니다. 두 예시는 대화와 실행을 모두 요구하고, 명확한 성공 기준 및 피드백 루프, 의미 있는 인간 감독이 통합될 때 에이전트의 진가가 드러남을 보여줍니다.

A. 고객 지원(Customer Support)

고객 지원은 챗봇 인터페이스에 도구 통합을 더해 한 단계 진화된 기능을 제공합니다. 이 분야가 오픈엔디드 에이전트에 특히 적합한 이유는:

  • 고객 상담은 대화 흐름을 따르면서 외부 정보 및 조치가 꼭 필요함
  • 도구 통합을 통해 고객 정보, 주문내역, 지식베이스 아티클 활용 가능
  • 환불 처리, 티켓 수정 등 액션을 프로그램적으로 실행 가능
  • 성공여부를 사용자 해소 체크 등 명확하게 측정 가능

일부 기업들은 성공 건에만 비용을 부과하는 사용 기반 과금 모델로 이 접근법의 실용성을 입증했습니다.

B. 코딩 에이전트(Coding Agents)

소프트웨어 개발 분야는 코드 자동완성에서 자율적 문제 해결로 LLM 기능이 빠르게 진화하는 대표 분야입니다. 에이전트가 특히 효과적인 이유는:

  • 코드 솔루션은 자동 테스트로 검증 가능
  • 에이전트가 테스트 결과를 피드백 삼아 반복 개선
  • 문제 공간이 구조화되고 명확
  • 산출물 품질이 객관적으로 계량 가능

우리 구현의 경우, SWE-bench Verified 벤치마크의 실제 GitHub 이슈도 풀리퀘스트 설명만으로 해결이 가능합니다. 단, 자동화 테스트가 기능 검증에는 도움되지만, 전체 시스템 요구사항과의 적합성은 여전히 인간 리뷰가 필수입니다.

부록 2: 프롬프트 엔지니어링 – 도구 만들기

에이전틱 시스템 종류와 무관하게, 도구는 에이전트에서 매우 중요한 역할을 차지할 수 있습니다. 도구는 Claude가 외부 서비스 및 API와 상호작용하게 해주며, API에서 정확한 구조와 정의가 필요합니다. Claude가 도구 호출을 계획하면, 응답에 tool use block이 포함됩니다. 도구 정의와 사양 역시 주된 프롬프트 못지않게 신경 써야 할 프롬프트 엔지니어링 대상입니다. 여기서는 도구 프롬프트 엔지니어링 방식을 간단히 소개합니다.

동일한 행동이라도 지정 방식은 다양할 수 있습니다. 예를 들어 파일 수정은 diff로, 전체 파일 재작성 등으로 놓을 수 있고, 구조화 출력은 마크다운 혹은 JSON 내부에 코드를 반환할 수 있습니다. 소프트웨어 공학 기준으론 이런 차이가 화장(형식)일 뿐 상호 변환이 간단하지만, LLM에게는 특정 포맷이 훨씬 더 어렵게 느껴질 수 있습니다. 예를 들어 diff 작성은 코드 쓰기 전에 헤더에 몇 줄이 바뀌는지 정확히 써야 합니다. JSON 내부 코드 작성은 마크다운 대비 개행이나 인용부호 이스케이프 등 추가 작업이 필요합니다.

도구 포맷 정할 때 고려사항:

  • 모델이 자기 자신을 '물리치기' 전에 생각할 여유(토큰)를 주기
  • 인터넷 텍스트에서 모델이 자연스럽게 봤을 만한 포맷에 가깝게 유지하기
  • 수천 줄 코드 줄 수 세기, 인용부호 이스케이프 등 모델의 '형식 오버헤드'를 최소화할 것

요령은, 인간-컴퓨터 인터페이스(HCI) 구축에 공들이듯 에이전트-컴퓨터 인터페이스(ACI)에도 그만큼 신경 쓰라는 점입니다. 고려 사항 몇 가지:

  • 모델 입장에서 생각해보기: 도구 설명과 파라미터만 보고도 명확히 쓸 수 있는가? 아니라면 모델도 마찬가지일 것. 좋은 도구 정의에는 사용 예시, 경계 사례, 입력 형식, 유사 도구와 구분점 등이 담겨야 함.
  • 파라미터 명/설명을 더 명확하게 바꿀 방법은? 주니어 개발자에게 좋은 docstring을 적듯, 비슷한 도구가 여럿일수록 특히 중요.
  • 워크벤치 등에서 모델이 도구를 실제로 어떻게 쓰는지 다양하게 실험하고, 반복 개선할 것. (워크벤치 참고)
  • 포카-요케 적용: 인자로 실수하기 어렵게 인터페이스 설계

실제로 우리가 SWE-bench용 에이전트를 만들 때, 프롬프트보다 도구 최적화에 더 많은 시간을 쏟았습니다. 예컨대, 루트 폴더 밖으로 이동한 뒤 상대 경로 지정 도구에서 모델이 오류를 냈기에 모든 경로를 절대경로로 강제하니 완벽하게 동작하는 것을 확인했습니다.