AI개발을 하려면 석사 학위, 개발 스킬, AI 발전의 타임라인과 원리에 대해 이해가 필수적이라고 여겨지던 시절이 있었다. 그 때와는 다르게, 지금(2025년 9월)은 많은 회사에서 다양한 개발 직무에 있는 사람들이 AI를 이용한 서비스 개발이나, 자사 혹은 타사의 서비스에 대한 MCP등을 많이 제작하고 사용하는 시대가 왔다.

 

Deep Research를 통해 보다 폭넓고 섬세한 의사결정을 통해 기술 도입의 결정을 처리할수도 있고, 학습 모드를 통해 내가 모르는, 또는 내가 몰랐던 부분에서의 학습도 체계적으로 진행하며 프로젝트를 진행할 수도 있고, Claude-Code같은 LLM 클라이언트를 IDE에 붙여 사용하거나 Cursor같이 IDE를 활용하는 방안도 있고, 너무나 커진 파라미터로 LLM을 다룰 때에 있어서의 섬세한 스킬의 필요성이 희석되었기 때문이다.

 

이 글은 위 조건이 없었던 작년을 기준으로 작성하고 있다.

시작

시작은 작년 9월, 여느 회사와 같이 '우리도 AI를 이용해서 뭘 좀 해볼 수 없을까?'와 같은 대표의 말로부터 첫 삽을 펐다. 그리고 지원자는 나 하나였다. 다른 사람들은 AI개발에 별로 관심이 없거나 두려워했기 때문이었다.

 

지원 사유는 크게 두가지로 나눌 수 있다.
하나는 회사에 입사해 솔루션을 사용해보면서 여기저기 이스터에그처럼 숨어있는 도큐먼트들을 찾아보는게 너무나 귀찮은 일이었고, 전래동화처럼 내려오던 경험에 근거한 솔루션 사용 꿀팁들을 바쁜 사람들에게 일일히 물어봐야 했었는데 INFP로서 그들에게 내가 안고 있는 문제에 대해 물어보기가 껄끄러웠다. 그래서 언젠가는 개인적으로 회사 도큐먼트를 가져와서 사용법을 알려주는 '비서'를 하나 만들고 싶었는데, 마침 지원자가 아무도 없길래 한다고 손을 들었다.

 

다른 하나는 성과였다. 사내 여러 조직에서 대표가 AI개발을 통해 하고 싶어하는 것이 많다는 것을 너무 잘 알았고, 프로젝트를 하느라 바쁜 와중에도 조금씩 '나 AI 조금 압니다'라는 이야기나 글이 회사 커뮤니티를 통해 조금씩 올라오면서 AI개발에 대한 파이를 해당 조직에서 가져가려고 하는게 보였다. 나는 중앙 연구조직에서 당연히 이를 맡아야 한다고 느꼈는데, 위에 서술했듯 지원자도 없었고, 이걸 이용해 개인/조직성과를 정말 많이 가져갈수 있을거라고 판단했고, R&D가 아닌 다른 조직에서 사이드로 AI서비스를 개발하는 것은 자존심이 매우 상하는 일이라고 생각했다.

 

그렇게 나는 도메인 아키텍트에 너무 관심이 있던 웹 백엔드 엔지니어에서 AI 엔지니어로 이동하게 되었다.

첫 번째 관문 : 자바냐, 파이썬이냐

지금은 JVM이든, 파이썬이든 그 위에서 AI 서비스 개발이나 ML 서빙을 충분히 할 수 있고, 굳이 한 언어를 고집해서 할 필요는 없다고 생각한다. 또는 어떤 언어나 프레임워크를 모르더라도 LLM 클라이언트를 IDE와 연계해 plan - execute의 순서로 쉽고 빠르게 프로토타입을 뚝딱 만들어낼 수 있다.
그러나 당시에는 CTO님와 최대한 빠른 의사결정을 통해 스택을 고르고, 당장 개발에 집중해야 했다.

 

먼저 언어를 골라야 했는데, 개발자 입장에서야 당연히 파이썬을 이용해 개발하면 레퍼런스도 많고, 쉽고, 편리하지만(특히 신입 개발자 입장에서 - 정말 깊은 소스 내부의 원리를 모른다고 생각했을 때), 스프링을 메인 프레임워크로 사용하는 회사 입장에서는 그렇기 힘든 경우가 있다.

 

