Langchain简单快速上手教程(四)——聊天模型之结构化输出
@
前言
本期我将要介绍LangChain 中聊天模型的另一功能结构化输出。这将原来大模型输出的AIMessage变成以例如Json等格式化输出,以适应特定的开发场景。
一、with_structured_output() 方法
要想使用结构化输出能力,LangChain提供了一种方法.with_structured_output() 。该方法需要先定义输出结构,然后执行通过 .with_structured_output() 得到Runnable 实例。
(一)返回 Pydantic 对象
我们可以设置执行Runnable 后的输出结果指定为 Pydantic 类,这将返回一个 Pydantic 对象。当收到模型的响应后,LangChain 会提取出代表 Pydantic 参数的 JSON 对象,并用 Pydantic 模型对其进行解析和验证,将这个验证后的 JSON 转换为⼀个可用的 Pydantic 对象实例返回。
# 结构化返回 Pydantic
model = ChatDeepSeek(model='deepseek-v4-flash')
class Joke(BaseModel):
"""给用户讲的一个笑话"""
setup:str = Field(description="笑话的开头")
punchline: str = Field(description='笑话的妙语')
rating: Optional[int] = Field(default=None,description="从1-10分,给这个笑话评分")
class Data(BaseModel):
"""获取关于笑话的数据列表"""
jokes: List[Joke]
# print(model.invoke("讲一个关于薛定谔的猫的笑话").content)
model_with_structured = model.with_structured_output(Data)
print(model_with_structured.invoke("讲一个关于薛定谔的猫的笑话"))
(二)返回 TypedDict
TypedDict 主要用于为字典对象提供精确的、结构化的类型提示。它允许我们指定字典中应该有哪些键,以及每个键对应的值的类型。它其中一个重要的能力就是捕捉键名拼写错误与类型错误。
因此我们也可以设置执行Runnable 后的输出结果指定为 TypedDict 类,这将就会返回一个字典,且输出后,会根据设定进行验证。
model = ChatDeepSeek(model='deepseek-v4-flash')
# 结构化返回 TypedDict
class Joke(TypedDict):
"""给用户讲的一个笑话"""
setup:str = Field(description="笑话的开头")
punchline: str = Field(description='笑话的妙语')
rating: Optional[int] = Field(description="从1-10分,给这个笑话评分")
model_with_structured = model.with_structured_output(Joke,include_raw=True)
print(model_with_structured.invoke("讲一个关于薛定谔的猫的笑话"))
(三)返回 JSON
为了声明 JSON,我们同时需要定义 JSON Schema。
model = ChatDeepSeek(model='deepseek-v4-flash')
# 结构化返回 JSON Schema
json_schema = {
"title": "joke",
"description": "给用户讲一个笑话。",
"type": "object",
"properties": {
"setup": {
"type": "string",
"description": "这个笑话的开头",
},
"punchline": {
"type": "string",
"description": "这个笑话的妙语",
},
"rating": {
"type": "integer",
"description": "从1到10分,给这个笑话评分",
"default": None,
},
},
"required": ["setup", "punchline"],
}
model_with_structured = model.with_structured_output(json_schema)
print(model_with_structured.invoke("讲一个关于薛定谔的猫的笑话"))
(四)选择输出格式
创建具有联合类型属性的父模式。
model = ChatDeepSeek(model='deepseek-v4-flash')
class Joke(BaseModel):
"""给用户讲的一个笑话"""
setup: str = Field(description="这个笑话的开头")
punchline: str = Field(description="这个笑话的妙语")
rating: Optional[int] = Field(default=None, description="从1-10分,给这个笑话评分")
class Response(BaseModel):
"""以对话的方式回应"""
content: str = Field(description="用于对用户查询的会话响应")
class FinalResponse(BaseModel):
"""最终回复,选择合适的输出结构"""
final_output: Union[Joke, Response]
model_with_structured = model.with_structured_output(FinalResponse)
print(model_with_structured.invoke("讲一个关于薛定谔的猫的笑话"))
print(model_with_structured.invoke("你是谁?"))
二、实用案例
(一)信息提取
model = ChatDeepSeek(model='deepseek-v4-flash')
# 结构化输出常见使用场景:信息提取
class Person(BaseModel):
"""一个人的信息。"""
# 注意:
# 1. 每个字段都是 Optional “可选的” —— 允许 LLM 在不知道答案时输出 None。
# 2. 每个字段都有一个 description “描述” —— LLM使用这个描述。
# 有一个好的描述可以帮助提高提取结果。
name: Optional[str] = Field(default=None, description="这个人的名字")
hair_color: Optional[str] = Field(default=None, description="如果知道这个人头发的颜色")
skin_color: Optional[str] = Field(default=None, description="如果知道这个人的肤色")
height_in_meters: Optional[str] = Field(default=None, description="以米为单位的高度")
structured_model = model.with_structured_output(schema=Person)
messages = [
SystemMessage(content="你是一个提取信息的专家,只从文本中提取相关信息。如果您不知道要提取的属性的值,属性值返回null"),
HumanMessage(content="史密斯身高6英尺,金发。")
]
result = structured_model.invoke(messages)
print(result)
(二)与工具结合使用
model = ChatOpenAI(
model='deepseek-v4-flash',
api_key=os.environ.get('DEEPSEEK_API_KEY'),
base_url="https://api.deepseek.com",
)
# 结构化输出常见使用场景:与工具结合使用
tool = TavilySearch(max_results=4)
model_with_tools = model.bind_tools([tool])
messages = [
HumanMessage("北京今天的天气怎么样?")
]
ai_message = model_with_tools.invoke(messages)
messages.append(ai_message)
for tool_call in ai_message.tool_calls:
tool_message = tool.invoke(tool_call)
messages.append(tool_message)
class SearchResult(BaseModel):
"""结构化搜索对象"""
query: str = Field(description="搜索查询")
findings: str = Field(description="查询结果摘要")
model_with_structured = model_with_tools.with_structured_output(SearchResult)
print(model_with_structured.invoke(messages))
与工具相结合的方式下,它并不能直接帮我们输出想要的SearchResult搜索结果,而是只返回了AIMessage。所以with_structured_output 方法只是让模型知道有哪些工具可以调用,但是并不会自动执行工具。要获得工具执行后的结果并整合到最终的结构化输出中,我们需要手动执行。
结语
以上便是Langchain中如何使用聊天模型的格式化输出的内容了。如果喜欢我的内容,请点赞、收藏加关注,多多支持我,以及欢迎各位在评论区讨论交流,并指出我的不足,谢谢大家。

我们主要介绍了介绍 LangChain 聊天模型的结构化输出功能。通过 `with_structured_output()` 方法,可将模型输出的 AIMessage 转换为 Pydantic 对象、TypedDict 或 JSON 等格式化结果,并支持联合类型灵活选择输出格式。文中结合信息提取、与工具结合使用等实用案例,帮助开发者快速掌握结构化输出的应用方法。
浙公网安备 33010602011771号