使用 Handlebars 提示模板

已完成

语义内核支持使用 Handlebars 模板语法进行提示。 句柄栏是一种简单的模板化语言,主要用于生成 HTML,但它也可以创建其他文本格式。 Handlebars 模板由常规文本和 Handlebars 表达式交错组成。

若要将 Handlebars 模板与语义内核配合使用,请先安装包:

dotnet add package Microsoft.SemanticKernel.PromptTemplates.Handlebars --version 1.30.0
pip install --upgrade semantic-kernel

接下来,将包导入代码:

using Microsoft.SemanticKernel.PromptTemplates.Handlebars;

添加的所有顶层语句包括以下内容:

using Microsoft.SemanticKernel; // Core Semantic Kernel SDK
using Microsoft.SemanticKernel.Connectors.AI.OpenAI; // Azure OpenAI connector
using Microsoft.SemanticKernel.PromptTemplates; // For prompt template configuration
using Microsoft.SemanticKernel.PromptTemplates.Handlebars; // For Handlebars template support
using System; // For Console and basic types
using System.Collections.Generic; // For Dictionary and KernelArguments
using System.IO; // For file operations (e.g., loading YAML)
using System.Threading.Tasks; // For async/await support
from semantic_kernel.prompt_template.handlebars_prompt_template import HandlebarsPromptTemplate   

添加的所有顶层语句包括以下内容:

from semantic_kernel.prompt_template import PromptTemplateConfig      # for prompt_config
from semantic_kernel.prompt_template.handlebars_prompt_template import HandlebarsPromptTemplate  # for function
import json      # for loading appsettings.json
import yaml      # for loading HandlebarsPrompt.yaml
import asyncio   # for running async main
from semantic_kernel import Kernel      #  Needed (for kernel)
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion  # for chat_service

以下示例演示了一个使用 Handlebars 语法的聊天提示模板。 该模板包含 Handlebars 表达式,由 {{}} 表示。 执行模板时,这些表达式将替换为输入对象中的值。

const string HandlebarsTemplate = """
    <message role="system">You are an AI assistant designed to help with image recognition tasks.</message>
    <message role="user">
        <text>{{request}}</text>
        <image>{{imageData}}</image>
    </message>
    """;
handlebars_template = """
<message role="system">You are an AI assistant designed to help with image recognition tasks.</message>
<message role="user">
    <text>{{request}}</text>
    <image>{{imageData}}</image>
</message>
"""

在此示例中,有两个输入对象:

  • request - 包含助手应完成的请求。
  • imageData - 包含 base64 图像数据。

若要使用提示模板,需要创建 PromptTemplateConfig 包含模板及其格式的对象。 之后,从模板配置创建对象 KernelFunction 并指定 Handlebars 模板工厂。 下面是一个示例:

// Create the prompt template configuration
var templateFactory = new HandlebarsPromptTemplateFactory();
var promptTemplateConfig = new PromptTemplateConfig()
{
    Template = HandlebarsTemplate,
    TemplateFormat = "handlebars",
    Name = "Vision_Chat_Prompt",
};

// Create a function from the Handlebars template configuration
var function = kernel.CreateFunctionFromPrompt(promptTemplateConfig, templateFactory);
# Load Azure OpenAI config from a JSON file
with open('appsettings.json', 'r') as f:
    config = json.load(f)

model_id = config["modelId"]
endpoint = config["endpoint"]
api_key = config["apiKey"]

# Set up Semantic Kernel and Azure OpenAI service
kernel = Kernel()
chat_service = AzureChatCompletion(
    deployment_name=model_id,
    endpoint=endpoint,
    api_key=api_key
)
kernel.add_service(chat_service, "chat_completion")

# Create the prompt template config and function
prompt_config = PromptTemplateConfig(
    template=handlebars_template,
    template_format="handlebars",
    name="Vision_Chat_Prompt"
)
function = HandlebarsPromptTemplate(prompt_template_config=prompt_config)

现在,可以使用输入数据创建 KernelArguments 对象并调用函数。

