4부 16장. 세션 상태와 작업 상태 설계
에이전트를 처음 만들 때 가장 흔한 실수 중 하나는, 상태를 전부 한 주머니에 넣어 버리는 것이다. 사용자와 주고받은 대화, 방금 실행한 도구 결과, 아직 끝나지 않은 작업의 진행 상황, 실패 횟수, 중간 산출물, 사용자 선호도까지 몽땅 한데 모아 둔다. 처음에는 편해 보인다. 어차피 다 중요한 정보 같기 때문이다.
그런데 시간이 조금만 지나면 이상한 일이 벌어진다. 에이전트는 방금 끝난 일을 아직 진행 중인 일처럼 말하고, 오래전에 끝난 작업을 현재 맥락으로 착각하고, 대화 중에 바뀐 사용자의 요구를 장기 작업에 제대로 반영하지 못한다. 더 나쁜 경우에는 같은 작업을 두 번 실행하거나, 이미 보낸 알림을 다시 보내기도 한다.
문제의 핵심은 상태의 양이 아니라 상태의 종류를 구분하지 않았다는 데 있다. 대화를 이어 가기 위한 상태와 일을 끝까지 수행하기 위한 상태는 성격이 다르다. 이 둘을 분리하면 에이전트는 훨씬 덜 흔들리고, 무슨 일이 왜 벌어졌는지도 추적하기 쉬워진다.
이번 장에서는 바로 그 구분을 다룬다. 세션 상태는 지금 이 대화를 이해하기 위한 상태이고, 작업 상태는 하나의 일을 완료하기 위해 유지되는 상태다. 이름은 단순하지만, 이 둘을 어떻게 나누느냐에 따라 시스템의 안정성이 크게 달라진다.

