你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

教程:使用 Azure Managed Redis 按语义相似性对 AI 请求进行路由

语义路由通过将请求与每个路径的代表性示例进行比较,将自然语言请求发送给正确的处理程序、模型、工具、提示或工作流程。 在这个教程中,你将用RedisVL和Azure托管Redis实现语义路由作为应用模式。 语义路由并不是 Azure Managed Redis 管理的一个独立功能。 它使用 Redis 矢量搜索和应用代码。

Redis中的矢量搜索需要RediSearch,并且可以在Azure托管Redis中找到,详见Azure托管Redis矢量搜索概览。 创建 Azure 托管 Redis 实例时必须启用包括 RediSearch 在内的 Redis 模块。 有关受支持的层级和策略,请参阅在 Azure Managed Redis 中使用 Redis 模块RediSearch 要求

RedisVL 提供了一个 SemanticRouter 接口,利用 Redis 搜索对一组引用进行 Route 请求分类。 对于底层向量模型,Redis 将向量和元数据存储在哈希或 JSON 对象中,并用向量字段、距离指标和 KNN 或范围查询进行搜索。 更多信息请参见 RedisVL SemanticRouter 指南Redis 向量搜索概念

本教程中,您将学习如何:

  • 定义带有代表性引用的命名语义路由。
  • 创建一个由 Azure Managed Resid 支持的 RedisVL 语义路由器。
  • 将请求转发到一个或多个匹配的路由。
  • 处理未命中和歧义匹配情况。
  • 在生产环境中调整阈值并操作语义路由。
  • 对常见的AI应用模式应用语义路由。

Prerequisites

  • 一份 Azure 订阅。 如果没有 Azure 订阅,可以创建一个免费帐户
  • 一个在创建时启用RediSearch的Azure管理Redis实例。 RediSearch 是 Redis 模块,用于在 Azure 托管的 Redis 中实现矢量搜索,创建实例时必须选择模块。 请在 在 Azure Managed Redis 中使用 Redis 模块 中查看支持的模块矩阵和 RediSearch 策略要求。
  • 用于您的 Azure 托管 Redis 实例的连接字符串或 Redis URL。 使用TLS和你应用认可的认证方式。
  • 一个可以安装RedisVL和你所选嵌入模型依赖的Python环境。
  • 嵌入或矢量化策略。 本教程用RedisVL HFTextVectorizer 做了一个简明的示例。 在路由器索引中,每个路由引用和每个入请求都使用相同的嵌入模型,这样矢量尺寸和距离指标就能保持一致。 Redis 向量索引要求向量字段具有固定的 DIMDISTANCE_METRIC。 更多信息请参见 Redis 向量搜索概念

安装RedisVL:

pip install redisvl

设计你的路线

路由代表应用决策,例如提示模板、工具、模型或工作流程。 每条工艺路线包括:

  • 一个稳定的 name,你的应用程序将其映射到某个处理程序。
  • references,这些语句是该路径的代表性语句。
  • 可选的 metadata,例如处理程序 ID、提示词版本、模型偏好或所有者信息。
  • 每条路由 distance_threshold。 在RedisVL中,路由阈值使用Redis COSINE 距离单位,较低的值需要更严格的匹配。 阈值是特定型号的,应该通过你自己的请求来验证。

例如,AI助手可能会使用以下路径:

Route 示例目标 代表性参考文献
billing 计费工作流程或提示 “更新我的发票”,“为什么我被收了两次钱?”
technical_support 支持分流工具 “我的缓存已超时”,“帮我排查连接错误”
sales 销售工作流程 “比较套餐”、“和销售沟通定价”

选择能够覆盖路由语义表面积且不与其他路线重叠的引用。 使用来自真实流量、支持工单或精心整理的评估数据的示例。 避免使用过于泛泛的引用,如“帮助”或“提问”,因为它们可能匹配多条路径。

创建一个语义路由器

在环境变量中设置你的 Redis URL 。 具体的URL格式取决于你的认证方式和客户端配置。 连接TLS时使用 rediss:// 网址。

import os

from redisvl.extensions.router import Route, SemanticRouter
from redisvl.utils.vectorize import HFTextVectorizer

redis_url = os.environ["REDIS_URL"]  # Example: rediss://:<password>@<host>:10000

billing = Route(
    name="billing",
    references=[
        "I need a copy of my invoice",
        "why was my card charged twice",
        "change the billing email for my account",
    ],
    metadata={"handler": "billing_workflow", "prompt": "billing_v1"},
    distance_threshold=0.55,
)

