十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用 Semantic Kernel 为 Microsoft Copilot Studio 构建自定义 Skill:从低代码扩展到 Pro-Code 的完整实战

用 Semantic Kernel 为 Microsoft Copilot Studio 构建自定义 Skill:从低代码扩展到 Pro-Code 的完整实战 用 Semantic Kernel 为 Microsoft Copilot Studio 构建自定义 Skill从低代码扩展到 Pro-Code 的完整实战【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel本篇技术指南以当前仓库中python/samples/demos/copilot_studio_skill示例为核心系统讲解如何将 Semantic Kernel 以Copilot Studio Skill的形式接入 Microsoft Copilot Studio通过 Azure Bot Service 与部署在 Azure Container Apps 上的自定义 API 扩展 Agent 能力。读完本文你将掌握 Copilot Studio Skill 的完整架构、Entra IDAzure AD应用注册、azd up一键部署、Bot Framework 技能清单Manifest编写以及基于 Semantic KernelChatCompletionAgent的对话后端实现细节并能直接照搬源码改造出你自己的生产级 Skill。为什么需要 Pro-Code 方式扩展 Copilot StudioMicrosoft Copilot Studio 是一个图形化的低代码工具既可以用于创建 Agent包括通过 Power Automate 构建自动化流程也可以将企业自有数据和场景扩展进 Microsoft 365 Copilot。然而在某些场景下默认 Agent 能力无法满足需求例如需要调用企业内部的私有 API、复杂计算或领域算法需要细粒度的权限控制与多租户安全校验需要把 LLM 编排多轮对话、函数调用、插件体系交给自己完全可控的代码。此时Pro-Code 优先的方式——把 Semantic Kernel 封装成一个可被 Copilot Studio 调用的 Skill——就成为一种自然选择。本示例正是这一思路的最小可运行实现Copilot Studio 中的 Topic 通过一个 Action 节点调用远程 SkillSkill 后端由 Semantic Kernel 驱动的聊天 Agent 处理并返回响应。注意示例演示了一个讲笑话的 Agentsk_conversation_agent.py中的指令为 You invent jokes to have a fun conversation with the user.但整个框架可以替换为任何业务逻辑如 RAG 问答、订单查询、内容生成等。架构总览一条从 Copilot Studio 到 SK Agent 的请求链路示例采用Azure Bot Service作为请求入口负责将请求路由到后端服务——一个运行在Azure Container Apps中、由 Semantic Kernel 驱动的自定义 API。整体时序如下摘自原文档架构图此处以 Mermaid 还原链路中有两条关键路径注册路径一次性Copilot Studio 直接向 SK App 的/manifest端点拉取技能清单Skill Manifest完成 Skill 注册运行时路径每次对话用户消息经 Copilot Studio → Azure Bot Service → SK App 的/api/messages端点SK Agent 处理后沿原路返回响应。从仓库源码看这个SK App实际是一个基于aiohttp的轻量 Web 服务app.py路由定义非常清晰APP web.Application() APP.router.add_post(/api/messages, messages) APP.router.add_get(/manifest, copilot_manifest)POST /api/messagesBot Framework 协议的消息处理入口处理来自 Copilot Studio 的 ActivityGET /manifest动态生成并返回 Copilot Studio Skill Manifest带身份与端点信息。提示原文档特别指出截至目前 Bot Framework SDK for Python 仅提供aiohttp支持不支持 FastAPI/Flask 等框架这也是示例选择 aiohttp 的原因。见 requirements.txt 中的botbuilder-integration-aiohttp4.15.0。前置条件与环境要求开始部署前请确认具备以下环境与原文档一致前置项说明Azure 订阅用于部署 Bot Service、Container Apps、Azure OpenAI 等资源Azure CLI用于创建 Entra ID 应用注册与凭据Azure Developer CLIazd用于一键部署基础设施与代码Python 3.12 或更高后端 API 的运行时Dockerfile 基于python:3.12-slim启用 Copilot Studio 的 Microsoft 365 租户用于注册 Skill 与测试对话关于租户有两个值得注意的细节Azure 订阅与 Microsoft 365 租户不必是同一租户但必须在启用 Copilot Studio 的租户的 Entra IDAzure AD中拥有注册应用的权限因为 Bot 身份App Registration决定了 Copilot Studio 能否安全调用你的 Skill。端到端部署步骤第一步克隆仓库并定位示例git clone https://gitcode.com/GitHub_Trending/se/semantic-kernel cd semantic-kernel/python/samples/demos/copilot_studio_skill示例目录结构如下仓库内实际文件copilot_studio_skill/ ├── azure.yaml # azd 服务定义Container Apps Docker ├── image.png # 运行效果截图 ├── infra/ # Bicep 基础设施模板main.bicep、bot.bicep、aca.bicep 等 └── src/api/ # SK Skill 后端 API ├── adapter.py # 带错误处理的 CloudAdapter ├── app.py # aiohttp 入口与路由 ├── auth.py # 调用方 Claims 校验器 ├── bot.py # Teams Application 消息处理 ├── config.py # 环境变量配置类 ├── copilot-studio.manifest.json # Skill Manifest 模板 ├── dockerfile ├── requirements.txt └── sk_conversation_agent.py # Semantic Kernel ChatCompletionAgent第二步在 Entra ID 中创建应用注册Skill 需要以 Bot 身份运行因此先在 Microsoft 365 租户Copilot Studio 所在租户中创建 App Registration并生成 client secret。原文档给出的 PowerShell 命令如下az login --tenant COPILOT-tenant-id $appId az ad app create --display-name SKCopilotSkill --query appId -o tsv $secret az ad app credential reset --id $appId --append --query password -o tsv记下三个值它们将用于后续部署与配置$appId→ 对应环境变量BOT_APPID$secret→ 对应环境变量BOT_PASSWORDCOPILOT-tenant-id→ 对应环境变量BOT_TENANT_ID对应关系可从 infra/main.parameters.json 中确认botAppId、botPassword、botTenantId分别绑定到BOT_APPID、BOT_PASSWORD、BOT_TENANT_ID环境变量。第三步使用 azd 一键部署 Azure 资源登录 Azure 订阅后执行azd auth login --tenant AZURE-tenant-id azd up交互过程中需要提供以下输入原文档明确列出提示项来源botAppId上一步的应用注册 App IDbotPassword上一步的 client secretbotTenantIdCopilot Studio 所在租户 ID现有的 Azure OpenAI 资源名及其资源组需提前在 Azure 订阅中创建好此外 main.parameters.json 还暴露了模型相关参数均有默认值openAIModel默认gpt-4oopenAIApiVersion默认2024-08-01-previewapiAppExists默认false是否复用已存在的容器应用部署由 azure.yaml 驱动——它将src/api作为containerapp类型的服务使用仓库内 dockerfile 构建镜像python:3.12-slim基础镜像暴露端口 80运行时环境变量HOST0.0.0.0、PORT80。提示部署完成后API 的 URL 会显示在 Azure Developer CLI 的output部分请复制保存后续注册 Skill 与配置homeUrl都会用到。第四步配置 App Registration 的 homeUrl将第二步创建的 App Registration 的homeUrl设置为已部署 API 的 URL。这是 Bot 能够响应 Copilot Studio 请求的必要条件——原文档强调required for the bot to be able to respond to requests from Copilot Studio。第五步在 Copilot Studio 中把 Bot 注册为 Skill在 Microsoft 365 租户中打开 Copilot Studio新建一个 Agent 或复用已有 Agent在 Agent 页面右上角进入 Settings进入 Skills 标签页点击 Add a skill输入API_URL/manifestAPI_URL即部署输出的 API 地址作为 Skill URL点击 Next 完成注册注册完成后编辑或新建一个 Topic在主题流中添加该 Skill 节点即可开始使用。上图image.png展示的正是这一步的产物左侧是 Copilot Studio 的主题工作流编辑器——Trigger 节点描述为 Jokes通过蓝色箭头连接到 Invoke Semantic Kernel skill 的 Action 节点右侧测试面板中用户提问 Tell me a joke about developersAgent 返回 Why do developers prefer dark mode? Because light attracts bugs!验证了端到端链路已打通。源码级实现解析Skill 后端是如何工作的1. 配置层环境变量即契约config.pyconfig.py 定义了全部运行时配置是理解 Skill 行为的关键入口HOST os.getenv(HOST, localhost) PORT int(os.getenv(PORT, 8080)) APP_ID os.getenv(BOT_APP_ID) # Bot 应用注册 ID APP_PASSWORD os.getenv(BOT_PASSWORD) # Bot 应用注册 client secret APP_TENANTID os.getenv(BOT_TENANT_ID) # 租户 ID APP_TYPE os.getenv(APP_TYPE, singletenant) # 默认单租户 # Required for Copilot Skill ALLOWED_CALLERS os.getenv(ALLOWED_CALLERS, [*]) # 允许调用本 Skill 的父 Bot ID 列表或 * 放行全部 AZURE_OPENAI_CHAT_DEPLOYMENT_NAME os.getenv(AZURE_OPENAI_CHAT_DEPLOYMENT_NAME) AZURE_OPENAI_ENDPOINT os.getenv(AZURE_OPENAI_ENDPOINT) AZURE_OPENAI_API_VERSION os.getenv(AZURE_OPENAI_API_VERSION)validate()方法在模块加载时强制执行配置校验HOST/PORT、APP_ID/APP_PASSWORD/APP_TENANTID、ALLOWED_CALLERS任一缺失都会直接抛异常避免带着错误配置上线。三个值得深挖的配置语义APP_TYPE默认singletenant声明 Bot 的身份验证模式单租户模式下令牌校验范围被限定在APP_TENANTID指定的租户内是多租户安全的第一道闸门ALLOWED_CALLERS声明允许调用本 Skill 的父 Bot即 Copilot Studio 一侧的 AgentApp ID 白名单默认[*]表示放行所有 Agent。生产环境务必改为具体的 App ID 列表见下方 auth.py 的校验逻辑Azure OpenAI 三件套AZURE_OPENAI_CHAT_DEPLOYMENT_NAME、AZURE_OPENAI_ENDPOINT、AZURE_OPENAI_API_VERSION会被AzureChatCompletion消费由 azd 部署时注入。2. 入口层aiohttp 应用与 Manifest 动态生成app.pyapp.py 实现两个端点/api/messages读取请求 JSON 后直接交给bot.process(req)。原文档与代码注释都强调了一个 Skill 特有约束在 Skill 上下文中必须把响应作为请求的返回值返回给 Copilot Studio而在 Teams 等其他渠道中Activity 是由 Bot Framework 主动推送的/manifest读取copilot-studio.manifest.json模板用容器应用的实际 FQDN 与 Bot App ID 做字符串替换后返回fqdn fhttps://{os.getenv(CONTAINER_APP_NAME)}.{os.getenv(CONTAINER_APP_ENV_DNS_SUFFIX)}/api/messages manifest manifest.replace(__botEndpoint, fqdn).replace(__botAppId, config.APP_ID)即 Manifest 中endpointUrl最终指向https://容器应用FQDN/api/messagesmsAppId指向 Bot 的 App ID。3. 清单层Copilot Studio Skill Manifestcopilot-studio.manifest.jsoncopilot-studio.manifest.json 是 Copilot Studio 识别 Skill 的名片核心字段包括$schemaBot Framework Skill Manifest v2.2 的 JSON Schema$id/name/version/description/publisherNameSkill 的标识与描述信息endpoints声明BotFrameworkV3协议的默认端点endpointUrl与msAppId为__botEndpoint/__botAppId占位符由/manifest端点动态替换activities声明本 Skill 支持message类型的 ActivityInvoke Semantic Kernel skill这是 Copilot Studio 与 Skill 交互的唯一活动类型。4. 对话层Teams Application Semantic Kernel Agentbot.py 与 sk_conversation_agent.pybot.py 使用teams-ai的Application[TurnState]构建 Bot 应用bot ApplicationTurnState, adapterAdapterWithErrorHandler(ConfigurationBotFrameworkAuthentication(config, auth_configurationauth)), ) )注意代码注释中的关键提醒adapter参数不能传 dict必须传一个带APP_ID、APP_PASSWORD、APP_TENANTID属性的类实例——这里的config对象恰好满足这一契约。对话逻辑通过两个事件装饰器挂载bot.before_turn async def setup_chathistory(context, state): chat_history state.conversation.get(chat_history) or ChatHistory() state.conversation[chat_history] chat_history return state bot.activity(message) async def on_message(context, state): user_message context.activity.text chat_history.add_user_message(user_message) sk_response await agent.get_response(historychat_history, user_inputuser_message) state.conversation[chat_history] chat_history await context.send_activity(MessageFactory.text(sk_response, input_hintInputHints.ignoring_input)) end Activity.create_end_of_conversation_activity() end.code EndOfConversationCodes.completed_successfully await context.send_activity(end) return True几个要点多轮记忆利用TurnState的 conversation 级存储把 Semantic Kernel 的ChatHistory持久化在会话状态中实现跨轮次的上下文连续SK 对话后端调用agent.get_response(historychat_history, user_inputuser_message)。代码注释标明该 API 需要semantic-kernel1.22.0见 requirements.txtSkill 协议收尾响应后必须发送EndOfConversation活动completed_successfully告知 Copilot Studio 本轮对话结束。注释也提醒真实 Skill 中应在用户完成目标任务后再发送而非像示例这样每轮都立即结束。sk_conversation_agent.py 则是最简的 Semantic Kernel Agent 构造from azure.identity import AzureCliCredential from semantic_kernel.agents import ChatCompletionAgent from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion agent ChatCompletionAgent( serviceAzureChatCompletion(credentialAzureCliCredential()), nameChatAgent, instructionsYou invent jokes to have a fun conversation with the user., )使用ChatCompletionAgentSemantic Kernel 的对话补全 Agent 抽象连接器为AzureChatCompletion凭证采用AzureCliCredential在 Azure 环境内亦可替换为工作负载身份等托管身份凭证instructions即系统提示词是 SK Agent 的行为底座可自由替换为你的业务指令。5. 安全层调用方校验与错误处理auth.py 与 adapter.py调用方白名单校验auth.pyauth.py 实现AllowedCallersClaimsValidator其核心逻辑将ALLOWED_CALLERS配置转为frozenset在claims_validator中当白名单不含*且请求带有 Skill 声明SkillValidation.is_skill_claim(claims)时从令牌中提取appId若不在白名单则抛出PermissionError该 validator 通过AuthenticationConfiguration注入 Bot 认证流程见 bot.py 中auth AuthenticationConfiguration(tenant_id..., claims_validator...)。代码注释明确指出不添加 claims validator 会导致 Skill 运行报错——这是 Skill 模式与普通 Bot 的关键差异之一。错误处理适配器adapter.pyadapter.py 的AdapterWithErrorHandler继承CloudAdapter在 turn 异常时向用户发送友好错误消息The skill encountered an error or bug.发送 trace activity 供 Bot Framework Emulator 排查向 Skill 调用方父 Bot发送EndOfConversation活动code 为SkillErrortext 携带异常信息让调用方决定后续处理。这保证了 Skill 异常不会导致父 Agent 挂起是生产化部署的必要加固。关键注意事项与生产化建议综合原文档与源码以下坑点与建议值得重点记录框架选择受限Python 的 Bot Framework SDK 目前仅支持 aiohttp不要尝试用 FastAPI/Flask 直接替换Skill 必须同步返回响应/api/messages的 HTTP 响应就是给 Copilot Studio 的回复这与 Teams 等主动推送渠道的编程模型不同必须实现 claims validatorALLOWED_CALLERS白名单校验是 Skill 安全的基础生产环境不要保留*通配记得发送 EndOfConversation一轮对话结束要显式发送该活动成功用completed_successfully异常用SkillError否则调用方可能一直等待homeUrl必须指向已部署 API否则 Copilot Studio 无法回调你的 Skill配置即契约BOT_APP_ID、BOT_PASSWORD、BOT_TENANT_ID等环境变量名是 Bot Framework 与 azd 参数映射的固定约定config.py 中特意注释 DO NOT CHANGE THIS KEYS!!模型参数可调通过 azd 参数可指定 Azure OpenAI 模型默认gpt-4o与 API 版本默认2024-08-01-preview需与你的 Azure OpenAI 资源实际部署保持一致。总结本示例展示了一条完整且可复用的低代码 Pro-Code混合扩展路径Copilot Studio 负责用户体验与流程编排Semantic Kernel 负责 LLM 驱动的对话智能。你可以在此基础上将sk_conversation_agent.py中的简单笑话 Agent 替换为接入插件Plugin、函数调用Function Calling、向量检索RAG等能力的完整业务 Agent并通过ALLOWED_CALLERS白名单、错误处理适配器与托管身份认证将 Skill 推向生产环境。示例全部源码位于 python/samples/demos/copilot_studio_skill基础设施模板集中在 infra 目录可作为你落地同类集成的起点。【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表