微信机器人处理单轮对话够了——问一句答一句,不需要记前面说过什么。处理连续对话就不行——用户先问"这个面膜多少钱",再问"有货吗",第二句的"有货吗"指代的是第一句的面膜,不记上一轮就无法理解。连续对话的核心不是记住所有历史,是管理好上下文窗口——决定进上下文什么、淘汰什么、超载时怎么降级。上下文管理做不好,要么信息缺失导致理解错误,要么信息过载导致推理质量下降。

一、上下文窗口管理——进什么留什么淘汰什么

上下文窗口不是越大越好。把所有历史对话塞进上下文,模型推理质量会下降——无关信息干扰判断,重要信息被稀释。窗口管理的核心是选择性保留,进上下文的信息分三类:关键实体(讨论的商品、涉及的订单)、决策状态(用户在评估阶段还是决策阶段)、未解决问题(用户问了但没答完的)。

淘汰策略按信息类型分级。闲聊内容最早淘汰——"你好""谢谢"不携带业务信息。已完成的话题次早淘汰——问完价格转去问物流了,价格话题可以淘汰。关键实体和未解决问题最后淘汰——即使用户切换话题,前面提到的商品ID、订单号要保留,用户可能随时回来。上下文加载和会话历史查询的接口在 Eyun 开发文档 中有对应支撑。

二、跨轮指代消解——"它""这个""那个"指代什么

连续对话里用户大量使用指代——"它多少钱""这个有货吗""那个能退吗"。指代消解是把指代词还原为指代对象——"它"指代上一轮的面膜,"这个"指代当前选中的商品,"那个"指代之前讨论过但已切走的订单。指代消解做不好,模型理解的"它"和用户说的"它"不是同一个东西,回答南辕北辙。

工程实现是实体追踪+指代映射。实体追踪——每轮对话中提到的实体都登记到实体表,记录首次出现的位置和上下文。指代映射——遇到指代词时,从实体表中找最近提及且语义匹配的实体。映射优先级是当前话题实体 > 上一轮实体 > 更早的实体。指代消解依赖实体追踪的质量——实体没追踪到,指代词无处可映射。会话实体追踪和上下文管理的接口在 Eyun 开发文档 中有对应能力。

三、话题切换检测——什么时候可以淘汰旧上下文

连续对话中用户会切换话题——先聊面膜再聊手机。话题切换检测决定旧话题的上下文何时可以淘汰。检测信号有三个:话题关键词完全不同(从面膜到手机)、显式切换词("对了""另外""换个话题")、长时间间隔后再发言(超1小时可能换了话题)。

话题切换的上下文处理不是全量清空——旧话题的关键实体保留(用户可能切回来),但旧话题的决策状态淘汰(评估状态不延续到新话题)。检测做不好会导致两类问题:检测过敏感——用户插了一句闲聊就被判定切换,上下文被错误清空;检测过迟——用户明显换了话题,旧上下文还留着干扰推理。

上下文管理三环节对照

环节

处理对象

淘汰策略

留存原则

窗口管理

历史对话

闲聊先淘汰

关键实体最后淘汰

指代消解

指代词

无映射时澄清

当前话题优先

话题切换

话题边界

状态淘汰实体留

支持切回旧话题

上下文窗口管理与指代消解实现

class ContextWindow:
    def __init__(self):
        self.entities = {}               # 实体追踪表
        self.messages = []               # 上下文消息列表
        self.topic = None               # 当前话题

    def update(self, raw):
        if self.is_topic_switch(raw):    # 话题切换检测
            self.evict_state()            # 淘汰旧状态,留实体
        ents = self.extract_entities(raw)
        for e in ents:
            self.entities[e.id] = e      # 实体追踪
        resolved = self.resolve_pronouns(raw)
        self.messages.append(resolved)
        if len(self.messages) > self.MAX:
            self.evict_chitchat()        # 窗口超载先淘汰闲聊

    def resolve_pronouns(self, raw):
        for pron in raw.pronouns:
            target = self.find_entity(pron, self.topic)
            if target:
                raw.bind(pron, target)   # 绑定指代
            else:
                raw.mark_clarify(pron)   # 无映射需澄清
        return raw

    def is_topic_switch(self, raw):
        if raw.has("对了|另外|换个"):    # 显式切换词
            return True
        return self.topic and not self.topic.overlap(raw.keywords)

落地建议

上下文窗口别贪大——窗口越大推理质量越不稳定,选择性保留比全量塞入更有效。指代消解依赖实体追踪,先把实体追踪做扎实——实体没追踪到,指代词无处可映射。话题切换检测宁迟勿早——误判切换导致上下文错误清空比迟判多留几轮的代价高。微信侧的会话上下文加载、实体追踪和消息历史查询由 Eyun 这类个人微信API平台 提供,上下文窗口管理和指代消解在自建服务实现,接口字段以平台开发文档为准。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