客服Agent设计:多轮对话与上下文管理,决定它到底像不像真人

做客服 Agent,真正难的往往不是“能不能答”,而是“能不能连续几轮都答对”。

用户第一句问退款,第二句补充订单号,第三句开始抱怨物流慢,第四句又问优惠券能不能补发。如果 Agent 到第四轮已经忘了前面说过什么,那体验基本就废了。说白了,客服 Agent 的上限,很大程度上取决于它怎么管上下文。

为什么客服场景特别容易把 Agent 做崩

很多人第一次做客服 Agent,思路都很直接:把最近几轮聊天记录拼进 prompt,让模型接着答。

这个方案在 demo 阶段 usually 没问题,甚至前几天你会觉得“挺聪明啊”。但一旦进真实场景,问题马上就冒出来了。

客服对话有几个很烦的特点:

  • 用户表达跳跃,经常一句一个话题
  • 信息分散,关键事实不会一次性说全
  • 对话轮次长,而且中间夹杂情绪表达
  • 回答不能只看语义,还要看业务规则和历史状态

比如下面这种对话,就很典型:

用户:我的订单怎么还没到?
Agent:请提供订单号,我帮你查询。
用户:A20260409001
Agent:查询到包裹正在派送中,预计今天送达。
用户:可是昨天你们也这么说。
Agent:很抱歉给你带来不便。
用户:如果今天还不到,能退款吗?

这时候 Agent 要处理的,不只是最后一句“能退款吗”。

它还得记住这几个上下文事实:用户在问 订单 A20260409001,问题是 物流延迟,之前已经有一次承诺落空,用户情绪在变差。少了任何一个点,回答都可能显得像机器人。

多轮对话里,真正要记住的不是“所有话”,而是“关键状态”

这是我觉得很多实现里最容易跑偏的地方。

不少系统把“上下文管理”理解成“尽量多塞历史消息”。结果 token 花得飞快,效果还不稳定。因为模型并不需要记住每一句客套话,它需要的是当前会话里那些会影响决策的事实

客服 Agent 最值得保留的,通常是这几类状态:

1. 用户身份和会话绑定信息

比如用户 ID、手机号尾号、会员等级、当前订单号、工单号。

这些东西一旦识别出来,就不该反复让用户再说一遍。你让用户每两轮重新报一次订单号,体验会非常差。

2. 当前意图和子任务

用户到底是在问退款、催发货、查物流,还是在投诉服务?

而且这个意图不是一成不变的。真实客服对话里,经常会从“查状态”转成“要补偿”,再转成“我要人工”。Agent 需要知道当前主任务是什么,已经执行到哪一步。

3. 业务事实

比如订单状态、支付状态、物流节点、退款资格、优惠券是否使用过。

这里有个坑:业务事实最好来自系统查询,不要只靠模型从聊天记录里猜。 聊天记录可以提供线索,但最终决策最好绑定后端数据。

4. 用户情绪和风险信号

这不是锦上添花,而是很多客服系统必须有的东西。

同样一句“那你们到底怎么处理”,普通咨询和高投诉风险的处理策略完全不一样。如果 Agent 能识别连续负面表达、重复追问、升级倾向,就能更早切人工或者切补偿流程。

一个靠谱的做法:把记忆拆成 3 层

我不太建议把所有信息都混在一段 prompt 里。更稳的方式,是把客服 Agent 的上下文拆成三层:短期对话记忆结构化会话状态外部知识与业务数据

这样做的好处很直接:谁负责聊天连续性,谁负责业务准确性,边界清楚,不容易互相污染。

第一层:短期对话记忆

这一层保存最近几轮原始对话,用来保持语气和语义连贯。

比如最近 6 到 10 轮对话,通常就够了。它适合处理这些问题:

  • 代词指代,比如“这个订单”“刚才那个地址”
  • 紧接着上一句的追问
  • 保持回复口吻一致

但它不适合无限增长。

因为轮次一长,模型就会开始“看似记得很多,其实抓不住重点”。而且成本会越来越高,延迟也会上去。

第二层:结构化会话状态

这是我觉得客服 Agent 里最关键的一层。

你可以把它理解成一份不断更新的会话摘要,但不是自然语言摘要,而是一份结构化状态。比如:

{
  "session_id": "sess_20260409_001",
  "user_id": "u_18392",
  "intent": "refund_query",
  "order_id": "A20260409001",
  "order_status": "delivering",
  "delivery_delayed": true,
  "emotion": "negative",
  "asked_for_human": false,
  "last_policy_checked": "refund_policy_v3",
  "next_best_action": "explain_refund_rule_or_offer_manual_transfer"
}

这份状态的价值非常大。

因为模型每次生成回复前,不用重新从十几轮对话里猜“用户现在到底在干嘛”,而是直接看到已经沉淀好的关键字段。这样回复会稳定很多,工具调用也更可控。

第三层:外部知识和业务数据

这一层包括知识库、FAQ、政策文档、订单系统、CRM、工单系统。

客服 Agent 不能只靠记忆活着。它必须有能力在需要的时候查“真相”。比如退款规则、运费险是否生效、某个活动券能不能补发,这些都应该从外部系统拿,而不是让模型脑补。

一个很实用的原则是:

对话历史负责理解上下文,结构化状态负责维持任务,外部系统负责提供事实依据。

这三者别混。

上下文不是越多越好,裁剪能力比堆料更重要

很多 Agent 后面变笨,不是模型不行,而是上下文已经脏了。

一段长对话里,常见的脏信息包括:

  • 已经失效的意图
  • 被纠正过的错误信息
  • 重复安抚类话术
  • 与当前任务无关的闲聊

如果你把这些东西原封不动全塞进去,模型很容易被旧信息带偏。

