부록 · Building Effective Agents
원문: Anthropic Engineering — Building effective agents (2024-12-19, Erik S. & Barry Zhang) 한국어 번역과 영문 원문 전문을 같은 페이지에서 탭으로 번갈아 볼 수 있게 두었습니다. 워크숍에서는 에이전트란 무엇일까?에서 핵심만 한 장으로 요약했습니다.
🇰🇷 한국어 번역
효과적인 에이전트 만들기
2024년 12월 19일 게시
지난 1년 동안 우리는 산업 전반에 걸쳐 수십 개 팀이 LLM 에이전트를 만드는 과정을 함께해 왔습니다. 가장 성공적인 구현은 한결같이 복잡한 프레임워크나 특수 라이브러리가 아닌, 단순하고 조합 가능한 패턴을 쓰고 있었습니다.
이 글에서는 고객과 함께 일하며, 그리고 우리가 직접 에이전트를 만들며 배운 것을 공유하고, 효과적인 에이전트를 만드는 개발자들에게 실용적인 조언을 드립니다.
에이전트란 무엇인가
“에이전트(Agent)“는 여러 방식으로 정의됩니다. 어떤 고객은 에이전트를 다양한 도구를 활용해 복잡한 작업을 완수하면서 장시간에 걸쳐 독립적으로 작동하는, 완전히 자율적인 시스템으로 정의합니다. 다른 고객은 더 정해진 절차를 그대로 따라 움직이는(prescriptive) 워크플로우를 따르는 구현을 가리키는 용어로 씁니다. Anthropic은 이 모든 변형을 agentic systems(에이전틱 시스템)로 묶지만, 구조적으로 워크플로우(Workflows) 와 에이전트(Agents) 를 중요하게 구분합니다.
- 워크플로우는 LLM과 도구가 미리 정의된 코드 경로를 통해 오케스트레이션되는 시스템입니다.
- 에이전트는 반대로 LLM이 자기 자신의 흐름과 도구 사용을 동적으로 결정하면서, 작업을 어떻게 완수할지에 대한 통제권을 유지하는 시스템입니다.
아래에서는 두 종류 모두를 자세히 살펴봅니다. 부록 1(“Agents in Practice”)에서는 고객들이 이런 종류의 시스템에서 특히 가치를 본 두 영역을 소개합니다.
언제 에이전트를 써야 (또는 쓰지 말아야) 하는가
LLM으로 애플리케이션을 만들 때는 가장 단순한 해법부터 시작하고, 필요할 때만 복잡도를 더할 것을 권장합니다. 이건 agentic 시스템을 아예 만들지 않는 것을 뜻할 수도 있습니다. agentic 시스템은 흔히 더 나은 작업 성능을 위해 지연(latency)과 비용을 거래합니다. 이 트레이드오프가 언제 말이 되는지 따져 봐야 합니다.
더 큰 복잡도가 필요하다면, 잘 정의된 작업에는 워크플로우가 예측 가능성과 일관성을 제공하고, 유연성과 모델 주도의 의사 결정이 대규모로 필요한 작업에는 에이전트가 더 나은 선택입니다. 하지만 많은 애플리케이션에서는 검색(retrieval)과 프롬프트 안에 직접 예시를 넣는 방식(in-context 예시)을 활용해 단일 LLM 호출을 최적화하는 것으로 충분합니다.
프레임워크를 쓸지, 어떻게 쓸지
agentic 시스템 구현을 쉽게 해 주는 프레임워크가 많이 있습니다. 예를 들어:
- The Claude Agent SDK
- Strands Agents SDK (AWS)
- Rivet — 드래그 앤 드롭 GUI LLM 워크플로우 빌더
- Vellum — 복잡한 워크플로우를 만들고 테스트하는 또 다른 GUI 도구
이 프레임워크들은 LLM 호출, 도구 정의·파싱, 호출 체이닝 같은 표준적인 저수준 작업을 단순화해 빠른 시작을 도와줍니다. 하지만 추가 추상화 레이어를 만들어 실제 프롬프트와 응답을 가리는 경우가 많아 오류 추적(디버깅)을 어렵게 만듭니다. 또한 더 단순한 구성이 충분한 자리에 복잡도를 더하고 싶게 만들기도 합니다.
우리는 개발자가 먼저 LLM API를 직접 사용해 보는 것을 권합니다. 많은 패턴은 몇 줄짜리 코드로 구현됩니다. 프레임워크를 쓰더라도, 그 안에서 무슨 일이 일어나는지 이해해야 합니다. 내부에 대한 잘못된 가정은 고객 오류의 흔한 원인입니다.
샘플 구현은 cookbook을 참고하세요.
빌딩 블록, 워크플로우, 그리고 에이전트
이번 절에서는 우리가 프로덕션에서 봐 온 agentic 시스템의 공통 패턴을 살펴봅니다. 기본 빌딩 블록 — 증강된 LLM(augmented LLM) — 에서 출발해, 단순한 조합형 워크플로우부터 자율적인 에이전트까지 점진적으로 복잡도를 올립니다.
빌딩 블록 · 증강된 LLM
agentic 시스템의 기본 빌딩 블록은 검색(retrieval), 도구(tools), 기억(memory) 같은 보강(augmentation)이 더해진 LLM입니다. 우리의 현재 모델은 이 능력들을 능동적으로 활용할 수 있습니다 — 스스로 검색 쿼리를 만들고, 적절한 도구를 고르고, 무엇을 남길지 결정합니다.
증강된 LLM은 LLM과 검색·도구·기억 능력의 결합입니다.
구현에서 중점을 둘 두 가지를 권합니다. (1) 이 능력들을 본인의 구체적 유즈케이스에 맞춰 재단(tailor) 하기, 그리고 (2) LLM에게 쉽고 잘 문서화된 인터페이스를 제공하기. 이 보강(augmentation)을 구현하는 방법은 많지만, 그중 하나는 최근 발표된 Model Context Protocol(MCP) 입니다. 간단한 클라이언트 구현만으로 점점 자라는 third-party 도구 생태계와 통합할 수 있게 해 줍니다.
이 글의 나머지 부분에서는 각 LLM 호출이 이 증강된 능력들에 접근할 수 있다고 가정합니다.
워크플로우 · Prompt chaining (프롬프트 체이닝)
프롬프트 체이닝은 작업을 순차적인 단계로 분해합니다. 각 LLM 호출이 이전 호출의 출력을 처리합니다. 중간 단계마다 프로그래밍적 검사(아래 다이어그램의 “gate”)를 추가해 흐름이 궤도에서 벗어나지 않도록 할 수 있습니다.
언제 쓰나 — 작업이 고정된 하위 작업으로 깔끔하고 쉽게 분해될 수 있는 경우에 이상적입니다. 주요 목적은 각 LLM 호출을 더 쉬운 작업으로 만들어 지연을 더 높은 정확도로 거래하는 것입니다.
예시
- 마케팅 카피를 만들고, 다른 언어로 번역하기.
- 문서 개요를 쓰고, 개요가 특정 기준을 만족하는지 검사한 뒤, 그 개요를 바탕으로 본문을 쓰기.
워크플로우 · Routing (라우팅)
라우팅은 입력을 분류해 전문화된 후속 작업으로 보냅니다. 관심사를 분리하고 더 특화된 프롬프트를 만들 수 있습니다. 이 워크플로우가 없으면, 한 종류의 입력에 맞춘 최적화가 다른 입력의 성능을 해칠 수 있습니다.
언제 쓰나 — 복잡한 작업에 별도로 다루는 게 나은 뚜렷한 범주가 있고, 분류가 LLM이나 더 전통적인 분류 모델/알고리즘으로 정확히 처리될 수 있을 때 잘 작동합니다.
예시
- 고객 서비스 쿼리(일반 질문, 환불 요청, 기술 지원)를 서로 다른 후속 프로세스·프롬프트·도구로 보내기.
- 쉬운/흔한 질문은 Claude Haiku 4.5 같은 더 작고 비용 효율적인 모델로, 어려운/이례적인 질문은 Claude Sonnet 4.5 같은 더 능력 있는 모델로 라우팅해 최적의 성능을 얻기.
워크플로우 · Parallelization (병렬화)
LLM이 동시에 작업하고 그 출력을 프로그래밍적으로 합칠 수 있습니다. 두 가지 변형이 있습니다.
- Sectioning(섹션) — 작업을 독립된 하위 작업으로 쪼개 병렬 실행.
- Voting(투표) — 같은 작업을 여러 번 돌려 다양한 출력을 얻기.
언제 쓰나 — 쪼개진 하위 작업이 속도를 위해 병렬화될 수 있을 때, 또는 더 높은 신뢰도를 위해 여러 관점이나 시도가 필요할 때 효과적입니다. 다중 고려사항이 얽힌 복잡한 작업에서는 각 고려사항을 별도 LLM 호출이 다루게 하는 편이 일반적으로 더 잘 작동합니다 — 각 측면에 집중된 주의를 둘 수 있기 때문입니다.
예시
- Sectioning
- 가드레일 — 한 모델 인스턴스가 사용자 쿼리를 처리하는 동안, 다른 인스턴스가 부적절한 콘텐츠/요청을 걸러냅니다. 같은 LLM 호출이 가드레일과 응답을 모두 다루는 것보다 잘 작동하는 경향이 있습니다.
- 평가 자동화 — 각 LLM 호출이 주어진 프롬프트에 대한 모델 성능의 다른 측면을 평가.
- Voting
- 보안 취약점 코드 리뷰 — 서로 다른 프롬프트가 코드를 리뷰하고 문제를 발견하면 표시.
- 콘텐츠 부적절성 판단 — 여러 프롬프트가 서로 다른 측면을 평가하거나, false positive/negative 균형을 맞추는 투표 임계값을 두기.
워크플로우 · Orchestrator-workers (오케스트레이터-워커)
중앙의 LLM이 작업을 동적으로 쪼개 워커 LLM에게 위임하고, 그 결과를 종합합니다.
언제 쓰나 — 필요한 하위 작업을 미리 예측할 수 없는 복잡한 작업에 적합합니다 (예: 코딩 작업에서 수정해야 하는 파일 수와 각 변경의 성격은 작업마다 다릅니다). 구조 모양은 병렬화와 비슷해 보이지만, 핵심 차이는 유연성입니다 — 하위 작업이 미리 정의되지 않고, 오케스트레이터가 구체적 입력을 보고 결정합니다.
예시
- 매번 여러 파일에 복잡한 변경을 가하는 코딩 제품.
- 가능한 관련 정보를 여러 소스에서 모아 분석하는 검색 작업.
워크플로우 · Evaluator-optimizer (평가자-최적화자)
한 LLM 호출이 응답을 생성하고, 다른 호출이 평가와 피드백을 제공하는 루프입니다.
언제 쓰나 — 명확한 평가 기준이 있고, 반복적 정제가 측정 가능한 가치를 줄 때 특히 효과적입니다. 잘 맞는 두 신호가 있습니다. (1) 사람이 피드백을 말로 표현하면 LLM 응답이 눈에 띄게 좋아진다, (2) LLM이 그런 피드백을 줄 수 있다. 사람이 다듬어진 문서를 쓸 때의 반복 글쓰기 과정과 닮았습니다.
예시
- 문학 번역 — 번역 LLM이 초기에는 못 잡는 뉘앙스를, 평가자 LLM이 유용한 비판으로 짚어 줄 수 있을 때.
- 종합적 정보를 얻기 위해 여러 라운드의 검색·분석이 필요한 복잡한 검색. 평가자가 추가 검색이 필요한지 판단.
에이전트
핵심 능력 — 복잡한 입력 이해, 추론과 계획, 도구의 신뢰성 있는 사용, 오류로부터의 회복 — 이 무르익으면서 에이전트가 프로덕션에서 등장하고 있습니다. 에이전트는 사람 사용자의 명령이나 상호작용으로 일을 시작합니다. 작업이 명확해지면 에이전트는 독립적으로 계획하고 작동하면서, 필요할 때 사람에게 추가 정보나 판단을 요청합니다. 실행 중에는 매 단계 환경에서 얻는 실제 사실값(“ground truth”) 이 결정적입니다 (도구 호출 결과, 코드 실행 결과 등). 그 결과로 진행 상황을 평가합니다. 에이전트는 체크포인트나 막힌 지점에서 사람 피드백을 위해 멈출 수 있습니다. 작업은 보통 완료 시점에 종료되지만, 제어를 위해 정지 조건(최대 반복 횟수 등)을 두는 것도 흔합니다.
에이전트는 정교한 작업을 다룰 수 있지만, 그 구현은 보통 단순합니다. 대개는 LLM이 환경 피드백을 보면서 루프 안에서 도구를 쓰는 것일 뿐입니다. 그래서 도구 세트와 그 문서를 명확하고 신중하게 설계하는 것이 결정적입니다. 도구 개발의 모범 사례는 부록 2(“Prompt Engineering your Tools”)에서 자세히 다룹니다.
언제 쓰나 — 필요한 단계 수를 예측하기 어렵거나 불가능하고, 고정된 경로를 하드코딩할 수 없는 열린 문제에 씁니다. LLM이 잠재적으로 많은 턴 동안 작동할 수 있어야 하고, 그 결정에 어느 정도 신뢰가 있어야 합니다. 에이전트의 자율성은 신뢰할 수 있는 환경에서 작업을 스케일링하는 데 이상적입니다.
에이전트의 자율적 특성은 더 높은 비용과 오류의 누적 가능성을 의미합니다. 샌드박스 환경에서의 광범위한 테스트와 적절한 가드레일을 권합니다.
예시 (우리 구현에서)
- SWE-bench 작업을 해결하는 코딩 에이전트 — 작업 설명을 바탕으로 여러 파일을 수정.
- “computer use” 레퍼런스 구현 — Claude가 컴퓨터를 직접 써서 작업을 수행.
패턴들을 조합하고 커스터마이즈하기
이 빌딩 블록들은 처방이 아닙니다. 개발자가 자기 유즈케이스에 맞춰 형태를 잡고 조합할 수 있는 흔한 패턴입니다. 다른 LLM 기능과 마찬가지로 성공의 열쇠는 성능을 측정하고 반복하는 것입니다. 다시: 복잡도는 결과를 입증 가능하게 개선할 때만 더해야 합니다.
요약
LLM 공간에서의 성공은 가장 정교한 시스템을 만드는 것이 아니라 자기 필요에 맞는 옳은 시스템을 만드는 것입니다. 단순한 프롬프트로 시작해, 포괄적 평가로 최적화하고, 더 단순한 해법이 부족할 때만 다단계 agentic 시스템을 더하세요.
에이전트를 구현할 때 우리는 세 가지 핵심 원칙을 따르려 노력합니다.
- 에이전트 설계에서 단순함(simplicity) 을 유지하라.
- 에이전트의 계획 단계를 명시적으로 보여 투명함(transparency) 을 우선하라.
- agent-computer interface(ACI) 를 도구 문서화와 테스트를 통해 정성껏 설계하라.
프레임워크는 빠르게 시작하도록 도와줍니다. 다만 프로덕션으로 갈 때는 추상화 레이어를 줄이고 기본 컴포넌트로 만드는 것을 망설이지 마세요. 이 원칙을 따르면 강력할 뿐 아니라 신뢰할 만하고, 유지보수 가능하며, 사용자가 신뢰하는 에이전트를 만들 수 있습니다.
Acknowledgements
Erik S.와 Barry Zhang이 작성했습니다. Anthropic에서 에이전트를 만들면서 얻은 경험과 고객이 공유해 준 통찰에 깊이 감사드립니다.
부록 1 · 실전에서의 에이전트
고객과의 작업에서 위 패턴들의 실용적 가치를 보여 주는, 특히 유망한 두 가지 응용을 발견했습니다. 두 응용 모두 대화와 행동이 모두 필요하고, 명확한 성공 기준이 있고, 피드백 루프가 가능하고, 의미 있는 사람 감독이 통합되는 작업에서 에이전트가 가장 큰 가치를 더한다는 점을 보여 줍니다.
A. 고객 지원
고객 지원은 도구 통합으로 능력이 확장된 친숙한 챗봇 인터페이스를 결합합니다. 더 열린(open-ended) 에이전트에 잘 맞습니다. 이유는:
- 지원 상호작용은 자연스럽게 대화 흐름을 따르면서도 외부 정보·행동에 대한 접근이 필요합니다.
- 도구로 고객 데이터, 주문 이력, 지식 베이스 글을 가져올 수 있습니다.
- 환불 발급, 티켓 갱신 같은 행동을 프로그래밍적으로 처리할 수 있습니다.
- 성공이 사용자 정의 해결(resolution)을 통해 명확히 측정됩니다.
이 접근의 실용성은 해결된 건수에만 과금하는 사용량 기반 가격 모델을 시도한 여러 회사들을 통해 입증됐습니다 — 그만큼 자기 에이전트의 효과에 자신이 있다는 신호입니다.
B. 코딩 에이전트
소프트웨어 개발 영역은 코드 자동완성에서 자율적 문제 해결로 능력이 진화하면서, LLM 기능에 놀라운 잠재력을 보여 왔습니다. 에이전트가 특히 효과적인 이유:
- 코드 해법이 자동화된 테스트로 검증 가능합니다.
- 에이전트가 테스트 결과를 피드백으로 받아 반복할 수 있습니다.
- 문제 공간이 잘 정의되고 구조화돼 있습니다.
- 출력 품질이 객관적으로 측정됩니다.
우리 구현에서는 에이전트가 SWE-bench Verified 벤치마크의 실제 GitHub 이슈를 PR 설명만 보고 해결할 수 있게 됐습니다. 다만 자동화된 테스트가 기능 검증을 도와주지만, 더 넓은 시스템 요구사항과의 정합성을 위해서는 여전히 사람 리뷰가 결정적입니다.
부록 2 · 도구의 프롬프트 엔지니어링
어떤 agentic 시스템을 만들든 도구는 에이전트의 중요한 일부가 될 가능성이 큽니다. 도구는 Claude가 API에 자기 구조와 정의를 정확히 명시함으로써 외부 서비스·API와 상호작용할 수 있게 합니다. Claude가 도구를 호출하기로 결정하면 API 응답에 도구를 어떻게 쓸지 알려주는 블록(tool use block) 을 포함합니다. 도구 정의와 명세는 전체 프롬프트만큼 프롬프트 엔지니어링의 주의를 받아야 합니다. 이 짧은 부록에서는 도구를 어떻게 프롬프트 엔지니어링할지를 다룹니다.
같은 행동을 명시하는 방법이 여럿일 때가 많습니다. 예를 들어 파일 편집을 diff를 써서 명시할 수도 있고 파일 전체를 다시 쓰는 식으로도 가능합니다. 구조화된 출력은 markdown 안의 코드로 줄 수도 있고 JSON 안의 코드로 줄 수도 있습니다. 소프트웨어 엔지니어링에서 이런 차이는 표면적이고 손실 없이 변환 가능하지만, 어떤 포맷은 LLM이 쓰기 훨씬 어렵습니다. diff를 쓰려면 새 코드가 쓰여지기 전에 청크 헤더에서 몇 줄이 바뀌는지 알고 있어야 합니다. JSON 안에 코드를 쓰는 것(markdown 대비)은 개행과 따옴표의 추가 이스케이핑이 필요합니다.
도구 포맷을 정할 때의 권장:
- 모델이 코너에 몰리기 전에 “생각할” 충분한 토큰을 주세요.
- 포맷을 모델이 자연스러운 인터넷 텍스트에서 본 적 있는 형태에 가깝게 유지하세요.
- 수천 줄짜리 코드의 정확한 라인 카운트 유지, 모든 코드의 문자열 이스케이핑 같은 포맷 오버헤드가 없도록 하세요.
한 가지 어림짐작: 사람-컴퓨터 인터페이스(HCI)에 들이는 만큼의 노력을 agent-컴퓨터 인터페이스(ACI) 에도 투자하세요. 다음은 그 방법에 대한 생각들:
- 모델 입장이 되어 보기. 설명과 매개변수만 보고 이 도구를 어떻게 쓰는지 한눈에 들어오나요, 아니면 신중히 생각해야 하나요? 후자라면 모델에게도 마찬가지일 가능성이 큽니다. 좋은 도구 정의는 보통 예시 사용법, 엣지 케이스, 입력 포맷 요구사항, 다른 도구와의 명확한 경계를 포함합니다.
- 매개변수 이름이나 설명을 어떻게 더 분명하게 바꿀 수 있을지 고민하기. 이를 팀의 주니어 개발자에게 좋은 docstring을 쓰는 것처럼 생각하세요. 비슷한 도구가 많을 때 특히 중요합니다.
- 모델이 도구를 어떻게 쓰는지 테스트하기. 워크벤치에서 많은 예시 입력을 돌려 모델이 어떤 실수를 하는지 보고 반복하세요.
- 도구를 실수 방지 설계로 다듬기 (원어로는 “poka-yoke”). 실수하기 더 어렵도록 인자를 바꾸세요.
SWE-bench용 에이전트를 만들면서 우리는 실제로 전체 프롬프트보다 도구를 다듬는 데 더 많은 시간을 썼습니다. 예를 들어 에이전트가 루트 디렉터리 밖으로 이동한 뒤 상대 경로 도구에서 실수를 한다는 걸 발견했습니다. 도구가 항상 절대 경로를 요구하도록 바꾸자, 모델은 그 방식을 흠 없이 썼습니다.
워크숍 매핑
| Anthropic 정의 | 우리 워크숍 |
|---|---|
| 증강된 LLM (retrieval + tools + memory) | Claude Project + 시스템 프롬프트 + MCP — 오전 5a·5b |
| 워크플로우 (예측 가능한 작업) | /주간정리 슬래시 명령 — 오후 7e |
| 에이전트 (열린 문제, 다단계) | /schedule routine + 매일 아침 뉴스레터 — 오후 7f |
| 단순함·투명함·도구 설계(ACI) | .claude/commands/ 안 한 줄 한 줄을 본인이 직접 볼 수 있게 — 전체 |
→ 본문 단원으로 돌아가기: 에이전트란 무엇일까? · 지식을 잘 정리한다는건 뭘까?