티스토리 뷰

 

데이터 수집 파이프라인을 Tool Wrapper로 통합한 Agent 설계와 구현

 

AI Agent를 실제 서비스 환경에 도입하려고 할 때 가장 먼저 부딪히는 문제는, Agent가 “무엇을 할 수 있는가”가 아니라 “어디까지 책임져야 하는가”입니다. 특히 이미 운영 중인 데이터 수집 파이프라인이 존재하는 경우, 이를 AI Agent 내부로 흡수할 것인지, 아니면 외부 시스템으로 유지한 채 연동할 것인지에 대한 판단은 전체 아키텍처의 복잡도와 안정성에 직접적인 영향을 미칩니다.

 

이 글에서는 자동화된 데이터 수집 파이프라인을 그대로 유지하면서, langchain4j가 제공하는 Tool 추상화를 활용해 AI Agent 로직과 단계적으로 통합한 설계와 구현 과정을 정리합니다. 단순한 예제나 개념 설명이 아니라, 실제 시스템 분리를 전제로 한 구조적 판단과 그에 따른 구현 방식을 중심으로 설명합니다.

 


 

데이터 수집 파이프라인을 독립 시스템으로 유지한 이유

 

첨부된 1단계 설계서에서 정의된 데이터 수집 파이프라인은, 특정 AI Agent를 위해 만들어진 구조가 아닙니다. 외부 API 호출, 정형·비정형 데이터 정제, 저장소 적재까지의 책임이 명확히 분리되어 있으며, 스케줄 기반 또는 이벤트 기반으로 동작하도록 설계되어 있습니다.

 

이 파이프라인을 Agent 내부 로직으로 흡수하지 않고 독립 시스템으로 유지한 이유는 명확합니다. 데이터 수집은 장기 실행 작업이며, 실패 복구와 재시도가 핵심 관심사입니다. 반면 AI Agent는 사용자 요청을 기반으로 판단하고 의사결정을 수행하는 컴포넌트입니다. 두 영역은 실행 시간, 장애 특성, 확장 전략이 다르기 때문에 하나의 책임 단위로 묶는 것이 합리적이지 않습니다.

 

따라서 이 설계에서는 데이터 수집 파이프라인을 “Agent가 사용할 수 있는 기능”으로만 노출하고, 내부 구현과 실행 흐름은 완전히 감추는 방향을 선택합니다.

 


 

langchain4j Tool 추상화를 선택한 배경

 

langchain4j는 Java 환경에서 LLM 기반 애플리케이션을 구성하기 위해 Agent, Tool, Memory, Chain과 같은 핵심 추상화를 제공합니다. 이 중 Tool은 “LLM이 호출할 수 있는 외부 기능”을 명시적으로 정의하기 위한 인터페이스입니다.

 

2단계 설계서에서는 데이터 수집 파이프라인을 직접 호출하는 서비스 레이어를 Agent 내부에 두지 않고, langchain4j Tool Wrapper로 감싸는 방식을 선택합니다. 이 접근의 핵심은 Tool이 단순한 유틸리티 메서드가 아니라, Agent와 외부 시스템 간의 계약 역할을 한다는 점입니다.

 

Tool 인터페이스에는 입력과 출력이 명확히 정의되며, 내부에서 어떤 네트워크 호출이나 비동기 처리가 이루어지는지는 Agent가 알 필요가 없습니다. 이는 langchain4j 공식 문서에서 설명하는 Tool의 목적과 정확히 일치합니다. Tool은 “무엇을 할 수 있는지”만 설명하고, “어떻게 구현되었는지”는 숨기는 계층입니다.

 


 

데이터 파이프라인 Tool Wrapper 설계의 핵심 제약

 

Tool Wrapper를 설계할 때 가장 중요하게 고려한 제약은, Tool 호출이 곧 파이프라인 실행을 의미하지 않도록 하는 것입니다. 즉, Agent가 Tool을 호출했다고 해서 즉시 전체 수집 파이프라인가 동기적으로 실행되는 구조는 피합니다.

 

설계서에서는 Tool 호출을 “작업 요청 생성” 수준으로 제한합니다. Tool은 수집 작업을 트리거하는 메시지나 요청 객체를 생성하고, 실제 실행은 기존 파이프라인의 실행 정책에 따라 처리됩니다. 이를 통해 Agent는 장시간 블로킹 없이 판단 흐름을 유지할 수 있습니다.

 

이 방식은 langchain4j Tool이 동기 메서드 형태로 정의되더라도, 내부 구현은 비동기 메시징이나 작업 큐 기반으로 위임할 수 있다는 점을 전제로 합니다. Tool의 시그니처와 실행 모델을 혼동하지 않는 것이 이 설계의 핵심입니다.

 


 

