- API 文档
- CLI
- 集成指南
- 博客
Communications Mining 开发者指南
实时自动化
在此实践教程中,我们将构建一个简单的自动化分类应用程序,该应用程序使用 Communications Mining 对传入的电子邮件进行实时分类。 我们将构建一个端到端工作流,将其用作您自己的 Communications Mining 自动化的起点,并详细介绍如何使用实时流 API。
要学习本教程,您需要具有以下权限。 您可以在“管理帐户”页面上查看当前权限。
项目 | 说明 | PERMISSIONS |
---|---|---|
reinfer-sandbox | 包含本教程中使用的预注释reinfer-sandbox/integration-tutorial 数据集。
| “查看来源”、“查看标签” |
您的开发项目 | 在入职期间,您应该已获得可用作开发环境的项目的访问权限。 | “流管理员”、“使用流”、“查看来源”、“查看标签” |
reinfer-sandbox
中的“查看源代码”和“查看标签”权限,请联系支持团队。
reinfer-sandbox/integration-tutorial
数据集,请在开发项目中使用“复制现有分类”选项创建一个新的数据集。 您可以在此处找到有关如何执行此操作的说明。
由于新数据集包含带注释的数据,因此模型将立即开始训练。 您可以在数据集状态栏中跟踪模型训练状态。 完成后,每个标签的性能指标将显示在“验证”页面上,并且新的模型版本将显示在“模型”页面上。
现在,您已经熟悉了先决条件,让我们开始构建端到端工作流。 在本节中,我们将讨论一个简单的自动化分类应用程序的设计及其与 Communications Mining 的集成。 在下一节中,我们将学习有助于推动自动化的流 API 。 最后,我们将根据此处的设计构建应用程序,并使用预先标注的数据对其进行测试。
我们将以典型的电子邮件支持用例为设计起点:
- Outlook 支持邮箱每天都会收到大量客户电子邮件。
- 分类团队将每封电子邮件转换为支持工单。 这需要使用电子邮件中的信息(例如客户 ID)填充工单字段。 然后,将每张工单添加到相应的工作流队列中。
- 客户支持团队会持续处理工作流队列中的工单。
图 3.一个简单的电子邮件支持用例
这里有两个自动化机会:分类步骤和处理步骤。 本教程将演示如何使用 Communications Mining 从电子邮件中提取必填字段来自动化分类步骤,并将电子邮件分配给工作流队列。
由于 Exchange 服务器和 Communications Mining 之间存在实时连接,因此 Communications Mining 可以充当应用程序的数据源。 通过这种方式,无需在应用程序和 Exchange 服务器之间建立单独的连接。 您的应用程序将持续轮询 Communications Mining 以获取新电子邮件,并接收新电子邮件及其预测标签和常规字段。 (我们假设在应用程序运行的同时没有用户直接在邮箱的收件箱中工作;否则,您需要考虑应用程序和邮箱用户之间的冲突)。
您的应用程序将查询 Communications Mining,并针对每封电子邮件检查 API 响应中是否存在必填标签和常规字段。 如果是,系统将在相应的工作流队列中创建工单。 如果不是,它会向 Communications Mining 发出第二个 API 请求,以将该电子邮件标记为“无预测”异常。 同样,处理工单的用户应该有一种方法来报告错误分类的工单,以便可以在 Communications Mining 中将相应的电子邮件标记为“错误预测”异常。 (模型维护者将审核和标注这两种异常类型,以提高模型性能)。
部分设计(在图中以虚线框显示)超出了本教程的范围。 在现实场景中,当然不应跳过以下步骤:
- 我们将使用平台中的现有数据,而不是设置实时 EWS 连接。
- 数据已预先标注,因此我们无需训练模型。
- 我们不会为“错误预测”异常设计反馈循环,因为设计取决于处理工单的系统的功能。
将电子邮件数据导入 Communications Mining 建议使用 Communications Mining EWS 连接器,但也有其他可用选项。 由于我们使用的是平台中已有的数据,因此本教程不包括设置数据提取。 您可以在此处了解有关所有可用数据提取选项的更多信息。
我们希望自动化此流程:
分类团队将每封电子邮件转换为支持工单。 这需要使用电子邮件中的信息(例如客户 ID)填充工单字段。 然后,将每张工单添加到相应的工作流队列中。
在本教程中,我们假设工作流队列为“续订”、“取消”、“管理员”和“紧急”队列。 有关续订、取消和管理任务的电子邮件(例如 地址更改)应进入相应的队列,而所有紧急电子邮件,无论主题如何,都应进入“紧急”队列。
为了能够将电子邮件分类到四个工作流队列中,我们训练了模型,以预测标签“续订”、“取消”、“管理员”和“加急”。 为了提取客户 ID,我们已配置“客户 ID”常规字段。 (Communication Mining 附带许多预构建的常规字段类型;您可以根据特定集成的需求添加更多常规字段类型。 您可以在此处查看当前可用的常规字段列表,并在此处了解有关请求新的常规字段类型的信息。
现在,我们可以得出从 Communications Mining 接收的预测标签与电子邮件应进入的工作流队列之间的映射:
IF number of labels == 0 THEN put email into "Uncategorised" queue
IF one of labels is "Urgent" THEN put email into "Urgent" queue
ELSE
IF number of labels == 1 THEN put email into the respective queue
ELSE put email into "Uncategorised" queue
IF number of labels == 0 THEN put email into "Uncategorised" queue
IF one of labels is "Urgent" THEN put email into "Urgent" queue
ELSE
IF number of labels == 1 THEN put email into the respective queue
ELSE put email into "Uncategorised" queue
在本教程中,我们做了一些选择:
- 除了现有的四个工作流队列外,还有一个特殊的“未分类”队列。 如果模型无法提供预测,我们会将电子邮件放入其中以供手动处理。 或者,我们也可以选择一个应处理所有未分类电子邮件的现有队列,例如“管理员”。
- 如果一封电子邮件具有
["Renewal", "Cancellation", "Admin"]
集合中的多个标签,则表示它包含多个请求。 我们选择将此类电子邮件放入“未分类”队列,可能是因为我们预计不会收到很多此类电子邮件。 或者,我们可以创建一个“复杂请求”队列。
在现实生活中,您应根据用例的特定要求做出此类决策。
为了查询模型进行预测,您当然需要有一个经过训练的模型。 通过注释您提取的一些数据来训练模型。 由于需要多个小时的标注才能生成性能良好的模型,因此我们将在本教程中使用预标注的数据,这样您就无需训练自己的模型。
在现实场景中,模型训练器应具备良好的数据领域知识。 例如,支持邮箱的用户就是一个很好的模型训练器,可以标记来自该邮箱的数据。 训练需要谨慎进行,以生成性能良好且无偏差的模型。 为此,Communications Mining 提供培训资源,并提供实践培训研讨会。
即使性能良好的模型有时也会提供不正确的结果,原因可能是未能预测标签或预测了错误的标签。 改进模型的最佳方法之一是注释模型性能不佳的电子邮件。 因此,我们希望为此类电子邮件建立一个反馈循环:
对于每封电子邮件,您的应用程序都会检查是否存在必填标签和常规字段。 如果是,则在相应的工作流队列中创建工单。 如果不是,它会向 Communications Mining 发出第二个 API 请求,以将该电子邮件标记为“无预测”异常。 同样,处理工单的用户应该有一种方法来报告错误分类的工单,以便可以在 Communications Mining 中将相应的电子邮件标记为“错误预测”异常。
我们的设计显示了这两类异常的反馈循环。
我们的设计以抽象的方式显示工作流队列。 在现实中,您可能会直接将电子邮件推送到 CRM 平台,也可能会使用消息代理(如卡夫卡),或者只是将电子邮件从收件箱文件夹移动到子文件夹中。 就本教程而言,我们将模拟队列,但鼓励您以端到端的方式开发测试集成。
为了获取传入的电子邮件以及预测的标签和提取的通用字段,流 API 允许您根据数据集、已固定的模型版本和可选的注释筛选器定义注释流,并以有状态的方式。
流响应中的每个结果都将包含注释、预测标签列表和常规字段列表。 这作为 JSON 结构传递,如下所示:
{
"comment": {...},
"entities": [...],
"labels": [...],
...
}
{
"comment": {...},
"entities": [...],
"labels": [...],
...
}
以下部分说明了如何正确解释每个流响应中的预测标签。
置信度分数
流端点将返回预测标签和置信度分数(0 到 1 之间的数字)。 例如,以下代码片段用于预测“取消”和“管理员”,其置信度分别约为 0.84 和 0.02:
"labels": [
{
"name": ["Cancellation"],
"probability": 0.8374786376953125
},
{
"name": ["Admin"],
"probability": 0.0164003014564514
}
]
"labels": [
{
"name": ["Cancellation"],
"probability": 0.8374786376953125
},
{
"name": ["Admin"],
"probability": 0.0164003014564514
}
]
为了正确解释此类结果,您需要确定将预测视为“是,标签适用”的最低置信度分数。 我们将此数字称为置信度分数阈值。
要了解置信度阈值,您应该熟悉术语“精度” 和“召回率”。 您可以在我们的支持页面上找到这些术语的解释。 简而言之,高精度与低误报率(即 则结果更有可能准确),高召回率与低漏报率(即 则不太可能错过相关结果)。
使用交互式滑块,您可以快速找到所需的阈值:向右移动滑块以优化精度,或向左移动滑块以优化召回率,直到找到符合应用程序要求的精度和召回率。 显示的阈值将是您所需的阈值。 如果要了解有关“验证”页面功能的更多信息,请参阅支持页面。
如果您仔细查看“验证”页面,您可能会注意到每个标签的精度召回曲线形状都不同。 这给您一个关于我们将如何选取阈值的提示:我们将为每个标签选取一个单独的阈值。 这在必须确保最佳性能的自动化应用程序中尤其重要。
我们将在本教程的其余部分使用以下阈值。
Admin: 0.898 (corresponds to 100% precision at 100% recall)
Cancellation: 0.619 (corresponds to 100% precision at 100% recall)
Renewal: 0.702 (corresponds to 100% precision at 100% recall)
Urgent: 0.179 (corresponds to 83% precision at 100% recall)
Admin: 0.898 (corresponds to 100% precision at 100% recall)
Cancellation: 0.619 (corresponds to 100% precision at 100% recall)
Renewal: 0.702 (corresponds to 100% precision at 100% recall)
Urgent: 0.179 (corresponds to 83% precision at 100% recall)
0.8374786376953125 > 0.619
起适用。 自0.0164003014564514 < 0.898
起“管理员”标签不适用。
"labels": [
{
"name": ["Cancellation"],
"probability": 0.8374786376953125
},
{
"name": ["Admin"],
"probability": 0.0164003014564514
}
]
"labels": [
{
"name": ["Cancellation"],
"probability": 0.8374786376953125
},
{
"name": ["Admin"],
"probability": 0.0164003014564514
}
]
为简化此过程,Streams API 允许您在流配置中指定标签阈值。 如果指定,则仅返回值高于其阈值的标签。
在现实场景中,目标精确召回性能将由业务要求和历史模型性能共同决定。 例如,如果一个标签过去在 55% 的召回率下实现了 85% 的精确度,则您可能会决定投入额外的时间来训练它,使其在 55% 的召回率下达到 90% 的精度。 然后,您将固定新的模型版本,选取新的阈值,并更新应用程序的配置。
完成设计后,我们准备开始构建应用程序。
转到“模型”页面,然后单击“保存”开关以固定模型。 固定模型后,您就可以开始通过 API 访问它。
如果您想使用不同的带注释的数据集来完成本部分教程,则应确保对该数据集进行充分的注释。 具体来说,仅包含少量带注释示例的数据集生成的模型不会返回大多数注释的预测。
在大多数情况下,指定流名称、数据集名称和模型版本以及您感兴趣的标签就足够了。 有关选项的完整列表,请参阅参考。
您应为每个标签指定一个阈值。 请参阅本教程前面有关如何选择标签阈值的部分。
curl -X PUT 'https://<my_api_endpoint>/api/v1/datasets/<my-project>/<my-dataset>/streams' \
-H "Authorization: Bearer $REINFER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"stream": {
"name": "<my-stream-name>",
"model": {
"version": <my-model-version>,
"label_thresholds": [
{
"name": [
"Parent Label",
"Child Label"
],
"threshold": <my-label-threshold>
},
{
"name": [
"Label Without Parent"
],
"threshold": <my-label-threshold>
}
]
}
}
}'
curl -X PUT 'https://<my_api_endpoint>/api/v1/datasets/<my-project>/<my-dataset>/streams' \
-H "Authorization: Bearer $REINFER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"stream": {
"name": "<my-stream-name>",
"model": {
"version": <my-model-version>,
"label_thresholds": [
{
"name": [
"Parent Label",
"Child Label"
],
"threshold": <my-label-threshold>
},
{
"name": [
"Label Without Parent"
],
"threshold": <my-label-threshold>
}
]
}
}
}'
现在,您可以使用流从 Communications Mining 获取注释。 请注意,非常小的批处理大小(例如分批提取 1 个注释)将影响提取注释的速度。
curl -X POST 'https://<my_api_endpoint>/api/v1/datasets/<my-project>/<my-dataset>/streams/<my-stream-name>/fetch' \
-H "Authorization: Bearer $REINFER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"size": <my-stream-batch-size>
}'
curl -X POST 'https://<my_api_endpoint>/api/v1/datasets/<my-project>/<my-dataset>/streams/<my-stream-name>/fetch' \
-H "Authorization: Bearer $REINFER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"size": <my-stream-batch-size>
}'
流的初始位置设置为其创建时间。 出于开发目的,获取在流之前创建的注释通常很有用。 为此,您可以将流设置为特定的时间戳。
curl -X POST 'https://<my_api_endpoint>/api/v1/datasets/<my-project>/<my-dataset>/streams/<my-stream-name>/reset' \
-H "Authorization: Bearer $REINFER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to_comment_created_at": "<YYYY-MM-DDTHH:MM:SS>"
}'
curl -X POST 'https://<my_api_endpoint>/api/v1/datasets/<my-project>/<my-dataset>/streams/<my-stream-name>/reset' \
-H "Authorization: Bearer $REINFER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to_comment_created_at": "<YYYY-MM-DDTHH:MM:SS>"
}'
fetch
请求,则该请求将从相同位置开始获取。 为了获取下一批注释,您必须使用advance
请求确认上一批注释。 在advance
请求中,您必须提供sequence_id
,可在fetch
响应中找到。
如果应用程序在处理过程中失败,“获取并推进”循环可确保您不会意外跳过注释。 请注意,如果已成功处理注释,但在高级步骤中失败,您的应用程序需要能够多次处理查看注释。
curl -X POST 'https://<my_api_endpoint>/api/v1/datasets/<my-project>/<my-dataset>/streams/<my-stream-name>/advance' \
-H "Authorization: Bearer $REINFER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"sequence_id": "<my-sequence-id>"
}'
curl -X POST 'https://<my_api_endpoint>/api/v1/datasets/<my-project>/<my-dataset>/streams/<my-stream-name>/advance' \
-H "Authorization: Bearer $REINFER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"sequence_id": "<my-sequence-id>"
}'
请注意,您必须在使用流的所有 API 请求中提供数据集名称 - 这是因为流的作用域是数据集。
如果您的应用程序允许用户标记错误预测的项目,则可以使用异常端点将相应的注释标记为平台中的异常。 异常名称将在数据集中用作筛选条件,以便模型训练器可以查看异常并为其添加注释,以改进模型。
curl -X PUT 'https://<my_api_endpoint>/api/v1/datasets/<my-project>/<my-dataset>/streams/<my-stream-name>/exceptions' \
-H "Authorization: Bearer $REINFER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"exceptions": [
{
"metadata": {
"type": "Wrong Prediction"
},
"uid": "<comment-uid>"
},
{
"metadata": {
"type": "Wrong Prediction"
},
"uid": "<comment-uid>"
}
]
}'
curl -X PUT 'https://<my_api_endpoint>/api/v1/datasets/<my-project>/<my-dataset>/streams/<my-stream-name>/exceptions' \
-H "Authorization: Bearer $REINFER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"exceptions": [
{
"metadata": {
"type": "Wrong Prediction"
},
"uid": "<comment-uid>"
},
{
"metadata": {
"type": "Wrong Prediction"
},
"uid": "<comment-uid>"
}
]
}'
恭喜您,您已完成 Communications Mining 自动化教程。 当然,您自己的自动化应用程序可能与此处介绍的应用程序不同。 如有疑问,请联系支持团队。