裁决 — 当政策冲突时
Source: Dev.to
Algolia Agent Studio Challenge – 面向消费者的非对话式体验
提交概览
大多数支持工具仅仅检索一条政策并交给客服。实际上,工单常常位于多条有时相互矛盾的政策交叉点。
示例: 跑步机马达在使用 6 周后损坏。
- 30 天退货窗口 → 否
- 2 年马达保修 → 是
Verdict 是一个决策引擎,用于解决这些冲突。客服点击工单后,Verdict 从 Algolia 中提取相关的政策条款,检测矛盾,并依据以下解决层级进行处理:
- 产品特定 优先于 通用
- 情境 优先于 所有
最终得到 带完整引用的结构化裁决——无需聊天机器人,无需来回沟通。
演示亮点
| 场景 | 结果 | 备注 |
|---|---|---|
| Treadmill X500(保修 vs. 退货) | ✅ 批准(绿色) | 马达保修覆盖已过期的退货窗口。 |
| SoundPro Earbuds(卫生例外) | ❌ 拒绝(红色) | 卫生例外阻止退货,即使在 30 天窗口内。 |
| Alpine Hiking Boots(损坏例外) | ✅ 批准(绿色) | 运输损坏的情境例外胜过已过期的退货窗口。 |
| TrailBlazer Daypack(标准退货) | ✅ 批准(绿色) | 无冲突——普通案例。 |
| 自定义工单 | 实时分析 | 粘贴任意文本,实时观看 Verdict 的推理。 |
| 政策索引 | 浏览 26 条记录 | 包含 3 条诱饵政策,系统会正确忽略它们。 |
- 实时 URL: (链接已省略)
- 演示视频: (链接已省略)
政策索引详情
- 索引名称:
apex_gear_policies - 记录数: 26 条单独的政策条款(每条记录对应一个条款),适用于虚构零售商 Apex Gear。
- 每条记录的元数据:
{
"policy_layer": 1‑4,
"priority_score": number,
"policy_type": "string",
"product_tags": ["string"],
"conditions": "string",
"effect": "string"
}
-
为何采用条款级别索引?
冲突解决需要比较 单个 条款,而不是整篇文档,并且每条记录都远低于 Algolia 10 KB 免费层的限制。 -
诱饵(3 条记录):
- 已过期的假日退货延长政策
- 会员积分优惠
- 大批量折扣政策
它们与演示场景的产品类别相同,但不应被引用。系统始终会忽略它们。
Algolia 配置
| 功能 | 描述 |
|---|---|
| 自定义排序 | desc(policy_layer), desc(priority_score), desc(specificity_score) – 确保最权威的条款排在前面。 |
| 索引级规则(3 条) | 当查询包含触发词时提升关键覆盖政策。例如,查询中出现 “hygiene” 时,将 HYG‑4.1(耳内音频卫生例外)提升至位置 1。 |
| 同义词组(6 组) | 扩展词汇表: • “defective” ↔ “broken”, “malfunction”, “stopped working” • “earbuds” ↔ “in‑ear audio”, “personal audio” |
| 结果流 | 检索时特性(排序、规则、同义词)决定 LLM 能看到的内容;推理时特性(条件匹配、解释)由 LLM 处理。 |
这些层级协同工作:Algolia 提供有序、词汇归一化的条款集合;随后 LLM 在其上进行推理,生成最终裁决。
Agent Studio 循环
-
系统提示 定义多步骤协议:
- 从工单中提取关键信息。
- 执行 三次针对性 Algolia 检索(通用退货、产品特定保修、情境覆盖)。
- 分析所有检索到的政策,检测冲突,依据层级进行解决,并输出 结构化 XML 裁决。
-
动态搜索选择
Source: …
– 代理根据工单内容决定运行哪些查询。
- 耳机工单:
"hygiene earbuds in‑ear audio return" - 跑步机工单:
"Pro‑Treadmill X500 warranty" - 登山靴工单:
"shipping damage carrier report override"
- 防幻觉守护 – 判决中的每个
clause_id必须逐字复制自搜索结果。代理不能凭空编造政策或向客户索取更多信息;它必须要么做出决定,要么升级处理。
如何探索
- 点击演示 UI 中的工单 → 查看判决卡、政策对比面板和冲突追踪。
- 将鼠标悬停在引用上 以查看确切的条款文本。
- 浏览政策索引,查看全部 26 条记录(包括诱饵记录)。
要点
判决展示了 非对话式、主动决策 可以基于 Algolia 的检索能力和 LLM 推理构建。代理的工作流很简单:
查看工单 → 点击 → 阅读结构化判决 → 执行
没有聊天气泡,没有来回交流,只有由 Algolia 与 LLM 提供支持的可靠、可解释的裁决。
概览
Agent Studio 的 /completions 端点返回 Server‑Sent Events (SSE) 流。我在 API 路由中构建了自定义 SSE 解析器,捕获 代理推理链中的每一个事件——不仅仅是最终的文本输出。
解析器:
- 将
tool-input-start事件(携带搜索查询和toolCallId)与tool-output-available事件(携带该toolCallId的实际 Algolia 命中)关联。 - 提供完整的流水线视图:
- 代理搜索了什么
- Algolia 返回了什么
- LLM 最终引用了哪些记录
前端渲染
UI 将此流水线追踪可视化呈现:
- 每个 Algolia 搜索步骤显示 查询文本、命中数量 与 返回的单条政策记录。
- 最终判决中被引用的记录会获得 “在判决中被引用” 徽章,方便查看到底是哪几条检索到的条款影响了决定。
如果 LLM 偏离了预期格式,UI 会回退显示原始响应并弹出警告横幅——永不崩溃。
系统提示 – XML 标记输出
<verdict>
<status>APPROVED</status>
<type>warranty_claim</type>
<explanation>Motor warranty overrides expired return window...</explanation>
<clause>
<id>WAR-3.1</id>
<title>Pro-Treadmill Motor Warranty</title>
<valid>true</valid>
<outcome>warranty_approved</outcome>
<details>Motor failed within 2-year warranty period</details>
</clause>
<rule>
<id>WAR-3.1</id>
<description>Product-specific warranty overrides general return</description>
</rule>
</verdict>
- 前端使用 基于正则的标签提取器 将其解析为类型化组件。
- 在每个场景下进行 20 多次
temperature=0的测试运行时,XML 始终保持良好结构。
Algolia 功能塑造检索
| 功能 | 作用 |
|---|---|
| 自定义排序 | 每个搜索结果在返回时已按政策权威度预排序。 |
| 索引级规则 | 当触发条件满足时,将关键覆盖条款提升至顶部。 |
| 同义词 | 规范词汇(例如 “motor stopped working” → “mechanical defect”),让 LLM 不必自行猜测。 |
所有这些都在 Algolia 仪表板中配置,并通过 Agent Studio 透明工作——无需额外的 API 代码。
为什么不使用向量数据库?
- 向量数据库会检索 “语义相似” 的政策,而这不是合规数据所需的。
- 当客户报告跑步机电机故障时,我们需要 确切的电机保修条款,对应特定产品型号(
policy_layer:3, applies_to:Pro‑Treadmill X500),而不是一堆通过嵌入距离排序的模糊相关健身设备政策。 - 带有精确过滤的结构化元数据才是此类使用场景的正确检索模型。
se‑case.
性能
- 总分析时间(在每个判决后 UI 中显示):5‑10 秒——几乎全部是 LLM 推理。
- Algolia 检索:< 50 ms,在所有三个搜索中。
在支持工作流中,代理需要筛选数十个工单,这种检索速度使瓶颈保持在推理阶段,而不是等待数据。