← 返回信息流

精选AWS AI Blog新闻

KnowledgeForge:从ITSM工单坟墓中挖掘知识金矿

aws.amazon.com作者:Anmol Dhankhar教程产品AI评分:70/100

本文介绍了KnowledgeForge,一个基于AWS生成式AI的文档处理流水线,用于从已解决的ITSM工单中自动生成知识库文章,并对现有知识库进行去重、质量评分和改进。系统采用闭环架构,使用Amazon Bedrock进行内容生成,Amazon S3 Vectors进行重复检测,AWS Step Functions进行编排。文章详细说明了各组件选择理由和实现细节,适合构建大规模文档处理流水线的开发者参考。

KnowledgeForge致力于从IT服务管理(ITSM)工单坟场中挖掘黄金:那些已解决的故障工单,其知识从未沉淀到知识库文章中。企业IT支持团队每月解决数千张工单,每张工单都蕴含着有价值的信息:症状、根因,以及工程师应用的修复方案。这些知识被锁在工单历史中,下一个遇到相同问题的工程师无法找到它们。

知识库本身则面临相反的问题。它在增长,但增长得杂乱无章:重复文章堆积,内容过时,质量因作者和撰写时间的不同而参差不齐。支持工程师搜索答案时,要在近乎相同的草稿中艰难跋涉,有些是准确的,有些则已经落后了三个产品版本。

我们构建KnowledgeForge就是为了弥合这两端的差距。它从已解决的故障工单中挖掘新文章。同时,它通过按类型对文章分类、去除重复、评分质量、重写薄弱内容来整理现有知识库。知识管理员负责审核并批准结果,因此最终上线的内容仍由人来掌控。

本文介绍KnowledgeForge背后的AWS构建模块:Amazon Bedrock用于生成和内容改进,Amazon S3 Vectors(Amazon Simple Storage Service(Amazon S3)的一项功能)用于重复检测,AWS Step Functions用于编排。对于每个组件,我们都会解释选择它的原因并附上文档链接。如果你正在基于生成式AI构建大规模文档处理流水线,可以直接复用这些模式。

前置条件

  • 一个可访问Amazon Bedrock的AWS账户,并已启用Anthropic Claude Sonnet 4.5和Amazon Titan Text Embeddings V2模型的访问权限。
  • 创建本解决方案所用资源的权限:Amazon S3存储桶和Amazon S3 Vectors索引、AWS Step Functions状态机、AWS Lambda函数、AWS Fargate上的Amazon Elastic Container Service(Amazon ECS)服务、Amazon DynamoDB表、Amazon Simple Queue Service(Amazon SQS)队列、Amazon Bedrock防护机制以及AWS Key Management Service(AWS KMS)密钥。
  • 已安装AWS Cloud Development Kit(AWS CDK),并熟悉Amazon Bedrock、AWS Step Functions、Amazon ECS和向量嵌入。
  • 来自aws-samples/sample-knowledgeforge仓库的代码。

闭环知识库生命周期

KnowledgeForge由两个相互馈送的子系统组成。生成子系统将聚类后的故障工单转化为新的草稿文章。当一组相关工单描述同一问题时,系统会从该聚类中撰写一篇知识库文章和一份根因分析文档。随后,整理子系统对每篇文章(包括新生成的和已有的)执行四个步骤:按类型分类、检查重复、评分质量、改进薄弱内容。完成后的文章进入ServiceNow供知识管理员审核。

闭环之所以成立,是因为整理子系统为每篇文章存储一个向量,而生成子系统在撰写任何新内容之前会先读取这些向量。下图展示了两个子系统如何连接。

Closed-loop lifecycle diagram: ingestion feeds generation and curation, then curation embeds every article as grounding…
Closed-loop lifecycle diagram: ingestion feeds generation and curation, then curation embeds every article as grounding…

图1:闭环知识库生命周期。数据摄取为生成和整理提供输入,知识管理员审核输出,整理子系统对每篇文章进行向量嵌入,以便生成子系统在下一轮运行时将这些向量作为 grounding 复用。

  1. 数据摄取——已解决的工单和现有文章落入Amazon S3,由数据目录跟踪。
  2. 生成——聚类后的工单在AWS Fargate上的Amazon ECS中转化为新的草稿文章。
  3. 整理——每篇文章通过AWS Lambda上的AWS Step Functions工作流进行分类、去重、质量评分和改进。
  4. 人工审核——增强后的文章进入ServiceNow供知识管理员审批,审批决定写回Amazon DynamoDB。
  5. 闭环——整理子系统将每篇文章嵌入Amazon S3 Vectors索引,生成子系统在下一轮运行时复用这些向量。