比如用户一开始说“我要退款”,后面在客服解释后改成“那先等等看今天会不会送到”。如果状态没更新,Agent 还是按退款流程往下走,用户会觉得这客服根本没在听。

所以一个成熟的上下文系统,必须具备两种能力:

1. 增量提取

每轮对话后,不是简单 append,而是抽取这轮新增了什么事实。

比如新出现了订单号、用户明确表达要人工、系统查询到物流节点变化,这些都应该进入结构化状态。

2. 冲突消解

如果新信息和旧信息冲突,要知道以谁为准。

比如:

  • 用户先说“我要退款”,后来说“先不退了”
  • 用户报了两个不同订单号
  • 系统状态和用户口述不一致

这时候不能把两份信息都留着让模型自己悟。最好在状态层就做冲突标记,必要时要求 Agent 主动澄清。

一个实用的处理流程

如果你正在设计客服 Agent,我比较推荐把每一轮处理拆成下面这几个步骤:

1. 接收用户输入
2. 从最近对话中理解当前语义
3. 更新结构化会话状态
4. 判断是否需要调用知识库或业务系统
5. 组合最小必要上下文给模型生成回复
6. 输出回复,并记录本轮结果

看着不复杂,但这里面的关键点是“最小必要上下文”。

不要每次都把全部信息给模型,而是按当前任务组装。比如用户只是追问“那多久能到账”,那你给模型的重点应该是退款申请状态、到账时效规则、最近一轮用户问题,而不是整段历史聊天。

生成回复前,建议固定一份上下文装配模板

这一步非常值得做,不然系统会越来越不可控。

我更推荐在调用模型前,统一组装一份上下文输入,大概像这样:

[系统角色]
你是电商客服助手,回答要准确、克制,不能编造政策。

[当前会话状态]
- 用户ID: u_18392
- 当前意图: refund_query
- 订单号: A20260409001
- 用户情绪: negative
- 是否需转人工: possible

[最近对话]
用户:如果今天还不到,能退款吗?

[实时业务数据]
- 订单状态:派送中
- 最近一次更新时间:2026-04-09 15:20
- 退款规则:未签收订单可发起退款申请,但派送中订单需提示时效和拦截限制

[回复要求]
1. 先回应用户关切
2. 明确说明规则边界
3. 不确定时给出下一步操作
4. 用户情绪持续恶化时建议转人工

这个模板的意义不只是“好看”,而是它能让系统行为更稳定。

因为你把“角色”“状态”“事实”“最近问题”“回复约束”分开了,模型更不容易把政策、情绪和历史聊天混成一锅粥。

真正难的地方,是状态更新而不是回答生成

很多人把精力都花在 prompt 上,想让回复更像真人。

但说实话,在客服场景里,决定系统质量的,经常不是最后那句回复,而是前面那套状态管理到底稳不稳。因为一旦状态错了,后面的回答再流畅也没用。

我见过几个特别常见的问题:

状态只增不减

系统一直往 session 里加标签,但从来不清理过期信息。

最后一个用户明明已经取消投诉,状态里还挂着 high_risk_user=true,后面所有回复都变得过度谨慎,甚至乱转人工。

摘要太像废话

有些系统会每几轮自动总结一次,但总结内容全是“用户咨询订单问题,客服进行了回复”。

这种摘要几乎没用。好的摘要必须能驱动下一步动作,比如“用户关注是否可退款,已提供订单号,当前因物流延迟产生负面情绪,若今日未送达可能升级投诉”。

业务状态和对话状态脱节

用户在聊天里说“已经收到货了”,但订单系统还没更新签收状态。这个时候 Agent 不能直接拍板,而应该识别成“用户口述已收货,系统待确认”,然后给出更稳妥的话术。

这类细节,特别容易决定一个客服 Agent 是专业还是翻车。

多轮对话里,什么时候该让 Agent 主动确认

不是所有上下文问题都应该靠猜。

当出现下面这些情况时,我建议 Agent 主动澄清,而不是继续强答:

  • 用户提到多个订单,当前处理对象不明确
  • 用户意图发生跳转,但未明确放弃旧诉求
  • 用户口述和系统数据冲突
  • 当前政策判断依赖缺失字段

一个成熟的客服 Agent,不是“什么都能秒答”,而是知道什么时候该问一句:

“你是想处理刚才那个订单,还是另一个订单?”

这句话看起来慢了一步,实际上是在避免后面更大的错。

如果只能给一个建议,我会选“状态机思维”

很多团队做客服 Agent,习惯把它当成聊天机器人。

但我越来越觉得,客服 Agent 本质上更像一个带自然语言接口的状态机。 聊天只是表层,核心还是识别当前状态、执行合适动作、在必要时切换流程。

你可以不把系统做成很重的 BPM,但至少要有这个意识:

  • 现在处于哪个阶段
  • 下一步允许做什么
  • 什么条件下要切人工
  • 什么条件下要重查系统
  • 什么条件下要重置上下文

有了这层设计,模型才不会在长对话里越跑越偏。

写在最后

客服 Agent 最容易被骗的一件事,就是 demo 看起来很聪明。

真上生产后,你会发现决定成败的不是那句“您好,很高兴为您服务”写得像不像人,而是系统能不能在第 8 轮、第 12 轮、第 20 轮还记得用户到底在解决什么问题。

所以如果你正在做这类系统,我的建议很明确:别把精力全砸在话术润色上,先把上下文管理做好。把短期记忆、结构化状态、业务事实三层拆开,再配上裁剪和冲突消解机制,客服 Agent 的稳定性会立刻上一个台阶。

这部分做稳了,后面再谈回复风格、服务温度、转人工体验,才有意义。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