technical_support = Route(
    name="technical_support",
    references=[
        "my cache is timing out",
        "help me debug Redis connection errors",
        "why am I seeing high server load",
    ],
    metadata={"handler": "support_triage_tool", "prompt": "support_v2"},
    distance_threshold=0.50,
)

sales = Route(
    name="sales",
    references=[
        "compare pricing plans",
        "I want to talk to sales",
        "which tier should I choose for production",
    ],
    metadata={"handler": "sales_workflow", "prompt": "sales_v1"},
    distance_threshold=0.60,
)

routes = [billing, technical_support, sales]
routes_by_name = {route.name: route for route in routes}

router = SemanticRouter(
    name="ai-request-router",
    vectorizer=HFTextVectorizer(),
    routes=routes,
    redis_url=redis_url,
    overwrite=False,
)

初始化后,RedisVL 会创建并填充 Redis 搜索索引以获取路由引用。 Redis 在索引中使用矢量场和元数据字段对嵌入引用进行相似性搜索。 有关路由器初始化和路由字段的详细信息,请参见 RedisVL SemanticRouter 指南。 有关Redis向量索引的详细信息,请参见 Redis向量搜索概念

Tip

每个环境使用不同的路由器名称或 Redis 密钥前缀。 如果不同租户需要不同的路由集,可以用不同的路由器索引或严格的租户专用密钥命名来隔离它们,这样一个租户的引用不会影响另一个租户的路由结果。

路由请求

呼叫路由器会返回最佳路由匹配。 如果没有任何路由与其阈值足够接近,RedisVL 会返回类似RouteMatch(name=None, distance=None)的未命中结果。

request = "The cache keeps timing out when my app connects."
match = router(request)

if match.name is None:
    destination = "fallback_workflow"
else:
    route = routes_by_name[match.name]
    destination = route.metadata["handler"]

print(match.name, match.distance, destination)

把它当 distance 作相似度距离,而不是概率。 在Redis COSINE 距离方面,较低的数值代表匹配度更近。 将匹配的路线、距离、阈值和选定的目的地存储在你的应用程序遥测中。

处理失误和模糊匹配

当没有路由匹配或多个路由合理时,语义路由器需要确定性行为。

对于失误:

  • 引导到备用工作流程,比如通用助理提示、关键词路由器、表单或人工交接。
  • 当用户意图不完整时,提出澄清性问题。
  • 记录该请求以供离线审查。 这可能会揭示缺失的路线或缺失的参考。

对于可能存在的多个路线匹配结果,请使用 route_many() 查看候选路线和距离:

request = "Can you help me choose a production tier and estimate the price?"
matches = router.route_many(request, max_k=3)

for candidate in matches:
    print(candidate.name, candidate.distance)

如果两条路径都有效,则选择确定性规则,如最低距离、显式优先级元数据或澄清性问题。 避免在最高距离接近且行动对业务或安全有影响时默默选择路线。

更新和串行化路由器配置

将路由定义管理为应用配置。 RedisVL 支持将路由器配置序列化为字典或 YAML,之后还原。 利用此功能审查路由变更,跨环境推广,并保持路由定义与提示和工具版本保持一致。 例如,你可以将路由配置与应用部署工件一起存储,并在启动时重新创建路由器。

RedisVL 还支持动态添加、列出和删除路由引用。 谨慎使用动态更新:验证新引用,跟踪谁更改了它们,并在升级到生产环境前测试路由影响。

用评估集调校阈值

阈值决定了路由何时匹配。 由于RedisVL路由 distance_threshold 值使用Redis COSINE 距离单位,较低的阈值更为严格。 正确的数值取决于你的嵌入模型、语言、引用和请求分布。

使用以下调优流程:

  1. 收集每条路线的标注示例和不应该匹配任何路线的负面示例。
  2. 将示例拆分为调优集和验证集。
  3. 独立评估每条路由,测量假接受、假拒绝和模糊匹配。
  4. 先对高影响操作采用更严格的阈值,仅在有验证数据支持时才放宽这些阈值。
  5. 每当你更改嵌入模型、参考或路由分类法时,都要重新评估阈值。

不要比较不同嵌入模型的路由器之间的距离值。 Redis 向量索引需要查询向量以匹配向量场维度,模型变更通常需要重建或对路由器索引进行版本调整。 更多信息请参见 Redis 向量搜索概念

理解距离、阈值和优先级

路由距离是输入请求嵌入与路由引用嵌入之间的相似距离。 在RedisVL语义路由器 COSINE 的距离度量中,值越小表示请求更接近路由引用。 路由器只有在结果距离在该路由 范围内时才接受该路由 distance_threshold

