云运营团队面对的工单,往往不是简单的“收到后转给某个人”。一张工单可能同时包含客户描述、错误日志、服务版本、历史对话和内部知识库线索。人工需要先补齐上下文,再判断优先级、识别问题类型,最后找到合适的处理队列。
Aderant 的实践展示了另一种路径:基于 Amazon Bedrock 调用 Amazon Nova Lite,把工单分诊拆成一条可自动执行的流程,覆盖上下文收集、分类、路由和知识 enrichment。关键不在于让模型直接“决定一切”,而在于把模型放进一个有输入约束、有结构化输出、有人工兜底的运营工作流中。
工单分诊不只是文本分类
一个可用的分诊系统至少要回答四个问题:
- 这是什么问题? 例如认证失败、部署异常、数据同步错误或性能下降。
- 影响有多大? 是否影响单个用户、单个租户,还是大范围云服务。
- 应该交给谁? 需要路由到哪个产品、服务或值班队列。
- 处理它需要什么上下文? 相关日志、版本、租户信息、历史工单和知识库文章是否已经齐全。
如果只让模型读取工单正文并输出一个类别,系统通常会遇到两个问题:输入信息不足,以及输出结果无法直接驱动后续系统。因此,更稳妥的设计是把分诊拆成几个阶段:
新工单
-> 收集结构化上下文
-> 检索相关历史工单和知识
-> 使用 Nova Lite 生成结构化判断
-> 校验分类、优先级和队列
-> 自动路由或进入人工复核
模型负责理解自然语言和综合证据,业务代码负责权限、字段校验、路由规则和审计记录。这个边界很重要:模型可以提出建议,但不应绕过确定性的运营约束。
用 Amazon Bedrock 调用 Nova Lite
下面是一个最小的 Python 示例。它假设已经配置好 AWS 凭证,并且当前区域允许访问对应的 Amazon Nova Lite 模型。示例使用 Amazon Bedrock Runtime 的 converse 接口,让模型返回 JSON 格式的分诊结果。
运行前准备:
- 安装
boto3。 - 配置具有调用 Bedrock 权限的 AWS 身份。
- 将
AWS_REGION替换为实际区域。 - 根据账户可用的模型 ID 调整
MODEL_ID。
python -m pip install boto3
export AWS_REGION=us-east-1
export NOVA_MODEL_ID=amazon.nova-lite-v1:0
python triage_ticket.py
创建 triage_ticket.py:
import json
import os
import boto3
REGION = os.getenv("AWS_REGION", "us-east-1")
MODEL_ID = os.getenv("NOVA_MODEL_ID", "amazon.nova-lite-v1:0")
client = boto3.client("bedrock-runtime", region_name=REGION)
TICKET = {
"id": "INC-1042",
"subject": "Users cannot sign in after the latest deployment",
"description": "Several users receive HTTP 401 responses after the identity service deployment.",
"service": "identity-api",
"environment": "production",
"recent_logs": "token validation failed: issuer mismatch",
"customer_impact": "Multiple tenants report failed sign-in attempts",
}
prompt = f"""
You are an operations ticket triage assistant.
Use only the evidence in the ticket and context below. Do not invent facts.
Return one JSON object with exactly these fields:
- category: short issue category
- priority: one of P1, P2, P3, P4
- suggested_queue: one of identity, platform, data, billing, or human-review
- missing_context: array of information needed for a confident decision
- rationale: concise explanation based on the evidence
Ticket context:
{json.dumps(TICKET, ensure_ascii=False, indent=2)}
"""
response = client.converse(
modelId=MODEL_ID,
messages=[
{
"role": "user",
"content": [{"text": prompt}],
}
],
inferenceConfig={
"temperature": 0.0,
"maxTokens": 500,
},
)
text = response["output"]["message"]["content"][0]["text"]
result = json.loads(text)
allowed_priorities = {"P1", "P2", "P3", "P4"}
allowed_queues = {"identity", "platform", "data", "billing", "human-review"}
if result.get("priority") not in allowed_priorities:
raise ValueError("Model returned an invalid priority")
if result.get("suggested_queue") not in allowed_queues:
raise ValueError("Model returned an invalid queue")
print(json.dumps(result, ensure_ascii=False, indent=2))
这个示例刻意保留了一个重要的安全边界:模型输出必须经过代码校验。生产系统还应增加 JSON Schema 校验、模型调用超时、重试策略、异常队列和完整的输入输出审计。
上下文收集决定分诊质量
“上下文收集”不是把更多文本一股脑塞进提示词。更实用的做法是建立固定的上下文契约,把信息分为几类:
- 工单字段:标题、描述、创建时间、客户或租户标识。
- 运行环境:服务名、版本、部署时间、区域和环境类型。
- 可观测性数据:相关时间窗口内的错误日志、指标异常和最近变更。
- 历史经验:相似工单、已关闭事件、根因分析和解决步骤。
- 知识库内容:适用的排障文档、已知问题和升级流程。
收集上下文时需要控制两个边界。第一是权限边界,不同工单处理者可能只能看到特定租户或服务的数据。第二是长度和相关性边界,检索结果应经过筛选、截断和去重,避免无关内容稀释真正的信号。
可以为每张工单生成一个内部上下文对象,例如:
{
"ticket": {
"id": "INC-1042",
"service": "identity-api",
"environment": "production"
},
"signals": {
"recent_deployments": ["identity-api 2025.01.18.3"],
"error_patterns": ["issuer mismatch", "HTTP 401"],
"affected_scope": "multiple-tenants"
},
"retrieved_knowledge": [
{
"title": "Identity issuer mismatch after deployment",
"source": "internal-runbook",
"relevance": 0.91
}
]
}
这种结构比直接拼接邮件、日志和历史对话更容易调试,也方便在模型升级后比较输入变化对结果的影响。
分类和路由要分层处理
模型适合做语义判断,但路由通常还需要遵守组织规则。例如,某些 P1 工单必须进入全天候值班队列;涉及安全事件的工单不能仅由普通产品队列处理;缺少租户标识的工单需要先回到人工复核。
因此可以采用两层决策:
- Nova Lite 输出分类、优先级、建议队列和理由。
- 确定性的路由器根据优先级、服务目录、权限和组织规则计算最终队列。
伪代码如下:
def route_ticket(model_result, context):
if context.get("security_signal"):
return "security-review"
if model_result["priority"] == "P1":
return "on-call-incident"
if not context.get("ticket", {}).get("service"):
return "human-review"
queue = model_result.get("suggested_queue", "human-review")
return queue if queue in ALLOWED_QUEUES else "human-review"
这里的 security_signal、ALLOWED_QUEUES 和服务目录都应来自受控系统,而不是由模型自行生成。这样即使模型给出了格式正确但不符合运营政策的结果,也不会直接把工单送错地方。
知识 enrichment 的价值在于可追溯
自动补充知识时,系统不应只给处理人员一段模型生成的长答案。更有用的结果包括:
- 相关知识库文章的标题和标识。
- 每条推荐与当前工单的关联理由。
- 文章的适用版本、服务范围和更新时间。
- 模型无法确认的缺口。
- 是否需要人工确认后才能执行的步骤。
例如,模型可以指出“HTTP 401 与 issuer mismatch 同时出现,可能与最近的身份服务部署相关”,并链接到内部排障文档。它不应把未经验证的猜测包装成已经确认的根因。
评估这类系统时,准确率不是唯一指标。还应观察:
- 自动路由命中率。
- 人工改派率。
- P1 工单识别的召回率。
- 平均分诊耗时。
- 处理人员打开推荐知识的比例。
- 错误路由造成的升级或延迟次数。
对于高影响工单,宁可降低自动化覆盖率,也要优先保证错误不会被静默吞掉。可以把低置信度、字段缺失和规则冲突统一送入人工复核队列。
落地时的检查清单
采用 Amazon Nova Lite 和 Amazon Bedrock 构建类似流程时,可以按以下顺序推进:
- 先定义工单分类、优先级和队列的枚举值。
- 为每类工单设计最小上下文契约。
- 用检索系统补充相关历史工单和知识库内容。
- 通过 Bedrock 调用模型,并要求结构化输出。
- 在应用层执行 Schema、权限和业务规则校验。
- 为低置信度、异常响应和规则冲突配置人工兜底。
- 记录提示词版本、上下文摘要、模型版本和最终路由结果。
- 用历史工单回放测试,再逐步扩大自动路由范围。
Aderant 的实践说明,智能工单分诊的核心不是单次模型调用,而是一条围绕运营流程设计的自动化链路。Amazon Nova Lite 可以承担自然语言理解、信息归纳和知识关联,但可靠的生产系统仍需要清晰的数据契约、确定性的路由规则、权限控制和可观测性。把这些部分组合起来,模型才真正能从“回答问题”进入“帮助团队完成工作”。