跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C#SaaSAI

C# 扩展 Dynamics 365 Copilot:自定义插件与场景实战

Dynamics 365 Copilot 扩展方案通过 C# 插件结合 Dataverse 数据与 Azure OpenAI,实现定制化 AI 交互。核心流程涵盖插件注册、请求拦截及响应构建,需注意性能优化与权限控制。该方案适用于零售等行业场景,支持从订单状态查询到自然语言回复的完整闭环。

moshang发布于 2026/4/5更新于 2026/10/2599 浏览

C# 扩展 Dynamics 365 Copilot:自定义插件与场景实战

Dynamics 365 Copilot 作为基于 AI 的智能助手,为企业用户提供了自动化流程、智能分析和自然语言交互的能力。不过,通用功能往往无法满足特定行业或企业的定制化需求。要实现这一点,关键在于通过 C# 编写自定义插件,扩展 Dynamics 365 Copilot 的能力,并结合实际业务场景实现定制化 AI 交互。

架构基础

Dynamics 365 Copilot 的扩展主要依赖于 Power Platform 插件框架 和 Copilot Studio 的自定义连接器。核心技术栈包括:

  • C# (.NET Framework 4.8 或 .NET 6+):编写业务逻辑插件
  • Dynamics 365 SDK:与 Dataverse 数据交互
  • Azure OpenAI / 自定义 LLM 接口:扩展 AI 生成能力
  • Power Platform 注册工具:部署插件到 Dynamics 365 环境

扩展的核心逻辑是:通过 C# 插件拦截 Copilot 的交互请求,注入自定义业务规则,调用外部 AI 服务或 Dataverse 数据,最终返回定制化的 AI 响应。

环境准备

首先准备好开发环境。需要安装 Visual Studio 2022(带 .NET 桌面开发和 Azure 开发工作负载)、Dynamics 365 SDK(最新版本)以及 Power Platform CLI(用于插件注册)。确保拥有一个有效的 Dynamics 365 环境,并已启用 Copilot 权限。

创建 Dynamics 365 插件项目时,可以通过 Power Platform CLI 初始化:

pac plugin init --name CopilotCustomPlugin --template ClassLibrary 

实战示例:定制客户服务 Copilot

业务场景

某零售企业需要定制 Copilot 能力:当用户通过 Copilot 查询客户订单状态时,Copilot 能自动从 Dataverse 中读取该客户的订单数据,并结合 AI 生成结构化、个性化的回复(而非通用话术)。

代码实现

插件核心逻辑

这是插件的入口类,继承 IPlugin 接口。执行方法负责获取上下文、校验参数、查询数据并构建响应。

using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Linq;
using System.Text;

// 插件入口类,继承 IPlugin 接口
public class CustomerOrderCopilotPlugin : IPlugin
{
    // 插件执行方法(核心入口)
    public void Execute(IServiceProvider serviceProvider)
    {
        // 1. 获取插件执行上下文
        IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        
        // 2. 获取组织服务(用于操作 Dataverse 数据)
        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

        try
        {
            // 3. 从 Copilot 请求中提取参数(客户名称/ID、查询类型)
            string customerId = context.InputParameters["CustomerId"]?.ToString();
            string queryType = context.InputParameters["QueryType"]?.ToString();

            // 校验必填参数
            if (string.IsNullOrEmpty(customerId) || queryType != "OrderStatus")
            {
                throw new InvalidPluginExecutionException("无效的查询参数:请提供客户 ID 并选择订单状态查询");
            }

            // 4. 从 Dataverse 查询客户订单数据
            var orderData = GetCustomerOrders(service, customerId);

            // 5. 构建定制化的 Copilot 响应内容
            string copilotResponse = BuildCopilotResponse(orderData);

            // 6. 将响应写入输出参数,返回给 Copilot
            context.OutputParameters["CopilotResponse"] = copilotResponse;
        }
        catch (Exception ex)
        {
            // 插件异常处理(Dynamics 365 标准规范)
            throw new InvalidPluginExecutionException("客户订单查询插件执行失败:" + ex.Message, ex);
        }
    }

    /// <summary>
    /// 从 Dataverse 查询指定客户的订单数据
    /// </summary>
    private EntityCollection GetCustomerOrders(IOrganizationService service, string customerId)
    {
        // 构建查询表达式(查询 salesorder 实体)
        QueryExpression query = new QueryExpression("salesorder")
        {
            ColumnSet = new ColumnSet("name", "salesorderid", "statuscode", "totalamount", "createdon"),
            Criteria = new FilterExpression
            {
                Conditions = { new ConditionExpression("customerid", ConditionOperator.Equal, new Guid(customerId)) }
            },
            // 按创建时间降序排列
            Orders = { new OrderExpression("createdon", OrderType.Descending) }
        };

        // 执行查询并返回结果
        return service.RetrieveMultiple(query);
    }

