테마 전환

AI 에이전트 개발 실전: 아키텍처 설계 및 구현 가이드

Easton editorial illustration: agent rollout and rollback rail

한 ReAct 에이전트가 20분 동안 실행된 뒤 무한 루프에 빠져 같은 도구를 계속 호출했습니다. 원인은 maxIterations를 설정하지 않았기 때문입니다. 반복 횟수 한도를 넘으면 강제로 중지하도록 해야 무한 루프를 막을 수 있습니다. 이는 에이전트 개발에서 가장 흔한 문제입니다. ReAct 에이전트는 무한 루프에 빠지고, 멀티 에이전트 시스템은 수렴하지 않으며, Plan-and-Execute는 동적 작업에 유연하게 대응하지 못할 수 있습니다.

에이전트 아키텍처는 세 단계로 나뉩니다. 모델 직접 호출은 단일 단계 작업에 적합하고, 도구를 사용하는 단일 에이전트는 대부분의 상황에서 기본 선택이며, 멀티 에이전트 오케스트레이션은 신중하게 도입해야 합니다. 세 가지 핵심 패턴도 각각 알맞은 쓰임새가 있습니다. ReAct는 동적 의사결정, Plan-and-Execute는 안정적인 프로세스, Multi-Agent는 전문 역할 분담에 적합합니다. Azure 공식 문서는 그룹 채팅 에이전트를 3개 이하로 제한할 것을 권장합니다. 그보다 많으면 토론이 수렴하기 어려워지기 때문입니다.

이 글에서는 2년 동안 직접 겪은 시행착오를 바탕으로 세 가지 아키텍처 패턴의 원리와 코드 구현, 다섯 가지 멀티 에이전트 오케스트레이션 패턴, LangChain/AutoGen/CrewAI/Claude Agent SDK 선택법, Claude Agent SDK로 실제 실행 가능한 에이전트를 만드는 방법을 자세히 설명합니다.

1. 에이전트 아키텍처의 세 단계

먼저 많은 초보자가 놓치기 쉬운 원칙부터 짚겠습니다. 간단한 방법으로 해결할 수 있다면 복잡한 아키텍처를 도입하지 마세요.

Azure 공식 문서는 에이전트 아키텍처를 세 단계로 구분합니다. 실제로 적용하기 매우 유용한 분류입니다.

1.1 모델 직접 호출(Direct Model Call)

가장 단순한 단계입니다. 모델에 작업을 전달하면 모델이 바로 답을 반환합니다.

// 最基础的调用方式
const response = await anthropic.messages.create({
  model: 'claude-sonnet-4-20250514',
  max_tokens: 1024,
  messages: [{ role: 'user', content: '帮我总结这段文本...' }]
});

단일 단계 작업, 결과가 비교적 확실한 상황, 외부 도구가 필요 없는 상황에 적합합니다. 예를 들면 텍스트 요약, 번역, 코드 자동 완성입니다.

장점은 단순하고 저렴하며 제어하기 쉽다는 점입니다. 단점은 여러 단계의 추론이 필요한 복잡한 작업을 처리하기 어렵고 외부 도구를 호출할 수 없다는 점입니다.

1.2 단일 에이전트 + 도구(Single Agent with Tools)

이는 대부분의 기업 환경에서 기본 선택입니다. 에이전트가 도구를 호출하며 여러 단계의 작업을 처리할 수 있습니다.

// LangChain 单代理示例
import { ChatAnthropic } from '@langchain/anthropic';
import { AgentExecutor, createToolCallingAgent } from 'langchain/agents';
import { tool } from '@langchain/core/tools';
import { z } from 'zod';

// 定义一个查询天气的工具
const weatherTool = tool(
  async ({ city }) => {
    // 模拟天气 API 调用
    return `${city}今天晴,气温 22°C`;
  },
  {
    name: 'get_weather',
    description: '获取指定城市的天气信息',
    schema: z.object({
      city: z.string().describe('城市名称'),
    }),
  }
);

const model = new ChatAnthropic({
  model: 'claude-sonnet-4-20250514',
  temperature: 0,
});

const agent = await createToolCallingAgent({
  llm: model,
  tools: [weatherTool],
  prompt: '你是一个有用的助手。',
});

const executor = AgentExecutor.fromAgentAndTools({
  agent,
  tools: [weatherTool],
});

// 运行
const result = await executor.invoke({
  input: '北京今天天气怎么样?',
});

도구 호출이 필요하고, 작업을 분해할 수 있으며, 단계가 비교적 고정된 상황에 적합합니다. 예를 들면 데이터 분석, 코드 실행, API 오케스트레이션입니다.

