diff --git a/docs/how-to-guides/develop-a-tool/add-prompt-template-for-tool.md b/docs/how-to-guides/develop-a-tool/add-prompt-template-for-tool.md new file mode 100644 index 000000000000..e7ddcd3d6040 --- /dev/null +++ b/docs/how-to-guides/develop-a-tool/add-prompt-template-for-tool.md @@ -0,0 +1,51 @@ +# Add prompt template for tool +Users sometimes need to use prompt template within their tools. To simplify this, we've introduced the `PromptTemplate` feature. +In this guide, we will provide a detailed walkthrough on how to use `PromptTemplate` as a tool input. We will also demonstrate the user experience when utilizing this type of tool within a flow. + +## Prerequisites +- Follow the [steps](create-and-use-tool-package.md#Prerequisites) to prepare prerequisites. +- The tool's type must be `custom_llm` + +## How to create a tool with prompt template +Here we use [an existing tool package](../../../examples/tools/tool-package-quickstart/my_tool_package) as an example. If you want to create your own tool, please refer to create and use tool package. + +1. Add a `PromptTemplate` input for your tool, such as in [this example](../../../examples/tools/tool-package-quickstart/my_tool_package/tools/tool_with_prompt_template_input.py) + + ```python + from jinja2 import Template + from promptflow import tool + from promptflow.connections import CustomConnection + # 1. import the PromptTemplate type + from promptflow.contracts.types import PromptTemplate + + + # 2. add a PromptTemplate input for your tool method + @tool + def my_tool(connection: CustomConnection, prompt: PromptTemplate, **kwargs) -> str: + # 3. customise your own code to handle and use the prompt here + message = Template(prompt, trim_blocks=True, keep_trailing_newline=True).render(**kwargs) + return message + ``` + +2. Configure the tool YAML, Note that the `PromptTemplate` input should not be included in the YAML, like in [this example](../../../examples/tools/tool-package-quickstart/my_tool_package/yamls/tool_with_prompt_template_input.yaml) + + ```yaml + my_tool_package.tools.tool_with_prompt_template_input.my_tool: + name: Tool with PromptTemplate + description: This is a tool to demonstrate the usage of PromptTemplate + type: custom_llm + module: my_tool_package.tools.tool_with_prompt_template_input + function: my_tool + inputs: + connection: + type: + - CustomConnection + ``` + +## Use tool with a prompt template input in VS Code extension +Follow steps to [build and install your tool package](create-and-use-tool-package.md#build-and-share-the-tool-package) and [use your tool from VS Code extension](create-and-use-tool-package.md#use-your-tool-from-vscode-extension). + +Here we use an existing flow to demonstrate the experience, open [this flow](../../../examples/flows/standard/prompt-template-input-tool-showcase/flow.dag.yaml) in VS Code extension +- There is a node named "tool_with_prompt_template" with prompt template file, and the inputs of this node contains the input for the prompt template.. + +![use_prompt_template_in_flow](../../media/how-to-guides/develop-a-tool/use_prompt_template_in_flow.png) \ No newline at end of file diff --git a/docs/how-to-guides/develop-a-tool/create-and-use-tool-package.md b/docs/how-to-guides/develop-a-tool/create-and-use-tool-package.md index 70581bd2198e..f11bba72882c 100644 --- a/docs/how-to-guides/develop-a-tool/create-and-use-tool-package.md +++ b/docs/how-to-guides/develop-a-tool/create-and-use-tool-package.md @@ -163,4 +163,5 @@ Alternatively, you can test your tool package using the script below to ensure t ## Advanced features [Customize your tool icon](add-a-tool-icon.md) -[Add category and tags for tool](add-category-and-tags-for-tool.md) \ No newline at end of file +[Add category and tags for tool](add-category-and-tags-for-tool.md) +[Add Prompt Template for Custom LLM Tool](add-prompt-template-for-tool.md) \ No newline at end of file diff --git a/docs/how-to-guides/develop-a-tool/index.md b/docs/how-to-guides/develop-a-tool/index.md index 83ea80ab778d..729936a6e527 100644 --- a/docs/how-to-guides/develop-a-tool/index.md +++ b/docs/how-to-guides/develop-a-tool/index.md @@ -8,4 +8,5 @@ We provide guides on how to develop a tool and use it. create-and-use-tool-package add-a-tool-icon add-category-and-tags-for-tool +add-prompt-template-for-tool ``` \ No newline at end of file diff --git a/docs/media/how-to-guides/develop-a-tool/use_prompt_template_in_flow.png b/docs/media/how-to-guides/develop-a-tool/use_prompt_template_in_flow.png new file mode 100644 index 000000000000..9ebd1afed417 Binary files /dev/null and b/docs/media/how-to-guides/develop-a-tool/use_prompt_template_in_flow.png differ diff --git a/examples/flows/standard/prompt-template-input-tool-showcase/flow.dag.yaml b/examples/flows/standard/prompt-template-input-tool-showcase/flow.dag.yaml new file mode 100644 index 000000000000..da1d7ae7f5b3 --- /dev/null +++ b/examples/flows/standard/prompt-template-input-tool-showcase/flow.dag.yaml @@ -0,0 +1,18 @@ +inputs: + text: + type: string + default: Microsoft +outputs: + output: + type: string + reference: ${tool_with_prompt_template.output} +nodes: +- name: tool_with_prompt_template + type: custom_llm + source: + type: package_with_prompt + tool: my_tool_package.tools.tool_with_prompt_template_input.my_tool + path: prompt_template.jinja2 + inputs: + connection: open_ai_connection + text: ${inputs.text} diff --git a/examples/flows/standard/prompt-template-input-tool-showcase/prompt_template.jinja2 b/examples/flows/standard/prompt-template-input-tool-showcase/prompt_template.jinja2 new file mode 100644 index 000000000000..b8ec99b1a892 --- /dev/null +++ b/examples/flows/standard/prompt-template-input-tool-showcase/prompt_template.jinja2 @@ -0,0 +1 @@ +Hello {{text}}. \ No newline at end of file diff --git a/examples/flows/standard/prompt-template-input-tool-showcase/requirements.txt b/examples/flows/standard/prompt-template-input-tool-showcase/requirements.txt new file mode 100644 index 000000000000..0310b74813b7 --- /dev/null +++ b/examples/flows/standard/prompt-template-input-tool-showcase/requirements.txt @@ -0,0 +1,3 @@ +promptflow +promptflow-tools +my-tools-package \ No newline at end of file diff --git a/examples/tools/tool-package-quickstart/my_tool_package/tools/tool_with_prompt_template_input.py b/examples/tools/tool-package-quickstart/my_tool_package/tools/tool_with_prompt_template_input.py new file mode 100644 index 000000000000..2d6d0c8e592c --- /dev/null +++ b/examples/tools/tool-package-quickstart/my_tool_package/tools/tool_with_prompt_template_input.py @@ -0,0 +1,14 @@ +from jinja2 import Template +from promptflow import tool +from promptflow.connections import CustomConnection +from promptflow.contracts.types import PromptTemplate + + +@tool +def my_tool(connection: CustomConnection, prompt: PromptTemplate, **kwargs) -> str: + # Replace with your tool code. + # Usually connection contains configs to connect to an API. + # Use CustomConnection is a dict. You can use it like: connection.api_key, connection.api_base + # Not all tools need a connection. You can remove it if you don't need it. + message = Template(prompt, trim_blocks=True, keep_trailing_newline=True).render(**kwargs) + return message diff --git a/examples/tools/tool-package-quickstart/my_tool_package/yamls/tool_with_prompt_template_input.yaml b/examples/tools/tool-package-quickstart/my_tool_package/yamls/tool_with_prompt_template_input.yaml new file mode 100644 index 000000000000..daaa42674cd3 --- /dev/null +++ b/examples/tools/tool-package-quickstart/my_tool_package/yamls/tool_with_prompt_template_input.yaml @@ -0,0 +1,10 @@ +my_tool_package.tools.tool_with_prompt_template_input.my_tool: + name: Tool with PromptTemplate + description: This is a tool to demonstrate the usage of PromptTemplate + type: custom_llm + module: my_tool_package.tools.tool_with_prompt_template_input + function: my_tool + inputs: + connection: + type: + - CustomConnection diff --git a/examples/tools/tool-package-quickstart/tests/test_tool_with_prompt_template_input.py b/examples/tools/tool-package-quickstart/tests/test_tool_with_prompt_template_input.py new file mode 100644 index 000000000000..d015a8a6fbfc --- /dev/null +++ b/examples/tools/tool-package-quickstart/tests/test_tool_with_prompt_template_input.py @@ -0,0 +1,28 @@ +import pytest +import unittest + +from promptflow.connections import CustomConnection +from my_tool_package.tools.tool_with_prompt_template_input import my_tool + + +@pytest.fixture +def my_custom_connection() -> CustomConnection: + my_custom_connection = CustomConnection( + { + "api-key" : "my-api-key", + "api-secret" : "my-api-secret", + "api-url" : "my-api-url" + } + ) + return my_custom_connection + + +class TestToolWithPromptTemplateInput: + def test_tool_with_prompt_template_input(self, my_custom_connection): + result = my_tool(my_custom_connection, "Hello {{text}}", text="Microsoft") + assert result == "Hello Microsoft" + + +# Run the unit tests +if __name__ == "__main__": + unittest.main()