两个子系统运行在不同的计算平台上,原因将在后续章节跟随一篇文章走完整个系统时逐一说明。

从故障工单聚类生成文章

生成从一组共享主题的工单聚类开始。上游流程按所描述的问题对已解决的故障进行分组,并将结果以JSON文件形式放入Amazon S3存储桶,范围限定为单个客户。每个主题携带关键词、文章范围,以及工单描述和工作备注的样本。

存储桶中的新文件会向Amazon SQS队列发送一个事件。AWS Fargate上的Amazon ECS容器轮询该队列,读取文件,并同时处理一个客户最多五个主题。

写作之前,系统会先以现有内容为基础进行自我锚定。针对每个主题,它会从该客户的 Amazon S3 Vectors 索引中检索出五篇最相似的现有文章,并将其作为参考上下文传递给模型。这种检索增强生成(RAG)方式保持了术语的一致性,并减少了凭空捏造的流程。当尚不存在参考文章时,系统仅根据工单数据生成内容,并将这些流程标记为待审核。

生成过程在 Amazon Bedrock 上的 Anthropic Claude Sonnet 4.5 中运行。针对每个主题,模型会生成两份结构固定的文档:

  • 知识库文章:标题与摘要、症状、根本原因、解决步骤、预防措施及相关主题。
  • 根本原因分析文档:执行摘要、问题描述、客户影响、五问分析、临时解决方案与最终修复、纠正与预防措施、关键事件时间线及原因代码。

我们使用 Amazon Bedrock 的响应流式传输,因此容器会在令牌到达时逐步组装每份文档,而无需等待完整响应。

为何选择容器而非函数

我们选择在带有 AWS Fargate 的 Amazon ECS 上运行生成任务,这是由工作形态决定的。为一个主题生成两份完整文档可能需要几分钟,而一个繁忙的文件包含许多主题,因此单个工作单元可能运行很长时间。工作负载也是突发性的,有时沉寂一段时间,然后一次性涌入大批量任务。一个长期运行的容器服务,根据队列深度伸缩任务数量,并在队列清空时缩回,非常契合这种模式。

AWS Fargate 符合这一需求。它以无服务器方式运行我们的容器,随着主题到来按需扩展,让团队专注于生成逻辑而非计算容量管理。每份文档以 JSON 格式存入 Amazon S3,随时可供审核整理。

使用 Amazon S3 Vectors 查找重复文章

审核整理的首要挑战是检测文章是否已存在。重复有多种形式:两篇文章用不同措辞描述同一个修复方案;新文章取代旧文章;或者工程师复制一篇文章,改动两行后另存为新文章。

我们选择 Amazon S3 Vectors 来解决这个问题。它直接将嵌入向量存储在 Amazon S3 中,无需独立的向量数据库。它将元数据与每个向量一同保存,支持按客户过滤,并按查询次数和存储容量计费,而非按运行节点计费。这使得为库中每篇文章保留一个向量变得经济实惠。如果您已将内容存储在 Amazon S3 中,就可以在不新增基础设施的情况下添加向量搜索。详情请参阅 Amazon S3 用户指南。

关键词匹配无法识别这些重复形式,因此该流程基于语义进行匹配。每篇文章都会通过 Amazon Titan Text Embeddings V2 生成一个 1,024 维的嵌入向量,存储在按客户划分的 Amazon S3 Vectors 索引中。向量存储通常用于检索,而这里同一个索引还兼作重复检测器。新文章被嵌入后,系统查询索引中最近的现有向量,任何落在严格余弦距离阈值内的结果都被视为重复。我们以 0.05 的余弦距离(即相似度 0.95 或更高)和 top-K 为 5 作为起点。我们通过抽样检查被标记的配对来调整距离阈值,逐步收紧,直到近乎相同的文章能被匹配出来,同时不会误捕仅属相关的文章。阈值过松会产生误报重复,过紧则会漏掉改写过的副本。该查询只需一次调用,并按当前客户和有效文章进行过滤:

