Agent-Reach这个项目,是我在给一家SaaS公司做客户运营自动化时,从零搭起来的一套智能触达方案。最开始只是想解决一个很简单的问题:大模型已经能写出漂亮的营销话术、能判断客户意向、能自动生成跟进策略,但真正要把这些内容送到客户面前时,却处处碰壁。渠道分散、频率失控、内容变量出错、回执追踪缺失,这些看似不起眼的细节,反而成了Agent落地最大的拦路虎。Agent-Reach的核心,就是把Agent的"决策能力"和"触达能力"彻底打通,让智能体不只是会想,还能把手伸出去,把话送到该送的人面前。我在这篇文章里会完整拆解这套方案的架构设计、核心实现和排查经验,适合正在做Agent落地、客服自动化、用户运营的技术同学参考,也适合产品经理和业务负责人了解一套真正可运行的Agent触达体系长什么样。
1. 项目整体认知与设计思路
1.1 Agent-Reach解决的核心问题
现在的LLM应用层,大家把大量精力花在"让模型更聪明"上——更好的Prompt、更长的上下文、更复杂的工具调用。但实际跑过业务的人都有体会:模型再聪明,最后一步"触达"如果掉链子,前面所有智能都等于零。
传统触达方式的痛点非常明显。群发消息无法区分用户状态,固定模板话术读起来生硬,人工客服跟进又撑不住量级。而Agent-Reach要做的,是让大模型生成的每一次触达内容,都能按照正确的渠道、正确的频率、正确的话术模板,到达正确的用户,并且把用户的反馈闭环回收。
说个直白的类比:Agent的大脑再好使,没有手和嘴,它就只能是个"思考者",不能是个"执行者"。Agent-Reach就是那双手和嘴,而且是经过训练的手和嘴,知道什么时候开口、对谁开口、用什么腔调开口。
1.2 为什么"触达"比"生成"更容易被忽视
很多团队做Agent时有个惯性思维:先调模型效果,再考虑触达。但等到真的要发消息时才发现,触达层的问题远比想象中复杂。
举个例子,我们用GPT生成了一段客户召回文案,模型输出没问题,但在发送环节遇到了一系列连环问题:短信接口要求内容签名,企微接口要求特殊格式的消息体,邮件接口需要处理HTML转义,不同渠道对敏感词的过滤规则还不一样。更麻烦的是,如果没有频率控制,同一客户可能在一天内被短信、邮件、客服电话三个通道轮番轰炸,体验直接归零。
Agent-Reach的设计思路,就是把触达层当作一个独立的、可插拔的工程模块来对待,而不是把它简单地当作"调接口发消息"。触达层有它自己的状态管理、重试机制、幂等控制、模板引擎和策略引擎。只有把这层工程化做扎实,Agent的能力才能真正转化为业务结果。
提示:这是我在这套方案里最想强调的一点——很多AI项目死因不是模型不够好,而是"最后一公里"没人认真做。
2. 核心架构拆解
2.1 四层架构的分工与协作
Agent-Reach的整体架构分为感知层、决策层、触达层和反馈层四部分,每一层都有清晰的边界和职责。
感知层负责接收外部事件,比如用户提交表单、订单超时未支付、客服会话结束未解决、用户主动发来消息等。这些事件是Agent开始工作的触发信号。感知层做的主要是事件归一化——不管上游消息来自Webhook、消息队列还是定时任务,最终都统一转换成内部的事件结构体,写进事件流。
决策层是Agent主脑,由大模型消费感知层传来的事件数据,结合业务知识库、用户画像标签和预设的运营策略,产出触达决策。这里的产出不只是话术文本,还包括一个结构化的决策对象,里面包含触达渠道、触达时间、需要使用的模板ID、上下文槽位变量等。
触达层就是Agent-Reach最核心的工程部分。它会根据决策层的输出,完成渠道选择、模板渲染、频率控制、幂等去重、发送执行和失败重试。触达层不关心大模型是怎么思考的,它只关心一件事:这条触达指令能不能被安全、准确、高效地执行。
反馈层负责收集触达后的用户行为数据,比如是否已读、是否回复、是否点击链接、是否完成转化。这些数据一方面用于生成触达报告,另一方面会回流到决策层,作为Agent后续判断的依据,形成完整的闭环。
2.2 触达层的关键设计:渠道适配器与模板引擎
触达层内部,我做得最重的两个模块是渠道适配器和模板引擎。
渠道适配器解决的是渠道多样性问题。每接入一个新渠道(短信、邮件、企业微信、App Push、站内信),不需要修改触达层主逻辑,只需要新增一个实现统一接口的适配器。适配器负责处理该渠道的鉴权方式、接口协议、内容格式要求、频率限制和错误码映射。
模板引擎则是触达内容的装配车间。它做的事情是把大模型输出的内容,按照渠道特性和用户属性做最终渲染。举个例子,短信渠道需要把长文案压缩到70字以内,并且带上退订指令;邮件渠道需要把纯文本转换成HTML布局;企业微信渠道则需要把内容包进符合规范的消息卡片结构里。这个过程会用到我们在决策层传来的槽位变量,比如用户昵称、订单号、优惠券失效日期等。
用代码来解释模板引擎的工作方式更直观。内部会维护一套模板注册表,每个模板都有唯一的模板ID,触发时按ID加载模板,用槽位变量替换模板中的占位符,最后交给渠道适配器格式化输出。
2.3 为什么不直接用LangChain之类的框架
可能有人会问:现在Agent框架这么多,为什么还要自己写触达层?
我的看法是:Agent框架擅长的是对话管理和工具调用编排,但业务触达场景需要的是精细化的工程控制能力。触达涉及大量不可控因素,比如渠道API抖动、用户投诉风险、合规要求、A/B测试分流,这些都是通用Agent框架覆盖不到的细节。
Agent-Reach本质上是一套"业务触达基础设施",它可以独立使用,也可以作为Agent框架的外挂组件。我在实际项目中,就是把Agent-Reach的触达能力通过Function Calling暴露给大模型,让模型在需要触达时调用,但触达的频率、渠道、合规校验等硬性规则仍然由Agent-Reach的策略引擎说了算。这样既保留了Agent的灵活性,又不会让大模型"乱来"。
3. 实操过程与核心环节实现
3.1 落地场景选择:售后工单自动跟进
我在第一个生产环境里,用Agent-Reach跑了"售后工单自动跟进"这个场景,原因有三:一是触达链路相对标准,二是失败成本可控,三是效果容易量化。这个场景选得好不好,直接决定了项目能不能顺利跑通,强烈建议第一次落地时先选这种中低风险的业务。
业务背景是这样的:每天会新增大量售后工单,客服团队处理完后,需要跟进用户是否满意、是否还有遗留问题。以前靠人工打电话发短信,量大了根本忙不过来。用Agent-Reach后,流程变成:工单关闭事件进入感知层,决策层的大模型根据工单类型、用户历史记录、服务评分生成跟进话术,触达层自动决定优先用短信还是企业微信触达,并在用户回复后把内容路由给客服人工处理。
3.2 配置文件与策略引擎实例
以下是一个简化的Agent-Reach配置示例,展示如何定义一条智能跟进策略。
{ "agent_id": "after_sale_followup_v1", "trigger": { "event_type": "ticket_closed", "condition": "status == 'solved' && satisfaction_score IS NULL" }, "decision": { "llm_prompt_id": "followup_prompt_v3", "template_id": "followup_sms_greeting", "slot_variables": ["user_nickname", "ticket_id", "close_time"] }, "reach": { "channels": [ { "type": "sms", "priority": 1, "active_hours": ["09:00-20:00"], "max_per_day": 1 }, { "type": "wecom", "priority": 2, "max_per_day": 1 } ], "frequency_control": { "global_max_per_day": 3, "cool_down_minutes": 90, "respect_user_timezone": true }, "retry": { "max_attempts": 3, "backoff_strategy": "exponential", "base_delay_seconds": 60 } }, "feedback": { "collect_reply": true, "escalate_to_human": true, "timeout_minutes": 720 } }渠道优先级这里做了个设计决策:短信优先级高于企业微信,是因为售后跟进场景里,很多用户并不在企微活跃,短信的到达率和阅读率更稳定。如果用户短信拒收或者发送失败,自动降级到企微渠道。
频率控制模块用的是"全局令牌桶+渠道独立配额"的组合策略。全局令牌桶规定了单个用户每天最多被触达3次,但同一渠道每小时最多1次。这个参数不是拍脑袋定的,是根据运营团队历史投诉数据倒推出来的:之前人工运营时,每天超过3次触达的用户投诉率会陡增四倍。
3.3 大模型决策与模板渲染的衔接
决策层生成的内容,不是直接把模型输出的字符串丢给触达层,而是必须经过一次"结构化提取"。我使用JSON Schema约束模型输出格式,固定返回渠道、模板ID、槽位变量值三个字段,话术正文则由触达层根据模板ID渲染生成。
这个设计可能看起来有些绕,但我测试下来能有效规避大模型的自由发挥问题。比如模型觉得某用户很急,擅自把话术改得过于煽动,或者自作主张给用户发了一条超出策略范围的消息,这些行为在结构化约束下都会被拦截。
模板引擎在处理槽位变量时用了三层转义:第一层是HTML转义,防止用户输入的内容被当作脚本执行;第二层是渠道特殊字符转义,比如短信里的某些符号会被运营商拦截;第三层是PII脱敏,手机号、地址等敏感信息在渲染时自动打码展示。这三层转义浪费不了多少性能,但能省下一堆运营事故。
3.4 触达执行的幂等控制
触达层最大的坑之一,就是重复发送。上游事件可能重复投递,消息队列也可能重复消费,如果不做幂等,用户会同时收到两条一模一样的短信。
Agent-Reach的幂等方案是:每一条触达指令,从决策层产生时就生成一个全局唯一的触达ID(Reach ID),这个ID会贯穿整个触达生命周期。触达层在执行前先查Redis,如果触达ID已经存在且状态不是终态,直接跳过不重复发送。只有状态为发送成功或者永久失败时,才允许同一触达ID的补偿请求进来。
幂等键的设计也很讲究:不能用用户ID加时间戳,因为同一个用户同一分钟可能被不同策略触发;也不能纯用渠道消息ID,因为发送失败后重试需要同一个Key。最终我采用的是"触达ID"作为一级幂等键,"用户ID+渠道+策略ID"作为二级去重键,两层配合,既保证同一策略内不重复,又能防止不同策略互相打架。
4. 常见问题与排查技巧实录
4.1 典型问题速查表
在Agent-Reach迭代过程中,我整理了最常见的问题,大家在自建触达系统时可以直接对照排查。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 同一用户一天收到多条重复消息 | 事件重复投递或幂等键设计不合理 | 查看触达ID日志,确认是否同一ID多次执行 | 在发送前增加Redis幂等校验 |
| 大模型生成的话术包含违规词 | 模型幻觉,Prompt约束不够 | 抓取决策层原始输出,跑一遍敏感词检测 | 在模板渲染前增加敏感词过滤规则 |
| 短信渠道发送成功率骤降 | 模板变量里含特殊符号 | 查看渠道API返回码,确认字符编码 | 对槽位变量做渠道特殊字符转义 |
| 用户凌晨收到触达消息 | 频率控制没按用户时区判断 | 检查用户画像中的时区字段是否为空 | 为缺失时区的用户设置默认触达窗口 |
| 重试风暴打爆上游API | 失败重试策略使用固定间隔 | 观察上游接口限流返回码 | 改用指数退避加抖动 |
| 触达结果回传丢失 | 回执消息未关联触达ID | 检查回执回调字段与触达ID绑定情况 | 回执消息必须带ID,死信队列兜底 |
这里多说一句排查时的实操技巧:Agent-Reach在触达层每次执行都打结构化日志,包含触达ID、渠道、模板ID、用户ID、耗时、上游返回码、最终状态等近二十个字段。排查问题时,先按触达ID过滤出完整链路日志,从决策层到触达层再到反馈层一次性看完,基本能定位80%以上的问题。
4.2 踩过的三个大坑
第一个坑是开放了过多的自由度给大模型。最初版本允许模型直接指定触达内容,结果出现过一次严重事故:某个对话场景里,模型根据用户的一句话推断用户情绪低落,生成了一条"如果你感到孤单,可以拨打心理援助热线"的消息,虽然出发点是好的,但这条消息与业务毫无关系,用户收到后一头雾水,还质疑我们是否泄漏了聊天记录。从那以后,所有触达内容的最终渲染权都收归模板引擎,模型只能输出槽位变量。
第二个坑是重试机制的鲁棒性不足。早期实现是在HTTP调用失败后立即重试,最多重试三次,中间间隔固定五秒。第一次遇到渠道短时不可用时,三条重试请求全部卡在同一时间窗口,渠道恢复后瞬间涌入大量重试请求,直接把网关打崩了。后来改成指数退避加随机抖动,初始延迟60秒,每次翻倍,同时加上熔断机制——连续失败超过10次就暂停该渠道五分钟。
第三个坑是反馈层设计得太轻。最初,反馈层只记录用户是否已读、是否点击,但忽略了用户情绪维度。有一次,用户连续收到三条售后跟进,回复了"烦不烦啊",系统仍然按正常流程推进,直到人工介入才止住。后来,我在反馈层增加了用户负面情绪识别模块,识别到"烦""投诉""不要再发了"等关键词时,会强制终止该用户的后续触达,并把会话升级给人工。
4.3 成本控制与效果调优记录
大模型决策层的调用成本,是本项目最大的单笔支出。调优时发现,很多事件根本不需要LLM介入,比如简单超时提醒、状态已完结通知,完全可以用规则模板处理。我就加了一个前置规则引擎,把约60%的低复杂度触达分流到规则链路,只有真正需要语义理解的事件才走大模型。算下来,整体推理成本下降了约55%。
触达效果方面,做了两轮A/B测试。第一轮对比了"纯镐模板话术"和"大模型个性化话术",后者回复率高出了约28%。第二轮在个性化话术的基础上,增加"触达时长竞速"优化——从事件发生到首次触达的平均时长从最初的43分钟缩短到9分钟,客户满意度明显提升。这个数据也印证了开头那句话:内容质量很重要,但触达速度同样重要。
5. 项目沉淀与后续扩展方向
5.1 扩展成通用的Agent触达基座
Agent-Reach这套设计,现在已经被我复用到了好几个不同的业务场景里。除了售后工单跟进,还跑了客户流失召回、活动通知触达、会员生日关怀、工单超时预警等,基本上换一套模板和策略配置就能上线。从中我提炼出的经验是:触达基座的核心在于抽象能力,把"触达"这个动作从具体业务中抽离出来,做成可以独立演进的基础设施。
如果你也想做类似的事情,我建议第一步先梳理清楚三类抽象:渠道抽象、触达动作抽象(发送、召回、静默、升级)、反馈抽象(已读、回复、转化、投诉)。这三类抽象稳定下来后,新增业务场景就变成纯粹的配置工作,而不是重新开发。
5.2 多Agent协同与高级编排
当前版本的决策层还比较"单兵作战",后续我在规划多Agent协同的编排能力。比如,运营Agent负责生成触达策略,合规Agent负责审核内容合规性,数据分析Agent负责预测最佳触达时间。三个Agent各自独立推理,再通过一个决策仲裁模块综合结果。这种编排方式比单Agent更稳,算是一种务实的可靠性提升手段。
我也在尝试把Agent-Reach接入到更多下游系统,比如内部CRM的工单系统、优惠券系统,让触达不只是发一条消息,而是能完成更复杂的业务动作——发消息的同时自动为用户发放补偿券,并在用户回复特定关键词后自动触发退款流程。触达的未来形态,一定是"消息+动作+反馈"三位一体的闭环。
基于这段项目经验,我最后分享一个体会:Agent-Reach这类触达项目,最忌讳一上来就追求全自动化。稳妥的路径是先让人在环里,让Agent生成触达内容之后,先经过人工确认再发送,跑上两到三周,积累足够多的样本数据后,再逐步把人工确认开放成"抽检模式",最后才放开全自动。这个节奏看起来慢,其实是最快的路径,因为每一次人工介入都等于给Agent做了一次免费的对齐训练,模型会越来越懂业务的边界在哪里。