1.3 멀티 에이전트 오케스트레이션(Multi-Agent Orchestration)

가장 복잡한 단계입니다. 여러 전문 에이전트가 각자의 역할을 맡아 협업으로 작업을 완수합니다.

솔직히 말해 이 단계가 꼭 필요한 상황은 생각보다 많지 않습니다. 멀티 에이전트를 도입하면 조율 비용, 상태 관리 복잡성, 디버깅 난도가 모두 기하급수적으로 증가합니다.

여러 영역을 아우르는 복잡한 작업, 전문 역할 분담이 필요한 작업, 단일 에이전트로 감당할 수 없는 작업에 적합합니다. 예를 들면 소프트웨어 개발 파이프라인(요구사항 분석 → 설계 → 코딩 → 테스트)이나 복잡한 의사결정 시스템입니다.

1.4 무엇을 선택해야 할까? 의사결정 표

상황권장 단계이유
간단한 질의응답, 텍스트 처리모델 직접 호출이것으로 충분하며 과도하게 설계할 필요가 없음
데이터베이스 조회, API 호출 필요단일 에이전트 + 도구전형적인 방식이며 안정성이 높음
작업을 분해할 수 있지만 단계가 불확실함단일 에이전트 + 도구(ReAct 패턴)에이전트가 직접 단계를 계획하게 함
여러 전문 역할의 협업 필요멀티 에이전트 오케스트레이션신중히 접근하고 실제 필요 여부부터 평가해야 함

한 문장 요약: 단순하게 시작하고 필요한 것을 하나씩 추가하세요.

2. 세 가지 핵심 아키텍처 패턴 자세히 보기

어느 단계를 사용할지 정했다면 다음은 패턴을 선택할 차례입니다. 세 패턴은 서로 배타적이지 않으며, 많은 상황에서 함께 사용됩니다.

2.1 ReAct(추론-행동) 패턴

ReAct는 Reasoning + Acting의 줄임말로, 모델이 ‘생각하면서 행동’하도록 하는 것이 핵심입니다.

작동 원리:

사용자 입력 → Thought(생각) → Action(행동) → Observation(관찰) → 반복 또는 종료

예를 들어 사용자가 ‘내일 베이징 날씨는 야외 운동에 적합한가요?‘라고 묻는다고 해봅시다.

  1. Thought: 먼저 내일 베이징 날씨를 확인해야 한다
  2. Action: get_weather 도구를 city: "北京" 매개변수로 호출한다
  3. Observation: 내일 베이징은 흐리고 기온은 18~25°C, 강수 확률은 10%다
  4. Thought: 기온이 적당하고 강수 확률이 낮으므로 야외 운동에 적합하다
  5. Final Answer: 내일 베이징은 야외 운동에 적합하며 얇은 겉옷을 준비하는 것이 좋습니다

코드 구현(LangChain):

import { ChatAnthropic } from '@langchain/anthropic';
import { AgentExecutor, createReactAgent } from 'langchain/agents';
import { pull } from 'langchain/hub';

// ReAct prompt 模板
const prompt = await pull('hwchase17/react');

const agent = await createReactAgent({
  llm: model,
  tools: [weatherTool, searchTool], // 你的工具列表
  prompt,
});

// 设置最大迭代次数,防止无限循环!
const executor = AgentExecutor.fromAgentAndTools({
  agent,
  tools: [weatherTool, searchTool],
  maxIterations: 10, // 重要:防止死循环
  verbose: true, // 打印推理过程,调试必备
});

장단점 분석:

장점단점
유연성이 높아 동적 작업을 처리할 수 있음무한 루프에 빠질 수 있음
추론 과정이 투명해 디버깅하기 쉬움한 번의 실행 비용이 비교적 높음
단계를 미리 정의할 필요가 없음복잡한 다단계 작업의 계획 능력은 제한적임

시행착오에서 얻은 주의점: 반드시 maxIterations를 설정하세요. 그렇지 않으면 완료할 수 없는 작업을 만났을 때 에이전트가 계속 실행됩니다. 제가 처음 만든 ReAct 에이전트도 그렇게 밤새 돌아갔습니다.

2.2 Plan-and-Execute(계획-실행) 패턴

ReAct는 ‘한 걸음씩 상황을 보며 나아가는’ 방식이라 복잡한 작업에서는 방향을 잃기 쉽습니다. Plan-and-Execute는 먼저 계획을 세운 다음 단계별로 실행합니다.

작동 원리:

