创建和使用工具包#

在本文档中,我们将指导您完成开发自己的工具包的过程,提供详细的步骤和建议,教您如何利用您的创作。

自定义工具是您自己开发的提示流工具。如果您觉得它有用,可以按照此指南将其制作成工具包。这将使您能够方便地重复使用它,与您的团队共享,或分发给世界上的任何人。

成功安装包后,您的自定义“工具”将如下所示显示在VSCode扩展中: custom-tool-list

创建你自己的工具包#

您的工具包应该是一个python包。要快速尝试,只需使用my-tools-package 0.0.1并跳过本节。

先决条件#

使用 Python 3.9 或 3.10 创建一个新的 conda 环境。运行以下命令来安装 PromptFlow 依赖项:

pip install promptflow

安装Pytest包以运行测试:

pip install pytest pytest-mock

使用以下命令从GitHub克隆PromptFlow仓库:

git clone https://github.com/microsoft/promptflow.git

创建自定义工具包#

在根文件夹下运行以下命令以快速创建您的工具项目:

python <promptflow github repo>\scripts\tool\generate_tool_package_template.py --destination <your-tool-project> --package-name <your-package-name> --tool-name <your-tool-name> --function-name <your-tool-function-name>

例如:

python D:\proj\github\promptflow\scripts\tool\generate_tool_package_template.py --destination hello-world-proj --package-name hello-world --tool-name hello_world_tool --function-name get_greeting_message

这个自动生成的脚本将为您创建一个工具。参数destinationpackage-name是必填的。参数tool-namefunction-name是可选的。如果留空,tool-name将默认为hello_world_toolfunction-name将默认为tool-name

该命令将生成如下工具项目,其中包含一个工具 hello_world_tool.py

hello-world-proj/    
│    
├── hello_world/    
│   ├── tools/    
│   │   ├── __init__.py    
│   │   ├── hello_world_tool.py    
│   │   └── utils.py    
│   ├── yamls/    
│   │   └── hello_world_tool.yaml    
│   └── __init__.py    
│    
├── tests/     
│   ├── __init__.py    
│   └── test_hello_world_tool.py    
│    
├── MANIFEST.in    
│    
└── setup.py  

下面列出的要点解释了包中每个文件夹/文件的用途。如果你的目标是在你的包中开发多个工具,请确保仔细检查要点2和5。

  1. hello-world-proj: 这是源目录。您项目的所有源代码都应放置在此目录中。

  2. hello-world/tools: 该目录包含您项目的各个工具。您的工具包可以包含一个工具或多个工具。当添加新工具时,您应该在tools文件夹下创建另一个*_tool.py。

  3. hello-world/tools/hello_world_tool.py: 在def函数中开发你的工具。使用@tool装饰器来标识该函数为工具。

    [!注意] 有两种编写工具的方法。默认且推荐的方法是函数实现方式。你也可以使用类实现方式,参考my_tool_2.py作为示例。

  4. hello-world/tools/utils.py: 该文件实现了工具列表方法,该方法收集所有定义的工具。必须拥有此工具列表方法,因为它允许用户界面(UI)检索您的工具并在UI中显示它们。

    [!注意] 如果您保持现有的文件夹结构,则无需创建自己的列表方法。您可以简单地使用utils.py文件中提供的自动生成的列表方法。

  5. hello_world/yamls/hello_world_tool.yaml: 工具 YAML 文件定义了工具的元数据。工具列表方法,如 utils.py 中所述,获取这些工具 YAML 文件。

    [!注意] 如果你创建了一个新工具,别忘了也要创建相应的工具YAML。你可以在你的工具项目下运行以下命令来自动生成你的工具YAML。你可能想要指定-nname-ddescription,这些将在提示流UI中显示为工具名称和工具提示。

    python <promptflow github repo>\scripts\tool\generate_package_tool_meta.py -m <tool_module> -o <tool_yaml_path> -n <tool_name> -d <tool_description>
    

    例如:

    python D:\proj\github\promptflow\scripts\tool\generate_package_tool_meta.py -m hello_world.tools.hello_world_tool -o hello_world\yamls\hello_world_tool.yaml -n "Hello World Tool" -d "This is my hello world tool."
    

    要填充您的工具模块,请遵循模式 .tools.,这表示包内工具的文件夹路径。

  6. tests: 该目录包含所有测试文件,尽管在创建自定义工具包时它们不是必需的。当添加新工具时,您也可以创建相应的测试并将其放置在此目录中。在您的工具项目下运行以下命令:

    pytest tests
    
  7. MANIFEST.in: 此文件用于确定项目中包含哪些文件以进行分发。工具 YAML 文件应包含在 MANIFEST.in 中,以便您的工具 YAML 文件可以被打包,并且您的工具可以在 UI 中显示。

    [!注意] 如果您保持现有的文件夹结构,则无需更新此文件。

  8. setup.py: 此文件包含有关您项目的元数据,如名称、版本、作者等。此外,入口点在generate_tool_package_template.py脚本中自动为您配置。在Python中,在setup.py中配置入口点有助于建立包的主要执行点,简化其与其他软件的集成。

    package_tools 入口点与工具列表方法一起用于检索所有工具并在用户界面中显示它们。

    entry_points={
          "package_tools": ["<your_tool_name> = <list_module>:<list_method>"],
    },
    

    [!注意] 如果您保持现有的文件夹结构,则无需更新此文件。

