
先从我最近踩的一个大坑说起。上个月我在做内部客服工单Agent调了一个多月的提示词模型终于能把客诉意图识别得七七八八——用户说“我要退款”它知道去查订单、知道该发什么通知。但真到接业务系统的时候问题全冒出来了查订单的接口字段老变历史工单的数据库读超时退款操作没人敢让它自动执行。模型再聪明“手”伸不出去一切都是白搭。后来我把模型、决策、执行这三件事彻底拆开专门做了一层触达服务项目才算是真正跑起来了。这套设计的名字就叫Agent-Reach。如果你也在做AI Agent落地大概率会遇到同一个瓶颈对话能力不是瓶颈触达能力才是。这篇内容就围绕Agent-Reach这套触达层方案展开——它是什么、内部有哪些核心组件、协议怎么定、落地时最容易在哪些位置塌方以及从0到1应该分几步走。不管你是正在做智能客服、办公自动化还是想把大模型接进内部系统这套设计思路都能直接参考。1. Agent-Reach到底解决什么问题模型在对话里全能在系统里失能1.1 三个典型的“手伸不出去”场景先说我在多个项目里反复撞见的几类问题你可以对照一下自己是不是也在经历。第一类是“消息收不到”。业务系统的上游接口变了字段从userId改成了user_idAgent那边还在按老格式传参数结果全链路报错。更麻烦的是这种变更通常没有通知——你是从日志里某个突然变多的400错误才发现接口挂了。模型不会主动去探测外部世界它只知道你告诉它的那些东西。第二类是“动作做不到”。意图识别很准也知道该调用哪个工具但工具参数怎么填、鉴权怎么过、幂等怎么控这套工程细节根本不在模型的认知范围内。你可能会在提示词里塞一大段“调用规范”结果模型照样会在不该重试的时候疯狂重试把下游数据库打挂。第三类是“边界兜不住”。高风险操作没人敢放权。让模型直接删一条生产数据、直接审批一笔退款谁心里都没底。但如果每一步都靠人肉介入这个Agent又谈不上“智能”。问题的本质是从“模型输出一段文本”到“系统执行一个动作”中间缺了一层可控、可观测、可治理的翻译与调度机制。1.2 Agent-Reach的定位在模型和业务系统之间加一层触达服务Agent-Reach的做法不是去优化模型也不是去推动业务系统改造而是在两者之间插入独立的触达层。你可以把它理解成一个“万能插座适配器”——模型的输出是标准化的意图业务系统提供的是千奇百怪的接口Agent-Reach负责把这两头接起来顺便把所有工程问题鉴权、超时、重试、审计、审批都收编到这一层里。这层设计最核心的价值是把“决策”和“执行”彻底解耦。Agent只负责决定“做什么”触达层负责解决“怎么做”。这样带来的好处是模型层可以随便升级换代今天用GPT明天换国产模型触达层完全不受影响业务系统的接口变了也只需要更新能力注册信息不用去改Agent的提示词和代码。我在实际项目里感受最深的就是这一点——以前每接一个新系统Agent代码就要膨胀一轮有了触达层之后新增一个系统的成本从“改代码”降到了“注册一个能力”。2. 触达层的核心组件五个部分怎么配各自管什么2.1 能力注册中心让Agent知道“自己周围有什么”能力注册中心是整个触达层的地基。所有可被Agent触达的业务能力——无论是查数据库、调第三方API还是执行某个内部操作——都按照统一的Schema注册进来。Agent在收到用户请求后第一步就是向注册中心要一份“当前可用的能力清单”就像手机系统弹出权限请求一样让模型知道这个环境里有哪些工具可以调用。这个设计的精髓在于“动态发现”。传统做法是提前写死在提示词里比如“你可以使用以下几个工具查订单、查物流、发优惠券”。问题是这个清单一旦超过十五六项模型的注意力就会开始涣散甚至会出现“明明有这个工具但它非要自己编一个答案”的情况。而通过注册中心动态下发你可以按会话上下文、按用户权限来裁剪能力清单——普通用户会话里只暴露查询类能力管理员会话里才暴露写操作类能力。我从实践里的体会是能力清单不在于“越多越好”而在于“合适的场景给合适的工具”这一步做对了后面的意图路由准确率会明显上升。2.2 意图路由模块从“自然语言”到“结构化参数”的两层翻译意图路由不是简单地把“查订单”映射到一个API接口它要做两层翻译。第一层是语义意图识别。模型判断用户这句话背后是什么目标比如“我想看看昨天华东区的销售额”这个意图被归类为sales_report_query。第二层是参数提取与补全。同一个意图参数可能是残缺的——用户只说了“华东区”没说是哪天。这时候触达层要么从会话上下文里补要么主动向用户追问要么填一个默认值。这里的关键约束是所有参数必须严格遵循JSON Schema类型、必填项、取值范围都定义得清清楚楚。我见过很多项目在意图识别上做得挺好结果死在参数这一步——模型把“2024年3月”提取成了2024-03还是2024/03下游接口直接不认账。参数标准化这件事必须在触达层用Schema硬约束不能指望模型自觉。2.3 动作协议定义触达层与外部世界沟通的“共同语言”触达层要对接Agent也要对接业务系统两边语言不通怎么办就需要一套统一的动作协议。我给这套协议起名叫ActionSpec它规定了每一个可触达动作的元信息。你可以把它类比成USB接口协议——不同设备外形千差万别但插上USB口就能通信靠的就是统一的标准。协议的具体字段设计我放在下一章讲这里先记住一个原则协议字段宁缺毋滥每多一个字段模型的理解成本、系统对接成本都会上升。2.4 执行引擎用状态机驱动而不是用流程硬编码执行引擎是真正去调用业务系统的那部分。它内部维护着一个动作状态机每个动作从创建到结束会经历几个确定的状态待处理、审批中、执行中、成功、失败、已取消。为什么非要用状态机而不是写死“调接口→等结果→返回”这种顺序流程因为ActionSpec里定义了“异步回调”“人工审批”“自动重试”这些机制一个动作的命运大概率不是一路畅通的。比如一个退款动作创建之后可能因为风险等级高被挂起等审批审批通过后才进入执行中网络异常后又进入失败状态触发重试或补偿。如果把这些状态分支全写在流程代码里每增加一个策略就要改一遍流程迟早变成一坨没人敢动的意大利面。状态机的核心价值在于让动作的全生命周期可追踪、可干预——你随时可以查某个动作卡在哪个环节也可以从外部推它一把。2.5 触达策略引擎把“能不能做、要不要批”从代码里拎出来最后是策略引擎它管的是权限、配额、审批、限流这些治理规则。我的建议是凡是涉及“能不能执行”“以什么身份执行”“要不要人工审批”“一分钟最多执行几次”的规则全部收进策略引擎用配置化管理绝不散落在各处代码里。举个例子我可以给某个动作配置三条策略一是仅允许在工作时间9:00-22:00执行二是单用户每分钟最多触发10次三是风险等级为high的动作必须流入人工审批通道。这套规则改起来特别快不需要动代码重新发布——而这种灵活性在Agent跑起来之后非常重要。因为你会发现线上真实流量和你在预演阶段猜的完全不是一回事策略大概率是要反复调的。3. ActionSpec动作协议长什么样最小但完整的字段集合3.1 十个核心字段的设计与理由协议设计这件事最怕的是“什么都想加”。我第一版ActionSpec写了二十多个字段结果对接业务系统时人家一头雾水模型理解起来也费劲。后来砍到十个反而刚好够用。这里我逐个说一下为什么保留这些字段字段用途设计理由action_id全局唯一动作标识审计日志、链路追踪全靠它name动作名称简短方便模型在候选列表里快速定位description自然语言描述给模型做意图匹配用的必须说“人话”version能力版本号业务接口变更时递增避免老Agent调用新接口parametersJSON Schema参数定义约束模型输出防止参数格式跑偏auth_scope需要的授权身份域区分是用户级授权还是服务级授权risk_level风险等级low/medium/high决定是否走审批、是否限流idempotent是否幂等直接决定重试策略这个后面专门展开timeout_ms超时时间短查询和长任务不能一刀切callback_url异步回调地址耗时操作不能干等同步返回这里我想多说一句description字段的写法。它直接决定了模型能不能把这个工具“选对”。我见过有人把description写成一整段需求文档模型看了半天反而困惑。好的description应该是一句话讲清楚“这个工具是干什么的、什么场景下用它、有什么特别注意”。比如查询订单状态的正确写法是“查询用户订单当前的状态当用户询问订单进度、物流信息时使用。入参order_id必须是字符串类型。” 控制在200字以内效果最好。3.2 一个完整注册示例从库存查询到参数约束下面是注册一个“库存查询”能力的实际样例我建议你直接照着这个格式去设计自己的能力注册表{ schema_version: 1.0, action_id: inv_001, name: stock_query, description: 查询指定SKU的实时库存数量当用户问某个商品有没有货、剩余多少件时使用。仓库维度可选不传则查全部仓库。, version: 1.2, parameters: { type: object, properties: { sku_id: { type: string, description: 商品SKU编码, required: true }, warehouse_id: { type: string, description: 仓库编码可选, required: false } } }, auth_scope: user_session, risk_level: low, idempotent: true, timeout_ms: 3000, callback_url: null }字段写清楚之后Agent侧的提示词里就不再需要重复描述这个工具的细节了只要给它一个动作名和一句简短说明让它知道“有这个东西可以用”就行。真正的细节全部由触达层在执行时补齐。这样做的好处是每次更新业务参数规则只需要改注册表不需要重新调一轮提示词。3.3 鉴权模型Agent到底“以谁的身份”在干活这是个特别容易被忽略但又特别要命的问题。当一个Agent调用查询接口时它用的是系统服务账号还是当前用户的身份如果用的是服务账号那就意味着任何一个普通用户只要能让Agent说出“查一下张三的订单”就能借助Agent的系统身份绕过权限检查。这就是典型的权限黑洞。Agent-Reach里的做法是引入“会话级代理身份”。用户在会话中完成了身份认证触达层会为该会话生成一个受控的临时凭证agent的每次下游调用都绑定这个会话ID和临时凭证。这样做有两个直接好处一是审计日志能准确记录“是哪个用户通过哪个会话触发了哪个动作”出了问题能追到人二是凭证可以随时吊销——一旦发现某个会话有异常行为终止凭证就行不需要去轮换系统级的密钥。这个设计我强烈建议你不要省它会在你上生产之后帮你挡掉非常多麻烦。4. 从“单动作”到“多步骤配合”触达编排链路的设计经验4.1 顺序执行与条件分支让Agent具备处理复杂任务的能力单个动作只能解决“查一下”“发一下”这种原子需求实际业务里的任务大多是复合的。比如一个“帮我处理退款”的需求链路可能是查订单确认金额→ 调退款接口 → 发通知。这就涉及触达层的编排能力。我用的不是那种复杂的可视化流程编排工具而是在触达层里定义了一套轻量级编排语法核心思路是“串行为主、条件分支为辅”。串行执行很好理解前一个动作的输出作为后一个动作的输入比如查订单返回的order_id自动填进退款请求的参数里。条件分支则靠“如果/否则”的规则来驱动例如如果退款金额超过2000元先走人工审批节点否则直接提交退款。这套逻辑放在触达层而不是让模型在对话里自己安排是为了保证关键路径的确定性。毕竟模型的规划能力就算再强也不可能每次都100%稳定地按业务规则走。4.2 任务上下文跨步骤变量不能被对话干扰编排链路让我在产品上线前最头疼的问题是“跨步骤的变量怎么保存”。举个例子用户一开始报了订单号Agent先查了订单详情拿到商品ID、金额、店铺ID。然后用户中间又问了一句“这个店还有别的款式吗”Agent去查了商品列表。这时候如果它忘了之前拿到的金额后面就没法继续退款流程了。一开始我试图让模型从对话历史里自己找这些关键信息实测下来相当不稳——对话一长模型就开始“丢三落四”。后来我在触达层里加了独立的“任务上下文”存储每个会话维护一个结构化KV存储专门放跨步骤需要复用的变量。比如查单动作返回的order_id、amount自动落进任务上下文后续动作需要参数时优先从任务上下文里取取不到才去问模型。这一步改动之后长链路任务的失败率下降非常明显。“让执行依赖显式的上下文存储而不是依赖模型的注意力”这是我趟了无数坑之后总结出来的一句话。4.3 人工审批插入与重试补偿留给自己的“保险丝”有些动作风险高到不能完全甩给模型。触达层在设计上预留了一个人工审批节点当策略引擎判定某个动作的risk_level为high时动作会进入等待状态把审批请求推给预设的负责人。负责人批准后执行引擎自动恢复流转驳回则直接终止链路并向用户返回“该操作未获授权”的明确信息。这一步的意义不只是“安全”它还能给你争取一个缓冲期——在Agent刚上线、大家对它的可靠性还没有信心的阶段有一个“人在回路”的节点兜底团队才会愿意放量。重试和补偿我单独提一下因为这两个位置很容易被忽视。Agent在调用外部系统时网络抖动、服务重启都是常态。我的经验是对幂等动作可以自动重试但一定要有次数上限和退避策略比如最多重试3次间隔按1秒、2秒、4秒递增对非幂等动作绝对不能无脑重试否则一次超时就可能造成重复扣款、重复开单。补偿动作是另一个设计点——比如某条链路先扣了库存、后面付款失败那就要有一个反向动作把库存加回来。这块建议在编排层预留“逆向操作”的声明别等出了线上事故再临时写修复脚本。5. 落地时最容易塌方的五个位置我踩过的坑和修复办法5.1 工具描述“太肥”模型反而选择困难先说一个反直觉的现象你以为能力描述写得越详细越好实际上把description写成2000字的小作文模型反而会非常困惑——它在有限的注意力窗口里面对大段文本很难快速分辨出“这个工具到底是干什么的”。我做过一个对照实验同一批意图分类任务把描述压缩到200字以内之后路由准确率从87%提升到了93%以上。原因也很简单模型的语义匹配能力更吃“精准的关键词信号”而不是长篇大论。所以这个坑的修复方法是每个动作的描述必须包含高频场景词、主要入参、以及行为边界控制在150-200字。5.2 嵌套调用时token爆掉上下文污染是隐形杀手多步骤任务里最常见的失败原因不是某个API挂了而是模型“忘记了自己在干什么”。当你把一个动作的完整响应体——可能是一大段JSON——直接塞回模型上下文再叠加后续要调用的工具说明很快令牌数就会逼近上限。而且响应里真正对下一步决策有用的可能只有一两个字段其余全是噪声。我的修复方法是在触达层做“响应裁剪”模型只能看到下一步真正需要的字段比如查单动作只返回order_id和amount什么创建时间、物流公司、商品图片全部留在触达层内部存着不往模型那送。这个做法除了省token更重要的是减少了干扰模型反而更不容易跑偏。5.3 并发乱序多个会话同时操作同一个“资源”Agent上线之后大概率会迎来多用户同时使用这时候就要小心了。如果两个用户几乎同一时刻让Agent去改同一个订单的状态先改后改的顺序不同结果可能完全不同。这个问题不是模型能感知到的必须由触达层去管。我的解决思路是引入乐观锁版本控制每个可写资源在任务上下文里带一个version字段执行动作前校验版本号版本不匹配就直接拒绝并提示“该数据已被其他操作修改请刷新后重试”。另外一个做法是对同一实体的写操作做互斥排队——触达层内部维护一把按实体ID分片的锁同一时间只允许一个写动作在跑。这两个机制谈不上高深但确实能拦下大量脏写问题。Agent项目里并发问题出现得比传统业务系统更隐蔽因为你看不到“谁在操作什么资源”——全被对话包装了一层。5.4 权限黑洞Agent拿着系统级密钥到处跑这是我在这篇文章里第三次提到权限问题了因为它在实操中真的非常普遍而且出事就是大事。很多团队的Agent要接内部系统就直接把系统管理员的API Key配在环境变量里所有Agnet调用都带着这个“超级身份”。一旦Agent被用户诱导去调那些不该调的接口轻则数据泄露重则误删数据。修复路径分三步第一步把全局Key废弃换成按应用区分的服务身份第二步引入会话级代理身份让每个调用都能追溯到具体的用户请求第三步在策略引擎里做“能力白名单”明确每个服务身份能触达的动作范围。这套做下来权限横切面的风险基本可控了。5.5 观测性缺失没有trace_id线上故障等于大海捞针最后这个坑是你在研发阶段感觉不到、一上生产就会被暴击的可观测性。Agent的调用链比传统系统长得多——一段用户对话可能触发模型判断、路由匹配、策略检查、动作执行、下游接口调用好几个环节中间任何一环出问题都可能导致最终结果异常。如果没有一套串起全链路的日志出问题之后你只能一个日志文件一个日志文件翻效率极低。我的做法是在触达层的入口统一生成一个trace_id整个会话生命周期内的所有动作、所有下游调用、所有日志都挂上这个ID。配合链路追踪系统你就能看到这个用户的问题是到了模型那一步就错了还是路由选错了工具还是下游接口返回了5xx。这一步投入不大但对排障效率的提升是数量级的。Agent项目能不能稳定运营可观测性可以说是一半的底气和话语权。6. 从0到1的实操路线别急着全自动化先站稳再走快6.1 第一阶段只读触达让Agent先“看得见”任何Agent项目都建议从只读能力开始。把查询类接口先接入触达层——查订单、查库存、查客户信息让Agent先具备“看懂业务数据”的能力。这个阶段风险很小即使模型选错了查询工具最坏的结果也只是拿错了数据不会造成资损。但它能帮你验证最核心的三件事能力注册Schema是否够用、意图路由的准确率是否达标、以及模型和触达层的协作是否顺畅。这个阶段的准确率数据就是你决定是否继续往下走的依据。6.2 第二阶段写操作人工审批让Agent“能干活但有人看着”跑通只读链路之后再加上中等风险的写操作比如提交工单、发送通知、批量修改数据这些。注意这几个操作必须都接上人工审批节点——不是全自动而是Agent生成动作建议由操作者在后台点击确认后执行。这个阶段你要重点观察的指标是“审批通过率”——如果通过率低于90%说明Agent的决策质量还不过关别急着放开如果通过率稳定在95%以上团队对Agent的信任度也建立起来了就可以考虑下一步。6.3 第三階段自动化灰度放量搭好审计与告警再放手最后才是放开自动执行但同样别一下子全量。我建议的做法是按用户维度灰度先放5%的低风险用户流量观察一段时间再逐步扩大比例。同时所有的自动执行动作必须实时写入审计日志并配置好异常告警——比如“单位时间内失败率超过10%”“某个动作被执行超过100次”这类规则一触发就通知值班的人。这个阶段的核心思想是自动化可以做但你不应该把“没有人看”当成目标。人不在执行链路里但人必须在监控室的屏幕前。写在最后Agent-Reach这套触达层我从第一版原型到现在大概重构了三轮。第一轮只做了工具注册和调用第二轮加了策略引擎和审批流第三轮把任务上下文和全链路观测彻底补齐。每一轮重构的驱动力都来自线上真实问题——不是我预先想得多周全而是问题逼着我把某个环节补强。如果你现在也卡在“模型很聪明但使唤不动”的阶段我的建议是不要急着堆模型能力先在触达层下功夫。让Agent的每一次动作都可控、可追踪、可回滚这种工程上的扎实感比任何花哨的模型调优都更能支撑你往前走。最后分享一个小经验在触达层设计里永远给“人工介入”留一扇门——它可能不会每次都用上但一旦线上出了你没想到的情况你会发现这扇门可以救你的命。