diff --git a/developer_notes/prompt_note.py b/developer_notes/prompt_note.py new file mode 100644 index 00000000..cb4bb167 --- /dev/null +++ b/developer_notes/prompt_note.py @@ -0,0 +1,84 @@ +def python_str_format_example(task_desc_str: str, input_str: str): + + # percent(%) formatting + print("%s User: %s" % (task_desc_str, input_str)) + + # format() method with kwargs + print( + "{task_desc_str} User: {input_str}".format( + task_desc_str=task_desc_str, input_str=input_str + ) + ) + + # f-string + print(f"{task_desc_str} User: {input_str}") + + # Templates + from string import Template + + t = Template("$task_desc_str User: $input_str") + print(t.substitute(task_desc_str=task_desc_str, input_str=input_str)) + + +def jinja2_template_example(template, **kwargs): + from jinja2 import Template + + t = Template(template, trim_blocks=True, lstrip_blocks=True) + print(t.render(**kwargs)) + + +def lightrag_prompt(template, task_desc_str, input_str, tools=None): + from lightrag.core.prompt_builder import Prompt + + prompt = Prompt( + template=template, + prompt_kwargs={ + "task_desc_str": task_desc_str, + "tools": tools, + }, + ) + print(prompt) + print(prompt(input_str=input_str)) + + saved_prompt = prompt.to_dict() + restored_prompt = Prompt.from_dict(saved_prompt) + print( + restored_prompt == prompt + ) # False as the jinja2 template can not be serialized, but we recreated the template from the string at the time of restoration, so it works the same + print(restored_prompt) + + +def lightrag_default_prompt(): + from lightrag.core.prompt_builder import Prompt + + prompt = Prompt() + input_str = "What is the capital of France?" + output = prompt(input_str=input_str) + print(output) + + +if __name__ == "__main__": + + task_desc_str = "You are a helpful assitant" + input_str = "What is the capital of France?" + tools = ["google", "wikipedia", "wikidata"] + template = r"""{{ task_desc_str }} +{# tools #} +{% if tools %} + +{% for tool in tools %} +{{loop.index}}. {{ tool }} +{% endfor %} + +{% endif %} +User: {{ input_str }}""" + python_str_format_example(task_desc_str, input_str) + jinja2_template_example(template, task_desc_str=task_desc_str, input_str=input_str) + jinja2_template_example( + template, task_desc_str=task_desc_str, input_str=input_str, tools=tools + ) + lightrag_prompt( + template, task_desc_str=task_desc_str, input_str=input_str, tools=tools + ) + + lightrag_default_prompt() diff --git a/docs/source/_static/database.png b/docs/source/_static/database.png deleted file mode 100644 index b7903a89..00000000 Binary files a/docs/source/_static/database.png and /dev/null differ diff --git a/docs/source/apis/components/index.rst b/docs/source/apis/components/index.rst index 3a311617..24890fa4 100644 --- a/docs/source/apis/components/index.rst +++ b/docs/source/apis/components/index.rst @@ -1,3 +1,5 @@ +.. _apis-components: + Components ============== @@ -10,9 +12,9 @@ Overview components.agent components.model_client components.data_process - + .. components.reasoning - + components.retriever components.output_parsers @@ -65,4 +67,3 @@ Retrievers :maxdepth: 1 components.retriever - diff --git a/docs/source/apis/core/index.rst b/docs/source/apis/core/index.rst index dc5dc194..c9f7399b 100644 --- a/docs/source/apis/core/index.rst +++ b/docs/source/apis/core/index.rst @@ -1,3 +1,5 @@ +.. _apis-core: + Core =================== @@ -7,7 +9,7 @@ Overview ---------- .. autosummary:: - core.base_data_class + core.base_data_class core.component core.db core.default_prompt_template diff --git a/docs/source/apis/eval/index.rst b/docs/source/apis/eval/index.rst index 966c01a1..d3b09e39 100644 --- a/docs/source/apis/eval/index.rst +++ b/docs/source/apis/eval/index.rst @@ -1,3 +1,5 @@ +.. _apis-eval: + Evaluation ============== diff --git a/docs/source/apis/optim/index.rst b/docs/source/apis/optim/index.rst index 74894349..3e2f23d8 100644 --- a/docs/source/apis/optim/index.rst +++ b/docs/source/apis/optim/index.rst @@ -1,3 +1,5 @@ +.. _apis-optim: + .. Optimizer .. ============== @@ -22,4 +24,4 @@ Optimizer optim.sampler optim.few_shot_optimizer optim.llm_augment - optim.llm_optimizer \ No newline at end of file + optim.llm_optimizer diff --git a/docs/source/apis/tracing/index.rst b/docs/source/apis/tracing/index.rst index 66ffceef..7a266ecd 100644 --- a/docs/source/apis/tracing/index.rst +++ b/docs/source/apis/tracing/index.rst @@ -1,3 +1,5 @@ +.. _apis-tracing: + Tracing ============== @@ -22,4 +24,4 @@ Loggers :maxdepth: 1 tracing.generator_state_logger - tracing.generator_call_logger \ No newline at end of file + tracing.generator_call_logger diff --git a/docs/source/apis/utils/index.rst b/docs/source/apis/utils/index.rst index 4f13a5c5..fb339773 100644 --- a/docs/source/apis/utils/index.rst +++ b/docs/source/apis/utils/index.rst @@ -1,3 +1,5 @@ +.. _apis-utils: + Utils ============================= @@ -31,4 +33,3 @@ Setup_env :maxdepth: 1 utils.setup_env - diff --git a/docs/source/developer_notes/index.rst b/docs/source/developer_notes/index.rst index 7fca9427..463b03a5 100644 --- a/docs/source/developer_notes/index.rst +++ b/docs/source/developer_notes/index.rst @@ -4,7 +4,7 @@ Tutorials ============================= -*Why and How Each Part works* +.. *Why and How Each Part works* Learn the `why` and `how-to` (customize and integrate) behind each core part within the `LightRAG` library. These are our most important tutorials before you move ahead to build use cases (LLM applications) end to end. @@ -47,7 +47,8 @@ Building ------------------- Base classes ~~~~~~~~~~~~~~~~~~~~~~ -Code path: ``lightrag.core``. +Code path: :ref:`lightrag.core `. + .. list-table:: :widths: 20 80 @@ -56,9 +57,9 @@ Code path: ``lightrag.core``. * - Base Class - Description * - :doc:`component` - - Similar to ``Module`` in `PyTorch`, it standardizes the interface of all components with `call`, `acall`, and `__call__` methods, handles states, and serialization. Components can be easily chained togehter via `Sequential` for now. + - The building block for task pipeline. It standardizes the interface of all components with `call`, `acall`, and `__call__` methods, handles state serialization, nested components, and parameters for optimization. Components can be easily chained together via ``Sequential``. * - :doc:`base_data_class` - - Leverages the ``dataclasses`` module in Python to ease the data interaction with prompt and serialization. + - The base class for data. It eases the data interaction with LLMs for both prompt formatting and output parsing. @@ -79,10 +80,10 @@ RAG components ^^^^^^^^^^^^^^^^^^^ -Code path: ``lightrag.core``. For abstract classes: +Code path: :ref:`lightrag.core`. For abstract classes: -- ``ModelClient``: the functional subclass is in ``lightrag.components.model_client``. -- ``Retriever``: the functional subclass is in ``lightrag.components.retriever``. It works hand-in-hand with the ``LocalDB`` and Cloud DB in ``lightrag.database``. +- ``ModelClient``: the functional subclass is in :ref:`lightrag.components.model_client`. +- ``Retriever``: the functional subclass is in :ref:`lightrag.components.retriever`. .. list-table:: @@ -92,11 +93,13 @@ Code path: ``lightrag.core``. For abstract classes: * - Part - Description * - :doc:`prompt` - - Built on ``jinja2``, it programmablly and flexibly format prompt(text) as **input to the generator**. + - Built on `jinja2`, it programmatically and flexibly formats prompts as input to the generator. * - :doc:`model_client` - ``ModelClient`` is the protocol and base class for LightRAG to **integrate all models**, either APIs or local, LLMs or Embedding models or any others. * - :doc:`generator` - The **center component** that orchestrates the model client(LLMs in particular), prompt, and output processors for format parsing or any post processing. + * - :doc:`output_parsers` + - The component that parses the output string to structured data. * - :doc:`embedder` - The component that orchestrates model client (Embedding models in particular) and output processors. * - :doc:`retriever` @@ -133,6 +136,7 @@ Components work on a sequence of ``Document`` and return a sequence of ``Documen prompt model_client generator + output_parsers embedder retriever text_splitter diff --git a/docs/source/developer_notes/output_parsers.rst b/docs/source/developer_notes/output_parsers.rst new file mode 100644 index 00000000..dc1f8e4c --- /dev/null +++ b/docs/source/developer_notes/output_parsers.rst @@ -0,0 +1,2 @@ +OutputParser +============= diff --git a/docs/source/developer_notes/prompt.rst b/docs/source/developer_notes/prompt.rst index 2c73bc85..c9a1e888 100644 --- a/docs/source/developer_notes/prompt.rst +++ b/docs/source/developer_notes/prompt.rst @@ -5,167 +5,244 @@ Prompt `Li Yin `_ -We strick to maximize developers' control towards the final experience and performance, simplify the development process, and minimize the token consumption. +Context +---------------- -For the major chat models, we eventually will only send two messages to the model: the system message and the user message. The user message is simple, -often you have a message `{'role': 'user', 'content': 'Hello, how are you?'}`. The system message is more complex, it contains the task description, tools, examples, chat history, context, and -intermediate step history from agents. +The prompt refers to the text input to the LLM models. +When sent to an LLM, the model uses the prompt to auto-regressively generate the next tokens, continuing the process until it reaches a specified stopping criterion. +The prompt itself plays a crucial role in the performance of the desired tasks. +Researchers often use `special tokens` [1]_ to separate different sections of the prompt, such as the system message, user message, and assistant message. +Ideally, developers should format this prompt with special tokens specific to the model's at training time. +However, many proprietary APIs did not disclose their special tokens, and requires users to send them in the forms of messages of different roles. -Prompt template ---------------------- +Design +---------------- -Our `DEFAULT_LIGHTRAG_SYSTEM_PROMPT` templates the system prompt with 7 important sections. We leverage `jinjia2` template for **programmable prompt** right along with string. +`LightRAG` seeks to maximize developers' control over the prompt. +Thus, in most cases we help developers gather together different sections and form them into one prompt. +This prompt will then be send to the LLM as a single message. +The default role of the message we use is `system`. +Though it is not a special token, we use ```` to represent the system message in the prompt, which works quite well. -The default template comes with 7 variables: `task_desc_str`, `output_format_str`, `tools_str`, `examples_str`, `chat_history_str`, `context_str`, and `steps_str`. +.. code-block:: python + + simple_prompt = r""" You are a helpful assistant. User: What can you help me with?""" -A jinjia2 template will rendered with :ref:`Prompt` class. If some fields being empty, that section will be empty in the final prompt string. +If it is `Llama3` model, the final text sent to the model for tokenization will be: .. code-block:: python - :linenos: - DEFAULT_LIGHTRAG_SYSTEM_PROMPT = r"""{# task desc #} - {% if task_desc_str %} - {{task_desc_str}} - {% endif %} - {# tools #} - {% if tools_str %} - - {{tools_str}} - - {% endif %} - {# example #} - {% if examples_str %} - - {{examples_str}} - - {% endif %} - {# chat history #} - {% if chat_history_str %} - - {{chat_history_str}} - - {% endif %} - {#contex#} - {% if context_str %} - - {{context_str}} - - {% endif %} - {# steps #} - {% if steps_str %} - - {{steps_str}} - - {% endif %} - """ - -Across our library, here our advanced features: - -- Various output formats where the `output_format_str` variable is used to pass the output format to the model. - -- Few-shot and Many-shots In-context Learning (ICL) where the `examples_str` variable is used to pass the examples to the model. - -- Tools/Function Calls where the `tools_str` variable is used to pass the tools to the model. - -- Memory where the `chat_history_str` variable is used to pass the memory to the model. - -- Retrieval augmented generation(RAG) where the `context_str`` variable is used to pass the retrieved context. - -- Agent with multiple step planning and replanning capabilities, where the `steps_str` variable is used to pass the previous steps to the model. - -**Note: this means in default our out-of-box components would not support API providers's tools/function calls as we only send the system and user messages to the model. -But it should not stop you from implementing them yourself.** + final_prompt = r"""<|begin_of_text|><|start_header_id|>system<|end_header_id|> + {{simple_prompt}} <|eot_id|>""" -Prompt class ---------------------- -We designed a :ref:`Prompt` class to render the `template` with the variables to string as the final system prompt. In the simplest case, the string is empty and we will only send -a user message to the model. And in most cases, you want to add at least the `task_desc_str` to the system message. +And the LLM will return the following text: + +.. code-block:: python + + prediction = r"""<|start_header_id|>assistant<|end_header_id|> You can ask me anything you want. <|eot_id|><|end_of_text|>""" + +Data Flow in LLM applications +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. figure:: /_static/images/LightRAG_dataflow.png + :align: center + :alt: Data Flow in LLM applications + :width: 620px + + Data flow in LLM applications + +Look at the most complicated case: We will have user query, retrieved context, task description, definition of tools, few-shot examples, past conversation history, step history from the agent, and the output format specification. +All these different parts need to be formatted into a single prompt. +We have to do all this with flexiblity and also easy for developers to read. -The cool thing about our `Prompt` system is how flexible it can be. If you need to put another `template` for say `task_desc_str`, you can do that using the `Prompt` class. -For example, your task is to instruct the llm to choose `top_k` from the given choices, you can define a new template like this: + +Why Jinja2? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To format the prompt, you can use any of Python's native string formatting. .. code-block:: python :linenos: - from core.prompt_builder import Prompt + # percent(%) formatting + print("%s User: %s" % (task_desc_str, input_str)) - task_desc_template = r""" - Choose the top {{top_k}} from the following choices: {{choices}} - """ - top_k = 3 - choices = ['apple', 'banana', 'orange', 'grape'] - task_desc_prompt = Prompt(template=task_desc_template, preset_prompt_kwargs={'top_k': top_k, 'choices': choices}) - task_desc_str = task_desc_prompt.call() - prompt = Prompt(preset_prompt_kwargs={'task_desc_str': task_desc_str}) - prompt.print_prompt() + # format() method with kwargs + print( + "{task_desc_str} User: {input_str}".format( + task_desc_str=task_desc_str, input_str=input_str + ) + ) -The output would be: + # f-string + print(f"{task_desc_str} User: {input_str}") -.. code-block:: xml - :linenos: + # Templates + from string import Template - Choose the top 3 from the following choices: ['apple', 'banana', 'orange', 'grape'] + t = Template("$task_desc_str User: $input_str") + print(t.substitute(task_desc_str=task_desc_str, input_str=input_str)) +We opted for `Jinja2` [1]_ as the templating engine for the prompt. +Besides of the placeholders using ``{{}}`` for key-word arguments, Jinja2 also allow users to write code similar to Python syntax. +This includes conditionals, loops, filters, and even comments that is lacked from Python's native string formatting. +Here is one example of using `Jinja2` to format the prompt: +.. code-block:: python + + def jinja2_template_example(**kwargs): + from jinja2 import Template -Prompt and Special Tokens context ----------------------------------- + template = r"""{{ task_desc_str }} + {# tools #} + {% if tools %} + + {% for tool in tools %} + {{loop.index}}. {{ tool }} + {% endfor %} + + {% endif %} + User: {{ input_str }}""" + t = Template(template, trim_blocks=True, lstrip_blocks=True) + print(t.render(**kwargs)) +Let's call it with and without tools: -Each section other than `task_desc_str` is encapulated in a special token. Different model can have different special tokens. -Here is one example of `Llama3 Documentation `_ prompts formatted with special tokens: +.. code-block:: python -input string to the LLM model and minimize the token consumption. -We enable advanced features without relying on API provider's prompt manipulation such as `OpenAI`'s tools or assistant APIs. + jinja2_template_example(task_desc_str=task_desc_str, input_str=input_str) + jinja2_template_example( + task_desc_str=task_desc_str, input_str=input_str, tools=tools + ) + +The printout would be: .. code-block:: - :linenos: - <|begin_of_text|><|start_header_id|>system<|end_header_id|> + You are a helpful assitant + User: What is the capital of France? + +And with tools: + +.. code-block:: + + You are a helpful assitant + + 1. google + 2. wikipedia + 3. wikidata + + User: What is the capital of France? + +We can see how easy and flexible to programmatically format the prompt with `Jinja2`. + - You are a helpful AI assistant for travel tips and recommendations<|eot_id|> - <|start_header_id|>user<|end_header_id|> - What can you help me with?<|eot_id|> +Prompt class +---------------- + - <|start_header_id|>assistant<|end_header_id|> +We created our :class:`Prompt Component` to render the prompt with the string ``template`` and ``prompt_kwargs``. +It is a rather simple component, but it is rather handy. +Let's use the same template as above: +.. code-block:: python + from lightrag.core.prompt_builder import Prompt + prompt = Prompt( + template=template, + prompt_kwargs={ + "task_desc_str": task_desc_str, + "tools": tools, + }, + ) + print(prompt) + print(prompt(input_str=input_str)) # takes the rest arguments in keyword arguments -Here is how you customize a new prompt: +The ``Prompt`` class allow us to preset some of the prompt arguments at initialization, and then we can call the prompt with the rest of the arguments. +Also, by subclassing ``Component``, we get to easily visualize this component with ``print``. +Here is the output: + +.. code-block:: + + Prompt( + template: {{ task_desc_str }} + {# tools #} + {% if tools %} + + {% for tool in tools %} + {{loop.index}}. {{ tool }} + {% endfor %} + + {% endif %} + User: {{ input_str }}, prompt_kwargs: {'task_desc_str': 'You are a helpful assitant', 'tools': ['google', 'wikipedia', 'wikidata']}, prompt_variables: ['input_str', 'tools', 'task_desc_str'] + ) + +As all components, you can use ``to_dict`` and ``from_dict`` to serialize and deserialize the component. + +Default Prompt Template +------------------------- +In default, ``Prompt`` class uses the :const:`DEFAULT_LIGHTRAG_SYSTEM_PROMPT` as its string template if no template is provided. +This default template will allow you conditionally passing seven important variables designed from the data flow diagram above. +These varaibles are: .. code-block:: python - :linenos: - from core.prompt_builder import Prompt + LIGHTRAG_DEFAULT_PROMPT_ARGS = [ + "task_desc_str", # task description + "output_format_str", # output format of the task + "tools_str", # tools used in the task + "examples_str", # examples of the task + "chat_history_str", # chat history of the user + "context_str", # context of the user query + "steps_str", # used in agent steps + "input_str", # user query or input + ] + +Now, let's see the minimum case where we only have the user query: - new_template = r""" - <|begin_of_text|><|start_header_id|>system<|end_header_id|> - {{task_desc_str}} - Your context: {{context_str}} <|eot_id|> +.. code-block:: python + + prompt = Prompt() + output = prompt(input_str=input_str) + print(output) + +The output will be bare minimum with only the user query and a prefix for assistant to respond: + +.. code-block:: + + + What is the capital of France? + + You: - <|start_header_id|>user<|end_header_id|> - {{query_str}}<|eot_id|> +.. note:: - <|start_header_id|>assistant<|end_header_id|> - """ + We barely need to use the raw ``Prompt`` class directly as it is orchestrated by the ``Generator`` component. - prompt = Prompt(template=new_template) -Prompt Engineering experience -------------------------------- -There is not robust prompt, and it is one of the most sensitive creatures in the AI world. -Here are some tips: -- Even the output format matters, the order of your output fields, the formating. -Output yaml or json format can lead to different performance. We have better luck with yaml format. -- Few-shot works so well in some case, but it can lead to regression in some cases. -- It is not fun to be a prompt engineer! But what can we do for now. +.. Prompt Engineering experience +.. ------------------------------- +.. There is no robust prompt, and it is one of the most sensitive creatures in the AI world. +.. Here are some tips: +.. - Even the output format matters, the order of your output fields, the formating. Output yaml or json format can lead to different performance. We have better luck with yaml format. +.. - Few-shot works so well in some case, but it can lead to regression in some cases. +.. - It is not fun to be a prompt engineer! But what can we do for now. + +.. admonition:: References + :class: highlight + + .. [1] Jinja2: https://jinja.palletsprojects.com/en/3.1.x/ + .. [2] Llama3 special tokens: https://llama.meta.com/docs/model-cards-and-prompt-formats/meta-llama-3/ + +.. admonition:: API References + :class: highlight -Resources: -1. `Jinja2`: + - :class:`core.prompt_builder.Prompt` + - :const:`core.default_prompt_template.DEFAULT_LIGHTRAG_SYSTEM_PROMPT` diff --git a/docs/source/insert_labels.py b/docs/source/insert_labels.py index bdf5f036..324c10af 100644 --- a/docs/source/insert_labels.py +++ b/docs/source/insert_labels.py @@ -4,17 +4,21 @@ def add_reference_labels(directory: str): try: for filename in os.listdir(directory): - if filename.endswith(".rst") and "index" not in filename: + if filename.endswith(".rst"): + if filename == "index.rst": + module_label = "-".join(directory.split("/")[-2:]) + else: + module_label = filename.replace(".rst", "").replace(".", "-") filepath = os.path.join(directory, filename) with open(filepath, "r+") as file: content = file.read() file.seek(0, 0) - module_label = filename.replace(".rst", "").replace(".", "-") + # module_label = filename.replace(".rst", "").replace(".", "-") if module_label not in content: label_line = f".. _{module_label}:\n\n" file.write(label_line + content) - except: - print(f"directory {directory} not exists") + except Exception as e: + print(f"directory {directory} not exists: {e}") if __name__ == "__main__": diff --git a/images/LightRAG-logo-circle.png b/images/LightRAG-logo-circle.png deleted file mode 100644 index 899dba0c..00000000 Binary files a/images/LightRAG-logo-circle.png and /dev/null differ diff --git a/images/LightRAG-logo-doc.jpeg b/images/LightRAG-logo-doc.jpeg deleted file mode 100644 index f8c64904..00000000 Binary files a/images/LightRAG-logo-doc.jpeg and /dev/null differ diff --git a/images/LightRAG-logo.jpg b/images/LightRAG-logo.jpg deleted file mode 100644 index 13ec4b56..00000000 Binary files a/images/LightRAG-logo.jpg and /dev/null differ diff --git a/images/LightRAG_dataflow.png b/images/LightRAG_dataflow.png deleted file mode 100644 index b385553c..00000000 Binary files a/images/LightRAG_dataflow.png and /dev/null differ diff --git a/images/lightrag_structure.png b/images/lightrag_structure.png deleted file mode 100644 index cf40969b..00000000 Binary files a/images/lightrag_structure.png and /dev/null differ diff --git a/lightrag/core/prompt_builder.py b/lightrag/core/prompt_builder.py index b529de86..75396f4d 100644 --- a/lightrag/core/prompt_builder.py +++ b/lightrag/core/prompt_builder.py @@ -33,7 +33,7 @@ def get_jinja2_environment(): class Prompt(Component): - __doc__ = r"""A component that renders a text string from a template using Jinja2 templates. + __doc__ = r"""Renders a text string(prompt) from a Jinja2 template string. In default, we use the :ref:`DEFAULT_LIGHTRAG_SYSTEM_PROMPT` as the template. @@ -66,7 +66,6 @@ class Prompt(Component): def __init__( self, - *, template: Optional[str] = None, prompt_kwargs: Optional[Dict] = {}, ): @@ -92,7 +91,7 @@ def __create_jinja2_template(self): raise ValueError(f"Invalid Jinja2 template: {e}") def update_prompt_kwargs(self, **kwargs): - r"""Update the preset prompt kwargs after Prompt is initialized.""" + r"""Update the initial prompt kwargs after Prompt is initialized.""" self.prompt_kwargs.update(kwargs) def get_prompt_variables(self) -> List[str]: @@ -109,7 +108,7 @@ def _find_template_variables(self, template_str: str): return meta.find_undeclared_variables(parsed_content) def compose_prompt_kwargs(self, **kwargs) -> Dict: - r"""Compose the final prompt kwargs by combining the preset_prompt_kwargs and the provided kwargs.""" + r"""Compose the final prompt kwargs by combining the initial and the provided kwargs at runtime.""" composed_kwargs = {key: None for key in self.prompt_variables} if self.prompt_kwargs: composed_kwargs.update(self.prompt_kwargs) @@ -141,7 +140,7 @@ def print_prompt(self, **kwargs): def call(self, **kwargs) -> str: """ - Renders the prompt template with the provided variables. + Renders the prompt template with keyword arguments. """ try: pass_kwargs = self.compose_prompt_kwargs(**kwargs) @@ -175,39 +174,3 @@ def to_dict(self) -> Dict[str, Any]: exclude = ["jinja2_template"] # unserializable object output = super().to_dict(exclude=exclude) return output - - -# if __name__ == "__main__": -# import logging - -# logging.basicConfig(level=logging.DEBUG) -# prompt = Prompt( -# preset_prompt_kwargs={"task_desc_str": "You are a helpful assistant."} -# ) -# print(prompt) -# prompt.print_prompt_template() -# prompt.print_prompt(context_str="This is a context string.") -# prompt.call(context_str="This is a context string.") -# states = prompt.state_dict() -# print(f"states: {states}") -# named_params = prompt.named_parameters() -# print(f"named_params: {named_params}") -# for name, param in named_params: -# print(f"{name}: {param}") - -# # get dict of prompt -# prompt_dict = prompt.to_dict() -# print(f"prompt_dict: {prompt_dict}") -# prompt_state = prompt.state_dict() -# print(f"prompt_state: {prompt_state}") - -# EXAMPLES_TEMPLATE = r""" -# {% if examples %} -# {% for example in examples %} -# {{loop.index}}. {{example}} -# {% endfor %} -# {% endif %} -# """ -# examples_prompt = Prompt(template=EXAMPLES_TEMPLATE) -# examples_str = examples_prompt.call(examples=["Example 1", "Example 2"]) -# prompt.print_prompt(examples_str=examples_str)