你需要在 invoke() 调用中添加 response_format 参数,让LLM返回符合你的JSON结构的结构化输出。
这样可以确保LLM始终返回有效的JSON,而不需要手动解析和验证。
from pydantic import BaseModel, Field
from typing import Literal
import json
# 定义结构化输出schema
class ChartAnalysis(BaseModel):
thoughts: str = Field(description="分析总结数据,说明为什么选择这种图表类型")
type: Literal["line", "column", "pie", "area", "bar", "histogram", "scatter", "table"] = Field(
description="根据用户的问题和查询结果,选择最合适的统计图类型"
)
result: dict = Field(description="根据选择的type,将SQL查询结果转换为对应type的data_format格式")
# 修改invoke调用
response = self._llm_client.with_structured_output(ChartAnalysis).invoke(
[system_message] + state["messages"]
)
# response现在是ChartAnalysis实例,可以直接访问属性
print(response.thoughts)
print(response.type)
print(response.result)
如果你使用 create_agent
如果在Agent中使用,传递 response_format 参数:
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy
agent = create_agent(
model=self._llm_client,
tools=[],
response_format=ToolStrategy(ChartAnalysis),
system_prompt=generate_query_system_prompt
)
result = await agent.invoke({
"messages": state["messages"]
})
chart_analysis = result["structured_response"]
print(chart_analysis.type) # "line", "column", 等
print(chart_analysis.result) # 图表数据
核心优势
自动验证 - LLM被迫返回有效的JSON,符合你的schema
类型安全 - 直接访问属性,IDE自动完成
错误处理 - 模型出错时会自动重试
无需手动解析 - 不用 json.loads() 和 try/except
更灵活的 result 字段
如果 result 的结构取决于 type 值,使用 Union:
from typing import Union
class LineChart(BaseModel):
x_axis: list[str]
y_axis: list[float]
class PieChart(BaseModel):
labels: list[str]
values: list[float]
class ChartAnalysis(BaseModel):
thoughts: str
type: Literal["line", "pie"]
result: Union[LineChart, PieChart] = Field(
description="根据type返回对应的图表数据结构"
)
这样LLM会根据 type 自动返回正确的 result 结构。
相关文档:

1702

被折叠的 条评论
为什么被折叠?



