MCP 반환 타입을 위한 Pydantic V2 디스크리미네이터 (Discriminator) 패턴
요약
MCP 도구의 다양한 반환 타입을 처리하기 위해 Pydantic V2의 디스크리미네이티드 유니온 패턴을 사용하는 방법을 설명합니다. 이 방식은 클라이언트와 LLM이 반환 형태를 명확히 파싱할 수 있도록 돕습니다.
핵심 포인트
- Pydantic V2의 디스크리미네이터를 통한 명확한 타입 정의
- 리터럴 필드를 활용한 클라이언트 측 분기 처리 최소화
- 옵셔널 필드 방식 대비 정확한 타입 시그니처 제공
- 서버 전체에서 디스크리미네이터 필드 이름의 일관성 유지 필요
MCP 도구가 여러 가지 형태(성공, 부분 성공, 에러) 중 하나를 반환할 수 있는 경우, 가장 깔끔한 타이핑(Typing) 방식은 Pydantic V2의 디스크리미네이티드 유니온 (Discriminated Union)입니다. 이 패턴은 도구 반환 인터페이스(tool-return surface)에 대한 최근 3번의 리팩토링 과정에서도 살아남았습니다.
from typing import Literal, Annotated
from pydantic import BaseModel, Field
...
이 방식이 다른 대안들보다 뛰어난 이유:
리터럴 디스크리미네이터 (status)는 MCP 클라이언트(및 다운스트림 LLM)가 가장 먼저 파싱하는 필드입니다. Pydantic은 해당 필드를 기반으로 적절한 모델을 구축합니다. 클라이언트 측에서 if-elif 분기 처리를 할 필요가 없습니다.
공통 부모 클래스를 상속(Subclassing)하는 방식도 작동하지만, 구조적 구체성(Structural specificity)을 잃게 됩니다. LLM은 부모 타입을 받게 되며, 실제 형태를 추측해야만 합니다.
누락된 분기에 대해 None을 사용하는 옵셔널 필드(Optional fields) 방식도 작동하지만, 타입 시그니처(Type signature)가 읽는 이에게 거짓 정보를 전달하게 됩니다. 디스크리미네이터 접근 방식은 형태를 명확하게 만들어 줍니다.
주의할 점: 전체 MCP 서버에 걸쳐 디스크리미네이터 필드 이름을 일관되게 유지하십시오. Pydantic V2의 discriminator=는 유니온(Union) 단위로 적용됩니다. 만약 어떤 유니온은 status를 사용하고 다른 유니온은 type을 사용한다면, 기여자(Contributors)들이 이를 혼동할 수 있습니다. 하나를 선택하여 기여자 가이드(Contributor guide)에 문서화하십시오.
AI의 도움을 받아 초안을 작성하였으며, 저자가 편집 및 검증하였습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기