만약 회사에서 프론트엔드 개발에 그동안 사용하던 자바스크립트를 계속 가지고 갈지, 또는 타입스크립트로의 전환을 시도할지 고민의 기로에 서 있다고 해 보자.
열정이 넘치는 개발자라면 당연히 타입스크립트를 선택하지 않을 이유가 없겠지만, 회사의 입장에서는 다르다.
먼저 기존 인원들이 기존 소스코드를 타입스크립트로 마이그레이션했을때 유지보수 또는 신규 건에 대해 개발을 할 수 있게끔 교육 비용이 들어가고, 신규 인원 채용에도 TS를 사용할 수 있는 인력에 한정해서 채용해야 한다.
또한, 만약 타입스크립트 사용에 이슈가 있거나, 더 좋은 결정안이 있어서 해당 결정을 롤백해야 한다면 그동안에 사용된 리소스는 실로 어마어마할 것이다.

 

물론 회사 내에서의 내 위치를 고려할 때, 내가 고민하거나 담당해야 하는 일은 아니라고 생각했지만 내가 작성한 소스코드도 회사 자산의 일부이고 추후 같이 일할 팀원을 구할 때에도 지금 하는 결정은 매우 크게 작용할 것이라 생각해 최선을 다해 여러 시나리오를 고려했다.

 

많은 고민과 회의 끝에 위의 조건을 차치하고도 파이썬을 선택했는데, 사유는 다음과 같다.

안정성과 기술 파이 : 'Time-to-Market'의 압도적 우위

작년 9월 기준으로 Spring-AI 라이브러리에는 하루에 5건 이상의 이슈가 올라오고 있는데에 반해, 파이썬은 든든한 국밥같은 Langchain과 LlamaIndex, HF Transformers등을 업고 AI개발의 표준 라이브러리 자리를 차지하고 있었다. 나는 파인튜닝보다는 RAG레벨에서 더 효용을 발휘하는 서비스를 만들기 위해서 LangChain을 사용할 수 있는 장점이 커서 파이썬으로 가고자 한 것도 있지만, 파인튜닝까지 해야 했다면 Pytorch같은 프레임워크와의 호환도 고려해야 해서 파이썬을 사용하고 싶은 생각이 더 컸을 것이다.
또한 회사의 사정 상 오류가 덜한 프로토타입을 빠르게 출시하고 피드백해야 했기에, 개발마다 코드 수정 > 컴파일 > 런타임을 거쳐야 했던 자바보다는 인터프리터 언어의 특성 상 빠르게 테스트를 실행하고, 결과를 얻고, 수정할 수 있는 파이썬을 사용하는 것이 맞다고 판단했다.
결론적으로 이 선택은 반은 맞고 반은 틀리게 되었다. 사정이 생겨 AI서비스에서 사내 다른 서비스의 피처를 개발하느라 3개월정도 자리를 비웠었는데, 'RAG'가 대세였던 서비스 개발 시장이 돌아와보니 어느새 'Agent'를 지나 'MCP'가 대세가 되려고 하고 있었다. 따라서 빠르게 동향을 훑고 개발에 들어가야 했었기에 정말 많은 테스트와 시행착오를 거쳐 더 빠르게 프로토타입을 내야 했어서 자바로 개발하는것보다 훨씬 빠르게 테스트를 해서 제품을 낼 수 있었다. 그러나 동시에 JVM 위에서 동작하는 여러 라이브러리와 커넥터도 출시되면서 '무조건 파이썬을 사용해야 한다'라는 선택지에 대한 힘도 많이 줄어들었다. 실제로 KSUG(한국 스프링 사용자 모임)등의 컨퍼런스에도 참여해보니, 실력있는 자바/스프링 진영의 개발자분들이 좋은 레퍼런스를 많이 개발해 주고 있었고, 랭체인 프레임워크와 자바 소스코드 기반의 프로젝트도 호환성이 많이 좋아졌다.(물론 아직 Langchain에서 제공하는 Java를 위한 SDK는 존재하지 않긴 하지만)

아키텍처: 의도적인 분리를 통한 안정성

