에이전트 기획을 위한 5가지 구조
AI 프레임워크를 결정하며 환경 세팅에 대한 고민을 마쳤다면, 이제 우리가 만들려는 '에이전트'가 정확히 어떤 구조로 동작하는지 정의할 차례다.
에이전트를 기획한다고 하면 흔히 챗봇의 프롬프트를 정교하게 깎는 작업 정도로 생각하기 쉽다. 하지만 'LLM' 기능과 '에이전트'는 동작 방식 자체가 다르다. Spring AI에서 발행한 아티클(Introducing Spring AI Agents)에서도 이 차이를 명확히 짚고 있다.
단순하게 정의하자면 LLM은 '엔진'이고, 에이전트는 '스스로 목표를 달성하는 AI'라고 할 수 있다. LLM이 사용자의 질문에 텍스트를 생성해 주는 수동적인 역할에 그친다면, 에이전트는 LLM을 판단의 주체로써, 외부 도구를 조작해 실제 서비스에 물리적인 변화(액션)를 만들어내기 때문이다.
표로 정리하면 이런 느낌이다.
결국 에이전트를 기획한다는 것은 프롬프트를 정교하게 깎는 작업을 넘어, 에이전트가 목표를 달성하기 위해 어떤 도구를 언제 어떻게 쓸지 판을 짜는 일이다.
에이전트에게 주어지는 최종 목적지다. "사용자에게 잘 대답해줘" 같은 모호한 프롬프트가 아니라, "업로드된 100장의 이력서에서 Java 3년 차 이상인 사람만 추려서 리포트를 작성해야 한다."처럼 끝이 명확한 과업이어야 한다. 기획자는 사용자가 어떤 문제를 해결하고 싶은지 정의하고, 이를 에이전트가 수행 가능한 단위의 목표로 쪼개야 한다.
에이전트의 시스템 프롬프트에 목적이 많아지면 자연스레 에이전트의 추론 시간이 길어진다. 이때는 '에이전트의 정규화가 필요한 시점'이 아닌지 고민하자. 때로는 에이전트를 여러 개로 분리한 후, 추론을 거치지 않는 라우팅 에이전트를 중간에 두는 게 속도와 정확도 측면에서 더 나을 때도 있다. 라우팅용으로는GPT-5.4-nano, Gemini-2.5-flash 같은 것을 추천한다.
에이전트 하나의 시스템 프롬프트에 목적(Goal)이 너무 많아지면 자연스레 추론 시간이 길어지고 할루시네이션이 심해진다. 이때가 '에이전트의 정규화'가 필요한 시점이다. 무거운 에이전트 하나를 통으로 돌리기보다, 역할별로 에이전트를 쪼개는 것이 좋다. 그리고 맨 앞단에 추론을 깊게 하지 않고 질문의 의도만 파악해 적절한 에이전트를 체이닝하는 '라우팅 에이전트(Routing Agent)'를 두면 속도와 정확도를 모두 잡을 수 있다. 라우팅용으로는 GPT-5.4-nano, Gemini 2.5 flash 같이 빠르고 가벼운 소형 모델을 추천한다.
에이전트가 작업을 수행할 때 참고해야 하는 정보들이다. 채용 에이전트로 예를 들면, 사용자가 제품에 미리 등록해 둔 '지원서 템플릿, 메시지 템플릿, 채용 분야 코드값, 전형 정보' 등이 여기에 해당한다. 이 데이터를 얼마나 최적화해서 에이전트에게 전달하느냐가 최종 퀄리티와 API 비용을 결정한다.
에이전트에게 데이터를 쥐여주는 방식을 크게 3가지로 정리했다.
① 프롬프트 변수 주입
시스템 프롬프트 자체에 특정 값을 치환해서(예: {user_name}) 강제로 밀어 넣는 방식이다. 주로 공통적인 메시지 포맷이나 고정된 규칙을 세팅할 때 쓴다.
② 벡터 DB와 RAG(검색 증강 생성) 활용
"지원자 이력서"처럼 텍스트가 길고 비정형적인 데이터에 적합하다. 지원자가 수만 명씩 몰릴 때를 대비해, 이력서를 어떤 규칙으로 쪼개고(Chunking) 임베딩할지, 실시간으로 저장할지 배치(Batch)로 돌릴지 다양한 시뮬레이션과 정책 설계가 필요하다. 특히 채용은 민감한 분야라 나중에 "왜 이 사람을 추천했는지" 원리를 소명할 수 있도록 설계해야 한다. 이처럼 제품 도메인에 적절한 방법을 고민해야 한다. (데이터 실시간 동기화가 필요하다면 CDC 같은 프레임워크 활용도 방법이다.)
③ 실시간 조회 도구(Tool) 활용
에이전트가 필요할 때마다 사내 API를 직접 호출해서 최신 데이터를 조회해 오는 방식이다. 아래 3번에서 조금 더 자세히 다룬다.
에이전트 기획의 꽃이자, 기존 챗봇과 에이전트를 가르는 가장 큰 차이다. 과거 '펑션 콜(Function Call)'이라 불리던 기능이 진화한 개념이다. 예를 들어, 사용자가 "합격자에게 안내 메일 보내줘"라고 했을 때, 에이전트가 직접 제품의 '메일 발송 API'를 사용하는 도구(Tool)를 자율적으로 판단해 호출하는 식이다.
기존 제품에 에이전트를 붙이는 과정이라면, PM도 웹 브라우저의 개발자 도구를 열어 네트워크 탭을 보거나, 스웨거와 같은 API 문서를 전달받아 API를 분석하는 과정도 필요하다. 사용자가 특정 기능을 쓸 때 어떤 API가 호출되고 어떤 응답값이 떨어지는지 개발자와 소통할 수 있어야 하기 때문이다.
주의할 점은 기존 API의 응답값을 에이전트에게 '그대로' 던져주면 안 된다는 것이다. 불필요한 데이터가 섞여 있어 인풋토큰이 비대해지거나 맥락 오염이 발생해 품질이 확 떨어진다. 반드시 LLM이 소화하기 좋게 응답값을 최적화해야 한다.
도구 최적화 노하우는 다음 글에서 깊게 풀 생각이다.
에이전트가 과업을 끝냈을 때, 그 결과가 성공적인지 판단하는 기준이다. 시스템 에러율처럼 정량적으로 떨어지는 지표도 있지만, 채용 에이전트가 요약한 '지원자 평가 리포트'의 퀄리티 같은 것은 숫자로 측정하기 매우 어렵다. 그래서 평가 기준을 프롬프트로 만들고, 또 다른 LLM이 에이전트의 결과물을 채점하게 만드는 'LLM-as-a-Judge' 패턴을 많이 쓴다.
내 경우에는 2월부터 내부 에이전트의 벤치마킹 지표를 직접 설계하고, 이를 자동화해 2주에 한 번씩 품질을 측정하고 있다. 가장 중요한 건 기대 결과가 꼼꼼히 작성된 '평가 데이터셋'을 구축하는 일이다. 에이전트 기능이 수백 개인데 일일이 손으로 프롬프트를 치고 있을 순 없다. Datadog LLM Observability나 Langfuse 같은 LLM Ops 도구들이 있지만, 우리 제품 규격에 딱 들어맞지 않는 경우가 많다. (실제로 데이터독 측과 미팅도 해봤지만, 우리 유즈케이스에 완벽히 핏하게 쓰기엔 무리가 있었다.)
결국 개발자와 협의해 테스트용 API를 따로 뚫고, 직접 자동화 프로세스를 구축하는 것이 가장 확실하다. 수동으로 하는 프로세스를 시스템화하는 것인 만큼, 백오피스를 한 두 번 만들어본 기획자라면 이만큼 편한 작업이 없는 듯.
에이전트는 스스로 판단하고 행동하기 때문에 대형 사고를 칠 위험이 늘 존재한다. 라이브 DB 데이터를 멋대로 날리거나 엉뚱한 사람에게 합격 메일을 보내면 끝장나는 것처럼. 이번에 데이터를 직접 생성하고 수정하는 도구(Tool)까지 에이전트에게 쥐여주면서 그 위험성은 더 커졌다.
따라서 에이전트가 마음껏 실패해도 실제 서비스에는 영향이 없는 철저히 격리된 개발(DEV) 혹은 검증(QA) 환경에서 테스트를 진행한다. (이건 기능 개발할 때와 동일함)
더불어 에이전트가 API를 무한 루프로 호출하는 과사용 문제나, 악의적인 프롬프트 탈취(Prompt Injection), 탈옥(Jail Break) 같은 보안 사고가 터지지 않도록 프롬프트 앞단에 단단한 가드레일을 깔아두는 작업도 필수적이다.
기술적인 구현은 개발자의 몫이다. 하지만 사용자의 의도(Goal)를 파악해, 필요한 데이터(Context)를 물려주고, 정확한 타이밍에 우리 서비스의 기능(Tool)을 호출하게 판을 짜는 '오케스트레이션'은 온전히 기획자의 역할이다.
그래서 기획자는 더 이상 화면만 그리거나 "알아서 똑똑하게 동작하는 AI 만들어주세요"라고 요구해서는 안 된다. 사용자 여정의 어느 지점에서 에이전트가 개입할지, 그때 어떤 데이터를 쥐여줄지, 그리고 우리 서비스의 어떤 API를 실행하게 만들지 구체적인 시나리오를 촘촘하게 짜야 한다. 개발자가 만든 API 명세서(Swagger 등)를 들여다보는 것에 익숙해지고, 에이전트가 칠 수 있는 사고를 미리 예상해 가드레일을 쳐두어야 한다.
다음 글에서는 이 '도구(Tool)'을 더 깊게 파보려 한다. 에이전트가 그럴싸한 텍스트만 뱉어내는 것에 그치지 않고, 실제로 우리 제품의 버튼을 누르고 데이터를 조작하게 만들려면 이 도구를 어떻게 쥐여주느냐가 핵심이다. 기존 제품의 API를 에이전트가 쓸 수 있게 개조하며 겪었던 토큰 다이어트와 프롬프트 최적화 경험을 다룰 예정이다.
ⓒ 2026. 327roy All rights reserved.