사용자 입력 → Planner(계획기)가 계획 생성 → Executor가 단계별 실행 → 결과 반환

코드 구현(LangGraph):

import { ChatAnthropic } from '@langchain/anthropic';
import { StateGraph, END } from '@langchain/langgraph';

// 定义状态结构
interface AgentState {
  input: string;
  plan: string[];
  pastSteps: string[];
  response: string;
}

// 规划节点:生成执行计划
async function planNode(state: AgentState): Promise<AgentState> {
  const plannerPrompt = `给定用户目标:${state.input}
请生成一个详细的执行计划,每步一个字符串,返回 JSON 数组格式。`;

  const response = await model.invoke(plannerPrompt);
  const plan = JSON.parse(response.content as string);
  return { ...state, plan };
}

// 执行节点:执行计划中的一步
async function executeNode(state: AgentState): Promise<AgentState> {
  const currentStep = state.plan[0];
  const result = await executor.invoke({ input: currentStep });

  return {
    ...state,
    plan: state.plan.slice(1), // 移除已完成的步骤
    pastSteps: [...state.pastSteps, `${currentStep}: ${result.output}`],
  };
}

// 构建图
const workflow = new StateGraph<AgentState>({
  channels: {
    input: { value: null },
    plan: { value: null },
    pastSteps: { value: null, default: () => [] },
    response: { value: null },
  },
});

workflow.addNode('planner', planNode);
workflow.addNode('executor', executeNode);

// 定义边:规划完成后执行
workflow.addEdge('planner', 'executor');

// 条件边:检查是否还有步骤
workflow.addConditionalEdges('executor', (state) => {
  return state.plan.length > 0 ? 'executor' : END;
});

장단점 분석:

장점단점
실행이 안정적이고 단계를 제어할 수 있음계획이 생성된 뒤에는 유연하게 바꾸기 어려움
결과가 확실한 작업에 적합함동적으로 변하는 환경에 대응하기 어려움
모니터링과 중단이 쉬움계획 품질이 Planner의 능력에 좌우됨

직접 사용해 본 경험: Plan-and-Execute는 일괄 데이터 처리나 보고서 생성처럼 ‘단계를 예측할 수 있는’ 작업에 특히 적합합니다. 반면 전략을 자주 조정해야 하는 작업에는 ReAct가 더 잘 맞습니다.

2.3 Multi-Agent(멀티 에이전트 협업) 패턴

작업이 단일 에이전트로 처리하기 어려울 만큼 복잡해지면 여러 에이전트가 필요합니다.

핵심 개념: 각 에이전트가 하나의 전문 영역에 집중하고 팀처럼 협업합니다.

코드 구현(Claude Agent SDK 스타일):

import { ClaudeAgent } from '@anthropic-ai/claude-agent-sdk';

// 创建专业代理
const researchAgent = new ClaudeAgent({
  name: 'researcher',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: '你是一个研究专家,负责收集和整理信息。',
  tools: ['WebSearch', 'WebFetch'],
});

const writerAgent = new ClaudeAgent({
  name: 'writer',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: '你是一个内容创作专家,负责撰写和润色文章。',
  tools: ['Read', 'Write', 'Edit'],
});

const reviewerAgent = new ClaudeAgent({
  name: 'reviewer',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: '你是一个质量审核专家,负责检查内容的准确性和可读性。',
  tools: ['Read'],
});

// 协作流程
async function collaborativeWriting(topic: string) {
  // 第一步:研究
  const research = await researchAgent.run(`研究主题:${topic}`);

  // 第二步:写作
  const draft = await writerAgent.run(
    `基于以下研究结果,撰写一篇文章:\n${research}`
  );

  // 第三步:审核
  const review = await reviewerAgent.run(
    `审核以下文章,提出修改建议:\n${draft}`
  );

  // 第四步:修改
  const final = await writerAgent.run(
    `根据审核意见修改文章:\n原稿:${draft}\n意见:${review}`
  );

  return final;
}

멀티 에이전트를 사용해야 할 때:

  • 프로그래밍, 디자인, 카피라이팅처럼 작업에 여러 전문 역량이 필요한 경우
  • 단일 에이전트의 컨텍스트 창이 충분하지 않은 경우
  • 역할별 전문 분담이 필요한 경우

경고: 멀티 에이전트는 디버깅 난도가 기하급수적으로 높아집니다. 두 에이전트 사이의 상태 동기화, 메시지 전달, 오류 처리만으로도 매우 복잡해집니다. 단일 에이전트로 해결할 수 있다면 억지로 멀티 에이전트를 도입하지 마세요.

