Skip to content

输出解析

在 LangChain 中,输出解析(Output Parsing)已通过 create_agentresponse_format 参数得到原生支持。你不再需要手动编写解析逻辑——只需定义期望的输出结构,Agent 会自动返回符合格式的数据。

response_format 参数

response_formatcreate_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}")
    # 可以在这里回退到无结构输出,或请求重新生成

最佳实践

  1. 使用 Field(description=...) 为每个字段添加描述,提高模型理解准确度
  2. 字段名使用有意义的英文名,避免特殊字符
  3. 适当设置 required 字段,区分必填和可选
  4. 使用枚举类型约束取值范围,如 enum=["简单", "中等", "困难"]
  5. 通过 Pydantic 验证器添加业务规则验证
  6. 对复杂嵌套结构使用嵌套 Pydantic 模型

下一步

本站为非官方中文学习站点,不代表 LangChain 官方。部分内容参考官方文档并重新整理为中文学习笔记。