客服对话变了,订单状态不能跟着被改写

发布时间:2026/10/25 16:38:52
客服对话变了,订单状态不能跟着被改写

“前一轮已经答应我退款”是对话内容,不是订单状态。10月19日微软讨论了Agent的内部访问风险。把聊天记忆直接当成业务状态,会让一段看似连贯的解释获得不该有的权限。

状态由事实驱动

客服可以从询问物流切换到售后咨询,这属于意图变化。能否退款却依赖付款、履约、退货及审核状态。有限状态机应读取可信事件,不能接受模型传入一个“当前状态”就继续办理。

不要为了限制注入把历史一刀切成最近五轮。截短会丢掉用户已经提供的信息,也不会自动消除恶意内容。把原始对话作为审计材料,业务系统只接收经过类型约束的请求,并独立查询状态。

状态转移的拒绝原因应返回给客服,允许它解释缺少什么材料。不要让模型反复改参数尝试撞过规则;规则拒绝后需要新的可信事件,而不是一段更长的理由。

图中的正常路径需要履约事实支持,红色跳转不因对话中的承诺而开放。

用服务端状态拒绝跨阶段跳转

以下是可离线运行的最小示例,使用Python标准库。输入均为教学构造,不连接业务系统。

ALLOWED = { "PAID": {"SHIPPED", "CANCELLED"}, "SHIPPED": {"DELIVERED"}, "DELIVERED": {"REVIEW"}, "REVIEW": {"REFUNDED", "REJECTED"}, } def transition(current, event): if event not in ALLOWED.get(current, set()): raise ValueError("invalid transition") return event assert transition("PAID", "SHIPPED") == "SHIPPED" for source, target in [("PAID", "REFUNDED"), ("UNKNOWN", "REVIEW")]: try: transition(source, target) except ValueError: pass else: raise AssertionError("unexpected transition") print("valid transition accepted; 2 invalid transitions rejected")

这个函数只验证单次转移。生产系统要把读取状态和写入新状态放进同一事务,校验事件来源并处理版本冲突;它不是完整的退款工作流。

让测试覆盖事实冲突

用同一段自然语言分别配上不同订单事实,检查后端结果是否随事实变化。再用不同的说法描述同一个合法请求,观察是否被不必要地拒绝。前一种检查越权,后一种检查可用性。

样例未运行任何语言模型、对话记忆系统或并发数据库。它验证的是有限状态关系,不能给出长上下文注入的拦截率。

参考资料

  • Microsoft agentic insider
  • MCP authorization