Source code for langchain_core.output_parsers.json
from__future__importannotationsimportjsonfromjsonimportJSONDecodeErrorfromtypingimportAnnotated,Any,Optional,TypeVar,Unionimportjsonpatch# type: ignore[import]importpydanticfrompydanticimportSkipValidationfromlangchain_core.exceptionsimportOutputParserExceptionfromlangchain_core.output_parsers.format_instructionsimportJSON_FORMAT_INSTRUCTIONSfromlangchain_core.output_parsers.transformimportBaseCumulativeTransformOutputParserfromlangchain_core.outputsimportGenerationfromlangchain_core.utils.jsonimport(parse_and_check_json_markdown,parse_json_markdown,parse_partial_json,)fromlangchain_core.utils.pydanticimportPYDANTIC_MAJOR_VERSIONifPYDANTIC_MAJOR_VERSION<2:PydanticBaseModel=pydantic.BaseModelelse:frompydantic.v1importBaseModel# Union type needs to be last assignment to PydanticBaseModel to make mypy happy.PydanticBaseModel=Union[BaseModel,pydantic.BaseModel]# type: ignoreTBaseModel=TypeVar("TBaseModel",bound=PydanticBaseModel)
[docs]classJsonOutputParser(BaseCumulativeTransformOutputParser[Any]):"""Parse the output of an LLM call to a JSON object. When used in streaming mode, it will yield partial JSON objects containing all the keys that have been returned so far. In streaming, if `diff` is set to `True`, yields JSONPatch operations describing the difference between the previous and the current object. """pydantic_object:Annotated[Optional[type[TBaseModel]],SkipValidation()]=None# type: ignore"""The Pydantic object to use for validation. If None, no validation is performed."""def_diff(self,prev:Optional[Any],next:Any)->Any:returnjsonpatch.make_patch(prev,next).patchdef_get_schema(self,pydantic_object:type[TBaseModel])->dict[str,Any]:ifissubclass(pydantic_object,pydantic.BaseModel):returnpydantic_object.model_json_schema()elifissubclass(pydantic_object,pydantic.v1.BaseModel):returnpydantic_object.schema()
[docs]defparse_result(self,result:list[Generation],*,partial:bool=False)->Any:"""Parse the result of an LLM call to a JSON object. Args: result: The result of the LLM call. partial: Whether to parse partial JSON objects. If True, the output will be a JSON object containing all the keys that have been returned so far. If False, the output will be the full JSON object. Default is False. Returns: The parsed JSON object. Raises: OutputParserException: If the output is not valid JSON. """text=result[0].texttext=text.strip()ifpartial:try:returnparse_json_markdown(text)exceptJSONDecodeError:returnNoneelse:try:returnparse_json_markdown(text)exceptJSONDecodeErrorase:msg=f"Invalid json output: {text}"raiseOutputParserException(msg,llm_output=text)frome
[docs]defparse(self,text:str)->Any:"""Parse the output of an LLM call to a JSON object. Args: text: The output of the LLM call. Returns: The parsed JSON object. """returnself.parse_result([Generation(text=text)])
[docs]defget_format_instructions(self)->str:"""Return the format instructions for the JSON output. Returns: The format instructions for the JSON output. """ifself.pydantic_objectisNone:return"Return a JSON object."else:# Copy schema to avoid altering original Pydantic schema.schema=dict(self._get_schema(self.pydantic_object).items())# Remove extraneous fields.reduced_schema=schemaif"title"inreduced_schema:delreduced_schema["title"]if"type"inreduced_schema:delreduced_schema["type"]# Ensure json in context is well-formed with double quotes.schema_str=json.dumps(reduced_schema,ensure_ascii=False)returnJSON_FORMAT_INSTRUCTIONS.format(schema=schema_str)
# For backwards compatibilitySimpleJsonOutputParser=JsonOutputParserparse_partial_json=parse_partial_jsonparse_and_check_json_markdown=parse_and_check_json_markdown