S
SkillNav

Semantic Kernel 收紧模板参数编码规则:复杂类型默认触发异常

资讯2025-08-27T05:17:18+00:006 分钟阅读
Semantic Kernel 收紧模板参数编码规则:复杂类型默认触发异常

在此前版本的 Semantic Kernel 中,如果模板参数类型是 string,系统会自动执行编码;但对于自定义类型、匿名类型或集合,则不会应用编码。

随着最新改动上线,我们引入了更严格的规则:如果启用了自动编码(默认行为),当参数中使用复杂类型时将直接抛出异常。这样可以强制开发者为复杂类型手动处理编码,并为这些变量显式关闭自动编码,从而实现更安全的模板渲染。尤其是在使用 Handlebars 或 Liquid 这类模板引擎时,这一改动有助于落实安全最佳实践。

本文将说明旧方案存在的问题、新行为,以及如何更新代码以符合这些变更。关于 Semantic Kernel 中模板渲染的更多细节,请参阅官方文档

复杂类型的编码

自动编码本质上是一道安全防线:它会转义字符串中的特殊字符,以防止模板注入等常见漏洞。但当参数是复杂类型(例如自定义对象、匿名类型或集合)时,SDK 无法可靠判断应如何对嵌套属性或集合元素进行编码;贸然处理可能导致数据损坏或防护不完整。

为了解决这个问题,SDK 现在会在这类场景中抛出异常,强制开发者显式进行手动编码和相关配置。

最新版本的变化与潜在报错

从最新的 .NET 与 Python Semantic Kernel 包开始,在启用编码的前提下渲染模板时,如果使用复杂类型且未做正确配置,就会抛出异常。这可以避免无意中的不安全渲染,并要求相关场景更新代码。

如果你的代码在 Handlebars 或 Liquid 模板中使用了复杂参数(例如包含用户输入属性的对象),就会遇到这一变化。异常信息会提示你手动编码数据,并为相关输入变量设置 AllowDangerouslySetContenttrue。这一调整在保留高级用法灵活性的同时,执行了更严格、更安全的规则,降低漏洞风险。

如何更新你的代码

要解决这个问题,你需要对复杂类型中可能不安全的数据执行手动编码,并在 prompt template 配置中为这些参数显式关闭自动编码,即设置 AllowDangerouslySetContenttrue

.NET 示例

以下是变更前的代码示例:

code
var arguments = new KernelArguments()
{
    { "customer", new
        {
            firstName = userInput.FirstName,
            lastName = userInput.LastName,
        }
    }
};

var templateFactory = new LiquidPromptTemplateFactory();
var promptTemplateConfig = new PromptTemplateConfig()
{
    TemplateFormat = "liquid"
};

var promptTemplate = templateFactory.Create(promptTemplateConfig);
// The following line will throw an exception now, because of the complex type passed as argument and enabled encoding
var renderedPrompt = await promptTemplate.RenderAsync(kernel, arguments);

变更后的代码:

code
var arguments = new KernelArguments()
{
    { "customer", new
        {
            // Perform encoding for each property of complex type
            firstName = HttpUtility.HtmlEncode(userInput.FirstName),
            lastName = HttpUtility.HtmlEncode(userInput.LastName),
        }
    }
};

var templateFactory = new LiquidPromptTemplateFactory();
var promptTemplateConfig = new PromptTemplateConfig()
{
    TemplateFormat = "liquid",
    InputVariables = new()
    {
        // We set AllowDangerouslySetContent to 'true' because each property of this argument is encoded manually
        new() { Name = "customer", AllowDangerouslySetContent = true },
    }
};

var promptTemplate = templateFactory.Create(promptTemplateConfig);
// No exception, because we disabled encoding for arguments due to manual encoding
var renderedPrompt = await promptTemplate.RenderAsync(kernel, arguments);

Python 示例

以下是变更前的代码示例:

code
arguments = {
    "customer": {
        "first_name": user_input.first_name,
        "last_name": user_input.last_name,
    }
}

prompt_template_config = PromptTemplateConfig(
    template_format="handlebars"
)

prompt_template = HandlebarsPromptTemplate(prompt_template_config=prompt_template_config)
# The following line will throw an exception now, because of the complex type passed as argument and enabled encoding
rendered_prompt = await prompt_template.render(kernel, arguments)

变更后的代码:

code
arguments = {
    "customer": {
        # Perform encoding for each property of the complex type
        "first_name": escape(user_input.first_name),
        "last_name": escape(user_input.last_name),
    }
}

prompt_template_config = PromptTemplateConfig(
    template=template,
    template_format="handlebars",
    input_variables=[
        # We set allow_dangerously_set_content to True because each property of this argument is encoded manually
        InputVariable(name="customer", allow_dangerously_set_content=True),
    ]
)

prompt_template = HandlebarsPromptTemplate(prompt_template_config=prompt_template_config)
# No exception, because we disabled encoding for arguments due to manual encoding
rendered_prompt = await prompt_template.render(kernel, arguments)

在这次更新中:

  1. 使用 HttpUtility.HtmlEncode(或模板引擎对应的等效方法)等方式,对属性进行手动编码,净化用户输入。
  2. PromptTemplateConfig 中增加 InputVariables,并为已自行完成编码的复杂参数设置 AllowDangerouslySetContent = true。这会告诉 SDK:跳过该变量的自动编码。

对于 Handlebars 或其他受支持模板,也应做类似调整。请务必测试渲染输出,确认编码生效且不影响功能。

总结

Semantic Kernel 这次更新为模板参数引入了更严格的编码规则:在自动编码开启时,复杂类型会触发异常,以强制手动净化与显式配置。这显著提升了模板渲染安全性,能够更有效地防止潜在漏洞。

我们始终欢迎你的反馈。如果你有任何意见、问题或想进一步讨论,欢迎前往 GitHub 的讨论区与我们及社区交流。也欢迎支持我们——如果你喜欢 Semantic Kernel,欢迎在 GitHub 给项目点个 star。

分类

作者

Dmytro Struk

高级软件工程师

原文链接:https://devblogs.microsoft.com/semantic-kernel/encoding-changes-for-template-arguments-in-semantic-kernel/

相关文章

AINews:Harness Engineering 到底是不是一门真学问?
深度·3月5日
AINews:Harness Engineering 到底是不是一门真学问?

这篇文章围绕 AI 工程中的核心争议展开:系统能力究竟主要来自更强的模型(Big Model),还是来自更强的编排层(Big Harness)。文中汇总了 OpenAI、Anthropic、Scale AI、METR 等多方观点与数据,显示两派在“模型进步会不会吞噬 Harness 价值”上分歧明显。作者最终认为,随着 Agent 产品落地加速,Harness Engineering 的独立价值正在被市场和社区进一步确认。

10 分钟
每个 Agent 都需要一个 Box:Aaron Levie 谈 AI 时代的新基础设施
深度·3月5日
每个 Agent 都需要一个 Box:Aaron Levie 谈 AI 时代的新基础设施

在围绕“AI 是否正在杀死 SaaS”的争论中,Box CEO Aaron Levie 提出相反观点:企业内容与文件系统在 Agent 时代反而更关键。随着 Filesystem、Sandbox 和 Agent 工作流快速普及,核心问题从“让 Agent 能做事”转向“如何治理 Agent 的身份、权限与安全边界”。他认为,未来企业将拥有远多于人的 Agent 数量,而真正的竞争力在于率先完成面向 Agent 的组织与基础设施改造。

8 分钟