AI 에이전트가 주목을 받은지도 꽤 오랜 시간이 흘러, langchain에서도 다양한 agent 관련 기능들이 추가되었고, langgraph와 같은 전문화된 프레임워크들도 속속 등장하고 있습니다.
하지만 흥미로운 점은, 이러한 발전된 에이전트들의 핵심에는 여전히 단순한 텍스트 입출력을 수행하는 언어모델이 있다는 것입니다. 단순한 텍스트 처리 모델이 어떻게 복잡한 작업들을 수행할 수 있을까요?
이 글에서는 복잡한 프레임워크들을 잠시 제쳐두고, 가장 기본적인 형태의 AI 에이전트를 직접 구현해보겠습니다. langchain의 기본적인 언어모델 호출 기능만을 사용하여, 에이전트의 핵심 동작 원리를 이해하고 실제로 작동하는 간단한 에이전트를 만들어보는 것이 목표입니다.
AI 에이전트의 핵심 원리
AI 에이전트의 가장 기본적인 동작 원리는 다음과 같은 순환 구조를 가집니다:

이는 마치 사람이 문제를 해결하는 과정과 비슷합니다. 우리도 어떤 질문을 받았을 때:
- 먼저 생각을 하고
- 필요한 정보나 도구가 있다면 그것을 활용하며
- 충분한 정보가 모였다면 최종 답변을 제시합니다
이러한 과정을 AI 에이전트에서 구현하기 위해 필요한 핵심 요소들을 하나씩 살펴보겠습니다.
0. 요구사항 설치
테스트에서 사용한 실행 환경은 python 3.10이며, 아래와 같은 requirements.txt를 가집니다.

1. 도구(Tool) 구현하기
AI 에이전트가 실제로 무언가를 ‘할 수 있으려면’ 도구가 필요합니다.
우리의 에이전트는 다음과 같은 기본적인 도구들을 가지고 있습니다:
- tool_run_cmd: 현재 실행 환경에서 시스템 명령어를 실행
- tool_search_wikipedia: 한국어 위키피디아에서 검색
- tool_eval_python_code: eval()을 사용하여 단순한 파이선 코드 실행
- tool_sqlite_query: sqlite3을 사용한 db 이용

2. 프롬프트 엔지니어링
AI 에이전트가 도구를 적절히 사용하도록 만들기 위해서는, 명확한 지침이 담긴 프롬프트가 필요합니다.
다음은 우리가 사용할 프롬프트입니다:

특히 주목할 부분은 프롬프트가 다음과 같은 구조화된 출력 형식을 정의한다는 점입니다:
- THINK: 현재 상황에 대한 분석
- TOOL: 사용할 도구 정보 (JSON 형식)
- TOOL_OUTPUT: 도구 실행 결과
- ANSWER: 최종 답변
언어모델이 생성하는 것은 텍스트이지만, 그 형식을 지정하여 파싱하는 것으로 언어모델과 프로그램 간의 소통이 가능하게 됩니다.
3. 에이전트 파이프라인 구현
아래는 에이전트의 동작을 구현한 코드입니다:
[Hands-On]
위 코드 중 에이전트의 핵심 동작은 다음과 같은 순환 구조로 구현됩니다:

이 구조는 언어모델이 ANSWER를 제시할 때까지 계속해서 생각하고 도구를 실행하는 과정을 반복합니다.

이로써 agent의 기초적인 형태가 완료되었습니다. 이를 테스트하기 위한 간단한 웹 인터페이스를 Gradio로 구현하였습니다.
웹 인터페이스 구현
UI 컴포넌트는 단 3개, gr.Chatbot, gr.Textbox, gr.ClearButton 으로 이루어져 있고, 텍스트박스에서 질문 입력 후 Submit(엔터)하면 agent_pipeline을 호출하여 답변을 생성합니다.