3. 다섯 가지 멀티 에이전트 오케스트레이션 패턴

멀티 에이전트가 정말 필요한 상황이라면 다음으로 오케스트레이션 패턴을 선택해야 합니다. Azure 공식 문서가 정리한 다음 다섯 가지 패턴은 대부분의 상황을 포괄합니다.

3.1 Sequential(순차 오케스트레이션)

가장 직관적인 패턴입니다. 에이전트 A의 출력이 에이전트 B의 입력으로 전달되는 파이프라인 방식입니다.

[에이전트 A] → [에이전트 B] → [에이전트 C] → 최종 결과

적합한 상황: 문서 생성 파이프라인(조사 → 초안 작성 → 검토 → 게시), 코드 생성 프로세스.

코드 예제:

// 顺序编排示例
async function sequentialPipeline(input: string) {
  const step1 = await researchAgent.run(input);
  const step2 = await writerAgent.run(step1.output);
  const step3 = await editorAgent.run(step2.output);
  return step3.output;
}

주의점: 각 단계의 출력 형식을 미리 합의해야 합니다. 그렇지 않으면 다음 에이전트가 이해할 수 없는 데이터를 받게 됩니다.

3.2 Concurrent(동시 오케스트레이션)

여러 에이전트가 같은 입력을 동시에 처리한 뒤 결과를 취합합니다.

           → [에이전트 A] →
[입력]  →  → [에이전트 B] →  → [취합기] → 최종 결과
           → [에이전트 C] →

적합한 상황: 다각도 분석, 주식 평가(기술적 분석 + 기본적 분석 + 뉴스 분석 병렬 처리), 코드 리뷰(보안 + 성능 + 스타일 병렬 검사).

코드 예제:

// 并发编排示例
async function concurrentAnalysis(code: string) {
  const [security, performance, style] = await Promise.all([
    securityAgent.run(`安全审查:\n${code}`),
    performanceAgent.run(`性能分析:\n${code}`),
    styleAgent.run(`代码风格检查:\n${code}`),
  ]);

  // 汇总结果
  return {
    security: security.output,
    performance: performance.output,
    style: style.output,
  };
}

주의점: 병렬 실행에서는 결과를 취합하는 로직을 잘 설계해야 합니다. 에이전트마다 서로 충돌하는 제안을 내놓을 수 있으므로 중재 메커니즘이 필요합니다.

3.3 Group Chat(그룹 채팅 오케스트레이션)

여러 에이전트가 하나의 ‘채팅방’에서 합의에 도달하거나 시간이 초과될 때까지 토론합니다.

[에이전트 A] ⇄ [에이전트 B] ⇄ [에이전트 C]
     ↑           ↓
   [Moderator/조정자]

적합한 상황: 브레인스토밍, 품질 검증, 의사결정을 위해 여러 차례 토론이 필요한 상황.

Azure 공식 권장 사항: 그룹 채팅 에이전트 수를 3개 이하로 제한하세요. 그보다 많으면 말 그대로 말싸움이 되기 쉽습니다.

코드 예제:

// 群聊编排示例(伪代码示意)
interface ChatMessage {
  sender: string;
  content: string;
}

async function groupChatDiscussion(
  topic: string,
  agents: ClaudeAgent[],
  maxRounds: number = 5
) {
  const history: ChatMessage[] = [];

  for (let round = 0; round < maxRounds; round++) {
    for (const agent of agents) {
      const response = await agent.run(
        `讨论主题:${topic}\n当前对话历史:${JSON.stringify(history)}\n请发表你的观点。`
      );
      history.push({ sender: agent.name, content: response.output });

      // 检查是否达成共识
      if (checkConsensus(history)) {
        return summarizeConsensus(history);
      }
    }
  }

  return '讨论超时,未达成共识';
}

시행착오에서 얻은 주의점: 반드시 maxRounds를 설정하세요. 그렇지 않으면 완고한 에이전트 두 개가 계속 논쟁할 수 있습니다. 토론이 수렴하도록 이끄는 Moderator 역할을 두는 것도 좋습니다.

3.4 Handoff(인계 오케스트레이션)

한 에이전트가 작업을 마치거나 다른 전문성이 필요하다고 판단하면 다음 에이전트에게 작업을 넘깁니다.

[에이전트 A] B의 전문성이 필요하다고 판단 → [에이전트 B]에게 인계 → 계속 처리

적합한 상황: 고객 상담 챗봇(영업 전 문의 → 기술 지원 → 사후 지원), 장애 처리(진단 → 수정 → 검증).

