이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- 자주 일어나지는 않지만 반드시 알아야 하는 AI 장애는 무엇인가?
- embedding 모델 변경, index 잔존 chunk, prompt cache 붕괴는 왜 위험한가?
- agent와 tool calling에서 드물지만 큰 사고가 나는 지점은 무엇인가?
- 이런 문제를 설계 체크리스트에 어떻게 반영하는가?
개요
실무자는 흔한 장애뿐 아니라 드물지만 피해가 큰 장애를 알아야 한다. AI 시스템은 모델, context, 검색, tool, provider, 로그, 비용이 연결되어 있어 낮은 확률의 문제가 큰 사고로 이어질 수 있다.
이 문서는 그런 문제를 미리 체크리스트에 넣기 위한 플레이북이다.
Embedding 모델 변경 후 검색 품질 붕괴
embedding 모델을 바꾸면 vector가 놓이는 의미 공간이 달라질 수 있다. 기존 index에 새 embedding을 섞거나 query만 새 모델로 만들면 유사도 점수가 무의미해질 수 있다.
대응:
- embedding model version을 index metadata에 저장한다.
- 모델 변경 시 전체 재색인 계획을 세운다.
- dual index로 비교 eval을 돌린다.
- old/new index를 섞지 않는다.
삭제된 문서 Chunk 잔존
원본 문서를 삭제했는데 vector index에 chunk가 남으면 오래된 정보나 개인정보가 계속 검색될 수 있다.
대응:
- 문서 삭제 이벤트가 index 삭제로 이어지게 한다.
- source id 기준 delete API를 둔다.
- 정기적으로 원본 DB와 index를 reconcile한다.
- 답변 trace에 source id를 남긴다.
Retry로 인한 Tool 중복 실행
모델 호출이나 host가 실패했다고 판단해 retry했지만, 실제 write tool은 이미 성공했을 수 있다. 이때 메일, 결제, 티켓 생성, DB 변경이 중복된다.
대응:
- write tool은 idempotency key 필수
- 실행 결과를 audit log에 남김
- timeout 후 상태 조회 먼저 수행
- retry 금지 tool 목록 관리
JSON Schema 강제에도 Parsing 실패
structured output을 써도 refusal, content policy, max token, provider error, streaming partial 때문에 파싱 실패가 난다.
대응:
- validation failure를 정상 실패 경로로 둔다.
- refusal을 별도 타입으로 처리한다.
- output token limit을 모니터링한다.
- fallback model도 schema eval을 통과시킨다.
Prompt Cache 붕괴
prompt caching은 고정 prefix가 반복될 때 유리하다. 앞부분에 timestamp, user id, 요청별 context를 넣으면 cache hit rate가 떨어질 수 있다.
대응:
- 고정 instruction과 schema를 앞에 둔다.
- 동적 값은 뒤쪽에 배치한다.
- cached token 지표를 본다.
- prompt version 변경 후 cache hit rate를 확인한다.
Observability 고카디널리티 비용 폭증
trace tag에 user input, prompt hash가 아닌 원문, source id 수천 개, document title을 넣으면 관측성 비용이 커질 수 있다.
대응:
- tag에는 낮은 cardinality 값을 둔다.
- 원문은 별도 저장소와 샘플링을 쓴다.
- source id 목록은 길이 제한을 둔다.
- prompt 전문 로그는 기본 비활성화한다.
Metadata Filter와 DB 권한 불일치
vector DB의 metadata filter가 실제 DB 권한 모델과 다르면 권한 없는 문서가 검색될 수 있다.
대응:
- 권한 모델의 source of truth를 정한다.
- index metadata 생성과 권한 변경 이벤트를 연결한다.
- 검색 후 서버에서 한 번 더 권한을 확인한다.
- 권한 경계 eval을 만든다.
최신 문서보다 오래된 Chunk가 더 높은 점수
벡터 유사도는 최신성을 자동으로 보장하지 않는다. 오래된 문서가 질문과 더 비슷하면 더 높은 점수를 받을 수 있다.
대응:
- updated_at과 document version을 ranking에 반영한다.
- 폐기된 문서를 index에서 제외한다.
- 답변에 문서 버전을 표시한다.
- 최신성 관련 eval case를 둔다.
Streaming Partial Output 저장
streaming 중 연결이 끊겼는데 부분 응답을 성공 결과로 저장하면 사용자는 깨진 답변을 보게 된다.
대응:
- stream 상태를
in_progress,completed,aborted로 분리한다. - 완료 marker를 받은 뒤에만 최종 저장한다.
- partial은 별도 임시 저장소에 둔다.
- 사용자 취소와 네트워크 실패를 구분한다.
Agent Loop 무한 반복
agent가 목표를 달성하지 못하고 같은 tool을 계속 호출할 수 있다.
대응:
- max steps
- max tool calls
- max cost
- 반복 tool call 감지
- human handoff
외부 Tool 결과의 Prompt Injection
tool이 가져온 웹 문서, 티켓, 사용자 입력 안에 악성 지시가 들어 있을 수 있다.
대응:
- tool result를 데이터로 감싼다.
- system instruction보다 tool result가 우선하지 않게 한다.
- 민감 tool 호출 전에 서버 검증을 둔다.
- prompt injection eval을 만든다.
실전 팁
- 드문 사고는 장애 후에야 찾으면 늦다. 설계 리뷰 체크리스트에 넣는다.
- RAG는 삭제와 권한 변경 테스트가 꼭 필요하다.
- agent는 write tool을 연결하기 전 read-only로 충분히 관찰한다.
- 로그 비용도 장애로 취급한다.
위험 신호!
- embedding model version을 저장하지 않는다.
- vector index 삭제 절차가 없다.
- write tool retry가 공통 retry 정책을 그대로 탄다.
- agent loop 제한이 없다.
- observability tag에 원문 텍스트가 들어간다.
확인 질문
확인 질문
- embedding 모델 변경 시 왜 재색인이 필요한가?
- 새 embedding과 기존 embedding이 같은 의미 공간에 있다고 보장할 수 없기 때문이다.
- vector index에 삭제된 chunk가 남으면 어떤 사고가 나는가?
- 오래된 정보와 개인정보, 권한 없는 문서가 계속 검색될 수 있다.
- agent loop에 max step이 필요한 이유는 무엇인가?
- 반복 tool 호출로 비용과 side effect가 계속 증가하는 것을 막기 위해서다.