
부제: 일어나지 않는 경우를 위한 방어 코드를, 어디까지 짜고 어디서 멈출지
에이전트가 사용자에게 버튼이나 선택지 같은 UI를 그리게 하는 도구가 있다.
정상이면 LLM이 이 도구를 정식으로 호출하고, 서버는 그 입력(버튼이 제대로 붙었는지 등)을 검증한다.
그런데 여기에 드문 실패 하나가 끼어들 여지가 있었다.
일어날 법한 실패
LLM이 가끔 이 UI를 도구 호출이 아니라 답변 본문에 마크업 텍스트로 흘릴 수 있다.<ui surface_id="..." ...> 같은 태그를 그냥 글자로 뱉는 것이다.
이게 왜 그럴듯하냐면, 시스템 프롬프트가 XML 스타일 태그를 여럿 쓰기 때문이다.
LLM은 주변 스타일을 흉내 내는 경향이 있어서, 그 태그 스타일을 따라 UI를 텍스트로 써 버리는 회귀가 충분히 가능하다.
이러면 두 가지가 나쁘다.
하나, 그 raw 마크업이 사용자 화면에 그대로 노출된다.
둘, 도구 호출이 아니니 UI가 제대로 렌더되지 않는다.
사용자 영향은 막되, 검증은 미룬다
그래서 방어를 만들었다.
스트리밍 도중 그 마크업을 감지해, 사용자 화면에 새지 않게 버퍼링하고,
파싱해서 정식 도구 호출로 합성한다.
여기서 판단이 갈렸다.
이 복구 경로에는, 정상 경로가 하는 완전한 검증(입력 정합성 검사)을 붙이지 않았다.
왜냐하면 실제로 이 경로는 한 번도 일어나지 않았기 때문이다.
쓰는 모델은 항상 정식 도구 호출로 UI를 보냈고, 이 텍스트-마크업 경로는 240번이 넘는 실측에서 0회였다.
일어나지 않는 경로에 완전한 검증까지 미리 짜는 건 과잉이다.
대신 그냥 비워 두지 않고, 주석으로 남겼다.
"이 경로에서 깨진 입력이 관측되면, 그때 검증과 폴백을 여기에 추가한다."
미완성을 감추지 않는다
정리하면 이렇다.
사용자에게 영향이 가는 부분(마크업 노출 차단)은 만들었다. 이건 드물어도 사용자가 겪으면 나쁘니까.
반면 실측 0회인 경로의 완전 검증은 일부러 미뤘다. 지금 짜 봤자 쓰이지 않으니까.
그리고 그 미완성을 감추는 대신, "언제 마저 짜야 하는지"를 코드에 박아 뒀다.
방어 코드는 "짜느냐 마느냐"가 아니라 "어디까지 짜느냐"의 문제였다.
정리
- LLM이 UI를 도구 호출 대신 텍스트 마크업으로 흘리는 드문 실패가 있을 수 있다(프롬프트 XML 스타일 모방)
- 사용자에게 영향 가는 부분(raw 마크업 노출)은 버퍼링·합성으로 막았다
- 그 경로의 완전 검증은 실측 0회(240런+)라 일부러 붙이지 않음 — 과잉 방어 회피
- 대신 "발생하면 여기에 검증·폴백 추가"를 주석으로 명시 — 미완성을 감추지 않고 문서화
방어 코드는 얼마나 짜느냐의 문제다.
사용자에게 닿는 실패는 막되, 실측 0회인 경로의 완전 검증까지 미리 짜는 건 과잉이다.
안 짜는 대신 언제 짜야 하는지를 코드에 남기면, 미완성이 부채가 아니라 표지판이 된다.
'AI' 카테고리의 다른 글
| [에이전트] 같은 말 반복, 프롬프트 대신 그래프 제어로 끝낸 턴 (0) | 2026.07.21 |
|---|---|
| [에이전트] 학계 1순위 중요도 점수를 버린 이유, LLM 1~10점은 변별력이 없다 (0) | 2026.07.15 |
| [에이전트] 컨텍스트 오염 타임존을 거주지로 착각한 날씨 조회 (0) | 2026.07.13 |
| [에이전트] 도메인 지식 지연 로딩 Progressive Disclosure 스킬 (0) | 2026.07.12 |
| [프롬프트] LLM 프롬프트 중앙 관리 Langfuse SWR 캐싱 (0) | 2026.07.12 |