Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DynamicPrompt class creation #13

Open
wants to merge 2 commits into
base: cloned_master_4bbaa
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion langchain/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from langchain.docstore import Wikipedia
from langchain.faiss import FAISS
from langchain.llms import Cohere, HuggingFaceHub, OpenAI
from langchain.prompt import Prompt
from langchain.prompt import DynamicPrompt, Prompt
from langchain.sql_database import SQLDatabase

__all__ = [
Expand All @@ -28,6 +28,7 @@
"SerpAPIChain",
"Cohere",
"OpenAI",
"DynamicPrompt",
"Prompt",
"ReActChain",
"Wikipedia",
Expand Down
99 changes: 99 additions & 0 deletions langchain/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,102 @@ def from_examples(
example_str = example_separator.join(examples)
template = prefix + example_str + suffix
return cls(input_variables=input_variables, template=template)


class DynamicPrompt(BaseModel):
r"""Schema to represent a dynamic prompt for an LLM.

Example:
.. code-block:: python

from langchain import DynamicPrompt
dynamic_prompt = DynamicPrompt(
examples=["Say hi. Hi", "Say ho. Ho"],
example_separator="\n\n",
prefix="",
suffix="\n\nSay {foo}"
input_variables=["foo"]
)
"""

examples: List[str]
"""A list of the examples that the prompt template expects."""

example_separator: str
"""Example separator, e.g. \n\n, for the dynamic prompt creation."""

input_variables: List[str]
"""A list of the names of the variables the prompt template expects."""

prefix: str
"""Prefix for the prompt."""

suffix: str
"""Suffix for the prompt."""

template_format: str = "f-string"
"""The format of the prompt template. Options are: 'f-string'."""

class Config:
"""Configuration for this pydantic object."""

extra = Extra.forbid

def format(self, **kwargs: Any) -> str:
"""Dynamically 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")
"""
# TODO segment self.examples based on example length &
# input_variables length here
example_str = self.example_separator.join(self.examples)
template = self.prefix + example_str + self.suffix
return _FORMATTER_MAPPING[self.template_format](template, **kwargs)
Comment on lines +145 to +164
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

category Error Handling

The format method in the DynamicPrompt class lacks proper error handling. It directly uses the formatted template without catching and handling potential exceptions that could occur during the formatting process. To improve the robustness of the code, consider wrapping the formatting logic inside a try-except block. This will allow you to catch and handle any exceptions, such as missing or invalid input variables, and provide meaningful error messages or raise appropriate exceptions to handle exceptional cases gracefully.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

Comment on lines +145 to +164
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address TODO and improve error handling in format.

The format method has a TODO comment indicating incomplete logic. Additionally, consider wrapping the formatting logic in a try-except block to handle potential errors gracefully, as suggested in previous comments.

Would you like assistance in implementing the error handling or completing the TODO logic?


@root_validator()
def template_is_valid(cls, values: Dict) -> Dict:
"""Check that suffix and input variables are consistent."""
input_variables = values["input_variables"]
suffix = values["suffix"]
template_format = values["template_format"]
Comment on lines +166 to +171
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

category Functionality

The template_is_valid method in the DynamicPrompt class currently only validates the suffix of the template. For a dynamic prompt, it's important to validate the entire template, including the prefix and examples. Please update this method to construct and validate the full template to ensure that all parts of the dynamic prompt are consistent with the input variables.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

if template_format not in _FORMATTER_MAPPING:
valid_formats = list(_FORMATTER_MAPPING)
raise ValueError(
f"Invalid template format. Got `{template_format}`;"
f" should be one of {valid_formats}"
)
dummy_inputs = {input_variable: "foo" for input_variable in input_variables}
try:
formatter_func = _FORMATTER_MAPPING[template_format]
formatter_func(suffix, **dummy_inputs)
except KeyError:
raise ValueError("Invalid prompt schema.")
return values

@classmethod
def from_examples(
cls,
examples: List[str],
suffix: str,
input_variables: List[str],
example_separator: str = "\n\n",
prefix: str = "",
) -> "DynamicPrompt":
"""Initialize DynamicPrompt with prefix, suffix, examples, etc."""
return cls(
examples=examples,
example_separator=example_separator,
input_variables=input_variables,
prefix=prefix,
suffix=suffix,
)