코드 예제:

// 移交编排示例
const supportAgent = new ClaudeAgent({
  name: 'support',
  systemPrompt: `你是客服。如果用户问技术问题,回复 "HANDOFF:tech"。
如果用户问售后问题,回复 "HANDOFF:after_sales"。`,
});

const techAgent = new ClaudeAgent({
  name: 'tech',
  systemPrompt: '你是技术支持专家。',
});

async function handleWithHandoff(userInput: string) {
  let currentAgent = supportAgent;
  let response = await currentAgent.run(userInput);

  // 检测移交信号
  while (response.output.includes('HANDOFF:')) {
    const targetAgent = response.output.match(/HANDOFF:(\w+)/)?.[1];

    if (targetAgent === 'tech') currentAgent = techAgent;
    else if (targetAgent === 'after_sales') currentAgent = afterSalesAgent;

    response = await currentAgent.run(userInput);
  }

  return response.output;
}

주의점: 인계 로직을 명확하게 설계해 순환 인계(A가 B에게 넘기고 B가 다시 A에게 넘기는 상황)를 방지해야 합니다.

3.5 Magentic(마젠틱 오케스트레이션)

가장 유연한 패턴입니다. 작업 특성에 따라 가장 적합한 에이전트를 동적으로 ‘끌어와’ 처리합니다.

[작업 풀] → [지능형 스케줄러] → 작업 특성에 따라 [에이전트 A/B/C] 선택

적합한 상황: 작업 유형이 다양한 시스템, 리소스를 동적으로 배정해야 하는 상황.

구현 아이디어:

// 磁性编排示例
interface Task {
  type: string;
  priority: number;
  content: string;
}

async function magenticScheduling(task: Task) {
  // 根据任务类型选择最合适的 Agent
  const agentScores = await Promise.all(
    agents.map(async (agent) => {
      const score = await evaluateAgentFit(agent, task);
      return { agent, score };
    })
  );

  // 选择得分最高的 Agent
  const bestAgent = agentScores.sort((a, b) => b.score - a.score)[0].agent;
  return bestAgent.run(task.content);
}

주의점: ‘적합도 평가’ 로직을 제대로 설계해야 합니다. 그렇지 않으면 스케줄링이 무작위 배정과 다르지 않게 됩니다.

3.6 패턴 선택 빠른 참조표

패턴적합한 상황복잡도주요 위험
Sequential파이프라인형 작업낮음단계 간 의존성으로 인한 지연
Concurrent다각도 병렬 분석중간결과 충돌로 중재 필요
Group Chat여러 차례 토론을 통한 의사결정높음수렴 실패, 무한 논쟁
Handoff동적인 역할 분담과 협업중간순환 인계, 인계 교착 상태
Magentic다양한 유형의 작업높음복잡한 스케줄링 로직

4. 주요 프레임워크 비교 및 선택

아키텍처 패턴을 살펴봤으니 이제 어떤 프레임워크를 사용할지 알아볼 차례입니다. LangChain, AutoGen, CrewAI, Claude Agent SDK는 각자 내세우는 강점이 있어 선택하기가 쉽지 않습니다.

먼저 제 생각부터 말하자면 최고의 프레임워크는 없고, 자신의 상황에 가장 적합한 프레임워크만 있습니다.

4.1 프레임워크 포지셔닝 비교

프레임워크핵심 포지셔닝강점적합한 상황
LangChain범용 에이전트 프레임워크풍부한 도구 통합, 성숙한 ReAct 구현빠른 프로토타이핑, 프로덕션 애플리케이션, 많은 도구 통합이 필요한 경우
AutoGen멀티 에이전트 협업대화형 협업, 사람과 AI의 협업복잡한 멀티 에이전트 시스템, 사람의 개입이 필요한 경우
CrewAI역할 기반 협업간결한 API, 직관적인 개념팀 시뮬레이션, 역할 구분이 명확한 경우
Claude Agent SDKClaude 네이티브코드 이해, 파일 작업, Claude와의 긴밀한 통합Claude 생태계, 코드 에이전트, 자동화 작업

4.2 각 프레임워크의 특징

LangChain: 오랜 역사를 지닌 프레임워크로 생태계가 가장 성숙했습니다.

  • TypeScript와 Python을 모두 완벽하게 지원합니다
  • 수많은 도구와 통합 기능이 내장되어 있습니다
  • ReAct와 Plan-and-Execute 구현을 바로 사용할 수 있습니다
  • 단점은 API가 자주 바뀌고 문서 업데이트가 이를 따라가지 못할 때가 있다는 것입니다

