LLMOps 04
LLMOps: 반복되는 루프 속에서 시스템을 통제하고 개선하기
LLMOps를 한 번 배포하면 끝나는 체크리스트로 오해하기 쉽다.
근거 · 교안 p12-p14
1장: 루나: LLMOps는 왜 단순 체크리스트가 아닐까요?
솔라는 거실 테이블에 노트북을 펼쳐놓고 만족스러운 표정으로 중얼거렸다. 화면에는 굵은 글씨로 다섯 단어가 나열되어 있었다.
Design, Run, Trace, Evaluate, Improve
“됐어. 이제 LLMOps가 뭔지 알겠어.”
솔라는 의자 등받이에 몸을 기댔다. “그러니까 LLM 에이전트 시스템을 만들 때, 이 5단계 순서대로 쭉 진행해서 배포하면 끝나는 거네. 신제품 출시 계획서처럼. 설계하고, 실행하고, 잘 돌아가는지 추적하고, 평가해서 보고서 내고, 마지막으로 개선점 정리하면 프로젝트 종료! 간단하잖아.”
마침 부엌에서 차를 들고 나온 루나가 솔라의 혼잣말을 들었다. 루나는 테이블 위에 찻잔을 조용히 내려놓고 솔라의 노트북 화면을 잠시 들여다보았다.
“그럼 솔라, 그 프로젝트가 ‘종료’된 지 한 달쯤 지났다고 해보자.”
루나의 차분한 목소리에 솔라는 고개를 들었다.
“우리가 만들었던 ‘오늘의 기분 시 추천 봇’ 기억나? 사용자가 ‘활기찬 하루’라고 입력하면 그에 맞는 시를 추천해 주는 시스템이었지. 그런데 어느 날부터 사용자가 뭘 입력하든 상관없이 무조건 슬픈 시만 추천하기 시작한 거야. ‘종료’된 프로젝트인데, 이제 어떡할까?”
“어?”
솔라는 순간 말문이 막혔다. 예상치 못한 질문이었다. “그야… 버그니까 고쳐야지. 음, 개발팀에 다시 요청해서….” 솔라는 자신의 논리가 삐걱거리는 것을 느꼈다. 이미 완료된 체크리스트에는 ‘한 달 뒤 갑자기 시스템이 이상해졌을 때’ 같은 항목은 없었다. 어디서부터 손을 대야 할지 막막했다. “다시… 설계부터 해야 하나? 아니면….”
솔라는 자기가 썼던 다섯 단어를 손가락으로 짚어보았다. Design, Run, Trace, Evaluate, Improve. 모든 단계를 이미 다 거쳐서 ‘완료’했는데, 이 상황은 어디에 해당할까? 마치 잘 지어진 건물이 한 달 만에 한쪽으로 기울기 시작했는데, 설계도와 시공 감리 보고서는 모두 완벽하다고 말하는 것과 같았다.
“솔라가 막막함을 느끼는 지점이 중요해.” 루나가 말했다. “솔라는 지금 LLM 시스템을 한 번 만들면 변하지 않는 ‘정체성’을 가진 존재로 본 것 같아. 시 추천 봇의 정체성은 ‘기분에 맞는 시를 추천하는 것’이고, 그 정체성을 한 번 부여하면 끝이라고 생각한 거지.”
루나는 찻잔 옆에 놓여 있던 작은 화분을 가리켰다. “저 화초를 처음 집에 들여올 때를 생각해봐. 햇빛이 잘 드는 곳에 두고, 물 주는 법을 배우고, 영양제를 처음 한 번 줬어. 그게 우리가 한 ‘설계’와 ‘실행’이야. 그럼 이제 끝일까? 아니지. 우리는 매일 화초의 상태를 살피고(Trace), 잎이 시들거나 색이 변하면(Evaluate), 물 주는 주기를 바꾸거나 다른 곳으로 옮겨주잖아(Improve). 저 화초의 ‘건강한 상태’는 한 번의 행동으로 완성되는 게 아니라, 계속되는 보살핌 속에서 유지되는 거야.”
솔라의 눈이 동그래졌다. 체크리스트와 화초 키우기. 완전히 다른 그림이었다.
“아….” 솔라는 나지막이 탄성을 내뱉었다. “LLMOps는 시스템의 ‘정체성’을 한 번 정해주는 설계도가 아니라, 살아있는 식물처럼 계속 변하는 시스템의 ‘행동’을 관리하는 방법론이구나. 시 추천 봇이 갑자기 슬픈 시만 뱉어내는 건, 정체성이 바뀐 게 아니라 외부 환경이나 데이터 변화 때문에 ‘행동’이 달라진 거고.”
솔라는 다시 노트북 화면을 보았다. ‘LLMOps는 Agent 시스템을 지속적으로 개선 가능한 구조로 만드는 것’이라는, 아까는 그냥 스쳐 지나갔던 문장이 눈에 들어왔다. 전에는 이 문장이 ‘개선할 수 있는 잠재력을 가진 시스템을 만든다’는 뜻으로 들렸다. 하지만 이제는 다르게 읽혔다.
“‘지속적으로 개선 가능한 구조로 만든다’는 건… 개선이라는 ‘행동’ 자체가 시스템 운영의 일부가 되는 구조를 뜻하는 거였어. 배포하고 끝나는 게 아니라, 문제가 생기거나 더 좋게 만들고 싶을 때 언제든 다시 손볼 수 있는 운영 체계를 갖추는 것. 그게 LLMOps의 본질이었네.”
솔라는 방금 전의 만족감과는 다른 종류의 명료함을 느꼈다. 흩어져 있던 점들이 하나의 선으로 이어지는 기분이었다. 이제 LLMOps는 일회성 프로젝트 계획서가 아니라, 예기치 못한 문제에 대응하고 시스템을 더 나은 방향으로 이끌기 위한 운영 지침으로 보였다. ‘종료’가 없는, 계속되는 관리의 과정.
“맞아.” 루나가 조용히 긍정했다. “시 추천 봇이 이상하게 행동할 때, 우리는 당황하지 않고 이 운영 체계를 다시 가동하는 거지.”
솔라는 고개를 끄덕이며 다섯 단어를 다시 한번 손가락으로 따라 그렸다. 이제 이 단어들은 더 이상 끝을 향해 달려가는 화살표가 아니라, 서로 맞물려 돌아가는 톱니바퀴처럼 느껴졌다.
“알겠어, 언니. 이게 왜 반복되어야 하는지는 이제 알겠어. 그런데 한 가지 궁금한 게 생겼어.” 솔라가 루나를 보며 물었다.
“왜 꼭 이 순서여야 해? 문제가 생겼으면 바로 ‘개선(Improve)‘하면 되는 거 아냐? 왜 굳이 다시 ‘설계(Design)‘부터 시작하는 것처럼 보이는 이 순서를 따라야 하는 거지?“
2장: 루나: 5단계는 어떻게 서로 연결되어 있을까요?
솔라는 거실 화이트보드 앞에 서서 보드마카 뚜껑을 열었다. 지난번 언니와의 대화에서 얻은 깨달음은 명확했지만, 여전히 풀리지 않는 매듭이 남아 있었다. 그녀는 화이트보드 한쪽에 ‘시 추천 봇 문제 발생: 슬픈 시만 추천함’이라고 적었다. 그리고 곧장 화살표를 길게 그어 ‘개선 (Improve)’이라는 단어로 연결했다.
“이거면 되잖아.”
솔라의 그림은 단순했다. 문제가 생겼으니, 고친다. 그녀는 자신의 논리가 깔끔하다고 생각했다. ‘지속적인 관리’라는 개념은 이해했다. 하지만 굳이 복잡한 절차를 다시 밟을 필요가 있을까? 문제가 명확한데, 진단은 건너뛰고 바로 처방으로 넘어가면 안 되는 걸까? 솔라는 자신이 그린 직선 화살표를 보며 고개를 끄덕였다. 가장 빠르고 효율적인 길처럼 보였다.
루나가 소파에 앉아 조용히 그 모습을 지켜보고 있었다. 솔라의 질문은 이미 지난 대화의 마지막에 던져진 것이었다. “왜 꼭 이 순서여야 해?” 루나는 솔라가 스스로 그 질문의 함정을 시각화하도록 잠시 내버려 두었다.
“좋아, 솔라. 그럼 거기서부터 시작해 보자.” 루나가 입을 열었다. “솔라가 그린 그림대로 ‘개선’을 하려고 해. 뭘 개선할 거지?”
“응? 그야 당연히 슬픈 시만 나오는 문제를 고쳐야지. 활기찬 시도 나오고, 다른 시도 나오게.” 솔라는 자신 있게 대답했다.
“어떻게?”
“어떻게라니…?” 솔라는 순간 말문이 막혔다. “코드를 수정해서…?”
“어떤 코드를? 추천 로직이 문제일까? 아니면 모델이 사용하는 데이터베이스 주소가 잘못된 걸까? 혹시 특정 사용자에게만 발생하는 문제일 수도 있고, 특정 시간대에만 API 호출이 실패하는 걸 수도 있잖아. ‘개선’이라는 행동을 하려면, 무엇을, 왜, 어떻게 바꿔야 하는지에 대한 정보가 필요하지 않을까?”
솔라는 마카를 든 채 멈칫했다. ‘고친다’는 말은 쉬웠지만, 막상 ‘무엇을’ 고칠 거냐는 질문 앞에서는 막막했다. 마치 의사에게 “배가 아파요”라고 했더니, 진찰도 없이 “그럼 약을 드세요”라고 하는 것과 같았다. 무슨 약을? 왜? 진단이 빠져 있었다. 솔라는 자신이 그린 화살표가 사실은 텅 비어있다는 것을 깨달았다.
루나가 자리에서 일어나 솔라 옆으로 다가왔다. 그리고는 솔라가 그린 화살표를 조용히 지웠다.
“우리가 길을 잃지 않도록, 각 단계가 다음 단계에게 무엇을 넘겨주는지 따라가 보자.”
루나는 화이트보드 맨 왼쪽에 ‘설계 (Design)’라고 적었다. “첫 단계는 청사진이야. ‘사용자의 감정 키워드를 받으면, 그에 맞는 분위기의 시를 추천한다’는 우리 시스템의 목표지. 이건 우리가 만들 시스템의 ‘의도’야.”
루나는 화살표를 그려 ‘실행 (Run)’이라고 썼다. “이 설계도를 바탕으로 시스템을 만들고 세상에 내보냈어. 이제 시스템은 실제로 작동하며 사용자와 상호작용하기 시작하지. 이 단계의 결과물은 ‘작동하는 시스템’ 그 자체야.”
솔라는 잠자코 지켜봤다. 아직은 지난번에 생각했던 것과 크게 다르지 않았다.
“자, 이제 문제가 발생했어.” 루나는 다음 화살표를 그리고 ‘관측 (Trace)’이라고 적었다. “시스템이 이상하게 작동해. 슬픈 시만 계속 추천하지. 여기서 우리는 시스템의 모든 행동을 기록한 ‘로그’를 들여다봐. ‘사용자 A가 ‘활기찬’이라고 입력했을 때, 시스템이 ‘슬픈 시 데이터베이스’에만 접근했고, 그 결과 ‘이별 시’를 반환했다’는 구체적인 ‘사실’을 확보하는 거야. 이 단계의 결과물은 ‘시스템의 실제 행동 기록’이야.”
솔라의 눈이 약간 커졌다. 그냥 ‘문제가 생겼다’가 아니라, 문제의 구체적인 현상이 데이터로 포착되는 단계였다.
루나는 다시 화살표를 그리고 ‘평가 (Evaluate)’라고 썼다. “기록을 얻었으니 이제 분석할 차례야. 왜 시스템은 ‘슬픈 시 데이터베이스’에만 접근했을까? 평가 단계에서는 이 ‘왜?’라는 질문에 답을 하는 거야. 여러 기록을 비교 분석한 결과, ‘최근 데이터베이스 업데이트 과정에서 전체 시 목록 대신 슬픈 시 목록 주소만 남기고 나머지는 누락된 것’이라는 원인을 찾아냈어. 이것이 바로 ‘진단 결과’지.”
“아…!”
솔라는 나지막한 탄성을 터뜨렸다. 비로소 연결고리가 보였다. ‘관측’이 CT 촬영이라면, ‘평가’는 영상 판독이었다.
루나는 마지막으로 화살표를 그려 솔라가 처음에 적었던 ‘개선 (Improve)’으로 연결했다. “이제 우리는 무엇을 해야 할지 정확히 알아. ‘누락된 데이터베이스 주소를 복원한다’는 명확한 ‘처방’이 나온 거지. 솔라가 아까 하려던 ‘개선’은 바로 이 마지막 단계였지만, 앞선 관측과 평가 없이는 뭘 해야 할지 알 수 없는 막연한 구호에 불과했던 거야.”
루나는 다섯 단어를 가리켰다.
Design → Run → Trace → Evaluate → Improve
이제 이 화살표들은 더 이상 분리된 작업 목록이 아니었다. 설계의 ‘의도’를 바탕으로 시스템이 ‘실행’되고, 실행된 결과는 ‘관측’을 통해 데이터가 되며, 이 데이터는 ‘평가’를 통해 정보가 되고, 이 정보는 ‘개선’을 위한 명확한 행동 지침이 되었다. 각 단계의 출력이 다음 단계의 필수적인 입력이 되는, 끊어질 수 없는 흐름이었다.
“각 단계는 독립적인 섬이 아니었구나. 앞 단계가 만들어준 흙을 밟고서야 다음 단계로 나아갈 수 있는 징검다리였어.” 솔라가 중얼거렸다. “문제가 생겼을 때 바로 ‘개선’으로 점프하는 건, 진단도 없이 수술실로 들어가는 것과 같았던 거네.”
솔라는 만족스러운 표정으로 새로 그려진 흐름도를 바라보았다. 이제 LLMOps의 5단계는 합리적이고 필연적인 순서로 느껴졌다. 혼란스러웠던 머릿속이 깔끔하게 정돈되는 기분이었다.
루나가 조용히 마카를 들어, ‘Improve’에서 다시 ‘Design’과 ‘Run’ 쪽으로 희미한 점선 화살표를 그렸다.
솔라가 그 점선을 보고 고개를 갸웃했다.
“언니, 그런데 왜 화살표가 다시 앞으로 돌아가? 이제 문제는 고쳤잖아. 여기서 끝나면 되는 거 아니야? 왜 이 순환을 또 반복해야 하는 거지?“
3장: 루나: 왜 LLMOps는 끊임없이 반복되어야 할까요?
솔라는 화이트보드 앞에 서서 잠시 망설였다. 언니가 방금 그린, ‘Improve’에서 ‘Design’으로 되돌아가는 희미한 점선 화살표. 그 화살표가 모든 것을 다시 원점으로 돌리는 것 같아 마음에 들지 않았다. 마침내 결심한 듯, 솔라는 지우개를 들어 그 점선을 단호하게 지워버렸다. 그리고는 ‘Improve’ 옆 빈 공간에 만족스럽게 두 글자를 적었다. ‘종료’.
이제야 완벽한 그림이 된 것 같았다. 문제 발생, 원인 분석, 해결, 그리고 프로젝트 종료. 이것이 솔라가 이해한 깔끔하고 합리적인 절차였다. 한번 고장 난 기계를 고쳤으면 된 거지, 왜 또 처음부터 설계를 고민해야 한단 말인가. 솔라는 이제야말로 5단계 여정의 종착역에 도착했다고 생각했다.
루나는 솔라가 점선을 지우고 ‘종료’라고 적는 모습을 말없이 지켜봤다. 솔라의 행동은 그녀의 머릿속 생각을 정확하게 보여주는 그림이었다. ‘해결되었으니, 이제 끝이다.’
“좋아.” 루나가 소파에 기댄 채 입을 열었다. “시 추천 봇의 데이터베이스 주소 문제는 완벽하게 해결됐어. 시스템은 다시 정상적으로 작동하고, 우리는 한숨 돌렸지.”
루나는 잠시 뜸을 들인 후, 새로운 상황을 던졌다.
“그렇게 한 달이 지났어. 시스템은 다운되지도 않고, 슬픈 시만 뱉어내지도 않아. 그런데 사용자 게시판에 새로운 불만들이 올라오기 시작해. ‘추천해 주는 시가 너무 뻔해요. 맨날 교과서에서 본 것만 나와요.’, ‘좀 더 신선한 시는 없나요?’ 같은 피드백이야. 솔라, 이제 어떡할까? 우리 프로젝트는 ‘종료’됐는데.”
솔라는 순간 할 말을 잃었다. “그건… 버그는 아니잖아?”
그녀의 목소리에는 당혹감이 묻어났다. 시스템은 설계된 대로 ‘감정에 맞는 시’를 잘 추천하고 있었다. 고장 난 것이 아니었다. 단지 사용자들이 만족하지 못할 뿐이었다. 솔라가 화이트보드에 적은 ‘종료’라는 단어가 갑자기 불안하게 흔들리는 것 같았다. 이런 종류의 문제—고장은 아니지만, 만족스럽지 않은 상태—는 그녀의 완결된 루프 안에 들어갈 자리가 없었다.
“바로 그 지점이야.” 루나가 몸을 일으켜 화이트보드 앞으로 다가왔다. 그녀는 솔라가 쓴 ‘종료’라는 글자를 손가락으로 가리켰다. “솔라는 LLMOps 루프를 시스템이 ‘죽었을 때’ 다시 살리는 심폐소생술처럼 생각한 것 같아. 하지만 이 루프의 진짜 목적은 시스템이 죽지 않게, 더 나아가서는 더 ‘건강’하게 만들기 위한 지속적인 건강검진과 같아.”
루나는 마카를 들어 ‘사용자 피드백: 추천이 뻔하다’라고 새로 적었다.
“이 피드백이 바로 새로운 순환을 알리는 신호탄이야. 우리가 길을 잃지 않으려면 다시 징검다리를 밟아야 해. 첫 번째 징검다리는 뭐였지?”
“관측(Trace)…” 솔라가 작게 대답했다.
“맞아. ‘뻔하다’는 주관적인 느낌을 데이터로 바꿔야지.” 루나가 말했다. “추천된 시 목록을 뽑아보니, 지난 한 달간 추천된 시 500편 중 상위 10개의 유명한 시가 400번을 차지했다는 ‘사실’을 확보했어. 이것이 우리의 새로운 ‘관측’ 결과야.”
다음으로 루나는 ‘평가(Evaluate)’ 단계로 화살표를 그었다. “왜 이런 일이 벌어졌을까? ‘평가’ 단계에서 우리는 원인을 분석하지. 그리고 깨달았어. 우리가 처음 시스템을 ‘설계(Design)’할 때 넣었던 시 데이터셋 자체가 너무 작고 고전 작품 위주였다는 걸. 알고리즘에 문제가 없어도, 재료가 한정적이니 결과물도 뻔할 수밖에 없었던 거야.”
솔라의 눈이 커졌다. 지난번 문제와는 전혀 다른 차원이었다. 지난번은 부품(데이터베이스 주소)의 결함이었지만, 이번은 최초의 설계도(데이터셋 구성) 자체가 가진 한계였다.
“그럼… 이번의 ‘개선(Improve)’은 단순히 코드를 수정하는 게 아니네.” 솔라가 마침내 깨달음을 얻은 목소리로 말했다. “데이터셋을 대규모로 확장하거나, 사용자에게 새로운 시를 추천하려는 인센티브를 주는 알고리즘을 추가해야 해. 이건… 이건 사실상 시스템을 다시 ‘설계(Design)’하는 거잖아!”
솔라는 자기가 지웠던 점선 화살표의 의미를 비로소 온전히 이해했다. ‘개선’은 단순히 구멍을 메우는 작업이 아니었다. 때로는 건물의 기초를 보강하고 새로운 층을 올리기 위해 다시 설계도를 펼쳐보는 일에 가까웠다. 시스템을 둘러싼 환경, 사용자 기대치, 새로운 기술 등 모든 것이 변하기 때문에, 시스템 역시 그에 맞춰 계속 진화해야만 했다. ‘종료’란 있을 수 없었다.
“맞아.” 루나가 조용히 고개를 끄덕였다. “그래서 이 순환은 끝나지 않는 거야. 한 번의 루프가 끝나면 시스템의 상태가 바뀌고, 그 바뀐 상태는 우리가 이전에는 보지 못했던 새로운 문제를 드러내거든. 이 반복적인 루프야말로 우리가 예측 불가능한 LLM 시스템을 통제하고, 지속적으로 개선해나갈 수 있는 유일한 방법이야.”
솔라는 지우개를 들어 자신이 썼던 ‘종료’라는 단어를 깨끗이 지웠다. 그리고 아까보다 훨씬 더 분명하고 확신에 찬 손길로, ‘Improve’에서 ‘Design’으로 돌아가는 순환 화살표를 진하게 그렸다. 이제 그 화살표는 더 이상 원점으로 돌아가는 패배의 길이 아니라, 더 높은 곳으로 올라가기 위한 나선형 계단처럼 보였다.
그녀는 책상 위 포스트잇 한 장을 떼어 화이트보드에 붙였다. 그리고는 방금 깨달은 것을 담아 새로운 계획을 세우기 시작했다.
[LLMOps 루프 적용 계획: 시 추천 봇 v2]
- 관측(Trace): 사용자 만족도 저하 피드백 수집. 추천 시 목록 분석 -> 상위 10개 시가 80% 차지.
- 평가(Evaluate): 원인 분석: 초기 데이터셋의 다양성 부족.
- 개선/설계(Improve/Design):
- 현대 시, 독립 출판 시 등 1만 편 데이터셋 추가 (Design 변경)
- 사용자별 추천 이력을 추적해, 이미 추천된 시의 가중치를 낮추는 로직 추가 (Design 변경)
- 실행(Run): v2 시스템 배포.
- (Next) 관측(Trace): 업데이트 후 추천 다양성 지표와 사용자 만족도 변화를 다시 추적 시작.
솔라는 자신이 쓴 계획을 바라보았다. 이것은 이제 일회성 문제 해결 목록이 아니었다. 시스템을 계속 살아 움직이게 하고, 끊임없이 더 나은 방향으로 나아가게 하는 엔진의 설계도였다.
“이제 알겠어.” 솔라가 루나를 보며 말했다. “LLMOps 루프는 끝나는 게 아니었어. 시스템을 계속 살아있게 만드는 심장 박동 같은 거였네.”