Skip to main content
구조화된 출력을 사용하면 에이전트가 특정하고 예측 가능한 형식으로 데이터를 반환할 수 있습니다. 자연어 응답을 파싱하는 대신, 애플리케이션에서 직접 사용할 수 있는 JSON 객체, Pydantic 모델 또는 데이터클래스 형태의 구조화된 데이터를 얻을 수 있습니다. LangChain의 create_agent는 구조화된 출력을 자동으로 처리합니다. 사용자가 원하는 구조화된 출력 스키마를 설정하면, 모델이 구조화된 데이터를 생성할 때 이를 캡처하고 검증한 후 에이전트 상태의 'structured_response' 키에 반환합니다.
def create_agent(
    ...
    response_format: Union[
        ToolStrategy[StructuredResponseT],
        ProviderStrategy[StructuredResponseT],
        type[StructuredResponseT],
    ]

Response Format

에이전트가 구조화된 데이터를 반환하는 방식을 제어합니다:
  • ToolStrategy[StructuredResponseT]: 구조화된 출력을 위해 도구 호출을 사용합니다
  • ProviderStrategy[StructuredResponseT]: 제공자 네이티브 구조화된 출력을 사용합니다
  • type[StructuredResponseT]: 스키마 타입 - 모델 기능에 따라 최적의 전략을 자동으로 선택합니다
  • None: 구조화된 출력 없음
스키마 타입이 직접 제공되면, LangChain이 자동으로 선택합니다:
  • 네이티브 구조화된 출력을 지원하는 모델의 경우 ProviderStrategy (예: OpenAI, Grok)
  • 그 외 모든 모델의 경우 ToolStrategy
구조화된 응답은 에이전트의 최종 상태에서 structured_response 키에 반환됩니다.

Provider strategy

일부 모델 제공자는 API를 통해 네이티브로 구조화된 출력을 지원합니다(현재 OpenAI와 Grok만 해당). 이는 사용 가능한 경우 가장 신뢰할 수 있는 방법입니다. 이 전략을 사용하려면 ProviderStrategy를 구성하세요:
class ProviderStrategy(Generic[SchemaT]):
    schema: type[SchemaT]
schema
required
구조화된 출력 형식을 정의하는 스키마입니다. 지원하는 형식:
  • Pydantic 모델: 필드 검증이 있는 BaseModel 서브클래스
  • 데이터클래스: 타입 어노테이션이 있는 Python 데이터클래스
  • TypedDict: 타입이 지정된 딕셔너리 클래스
  • JSON 스키마: JSON 스키마 사양이 포함된 딕셔너리
스키마 타입을 create_agent.response_format에 직접 전달하고 모델이 네이티브 구조화된 출력을 지원하는 경우, LangChain이 자동으로 ProviderStrategy를 사용합니다:
from pydantic import BaseModel
from langchain.agents import create_agent


class ContactInfo(BaseModel):
    """연락처 정보입니다."""
    name: str = Field(description="사람의 이름")
    email: str = Field(description="사람의 이메일 주소")
    phone: str = Field(description="사람의 전화번호")

agent = create_agent(
    model="openai:gpt-5",
    tools=tools,
    response_format=ContactInfo  # ProviderStrategy 자동 선택
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "Extract contact info from: John Doe, [email protected], (555) 123-4567"}]
})

result["structured_response"]
# ContactInfo(name='John Doe', email='[email protected]', phone='(555) 123-4567')
제공자 네이티브 구조화된 출력은 모델 제공자가 스키마를 강제하기 때문에 높은 신뢰성과 엄격한 검증을 제공합니다. 사용 가능한 경우 이를 사용하세요.
제공자가 선택한 모델에 대해 네이티브로 구조화된 출력을 지원하는 경우, response_format=ProductReview 대신 response_format=ToolStrategy(ProductReview)로 작성하는 것과 기능적으로 동일합니다. 두 경우 모두 구조화된 출력이 지원되지 않으면 에이전트가 도구 호출 전략으로 폴백합니다.

Tool calling strategy

네이티브 구조화된 출력을 지원하지 않는 모델의 경우, LangChain은 도구 호출을 사용하여 동일한 결과를 달성합니다. 이는 도구 호출을 지원하는 모든 모델에서 작동하며, 대부분의 최신 모델이 이에 해당합니다. 이 전략을 사용하려면 ToolStrategy를 구성하세요:
class ToolStrategy(Generic[SchemaT]):
    schema: type[SchemaT]
    tool_message_content: str | None
    handle_errors: Union[
        bool,
        str,
        type[Exception],
        tuple[type[Exception], ...],
        Callable[[Exception], str],
    ]