AutoGen: Microsoft가 만든 멀티 에이전트 협업용 대표 선택지입니다.

  • 핵심 개념은 ‘대화’이며, 에이전트가 메시지를 주고받으며 협업합니다
  • 사람의 개입(Human-in-the-loop)을 지원합니다
  • 여러 차례 토론과 의사결정이 필요한 상황에 적합합니다
  • 단점은 학습 곡선이 가파르고 멀티 에이전트 시스템을 디버깅하기가 매우 어렵다는 것입니다

CrewAI: 간결함을 내세운 신생 프레임워크입니다.

  • ‘역할’, ‘작업’, ‘팀’이라는 개념으로 모델링해 매우 직관적입니다
  • API 설계가 깔끔해 배우기 쉽습니다
  • 멀티 에이전트 프로토타입을 빠르게 만드는 데 적합합니다
  • 단점은 생태계와 도구 통합이 LangChain만큼 풍부하지 않다는 것입니다

Claude Agent SDK: Anthropic이 2026년에 새로 출시한 공식 도구입니다.

  • Claude 모델과 긴밀하게 통합됩니다
  • 파일 읽기와 쓰기, 코드 편집, 명령 실행 기능이 내장되어 있습니다
  • permissionMode로 작업 권한을 제어할 수 있습니다
  • 주력 모델이 Claude라면 가장 먼저 고려할 선택지입니다

4.3 선택 가이드

다음 질문을 스스로에게 해보세요.

  1. 주력 모델은 무엇인가요?

    • Claude → Claude Agent SDK 우선 고려
    • OpenAI → LangChain 생태계가 더 성숙함
    • 멀티 모델 → LangChain 또는 AutoGen
  2. 작업의 복잡도는 어느 정도인가요?

    • 단일 에이전트 + 도구 → LangChain으로 충분함
    • 멀티 에이전트 협업 → AutoGen 또는 CrewAI
    • 코드 관련 작업 → Claude Agent SDK
  3. 팀의 기술 스택은 무엇인가요?

    • 주로 Python 사용 → 모든 프레임워크 지원
    • 주로 TypeScript 사용 → LangChain과 Claude Agent SDK가 더 잘 지원함
  4. 사람과 AI의 협업이 필요한가요?

    • 필요함 → AutoGen의 Human-in-the-loop 설계가 뛰어남
    • 필요 없음 → 다른 프레임워크도 모두 사용 가능

4.4 제가 권하는 선택법

솔직히 말하면 대부분의 상황에서는 LangChain으로 충분합니다. 도구 통합과 ReAct 구현이 성숙했고 커뮤니티 지원도 좋습니다.

멀티 에이전트를 사용하기로 확실히 정했고, 작업이 여러 전문 에이전트의 협업을 요구할 만큼 복잡하다면 AutoGen을 시도해 볼 만합니다. 다만 멀티 에이전트는 디버깅 비용이 높다는 점을 기억하세요. 단지 ‘기술적으로 앞서 보인다’는 이유만으로 억지로 도입하면 안 됩니다.

Claude를 주력으로 사용한다면 Claude Agent SDK가 현재 가장 좋은 선택입니다. 공식 도구인 만큼 Claude 모델과 가장 매끄럽게 연동됩니다.

5. 실전 - Claude Agent SDK로 에이전트 구축하기

이론은 충분히 살펴봤으니 이제 실습해 봅시다. Claude Agent SDK를 이용해 실제로 실행되는 코드 리팩터링 에이전트를 만들어 보겠습니다.

5.1 환경 준비

# 安装依赖
npm install @anthropic-ai/claude-agent-sdk

# 设置 API Key
export ANTHROPIC_API_KEY=your_api_key_here

5.2 기본 에이전트 예제

import { ClaudeAgent } from '@anthropic-ai/claude-agent-sdk';

// 创建一个代码重构 Agent
const refactorAgent = new ClaudeAgent({
  model: 'claude-sonnet-4-20250514',
  tools: ['Read', 'Write', 'Edit', 'Bash'],
  permissionMode: 'acceptEdits', // 自动接受编辑操作
  workingDirectory: './src', // 工作目录
});

// 执行任务
async function refactorCode(task: string) {
  const result = await refactorAgent.run(task);
  console.log('重构结果:', result);
  return result;
}

// 使用示例
refactorCode('重构 auth.ts 文件,将回调风格的代码改为 async/await');

5.3 주요 설정 설명

