输出解析
在 LangChain 中,输出解析(Output Parsing)已通过 create_agent 的 response_format 参数得到原生支持。你不再需要手动编写解析逻辑——只需定义期望的输出结构,Agent 会自动返回符合格式的数据。
response_format 参数
response_format 是 create_agent 的核心参数,用于指定 Agent 输出的结构化格式:
python
from pydantic import BaseModel
from langchain import create_agent
from langchain.chat_models import init_chat_model
from langchain.tools import tool
# 定义输出结构
class WeatherResponse(BaseModel):
city: str
temperature: float
condition: str
humidity: int
@tool
def get_weather_data(city: str) -> str:
"""获取天气数据。"""
return f"北京,25.5,晴朗,40"
agent = create_agent(
model=init_chat_model("openai/gpt-4o"),
tools=[get_weather_data],
system_prompt="查询天气并以结构化格式返回。",
response_format=WeatherResponse,
)
result = agent.invoke({
"messages": [{"role": "user", "content": "北京今天的天气如何?"}]
})
# result 是 WeatherResponse 实例
print(f"城市:{result.city}")
print(f"温度:{result.temperature}°C")
print(f"天气:{result.condition}")支持的输出格式
Pydantic BaseModel(推荐)
使用 Pydantic v2 模型定义结构化输出:
python
from pydantic import BaseModel, Field
from typing import Optional
class Recipe(BaseModel):
"""食谱信息"""
name: str = Field(description="菜品名称")
ingredients: list[str] = Field(description="食材列表")
steps: list[str] = Field(description="烹饪步骤")
cooking_time_minutes: Optional[int] = Field(description="烹饪时间(分钟)", default=None)
difficulty: str = Field(description="难度:简单/中等/困难")
agent = create_agent(
model=init_chat_model("openai/gpt-4o"),
tools=[],
system_prompt="根据用户描述的菜品生成食谱。",
response_format=Recipe,
)
result = agent.invoke({
"messages": [{"role": "user", "content": "怎么做番茄炒蛋?"}]
})
# result 是 Recipe 实例
print(result.name) # "番茄炒蛋"
print(result.ingredients) # ["番茄", "鸡蛋", ...]JSON Schema
直接使用 JSON Schema 定义输出格式:
python
schema = {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "文章摘要,不超过 200 字"
},
"keywords": {
"type": "array",
"items": {"type": "string"},
"description": "关键词列表"
},
"sentiment": {
"type": "string",
"enum": ["正面", "负面", "中性"],
"description": "情感倾向"
}
},
"required": ["summary", "keywords", "sentiment"]
}
agent = create_agent(
model=init_chat_model("openai/gpt-4o"),
tools=[],
system_prompt="分析用户提供的文本。",
response_format=schema,
)
result = agent.invoke({
"messages": [{"role": "user", "content": "今天天气真好,适合出去玩!"}]
})
# result 是 dict
print(result["summary"]) # "用户表达了愉快的情绪..."
print(result["sentiment"]) # "正面"TypedDict
使用 Python 标准库的 TypedDict:
python
from typing import TypedDict, Optional
class MovieInfo(TypedDict):
title: str
year: int
director: str
rating: Optional[float]
genres: list[str]
agent = create_agent(
model=init_chat_model("openai/gpt-4o"),
tools=[],
system_prompt="根据用户描述返回电影信息。",
response_format=MovieInfo,
)
result = agent.invoke({
"messages": [{"role": "user", "content": "推荐一部诺兰导演的电影"}]
})
# result 是 dict
print(result["title"]) # "盗梦空间"dataclass
使用 Python dataclass:
python
from dataclasses import dataclass, field
@dataclass
class SearchResult:
query: str
count: int
results: list[str] = field(default_factory=list)
agent = create_agent(
model=init_chat_model("openai/gpt-4o"),
tools=[],
system_prompt="生成搜索结果。",
response_format=SearchResult,
)
result = agent.invoke({
"messages": [{"role": "user", "content": "搜索 Python 教程"}]
})
# result 是 SearchResult 实例(或匹配的 dict)response_format 的输入格式
response_format 参数接受多种输入格式并自动处理:
| 输入类型 | 自动处理 |
|---|---|
Type[BaseModel] | 自动提取 schema,返回 Pydantic 实例 |
TypedDict 类 | 转换为 JSON Schema,返回 dict |
dict | 直接作为 JSON Schema 使用,返回 dict |
dataclass 类 | 自动提取字段定义,返回 dataclass 实例 |
自定义验证
Pydantic 模型支持内置验证逻辑:
python
from pydantic import BaseModel, Field, field_validator
class AnalysisResult(BaseModel):
score: int = Field(description="评分 1-10")
feedback: str = Field(description="反馈意见")
@field_validator("score")
@classmethod
def validate_score(cls, v):
if not 1 <= v <= 10:
raise ValueError("评分必须在 1-10 之间")
return v
agent = create_agent(
model=init_chat_model("openai/gpt-4o"),
tools=[],
system_prompt="分析用户的问题并评分。",
response_format=AnalysisResult,
)不使用 Agent 时的输出解析
如果你需要在不使用 create_agent 的情况下解析输出,也可以直接使用模型的结构化输出能力:
python
from langchain.chat_models import init_chat_model
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: int
occupation: str
model = init_chat_model("openai/gpt-4o")
# 直接使用模型的 with_structured_output
structured_model = model.with_structured_output(Person)
result = structured_model.invoke("介绍一位叫张三的人,30岁,工程师")
print(result.name) # "张三"错误处理
python
from pydantic import ValidationError
try:
result = agent.invoke({
"messages": [{"role": "user", "content": "分析这段文本"}]
})
except ValidationError as e:
print(f"输出格式验证失败:{e}")
# 可以在这里回退到无结构输出,或请求重新生成最佳实践
- 使用
Field(description=...)为每个字段添加描述,提高模型理解准确度 - 字段名使用有意义的英文名,避免特殊字符
- 适当设置
required字段,区分必填和可选 - 使用枚举类型约束取值范围,如
enum=["简单", "中等", "困难"] - 通过 Pydantic 验证器添加业务规则验证
- 对复杂嵌套结构使用嵌套 Pydantic 模型