schema
required
구조화된 출력 형식을 정의하는 스키마입니다. 지원하는 형식:
  • Pydantic 모델: 필드 검증이 있는 BaseModel 서브클래스
  • 데이터클래스: 타입 어노테이션이 있는 Python 데이터클래스
  • TypedDict: 타입이 지정된 딕셔너리 클래스
  • JSON 스키마: JSON 스키마 사양이 포함된 딕셔너리
  • Union 타입: 여러 스키마 옵션. 모델이 컨텍스트를 기반으로 가장 적절한 스키마를 선택합니다.
tool_message_content
구조화된 출력이 생성될 때 반환되는 도구 메시지의 커스텀 콘텐츠입니다. 제공되지 않으면 구조화된 응답 데이터를 표시하는 기본 메시지가 사용됩니다.
handle_errors
구조화된 출력 검증 실패에 대한 오류 처리 전략입니다. 기본값은 True입니다.
  • True: 기본 오류 템플릿으로 모든 오류 처리
  • str: 이 커스텀 메시지로 모든 오류 처리
  • type[Exception]: 기본 메시지로 이 예외 타입만 처리
  • tuple[type[Exception], ...]: 기본 메시지로 이러한 예외 타입만 처리
  • Callable[[Exception], str]: 오류 메시지를 반환하는 커스텀 함수
  • False: 재시도 없이 예외를 전파
from pydantic import BaseModel, Field
from typing import Literal
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy


class ProductReview(BaseModel):
    """제품 리뷰 분석입니다."""
    rating: int | None = Field(description="제품 평점", ge=1, le=5)
    sentiment: Literal["positive", "negative"] = Field(description="리뷰의 감성")
    key_points: list[str] = Field(description="리뷰의 핵심 포인트. 소문자, 각 1-3 단어.")

agent = create_agent(
    model="openai:gpt-5",
    tools=tools,
    response_format=ToolStrategy(ProductReview)
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "Analyze this review: 'Great product: 5 out of 5 stars. Fast shipping, but expensive'"}]
})
result["structured_response"]
# ProductReview(rating=5, sentiment='positive', key_points=['fast shipping', 'expensive'])

Custom tool message content

tool_message_content 매개변수를 사용하면 구조화된 출력이 생성될 때 대화 기록에 나타나는 메시지를 커스터마이즈할 수 있습니다:
from pydantic import BaseModel, Field
from typing import Literal
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy


class MeetingAction(BaseModel):
    """회의록에서 추출한 액션 아이템입니다."""
    task: str = Field(description="완료해야 할 구체적인 작업")
    assignee: str = Field(description="작업 담당자")
    priority: Literal["low", "medium", "high"] = Field(description="우선순위 레벨")

agent = create_agent(
    model="openai:gpt-5",
    tools=[],
    response_format=ToolStrategy(
        schema=MeetingAction,
        tool_message_content="액션 아이템이 캡처되어 회의록에 추가되었습니다!"
    )
)

agent.invoke({
    "messages": [{"role": "user", "content": "From our meeting: Sarah needs to update the project timeline as soon as possible"}]
})
================================ Human Message =================================

From our meeting: Sarah needs to update the project timeline as soon as possible
================================== Ai Message ==================================
Tool Calls:
  MeetingAction (call_1)
 Call ID: call_1
  Args:
    task: Update the project timeline
    assignee: Sarah
    priority: high
================================= Tool Message =================================
Name: MeetingAction

액션 아이템이 캡처되어 회의록에 추가되었습니다!
tool_message_content 없이는 최종 ToolMessage가 다음과 같이 표시됩니다:
================================= Tool Message =================================
Name: MeetingAction

Returning structured response: {'task': 'update the project timeline', 'assignee': 'Sarah', 'priority': 'high'}

Error handling

모델은 도구 호출을 통해 구조화된 출력을 생성할 때 실수를 할 수 있습니다. LangChain은 이러한 오류를 자동으로 처리하기 위한 지능형 재시도 메커니즘을 제공합니다.

Multiple structured outputs error

모델이 여러 구조화된 출력 도구를 잘못 호출하면, 에이전트는 ToolMessage에 오류 피드백을 제공하고 모델에 재시도를 요청합니다:
from pydantic import BaseModel, Field
from typing import Union
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy


class ContactInfo(BaseModel):
    name: str = Field(description="사람의 이름")
    email: str = Field(description="이메일 주소")

class EventDetails(BaseModel):
    event_name: str = Field(description="이벤트 이름")
    date: str = Field(description="이벤트 날짜")

agent = create_agent(
    model="openai:gpt-5",
    tools=[],
    response_format=ToolStrategy(Union[ContactInfo, EventDetails])  # 기본값: handle_errors=True
)

agent.invoke({
    "messages": [{"role": "user", "content": "Extract info: John Doe ([email protected]) is organizing Tech Conference on March 15th"}]
})
================================ Human Message =================================

Extract info: John Doe ([email protected]) is organizing Tech Conference on March 15th
None
================================== Ai Message ==================================
Tool Calls:
  ContactInfo (call_1)
 Call ID: call_1
  Args:
    name: John Doe
    email: [email protected]
  EventDetails (call_2)
 Call ID: call_2
  Args:
    event_name: Tech Conference
    date: March 15th