permissionMode(권한 모드):

  • 'acceptEdits': 파일 편집 작업을 자동으로 승인
  • 'interactive': 작업할 때마다 사람의 확인 필요
  • 'planOnly': 계획만 만들고 실행하지 않음

tools(사용 가능한 도구):

  • Read: 파일 읽기
  • Write: 새 파일 생성
  • Edit: 기존 파일 편집
  • Bash: 명령줄 명령 실행
  • Glob: 파일 패턴 매칭
  • Grep: 내용 검색

5.4 더 복잡한 예제: 제약 조건이 있는 에이전트

const cautiousAgent = new ClaudeAgent({
  model: 'claude-sonnet-4-20250514',
  tools: ['Read', 'Write', 'Edit', 'Bash'],
  permissionMode: 'interactive', // 谨慎模式:需要人工确认
  maxIterations: 20, // 限制最大迭代次数
  timeout: 300000, // 5 分钟超时

  // 系统提示词:定义 Agent 行为边界
  systemPrompt: `你是一个代码重构专家。
规则:
1. 不删除任何测试文件
2. 不修改 package.json
3. 每次修改前先备份原文件
4. 修改后运行测试确保功能正常`,
});

async function safeRefactor(filePath: string) {
  try {
    const result = await cautiousAgent.run(
      `请重构 ${filePath},优化代码结构和可读性。`
    );
    return result;
  } catch (error) {
    console.error('重构失败:', error);
    // 回滚逻辑...
  }
}

5.5 모범 사례

  1. 반복 횟수 제한: 에이전트가 무한 루프에 빠지는 것을 방지합니다
  2. 제한 시간 설정: 오래 실행되는 작업에는 반드시 안전장치를 둡니다
  3. 권한 등급 구분: 민감한 작업에는 interactive 모드를 사용합니다
  4. 백업 메커니즘: 중요한 파일을 수정하기 전에 백업합니다
  5. 테스트 검증: 수정 후 테스트를 실행해 기능이 정상인지 확인합니다

5.6 디버깅 팁

// 开启详细日志
const debugAgent = new ClaudeAgent({
  model: 'claude-sonnet-4-20250514',
  tools: ['Read', 'Write', 'Edit'],
  verbose: true, // 打印详细执行过程
});

// 监听事件
debugAgent.on('toolCall', (tool, args) => {
  console.log(`调用工具:${tool},参数:${JSON.stringify(args)}`);
});

debugAgent.on('thinking', (thought) => {
  console.log(`Agent 思考:${thought}`);
});

마치며

에이전트 아키텍처를 선택하는 핵심 원칙은 결국 한 문장으로 정리할 수 있습니다. 단순하게 시작하고 필요한 것을 하나씩 추가하세요.

먼저 작업의 복잡도를 판단합니다.

  • 단일 단계 작업인가요? 모델을 직접 호출하세요
  • 도구가 필요한가요? 단일 에이전트 + 도구를 사용하세요
  • 여러 전문 역할이 정말 필요한가요? 그때 멀티 에이전트를 고려하세요

그다음 패턴을 선택합니다.

  • 작업이 동적으로 변하나요? ReAct
  • 단계를 예측할 수 있나요? Plan-and-Execute
  • 전문 역할 분담이 필요한가요? Multi-Agent

마지막으로 프레임워크를 선택합니다.

  • Claude 사용자라면? Claude Agent SDK
  • 여러 모델과 도구를 사용한다면? LangChain
  • 멀티 에이전트 협업이라면? AutoGen 또는 CrewAI

무엇보다 중요한 것은 직접 시도해 보는 일입니다. 작은 프로젝트를 하나 골라 에이전트를 만들고 실행해 보세요. 몇 가지 시행착오를 겪고 나면 자연스럽게 이해하게 될 것입니다.

궁금한 점이 있다면 댓글로 이야기해 주세요. 또는 앞서 작성한 두 글인 ‘MCP Server 개발 입문’과 ‘에이전트 도구 호출 실전’도 확인해 보세요. 세 글이 하나의 흐름으로 이어집니다.

Claude Agent SDK로 에이전트 구축하기

환경 준비부터 첫 번째 에이전트 실행까지의 전체 과정

