AI Agent 개발 할 때 고민해볼 내용

TL;DR

시작하며

최근 AI 에이전트 기반의 간단한 로보틱스 프로젝트를 하게 되었다. 에이전트 방식으로 LLM (정확히는 Large Multimodal Model) 을 사용해보니 LLM 의 성능이 단순 프롬프트로만 처리했을 때보다 훨씬 다양한 문제를 더 쉽게 풀 수 있다는 것을 알게되었다.

개인적으로는 AI 에이전트(이하 에이전트) 가 앞으로 대세가 될 것 같은 느낌은 있지만, 다른 사람들에게 설명할 정도로 깊이 고민한 적은 없었다. 이번 기회에 개발자로서 에이전트에 대해서 간단히 정리해보려고 한다.

AI 에이전트란?

일단 AI 에이전트의 정의부터가 조금씩 다르기 때문에 이걸 먼저 정의하고 넘어가야 할 것 같다.

AWS 에서는 AI 에이전트를 다음과 같이 정의한다.1

An artificial intelligence (AI) agent is a software program that can interact with its environment, collect data, and use the data to perform self-determined tasks to meet predetermined goals.

GPT-4o 는 다음과 같이 정의한다.

AI 에이전트(AI Agent)는 특정 작업을 수행하거나 문제를 해결하기 위해 설계된 소프트웨어 프로그램 또는 시스템으로, 인공지능(AI) 기술을 활용하여 자동화된 방식으로 작동합니다. AI 에이전트는 자율적으로 행동하고, 데이터를 처리하며, 환경과 상호 작용할 수 있습니다

다른 곳에서는 각각 자신들의 논지에 맞춰서 조금씩 바꿔가면서 정의를 내리고 있고, 해당 정의를 넘어서는 내용들을 포함한 피쳐들을 특성이라는 이름으로 추가해서 설명하는 경향이 있다.

여튼 전체적으로는 다 맞는 말이지만, 개발자 입장에서는 해석의 여지가 너무 많은 정의인 것은 확실하다.

예를 들어, LLM 프롬프트 하나로만 충분히 처리할 수 있는 작은 프로그램은 에이전트라고 부를 수 없을까? (추가적인 데이터도 필요없고, 환경과 상호작용도 필요없는데) 혹은, 현재의 날씨를 지난 1주일간의 날씨 데이터를 이용해서 예측하는 프로그램은 에이전트라고 부를 수 있을까? (추가적인 데이터에 접근하고 환경과 상호작용하는 인공지능 기반의 프로그램인데) 그리고 그런 작업을 엄청 복잡하고 거대한 컴퓨팅 자원을 써서 1주일간 돌리는 프로그램은 어떨까?

이와 같이 다양한 방식으로 해석할 수 있는 것이 현재 AI 에이전트의 정의이다 보니, 고객이나 다른 개발자와 이야기 할 때 커뮤니케이션이 산으로 갈때가 많다.

그래서 실제 구현을 위한 이야기할 때는 좀 더 구체적인, 기능과 효용에 기반한 정의가 필요하게 된다. 이런 이유로 개인적으로 AI 에이전트를 부를 때는 다음과 같은 정의를 염두해두고 이야기를 하는 편이다.

특정한 작업을 주어진 리소스를 이용하여 완료할 수 있는 인공지능 기반의 프로그램

위의 내용은 다음과 같은 전제를 포함하고 있다.

즉, 현재의 AI 에이전트란:

사용자로 부터 하나의 목적을 가진 작업을 입력으로 받고, 작업을 실행하기 위한 리소스를 할당 받아서 실행되는 인공지능 기반의 프로그램이다. 이 프로그램은 작업완료에 대한 정의를 내부에 가지고며 있으므로 지정된 리소스를 최대한 활용하여 반드시 작업을 완료한다.

현재라고 제한을 걸어둔 이유는 AGI 와 같이 여러개의 서로 다른 복잡한 작업을 처리하는 능력이 현재의 LLM 에게 아직 없다고 보기 때문이다.

프레임워크 선택

위와 같이 에이전트에 대한 정의를 내리고 구현단계에 들어가게 되면, 이제 어떤 프레임워크를 이용하여 개발을 진행할 지 고민하게 된다.

현재 잘 알려진 에이전트 프레임워크로는 다음과 같은 것들이 있다.

