
过去大半年我们团队给自己运维了两年的客服机器人体系加装了一个新模块内部代号叫 Agent-Reach。原因很直接不管底层大模型换了几代机器人始终处在你问我答的被动位置用户不开口它就不吱声。但业务侧的诉求早就变了从售后回访、物流异常通知、活动触达、会员唤醒到订单跟进全都希望机器人能主动找人说话。Agent-Reach 的定位就是一套统一的智能体主动触达引擎负责把 AI Agent 从被动响应变成按策略发起对话同时把打扰用户的风险牢牢控制住。这篇文章写给做智能客服、用户运营中台、消息推送体系的朋友也适合对 AI Agent 真正落地方案感兴趣的工程师。立项逻辑、分层架构、踩过的坑、用哪些指标评估我都会讲清楚。1. 为什么要给 AI 智能体装上主动触达能力Agent-Reach 的立项逻辑1.1 被动响应的瓶颈先说我们团队最真切的感受。两年时间里客服机器人的意图识别、知识库问答、多轮对话能力都迭代过好几轮线上会话的解决率从不到六成提到了八成以上。但所有能力都依赖一个前提用户先发起会话。无论用户从 App、小程序、企业微信还是网页进来机器人只是坐在那里等。用户不来它就什么也不做。这时候业务侧的同事就很痛苦。大促做完要回访高价值客户订单出现异常要主动通知用户会员沉睡超过三个月要尝试唤醒预约服务前一天要提醒。这些场景过去全靠运营手动建活动、发模板短信或者让客服坐席一条条复制粘贴回复。模板消息的问题很明显用户回复一句在吗运营同学不知道怎么接用户说我那个订单到底怎么了消息里根本没有上下文用户连续两次没点链接运营也完全没有感知。所有的触达都是一次性广播发出去就结束了没有反馈回路。我们在排查了十几个这样的需求之后意识到问题的根源不是缺少渠道不是没有用户联系方式而是没有一个能基于业务事件主动开口、根据用户回复动态调整话术、并把结果收回来的执行引擎。市面上有推送平台、有外呼系统、有客服机器人但它们互相隔离推送平台不知道怎么对话客服机器人不会主动发起会话外呼系统又不够智能。Agent-Reach 就是在这个缝隙里立项的。1.2 Agent-Reach 的目标与边界立项时我们定了一个很明确的表述Agent-Reach 不是一个新的聊天机器人也不是一个短信平台而是一个触达编排层。它接住业务侧下发的触达任务调用对话智能体与用户交互再通过已有渠道完成消息投递和回复回收。项目名字里的 Reach 强调的是够到用户这一动作而不是对话本身。我们同时划了三条边界避免项目膨胀。第一不做 IM 或者即时通讯软件不做新的用户端入口只接入公司现有的触达渠道包括 App Push、企业微信、短信、电话外呼。第二不做营销投放系统不负责选人群、定预算这些由运营平台负责Agent-Reach 只执行和反馈。第三内容安全是底线任何一次主动触达必须能被追溯、能随时终止、能一键撤回。这三条边界在公司内部讨论时吵了挺久有人希望把人群圈选功能也放进来被我们顶回去了——功能边界一旦模糊后面所有稳定性设计都会跟着失控。在这个定位下Agent-Reach 的核心价值可以概括成三句话让 AI 智能体从被动响应走向主动服务让每一次触达都成为一个完整对话而不仅是一条消息让主动触达过程可度量、可干预、可复盘。立项后我们给团队定了一个目标三个月内跑通异常订单主动召回高价值场景触达问答完成率不低于人工坐席的 80%同时负面反馈率不高于原模板消息的水平。后面所有设计都是围绕这三个约束开展的。2. Agent-Reach 的分层架构触达编排、状态机与渠道适配2.1 三层模型策略、编排、适配Agent-Reach 的整体架构我们拆成了三层设计原则是策略可热更新、对话不绑定渠道、渠道替换不影响上游。第一层是策略层负责回答四个问题触达谁目标用户范围、什么时候触达业务事件触发还是定时任务、通过哪个渠道、说一件什么事。策略层在实现上就是一组规则引擎加任务调度器运营和研发可以通过配置下发新的触达任务不需要改核心代码。比如订单出现异常后 30 分钟未处理且用户最近 7 天没有投诉记录就是一条典型的策略规则。第二层是编排层这是 Agent-Reach 的心脏。它拿到策略层的任务后先检查用户触达资格和频控再动用对话模型生成第一句开场白根据用户回复驱动多轮对话识别用户意图判断何时结束、何时转人工。这一层维护着每次触达的会话状态把大模型生成能力包裹在一个可控状态机里避免模型放飞自我。第三层是适配层统一封装所有渠道差异。不管走企业微信还是短信上层编排层只面向一个统一消息模型发送意图适配器负责把意图转换成对应渠道的 API 调用再把渠道回执和用户回复统一成标准事件返回编排层。这样分层的直接好处我们在改造短信渠道时体会得很深。我们原来有另一套系统对话逻辑里到处散落着短信网关的字段后来要接企业微信时几乎重写了一遍。Agent-Reach 从第一天就强制所有渠道走适配器后来一个月内接入了新的小程序客服渠道编排层一行没改。2.2 会话状态机的实现要点编排层最关键的实现是会话状态机。我们定义了五个核心状态待发起、进行中、沟通中、已完成、已终止。待发起表示任务已创建在等待频控检查或者最佳发送时间。进行中表示消息已投递但用户尚未回复。沟通中表示用户已回复Agent 正在多轮交互。已完成表示目标达成比如用户确认了新配送时间。已终止表示用户退订、投诉、超时未回复或人工介入后结束。状态转换由事件驱动事件来源有三类用户回复、渠道回执、定时超时。这个设计和直播弹幕那种无状态消息处理有本质区别因为每一次触达都是一段有始有终的对话没有状态机就无法回答这个用户现在进行到哪一步了。状态存储我们用 Rediskey 是触达任务 ID 拼接用户 IDvalue 是 JSON 结构包含状态、当前轮次、上下文摘要、最近一次事件时间。状态更新必须走 Lua 脚本保证原子性否则在高并发下两个事件同时到达会把状态打乱。比如用户回复和定时超时同时触发如果没有原子判断可能超时任务已经终止了会话用户的回复又把它唤醒导致用户收到一条莫名其妙的后续消息。这里还有一个容易忽略的点大模型生成的上下文不能全部塞进 Redis一个长对话几万字存起来既浪费内存又拖慢读写。我们的做法是每轮对话结束后做一次上下文压缩把关键信息提炼成结构化字段比如用户已同意改期期望时间周六上午原始消息异步落到对象存储用于审计复盘。2.3 渠道适配器怎么设计才不返工渠道适配器是三层架构里最琐碎但又最容易出问题的地方。每个渠道的技术特征差异很大企业微信要求先加好友且消息模板需要审核App Push 到达率高但点击率飘忽短信到达稳定但界面表达能力差电话外呼依赖 TTS 和 ASR 还需要考虑用户接听时段。如果适配器只是简单封装接口很快就会变成一堆 if-else 判断后面维护成本极高。我们规定所有适配器必须具备四个能力发送、接收回执、接收用户回复、查询可触达状态。发送接口统一收一个 ReachPayload 对象包含触达任务 ID、用户标识、渠道标识、消息内容、过期时间、幂等键。幂等键尤其重要渠道网关超时时重试不能导致用户收到两条一模一样的消息。我们统一生成一个 UUID 作为幂等键渠道网关层有去重表保证同一键只投递一次。App Push 适配器是最早写的也最有代表性。它要和手机厂商通道对接厂商通道各有各的限制有的要求 message 体不超过 4KB有的不支持点击跳转自定义参数有的对通知栏展示文案有敏感词过滤。我们的适配器把这些差异全部收敛在内部上层只需要说给这个用户发一条 App 内未读消息卡片具体是走厂商通道还是走应用内长连接适配器自己判断。遇到厂商通道回执延迟超过 5 分钟的情况适配器要自动降级改走应用内长连接补发保证触达时效。3. 主动触达的安全边界频控、防打扰与人工兜底3.1 什么时候允许智能体主动发起对话主动触达和被动响应的最大区别是被动响应的用户自己有意图机器人的任务是理解并满足主动触达是系统先开口用户可能根本没有准备好。所以什么情况下可以主动开口必须有一套严格规则而不是依赖模型临场判断。我们定的准入规则有四条全部满足才允许发起触达。第一存在明确的业务事件或用户订阅意愿例如订单状态异常、服务预约确认第二用户对这类触达有授权记录或平台协议中已涵盖第三用户不在全局退订名单和渠道退订名单中第四同一用户在所有渠道最近 7 天主动触达次数不超过两次且本次与最近一次触达间隔超过 24 小时。这四条规则翻译成代码就是策略层的一个准入检查函数每次任务创建时先做一道布尔判断判断失败直接返回不可触达根本不会进入编排层。这么做不是为了限制功能而是保护用户信任。一次不合时宜的打扰可能让用户把 App 通知权限关掉后续所有真实重要通知都进不来损失反而更大。另外我们特别强调一个细节任何智能体主动发出的第一条消息必须向用户表明我是机器人正在帮你处理什么事项。这个要求写进了系统配置由编排层强制校验不是靠提示词约束——因为提示词约束在模型升级后可能失效但代码强制不会。3.2 三层兜底从置信度阈值到人工接管主动触达场景里模型翻车的概率远大于被动响应场景。被动场景用户已经表达了意图模型只需要在几个候选意图里选一个主动场景用户回复可能是表达需求、反问、抱怨、调侃、拒绝甚至骂人任何话都得接得住。我们做了三层兜底。第一层是意图置信度阈值。编排层对用户每一条回复做一个轻量意图分类分类结果包含意图标签和置信度。如果置信度低于 0.4直接把对话转给人工坐席不让模型硬撑。比如用户回一句啊你谁啊模型给的「询问身份」置信度可能只有 0.35这种就直接转人工。第二层是情感护栏。意图分类器里专门加了一个负面情绪tag一旦置信度高于设定值会话立即进入安抚流程机器人不再推销或追问只做致歉和终止。第三层是强制退订识别。用户说出退订别再发拉黑不需要这类表达无论模型判断成什么意图状态机都无条件跳转到终止态把用户从触达名单中移除并发送一条确认退订的收尾消息。三层兜底全部接入审计日志。我们每次触达都会记录用户原话、模型判断、置信度、兜底动作哪怕是正常完成的对话也保留。这些日志一方面用于事后抽检另一方面是意图分类器迭代的训练样本。没有这些真实数据调模型就是闭门造车。3.3 防打扰策略与跨渠道去重防打扰有个容易被忽视的难点用户在小程序里被触达一次在 App 里又被触达一次在企业微信里再被触达一次表面看单渠道频控都没超但用户感知是一天被同一个事骚扰三次。所以我们做的是跨渠道去重统一以用户唯一 ID 维度评估触达频率。实现方案很直接在 Redis 里存一个滚动时间窗口的触达记录每次触达前检查窗口内触达次数。我们用 ZSET 结构存储最近 7 天的触达时间戳只需要 ZCARD ZRANGEBYSCORE 就能判断是否超限。频控阈值的配置在策略层支持按场景调整。比如订单异常通知因为时效性高允许同一用户 7 天内被触达 3 次但普通营销类活动最多 2 次。退订管理也是硬功夫。我们维护了三张名单全局退订名单、按渠道退订名单、按场景退订名单。全局退订意味着用户不想收到任何主动触达这个优先级最高。名单存 Redis 同时也落库每次准入检查先查名单再用布隆过滤器做一次粗筛避免每次都穿透到数据库。布隆过滤器会有极小的误判被误判的用户最多是少收到一次触达不会造成实质伤害这个取舍可以接受但反过来如果布隆过滤器误判成了该触达而数据库查不到就会造成打扰所以我们宁可多查一次库也要保证名单判断的绝对准确。4. 落地过程踩过的坑超时风暴与误触达的排查链路4.1 坑一外呼渠道超时引发雪崩Agent-Reach 第一次压测就出了个大问题当时场景是 App Push 批量触达 5 万用户。压测一开始推送网关的响应时间开始上涨从平均 200 毫秒涨到 3 秒然后我们的服务全部卡死Redis 连接数瞬间打满超时错误刷屏最后整个触达服务不可用。我们花了一个下午排查完整链路是这样的第一看监控面板发现业务服务线程池被打满几乎全部阻塞在等待渠道 HTTP 响应上第二顺着火焰图发现阻塞点集中在 push 适配器的同步 HTTP 调用上第三查渠道网关侧日志发现渠道网关处理能力其实正常问题出在我们这边没有设置合理的超时时间实际上是默认的 30 秒超时导致上游排队。等于说一旦网关 RT 接近服务超时大量请求会在等待中堆积线程池耗尽新请求进不来形成雪崩。修复方案分三步。第一步所有渠道适配器显式设置超时时间Push 默认 3 秒短信默认 5 秒企业微信默认 5 秒超时立即放弃并记录渠道超时回执不允许无限等待。第二步给渠道调用加熔断器连续失败率达到 30% 时快速熔断后续请求直接降级走备用渠道比如 Push 失败降级为短信提醒。第三步消息投递全部改成异步化发消息动作放到消息队列里削峰适配器消费队列后再调渠道把高峰期的突发流量打散。这个坑给我们的教训是接入任何外部渠道第一步不是看功能文档而是要先确认渠道的 SLA、超时行为和限流阈值。我们后续接新渠道都有一份渠道接入 checklist第一项就是确认超时模型和限流策略。4.2 坑二意图分类器复用导致误触达第二个坑更隐蔽属于模型层面的问题。我们在测试异常订单召回场景时有一个用户回复你平时几点方便联系Agent 判断这是一个时间咨询问题回答之后用户又回都可以你们也别半夜打就行Agent 又正常接住了。但问题出在意图分类管线这条对话被语义分类器同时打上了购买意向的标签因为联系“时间”被过往的营销线索模型学成了高购买意向的特征结果用户被加进了一个高意向跟进名单。第二天运营同事按名单打电话过去回访用户一脸懵体验很糟糕。我们复盘后发现根因有两个第一Agent-Reach 起初偷懒直接复用了公司里现成的销售线索意图分类模型没有针对触达场景重新规划标签体系第二没有把用户在表达沟通偏好和用户在表达购买意向做区分分类标签本身重合。修复措施是彻底隔离。我们不再复用任何业务侧的意图管线而是单独训练了一个触达场景专用的轻量分类器意图标签只有七类查询、确认、拒绝、退订、要求转人工、情绪表达、无关闲聊。同时给每类标签都配备了 few-shot 示例特别把时间偏好咨询这类容易和营销意图混淆的样本加进去作为负例。然后所有低置信度判断不对上层直接使用必须进入人工复核队列。从那以后误触达投诉的数量降到了原来的五分之一。4.3 一次完整排查链路可以怎么沉淀踩过两个大坑之后团队沉淀了一套触达系统问题排查清单后面几次出问题基本都能在半小时内定位。顺序很固定先看监控大盘确认影响面再查日志定位具体请求然后从日志还原触发条件和上下文构造最小复现用例用隔离环境验证根因修复后小流量灰度最后把事故复盘写成测试用例放进回归集。这套链路里最容易被跳过的是记录用户原话。很多系统为了省钱只记录结构化日志不存用户回复原文。但如果遇到模型类问题没有原话你根本无法做根因分析也不可能构造复现用例。我们现在的做法是所有触达会话的用户文本至少保留 90 天单独存储在对象存储里结构化日志里只保存一条索引。数据量确实不小但关键时刻这就是排查的命根子。5. 效果评估与数据回流用三个指标衡量一套触达引擎5.1 三个核心指标的计算口径Agent-Reach 上线后我们砍掉了原先运营体系里五花八门的报表统一用三个核心指标评估引擎效果。第一个是触达成功率等于渠道回执为已送达的消息数除以计划触达总数。这个指标反映的是通道质量和准入筛选是否合理。第二个是应答转化率等于用户在触达会话中有实质回复的次数除以成功触达数。注意实质回复要排除掉退订别发了这类负向互动定义上比简单点开率严格得多。第三个是负向反馈率等于用户主动退订、投诉或明确表达不满的次数除以成功触达数。这是所有主动触达系统的北极星门槛只要负向反馈率超过预设红线任何收益指标我们都视为无效。三个指标的分工也很清楚触达成功率可以快速发现通道问题应答转化率衡量对话质量负向反馈率衡量用户接受度。三者要一起看不能单看某一个。曾经有渠道因为通道到达率高但应答率极低一查原因是厂商通道把 App 内长连接切换到通知栏用户虽然收到了消息却因为展示形式不佳根本不点。5.2 小流量实验的效果对比我们做了两周小流量对比实验同一个沉睡会员唤醒场景三种触达策略各覆盖 1 万名用户。第一组是原来的模板消息发送固定文案加链接第二组是固定剧本机器人按照预先画好的分支菜单引导用户第三组是 Agent-Reach 动态对话由 AI 智能体根据用户回复自由对话。实验结果非常有代表性整理成表格看起来更直观触达策略成功触达率应答转化率负向反馈率单用户成本模板消息95.2%2.1%0.8%0.02 元固定剧本机器人94.8%4.5%0.5%0.08 元Agent-Reach 动态对话94.5%9.8%0.3%0.35 元动态对话的应答转化率是模板消息的 4.6 倍负向反馈率反而最低。成本确实高不少因为每次对话消耗大模型 tokens整体单用户成本增长了十几倍。但算总账还是划算的唤醒一个沉睡会员的后续贡献远大于 0.35 元且同等唤醒人数下运营人力成本大幅下降。更重要的是负向反馈率从 0.8% 降到 0.3%意味着用户对被打扰的感知没有随触达次数上升而恶化这条红线守住了。这次实验还有一个副产品我们意识到固定剧本机器人其实已经能解决一部分低复杂度场景比如纯粹的提醒通知。Agent-Reach 应该优先用在需要理解用户自由表达的场景用在纯通知上是杀鸡用牛刀成本上不可持续。5.3 数据回流到策略层和模型层评估不只是为了汇报更要形成闭环。Agent-Reach 每天产生大量真实触达会话数据这些数据有三个去向。去向一是策略层调优。每周我们都会分析负向反馈原因按时间不合适内容不相关频率过高话术有压迫感分类对应调整策略规则。比如有 15% 的负向反馈发生在晚上十点后我们就加了晚间触达开关默认关停只有高优先级业务可以申请豁免。去向二是模型迭代。触达会话里的用户原话成了意图分类器每周增量训练的主要样本来源。我们每周末跑一次训练流水线用新数据更新 few-shot 示例第二周一灰度发布。去向三是知识沉淀。高价值对话会被抽成范例补充进人工坐席的知识库。比如用户对改期时间的各种表达方式坐席在人工接管时能直接看到 Agent-Reach 已获取的上下文不用让用户重复一遍。闭环之后出现了一个有意思的现象触达会话长度在下降。最开始平均每个触达会话要八轮对话才结束三个月后降到五轮左右。原因是分类器精准度上来了模型更早判断出用户意图更快结束对话或转人工用户不需要被反复追问。6. 后续演进与个人经验6.1 从通知触达到真正的对话式触达Agent-Reach 第一阶段完成后我们复盘时把它定性为能在对话中完成任务通知和简单确认的系统距离让智能体像人一样主动服务还有距离。接下来的演进方向有两个。一个方向是接任务执行能力。异常订单场景里用户说能不能帮我改成周六送现在的 Agent 只能记录偏好然后转人工下一步要让它直接调订单系统的改期接口完成改期后把新配送单号发回给用户。这就从触达问答升级成触达任务闭环价值会上一个台阶。另一个方向是跨渠道连续触达。用户在小程序里没回复两小时后换短信补一条摘要短信那条用户回了但表达不完整再通过企业微信继续。跨渠道无缝衔接是这类系统的终局形态但实现难度很大因为会话状态、用户偏好、渠道能力都要协调我们有专门的子项目在推。6.2 给同行的落地建议和我的体会如果你们团队也准备做类似的事我有几条不成熟但都是踩坑换来的建议。第一从高价值存量场景切入不要一上来就做全渠道全场景。找一个用户确实迫切需要、打扰风险最低的场景比如订单异常通知跑通端到端闭环再扩展。第二先做退订、频控、审计再做花哨的对话能力。这三个能力表面上不产生业务价值但如果缺失任何一次事故都可能让项目被叫停。第三所有模型判断必须有置信度出口和人工兜底不要把大模型当作最终的决策器。Agent-Reach 里做决策的依然是策略规则和状态机模型只是生成表达和理解语义这个职责划分要非常清晰。我个人的体会是用户最讨厌的其实不是被打扰而是被假装理解地打扰。模板消息粗暴是粗暴但至少它不装聪明。AI 主动触达最危险的地方在于它会生成看起来人性化的表达一旦判断失误那种被欺骗感比单纯的打扰更让用户反感。所以 Agent-Reach 从头到尾都把让用户明确知道自己在和机器对话、随时可以叫停、说退就退放在最高优先级。技术上的各种优化都建立在尊重用户意愿这个地基上。地基稳了剩下的工程问题慢慢磨总能解决。