response = s3vectors.query_vectors(
    vectorBucketName=VECTOR_BUCKET,
    indexName=VECTOR_INDEX,
    queryVector={"float32": embedding},
    topK=TOP_K + 1,  # +1 因为文章可能匹配到自身
    returnMetadata=True,
    returnDistance=True,
    filter={"$and": [
        {"tenant_id": {"$eq": TENANT_ID}},  # 按客户隔离
        {"status": {"$in": ["UNIQUE", "PENDING"]}},  # 忽略已停用文章
    ]},
)
matches = [v for v in response.get("vectors", []) if v["key"] != article_id]

当系统发现重复配对时,默认做法是保留较新的文章并停用旧文章,而不是直接丢弃新文章。最新且准确的版本胜出——这正是支持工程师想要的行为。

以这种方式复用索引也有助于重试场景。生成嵌入需要调用模型,而重新运行时可以直接读取已存储的向量,无需重新计算,从而在批次重跑时节省时间和 Amazon Bedrock 费用。

使用 AWS Step Functions 大规模编排审核流程

审核整理针对的是成批的文章,需要编排以将工作分散到多个工作节点并实现故障恢复。AWS Step Functions 通过两阶段分布式映射提供了这一能力。它管理工作流状态,应用定义中声明的重试和错误处理策略,并将工作分发到各工作节点,无需自定义协调代码。有关分布式映射的运作方式,请参阅 AWS Step Functions 开发者指南。

有两个配置选择值得特别说明。首先,我们将条目处理器设置为 STANDARD 而非 EXPRESS。每篇文章都会发起长时间运行的 Amazon Bedrock 调用,超出 5 分钟的 EXPRESS 限制,而 STANDARD 模式会保留完整的执行历史以供调试。其次,我们将 ItemReader 指向 Amazon S3 中的清单文件,而不是内联传递条目,这样可以使工作流状态保持精简。

Amazon EventBridge 上的每日调度启动运行。一个 AWS Lambda 函数查找有新文章或文章有变动的客户,将变更分组为批次,并将每个批次放入 Amazon SQS 先进先出(FIFO)队列。FIFO 队列以客户 ID 作为消息组键,按客户对跨运行的批次进行排序,因此不同客户仍可并行运行。跨运行排序只是其中一部分。在单次执行中,阶段 2 可同时处理多达 40 个批次,因此仅靠 FIFO 并不能阻止不同批次中的两个重复项发生竞争。真正保障去重一致性的机制是:去重在 worker 内部每个批次内串行执行,而质量评分和改进则并行运行。每批次串行去重、质量与改进并行处理、以及 FIFO 实现跨运行排序,三者共同确保重复检测的一致性。

一个调度函数每次拉取一个批次并启动 Step Functions 执行。状态机分两个阶段运行,每个阶段都是一个分布式映射(distributed map),使批次内的文章并发处理:

  1. 分类与嵌入——每篇文章按类型分类并生成向量嵌入。
  2. 去重、评分与改进——管道查找重复项、评估质量,并改进低于阈值的內容。

下图展示了触发链、两个阶段以及保护运行容错机制。

Two-phase curation workflow: an Amazon SQS FIFO queue orders batches, article content passes as an Amazon S3 pointer, a…
Two-phase curation workflow: an Amazon SQS FIFO queue orders batches, article content passes as an Amazon S3 pointer, a…

图 2:内容策展以两阶段分布式映射运行。批次通过 Amazon SQS FIFO 队列按客户排序,文章内容以 Amazon S3 指针而非内联状态传递,断路器(circuit breaker)和死信队列(dead-letter queue)防止坏批次阻塞运行。

传递指针而非负载

Step Functions 执行在状态之间传递状态,上限为 256 KB。知识库文章包含完整的 HTML 正文,很快就会超过该限制。我们没有将文章内容贯穿状态机,而是将批次写入 Amazon S3,仅通过工作流传递位置信息。每个映射 worker 直接从 Amazon S3 读取所需内容,因此无论文章多大,状态负载都保持精简。

分布式映射从 Amazon S3 中的清单读取工作项,而非从内联状态读取。容错百分比允许运行吸收少量坏文章而不会中止整个批次:

"Phase1_ClassifyEmbed": {
    "Type": "Map",
    "ItemProcessor": {
        "ProcessorConfig": { "Mode": "DISTRIBUTED", "ExecutionType": "STANDARD" }
    },
    "ItemReader": {
        "Resource": "arn:aws:states:::s3:getObject",
        "ReaderConfig": { "InputType": "JSON" },
        "Parameters": { "Bucket.$": "$.bucket", "Key.$": "$.manifest_key" }
    },
    "MaxConcurrency": 40,
    "ToleratedFailurePercentage": 10
}