⏱️ Estimated time: 30 min

  1. 1

    Step 1: 의존성 설치 및 환경 설정

    다음 명령을 실행합니다.

    ```bash
    npm install @anthropic-ai/claude-agent-sdk
    export ANTHROPIC_API_KEY=your_api_key_here
    ```

    참고: API Key는 Anthropic 공식 웹사이트에서 발급받아 환경 변수에 저장하는 것이 좋습니다.
  2. 2

    Step 2: 기본 에이전트 인스턴스 생성

    에이전트를 만들 때는 세 가지 핵심 매개변수를 설정해야 합니다.

    ```typescript
    const agent = new ClaudeAgent({
    model: 'claude-sonnet-4-20250514',
    tools: ['Read', 'Write', 'Edit', 'Bash'],
    permissionMode: 'acceptEdits'
    });
    ```

    • model: 사용할 Claude 모델 버전
    • tools: 에이전트가 사용할 수 있는 도구
    • permissionMode: 권한 제어 모드
  3. 3

    Step 3: 작업 실행 및 결과 가져오기

    run 메서드를 호출해 작업을 실행합니다.

    ```typescript
    const result = await agent.run('重构 auth.ts 文件');
    ```

    오류 처리와 로그 기록을 추가하는 것이 좋습니다.
  4. 4

    Step 4: 안전장치 설정

    프로덕션 환경에서는 반드시 다음 안전장치를 설정해야 합니다.

    • maxIterations: 최대 반복 횟수 제한(권장값 20)
    • timeout: 제한 시간 설정(권장값 5분)
    • systemPrompt: 행동 경계 정의
    • permissionMode: 민감한 작업에는 'interactive' 모드 사용

FAQ

ReAct, Plan-and-Execute, Multi-Agent 세 가지 패턴은 어떻게 선택하나요?
작업 특성에 따라 선택합니다. ReAct는 단계가 불확실하고 동적 의사결정이 필요한 상황(예: 고객 상담)에 적합합니다. Plan-and-Execute는 단계를 예측할 수 있고 안정적인 출력이 필요한 상황(예: 보고서 생성)에 적합합니다. Multi-Agent는 여러 전문 역량이 협업해야 하는 복잡한 작업(예: 소프트웨어 개발 파이프라인)에 적합합니다.
Azure가 그룹 채팅 에이전트를 3개 이하로 제한하라고 권장하는 이유는 무엇인가요?
그룹 채팅 에이전트가 너무 많으면 두 가지 문제가 생깁니다. 첫째, 토론이 수렴하기 어려워 여러 에이전트가 끝없는 논쟁에 빠질 수 있습니다. 둘째, 에이전트 간 상태 동기화와 메시지 전달이 매우 복잡해져 디버깅 비용이 기하급수적으로 증가합니다. 에이전트 3개(예: 진행자와 서로 다른 관점을 가진 두 참여자)면 토론과 의사결정이 필요한 대부분의 상황을 처리하기에 충분합니다.
LangChain과 AutoGen/CrewAI 중 무엇을 선택해야 하나요?
대부분의 상황에서는 LangChain으로 충분합니다. 도구 통합이 풍부하고 ReAct 구현이 성숙했으며 커뮤니티 지원도 좋습니다. 멀티 에이전트 협업이 확실히 필요할 때만 AutoGen이나 CrewAI를 고려하세요. AutoGen은 사람의 개입(Human-in-the-loop)을 지원하므로 수동 개입이 필요한 상황에 적합하고, CrewAI는 API가 더 간결해 빠른 프로토타이핑에 적합합니다.
Claude Agent SDK는 어떤 상황에 적합한가요?
Claude Agent SDK는 Anthropic의 공식 도구로, 세 가지 상황에 특히 적합합니다. 첫째, 주력 모델이 Claude여서 Claude와의 긴밀한 통합이 필요할 때입니다. 둘째, 파일 읽기와 쓰기, 코드 편집 기능이 내장된 코드 관련 작업입니다. 셋째, permissionMode를 통해 작업 권한을 단계별로 관리해야 하는 정교한 권한 제어 상황입니다.
에이전트가 무한 루프에 빠지는 것을 어떻게 막을 수 있나요?
세 가지 핵심 안전장치가 있습니다. 첫째, maxIterations를 설정해(권장값 10~20회) 한도를 넘으면 강제로 중지합니다. 둘째, timeout을 설정해(권장값 5분) 시간이 초과되면 자동 중단합니다. 셋째, systemPrompt에 종료 조건을 명확히 적어 어떤 상황에서 작업을 포기해야 하는지 에이전트에게 알려 줍니다. 제가 처음 만든 ReAct 에이전트는 이런 설정이 없어 밤새 실행됐습니다.

6분 읽기 · 게시일: 2026년 3월 21일 · 수정일: 2026년 9월 4일

댓글

GitHub로 로그인하여 댓글을 남기세요

Easton BlogEaston Blog