LLMOps 10
Agent 시스템을 위한 State 정의서: 데이터 혼란을 계약으로 바꾸는 방법
State를 그냥 공유 메모장처럼 생각하면 key가 늘어날수록 흐름이 흐려진다.
근거 · 교안 p28
1장: 공유 메모장의 혼돈을 넘어: 왜 ‘정의’가 필요한가?
솔라는 거실 테이블에 앉아 노트북 화면과 노트를 번갈아 보며 미간을 찌푸렸다. 화면 한쪽에 띄워진 짧은 문장이 머릿속을 맴돌았다. ‘State 정의서는 Agent 간에 무엇을 기억하고 무엇을 전달하는지 명확히 하는 문서다.’
“언니.”
소파에서 책을 읽던 루나가 고개를 들었다.
“나 Agent 시스템을 생각하고 있는데, 아무래도 이상해. 여러 Agent가 협력하려면 서로 정보를 주고받아야 하잖아. 그걸 ‘State’라는 공간에 기록하고 공유한다고 배웠어. 면접관 Agent를 만든다고 치면, ‘이력서 분석 Agent’, ‘질문 생성 Agent’, ‘답변 평가 Agent’가 각자 자기 일을 하고 State에 결과를 남기는 거지.”
솔라는 말을 이어가며 손가락으로 허공에 네모를 그렸다. 마치 보이지 않는 칠판에 무언가를 적는 것 같았다.
“그런데 이게 꼭… 시끄러운 시장 한복판에 있는 커다란 메모판 같아. ‘이력서 분석 Agent’가 ‘핵심역량’이라는 제목으로 내용을 적고, ‘질문 생성 Agent’는 ‘최종질문’을 적고, ‘답변 평가 Agent’는 ‘답변점수’를 남기고. Agent가 몇 개 없을 땐 괜찮겠지. 하지만 Agent가 수십 개로 늘어나면? 저마다 다른 이름으로, 다른 형식으로 정보를 마구잡이로 써넣기 시작하면 이 메모판은 그냥 쓰레기장이 되는 거 아닐까? 뭘 믿어야 할지, 정보의 흐름이 어떻게 되는지 완전히 흐려질 것 같아.”
솔라의 목소리에는 자기가 만든 상상에 스스로가 질린 듯한 기색이 묻어났다. 그냥 모두가 접근할 수 있는 공유 메모장. 편리할 것 같지만, 그 끝은 혼돈일 거라는 예감이 강하게 들었다.
루나는 책을 덮고 테이블로 다가왔다. 그리고는 서랍에서 커다란 스케치북 한 권과 색깔이 다른 펜 세 자루를 꺼내 솔라 앞에 놓았다.
“네 말이 맞아. 혼란스러워지지. 그럼 우리가 직접 그 혼란을 만들어볼까?”
루나는 스케치북의 깨끗한 페이지를 펼쳤다.
“이 스케치북이 Agent들의 ‘공유 메모장’, 즉 State라고 하자. 솔라, 네가 ‘이력서 분석 Agent’야. 나는 검은 펜으로 ‘질문 생성 Agent’ 역할을 할게. 그리고 이 파란 펜은 ‘답변 평가 Agent’야.”
솔라는 잠시 어리둥절했지만, 이내 루나의 의도를 알아채고는 빨간 펜을 집어 들었다. 재미있는 역할 놀이가 시작될 것 같았다.
“자, ‘이력서 분석 Agent’. 방금 훌륭한 개발자의 이력서를 읽었어. 공유 메모장에 어떤 정보를 남겨서 다른 Agent들에게 알려주고 싶어?”
솔라는 잠시 고민하더니 스케치북 중앙에 또박또박 적었다.
주요 기술: 파이썬, LangChain
루나는 고개를 끄덕이고는 검은 펜을 들었다. “좋아. 그럼 나, ‘질문 생성 Agent’는 그 정보를 보고 질문을 만들게.” 그녀는 솔라가 쓴 글씨 바로 아래에 이렇게 적었다.
생성된 질문: LangChain을 이용한 프로젝트 경험에 대해 설명해주세요.
“이제 면접자가 답변을 했고, ‘답변 평가 Agent’가 나설 차례야.” 루나는 파란 펜으로 바꿔 들고 그 아래에 덧붙였다.
평가: 우수
스케치북에는 세 줄의 정보가 각기 다른 필체와 색으로 남았다. 루나는 펜을 내려놓고 솔라를 바라보았다.
“이제 마지막으로, 이 모든 과정을 종합해서 최종 보고서를 만들어야 하는 ‘리포트 생성 Agent’가 등장했어. 이 메모장만 보고 보고서를 쓸 수 있을까?”
솔라는 스케치북을 들여다보았다. 처음에는 문제없어 보였다. 필요한 정보가 다 있는 것 같았다. 하지만 잠시 후, 솔라의 표정이 다시 찌푸려졌다.
“잠깐만… ‘평가: 우수’라고 되어 있는데, 이게 점수야? 아니면 등급? A, B, C 같은 건가? 100점 만점에 90점 이상이라는 뜻인가? ‘리포트 생성 Agent’는 이걸 어떻게 해석해야 하지?”
솔라의 손가락이 스케치북을 짚었다.
“그리고 ‘주요 기술’은 ‘이력서 분석 Agent’가 쓴 게 확실한데, 만약 나중에 다른 Agent가 이 내용을 덮어쓰면 어떡해? 예를 들어, 면접 도중에 새로운 기술이 언급돼서 ‘답변 평가 Agent’가 ‘주요 기술’ 목록에 ‘AWS’를 추가하고 싶을 수도 있잖아. 그럼 이 정보의 최종 책임자는 누구야? 더 큰 문제는… 만약 내가 지금 이 팀에 새로 합류한 개발자라면, 이 메모장에 적힌 ‘평가’나 ‘주요 기술’이 정확히 뭘 의미하는지 알려면 이걸 쓴 Agent를 만든 사람을 일일이 찾아가서 물어봐야 하잖아. 이건 시스템이 아니야. 그냥 쪽지 돌리기지.”
그 순간 솔라의 머릿속에서 무언가 ‘탁’ 하고 끊어지는 느낌이 들었다. 자신이 상상했던 혼란이 눈앞의 스케치북에 고스란히 재현되어 있었다. 규칙 없는 자유가 얼마나 비효율적이고 위험한지를 체감한 것이다.
솔라는 고개를 들어 루나를 보았다.
“알겠어. 뭐가 문제인지. 그냥 ‘알아서 잘 쓰자’고 하는 건 아무 의미가 없었어. 시작하기 전에 약속을 해야만 해.”
“어떤 약속?” 루나가 조용히 물었다.
“이 메모장에 어떤 종류의 데이터를, 어떤 이름으로, 어떤 모양으로 적을지 미리 전부 정해놓는 약속. ‘평가’라는 이름의 데이터는 ‘우수/보통/미흡’ 세 가지 중 하나만 써야 한다거나, ‘주요 기술’은 목록 형태로 계속 추가만 할 수 있고 수정은 안 된다는 식으로. 즉, 이 메모판의 사용법, 데이터의 구조를 먼저 정의해야 했던 거야.”
솔라는 ‘정의’라는 단어를 힘주어 말했다. 처음에는 막연하게만 느껴졌던 그 단어가 이제는 혼돈을 막을 유일한 열쇠처럼 보였다. 무질서한 메모판을 보고 나서야 비로소 질서의 필요성을 깨달은 것이다. 하지만 동시에 새로운 질문이 떠올랐다.
“좋아, ‘데이터 구조를 정의한다’는 것까지는 알겠어. 그럼 그 정의서에는 정확히 뭘 담아야 할까? 그냥 우리가 사용할 데이터 이름 목록만 쭉 나열하면 되는 걸까? ‘주요 기술, 생성된 질문, 평가’. 이렇게? 왠지 그것만으로는 부족할 것 같은데…”
2장: 데이터 계약의 첫걸음: Key와 Type으로 질서 잡기
솔라의 질문이 채 끝나기도 전에, 루나는 말없이 검은 펜을 다시 들었다. 그리고는 조금 전 세 가지 색깔의 펜으로 어지럽혀진 스케치북 페이지의 빈 공간에 자를 대고 반듯하게 선을 긋기 시작했다. 잠시 후, 어지러운 낙서들 옆으로 깔끔한 표가 하나 생겨났다. 세 개의 칸으로 나뉜, 아직은 텅 비어 있는 표였다.
솔라는 자기가 던진 질문—“정의서에는 정확히 뭘 담아야 할까?”—에 대한 대답이 말 대신 표로 돌아온 것을 직감했다. 루나는 표의 첫 번째 칸 상단에 Key라고 적었다. 그리고 두 번째 칸에는 설명, 세 번째 칸에는 Data Type이라고 썼다. 그제야 솔라는 자신이 했던 생각이 얼마나 막연했는지 깨달았다. ‘데이터 이름 목록’ 정도로는 어림도 없었다. 루나가 만든 표는 훨씬 더 구체적인 약속을 요구하고 있었다.
“네가 아까 말했던 데이터들을 여기에 한번 채워볼래?” 루나가 펜을 건네며 말했다.
솔라는 펜을 받아 들고 Key 열 아래에 익숙한 이름들을 적어 내려갔다.
- 주요 기술
- 생성된 질문
- 평가
첫 번째 열을 채우는 것은 쉬웠다. 다음은 설명 열이었다. 솔라는 각 데이터가 무엇을 의미하는지 간략하게 적었다.
| Key | 설명 | Data Type |
|---|---|---|
| 주요 기술 | 이력서에서 추출한 핵심 기술 스택 | |
| 생성된 질문 | 면접관 Agent가 생성한 질문 | |
| 평가 | 지원자 답변에 대한 평가 결과 |
여기까지는 순조로웠다. 하지만 마지막 Data Type 열 앞에서 솔라의 펜이 멈칫했다. 데이터의 ‘모양’을 정하는 칸. 바로 여기서 모든 혼란이 시작되었던 것을 기억해냈다.
“‘평가’… 아까는 그냥 ‘우수’라고 적었었지.”
솔라는 지난 실험의 기억을 떠올렸다. ‘우수’라는 글자만으로는 그것이 등급인지, 점수인지, 아니면 다른 무엇인지 알 길이 없었다.
“‘리포트 생성 Agent’가 이 ‘평가’ 값을 받아서 보고서에 써야 한다고 생각해 봐. 이 칸에 뭐라고 적어둬야 그 Agent가 혼란에 빠지지 않을까?” 루나가 조용히 물었다.
솔라는 잠시 고민에 잠겼다. 단순히 ‘글자’라고 하기에는 부족했다. 약속은 더 명확해야 했다.
“‘문자열(string)’이겠지. 그런데 그것만으로는 부족해. ‘우수’일 수도 있고, ‘아주 잘함’일 수도 있고, 누군가는 ‘Good’이라고 쓸 수도 있잖아.”
솔라는 무언가 깨달은 듯 Data Type 열에 string이라고 적은 뒤, 설명 열에 적었던 ‘지원자 답변에 대한 평가 결과’라는 문장 뒤에 괄호를 열고 새로운 문장을 덧붙였다.
| Key | 설명 | Data Type |
|---|---|---|
| … | … | … |
| 평가 | 지원자 답변에 대한 평가 결과 (‘우수’, ‘보통’, ‘미흡’ 중 하나의 값만 가짐) | string |
“이렇게! 데이터의 형태는 문자열이고, 허용되는 값은 이 세 가지뿐이라고 못 박아두는 거야. 일종의 규칙, 아니, 계약인 셈이지. 이걸 보면 ‘리포트 생성 Agent’는 ‘평가’라는 열쇠로 데이터를 꺼냈을 때, 그 안에는 반드시 저 세 단어 중 하나가 들어있을 거라고 믿을 수 있어.”
솔라는 흥분하며 말했다. 드디어 ‘흐름이 흐려진다’는 문제의 실마리를 잡은 것 같았다. 데이터의 이름인 Key와 데이터의 형태인 Data Type을 명확히 정의하는 것만으로도 수많은 오해와 버그를 막을 수 있었다. 이것이 바로 ‘정의’가 가진 힘이었다. 모든 참여자가 데이터를 정확히 같은 방식으로 인식하게 만드는 힘.
기세를 몰아 솔라는 나머지 칸도 채워나갔다. ‘생성된 질문’은 당연히 string이었고, ‘주요 기술’은 여러 개가 나올 수 있으니 list[string], 즉 문자열의 목록으로 정했다.
| Key | 설명 | Data Type |
|---|---|---|
| 주요 기술 | 이력서에서 추출한 핵심 기술 스택 | list[string] |
| 생성된 질문 | 면접관 Agent가 생성한 질문 | string |
| 평가 | 지원자 답변에 대한 평가 결과 (‘우수’, ‘보통’, ‘미흡’ 중 하나의 값만 가짐) | string |
표가 채워지자 무질서했던 메모판이 비로소 의미 있는 정보판으로 보이기 시작했다. 솔라는 만족스러운 얼굴로 표를 바라보다가, 문득 한 가지 의문점이 고개를 들었다.
“좋아, 이제 ‘주요 기술’은 문자열 목록이라는 걸 모두가 알게 됐어. 그런데 여기서 또 다른 문제가 생길 수 있겠는데?”
솔라는 주요 기술 행을 손가락으로 가리켰다.
“‘이력서 분석 Agent’가 처음에 ‘파이썬’이랑 ‘LangChain’을 이 목록에 넣었어. 그런데 면접 중간에 지원자가 ‘AWS 경험도 풍부하다’고 말했어. 그럼 ‘답변 평가 Agent’가 이 ‘AWS’라는 정보를 주요 기술 목록에 추가해야 할까? 아니면 기존 목록을 지우고 새로 만들어야 할까? 그리고 애초에 ‘답변 평가 Agent’가 이 목록을 수정할 권한은 있는 거야? 혹시 ‘이력서 분석 Agent’만 수정할 수 있도록 해야 하는 거 아닐까?”
솔라는 고개를 저었다. “데이터의 이름(Key)과 모양(Data Type)을 정하는 것만으로는 부족했어. 계약서에 중요한 조항이 몇 개 빠진 느낌이야. 이 데이터를 ‘어떻게’ 바꿀 수 있는지, 그리고 ‘누가’ 바꿀 책임과 권한을 갖는지에 대한 약속 말이야.”
3장: 계약의 완성: 변경 방식과 책임 Agent 명확히 하기
솔라의 마지막 말이 공중에 흩어지기도 전에, 루나는 조용히 스케치북에 그려진 표의 맨 오른쪽 칸 옆으로 자를 가져갔다. 솔라는 언니가 또다시 말 대신 행동으로 대답하려는 것을 알아차렸다. 루나는 익숙한 손놀림으로 두 개의 칸을 더 추가했다. 이제 갓 세 칸짜리였던 표는 어느새 다섯 칸짜리의 제법 그럴듯한 명세서처럼 보였다.
루나는 새로 생긴 두 칸의 머리글에 각각 구분과 사용 Agent라고 적었다. 솔라의 머릿속에 떠다니던 막연한 질문들—‘어떻게 바꾸지?’, ‘누가 바꾸지?’—이 인쇄된 활자처럼 명확한 형태로 눈앞에 나타났다. 이것은 질문에 대한 직접적인 답이 아니었다. 질문을 담을 수 있는, 정돈된 그릇이었다.
“이 두 칸이 네가 빠졌다고 느낀 계약 조항들이야.”
루나가 펜 끝으로 구분 열을 가리켰다. 솔라는 그 단어를 뚫어지라 쳐다봤다.
“구분이라… 뭘 구분한다는 거지?”
“네가 조금 전에 했던 말을 떠올려봐. ‘AWS’라는 정보를 주요 기술 목록에 추가해야 할지, 아니면 기존 목록을 지우고 새로 만들어야 할지 고민했잖아.”
루나의 말에 솔라의 머릿속에서 두 가지 시나리오가 생생하게 그려졌다. 하나는 기존의 ['파이썬', 'LangChain'] 목록에 'AWS'를 더해 ['파이썬', 'LangChain', 'AWS']로 만드는 것이고, 다른 하나는 기존 목록을 통째로 버리고 ['AWS']라는 새 목록으로 교체하는 것이었다. 두 방식은 완전히 다른 결과를 낳았다.
“아! 데이터가 바뀔 때, 기존 값에 새로운 걸 더하는 방식인지, 아니면 기존 값을 완전히 무시하고 새 값으로 덮어쓰는 방식인지를 정하는 거구나!”
솔라는 무릎을 쳤다. 주요 기술처럼 정보가 계속 쌓여야 하는 데이터는 전자의 방식이 맞았다. 대화 기록 같은 것도 마찬가지일 것이다. 하지만 매번 평가가 끝날 때마다 새로 계산되는 ‘최종 점수’ 같은 데이터라면 후자의 방식이 더 적합했다.
“맞아. 우리는 보통 기존 데이터에 새로운 값을 더해서 갱신하는 방식을 Reducer, 기존 데이터를 완전히 덮어쓰는 방식을 Overwrite라고 불러.” 루나가 구분 열 아래에 작은 글씨로 두 단어를 적어주었다.
솔라는 펜을 들고 주요 기술 행의 구분 칸에 망설임 없이 Reducer라고 적었다. 그리고 잠시 고민하더니, 평가 행에는 Overwrite라고 썼다.
“‘평가’는 면접관 Agent가 질문 하나에 대해 내리는 거니까, 질문이 바뀔 때마다 평가는 새로 내려져야 해. 이전 질문의 평가 결과가 다음 평가에 영향을 주면 안 되잖아. 그래서 덮어쓰는 게 맞아.”
이제 마지막 한 칸, 사용 Agent 열만이 비어 있었다. 솔라는 이 칸이 의미하는 바를 바로 알아차렸다. 이것은 ‘책임’과 ‘권한’에 대한 조항이었다.
솔라는 주요 기술 행을 보며 중얼거렸다. “이 데이터를 누가 사용하지? ‘이력서 분석 Agent’가 처음 만들고, ‘질문 생성 Agent’는 이걸 읽어서 질문을 만들고… 아까 내가 고민했던 것처럼 ‘답변 평가 Agent’도 새로운 기술을 추가할 수 있게 하고 싶어.”
솔라는 사용 Agent 칸에 세 Agent의 이름을 꼼꼼하게 적었다.
이력서 분석 Agent, 질문 생성 Agent, 답변 평가 Agent
그러고 나자 중요한 사실 하나가 명확해졌다. 이 목록에 이름이 없다는 것은, 해당 데이터를 함부로 건드려서는 안 된다는 뜻이었다. 이 목록은 단순한 참고 정보가 아니라, 강력한 규칙이었다. ‘리포트 생성 Agent’는 설령 보고서를 쓰다가 주요 기술 목록에 오타를 발견하더라도, 이 목록에 이름이 없기 때문에 임의로 수정할 수 없다. 수정이 필요하다면, 책임이 있는 Agent에게 요청해야만 하는 것이다.
“이제 알겠어….” 솔라가 완성된 표를 보며 나지막이 말했다.
| Key | 설명 | Data Type | 구분 | 사용 Agent |
|---|---|---|---|---|
| 주요 기술 | 이력서에서 추출한 핵심 기술 스택 | list[string] | Reducer | 이력서 분석 Agent, 질문 생성 Agent, 답변 평가 Agent |
| 생성된 질문 | 면접관 Agent가 생성한 질문 | string | Overwrite | 질문 생성 Agent |
| 평가 | 지원자 답변에 대한 평가 결과 (‘우수’, ‘보통’, ‘미흡’ 중 하나) | string | Overwrite | 답변 평가 Agent |
“이건 그냥 데이터 목록이 아니야. Agent들 사이의 약속, 데이터 계약서 그 자체였어. 데이터의 이름(Key)과 모양(Data Type)을 정하고, 어떻게 바꿀지(구분)와 누가 책임질지(사용 Agent)까지 모두 명시하는 것. 이렇게 해야만 Agent가 수십, 수백 개로 늘어나도 혼란 없이 서로를 믿고 협력할 수 있는 거야.”
처음 솔라가 상상했던 ‘시끄러운 시장의 메모판’은 사라지고, 그 자리에는 잘 설계된 시스템의 청사진이 놓여 있었다. 무질서한 낙서 같았던 스케치북 페이지가 이제는 모든 참여자가 따라야 할 명확한 규칙을 담은 문서로 보였다.
솔라는 더 이상 질문하지 않았다. 대신 스케치북의 새 페이지를 넘겼다. 그리고는 페이지 맨 위에 자를 대고 반듯하게 제목을 적었다.
<AI 면접관 Agent 시스템 - State 정의서 (초안)>
솔라는 망설임 없이 다섯 개의 열—Key, 설명, Data Type, 구분, 사용 Agent—을 그리고, 첫 번째 행부터 스스로 채워나가기 시작했다. 이제 솔라에게 State는 더 이상 혼돈의 원인이 아니었다. 오히려 혼돈을 제어하고 질서를 부여하는 가장 강력한 도구였다. 그녀는 이제 이 도구를 어떻게 사용해야 하는지 정확히 알고 있었다.