
“사용자가 자연어로 요청하면 AI가 알아서 처리해줍니다” – 매력적으로 들리지만, 프로덕션 환경에서는 위험천만한 접근입니다. 프롬프트 하나 바뀌면 비즈니스 로직이 바뀌고, 조용히 실패하는데 디버깅은 불가능하죠.
Microsoft 개발자 커뮤니티가 Azure OpenAI와 LangGraph로 실제 시스템을 구축하며 검증한 프로덕션 아키텍처를 공개했습니다. 핵심은 “자연어를 실행하지 말고, 구조화된 요청으로 변환하라”입니다.
출처: How to Build Safe Natural Language-Driven APIs – Microsoft Tech Community
자연어를 직접 실행하면 안 되는 이유
자연어를 API 계약으로 직접 사용하면 심각한 문제가 발생합니다. API 계약이 암묵적이 되고, 작은 프롬프트 변경이 예상치 못한 동작 변화를 일으킵니다. “비슷한 상품 보여줘”와 “유사 제품 추천해줘”가 다른 결과를 낼 수 있죠.
더 큰 문제는 조용한 실패입니다. LLM이 불확실한 상황에서도 그럴듯한 답을 내놓기 때문에, 시스템은 잘못된 해석으로 작업을 실행하고 사용자는 뭐가 잘못됐는지조차 모릅니다. 비즈니스 로직이 프롬프트 속으로 조용히 스며들면서 테스트도 재현도 불가능해집니다.
해결책: 2단계 분리 아키텍처
Microsoft가 제안하는 해법은 명확한 책임 분리입니다.
첫 번째 레이어: Semantic Parse API는 자연어를 구조화된 요청으로 변환합니다. 사용자가 “저 파란 가방이랑 비슷한데 더 싼 거 보여줘”라고 말하면, LLM이 이를 분석해 {intent: "recommend_similar", product_id: "blue_backpack_123", price_bias: -0.8} 같은 표준 스키마로 변환하죠. 중요한 것은 이 레이어가 절대 비즈니스 로직을 실행하지 않는다는 점입니다. 정보가 부족하면 “어떤 제품과 비교하시나요?”처럼 명확한 질문을 던집니다.
두 번째 레이어: Structured Execution API는 구조화된 입력만 받아 결정론적으로 실행합니다. 자연어 처리는 전혀 없고, 버전 관리가 가능하며, 완전히 테스트 가능합니다. 전통적인 API처럼 동작하지만, 사용자는 자연어로 접근할 수 있는 거죠.
이 접근법의 핵심은 LLM을 실행 엔진이 아닌 “컴파일러”로 사용한다는 점입니다. 자연어라는 고수준 언어를 기계가 이해할 수 있는 구조화된 언어로 번역하는 역할만 맡기는 겁니다.
안전장치: Schema와 Confidence Gate
실전에서는 추가 안전장치가 필요합니다.
Canonical Schema는 각 의도마다 코드로 명확히 정의된 계약입니다. “유사 상품 추천” 의도면 어떤 필드가 필수이고, 값의 범위는 어떻게 되는지 명시하죠. 프롬프트가 아니라 이 스키마가 진짜 API 계약입니다.
Confidence Gate는 불확실성을 차단합니다. LLM이 “가방”이라는 모호한 입력으로 특정 상품을 추측했는데 확신도가 0.4라면? 실행을 멈추고 “파란 백팩, 가죽 토트백, 여행용 더플백 중 어느 것인가요?”라고 되묻습니다. 잘못된 추측으로 실행하는 것보다 한 번 더 물어보는 게 낫습니다.
Microsoft 팀이 측정한 전체 오버헤드는 250-300ms 수준이었습니다. 의도 분류 40ms, 엔티티 추출 200ms, 검증과 라우팅 1ms. 채팅 기반 UX에서는 충분히 허용 가능한 지연시간이죠.
자연어의 편리함, 시스템의 안정성
이 아키텍처는 자연어 인터페이스의 편리함을 유지하면서도 엔터프라이즈급 안정성을 확보합니다. 사용자는 여전히 “이거랑 비슷한데 더 싼 거”라고 말할 수 있고, 시스템은 예측 가능하고 테스트 가능하게 동작합니다.
원문에는 LangGraph를 활용한 워크플로우 구성, 동의어 정규화를 위한 온톨로지 설계, 그리고 실제 코드 예시까지 포함되어 있습니다. 자연어 API를 프로덕션에 도입하려는 팀이라면 필독할 만한 가이드입니다.

답글 남기기