从故障中恢复

  • 死信队列——反复失败的批次会被搁置以待调查,而不会阻塞其后的队列。
  • 断路器(尽力而为)——连续三次失败后,调度函数停止启动新批次,并将受影响的文章重置为初始状态。失败计数器保存在热 Lambda 函数的内存中,因此不会在并发的调度容器之间共享,并在新任务启动时重置。在交错的多租户负载下,断路器可能不会触发,因此我们将其视为尽力而为的后备机制而非保证。无论哪种情况都不会丢失任何内容:下一次定时运行会拾取已重置的文章,而触发的断路器则表明某个服务依赖需要优先关注。

让 Amazon Bedrock 在大规模下保持可靠,并提升文章质量

工程工作的重点在于并发运行数万次模型调用并共享服务配额。管道通过 Amazon Bedrock 模型推理调用 Anthropic Claude Sonnet 进行生成和改进,使用 Amazon Titan Text Embeddings V2 生成去重向量。关于各 AWS 区域的模型可用性,请参阅按 AWS 区域划分的受支持模型。

让模型调用保持在限额之内

每次执行都设有硬性的挂钟超时,因此响应缓慢不会让工作人员无限期地保持占用状态。

自动重试与退避——Amazon Bedrock 客户端以自适应模式运行,遇到限流时自行重试,对较长的内容改进调用采用指数退避策略。

护栏回退——我们在模型输出上运行 Amazon Bedrock 护栏,以过滤非预期内容。护栏是一项生产控制措施,而下面的回退是一种弹性措施,确保在正常条件下护栏持续生效,而非暗示它是可选的。

护栏 API 有自己的速率限制。如果它被限流,流水线会在不使用护栏的情况下处理文章,并记录一条警告而不是失败,这样在流量高峰期间流程仍能继续推进。在代码中,这个回退是模型调用包装器中的一小段:

try:
    return converse_with_timeout(kwargs, BEDROCK_CALL_TIMEOUT)
except ClientError as e:
    if "ThrottlingException" in str(e) and guardrail_config:
        log.warn("Guardrail throttled, retrying without guardrail")
        del kwargs["guardrailConfig"]
        return converse_with_timeout(kwargs, BEDROCK_CALL_TIMEOUT)
    raise

第四项控制处理截断输出。内容改进响应有 token 预算,长文章可能触及上限,导致 JSON 响应被截断。系统检测到“因 token 上限而停止”的信号后,会以双倍预算重试,直到达到模型的上限。短文章永远不会触发这条路径,因此常见情况下无需为安全网付出任何代价。

改进前后的质量评分

并非每篇文章都需要改进,改进也并非总是有益。由质量评分来决定。每篇文章按十个加权维度评分,权重从高到低排列:

  • 完整性
  • 可操作性
  • 结构
  • 连贯性
  • 可读性
  • 自助服务价值
  • 时效性
  • 自动化就绪度
  • 语法
  • 安全性

加权总分产生一个分数,阈值决定文章是原样达标,还是需要进入改进流程。阈值是可配置的,因此客户可以对生成内容设定比导入内容更高的标准。

低于阈值的文章会进入内容改进环节,同样在 Amazon Bedrock 上运行。这一步有一个实际挑战:被要求改进文风的模型往往也会改动图片标签和超链接,并导致它们损坏。占位符解决了这个问题。改进之前,系统将每个图片和链接替换为编号 token,围绕这些 token 改进正文,之后再将真实媒体换回。模型从未看到原始标记,因此标题和结构得以保留。

在代码中,这是围绕改进调用的一对函数。第一个函数将每个媒体标签和链接替换为编号 token,并记录它移除了什么。第二个函数在模型返回后将原始内容放回:

# 改进之前:将媒体/链接替换为 [IMG_N] / [LINK_N] token
html_with_placeholders, placeholder_map = extract_placeholders(article_html)

enriched = improve_with_bedrock(html_with_placeholders)  # 模型从未看到原始标记

# 改进之后:原位恢复确切的原始标签
restored_html, missing = restore_placeholders(enriched, placeholder_map)

因为模型只看到 [IMG_1] 或 [LINK_3],它不可能破坏 URL 或图片引用。恢复步骤确保发布文章的媒体与开始时完全一致。

改进之后,文章会再次评分。只有新版本得分超过原版时才保留新版本,否则维持原版。这种前后对比检查让流水线能够自动改进内容,而不会悄悄让知识库变得更差。