AI Agent의 역할을 판단 로직으로 한정한 이유

 

3단계 설계서에서 정의된 AI Agent의 역할은 명확합니다. Agent는 데이터를 수집하지 않고, 수집이 필요한지를 판단합니다. 다시 말해 Agent는 “실행 주체”가 아니라 “의사결정자”입니다.

 

langchain4j Agent는 LLM의 추론 결과를 바탕으로 Tool을 선택적으로 호출할 수 있습니다. 이 구조를 그대로 활용하되, Agent 내부에는 데이터 소스, API 엔드포인트, 저장소와 같은 정보가 전혀 존재하지 않도록 설계합니다. 이러한 정보는 모두 Tool 구현 내부에만 존재합니다.

 

이로 인해 Agent 프롬프트는 단순해집니다. “어떤 상황에서 어떤 Tool을 호출할 수 있는지”만 기술하면 되며, 복잡한 실행 흐름을 프롬프트에 설명할 필요가 없습니다. 이는 프롬프트 안정성과 재현성을 높이는 방향이기도 합니다.

 


 

단순 서비스 호출과 Agent + Tool 구조의 차이

 

표면적으로 보면, Agent가 Tool을 호출하는 구조는 단순한 서비스 메서드 호출과 크게 다르지 않아 보일 수 있습니다. 그러나 실제로는 책임 분리와 변경 영향 범위에서 차이가 발생합니다.

 

일반적인 서비스 호출 구조에서는 호출 조건과 호출 로직이 코드에 고정됩니다. 반면 Agent + Tool 구조에서는 호출 여부 자체가 LLM의 판단 결과로 결정됩니다. 이는 비즈니스 규칙이 코드가 아닌 프롬프트와 모델 출력에 의해 유연하게 조정될 수 있음을 의미합니다.

 

이 글의 설계에서는 이러한 유연성을 무분별하게 사용하지 않습니다. Agent의 판단 범위는 설계서에 정의된 조건으로 제한되며, Tool 호출은 명확한 트리거 상황에서만 허용됩니다. 이는 langchain4j가 제공하는 Agent 구조를 “자동화된 비즈니스 로직”이 아니라 “보조적 판단 계층”으로 사용하기 위한 의도적인 선택입니다.

 


 

Tool과 Agent 간 결합도를 낮추기 위한 구조적 판단

 

Agent가 Tool의 존재를 알되, Tool의 결과에 과도하게 의존하지 않도록 하는 것도 중요한 설계 포인트입니다. Tool 호출 결과는 성공 여부와 최소한의 메타데이터만 반환하며, 대량의 데이터나 상세 실행 로그는 반환하지 않습니다.

 

이는 Agent의 메모리 사용량과 토큰 소비를 제한하는 효과도 있습니다. langchain4j Memory 설계 가이드에서도, Agent가 필요 이상의 데이터를 컨텍스트로 유지하지 않도록 주의할 것을 권장합니다. 이 설계는 해당 권고를 그대로 반영한 결과입니다.

 


 

단계적 통합이 가능했던 이유

 

이 구조의 장점은 기존 시스템을 거의 수정하지 않고도 AI Agent를 단계적으로 도입할 수 있었다는 점입니다. 1단계에서는 데이터 파이프라인만 존재했고, 2단계에서는 이를 감싸는 Tool Wrapper가 추가되었으며, 3단계에서야 Agent가 등장합니다.

 

각 단계는 독립적으로 테스트 가능하며, 특정 단계의 문제가 전체 시스템으로 확산되지 않습니다. 이는 AI Agent 도입을 “대규모 전환”이 아니라 “점진적 확장”으로 만들기 위한 설계 전략이었습니다.

 


 

정리하며

 

langchain4j를 활용한 AI Agent 구현에서 가장 중요한 요소는 기술 스택 자체가 아니라, 책임 경계를 어디에 두느냐입니다. 이 글에서 다룬 구조는 Agent를 모든 것을 해결하는 만능 컴포넌트로 취급하지 않고, 기존 시스템 위에 판단 계층으로 얹는 방식에 가깝습니다.

 

데이터 수집 파이프라인을 Tool로 감싸고, Agent는 이를 선택적으로 호출하는 구조는 단순해 보이지만, 실제 운영 환경에서 안정성과 확장성을 동시에 확보하기 위한 현실적인 선택이었습니다. langchain4j가 제공하는 Tool과 Agent 추상화는 이러한 구조를 Java 환경에서 비교적 명확하게 구현할 수 있도록 돕는 도구에 가깝습니다.

 

이 접근은 AI Agent를 도입하려는 모든 시스템에 정답이 될 수는 없지만, 기존 자동화 파이프라인을 보유한 환경에서는 충분히 검토할 가치가 있는 설계 방향입니다.