핵심 원칙

  • 자연어 API 프로덕션 구축 시 semantic parsingexecution 분리 필수
  • LLM은 자연어 → 구조화된 요청(canoical structured requests) 변환에만 사용
  • 자연어를 입력으로만 취급, API 계약으로 삼지 말아야 함 (언어는 취약)

자연어 직접 사용 문제점

  • 비결정적 행동(nondeterministic behavior)
  • 프롬프트 기반 비즈니스 로직 → 디버깅·재현 어려움
  • 암묵적 API 계약 → 작은 변화로 동작 변형
  • 조용한 실패(silent failures) 발생, 시스템 취약

아키텍처: 2단계 레이어 분리

1. Semantic Parse API (자연어 → 구조 변환)

  • 사용자 텍스트 입력 수용
  • LLM으로 intent·entities 추출
  • 미리 정의된 스키마 완성
  • 정보 부족 시 clarification 질문 (비즈니스 로직 실행 금지)
  • 컴파일러 역할 (e.g., “blue backpack but cheaper” → {intent: “recommend_similar”, reference_product_id: “blue_backpack_123”, price_bias: -0.8})

2. Structured Execution API (구조 → 실행)

  • 구조화 입력만 수용
  • 결정론적·버전 관리·테스트 가능
  • 자연어 처리 없음, 안정적 백엔드 역할

주요 요소: Canonical Schemas

  • 코드로 정의된 intent별 계약 (필수/선택 필드, 값 범위, 유효성 규칙)
  • 자연어 변형 흡수 → 일관된 출력 보장
  • API 계약의 backbone 역할

Schema Completion (Clarification)

  • 정보 부족 시 “needs_clarification” 응답 (missing fields, targeted question, current state)
  • 상태 객체로 메모리 관리 (API는 stateless)
  • 클라이언트가 상태 전달하며 대화 유지 → 완성 시 canonical_request 실행

오케스트레이션: LangGraph 활용

  • 구조화 워크플로우 모델링 (intent 분류 → entity 추출 → schema 병합 → 유효성 검사 → 완성/Clarification 라우팅)
  • 코드 기반 결정, LLM은 제안만
  • 명확한 상태 전환·관찰 가능·안전 재시도

안전장치: Confidence Gates

  • LLM 출력에 confidence score 요구
  • 임계값 미달 시 실행 차단, clarification 요청 (e.g., 모호한 “the bag” → 저신뢰도 → 추가 질문)
  • silent misinterpretation 방지

정규화: Lightweight Ontologies

  • 코드 기반 (허용 intent, synonym mappings, cross-field validation)
  • LLM 제안 값 → 코드로 정규화 (e.g., “cheaper” → price_bias: -0.7)
  • 논리 불일치 시 clarification (e.g., cheap + high quality 우선순위 질문)

성능 고려

  • 지연 시간: intent 분류 ~40ms, entity 추출 ~200ms, 검증 1ms → 총 250300ms
  • 채팅 UX에서 수용 가능, 오류 비용보다 저렴

주요 교훈 (Key Takeaways)

  • 언어는 API 계약 아님, 구조로 변환
  • 서버 측 schema 완성 소유
  • LLM은 discovery·extraction에만, 실행 아님
  • 안전·결정론성 최우선
  • Azure OpenAI + LangGraph로 실제 시스템 구축 경험 기반

https://aisparkup.com/posts/9012