챗봇 모듈 하나 때문에 당장 MSA로 전환해야 하는 것은 아니지만 파이썬이라는 다른 기술 스택을 선택하는 것 자체가 의도적으로 서비스의 경계를 만드는 행위였다. 만약 Java로 개발했다면, 높은 확률로 기존의 모놀리식 프로젝트의 일부로 편입되었을 것이라고 생각했다. 당장은 편할지 몰라도, 향후 챗봇 기능이 고도화될수록 기존 서비스와의 결합도(Coupling)가 높아져 분리가 거의 불가능해지는 기술적 부채를 낳게 된다. 챗봇 모듈은 ITSM을 제공하는 회사 솔루션 특성상 필수 설치가 아니라 옵셔널하기 때문에, 급하게 떼어낼 수 없어 모듈단으로 분리를 해야 하는데, 이렇게 떼어내게 된다면 굳이 자바를 쓰면서 개발해야 할 이유가 없어진다.

 

특히 챗봇은 LLM API 호출로 인한 긴 대기 시간과 간헐적인 대규모 연산(Embedding 등)이라는 독특한 부하 특성을 가진다. 파이썬 기반의 별도 서비스로 분리함으로써, 챗봇의 부하가 회사의 핵심 서비스 안정성에 영향을 미치는 것을 원천적으로 차단할 수 있다. 이는 향후 회사가 클라우드 네이티브 환경으로 본격적으로 전환할 때, 각 서비스를 독립적으로 확장하고 관리할 수 있는 바탕이 된다.(현재도 클라우드네이티브로의 전환이나 온프레미스 - 클라우드 2개 버전을 독립적으로 개발할 계획을 가지고 있다.)

조직: 미래를 위한 기술 자산과 전문성

파이썬 도입은 위에서 말했듯 당장의 유지보수 비용과 채용의 어려움을 동반하는 것이 사실이다. 그러나 회사가 성장함에 따라 모든 것을 아는 제너럴리스트(Generalist) 개발자만으로는 한계에 부딪힌다. 특정 도메인에 대한 깊은 이해를 가진 스페셜리스트(Specialist)가 반드시 필요해지는 순간이 오고, 현재 회사에서 요구하는 역량도 사내의 전체 코드를 이해하고, 피처 중 사람이 빠진 곳에 당장 투입되는 '땜빵'을 할 수 있는 사람보다, 기획과 개발에 동시에 참여하며 조금 더 전문성과 책임감을 가지는 프로덕트 엔지니어적 역량이기 때문에, '파이썬을 사용하는 개발자'를 뽑아야 한다는 위험성에 초점을 맞추는 것이 아니라, AI 서비스 개발을 집중해서 개발할 수 있는 사람을 뽑아야 하는게 맞다고 생각한다.

 

 

다음 글에서는 조금 더 깊이 들어가서, 아키텍처나 사용했던 라이브러리의 변화에 대해서 얘기하려고 한다.

'AI > Python' 카테고리의 다른 글

매직 명령어는 왜 사용할까?  (0) 2025.01.10

오늘 참여하고 있는 랭체인 글로벌 튜토리얼을 제작하는 프로젝트에서 일괄적으로

!pip install package

구문을 아래와 같이 바꾸었다.

%pip install package

!pip 명령어가 돌아가지 않는것도 아니었는데, 왜 그렇게 바꿔야 했을까?

!pip install package
%pip install package 

둘의 차이는 무엇일까?
바로 (!)는 시스템 명령어, (%)는 매직 명령어라는 것이다.
OS에서 실행하는 시스템 명령어와는 달리, Jupyter Notebook이나 IPython에서 제공하는 매직 명령어는 다음 부분에서 시스템 명령어와 차이를 보인다.

  시스템 명령어(!) 매직 명령어(%)
역할 시스템 쉘 명령어 실행 IPython 및 Jupyter에서 제공하는 명령어
문법 !<쉘 명령어> %<매직 명령어>(라인 단위) 또는 %%<매직 명령어>(셀 단위)
예시 !ls %time
Python 변수 지원 Python 변수 삽입 가능 {} 대부분 직접 사용 가능
실행 환경 OS의 shell Jupyter Notebook / IPython

시스템 명령어가 있는데 매직 명령어는 왜 쓸까?

!pip install package를 ipynb파일의 code 셀에서 돌려 보면, 잘 돌아가는것을 알 수 있다. 그런데도 왜 매직 명령어를 쓰는 걸까? 이를 이해하기 위해서는, Jupyter Notebook의 동작 원리부터 이해해야 한다.