构建并分享工具包#

在工具包的根目录下执行以下命令来构建你的工具包:

python setup.py sdist bdist_wheel

这将生成一个工具包 -0.0.1.tar.gz 和相应的 whl 文件dist 文件夹内。

如果您还没有在PyPI上创建账户,请创建一个,并通过运行pip install twine来安装twine包。

通过运行twine upload dist/*将您的包上传到PyPI,这将提示您输入PyPI用户名和密码,然后将您的包上传到PyPI。一旦您的包上传到PyPI,其他人可以通过运行pip install your-package-name来安装它。请确保将your-package-name替换为您的包在PyPI上显示的名称。

如果你只想将其上传到Test PyPI,可以通过运行twine upload --repository-url https://test.pypi.org/legacy/ dist/*来上传你的包。一旦你的包上传到Test PyPI,其他人可以通过运行pip install --index-url https://test.pypi.org/simple/ your-package-name来安装它。

从VSCode扩展中使用您的工具#

  • 步骤1: 安装 Prompt flow for VS Code 扩展.

  • 第二步:转到终端并在扩展的conda环境中安装您的工具包。假设您的conda环境名称是prompt-flow

    (local_test) PS D:\projects\promptflow\tool-package-quickstart> conda activate prompt-flow
    (prompt-flow) PS D:\projects\promptflow\tool-package-quickstart> pip install .\dist\my_tools_package-0.0.1-py3-none-any.whl
    
  • 步骤3:转到扩展并打开一个流程文件夹。点击‘flow.dag.yaml’并预览流程。接着,点击+按钮,你将看到你的工具。如果在列表中看不到你的工具,可能需要重新加载窗口以清除之前的缓存。 auto-list-tool-in-extension

常见问题解答#

为什么我的自定义工具没有在用户界面中显示?#

确认工具YAML文件已包含在您的自定义工具包中。您可以将YAML文件添加到MANIFEST.in,并在setup.py中包含包数据。 或者,您可以使用下面的脚本来测试您的工具包,以确保您已正确打包工具YAML文件并配置了包工具入口点。

  1. 在执行此脚本之前,请确保在您的conda环境中安装工具包。

  2. 在任何地方创建一个python文件,并将以下内容复制到其中。

    import importlib
    import importlib.metadata
    
    def test():
        """List all package tools information using the `package-tools` entry point.
    
        This function iterates through all entry points registered under the group "package_tools."
        For each tool, it imports the associated module to ensure its validity and then prints
        information about the tool.
    
        Note:
        - Make sure your package is correctly packed to appear in the list.
        - The module is imported to validate its presence and correctness.
    
        Example of tool information printed:
        ----identifier
        {'module': 'module_name', 'package': 'package_name', 'package_version': 'package_version', ...}
        """
        entry_points = importlib.metadata.entry_points()
        if hasattr(entry_points, "select"):
            entry_points = entry_points.select(group=PACKAGE_TOOLS_ENTRY)
        else:
            entry_points = entry_points.get(PACKAGE_TOOLS_ENTRY, [])
        for entry_point in entry_points:
            list_tool_func = entry_point.load()
            package_tools = list_tool_func()
    
            for identifier, tool in package_tools.items():
                importlib.import_module(tool["module"])  # Import the module to ensure its validity
                print(f"----{identifier}\n{tool}")
    
    if __name__ == "__main__":
        test()
    
  3. 在你的conda环境中运行此脚本。这将返回你本地环境中安装的所有工具的元数据,你应该验证你的工具是否被列出。

为什么我无法上传包到PyPI?#

  • 确保输入的PyPI账户用户名和密码准确无误。

  • 如果您遇到403 Forbidden Error,这很可能是由于与现有包的命名冲突。您需要选择一个不同的名称。在PyPI上,包名称必须是唯一的,以避免用户之间的混淆和冲突。在创建新包之前,建议搜索PyPI(https://pypi.org/)以验证您选择的名称是否已被占用。如果您想要的名称不可用,请考虑选择一个替代名称或变体,以明确区分您的包与现有包。

高级功能#