모든 프레임워크는 각각의 장단점이 있어서 뭘 써야할 지 고민이 많이 될 것이다. 나도 툴 선택에 있어서 고민을 많이 하고 자료를 찾아봐도 잘 모르겠어서 결국 튜토리얼을 다 해봤다. 그리고 나서도 장단점들이 명확해서 계속 고민을 하게 되었다.

이 때 도움이 되는 것이 위에 설명한 에이전트의 정의였다.

에이전트는 주어진 작업을 완료하기 위해서 스스로 생각하고 동작한다. 에이전트의 내부 구현 자체는 대부분 ReAct6 또는 OpenAI Agent7 기반이며, 둘다 탈출조건(작업 완료) 이 만족되기 전까지 재귀적으로 LLM 을 계속해서 호출하게 된다. 그리고 두 방식 모두 특별한 구현이 없다면 이를 중간에 끊을 수 있는 방법이 딱히 없다. (예를 들면, 스스로 코드를 수정하면서 코드 생성을 하는 에이전트의 경우, LLM 이 특정 에러에 대해서 코드를 고치지 못하고 같은 에러를 계속해서 내면서 반복하는 경우가 있다.)

이런 리소스 제어 의 측면에서 현재 langgraph 외에는 위의 정의를 만족하지 못하기 때문에, 실제 프로젝트를 진행할 때는 langgraph 외에 다른 프레임워크를 선택하기 어려운 것 같다.

state 제어를 하는 기능들을 직접 구현한다면 다른 프레임워크를 사용할 수도 있겠지만, 그렇게 되면 프레임워크를 사용하는 이유가 없어지는 것이기 때문에, 직접 state machine 을 구현하거나 langgraph 를 사용하는 것이 가장 현명한 선택이 될 것이다.

Observability

위에 언급한대로 에이전트는 재귀적으로 동작하게 된다. 이 때문에 에이전트가 어떻게 동작하는지, 어떤 데이터를 사용하고 있는지, 어떤 리소스를 사용하고 있는지 등을 파악하기 위해서는 Observability 가 필요하다.

이를 위한 툴들로 많이 쓰이는 것은 다음과 같다.

langsmith 가 langchain 과 가장 쉽게 호환되는 툴이기 때문에 langsmith 를 사용하는 것이 가장 무난한 선택이지만, 약간의 코드를 추가 한다면 비용측면에서 wandb 가 더 매력적이며, 로컬에서 테스트 하거나 비용효율적인 방식을 원한다면 langfuse 가 더 나은 선택이 될 수도 있다.

배포

에이전트 개발을 했다면 배포를 해야하는데, 이 때 가장 크게 고민되는 부분은 에이전트를 어떤 단위로 패키징해서 배포할 것인가 일 것이다.

가장 일반적인 방식은 에이전트와 툴을 한번에 패키징해서 배포하는 방식이다. 툴들을 에이전트와 통합해서 배포하게 되면 에이전트가 동작하는 환경을 쉽게 구축하고 배포할 수 있다. 다만 툴의 업데이트가 빈번하게 일어나는 경우에는 에이전트를 업데이트 하기 위해서 전체를 다시 배포해야 하는 단점이 있다.

이에 반해 Amazon Bedrock Agent11 의 경우에는 에이전트와 툴을 따로 분리해서 배포하는 방식을 쓰고 있다. 툴은 람다를 통해서 배포되고 에이전트는 람다에 배포된 툴들을 호출하는 방식을 가지고 있기 때문에 툴과 에이전트의 배포를 서로 독립적으로 가져갈 수 있다는 장점이 있다.

전자의 방식은 모노리스 방식에 가깝고, 후자의 방식은 마이크로 서비스 방식과 가깝다고 생각하는데, 실제로 운영할 때 분산 트레이싱을 통한 디버깅의 편의성 측면에서도 비슷한 특성을 가지고 있다.

마치며

Devin12, MultiOn13 과 같은 서비스를 보면서 앞으로 필요한 에이전트를 API 처럼 제공받는 에이전시(또는 OpenAPI 같은 개념으로의 OpenAgent, Meshup) 가 나오지 않을까 하는 생각이 들었다. 이런 서비스가 나오면 개발자들은 에이전트를 직접 개발하지 않고도 쉽게 에이전트를 사용할 수 있게 되어서, 더 많은 사람들이 AI 에이전트를 사용하게 될 것이다.

Langgraph 에 대한 정말 좋은 강의14가 DLAI 에 무료로 올라와 있으니, 에이전트에 관심있는 사람들은 반드시 들어보는 것을 권장한다.