NEW

免费试用已开放

立即开始

AI · 大模型 · 智能客服

企业微信 AI 会话上下文怎么管

更新于 2026-08-169 分钟

多轮做不好的表现很一致:客户说「就上次那个方案」,机器人回「请问您指的是哪个方案」。这通常不是模型能力问题,是上下文装配问题 —— 企业微信侧的会话是一条连续的流,没有天然的「一轮对话」边界,也没有会话结束信号,边界得你自己切;切在哪、窗口里装什么、什么时候压成摘要,每一步都能单独把多轮毁掉。这篇讲这三件事,外加归属键、并发和人工接管四个具体坑;接入部分按 wecomapi 的事件与消息接口来讲。

先切边界:没有 session,就得自己定义

HTTP 有请求边界,工单有开闭状态,即时通讯的会话什么都没有。消息一条条进来,相邻两条之间可能隔三秒,也可能隔三天。不切边界,上下文会无限增长,成本和延迟一起涨,模型还会被半年前的话带偏;切错了,客户会立刻感觉到机器人「失忆」。这是上下文工程里第一个必须做的决定,而且它不该由模型来做。

  1. 1超时切:最后一条消息之后 N 分钟无新消息即结束本轮。简单、可复现、成本为零。N 按业务定 —— 售前咨询取十几到几十分钟,售后与工单类可以放到几小时。
  2. 2显式切:客户或坐席明确表示问题解决,或者业务侧产生了一个结束事件(下单、工单关闭、退出群)。最准,但覆盖率低,只能当补充。
  3. 3话题切:让模型判断新消息与前文是否相关,不相关就开新一轮。听起来最聪明,实际最不稳 —— 判错一次就丢掉客户刚说过的关键信息。

可用的组合是超时为主、显式为辅,话题切只用来提示不用来决定。理由是代价不对称:多带一段无关上下文,损失是一点推理成本和轻微的注意力分散;少带一段关键上下文,损失是答错并且客户要重说一遍。在不对称的地方选保守那一侧,是这类系统里反复适用的原则。

边界不等于遗忘。切轮次只是不再把旧消息塞进窗口,历史仍然完整躺在存储里;客户提起旧事时靠检索捞回来,而不是靠窗口一直背着。把这两件事混为一谈,是把上下文越做越大的根本原因。

窗口装三段,比例比总量重要

上下文窗口既不是越大越好,也不是越省越好。可用的结构是固定三段:不变的系统指令与业务约束、这一轮检索来的知识片段、最近若干轮原文。三段要在代码里显式分开拼装,因为它们的失效方式完全不同 —— 指令段错了全线歪,检索段错了答错一题,原文段少了答非所问。混在一个字符串里拼,出问题时没法定位是哪一段的锅。

  • 指令段:稳定、可版本化、每次改动走一遍回归用例。临时活动规则不要往这里塞,它们属于检索段或槽位。
  • 检索段:每轮重算,带出处,条数设硬上限。宁可少给三条也不要为了「多点信息」把窗口塞满。
  • 原文段:按轮数截断而不是按字符数,而且必须成对截 —— 只留客户的话不留上一次的回答,模型会重复自我介绍或者重复提问。

原文段留几轮,按「错误恢复成本」定而不是按窗口余量定。纯查询类场景两三轮足够,答错了客户再问一次就行;涉及多步信息收集的场景 —— 报价、预约、故障排查 —— 必须覆盖完整的收集过程,否则会反复追问已经问过的字段,这是客户最反感的失败模式,比答不上来还伤。

示意:三段装配,槽位排在摘要之前javascript
// 示意逻辑:消息由 wecomapi 的事件回调推来,此处只表达装配顺序
// 精确事件类型与字段以线上文档为准
async function buildContext(convId, incoming) {
  const slots  = await slotStore.get(convId);              // 结构化事实
  const brief  = await summaries.get(convId);              // 自然语言摘要
  const recent = await turns.tail(convId, { rounds: 6 });  // 成对截断的最近轮次
  const docs   = await retrieve(incoming.text, { topK: 3 });

  return [
    systemPrompt(PROMPT_VERSION),  // 指令段:版本化,改动走回归
    renderSlots(slots),            // 槽位段:冲突时以它为准
    renderBrief(brief),            // 摘要段:只描述过程
    renderDocs(docs),              // 检索段:带出处
    ...renderTurns(recent),        // 原文段:按轮数截断
  ];
}

摘要会漂移,用槽位兜住事实

长会话装不下就压成摘要,这是标准做法。问题在于常见实现是滚动摘要:每 N 轮把「旧摘要 + 新消息」再摘一次。这个结构有个致命特性 —— 错误只进不出。第三轮把「预算大概五万左右吧,也不一定」误记成「客户预算五万」,之后每一轮都在复制这个结论,原文早就不在窗口里了,没有任何环节能纠正它。等到第二十轮,模型对着一个从来没人说过的事实在报价。