이제 테스트 준비가 완료되었습니다. 질문을 입력하여 어떻게 동작하는지 몇가지 시나리오를 테스트해보겠습니다.
시나리오1. DB
DB 테이블을 생성하여 가상의 학생 10명 에 대한 성적을 집어 넣고, 그 테이블을 조회하여 데이터를 분석하는 예시입니다.
에이전트는 아래와 같은 순서로 동작했습니다. 필요한 동작을 수행할 뿐 아니라, 실패한 작업에 대한 대안 작업도 수행하는 것을 볼 수 있습니다.
- 학생 10명의 점수를 랜덤 생성하고, DB에 테이블을 넣어달라는 요청에 대해:
- 테이블이 이미 있을 것을 염려하여, students라는 테이블을 삭제하고 생성하는 쿼리문을 한 쿼리 실행으로 하려고 시도함
⇒ 한 쿼리 실행에 한 쿼리만 사용 가능하다는 에러를 받음 - 에러를 확인하여 우선 삭제를 진행함
- 그 다음 테이블 생성을 시도함
- 학생 10명의 이름과 랜덤 점수를 넣는 쿼리 실행
- select문으로 데이터가 들어갔는지 확인
- [최종 답변] 출력된 값을 사용하여 markdown으로 테이블을 출력하여 답변
- 테이블이 이미 있을 것을 염려하여, students라는 테이블을 삭제하고 생성하는 쿼리문을 한 쿼리 실행으로 하려고 시도함
- 평균 점수가 높은 학생과 과목을 각각 찾아달라는 요청에 대해:
- 쿼리문으로 평균 점수가 높은 학생을 찾음
- 그 다음 쿼리문으로 평균 점수가 높은 과목을 찾음
- [최종 답변] 앞의 두 결과값을 사용하여 사용자에게 답변함

시나리오2. GIT
Git repository에 있는 branch를 확인하고, branch별로 gradle 빌드하여 생성된 jar 파일을 usb에 복사하도록 지시하는 시나리오입니다.
- 특정 깃 저장소 폴더에 어떤 브랜치가 있는지 확인
- [최종 답변]
CD
명령어로 해당 위치로 가서GIT
명령어로 branch를 확인하여 답변함
- [최종 답변]
- 브랜치별로 jar를 빌드하여 E드라이브에 복사하도록 요청함.
- 해당 저장소 폴더를 이동하고 main 브랜치를 체크아웃하여
./gradlew bootJar
시도
⇒ 에러 출력문을 확인하여 명령어가 실행 환경에 맞지 않은 것을 확인함 gradlew.bat bootJar
라고 윈도우 환경용 명령어를 수행하여 빌드 완료- 빌드된 jar 파일의 이름에 브랜치명을 붙여서 E드라이브로 복사
- dev 브랜치를 체크아웃
- 2와 동일 명령어로 빌드
- 빌드된 jar 파일의 이름에 브랜치명을 붙여서 E드라이브로 복사
- [최종 답변] 빌드 및 복사가 완료되었고 어떤 경로에 저장되었는지 정리하여 알려줌
- 해당 저장소 폴더를 이동하고 main 브랜치를 체크아웃하여


마무리
지금까지 살펴본 것처럼, AI 에이전트의 기본 원리는 생각보다 단순하지만, 실제로도 상당히 유용한 작업들을 수행할 수 있습니다. 앞서 보았던 테스트 케이스들 – SQL을 활용한 DB 데이터 분석이나 Git 저장소 작업 등 – 에서 확인할 수 있듯이, 언어모델의 추론 능력과 잘 정의된 도구들을 결합하면 실무에서도 충분히 활용 가능한 에이전트를 만들 수 있습니다.
여기서 구현한 에이전트는 매우 기초적인 형태이지만, 이를 기반으로 더 복잡한 기능들을 추가할 수 있습니다:
- 더 많은 종류의 도구 추가
- 도구 실행 결과의 캐싱
- 병렬 도구 실행
- 에러 처리 개선 등
실제 프로덕션 환경에서는 이미 잘 구현된 프레임워크를 활용하는 것이 효율적입니다. langchain과 langgraph에는 이미 다양한 에이전트 기능들이 구현되어 있으며, 여러가지 도구들이 제공되고 있어 훨씬 더 고도화된 에이전트를 쉽게 구현할 수 있습니다.
특히 주목할 만한 것은, 앤트로픽이 작년 11월에 공개한 MCP(Model Context Protocol)입니다. 이는 언어 모델이 도구를 사용할 때 특정 프레임워크에 종속되지 않고도 일관된 방식으로 상호작용할 수 있게 해주는 프로토콜입니다. 마치 USB-C 포트가 다양한 기기들을 표준화된 방식으로 연결하듯이, MCP는 AI 모델과 도구들 사이의 표준화된 연결 방식을 제공합니다. 이를 통해 langchain과 같은 프레임워크에 의존하지 않고도 AI 에이전트가 도구를 활용할 수 있게 되어, 향후 AI 에이전트 개발이 더욱 유연하고 확장 가능한 방향으로 발전할 것으로 기대됩니다.