Jupyter Notebook의 동작 원리


주피터 노트북은 위와 같은 구조를 가지고 있다. (참조 : https://sawyer-jo.tistory.com/72)
주피터 노트북이 설치된 웹 브라우저(jupyter lab)나, VSC에서 제공하는 jupyter notebook extension을 설치하면, ipynb 파일 내부에 코드를 실행할 수 있는 셀이 제공된다.
이 셀을 위의 사진의 클라이언트(Client)라고 이해하면 쉽다. 이 셀에서 코드를 작성하고 run을 하면, 웹에서는 제공되는 앱 서버, 로컬에서는 로컬 앱 서버에서 '커널'이라는 핵심 컴포넌트에서 코드를 실행하게 된다.

커널

커널은 위에서 설명했다시피, 실제적으로 코드를 실행시키는 파이썬 인터프리터(엔진) 위에 존재한다. 사용자가 작성한 코드를 받아서 파이썬 인터프리터에 코드를 가져다 주고, 그 결과를 반환받아 Jupyter Notebook이라는 사용자 인터페이스에 포매팅하여 제공한다. 다음의 비유로 이해하면 쉽다.
Python Restaruant

  • 손님 : ipynb 셀
  • 웨이터 : 커널
  • 요리사 : 파이썬 인터프리터
  • 요리사마다 다른 주방 : 가상 환경
    Jupyter에서는 프로그램 언어별 여러가지 커널을 지원하지만, 가장 많이 사용되는 커널은 Python용 ipykernel이다.
    통합 환경에서 커널을 설치하였다면 다음과 같은 명령어로 확인할 수 있다.
    pip show ipykernel

그리고, python이 여러 개 설치되어 있거나, 가상 환경을 이용 중이라면, 프로젝트 내부에서 명령어로 확인할 수 있다.

PS C:\Users\User\Documents\langchain-kr> pip show ipykernel

Name: ipykernel
Version: 6.29.5
Summary: IPython Kernel for Jupyter
Home-page: https://ipython.org
Author:
Author-email: IPython Development Team <ipython-dev@scipy.org>
License: BSD 3-Clause License

...

환경 통합

따라서, 프로젝트마다 다른 커널을 사용할 수 있기 때문에 패키지의 분리가 중요하다. pip install package는 위의 예를 기반으로 하면, 요리사가 새로운 재료를 시장에서 사 오는 행위라고 생각하면 된다.

%pip install을 하는 경우, 현재 Jupyter Notebook의 kernel의 가상 환경 위에 패키지를 설치한다. 각각의 요리사가 레스토랑 규정에 따라 재료를 요청하고, 그 재료를 자신의 주방에 넣어놓고 쓰는 행위라고 볼 수 있다. 매직 명령어는 현재 활성화된 Jupyter kernel의 환경에만 패키지를 설치하는 것을 원칙으로 하기 때문이다. 커널이 가상 환경을 사용 중이라면, 가상 환경에서의 설치를 보장한다.

반면 !pip install은 기본 환경에 설치할 수 있어 의도하지 않은 위치에 패키지가 설치될 수 있다.
요리사가 레스토랑 규정을 무시하고 시장에서 재료를 사 와서 공용 주방이나 레스토랑이 대충 관리하는 주방(전역 python 환경 또는 기본 설정된 pip와 연결된 환경)에 설치하는 행위라고 볼 수 있다.

!pip install은 잘못된 방식은 아니다. 그러나 Jupyter 커널이 가상 환경을 사용중인 경우, !pip install은 가상 환경이 아닌 시스템 Python 환경에 패키지를 설치해버릴 수도 있기 때문에, 잘못하다가 패키지가 꼬여버릴 수가 있어 %pip install을 권장한다.
패키지가 충돌하거나, Jupyter kernel이 패키지를 찾지 못하면 그 때부터는 문제가 더 어려워지기 때문이다.

추가 기능성

매직 명령어는 IPython 커널에 의해 해석되기 때문에, 추가 기능을 제공한다.

%lsmagic

으로 다양한 매직 명령어를 확인할 수 있다.
jupyter lab 또는 본인 ipynb 파일에서 %lsmagic 명령어로 확인해보자.

+ Recent posts