    /// <summary>
    /// 构建 Copilot 定制化响应内容
    /// </summary>
    private string BuildCopilotResponse(EntityCollection orders)
    {
        if (orders.Entities.Count == 0)
        {
            return "未查询到该客户的任何订单记录。";
        }

        // 构建结构化回复(结合业务规则定制话术)
        var responseBuilder = new StringBuilder();
        responseBuilder.AppendLine($"为您查询到 {orders.Entities.Count} 条订单记录:\n");

        foreach (var order in orders.Entities)
        {
            string orderName = order["name"].ToString();
            string orderStatus = GetOrderStatusText(order.GetAttributeValue<OptionSetValue>("statuscode").Value);
            decimal totalAmount = order.GetAttributeValue<Money>("totalamount").Value;
            DateTime createDate = order.GetAttributeValue<DateTime>("createdon");

            responseBuilder.AppendLine($"订单编号:{orderName}");
            responseBuilder.AppendLine($"状态:{orderStatus}");
            responseBuilder.AppendLine($"金额:{totalAmount:C}");
            responseBuilder.AppendLine($"创建时间:{createDate:yyyy-MM-dd HH:mm}\n");
        }

        responseBuilder.AppendLine("如需了解某笔订单的详细进度,可直接说出订单编号,我会为您进一步查询。");
        return responseBuilder.ToString();
    }

    /// <summary>
    /// 将订单状态码转换为易读文本(适配中文场景)
    /// </summary>
    private string GetOrderStatusText(int statusCode)
    {
        return statusCode switch
        {
            1 => "草稿",
            2 => "已提交",
            3 => "已批准",
            4 => "已发货",
            5 => "已完成",
            6 => "已取消",
            _ => "未知状态"
        };
    }
}
注册辅助类

这部分代码用于辅助注册插件到 Dynamics 365 环境,通常配合 Power Platform CLI 使用。

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using System;
using System.ServiceModel;

// 插件注册辅助类(用于 Power Platform CLI 部署)
public class PluginRegistrationHelper
{
    /// <summary>
    /// 注册插件到 Dynamics 365 环境
    /// </summary>
    public static void RegisterPlugin(Uri serviceUri, string username, string password, string domain)
    {
        // 构建认证凭据
        ClientCredentials credentials = new ClientCredentials();
        credentials.UserName.UserName = username;
        credentials.UserName.Password = password;

        // 创建组织服务代理
        using (OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(serviceUri, null, credentials, null))
        {
            serviceProxy.EnableProxyTypes();
            CreatePluginStep(serviceProxy, "new_CopilotCustomerOrderQuery", "CustomerOrderCopilotPlugin", "Microsoft.Crm.Sdk.Messages.ExecutePluginRequest");
        }
    }

    private static void CreatePluginStep(IOrganizationService service, string messageName, string pluginTypeName, string requestType)
    {
        // 插件步骤创建逻辑(简化版,实际部署建议使用 Power Platform CLI)
        Entity pluginStep = new Entity("sdkmessageprocessingstep")
        {
            ["name"] = $"Copilot_{messageName}_Step",
            ["sdkmessageid"] = new EntityReference("sdkmessage", new Guid("替换为实际消息 ID")),
            ["pluginassemblyid"] = new EntityReference("pluginassembly", new Guid("替换为程序集 ID")),
            ["plugintypeid"] = new EntityReference("plugintype", new Guid("替换为插件类型 ID")),
            ["stage"] = 40, // 操作后执行
            ["mode"] = 0, // 同步模式
            ["rank"] = 1
        };
        service.Create(pluginStep);
    }
}

部署与集成

编译与注册

在 Visual Studio 中编译项目,生成强名称签名的 DLL(右键项目 → 属性 → 签名 → 选择强名称密钥文件)。随后使用 Power Platform CLI 将 DLL 注册到 Dynamics 365 环境:

# 登录 Dynamics 365 环境
pac auth create --url https://your-org.crm.dynamics.com

# 注册插件程序集
pac plugin register --assembly "bin\Debug\CopilotCustomPlugin.dll" --serviceprincipalid "你的 SPN ID" --serviceprincipalsecret "你的 SPN 密钥"

