LangChain1.0智能体开发:结构化输出

阅读本文您将获得:

  • LangChain如何控制智能体最终的格式化输出?
  • 格式化输出的模型提供商原生策略
  • 格式化输出的工具调用策略
  • 格式化输出的工具调用错误处理

结构化输出能让智能体以特定、可预测的格式返回数据。无需解析自然语言响应,你就能直接获取JSON对象、Pydantic模型或数据类(dataclasses)形式的结构化数据,供应用程序直接使用。LangChain的create_agent接口会自动处理结构化输出。用户只需设置所需的结构化输出模式(schema),当模型生成结构化数据后,该数据会被捕获、验证,并最终在智能体状态的structured_response键中返回。

1、响应格式

控制智能体返回结构化数据的方式在创建智能体时给create_agent接口传递response_format参数,参数赋值类型如下:

  • ToolStrategy[StructuredResponseT]:使用工具调用获取结构化输出
  • ProviderStrategy[StructuredResponseT]:使用提供商原生的结构化输出
  • type[StructuredResponseT]:Schema类型 ------ 根据模型能力自动选择最佳策略
  • None:无结构化输出

当直接提供Schema类型时,LangChain会自动选择:

  • 对于支持原生结构化输出的模型(如OpenAI、Grok),使用ProviderStrategy;
  • 对于其他所有模型,使用ToolStrategy;

结构化响应会在智能体最终状态的structured_response键中返回。

2、ProviderStrategy(提供商原生策略)

部分模型提供商可通过其API原生支持结构化输出(目前仅支持 OpenAI 和 Grok)。在支持该功能的情况下,这是最可靠的方法。 若要使用此策略,可以给create_agent.response_format配置一个ProviderStrategy; 也可以将Schema类型直接传递给create_agent.response_format,且所用模型支持原生结构化输出时,LangChain会自动使用ProviderStrategy。

python 复制代码
class ProviderStrategy(Generic[SchemaT]):
    schema: type[SchemaT]

使用示例:

python 复制代码
from pydantic import BaseModel
from langchain.agents import create_agent


class 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="gpt-5",
    tools=tools,
    response_format=ContactInfo  # Auto-selects ProviderStrategy
)

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

result["structured_response"]
# ContactInfo(name='John Doe', email='john@example.com', phone='(555) 123-4567')

提供商原生结构化输出具有高可靠性和严格的验证能力,这是因为模型提供商会对schema进行强制约束。在支持该功能的情况下,建议使用此方式。

3、ToolStrategy(工具调用策略)

对于不支持原生结构化输出的模型,LangChain会通过工具调用来实现相同的效果。该方式适用于所有支持工具调用的模型,大多数现代模型均具备这一能力。 若要使用此策略,需要给create_agent.response_format配置一个ToolStrategy; 也可以将Schema类型直接传递给create_agent.response_format,且所用模型不支持原生结构化输出时,LangChain会自动使用ToolStrategy。

python 复制代码
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],
    ]

使用示例:

python 复制代码
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):
    """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="gpt-5",
    tools=[],
    response_format=ToolStrategy(
        schema=MeetingAction,
        tool_message_content="Action item captured and added to meeting notes!" #可选项,输出ToolMessage的内容
    )
)

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

result["structured_response"]
# MeetingAction(task='Update project timeline', assignee='Sarah', priority='high')

3.1 错误处理

模型在通过工具调用生成结构化输出时可能会出现错误。LangChain提供了智能重试机制,可自动处理这些错误。

3.1.1 多结构化输出工具错误

当模型错误地调用多个结构化输出工具时,智能体会在ToolMessage中提供错误反馈,并提示模型进行重试,可自动处理这些错误。

python 复制代码
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="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="gpt-5",
    tools=[],
    response_format=ToolStrategy(Union[ContactInfo, EventDetails])  # Default: handle_errors=True
)

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

3.1.2 Schema验证错误

当结构化输出与预期Schema不匹配时,智能体会提供具体的错误反馈,并提示模型进行重试,可自动处理这些错误。

python 复制代码
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="Rating from 1-5", ge=1, le=5)
    comment: str = Field(description="Review comment")

agent = create_agent(
    model="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!"}]
})

3.1.3 自定义错误处理策略

可以通过handle_errors参数自定义错误的处理方式:

  • True:默认值,捕获所有错误,使用默认错误模板,自动重试
  • str(字符串):捕获所有错误,使用此自定义消息,自动重试
  • type[Exception](异常类型):仅捕获该类型异常并重试,使用默认消息;其它类型错误则直接报错退出
  • tuple(type[Exception], ...)(异常类型元组):仅捕获这些类型异常,使用默认消息
  • Callable[[Exception], str](可调用对象):自定义函数,返回错误消息
  • False:不重试,让异常继续传播

示例(handle_errors传入可调用对象):

python 复制代码
# 自定义函数处理错误
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
)
相关推荐
Akamai中国15 小时前
基准测试:Akamai云上的NVIDIA RTX Pro 6000 Blackwell
人工智能·云计算·云服务·云存储
雨大王51215 小时前
汽车AI智能体矩阵:驱动行业智能化变革的新范式
人工智能·汽车
SmartRadio16 小时前
在CH585M代码中如何精细化配置PMU(电源管理单元)和RAM保留
linux·c语言·开发语言·人工智能·单片机·嵌入式硬件·lora
旦莫16 小时前
Pytest教程:Pytest与主流测试框架对比
人工智能·python·pytest
●VON16 小时前
从模型到价值:MLOps 工程体系全景解析
人工智能·学习·制造·von
XiaoYu200216 小时前
第11章 LangChain
前端·javascript·langchain
智慧地球(AI·Earth)16 小时前
Codex配置问题解析:wire_api格式不匹配导致的“Reconnecting...”循环
开发语言·人工智能·vscode·codex·claude code
GISer_Jing16 小时前
AI:多智能体协作与记忆管理
人工智能·设计模式·aigc
qq_4112624216 小时前
纯图像传感器(只出像素),还是 Himax WiseEye/WE1/WE-I Plus 这类带处理器、能在端侧跑模型并输出“metadata”的模块
人工智能·嵌入式硬件·esp32·四博智联
InfiSight智睿视界16 小时前
门店智能体技术如何破解美容美发连锁的“标准执行困境”
大数据·运维·人工智能