DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

JsonOutputParser 报 Invalid json output

JsonOutputParser 能处理 JSON 围栏,但仍会遇到非法语法、缺字段或截断内容。区分 JSON 解析、Pydantic 字段验证和流式完成状态。

模型返回一段带 json 代码围栏的文本,JsonOutputParser 却报 Invalid json output。先读完整异常和解析位置:围栏中的内容可能本来就不是合法 JSON,例如字符串值没有双引号:

{"tool_to_use": Document_Search_Tool}

Document_Search_Tool 在这里既不是 JSON 字符串,也不是合法 JSON 常量。改成 "Document_Search_Tool" 才是字符串。仅删掉围栏,里面的语法错误仍然存在。

下面按 langchain-core 0.3.79 与 Pydantic 2 的接口说明。模型、服务商及其结构化输出支持需要按应用实际配置判断。

先分清语法、形状和业务含义

这个版本的 JsonOutputParser 会尝试解析 Markdown 中的 JSON,并包含针对不完整 JSON 的容错逻辑。不能把“出现围栏”本身当成它一定失败的理由;也不能把解析器返回结果当成整段生成内容严格完整的证明。

常见语法错误包括单引号、未加引号的字符串、注释、错误的逗号及未完成的转义。JSON 能解析后,仍可能是一个数组而非预期对象,或者缺字段、字段类型错误。即使字段都合格,工具名或业务值也可能不允许使用。

因此保留受控的原始输出与失败位置,用于区分这几层问题。不要将包含业务数据或密钥的原始输出直接写入公开日志。用正则从第一个 { 截到最后一个 },会在字符串内花括号、多个对象或附加解释的情况下选错内容,不是通用修复。

需要字段验证时,使用对应的解析器

在 0.3.79 中,给 JsonOutputParser 传 pydantic_object 可以生成格式说明,但其解析流程并不自动执行该模型的字段验证。需要 Pydantic 验证,应使用 PydanticOutputParser 或解析后显式验证。

下面是解析已经收到的示例文本,不发送模型请求:

from typing import Literal
from pydantic import BaseModel, ConfigDict
from langchain_core.output_parsers import PydanticOutputParser

class ToolChoice(BaseModel):
    model_config = ConfigDict(extra="forbid", strict=True)
    tool_to_use: Literal["Document_Search_Tool"]
    tool_input: str

parser = PydanticOutputParser(pydantic_object=ToolChoice)
result = parser.parse(
    '{"tool_to_use": "Document_Search_Tool", "tool_input": "检索文档"}'
)

这个模式限制工具名、拒绝额外字段并收紧类型转换。实际业务允许的工具名与字段应改成自己的契约。解析器不能替代工具权限检查,模型生成了一个名称也不表示允许执行它。

格式说明可以通过 parser.get_format_instructions() 取得,再作为提示词变量传入。把说明直接拼到模板源字符串中,可能另引出花括号占位符问题;应把模板渲染与输出解析分开诊断。

流式结果不是完成信号

JsonOutputParser 流式处理中可能输出阶段性的对象,部分字段尚未到达。不要收到第一个可解析片段就执行写操作,也不要把容错补齐后的对象自动当成模型已经完整回答。

若业务要求严格完整 JSON,可在接收端等到生成完成,按已约定的完整 JSON 文本协议用标准 JSON 解码,再验证对象形状和字段;围栏协议应在边界明确处理。Pydantic 字段验证能检查对象,却不能单独证明原始输出没有被容错截取。

模型端支持结构化输出时,按对应模型及集成包的能力配置并检查完成状态。失败可以有限次重新生成或进入人工处理,但应保留失败原因;不要无条件修改引号、删除尾部文本或反复重试直到偶然解析成功。验收除了没有异常,还应覆盖缺字段、错误工具名、额外字段和截断输出等业务本来就要拒绝的情况。