Copilot Studio 集成

  1. 打开 Copilot Studio,创建新的自定义主题'客户订单查询';
  2. 添加'调用自定义插件'操作,绑定上述 C# 插件;
  3. 配置输入参数(客户 ID)和输出参数(Copilot 响应);
  4. 发布自定义主题,关联到 Dynamics 365 应用。

进阶:集成外部 LLM

如果需要进一步增强 AI 生成能力,可以在插件中调用 Azure OpenAI API,结合业务数据生成更自然的回复:

// 新增方法:调用 Azure OpenAI 生成定制化回复
private string GenerateAiResponseWithOpenAI(string orderData)
{
    var openAIClient = new Azure.AI.OpenAI.OpenAClient(
        new Uri("https://your-openai-resource.openai.azure.com/"),
        new Azure.AzureKeyCredential("你的 OpenAI API 密钥"));

    var chatCompletionsOptions = new Azure.AI.OpenAI.ChatCompletionsOptions()
    {
        DeploymentName = "gpt-35-turbo",
        Messages =
        {
            new Azure.AI.OpenAI.ChatMessage(Azure.AI.OpenAI.ChatRole.System, "你是零售企业的客户服务助手,需基于提供的订单数据生成友好、简洁的中文回复,避免技术术语。"),
            new Azure.AI.OpenAI.ChatMessage(Azure.AI.OpenAI.ChatRole.User, $"基于以下订单数据生成回复:{orderData}")
        },
        Temperature = 0.7f,
        MaxTokens = 500
    };

    var response = openAIClient.GetChatCompletions(chatCompletionsOptions);
    return response.Value.Choices[0].Message.Content;
}

关键注意事项

  1. 性能优化:插件执行超时时间默认 2 分钟,需优化 Dataverse 查询(使用分页、索引);
  2. 权限控制:插件以当前用户身份执行,需为用户分配 salesorder 实体的读取权限;
  3. 异常处理:必须捕获并抛出 InvalidPluginExecutionException,确保错误信息能返回给 Copilot;
  4. 版本管理:插件更新需通过 Power Platform CLI 重新注册,建议保留历史版本。

总结

Dynamics 365 Copilot 可通过 C# 插件扩展,核心是实现 IPlugin 接口并拦截 Copilot 交互请求,结合 Dataverse 数据定制 AI 响应。自定义插件的核心流程为:提取请求参数 → 查询业务数据 → 构建定制化响应 → 返回给 Copilot。进阶场景可集成 Azure OpenAI 等外部 LLM,进一步增强 Copilot 的自然语言生成能力,同时需注意插件的性能、权限和异常处理。

目录

  1. C# 扩展 Dynamics 365 Copilot:自定义插件与场景实战
  2. 架构基础
  3. 环境准备
  4. 实战示例:定制客户服务 Copilot
  5. 业务场景
  6. 代码实现
  7. 插件核心逻辑
  8. 注册辅助类
  9. 部署与集成
  10. 编译与注册
  11. 登录 Dynamics 365 环境
  12. 注册插件程序集
  13. Copilot Studio 集成
  14. 进阶:集成外部 LLM
  15. 关键注意事项
  16. 总结

更多推荐文章

查看全部
  • 米家 API Python 智能家居控制指南
  • Ubuntu 22.04 下基于 ROS2 Humble 的 PX4 无人机仿真环境搭建
  • Openclaw 结合 Seed2.0 Skills 实现 AI 漫剧自动化生成
  • 宇树机器人 G1 二次开发:导航仿真与地图转换教程
  • Stable Diffusion 秋葉 aaaki 整合包安装与云主机配置指南
  • Office 区域不支持 Copilot 的解决方法
  • 从 0 到 1 打造 RISC-V 智能家居中控:硬件 + 固件 + 通信全链路实战
  • Qwen3-VL WebUI 本地部署与核心功能实战指南
  • MCPo:将 MCP 协议转换为 OpenAPI 的代理服务器实践
  • Claude Code 安装配置与使用指南
  • Electron 前端跨平台桌面应用开发快速入门教程
  • Z-Image Turbo 本地部署与使用指南
  • intv_ai_mk11 开源模型实战:Llama 架构中文优化细节解析
  • Git 在 Windows 系统上的安装与配置指南
  • 鸿蒙 WebView 混合开发中 Web 内部网络请求跨域问题的客户端解决方案
  • Android 中高级开发技术面试真题与解析
  • KWDB 运维实战:用 SQL 融合 Metrics 与 CMDB 数据
  • LazyLLM 多 Agent 应用全流程实践:从源码部署到可视化 Web 调试
  • Vivado 工程 Git 版本管理实战指南
  • 贪心算法核心思想与 LeetCode 经典例题解析

相关免费在线工具

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online