安全地服务众多客户

系统在共享基础设施上运行多个客户,而知识库恰恰是客户期望被严格隔离的数据。隔离从设计之初就内置其中:每个客户拥有与其内容相关的所有内容的独立副本:

  • 一个配置档案
  • 一个 Amazon S3 Vectors 索引
  • 一组模型提示词
  • 一个 Amazon Bedrock 护栏
  • 一个 AWS KMS 加密密钥

由于这些资源是按客户隔离的,每个客户的数据都保持在自己的边界内。重复检查仅针对该客户的索引运行,内容改进使用该客户的提示词,数据使用该客户的密钥加密。不存在任何共享池,让一个客户的文章出现在另一个客户的结果中。

接入新客户不需要编辑中央列表。系统在运行时从数据目录中发现客户,因此添加一个客户只需配置其资源,无需更改流水线代码。

结果与经验教训

这里的行为来自我们的内部测试,并非有保障的服务水平。由于每个客户都流经自己的 Amazon SQS FIFO 消息组,因此增加一个客户只是增加一条并行工作流,而不会拖慢其他客户。您自己的吞吐量将取决于文章大小、模型延迟以及您的 Amazon Bedrock 配额。

一次有代表性的运行展示了您可以预期的模式。大多数文章在第一次处理时就完整通过,一小部分被保留以待改进,更小的一部分作为重复内容被移除。该次运行完成时没有死信队列消息,也没有超时。少数文章触及了内容改进的令牌限制,被自动重置,并在下一次运行时以更高的预算重试,而不是失败。最后这种情况很重要,因为它展示了弹性控制如何将原本的硬性失败转化为自动重试。

四条经验值得注意。将向量索引复用为重复检测器,把一个难题变成了最近邻查询。通过 Step Functions 传递 Amazon S3 指针而非文章正文,消除了一类状态大小故障。在改进前后两侧都进行质量评分,使得自动运行变得安全。将护栏限流视为警告,使管道在负载高峰期间保持健康。更大的要点在于闭环本身:生成的内容为策展提供输入,而策展又为下一轮生成提供基础,因此知识库会随着系统的运行而不断改进。

清理资源

本解决方案中的资源均需计费,因此请在完成后将其移除,以避免持续产生费用。删除两个 AWS CDK 堆栈(一个用于知识库生成,一个用于知识库策展)即可移除大部分资源。这包括 AWS Lambda 函数、AWS Step Functions 状态机、AWS Fargate 上的 Amazon ECS 服务、Amazon SQS 队列以及 Amazon DynamoDB 表。

  • Amazon S3 Vectors 索引和向量存储桶 – 先删除每个客户的索引,再删除向量存储桶。
  • Amazon S3 存储桶 – 清空并删除源存储桶、输出存储桶和管道存储桶。
  • Amazon Bedrock 护栏 – 如果堆栈未移除每个客户的护栏,请手动删除。
  • AWS KMS 密钥 – 安排删除每个客户的密钥。
  • Amazon DynamoDB 表 – 如果您禁用了时间点恢复保留,请确认指标表和文章状态表已被移除。

有关确切的删除命令,请参阅存储库 README。

结论

ITSM 工单墓地是一个看起来像数据问题的知识问题。解决方案早已存在,却被困在无人能够复用的地方,旁边是一个衰败速度远超任何团队手工策展能力的知识库。KnowledgeForge 利用 AWS 上的生成式 AI 弥合了这一差距。它通过 Amazon Bedrock 将工单挖掘成文章,通过 Amazon S3 Vectors 捕获重复内容,并通过 AWS Step Functions 编排整个流程。知识管理员始终掌控着最终上线的内容。

  1. 使用 Amazon S3 Vectors 文档创建向量索引。
  2. 嵌入您自己文章的一个样本并加载向量。
  3. 运行前面展示的最近邻查询以标记重复内容。
  4. 添加 AWS Step Functions 分布式映射以批量处理文章。
  5. 叠加“评分—改进—重新评分”的质量门控。

完整代码可在 GitHub 上的 aws-samples/sample-knowledgeforge 存储库中获取。全文中的代码示例展示了每种模式的承重部分,可随时适配到您自己的知识库。

如需了解更多信息,请参阅 Amazon Bedrock 用户指南、AWS Step Functions 开发人员指南和 Amazon S3 用户指南。

关于作者

阅读原文