更稳的做法是把「事实」和「叙述」分开存。事实走结构化槽位:客户身份、已确认的需求、报过的价、承诺过的时间点。字段定死,每次更新记录来源消息标识,允许被后续消息覆盖但要留痕。叙述才走自然语言摘要,而且摘要里不承载数字、日期、金额和承诺,只描述过程 —— 「客户比较过两个方案,倾向后者,还在等内部确认」这种。

  • 槽位可覆盖、可追溯到某条原文、可被人工直接修正。修正入口要有,坐席发现记错了能当场改。
  • 摘要不含数字、日期、金额与承诺。这四类一旦进了自然语言,就再也验证不了。
  • 装配时槽位排在摘要之前,两者冲突时明确以槽位为准,并把这条写进指令段。

分开存还有个附带好处:可测。槽位是结构化的,能对着人工标注算准确率、算漂移率,出了问题能定位到具体字段;自然语言摘要只能靠人读,会话量一上来就没人读了,质量退化是悄悄发生的。凡是不能自动评的环节,最终都会退化 —— 这条在这套系统的每一层都成立。

上下文归属键:默认不合并

一个客户可能同时在单聊里问你、在两个外部群里出现,还被另一个同事的账号加过。上下文以什么为键,是这套系统里最容易埋雷的一个决定,而且它埋的雷通常在半年后才炸。

默认应该是「账号 + 对端会话」,也就是不合并。第一个理由是体感:群里随口说的话被拿到单聊里引用,客户会觉得被跟踪,这种不适感比多答对几个问题的收益大得多。第二个理由是边界:两个不同同事名下的会话内容互相串,在不少企业里直接是合规问题,尤其涉及客户归属和提成的时候。

确实需要合并时,只合并槽位不合并原文 —— 从另一个会话带过来的只有「已确认的事实」,不带具体的话,也不在回复里暗示信息来自别处。落地上,用 wecomapi 的事件回调拿到消息时先按会话维度原样落库,客户身份的归并放到自己这边的档案层去做,接入层保持最原始的粒度,后面想怎么合并都还有余地;反过来,在接入层就合并掉,拆回来要重跑历史数据。

群会话额外一条:@ 了谁、回复的是哪条消息,决定了这条消息该不该进上下文。把整个群的消息流全塞进窗口,模型会开始回答根本不是问它的问题,在客户群里这种插话比不回答更尴尬。

并发、过期与人工接管

客户连发三条消息是常态 —— 「在吗」「我想问下」「就是上次那个报价」。如果每条都触发一次完整装配和生成,会出现三个回答互相打架,顺序还可能是乱的。处理方式是合并窗口:收到消息后等一小段时间,通常一两秒,期间的新消息合并成一次输入再生成。这个等待对客户是无感的,对回复质量的提升非常明显。

同一会话必须串行处理。用会话标识做单飞或分布式锁,保证同一时刻只有一个生成在跑,后到的消息要么合并进去要么排队。这与站内讲消息时序的做法一致:保序范围压到会话粒度就够,不需要全局有序,全局有序的代价大得多而且解决不了这里的问题。

人工接管之后有一个必须明确回答的问题:坐席发出去的话,要不要进 AI 的上下文?答案是要,而且必须标明来源。不写进去,AI 回到这个会话时会与坐席刚说过的话冲突,客户会看到两种口径;写进去但不标来源,模型会把坐席的临场承诺当成自己可以复用的话术,下一个客户问同样的问题时照着说一遍。坐席消息同样以事件形式推来,用 wecomapi 的事件订阅一并接住,落库时打上来源标记即可。

过期策略跟着轮次边界走:一轮结束,窗口清空,原文落存储,槽位保留。槽位本身也要有生命周期 —— 三个月前确认的预算、半年前提过的上线时间,不该被当成当下的事实直接使用,装配时要么带上时间标注让模型自己判断,要么按类型设置有效期直接淘汰。这一层不做,系统跑一年之后会开始拿陈年信息跟客户对话。

本文讲的是上下文的组织方式与工程取舍。精确的事件类型、字段与调用约束以 wecomapi 文档为准,示意代码只表达装配顺序,不要照抄上生产。

常见问题

企业微信AI私域场景下,同一个客户的上下文要不要跨会话合并?
默认不合并。群里的发言被引用到单聊会让客户觉得被跟踪,跨同事账号串会话在多数企业里是合规和归属问题。确有必要时只合并结构化槽位、不合并原文,并且不要在回复里暗示信息来自另一个会话。
窗口该开多大?
先定原文轮数,再谈总量。查询类两三轮够用,多步信息收集类要覆盖完整的收集过程。窗口大小是结果不是目标:装不下时先砍检索段的条数,再砍摘要长度,最后才动原文段。
上下文该存在哪里?
热的部分(当前轮次窗口、槽位)放低延迟存储,按会话标识直取;冷的部分(历史原文)落主存储,供检索与合规留存。用 wecomapi 的事件接入时,消息进来先落库再进处理链路,事后重放和排障都靠这份原始记录,缺了它线上问题基本查不动。

准备好动手了?

精确字段、鉴权与端点以线上文档为准;可在控制台创建密钥后联调。

相关文章