Semantic Kernel 入门:实用指南

open-source入门12 分钟阅读2026/7/11

几个月前,我正在开发一个内容处理工具——它能读取原始的会议记录,提取出待办事项,然后自动起草跟进邮件。一开始,我直接调用 OpenAI 的 API,结果不到一周,我的代码就变成了一团乱麻:到处都是字符串拼接、手动解析 JSON,还有十几个文件里散落着脆弱的提示词模板。每次想给处理流程加个新步骤,我都得再接一次 API 调用,处理一套新的报错,还得想办法在各步骤之间传递上下文。

就在那时,我偶然发现了 Semantic Kernel。微软把它做成了一个编排层——用来规范代码与 AI 模型交互的方式,免得你的代码库变成一团乱麻。它提供了一个用于管理 AI 服务的 kernel 对象,一个用来整理提示词和函数的插件系统,还有能自动把多个步骤串联起来的规划器。花了一个周末用重构了我的工具后,我彻底被圈粉了。接下来我带你上手配置,你亲自感受一下就知道了。

第一步:安装 SDK 并配置密钥

我主要用 Python 开发,所以这里重点讲 Python,不过 Semantic Kernel 也支持 C# 和 Java。Python 的安装很简单:

pip install semantic-kernel

C# 的话是这样:

dotnet add package Microsoft.SemanticKernel

接下来,你需要配置 API 密钥。Semantic Kernel 开箱即支持 OpenAI 和 Azure OpenAI。我在生产环境中用的是 Azure OpenAI,但入门的话,普通的 OpenAI 更简单。在项目根目录创建一个 .env 文件:

OPENAI_API_KEY=sk-your-key-here
OPENAI_ORG_ID=your-org-id-if-applicable

如果你用的是 Azure OpenAI,.env 文件内容就不一样了:

AZURE_OPENAI_API_KEY=your-azure-key
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME=gpt-4

说说我踩过的第一个坑:一开始我直接把 API 密钥硬编码在了脚本里。能跑是能跑,但那天晚些时候我把代码推到 GitHub 之后——对,你懂的,我只好去重置密钥。从一开始就老老实实用环境变量吧。如果你用了 python-dotenv,Semantic Kernel 会自动读取 .env 文件。

第二步:创建你的第一个 Kernel 并进行对话

kernel 是核心对象,负责管理你的 AI 服务和插件。下面演示如何实现一个基础的来回对话:

import asyncio
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion

async def main():
    # 初始化 kernel
    kernel = Kernel()

    # 添加 AI 服务
    kernel.add_service(
        OpenAIChatCompletion(
            service_id="chat",
            ai_model_id="gpt-4o",
        )
    )

    # 简单的聊天调用
    from semantic_kernel.contents import ChatHistory
    from semantic_kernel.connectors.ai.chat_completion_client_base import ChatCompletionClientBase

    chat_service = kernel.get_service(type=ChatCompletionClientBase)
    history = ChatHistory()
    history.add_user_message("我有一份会议记录,你能帮我提取待办事项吗?")

    response = await chat_service.get_chat_message_contents(
        chat_history=history,
        settings=chat_service.get_prompt_execution_settings_from_service_id("chat"),
    )

    print(response[0].content)

asyncio.run(main())

我第一次跑这段代码时报错了,提示找不到 API 密钥,因为我忘了加载 .env 文件。在脚本顶部加上 from dotenv import load_dotenv 并调用 load_dotenv() 就行了。加上之后,代码顺利跑通——GPT-4o 给出了关于提取待办事项的有用回复。

拿来做演示是没问题,但这跟直接调用 OpenAI API 没太大区别。真正的大招在后面。

第三步:赋予 AI 运行你代码的能力

这才是 Semantic Kernel 让我顿悟的地方。你可以写普通的 Python 函数,加上装饰器,AI 就能在对话过程中调用它们。这就是所谓的“原生函数”或插件。

from semantic_kernel.functions import kernel_function

class ActionItemsPlugin:
    @kernel_function(
        description="从会议文本中提取待办事项",
        name="extract_actions"
    )
    def extract_actions(self, text: str) -> str:
        # 实际开发中,这里会有更复杂的逻辑
        # 比如查询数据库、调用其他 API 等
        lines = text.split(".")
        action_items = [line.strip() for line in lines if "need to" in line.lower() or "will" in line.lower()]
        return "\n".join(f"- {item}" for item in action_items)

class EmailPlugin:
    @kernel_function(
        description="根据待办事项起草跟进邮件",
        name="draft_email"
    )
    def draft_email(self, action_items: str, recipient: str) -> str:
        return f"Hi {recipient},\n\nHere are the action items from our meeting:\n{action_items}\n\nBest regards"