var arguments = new KernelArguments(new Dictionary<string, object?>
{
    {"request","Describe this image:"},
    {"imageData", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAACVJREFUKFNj/KTO/J+BCMA4iBUyQX1A0I10VAizCj1oMdyISyEAFoQbHwTcuS8AAAAASUVORK5CYII="}
});

var response = await kernel.InvokeAsync(function, arguments);
arguments = {
    "request": "Describe this image:",
    "imageData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAACVJREFUKFNj/KTO/J+BCMA4iBUyQX1A0I10VAizCj1oMdyISyEAFoQbHwTcuS8AAAAASUVORK5CYII="
}

async def main():
    result = await kernel.invoke_prompt(
        prompt=prompt_config.template,
        request=arguments["request"],
        imageData=arguments["imageData"],
        service_id="chat_completion",
        template_format="handlebars"
    )
    print("Kernel result:", result)

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

此提示的响应将会与以下输出类似

The image is a solid block of bright red color. There are no additional features, shapes, or textures present.

在 YAML 提示符中使用 Handlebars 模板

可以从 YAML 文件创建提示函数,以便将提示模板与关联的元数据和提示执行设置一起存储。 这些文件可以在版本控制中管理,这对于跟踪对复杂提示的更改很有用。

以下代码是上一部分中使用的聊天提示的 YAML 表示形式示例:

name: Vision_Chat_Prompt
template: |
    <message role="system">
        You are an AI assistant designed to help with image recognition tasks.
    </message>
    <message role="user">
        <text>{{request}}</text>
        <image>{{imageData}}</image>
    </message>
template_format: handlebars
description: Vision chat prompt template.
input_variables:
  - name: request
    description: Request details.
    is_required: true
  - name: imageData
    description: Base64 image data.
    is_required: true

若要使用此提示,请将其加载为嵌入资源,将其转换为函数,然后调用它。

// Load prompt from resource
var handlebarsPromptYaml = EmbeddedResource.Read("HandlebarsPrompt.yaml");

// Create the prompt function from the YAML resource
var templateFactory = new HandlebarsPromptTemplateFactory();
var function = kernel.CreateFunctionFromPromptYaml(handlebarsPromptYaml, templateFactory);

// Input data for the prompt rendering and execution
var arguments = new KernelArguments(new Dictionary<string, object?>
{
    {"request","Describe this image:"},
    {"imageData", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAACVJREFUKFNj/KTO/J+BCMA4iBUyQX1A0I10VAizCj1oMdyISyEAFoQbHwTcuS8AAAAASUVORK5CYII="}
});

// Invoke the prompt function
var response = await kernel.InvokeAsync(function, arguments);
import yaml

# Load YAML prompt from file
with open("HandlebarsPrompt.yaml", "r") as f:
    yaml_prompt = yaml.safe_load(f)

prompt_config = PromptTemplateConfig(
    template=yaml_prompt["template"],
    template_format="handlebars",
    name=yaml_prompt.get("name", "Vision_Chat_Prompt")
)

function = HandlebarsPromptTemplate(prompt_template_config=prompt_config)

arguments = {
    "request": "Describe this image:",
    "imageData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAACVJREFUKFNj/KTO/J+BCMA4iBUyQX1A0I10VAizCj1oMdyISyEAFoQbHwTcuS8AAAAASUVORK5CYII="
}

async def main():
    result = await kernel.invoke_prompt(
        prompt=prompt_config.template,
        request=arguments["request"],
        imageData=arguments["imageData"],
        service_id="chat_completion",
        template_format="handlebars"
    )
    print("Kernel result:", result)

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

将 Handlebars 模板与语义内核配合使用是为应用程序创建动态提示的简单且有效的方法。 Handlebars 语法易于使用,允许你在 YAML 中包含变量、管理 YAML 中的提示,以便更好地组织,并无缝集成 AI 驱动的函数。 此方法使提示更加灵活、可重用且更易于维护。

您可以从 Handlebars 指南 了解 Handlebars 提示模板的更多信息。