
부제: 사용자가 응답 도중 앱을 닫아도, 생성 중이던 답을 잃지 않게 한 이야기
챗봇은 답을 스트리밍(SSE)으로 한 조각씩 흘려보낸다.
그런데 사용자가 답이 끝나기 전에 앱을 닫거나 화면을 나가면 연결이 끊긴다.
문제는 그 순간 서버가 무엇을 하느냐였다.
끊기면 진행 중이던 답이 사라진다
연결이 끊기면 서버(uvicorn)는 그 요청에 딸린 작업들을 통째로 취소한다.
비동기에서 요청 하나는 여러 작업이 묶인 나무 같은 구조라, 요청이 끝나면 그 나무 전체가 취소된다.
그런데 하필 그 시점에 LLM은 아직 답을 생성하는 중일 수 있다.
저장도 후처리도 남아 있다.
그냥 두면 생성 중이던 턴이 통째로 사라진다.
사용자가 다시 들어와도 그 답이 없고, DB는 반쯤 쓰다 만 상태가 된다.
사용자가 잠깐 끊었을 뿐인데, 진행 중이던 일이 전부 날아가는 것이다.
이미 시작한 일은 마저 끝낸다
우리가 원한 건 이거였다.
사용자가 끊어도, 이미 생성 중이던 답은 끝까지 만들어 저장해 두자.
다시 들어오면 이어 볼 수 있게.
그래서 끊김(취소)을 잡아, 남은 일을 백그라운드로 넘겼다.
진행 중이던 대화를 체크포인트에서 이어 완성하고, 후처리를 마치는 작업이다.
핵심은 이 백그라운드 작업을 asyncio.shield로 감싼 것이다.
shield는 서버의 취소가 이 작업까지 전파되는 걸 막는다.
요청 나무가 취소돼도, 감싼 작업만은 취소되지 않고 끝까지 돈다.
작은 함정도 있었다.shield()는 Future를 돌려주는데, 이건 백그라운드 태스크 생성에 바로 넘길 수 없다.
그래서 얇은 코루틴으로 한 번 감싸는 헬퍼를 뒀다.
이제 사용자가 떠나도, 생성 중이던 턴은 체크포인트에서 재개돼 완성되고 저장된다.
정리
- 스트리밍 중 클라이언트가 끊기면 서버(uvicorn)가 요청에 딸린 작업 나무를 통째로 취소한다
- 그러면 생성 중이던 LLM 턴·저장·후처리가 함께 날아가 버린다
- 끊김을 잡아, 진행 중이던 그래프를 체크포인트에서 이어 완성하는 작업을 백그라운드로 넘겼다
- 그 작업을
asyncio.shield로 감싸 취소 전파로부터 보호 — 사용자가 떠나도 완주 - shield는 Future를 반환해 태스크에 직접 못 넘기니, 얇은 코루틴 헬퍼로 감쌌다
스트리밍에서 클라이언트가 끊기면 서버는 관련 작업을 취소한다.
하지만 "이미 시작한 일은 마저 끝내야" 하는 게 있다 — 생성 중이던 답, 그 저장.
그런 건 취소로부터 shield로 지켜 백그라운드에서 완주시킨다.
사용자의 이탈이 진행 중인 일을 죽이면 안 된다.
'AI' 카테고리의 다른 글
| [LLM] 대화 요약 대신 정보 추출 화자 귀속 편향 방지 (0) | 2026.07.23 |
|---|---|
| [LLM] 프롬프트 캐시 깨는 시계 현재시각 도구로 분리 (1) | 2026.07.22 |
| [에이전트] 내부 도구 MCP 안 쓴 이유 이식성 재사용성 (0) | 2026.07.22 |
| [메모리] 챗봇 사용자 기억 Identity Episodic 4계층 (1) | 2026.07.21 |
| [에이전트] 같은 말 반복, 프롬프트 대신 그래프 제어로 끝낸 턴 (0) | 2026.07.21 |