Spring AI 에이전트 패턴, 초보자도 이해하는 쉬운 해설

·10분 읽기
Spring AI 에이전트 패턴, 초보자도 이해하는 쉬운 해설

Spring AI 에이전트 패턴 원문 흐름 번역 + 쉬운 해설 (코드/다이어그램 포함)

Spring AI Agentic Patterns

좋아, 이번 글은 요약이 아니라 Spring 원문 흐름을 따라가면서,

  • 패턴별 핵심 의미
  • 원문 맥락의 코드
  • 이해를 돕는 다이어그램 을 모두 포함해서 정리했다.

0) 먼저 큰 메시지

Spring 글이 Anthropic 연구를 바탕으로 강조하는 핵심은 아래다.

  1. 복잡한 프레임워크부터 시작하지 말 것
  2. 단순한 패턴을 조합할 것
  3. 운영 가능성(예측 가능성/유지보수성)을 우선할 것

1) Agentic Systems: 워크플로우 vs 에이전트

  • 워크플로우: 코드로 경로를 고정
  • 에이전트: 모델이 다음 행동/도구를 동적으로 결정

다이어그램

flowchart LR
  A[입력] --> B{고정 경로?}
  B -->|예| C[Workflow\n(정해진 코드 경로)]
  B -->|아니오| D[Agent\n(모델이 동적 결정)]
  C --> E[예측 가능성 높음]
  D --> F[유연성 높음]

초보자 관점 한 줄:

  • 운영 안정성이 중요하면 워크플로우부터,
  • 미리 경로를 정할 수 없는 복잡한 문제면 에이전트로 확장.

2) 패턴 1 — Chain Workflow

복잡한 작업을 단계로 나눠 순차 처리하는 패턴.

의미

  • 각 단계 책임이 명확해짐
  • 한 번에 시키는 것보다 정확도 향상 가능
  • 대신 지연시간은 증가

다이어그램

Chain Workflow Diagram

코드 (원문 맥락)

public class ChainWorkflow {
    private final ChatClient chatClient;
    private final String[] systemPrompts;

    // Processes input through a series of prompts, where each step's output
    // becomes input for the next step in the chain.
    public String chain(String userInput) {
        String response = userInput;
        for (String prompt : systemPrompts) {
            String input = String.format("{%s}\n {%s}", prompt, response);
            response = chatClient.prompt(input).call().content();
        }
        return response;
    }
}

3) 패턴 2 — Parallelization Workflow

여러 LLM 호출을 동시에 실행하고 결과를 합치는 패턴.

의미

  • 속도 개선(동시 처리)
  • 관점 다양화(투표/합의)

다이어그램

Parallelization Workflow Diagram

코드 (원문 맥락)

List<String> parallelResponse = new ParallelizationWorkflow(chatClient)
    .parallel(
        "Analyze how market changes will impact this stakeholder group.",
        List.of(
            "Customers: ...",
            "Employees: ...",
            "Investors: ...",
            "Suppliers: ..."
        ),
        4
    );

4) 패턴 3 — Routing Workflow

입력을 분류해서 가장 적합한 전문 프롬프트로 보내는 패턴.

의미

  • 하나의 범용 프롬프트보다 품질 개선
  • 입력 유형별 전문화 가능

다이어그램

Routing Workflow Diagram

코드 (원문 맥락)

@Autowired
private ChatClient chatClient;

RoutingWorkflow workflow = new RoutingWorkflow(chatClient);

Map<String, String> routes = Map.of(
    "billing", "You are a billing specialist. Help resolve billing issues...",
    "technical", "You are a technical support engineer. Help solve technical problems...",
    "general", "You are a customer service representative. Help with general inquiries..."
);

String input = "My account was charged twice last week";
String response = workflow.route(input, routes);

5) 패턴 4 — Orchestrator-Workers

중앙 LLM(오케스트레이터)이 과업을 분해하고, 워커들이 병렬 처리한 뒤 합성하는 패턴.

의미

  • 하위 작업을 미리 고정하기 어려운 문제에 유리
  • 복잡 작업을 유연하게 분해 가능

다이어그램

Orchestrator-Workers Diagram

코드 (원문 맥락)

public class OrchestratorWorkersWorkflow {
    public WorkerResponse process(String taskDescription) {
        // 1. Orchestrator analyzes task and determines subtasks
        OrchestratorResponse orchestratorResponse = // ...

        // 2. Workers process subtasks in parallel
        List<String> workerResponses = // ...

        // 3. Results are combined into final response
        return new WorkerResponse(/*...*/);
    }
}
ChatClient chatClient = // ... initialize chat client
OrchestratorWorkersWorkflow workflow = new OrchestratorWorkersWorkflow(chatClient);

WorkerResponse response = workflow.process(
    "Generate both technical and user-friendly documentation for a REST API endpoint"
);

System.out.println("Analysis: " + response.analysis());
System.out.println("Worker Outputs: " + response.workerResponses());

6) 패턴 5 — Evaluator-Optimizer

생성 모델과 평가 모델이 반복 루프를 돌며 결과를 개선하는 패턴.

의미

  • 품질 기준이 명확한 작업에서 강력
  • 사람의 “작성→리뷰→수정” 흐름을 자동화

다이어그램

Evaluator-Optimizer Loop Diagram

코드 (원문 맥락)

public class EvaluatorOptimizerWorkflow {
    public RefinedResponse loop(String task) {
        // 1. Generate initial solution
        Generation generation = generate(task, context);

        // 2. Evaluate the solution
        EvaluationResponse evaluation = evaluate(generation.response(), task);

        // 3. If PASS, return solution
        // 4. If NEEDS_IMPROVEMENT, incorporate feedback and generate new solution
        // 5. Repeat until satisfactory
        return new RefinedResponse(finalSolution, chainOfThought);
    }
}
ChatClient chatClient = // ... initialize chat client
EvaluatorOptimizerWorkflow workflow = new EvaluatorOptimizerWorkflow(chatClient);

RefinedResponse response = workflow.loop(
    "Create a Java class implementing a thread-safe counter"
);

System.out.println("Final Solution: " + response.solution());
System.out.println("Evolution: " + response.chainOfThought());

7) Spring AI 구현 장점 (원문 포인트)

  • 모델 포터빌리티: 모델 교체 유연성
  • Structured Output: 타입 안전한 응답 파싱
  • 일관된 ChatClient API: 구현 일관성

예시(원문 맥락):

<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
EvaluationResponse response = chatClient.prompt(prompt)
    .call()
    .entity(EvaluationResponse.class);

8) 초보자용 적용 순서 (실무 권장)

  1. 단일 프롬프트 + RAG부터 시작
  2. 안 되면 체인/라우팅 하나 추가
  3. 성능 개선이 확인되면 병렬화 확장
  4. 복잡 과제에서만 오케스트레이터 도입
  5. 완성도 필요 시 평가-최적화 루프 추가

즉, 복잡도는 기능이 아니라 비용이므로, 반드시 성능 개선이 확인될 때만 올리는 게 정석이다.


출처

원문 패턴 설명 및 코드 예시를 기반으로 한국어 번역/해설했습니다.