================================= Tool Message =================================
Name: ContactInfo

Error: Model incorrectly returned multiple structured responses (ContactInfo, EventDetails) when only one is expected.
 Please fix your mistakes.
================================= Tool Message =================================
Name: EventDetails

Error: Model incorrectly returned multiple structured responses (ContactInfo, EventDetails) when only one is expected.
 Please fix your mistakes.
================================== Ai Message ==================================
Tool Calls:
  ContactInfo (call_3)
 Call ID: call_3
  Args:
    name: John Doe
    email: [email protected]
================================= Tool Message =================================
Name: ContactInfo

Returning structured response: {'name': 'John Doe', 'email': '[email protected]'}

Schema validation error

구조화된 출력이 예상 스키마와 일치하지 않으면, 에이전트가 구체적인 오류 피드백을 제공합니다:
from pydantic import BaseModel, Field
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy


class ProductRating(BaseModel):
    rating: int | None = Field(description="1-5 사이의 평점", ge=1, le=5)
    comment: str = Field(description="리뷰 코멘트")

agent = create_agent(
    model="openai:gpt-5",
    tools=[],
    response_format=ToolStrategy(ProductRating),  # 기본값: handle_errors=True
    system_prompt="You are a helpful assistant that parses product reviews. Do not make any field or value up."
)

agent.invoke({
    "messages": [{"role": "user", "content": "Parse this: Amazing product, 10/10!"}]
})
================================ Human Message =================================

Parse this: Amazing product, 10/10!
================================== Ai Message ==================================
Tool Calls:
  ProductRating (call_1)
 Call ID: call_1
  Args:
    rating: 10
    comment: Amazing product
================================= Tool Message =================================
Name: ProductRating

Error: Failed to parse structured output for tool 'ProductRating': 1 validation error for ProductRating.rating
  Input should be less than or equal to 5 [type=less_than_equal, input_value=10, input_type=int].
 Please fix your mistakes.
================================== Ai Message ==================================
Tool Calls:
  ProductRating (call_2)
 Call ID: call_2
  Args:
    rating: 5
    comment: Amazing product
================================= Tool Message =================================
Name: ProductRating

Returning structured response: {'rating': 5, 'comment': 'Amazing product'}

Error handling strategies

handle_errors 매개변수를 사용하여 오류 처리 방식을 커스터마이즈할 수 있습니다: 커스텀 오류 메시지:
ToolStrategy(
    schema=ProductRating,
    handle_errors="1-5 사이의 유효한 평점과 코멘트를 제공해주세요."
)
handle_errors가 문자열인 경우, 에이전트는 항상 고정된 도구 메시지로 모델에 재시도를 요청합니다:
================================= Tool Message =================================
Name: ProductRating

1-5 사이의 유효한 평점과 코멘트를 제공해주세요.
특정 예외만 처리:
ToolStrategy(
    schema=ProductRating,
    handle_errors=ValueError  # ValueError에서만 재시도, 나머지는 raise
)
handle_errors가 예외 타입인 경우, 발생한 예외가 지정된 타입인 경우에만 에이전트가 재시도합니다(기본 오류 메시지 사용). 다른 모든 경우에는 예외가 발생합니다. 여러 예외 타입 처리:
ToolStrategy(
    schema=ProductRating,
    handle_errors=(ValueError, TypeError)  # ValueError와 TypeError에서 재시도
)
handle_errors가 예외 튜플인 경우, 발생한 예외가 지정된 타입 중 하나인 경우에만 에이전트가 재시도합니다(기본 오류 메시지 사용). 다른 모든 경우에는 예외가 발생합니다. 커스텀 오류 핸들러 함수:
def custom_error_handler(error: Exception) -> str:
    if isinstance(error, StructuredOutputValidationError):
        return "형식에 문제가 있습니다. 다시 시도해주세요."
    elif isinstance(error, MultipleStructuredOutputsError):
        return "여러 구조화된 출력이 반환되었습니다. 가장 관련성 높은 것을 선택하세요."
    else:
        return f"오류: {str(error)}"

ToolStrategy(
    schema=ToolStrategy(Union[ContactInfo, EventDetails]),
    handle_errors=custom_error_handler
)
StructuredOutputValidationError 발생 시:
================================= Tool Message =================================
Name: ToolStrategy

형식에 문제가 있습니다. 다시 시도해주세요.
MultipleStructuredOutputsError 발생 시:
================================= Tool Message =================================
Name: ToolStrategy

여러 구조화된 출력이 반환되었습니다. 가장 관련성 높은 것을 선택하세요.
기타 오류 발생 시:
================================= Tool Message =================================
Name: ToolStrategy

오류: <error message>
오류 처리 없음:
response_format = ToolStrategy(
    schema=ProductRating,
    handle_errors=False  # 모든 오류 발생
)

Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.
I