왜 상태를 둘로 나눠야 할까
사람이 일하는 모습을 떠올려 보자. 고객과 대화하는 상담 창구와, 실제 업무를 처리하는 백오피스는 보통 분리되어 있다. 창구에서는 고객이 무엇을 원하는지 듣고, 필요한 추가 정보를 묻고, 진행 상황을 설명한다. 반면 백오피스에서는 서류를 확인하고, 승인 절차를 밟고, 시스템을 갱신하고, 결과물을 만든다.
에이전트도 비슷하다. 사용자의 말투, 직전 질문, 선호하는 출력 형식 같은 정보는 대화 창구에 가깝다. 반면 현재 작업의 단계, 이미 실행한 도구, 실패한 재시도 횟수, 생성된 파일 경로, 승인 대기 여부 같은 정보는 업무 처리 라인에 가깝다.
이 둘을 섞어 두면 어떤 일이 생길까. 사용자가 잠깐 말을 바꾼 것과 시스템이 확정한 작업 상태가 같은 무게로 저장된다. 그러면 모델은 무엇이 현재 대화의 힌트인지, 무엇이 실제 실행의 진실인지 구분하기 어려워진다. 대화는 유연해야 하지만, 작업은 일관되어야 한다. 이 두 요구를 한 덩어리 상태로 동시에 만족시키기는 생각보다 어렵다.
결국 상태 분리는 복잡함을 늘리는 일이 아니라, 서로 다른 책임을 분명히 만드는 일이다. 세션 상태는 "지금 무슨 이야기를 하고 있는가"를 붙잡고, 작업 상태는 "이 일이 어디까지 왔는가"를 붙잡는다.
세션 상태는 대화의 현재 장면을 붙잡는다
세션 상태는 사용자가 지금 이 대화에서 무엇을 원하고 있는지, 방금 어떤 맥락이 오갔는지, 어떤 표현 방식이 적절한지를 유지하는 상태다. 쉽게 말해, 에이전트가 대화의 흐름을 놓치지 않게 해 주는 손잡이다.
예를 들어 사용자가 "좀 더 짧게 요약해 줘", "표로 보여 줘", "고객에게 보내는 말투로 바꿔 줘", "아까 세 번째 항목만 다시 설명해 줘"라고 말할 때, 이런 정보는 세션 상태에 가깝다. 지금 대화의 맥락을 반영해야 하기 때문이다.
세션 상태에는 보통 이런 것들이 들어간다.
최근 대화 요약과 직전 사용자 의도
현재 대화에서 유효한 선호도나 출력 형식
사용자가 방금 정정한 사실이나 추가 제약
아직 답하지 않은 질문이나 확인이 필요한 항목
사용자에게 보여 줄 진행 상황 요약
중요한 점은 세션 상태가 대화 중심이라는 것이다. 사용자가 브라우저를 닫고 다시 들어왔을 때 꼭 이어져야 하는 정보도 있을 수 있지만, 많은 경우 세션 상태는 짧은 생명주기를 가진다. 또한 세션 상태는 사용자와의 상호작용에 따라 자주 바뀐다. 방금 전까지는 보고서 형식을 원했지만, 지금은 이메일 초안 형식을 원할 수도 있다.
세션 상태는 그래서 비교적 가볍고, 현재 대화에 민감하며, 사용자 경험에 직접 닿아 있다. 말하자면 프런트 데스크의 메모장이다.
작업 상태는 일을 끝까지 밀고 가는 기록이다
작업 상태는 하나의 목표를 수행하기 위해 필요한 실행 정보를 담는다. 대화가 잠시 멈춰도 유지되어야 하고, 시스템이 재시작되어도 가능하면 이어져야 하며, 누가 봐도 "이 작업이 지금 어디까지 왔는지" 알 수 있어야 한다.
예를 들어 "지난달 매출 하락 원인을 분석해서 보고서를 만들어 줘"라는 요청이 들어오면, 작업 상태에는 목표, 현재 단계, 조회해야 할 데이터 소스, 이미 수행한 도구 호출, 중간 결과 요약, 실패 횟수, 생성된 산출물, 승인 여부 등이 들어갈 수 있다.
작업 상태의 핵심은 대화가 아니라 실행이다. 사용자가 잠깐 다른 질문을 하거나, 세션이 새로 열리거나, 담당 에이전트가 교체되더라도 작업 자체는 같은 정체성을 유지해야 한다. 그래서 작업 상태는 보통 작업 ID를 갖고, 상태 전이도 더 엄격하다. 예를 들어 대기 중, 실행 중, 추가 정보 필요, 사람 승인 대기, 완료, 실패 같은 단계가 명확히 나뉜다.
작업 상태에는 특히 외부 세계에 영향을 준 행동의 흔적이 잘 남아야 한다. 이미 이메일을 보냈는지, 결재 요청을 생성했는지, 파일을 업로드했는지, 어느 단계까지 성공했는지 기록되지 않으면 재시도할 때 같은 행동을 또 할 수 있다. 에이전트가 똑똑해 보이는 것보다 더 중요한 것은, 같은 일을 두 번 하지 않는 것이다.
세션 상태가 대화의 온도를 담는다면, 작업 상태는 실행의 뼈대를 담는다. 전자는 유연함이 중요하고, 후자는 내구성이 중요하다.
세션 상태와 작업 상태는 무엇이 다른가
둘의 차이를 한눈에 보면 훨씬 선명해진다.
| 구분 | 세션 상태 | 작업 상태 |
|---|---|---|
| 중심 질문 | 지금 이 대화에서 무엇이 중요할까 | 이 일은 지금 어디까지 진행됐을까 |
| 생명주기 | 대화 단위로 짧고 유동적 | 작업 완료까지 비교적 길고 지속적 |
| 주된 변화 원인 | 사용자 발화, 응답 형식 변경, 정정 | 도구 실행, 단계 전이, 승인, 실패와 재시도 |
| 대표 정보 | 최근 대화 요약, 말투, 선호 형식, 미해결 질문 | 목표, 단계, 체크포인트, 산출물, 실패 기록, 부작용 기록 |
| 저장 성격 | 가볍고 요약 중심 | 내구성 있고 추적 가능해야 함 |
| 실패했을 때 문제 | 대화가 어색해짐, 맥락을 놓침 | 작업 중복 실행, 복구 실패, 상태 불일치 |
이 표를 보면 중요한 감각이 하나 드러난다. 세션 상태와 작업 상태는 단순히 기간만 다른 것이 아니다. 무엇을 위해 존재하는지가 다르다. 세션 상태는 모델이 지금 어떤 대답을 해야 하는지 돕고, 작업 상태는 시스템이 지금 어떤 행동을 해야 하는지 붙잡는다.
같은 요청도 두 개의 상태로 나눠서 봐야 한다
조금 더 생생한 예를 보자. 사용자가 이렇게 요청했다고 하자.
"어제 회의 녹취를 요약해서, 결정된 액션 아이템을 팀별로 정리해 줘. 끝나면 슬랙으로도 보내 줘."
이 요청을 하나의 상태 덩어리로 다루면 처음에는 그럭저럭 굴러갈 수 있다. 하지만 사용자가 중간에 "아, 슬랙 전송은 내가 확인한 뒤에 해 줘"라고 말하는 순간부터 복잡해진다. 이 수정은 대화의 변화이자 실행 정책의 변화다. 무엇이 세션에 남고, 무엇이 작업에 반영되어야 할까.
세션 상태에는 우선 이런 정보가 들어간다. 사용자는 회의 요약을 원하고, 결과는 팀별 액션 아이템 중심이어야 하며, 지금은 슬랙 자동 전송이 아니라 사용자 확인 후 전송으로 바뀌었다. 또한 사용자는 아마 지금 이 대화에서 진행 상황을 알고 싶어 할 수도 있다.
반면 작업 상태에는 다른 정보가 들어간다. 녹취 파일 경로, 현재 단계가 요약 중인지 액션 아이템 추출 중인지, 팀 분류가 완료되었는지, 슬랙 전송은 승인 대기인지, 이미 생성된 초안 문서가 어디에 저장되었는지, 전송 도구는 아직 호출되지 않았는지 같은 정보다.
같은 요청인데도 상태의 종류가 이렇게 다르다. 대화 쪽은 사용자의 의도와 표현 방식을 붙잡고, 작업 쪽은 수행 과정과 결과물을 붙잡는다. 이 분리가 되면 사용자가 말을 바꾸더라도 작업 상태에 어떤 필드가 업데이트되어야 하는지 명확해진다. 반대로 분리가 없으면 모델은 단지 대화 어딘가에 적힌 문장을 보고 "슬랙을 보내야 하나, 말아야 하나"를 매번 추측하게 된다.
세션은 작업을 만들고, 작업은 세션에 보고한다
실무에서는 세션 상태와 작업 상태가 완전히 따로 노는 것이 아니라, 자연스럽게 연결된다. 둘의 관계를 잘 설계하면 흐름이 매끄러워진다.
가장 흔한 흐름은 다음과 같다.
세션이 사용자의 요청을 받고, 그 요청이 장기 실행이 필요한 일인지 판단한다.
필요하면 새로운 작업 객체를 만들고 작업 ID를 발급한다.
작업은 자기 상태를 바꾸며 독립적으로 진행한다.
진행 중간중간 핵심 요약을 세션에 전달해 사용자에게 보여 준다.
사용자의 추가 지시나 수정은 다시 세션을 거쳐 적절한 작업 상태 변경으로 반영된다.
이 구조가 좋은 이유는 간단하다. 세션은 사람과 대화하는 창구 역할에 집중하고, 작업은 실행 책임에 집중할 수 있기 때문이다. 사용자는 "지금 어디까지 됐어?"라고 묻고, 세션은 작업 상태를 읽어 "데이터 정리는 끝났고, 현재 요약 초안을 검토 중입니다"라고 답한다. 여기서 세션은 작업 전체를 직접 들고 있지 않아도 된다. 필요한 만큼만 읽어 설명하면 된다.
이 패턴은 특히 장기 작업에서 중요하다. 작업이 10초 안에 끝나지 않고 몇 분, 몇 시간, 때로는 하루 이상 이어질 수도 있기 때문이다. 이런 작업은 세션보다 오래 살아남아야 한다. 사용자가 앱을 닫았다가 다시 들어와도, 작업은 멈춘 자리에서 이어질 수 있어야 한다.
상태를 분리하면 장기 실행이 훨씬 쉬워진다
에이전트가 단순한 질의응답을 넘어 실제 일을 하려면, 언젠가는 장기 실행 문제를 만난다. 파일 여러 개를 읽고, 외부 API를 호출하고, 검토 단계를 거치고, 승인까지 기다리는 작업은 한 번의 모델 호출로 끝나지 않는다.
이때 세션 상태만 믿고 있으면 금방 한계가 온다. 세션은 대화 중심이라 중간 실행 결과를 세밀하게 보존하기 어렵고, 재시작이나 복구에도 약하다. 반면 작업 상태를 따로 두면 중간 체크포인트를 만들 수 있다. 예를 들어 문서 수집 완료, 초안 작성 완료, 사람 검토 대기, 전송 승인 대기 같은 단계가 남는다.
이 기록은 단순한 메모가 아니다. 복구의 기준점이 된다. 시스템이 중간에 멈췄다면, 마지막으로 성공한 단계가 어디인지 보고 거기서 다시 시작할 수 있다. 또한 같은 작업이 이미 끝난 단계를 또 실행하지 않게 막아 준다. 결국 작업 상태는 장기 실행의 지도이자, 사고가 났을 때 다시 길을 찾게 해 주는 표지판이다.
저장소를 꼭 따로 나눠야 할까
여기서 종종 오해가 생긴다. 세션 상태와 작업 상태를 분리하라고 하면, 반드시 서로 다른 데이터베이스나 완전히 다른 시스템에 저장해야 한다고 생각하는 경우가 있다. 꼭 그럴 필요는 없다.
중요한 것은 물리적 분리보다 논리적 분리다. 같은 저장소를 써도 된다. 다만 세션 엔터티와 작업 엔터티가 개념적으로 구분되어 있어야 하고, 어떤 필드가 어느 쪽의 진실인지가 명확해야 한다.
예를 들어 하나의 데이터베이스 안에 sessions 테이블과 tasks 테이블을 둘 수 있다. 혹은 하나의 문서 저장소에 세션 문서와 작업 문서를 따로 둘 수도 있다. 핵심은 세션 문서에 작업의 모든 내부 로그를 밀어 넣지 않고, 작업 문서에 사용자의 모든 잡담을 그대로 쌓아 넣지 않는 것이다.
실무에서는 대개 이런 원칙이 도움이 된다. 세션에는 사용자 경험에 필요한 요약만 남기고, 작업에는 실행과 복구에 필요한 사실을 남긴다. 세션은 작업을 참조하고, 작업은 세션과 분리된 생명주기를 갖는다. 같은 집 안에 살아도 방은 따로 써야 한다는 뜻이다.
디버깅은 상태 분리에서 절반이 끝난다
운영 단계에 들어가면 "왜 이상한 행동을 했지?"라는 질문이 끊임없이 나온다. 이때 상태가 섞여 있으면 원인을 찾기 어렵다. 모델이 대화를 오해한 것인지, 작업 상태가 꼬인 것인지, 이미 끝난 단계를 다시 실행한 것인지 구분이 안 된다.
하지만 세션 상태와 작업 상태가 분리되어 있으면 디버깅 질문이 훨씬 명확해진다.
먼저 세션을 보면, 사용자의 최신 요구가 정확히 반영되었는지 확인할 수 있다. 사용자가 "전송하지 말고 초안만 보여 줘"라고 말했는데 세션 요약에 그 변화가 반영되지 않았다면 대화 계층의 문제다.
반대로 작업을 보면, 실제로 어느 단계에서 어떤 도구가 실행되었고 어떤 결과가 저장되었는지 확인할 수 있다. 슬랙 전송이 발생했다면, 승인 상태가 잘못 기록되었는지, 이미 전송된 사실을 중복 방지 키 없이 처리했는지, 재시도 로직이 부작용을 두 번 일으켰는지 볼 수 있다.
이런 분리는 책임 소재를 분명하게 만든다. 대화 해석 문제는 세션 계층에서 보고, 실행 문제는 작업 계층에서 본다. 결국 디버깅이 쉬워진다는 말은 단지 로그를 잘 본다는 뜻이 아니다. 어디를 봐야 할지 안다는 뜻이다.
설계할 때 특히 중요하게 볼 세 가지 질문
상태를 나눌 때는 복잡한 이론보다 세 가지 질문이 더 실용적이다.
첫째, 이 정보는 사용자의 현재 대화를 이해하기 위해 필요한가, 아니면 작업을 복구하고 이어 가기 위해 필요한가. 전자라면 세션 쪽, 후자라면 작업 쪽일 가능성이 크다.
둘째, 세션이 사라져도 이 정보가 반드시 살아남아야 하는가. 그렇다면 작업 상태에 있어야 한다. 장기 작업의 진행 단계, 이미 발생한 외부 부작용, 산출물 위치, 승인 이력 같은 것은 특히 그렇다.
셋째, 이 정보가 바뀌면 모델의 응답 스타일이 달라지는가, 아니면 시스템의 실행 경로가 달라지는가. 응답 스타일 쪽이면 세션, 실행 경로 쪽이면 작업에 더 가깝다.
물론 현실에서는 경계가 완전히 칼같이 잘리지 않는다. 어떤 정보는 양쪽에 모두 나타날 수 있다. 예를 들어 작업 진행률은 작업 상태가 원본 진실이지만, 세션에는 사용자에게 보여 주기 위한 요약본이 들어갈 수 있다. 중요한 것은 중복 자체가 아니라 어디가 원본인지를 정하는 일이다.
자주 하는 실수는 늘 비슷하다
상태 분리를 어렵게 만드는 실수도 대체로 반복된다.
세션에 모든 도구 로그를 그대로 밀어 넣는 실수
작업 상태를 너무 추상적으로 적어 실제 복구에 도움이 안 되는 실수
같은 사실을 세션과 작업 양쪽에서 따로 수정해 서로 어긋나는 실수
이미 발생한 외부 행동을 기록하지 않아 재시도 때 중복 실행하는 실수
첫 번째 실수는 대화를 무겁게 만든다. 사용자는 "지금 뭐가 됐는지"를 알고 싶은데, 세션에는 온통 내부 로그만 남는다. 두 번째 실수는 겉으로만 상태가 있는 척하는 경우다. 진행 중 한 마디만으로는 아무도 복구하지 못한다. 세 번째 실수는 원본과 복사본의 경계가 흐릴 때 생긴다. 네 번째 실수는 실제 서비스에서 가장 위험하다. 이메일 중복 발송이나 중복 결제처럼 눈에 보이는 사고로 이어지기 때문이다.
이 장의 구분은 메모리와도 조금 다르다
여기서 한 가지를 미리 짚고 가면 다음 장을 이해하기 쉬워진다. 세션 상태와 작업 상태의 구분은, 단기 메모리와 장기 메모리의 구분과 비슷해 보이지만 완전히 같지는 않다.
세션과 작업은 무슨 단위를 중심으로 상태를 볼 것인가의 문제다. 대화 단위로 볼 것인가, 일 단위로 볼 것인가의 문제다. 반면 단기 메모리와 장기 메모리는 얼마나 오래, 어떤 방식으로 기억할 것인가의 문제에 더 가깝다.
예를 들어 작업 상태는 장기적으로 유지될 수 있지만, 언제나 장기 메모리라고 부를 수는 없다. 어떤 작업은 하루 만에 끝나고 사라질 수 있다. 반대로 사용자 선호도는 여러 세션에 걸쳐 유지되니 장기 메모리 성격이 강하지만, 특정 작업의 진행 단계는 아닐 수 있다.
즉, 이번 장의 핵심은 기억의 기간보다 상태의 책임을 나누는 데 있다. 이 차이를 잡고 가면 나중에 메모리 설계도 훨씬 덜 헷갈린다.
결국 안정성은 상태의 경계에서 나온다
에이전트가 불안정해 보일 때 사람들은 종종 모델 성능부터 의심한다. 물론 모델도 중요하다. 하지만 실제 운영에서 흔들림의 원인은 의외로 상태 설계에 있는 경우가 많다. 지금 대화에 필요한 정보와 장기 작업을 이어 가기 위한 정보를 같은 통에 넣는 순간, 에이전트는 말과 행동 사이에서 자주 미끄러진다.
세션 상태와 작업 상태를 분리하면 좋은 점은 분명하다. 대화는 더 자연스러워지고, 작업은 더 끈질기게 이어지며, 실패했을 때 어디서 잘못됐는지도 더 선명하게 보인다. 세션은 사용자와 호흡을 맞추고, 작업은 일을 끝낸다. 이 둘이 서로 다른 리듬으로 움직인다는 사실을 인정하는 순간, 에이전트 설계는 훨씬 현실적인 모양을 갖기 시작한다.
좋은 에이전트는 많이 기억하는 시스템이 아니라, 무엇을 어떤 책임 아래 기억할지 아는 시스템이다. 그리고 그 첫 번째 분기점이 바로 여기다. 이 정보는 대화를 위한 것인가, 일을 위한 것인가. 이 질문에 답할 수 있으면, 상태 설계의 절반은 이미 끝난 셈이다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.