구조화된 출력

구조화된 출력 (Structured output)

자연어 응답을 받아서 일일이 파싱하다 보면, 형식이 매번 조금씩 달라져 골치 아픈 경우가 많죠. 구조화된 출력(structured output)은 에이전트가 데이터를 특정하고 예측 가능한 형식으로 반환하게 해서 그 문제를 해결해 줍니다. 자연어 응답을 파싱하는 대신, 애플리케이션이 바로 사용할 수 있는 JSON 객체, Pydantic 모델, 또는 dataclass 형태의 구조화된 데이터를 받는 거죠.

출처: LangChain 공식 문서 — Structured output

create_agent가 처리해 주는 구조화된 출력

LangChain의 create_agent는 구조화된 출력을 자동으로 처리해요. 사용자가 원하는 구조화된 출력 스키마를 설정하면, 모델이 구조화된 데이터를 생성할 때 그것이 캡처되고 검증되어 에이전트 state의 'structured_response' 키로 반환됩니다.

코드 예시는 원문 페이지에 인터랙티브로 포함되어 있으며, 페이지 접근 시 표시됩니다(여기서는 텍스트 추출로 코드가 빠져 있어 '확인 필요'). 핵심 개념은 다음과 같아요.

  • 구조화된 출력을 원하면 create_agentresponse_format으로 스키마를 지정한다.
  • 모델이 구조화된 데이터를 생성하면 자동으로 검증·캡처되어 최종 state의 structured_response 키에 담긴다.

응답 형식 (Response format)

response_format으로 에이전트가 구조화된 데이터를 반환하는 방식을 제어해요.

  • ToolStrategy[StructuredResponseT]: 구조화된 출력에 도구 호출(tool calling)을 사용
  • ProviderStrategy[StructuredResponseT]: 제공자 네이티브(structured output)를 사용
  • type[StructuredResponseT]: 스키마 타입 — 모델 능력에 따라 최적 전략을 자동 선택
  • None: 구조화된 출력을 명시적으로 요청하지 않음

스키마 타입을 직접 제공하면 LangChain이 자동으로 선택합니다.

  • 모델과 제공자가 네이티브 구조화된 출력을 지원하면(OpenAI, Anthropic (Claude), xAI (Grok) 등) ProviderStrategy.
  • 그 외 모든 모델은 ToolStrategy.

구조화된 응답은 에이전트 최종 state의 structured_response 키로 반환돼요.

제공자 전략 (Provider strategy)

일부 모델 제공자는 API를 통해 구조화된 출력을 네이티브로 지원해요(예: OpenAI, xAI (Grok), Gemini, Anthropic (Claude)). 가능할 때 가장 신뢰할 수 있는 방법입니다. 이 전략을 쓰려면 ProviderStrategy를 구성하세요.

필수 (required) — 구조화된 출력 형식을 정의하는 스키마. 다음을 지원해요.

  • Pydantic 모델: 필드 검증이 있는 BaseModel 하위클래스. 검증된 Pydantic 인스턴스를 반환.
  • Dataclass: 타입 어노테이션이 있는 Python dataclass. dict를 반환.
  • TypedDict: 타입이 지정된 딕셔너리 클래스. dict를 반환.
  • JSON Schema: JSON 스키마 명세가 있는 딕셔너리. 최상위 titledescription 키를 포함해야 하고, dict를 반환.

선택 (Optional) — 엄격한 스키마 준수를 활성화하는 불리언 파라미터. 일부 제공자(OpenAI, xAI)가 지원해요. 기본값은 None(비활성화)입니다.

create_agent.response_format에 스키마 타입을 직접 전달하고 모델이 네이티브 구조화된 출력을 지원하면 LangChain이 자동으로 ProviderStrategy를 사용합니다.

제공자 네이티브 구조화된 출력은 모델 제공자가 스키마를 강제하므로 높은 신뢰성과 엄격한 검증을 제공해요. 가능할 때는 이를 사용하는 걸 권장합니다.

도구 호출 전략 (Tool calling strategy)

네이티브 구조화된 출력을 지원하지 않는 모델은 LangChain이 도구 호출을 사용해 같은 결과를 얻어요. 이 방식은 도구 호출을 지원하는(대부분의 현대 모델) 모든 모델에서 동작합니다. 이 전략을 쓰려면 ToolStrategy를 구성하세요.

필수 (required) — 구조화된 출력 형식을 정의하는 스키마. 다음을 지원해요.

  • Pydantic 모델: BaseModel 하위클래스. 검증된 Pydantic 인스턴스를 반환.
  • Dataclass: 타입 어노테이션이 있는 Python dataclass. dict를 반환.
  • TypedDict: 타입이 지정된 딕셔너리 클래스. dict를 반환.
  • JSON Schema: JSON 스키마 명세가 있는 딕셔너리. 최상위 titledescription 키를 포함해야 하고, dict를 반환.
  • Union 타입: 여러 스키마 옵션. 모델이 컨텍스트에 따라 가장 적절한 스키마를 선택해요.

또한 구조화된 출력이 생성됐을 때 반환되는 도구 메시지의 커스텀 콘텐츠(tool_message_content)와, 구조화된 출력 검증 실패 시의 오류 처리 전략(handle_errors)도 설정할 수 있어요.

tool_message_content 파라미터로 구조화된 출력이 생성됐을 때 대화 기록에 나타나는 메시지를 커스터마이즈할 수 있어요. tool_message_content 없이 생성되는 최종 ToolMessage와, 이를 지정했을 때의 차이는 원문 페이지에서 확인할 수 있어요.

오류 처리 (Error handling)

모델은 도구 호출로 구조화된 출력을 생성할 때 실수를 할 수 있어요. LangChain은 이런 오류를 자동으로 처리하는 지능적인 재시도(retry) 메커니즘을 제공합니다.

다중 구조화된 출력 오류 (Multiple structured outputs error)

모델이 구조화된 출력 도구를 실수로 여러 번 호출하면, 에이전트가 ToolMessage로 오류 피드백을 제공하고 모델에게 재시도를 요청해요.

스키마 검증 오류 (Schema validation error)

구조화된 출력이 기대 스키마와 일치하지 않으면, 에이전트가 구체적인 오류 피드백을 제공합니다.

오류 처리 전략 (Error handling strategies)

handle_errors 파라미터로 오류 처리 방식을 커스터마이즈할 수 있어요.

  • True: 기본 오류 템플릿으로 모든 오류를 잡음
  • str: 이 커스텀 메시지로 모든 오류를 잡음
  • type[Exception]: 기본 메시지로 이 예외 타입만 잡음
  • tuple[type[Exception], ...]: 기본 메시지로 이 예외 타입들만 잡음
  • Callable[[Exception], str]: 오류 메시지를 반환하는 커스텀 함수
  • False: 재시도하지 않고 예외를 그대로 전파

커스텀 오류 메시지: handle_errors가 문자열이면 에이전트가 항상 고정된 도구 메시지로 모델에 재시도를 요청해요. 특정 예외만 처리: 예외 타입이면, 발생한 예외가 그 타입일 때만 (기본 오류 메시지로) 재시도하고 그 외에는 예외를 던져요. 여러 예외 타입: 튜플이면, 발생한 예외가 그 중 하나일 때만 재시도해요. 커스텀 오류 핸들러 함수: StructuredOutputValidationError, MultipleStructuredOutputsError, 그 외 오류에 대해 각각 다른 처리를 할 수 있어요. 오류 처리 없음: False로 재시도를 끄면 예외가 그대로 전파됩니다.

더 알아보기 (Learn more)