避免将路线距离当作置信百分比来衡量。 0.35 这一距离并不意味着置信度是 35%,而且对某个嵌入模型有效的阈值,未必对另一个模型也有效。 用距离作为排名和接受信号,用标注的例子进行校准。

RedisVL 路由没有单独的语义权重设置。 改用这些路由控制杆:

杠杆 何时使用它 Effect
下层 distance_threshold 该路线会触发昂贵、敏感或不可逆的操作。 误接受更少,但回退或澄清请求会更多。
更高 distance_threshold 该路线风险低、宽广,或可安全恢复下游。 匹配更多,但无关请求进入该路由的风险也更高。
更好的参考资料 这条路线过窄、过宽,或者与其他路线混淆。 通过改变路由代表的事物来移动路由边界。
聚合方法 一条路线有多个参照项,只需一个参照项即可匹配。 min 可以偏向最接近的参考;平均型聚合偏好参考点始终接近的路线。
应用优先级元数据 两条在语义上都成立的路径彼此非常接近,而你的业务逻辑需要一个决胜规则。 让应用选择一个确定的胜出者,而不是声称该路由在语义上更接近。

对于访问账户数据、调用工具、更改状态或升级到人工的路由,选择更严格的阈值。 对于低风险路径如常见问题选择、文档搜索或模型选择,选择更宽松的阈值,因为下游提示仍可提出澄清性问题。 如果前两条路线距离相近,建议采用澄清步骤或确定性优先规则,而不是默默选择高影响的行动。

在现实世界的人工智能模式中使用语义路由

语义路由在AI应用需要快速且可解释的决策后,在调用模型、提示、工具或工作流程之前非常有用。 常见模式包括:

图案 语义路由如何发挥作用
模型路由 将简单请求发送给更小或更低成本的模型,较大的模型则保留给复杂的推理、编码或安全敏感任务。
提示路由 选择合适的系统提示或提示模板,用于计费、支持、销售、故障排除或政策问题。
工具路由 请选择客服是否拨打搜索、工单、诊断、计费、客户关系管理,或者干脆不使用任何工具。
RAG 路由 在运行向量搜索前,选择合适的检索索引、知识库、租户语料库或产品文档集。
人工切换路由 当语义意图与敏感工作流相符时,将请求路由到专业队列、升级路径或人工审核。
安全与策略路由 在调用主助手之前,先识别那些需要采用更严格防护措施、受限提示词、审计跟踪或拒绝流程的请求。

在生产环境中操作语义路由

在生产工作负载中应用以下做法:

  • 保持路线分明。 拆分或重命名重叠的路线。 合并那些经常产生模糊匹配的路线。
  • 优先选择经过筛选的参考资料。 添加代表性话语,映射到一条路径。 删除那些吸引无关流量的引用。
  • 审慎地使用回退机制。 在应用程序逻辑中实现回退机制。 广泛的备选路径可以捕获本应错过的请求。
  • 版本路由配置。 包含提示词、工具、模型和路由版本元数据。 像回滚其他应用配置变更一样,对路由变更进行回滚。
  • 观察路由质量。 追踪路由命中率、未命中率、顶线路径、距离、阈值、模糊匹配计数、退回率及下游成功指标。 查看按路线划分的距离和置信度分桶分布。
  • 需要时分开租户。 当租户有不同的路由集或严格的数据隔离要求时,可以使用隔离路由器、密钥前缀或 Redis 实例。
  • 保护敏感元数据。 不要在路由元数据或引用中存储秘密。 将路由示例视为应用数据。
  • 规划容量。 路由引用嵌入并索引于 Redis 中。 保持路由集紧凑且具代表性,并随着引用的增长监控内存、延迟和索引大小。

清理资源

要继续使用在本文中创建的资源,请保留资源组。

否则,如果您已不再需要使用这些资源,可以删除您创建的 Azure 资源组以避免产生费用。

Important

删除资源组的操作不可逆。 删除资源组时,包含在其中的所有资源会被永久删除。 请确保不会意外删除错误的资源组或资源。 如果在现有资源组(其中包含要保留的资源)内创建了此资源,可以逐个删除这些资源,而不是删除资源组。

删除资源组的步骤

  1. 登录到 Azure 门户,然后选择“资源组”。

  2. 选择要删除的资源组。

    如果有多个资源组,请使用“筛选任何字段...”框,键入为本文创建的资源组的名称。 在结果列表中选择资源组。

    截图显示工作面板中需要删除的资源组列表。

  3. 选择“ 删除资源组”。

  4. 系统会要求确认是否删除资源组。 键入资源组的名称进行确认,然后选择“删除”。

    截图显示了一个需要资源名称确认删除的表单。

片刻之后,将会删除该资源组及其所有资源。