Source code for langchain_core.prompts.few_shot_with_templates
"""Prompt template that contains few shot examples."""frompathlibimportPathfromtypingimportAny,Optional,UnionfrompydanticimportConfigDict,model_validatorfromtyping_extensionsimportSelffromlangchain_core.prompts.promptimportPromptTemplatefromlangchain_core.prompts.stringimport(DEFAULT_FORMATTER_MAPPING,PromptTemplateFormat,StringPromptTemplate,)
[docs]classFewShotPromptWithTemplates(StringPromptTemplate):"""Prompt template that contains few shot examples."""examples:Optional[list[dict]]=None"""Examples to format into the prompt. Either this or example_selector should be provided."""example_selector:Any=None"""ExampleSelector to choose the examples to format into the prompt. Either this or examples should be provided."""example_prompt:PromptTemplate"""PromptTemplate used to format an individual example."""suffix:StringPromptTemplate"""A PromptTemplate to put after the examples."""example_separator:str="\n\n""""String separator used to join the prefix, the examples, and suffix."""prefix:Optional[StringPromptTemplate]=None"""A PromptTemplate to put before the examples."""template_format:PromptTemplateFormat="f-string""""The format of the prompt template. Options are: 'f-string', 'jinja2', 'mustache'."""validate_template:bool=False"""Whether or not to try validating the template."""@classmethoddefget_lc_namespace(cls)->list[str]:"""Get the namespace of the langchain object."""return["langchain","prompts","few_shot_with_templates"]@model_validator(mode="before")@classmethoddefcheck_examples_and_selector(cls,values:dict)->Any:"""Check that one and only one of examples/example_selector are provided."""examples=values.get("examples")example_selector=values.get("example_selector")ifexamplesandexample_selector:msg="Only one of 'examples' and 'example_selector' should be provided"raiseValueError(msg)ifexamplesisNoneandexample_selectorisNone:msg="One of 'examples' and 'example_selector' should be provided"raiseValueError(msg)returnvalues@model_validator(mode="after")deftemplate_is_valid(self)->Self:"""Check that prefix, suffix, and input variables are consistent."""ifself.validate_template:input_variables=self.input_variablesexpected_input_variables=set(self.suffix.input_variables)expected_input_variables|=set(self.partial_variables)ifself.prefixisnotNone:expected_input_variables|=set(self.prefix.input_variables)missing_vars=expected_input_variables.difference(input_variables)ifmissing_vars:msg=(f"Got input_variables={input_variables}, but based on "f"prefix/suffix expected {expected_input_variables}")raiseValueError(msg)else:self.input_variables=sorted(set(self.suffix.input_variables)|set(self.prefix.input_variablesifself.prefixelse[])-set(self.partial_variables))returnselfmodel_config=ConfigDict(arbitrary_types_allowed=True,extra="forbid",)def_get_examples(self,**kwargs:Any)->list[dict]:ifself.examplesisnotNone:returnself.examplesifself.example_selectorisnotNone:returnself.example_selector.select_examples(kwargs)raiseValueErrorasyncdef_aget_examples(self,**kwargs:Any)->list[dict]:ifself.examplesisnotNone:returnself.examplesifself.example_selectorisnotNone:returnawaitself.example_selector.aselect_examples(kwargs)raiseValueError
[docs]defformat(self,**kwargs:Any)->str:"""Format the prompt with the inputs. Args: kwargs: Any arguments to be passed to the prompt template. Returns: A formatted string. Example: .. code-block:: python prompt.format(variable1="foo") """kwargs=self._merge_partial_and_user_variables(**kwargs)# Get the examples to use.examples=self._get_examples(**kwargs)# Format the examples.example_strings=[self.example_prompt.format(**example)forexampleinexamples]# Create the overall prefix.ifself.prefixisNone:prefix=""else:prefix_kwargs={k:vfork,vinkwargs.items()ifkinself.prefix.input_variables}forkinprefix_kwargs:kwargs.pop(k)prefix=self.prefix.format(**prefix_kwargs)# Create the overall suffixsuffix_kwargs={k:vfork,vinkwargs.items()ifkinself.suffix.input_variables}forkinsuffix_kwargs:kwargs.pop(k)suffix=self.suffix.format(**suffix_kwargs,)pieces=[prefix,*example_strings,suffix]template=self.example_separator.join([pieceforpieceinpiecesifpiece])# Format the template with the input variables.returnDEFAULT_FORMATTER_MAPPING[self.template_format](template,**kwargs)
[docs]asyncdefaformat(self,**kwargs:Any)->str:"""Async format the prompt with the inputs. Args: kwargs: Any arguments to be passed to the prompt template. Returns: A formatted string. """kwargs=self._merge_partial_and_user_variables(**kwargs)# Get the examples to use.examples=awaitself._aget_examples(**kwargs)# Format the examples.example_strings=[# We can use the sync method here as PromptTemplate doesn't blockself.example_prompt.format(**example)forexampleinexamples]# Create the overall prefix.ifself.prefixisNone:prefix=""else:prefix_kwargs={k:vfork,vinkwargs.items()ifkinself.prefix.input_variables}forkinprefix_kwargs:kwargs.pop(k)prefix=awaitself.prefix.aformat(**prefix_kwargs)# Create the overall suffixsuffix_kwargs={k:vfork,vinkwargs.items()ifkinself.suffix.input_variables}forkinsuffix_kwargs:kwargs.pop(k)suffix=awaitself.suffix.aformat(**suffix_kwargs,)pieces=[prefix,*example_strings,suffix]template=self.example_separator.join([pieceforpieceinpiecesifpiece])# Format the template with the input variables.returnDEFAULT_FORMATTER_MAPPING[self.template_format](template,**kwargs)
@propertydef_prompt_type(self)->str:"""Return the prompt type key."""return"few_shot_with_templates"
[docs]defsave(self,file_path:Union[Path,str])->None:"""Save the prompt to a file. Args: file_path: The path to save the prompt to. Raises: ValueError: If example_selector is provided. """ifself.example_selector:msg="Saving an example selector is not currently supported"raiseValueError(msg)returnsuper().save(file_path)