# 将插件添加到 kernel 中
kernel.add_plugin(ActionItemsPlugin(), plugin_name="actions")
kernel.add_plugin(EmailPlugin(), plugin_name="email")

@kernel_function 装饰器就是施展魔法的地方。description 参数会告诉 AI 这个函数是干嘛的。当你开启函数调用(也叫工具调用)时,AI 就能根据用户的请求,自己决定什么时候调用这些函数。

开启方法如下:

from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior

settings = chat_service.get_prompt_execution_settings_from_service_id("chat")
settings.function_choice_behavior = FunctionChoiceBehavior.Auto()

response = await chat_service.get_chat_message_contents(
    chat_history=history,
    settings=settings,
    kernel=kernel,  # 传入 kernel,让它知道有哪些可用函数
)

设置了 FunctionChoiceBehavior.Auto() 之后,AI 会查看可用的插件函数,根据用户消息自行决定调用哪些,并自动执行。当我发送“从这份记录中提取待办事项,然后给 Sarah 起草一封邮件”时,AI 按顺序调用了 extract_actionsdraft_email,并把前一个的输出作为后一个的输入。这就是编排,而且我完全没写任何胶水代码。

第四步:看 AI 临场生成计划

上面的函数调用能处理简单的链式操作。面对更复杂的场景,Semantic Kernel 提供了规划器。规划器接收一个目标,然后自己琢磨该调用哪些插件函数、按什么顺序、传什么参数。

说实话,我第一次试用规划器时是持怀疑态度的。让 AI 自己决定运行我的哪个函数,感觉挺冒险。但对于范围明确、函数描述清晰的任务,它的效果出奇地好。

from semantic_kernel.connectors.ai.open_ai import OpenAIPromptExecutionSettings

# 设定一个目标
goal = "拿这份会议记录,提取待办事项,然后给团队负责人起草一封跟进邮件"

# 规划器会利用 AI 算出该调用哪些函数
# 以及按什么顺序来实现这个目标

新版 Semantic Kernel 在规划上重度依赖函数调用机制,而不是以前那种 Handlebars 规划器。这其实是件好事——因为 AI 用的是结构化的工具调用,而不是生成一堆自由文本再去解析,所以更可靠。

我碰到过一个意外情况:如果你的函数描述很模糊,规划器有时会以奇怪的顺序调用函数。我一开始把 extract_actions 描述成“处理文本”,结果 AI 试图先把原始记录塞进邮件起草器里。所以在写 @kernel_function 的描述时一定要具体。它们不仅是写给人看的文档,更是给 AI 看的提示词。

实用建议与诚实的局限性

用了 Semantic Kernel 几个月后,这是我总结的经验:

函数描述一定要具体。 AI 完全依赖你的描述来决定何时以及如何调用函数。“从会议文本中提取待办事项”可比“处理文本”好太多了。我曾花了一个小时调试一个奇怪的规划失败问题,最后发现全是因为描述太模糊。

从函数调用开始,别上来就用规划器。 FunctionChoiceBehavior.Auto() 方法比完整的规划器更可预测、更容易调试。只有当你遇到真正需要动态编排的复杂多步工作流时,再考虑用规划器。

独立测试你的插件。 像对待其他代码一样,为你的插件函数写单元测试。AI 层只是你函数的消费者——如果函数本身有 bug,AI 也会把错误结果往下传。

留意 Token 消耗。 开启函数调用后,每个函数的 schema 都会随请求一起发送。如果你有几十个插件,参数类型又复杂,Token 数量会迅速膨胀。我就因为函数定义占用了大量上下文窗口,比预期更早触发了频率限制。

文档还在努力跟上节奏。 Semantic Kernel 发展很快,网上有些教程已经过时了。微软官方文档是目前最好的参考,但就连它也落后于最新版本。想看最新的用法,最好去 GitHub 仓库的 examples 文件夹里找找。

它不是银弹。 如果你只是简单调调 API,根本不需要编排,那用 Semantic Kernel 只会徒增复杂性。写一次性脚本时,我依然会直接裸调 OpenAI API。只有当你需要复用函数、处理多步工作流,或者需要在不同的 AI 供应商之间切换时,Semantic Kernel 才真正大放异彩。

对我来说,最大的收获就是它的插件系统。我再也不用把提示词和 API 调用散落在代码库的各个角落了,所有东西都被组织成具有清晰接口的插件。后来因为成本原因,我需要把模型从 GPT-4o 换成别的,我只改了 kernel 配置里的一行代码,所有插件照常运行。光凭这一点,就值得我去花时间踩这个学习曲线了。

相关 Agent

M

Meta AI

Meta AI 是一个开源AI平台,用于研究和开发先进的语言模型及生成式AI工具。

了解更多 →