Structured output을 사용하면 agent가 특정하고 예측 가능한 형식으로 데이터를 반환할 수 있습니다. 자연어 응답을 파싱하는 대신, 애플리케이션에서 직접 사용할 수 있는 JSON 객체, Pydantic model 또는 dataclass 형태의 구조화된 데이터를 얻을 수 있습니다.LangChain의 create_agent는 structured output을 자동으로 처리합니다. 사용자가 원하는 structured output schema를 설정하면, model이 구조화된 데이터를 생성할 때 이를 캡처하고 검증하여 agent state의 'structured_response' key에 반환합니다.
LangChain은 schema type을 create_agent.response_format에 직접 전달하고 model이 네이티브 structured output을 지원하는 경우 자동으로 ProviderStrategy를 사용합니다:
Copy
from pydantic import BaseModelfrom langchain.agents import create_agentclass ContactInfo(BaseModel): """Contact information for a person.""" name: str = Field(description="The name of the person") email: str = Field(description="The email address of the person") phone: str = Field(description="The phone number of the person")agent = create_agent( model="openai:gpt-5", tools=tools, response_format=ContactInfo # Auto-selects 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')
Provider 네이티브 structured output은 model provider가 schema를 강제하기 때문에 높은 신뢰성과 엄격한 검증을 제공합니다. 사용 가능한 경우 이를 사용하세요.
Provider가 선택한 model에 대해 네이티브로 structured output을 지원하는 경우, response_format=ToolStrategy(ProductReview) 대신 response_format=ProductReview로 작성하는 것이 기능적으로 동일합니다. 어느 경우든 structured output이 지원되지 않으면 agent는 tool calling 전략으로 대체됩니다.
네이티브 structured output을 지원하지 않는 model의 경우, LangChain은 tool calling을 사용하여 동일한 결과를 달성합니다. 이는 tool calling을 지원하는 모든 model에서 작동하며, 대부분의 최신 model이 이에 해당합니다.이 전략을 사용하려면 ToolStrategy를 구성하세요:
tool_message_content 매개변수를 사용하면 structured output이 생성될 때 대화 기록에 나타나는 메시지를 사용자 정의할 수 있습니다:
Copy
from pydantic import BaseModel, Fieldfrom typing import Literalfrom langchain.agents import create_agentfrom langchain.agents.structured_output import ToolStrategyclass MeetingAction(BaseModel): """Action items extracted from a meeting transcript.""" task: str = Field(description="The specific task to be completed") assignee: str = Field(description="Person responsible for the task") priority: Literal["low", "medium", "high"] = Field(description="Priority level")agent = create_agent( model="openai:gpt-5", tools=[], response_format=ToolStrategy( schema=MeetingAction, tool_message_content="Action item captured and added to meeting notes!" ))agent.invoke({ "messages": [{"role": "user", "content": "From our meeting: Sarah needs to update the project timeline as soon as possible"}]})
Copy
================================ 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: MeetingActionAction item captured and added to meeting notes!
tool_message_content 없이는 최종 ToolMessage가 다음과 같이 표시됩니다:
Model이 여러 structured output tool을 잘못 호출하면, agent는 ToolMessage에 오류 피드백을 제공하고 model에 재시도를 요청합니다:
Copy
from pydantic import BaseModel, Fieldfrom typing import Unionfrom langchain.agents import create_agentfrom langchain.agents.structured_output import ToolStrategyclass ContactInfo(BaseModel): name: str = Field(description="Person's name") email: str = Field(description="Email address")class EventDetails(BaseModel): event_name: str = Field(description="Name of the event") date: str = Field(description="Event date")agent = create_agent( model="openai:gpt-5", tools=[], response_format=ToolStrategy(Union[ContactInfo, EventDetails]) # Default: handle_errors=True)agent.invoke({ "messages": [{"role": "user", "content": "Extract info: John Doe ([email protected]) is organizing Tech Conference on March 15th"}]})
Copy
================================ Human Message =================================Extract info: John Doe ([email protected]) is organizing Tech Conference on March 15thNone================================== 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: ContactInfoError: Model incorrectly returned multiple structured responses (ContactInfo, EventDetails) when only one is expected. Please fix your mistakes.================================= Tool Message =================================Name: EventDetailsError: 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: ContactInfoReturning structured response: {'name': 'John Doe', 'email': '[email protected]'}
Structured output이 예상 schema와 일치하지 않으면, agent는 구체적인 오류 피드백을 제공합니다:
Copy
from pydantic import BaseModel, Fieldfrom langchain.agents import create_agentfrom langchain.agents.structured_output import ToolStrategyclass ProductRating(BaseModel): rating: int | None = Field(description="Rating from 1-5", ge=1, le=5) comment: str = Field(description="Review comment")agent = create_agent( model="openai:gpt-5", tools=[], response_format=ToolStrategy(ProductRating), # Default: 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!"}]})
Copy
================================ 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: ProductRatingError: 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: ProductRatingReturning structured response: {'rating': 5, 'comment': 'Amazing product'}
handle_errors 매개변수를 사용하여 오류 처리 방식을 사용자 정의할 수 있습니다:사용자 정의 오류 메시지:
Copy
ToolStrategy( schema=ProductRating, handle_errors="Please provide a valid rating between 1-5 and include a comment.")
handle_errors가 문자열인 경우, agent는 고정된 tool message로 항상 model에 재시도를 요청합니다:
Copy
================================= Tool Message =================================Name: ProductRatingPlease provide a valid rating between 1-5 and include a comment.
특정 예외만 처리:
Copy
ToolStrategy( schema=ProductRating, handle_errors=ValueError # Only retry on ValueError, raise others)
handle_errors가 예외 타입인 경우, agent는 발생한 예외가 지정된 타입인 경우에만 재시도합니다(기본 오류 메시지 사용). 다른 모든 경우에는 예외가 발생합니다.여러 예외 타입 처리:
Copy
ToolStrategy( schema=ProductRating, handle_errors=(ValueError, TypeError) # Retry on ValueError and TypeError)
handle_errors가 예외 튜플인 경우, agent는 발생한 예외가 지정된 타입 중 하나인 경우에만 재시도합니다(기본 오류 메시지 사용). 다른 모든 경우에는 예외가 발생합니다.사용자 정의 오류 핸들러 함수:
Copy
def custom_error_handler(error: Exception) -> str: if isinstance(error, StructuredOutputValidationError): return "There was an issue with the format. Try again. elif isinstance(error, MultipleStructuredOutputsError): return "Multiple structured outputs were returned. Pick the most relevant one." else: return f"Error: {str(error)}"ToolStrategy( schema=ToolStrategy(Union[ContactInfo, EventDetails]), handle_errors=custom_error_handler)
StructuredOutputValidationError의 경우:
Copy
================================= Tool Message =================================Name: ToolStrategyThere was an issue with the format. Try again.
MultipleStructuredOutputsError의 경우:
Copy
================================= Tool Message =================================Name: ToolStrategyMultiple structured outputs were returned. Pick the most relevant one.