[docs]classCombiningOutputParser(BaseOutputParser[Dict[str,Any]]):"""Combine multiple output parsers into one."""parsers:List[BaseOutputParser]@classmethoddefis_lc_serializable(cls)->bool:returnTrue
[docs]@pre_initdefvalidate_parsers(cls,values:Dict[str,Any])->Dict[str,Any]:"""Validate the parsers."""parsers=values["parsers"]iflen(parsers)<2:raiseValueError("Must have at least two parsers")forparserinparsers:ifparser._type=="combining":raiseValueError("Cannot nest combining parsers")ifparser._type=="list":raiseValueError("Cannot combine list parsers")returnvalues
@propertydef_type(self)->str:"""Return the type key."""return"combining"
[docs]defget_format_instructions(self)->str:"""Instructions on how the LLM output should be formatted."""initial=f"For your first output: {self.parsers[0].get_format_instructions()}"subsequent="\n".join(f"Complete that output fully. Then produce another output, separated by two newline characters: {p.get_format_instructions()}"# noqa: E501forpinself.parsers[1:])returnf"{initial}\n{subsequent}"
[docs]defparse(self,text:str)->Dict[str,Any]:"""Parse the output of an LLM call."""texts=text.split("\n\n")output=dict()fortxt,parserinzip(texts,self.parsers):output.update(parser.parse(txt.strip()))returnoutput