Dynamics 365 Sales 中的推荐操作智能体可为商机、潜在客户、客户和联系人显示按优先级排序的建议。 它提供共享的评分流程、数据合同和双向状态同步,使任何定制代理都能与第一方代理同时呈现推荐。
本文描述了自定义代理与推荐动作代理集成时所使用的架构、关键组件、数据合同和集成流程。 它提供了实施集成所需的基础知识。
先决条件
NextBestActionAgent 解决方案已部署到目标组织。 更多信息请参见 “将代理导入目标环境”。
一个稳定且唯一的自定义代理 SourceAgentId 字符串。 有关详细信息,请参阅 为推荐操作添加自定义代理。
推送推荐操作需要以下权限:
表 所需权限 Scope msdyn_rawactioncatalogue 读取、写入、追加和 AppendTo 全球 msdyn_prioritizedactioncatalogue 读取、写入、追加和 AppendTo 全球 msdyn_recommendedactionsourceagentconfig 阅读 全球 msdyn_salesagentprofile 阅读 全球
集成体系结构
推荐操作代理集成采用一个处理管道,该管道接收源代理提供的原始操作项,使用UICE(紧迫性、影响、置信度、工作量)评分引擎对其评分,并在卖家轮播中展示按优先级排序的结果。
处理流程如下:
- 定制代理 检测到可操作的洞察(例如交易风险、停滞交易或缺失的利益相关者)。
-
自定义代理调用
msdyn_PushActionDataToRecommendedActionAgent自定义 API 来推送该动作。 - 操作存储在
msdyn_rawactioncatalogue(输入表)中。 - 对于每个动作, 计分引擎:
- 从 Dataverse 提取实体信号。
- 从操作目录中提取特定于代理的优先顺序数据。
- 调用 LLM 根据 UICE(紧急程度、影响、置信度、工作量)维度对操作进行评分。
- 应用下限和上限规则。
- 通过使用
GetRecommendedActionAgentResponse计算最终优先级得分。
- 已评分的操作被插入到
msdyn_prioritizedactioncatalogue(输出表)中。 - 推荐操作轮播会获取已评分的操作,并在该实体的列表视图中呈现卡片,前提是已为该实体启用该轮播。
重要组件
该集成依赖于以下Dataverse表和API。
| 组件 | 位置 | 说明 |
|---|---|---|
| 输入表 | msdyn_rawactioncatalogue(Dataverse) | 自定义代理推送的原始动作 |
| 输出表 | msdyn_prioritizedactioncatalogue (Dataverse) | UI 操作的评分和排序 |
| 代理配置 | msdyn_recommendedactionsourceagentconfig (Dataverse) | 每个代理的注册和配置 |
| 推送 API | msdyn_PushActionDataToRecommendedActionAgent(自定义 API) | 智能体 → 建议的操作智能体操作推送 |
代理注册
将自定义代理注册到推荐操作代理中,这样平台才能识别并获取他们的操作。 有关注册代理的更多信息,请参见 添加自定义代理以获取推荐操作。
当你注册代理时,它会在msdyn_recommendedactionsourceagentconfig中创建一个条目。 唯一的 SourceAgentId 用于标识该自定义代理的条目。
代理配置
该 msdyn_recommendedactionsourceagentconfig 表包含每个代理的配置,规范推荐动作代理如何解释代理的行为。 两个最重要的填充字段是 msdyn_internalprioritizationinstruction 和 msdyn_syncactionexecutionstateapiconfig。
你可以手动更新表记录,或者调用自定义 API UpsertRecommendationAgentConfigRequest来应用配置。
UpsertRecommendationAgentConfigRequest 架构
以下示例展示了该模式中可用的配置字段。
{
"agentName": "YourAgentName",
"agentType": "CustomAgent",
"isRecommendedActionAgentEnabled": true,
"salesAgentProfileId": "<SourceAgentId that was configured>",
"agentImpactMapping": "[]",
"internalPrioritizationInstruction": "{\"signals\":[...]}",
"syncActionExecutionStateApiConfig": "{\"syncactionuistatusapiname\":\"your_SyncBackCustomApiName\"}",
"description": "Brief description of your agent"
}
| JSON 字段 | 类型 | 说明 |
|---|---|---|
| agentName | 字符串 | 映射到 msdyn_agentname(最多 850 个字符)。 新建记录时必填。 |
| 代理类型 | 字符串 | 代理类别。 使用“CustomAgent”自动创建个人资料。 |
| isRecommendedActionAgentEnabled | 布尔 | 映射到 msdyn_isrecommendedactionagentenabled。 Null = 保持不变。 |
| salesAgentProfileId | guid? | 链接到 msdyn_salesagentprofile。 用于 upsert 操作中的记录查找。 |
| agentImpactMapping | 字符串 | 主体名称的平面JSON数组。 映射到 msdyn_agentimpactmapping。 |
| 内部优先级排序指令 | 字符串 | 包含信号数组的 JSON 映射到 msdyn_internalprioritizationinstruction。 |
| syncActionExecutionStateApiConfig | 字符串 | JSON 对象 {"syncactionuistatusapiname":"..."}。 映射到 msdyn_syncactionexecutionstateapiconfig。 |
| sourceAgentUniqueId | 字符串 | 映射到 msdyn_sourceagentuniqueid。 |
| 描述 | 字符串 | 映射到 msdyn_sourcedescription(最多 1000 个字符)。 |
内部优先顺序指令
内部优先级指令包含代理专属信号元数据,告诉评分引擎如何解读代理的优先级数据字段。 它是一个带有顶层 signals 数组的 JSON 对象。 每个信号都会被反序列化为 AgentSignalInstructionConfig,包含以下字段:
| Field | 类型 | 说明 |
|---|---|---|
| 名字 | 字符串 | 信号标识符 — 用作评分提示中“信号参考”部分的键 |
| 类型 | 字符串 | 数据类型:“字符串”、“数字”、“布尔值” |
| 源 | 字符串 | 信号的来源的描述性标签。 不用于路由——fetch_info.fetch_type 控制实际的获取机制。 通常用“action_data”表示代理推送的信号。 |
| 维度_影响 | {维度:力量} | 此信号影响哪些 UICE 维度以及信号的强烈程度。 关键:“紧迫感”、“影响力”、“自信”、“努力”。 优势:“强”、“中等”、“弱” |
| 解释 | 字符串 | 关于该信号对评分意味着什么的自然语言描述——注入到LLM提示词中 |
| 可靠性 | 字符串 | 这个信号的可靠性:“高”、“中”、“低” |
| (必需) | 布尔 | 信号是否必须存在才能进行评分 |
| fetch_info | 对象 | 控制在评分时检索信号值的位置和方式。 |
信号块示例:
{
"signals": [
{
"name": "risk_type",
"type": "string",
"source": "action_data",
"dimension_influence": { "urgency": "moderate", "confidence": "weak" },
"interpretation": "Risk category code assigned by the source agent (e.g. 8 = Missing BANT Info). Used for pre-filter rule matching and prompt context.",
"reliability": "high",
"required": false,
"fetch_info": { "fetch_type": "action_data", "crm_field": "riskType" }
},
{
"name": "risk_label",
"type": "string",
"source": "action_data",
"dimension_influence": { "urgency": "weak", "confidence": "weak" },
"interpretation": "Human-readable risk name from the source agent (e.g. 'Missing BANT Info', 'Stalled Pipeline'). Useful for prompt context and seller explanation.",
"reliability": "high",
"required": false,
"fetch_info": { "fetch_type": "action_data", "crm_field": "risk" }
}
]
}
同步操作执行状态 API 配置
同步操作执行状态 API 配置为一个 JSON 对象,用于指定“推荐操作”代理在卖家对卡片执行操作时调用的自定义 API 名称(例如将其标记为已完成或不相关)。 此 API 设置源自定义代理中操作的状态。
{
"syncactionuistatusapiname": "your_SyncBackCustomApiName"
}
操作推送契约
自定义代理通过自定义 msdyn_PushActionDataToRecommendedActionAgent API推送动作。 每次代理为目标实体生成或更新动作时都会调用该 API。
请求参数
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| msdyn_ActionId | 字符串 | 是 | 智能体在此操作中的唯一标识符。 用于重复数据删除和状态同步。必须具有确定性(相同的操作 = 相同的 ID)。 示例格式:DealRisk_{opportunityId}_{riskType} |
| msdyn_SourceAgentId | 字符串 | 是 | 代理的标识符。 必须与代理配置记录中的msdyn_agentname匹配。 示例:“DealClosingAgent” |
| msdyn_TargetEntityId | uniqueidentifier (GUID) | 是 | 此操作关联的目标记录(商机、潜在客户)的 GUID |
| msdyn_TargetEntityTypeName | 字符串 | 是 | 目标实体的逻辑名称。 示例:“opportunity”、“lead” |
| msdyn_ActionReason | 字符串 | 是 | 生成操作的原因。 由评分引擎用于基本映射。 |
| msdyn_ActionUIPayload | 字符串 | 否 | 用于卡片渲染的 JSON 负载。 如果遗漏,推荐操作代理将无法显示该卡片。 |
| msdyn_ActionPrioritizationData | 字符串 | 否 | 带有代理特定数据用于评分的 JSON |
| msdyn_ActionCTA | 字符串 | 否 | CTA 类型为字符串。 示例:“电子邮件”、“审核”、“电话” |
| msdyn_PrioritizationPrinciples | 字符串 | 否 | 此特定操作映射到的优先顺序原则的 JSON 数组(可以替代代理级映射) |
示例:C# 插件调用
以下示例创建并执行请求,将交易风险动作推送到推荐行动代理。 请求会识别源代理和目标机会,提供原因和卡片界面负载,包含优先级风险信号,并检查操作是否成功。
var request = new OrganizationRequest("msdyn_PushActionDataToRecommendedActionAgent")
{
["msdyn_ActionId"] = $"DealRisk_{opportunityId}_{riskType}",
["msdyn_SourceAgentId"] = "DealClosingAgent",
["msdyn_TargetEntityId"] = opportunityId, // Guid
["msdyn_TargetEntityTypeName"] = "opportunity",
["msdyn_ActionReason"] = "Customer has not responded in 14 days, deal is at risk of stalling",
["msdyn_ActionUIPayload"] = JsonConvert.SerializeObject(new
{
version = "1.0",
payload = new
{
header = "Follow up with Contoso",
description = "No customer response in 14 days. Deal may stall without re-engagement.",
oncardClickActionType = "Navigate",
oncardClickActionTypeParameters =
"{etn=\"opportunity\", id=\"aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb\", pagetype=\"entityrecord\"}"
}
}),
["msdyn_ActionPrioritizationData"] = JsonConvert.SerializeObject(new
{
riskType = "14",
risk = "low"
})
};
var response = orgService.Execute(request);
bool success = (bool)response["msdyn_IsSuccess"];
Action UI 负载契约
该 msdyn_ActionUIPayload 字段包含一个 JSON 负载,用于控制动作卡在推荐行动代理轮播中的出现方式。
{
"version": 1.0,
"header": "Follow up with Contoso on pricing proposal",
"description": "Stakeholder engagement has dropped. The customer expressed interest in the enterprise tier but hasn't responded to the last proposal sent 10 days ago.",
"oncardClickActionType": "Navigate",
"oncardClickActionTypeParameters": "{\"etn\":\"opportunity\",\"id\":\"<guid>\",\"pagetype\":\"entityrecord\"}",
"onctaClickActionType": "Navigate",
"onctaClickActionTypeParameters": "{\"etn\":\"opportunity\",\"id\":\"<guid>\",\"pagetype\":\"entityrecord\"}"
}
优先级划分数据契约
该 msdyn_prioritizationdata 字段允许代理传递代理特定的信号,影响 UICE 评分引擎如何优先排序动作。
[
{ "signalName": "risk", "value": "low" },
{ "signalName": "riskType", "value": "4" }
]
评分引擎会将这些信号与实体级信号(交易价值、阶段、竞争者等)并行读取。 代理配置中的 msdyn_internalprioritizationinstruction 会告诉 LLM 如何解释每个信号,而评分引擎会将所有信号整合到 UICE 评分提示词中。
激活推荐操作旋转木马
启用推荐操作轮播,使其显示在实体的列表视图中。 该 aiinsightcard 实体控制每个实体旋转木马的激活状态。 确保该实体对应的 aiinsightcard 记录处于活动状态。
下表显示了针对某个实体激活或停用轮播时应设置的值:
| 卡状态 | statecode |
statuscode |
|---|---|---|
| 积极 | 0 |
1 |
| 非活动 | 1 |
2 |
操作版本化与失效处理
当代理更新之前推送过的动作数据时,会再次调用msdyn_PushActionDataToRecommendedActionAgent,创建一个包含相同msdyn_ActionId内容的新记录。 系统会在msdyn_rawactioncatalogue中创建一个新行,该行具有相同的msdyn_actionid,但使用新的msdyn_rawactioncatalogueid。 推荐操作代理会一直显示旧版本,直到处理新版本。
要使某项操作失效(例如,在风险已解除时),代理会使用 actionId 调用 msdyn_RAAgent_RemoveActionsV2 自定义 API。 此操作将该操作的所有 msdyn_rawactioncatalogue 记录标记为非活动状态,且卡片将从轮播中消失。
双向状态同步
操作状态会在“推荐操作”代理轮播和您的自定义代理中保持同步,确保卖家无论在哪里处理某项操作,都能看到一致的信息。
推荐操作代理 → 自定义代理(卖家在轮播中执行操作): 当卖家在轮播中将某项操作标记为 “完成” 或 “已忽略” 时:
- 建议的操作智能体将
msdyn_actionuistatus更新为msdyn_prioritizedactioncatalogue。 - 建议的操作智能体从智能体配置中读取
msdyn_syncactionexecutionstateapiconfig。 - 推荐操作代理会调用该代理的自定义 API:
| 参数 | 类型 | 说明 |
|---|---|---|
| actionid | GUID | 操作标识符 |
| 状态 | 字符串 | “MarkedDone” 或 “Dismissed” |
代理必须实现一个自定义API,接受这两个参数并更新其自身数据存储中的动作状态。
定制代理 → 推荐操作代理(卖家在代理界面中操作): 当卖家在代理自身界面中执行某项操作(例如,在自定义代理页面上标记为缓解)时,代理通过调用 msdyn_SyncActionExecutionStateFromAgent将该状态同步到推荐操作代理。 此操作会更新“建议的操作智能体”输出表中的状态,使其从轮播栏中隐藏。
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| msdyn_ActionId | 字符串 | 是 | 操作标识符(与推送时相同) |
| msdyn_ActionState | 整数 | 是 | 新状态 — 值(映射到 MarkAsDone/Dismissed) |
| msdyn_TargetEntityId | 唯一标识符 (uniqueidentifier) | 是 | 目标实体 GUID |
| TargetEntityTypeName | 字符串 | 是 | 目标实体逻辑名称 |
| msdyn_TrackingId | 字符串 | 否 | 可选跟踪/关联 ID |
测试和验证
配置和实现后,通过以下检查验证端到端流程。
验证代理配置:
GET [org-url]/api/data/v9.2/msdyn_recommendedactionsourceagentconfigs
?$filter=msdyn_agentname eq 'YourAgentName'
&$select=msdyn_agentname,msdyn_agentimpactmapping,msdyn_internalprioritizationinstruction,msdyn_syncactionexecutionstateapiconfig
通过调用 msdyn_PushActionDataToRecommendedActionAgent 推送一个测试操作,并验证 msdyn_IsSuccess 为 true,且 msdyn_rawactioncatalogue 中出现一条新记录。
通过调用 msdyn_RAAgent_TriggerRecommendedActionsAgentOrchestration 按需触发评分(而不是等待 4 小时计时器)。
核实评分结果:
GET [org-url]/api/data/v9.2/msdyn_prioritizedactioncatalogues
?$filter=msdyn_actionid eq 'your-action-id'
&$select=msdyn_actionid,msdyn_actionscore,msdyn_actionuipayload,msdyn_hascrossedceiling,msdyn_hascrossedfloor,msdyn_actionuistatus,msdyn_scoredetails
预期值:
-
msdyn_actionscore用 0-10 范围内的值填充。 -
msdyn_hascrossedfloor为 false (该操作处于阈值以上,并在轮播栏中显示)。 -
msdyn_actionuistatus是1(主动)。 -
msdyn_scoredetails包含 LLM 生成的说明。
通过在 Dynamics 365 Sales 中打开“商机”表单并检查“建议操作”部分,验证轮播栏的显示效果。 通过在轮播栏中关闭一项操作(应调用同步回传 API 并传入 state = "Dismissed")以及在智能体界面中标记一项操作(输出表记录应反映更新的 msdyn_actionuistatus),验证状态同步。
示例:销售商机智能体
销售商机智能体是首个接入“建议的操作智能体”的智能体,其集成方案作为参考实现。
代理配置值:
| 配置字段 | 销售商机智能体的值(来自 OraDefaults.cs) |
|---|---|
| msdyn_agentname | "SalesOpportunityAgent" |
| msdyn_agentimpactmapping | [“交易风险”、“交易速度”] |
| msdyn_syncactionexecutionstateapiconfig | {"syncactionuistatusapiname":"msdyn_SyncDealRiskActionFromNba"} |
| msdyn_internalprioritizationinstruction | 查看销售机会代理的 产值 |
当销售机会代理完成研究并识别出交易风险时,DealRiskToNBAService会将每项风险作为单独的操作项推送:
| 推送参数 | 销售商机智能体值 |
|---|---|
| msdyn_ActionId | DealRisk_{opportunityId}_{riskType} |
| msdyn_SourceAgentId | “交易风险代理” |
| msdyn_TargetEntityTypeName | “机会” |
| msdyn_ActionReason | 来自研究的风险描述 |
| msdyn_ActionUIPayload | 具有风险标头的卡片 + 说明 |
| msdyn_ActionPrioritizationData |
{"riskType":"8","risk":"Missing BANT Info"} (示例) |
状态同步行为:
-
销售机会代理 → 推荐操作代理: 当卖家在调研页面将某个风险标记为已完成时,代理会调用
msdyn_SyncActionExecutionStateFromAgent。 -
建议的操作智能体 → 销售商机智能体:当销售人员在轮播卡片中关闭某张卡片时,建议的操作智能体会调用
ora_UpdatedActionStateFromRAAgent(在智能体配置中设置)。