
最近半年我一直在折腾 Agent-Reach简单说它就是一套管 Agent 的连接层。起因是我所在的项目组从单体 LLM 调用切到多 Agent 协作之后混乱一下子涌进来了模型时不时上下文爆炸、若干个 Agent 抢同一个工具的执行权、重试逻辑把同一笔订单重复提交了几次最后连问题出在业务代码还是模型判断上都说不清。我们当时缺的不是更好的提示词缺的是一个能在所有 Agent 前面统一做触达、路由、配额和兜底的中间层。这个层在社区里有人叫 Agent Gateway有人叫 Agent 编排器而我们的内部代号就是 Agent-Reach。这篇文章我尽量把 Agent-Reach 的架构思路、路由设计、容量控制、记忆与缓存机制以及我在实际落地过程中踩过的坑一条一条说明白。适合正在做 Agent 基础设施选型、或者已经把手上的多个 Agent 插件跑起来但总觉得缺了一层东西的朋友看。核心结论先放这儿Agent 的数量一旦超过三个真正的瓶颈不是单个模型有多聪明而是工程上能不能把每个 Agent 的触达范围、调用顺序和失败代价管住。1. 为什么需要 Agent-Reach单模型调用到多 Agent 编排的失控时刻1.1 触达瓶颈业务侧不关心模型只关心能得到结果从业务方的视角看LLM 再强也只是一个判断引擎。业务系统真正关心的是给定输入你能不能稳定地给出一个符合格式的结果。过去我们直接调 GPT 或者 Claude 的 API写提示词、解析 JSON、处理超时日子还算能过。但当 Agent 数量上来之后问题就变了每个 Agent 有自己擅长的领域有自己的工具集有自己的提示上下文调用它们不再是一个接口的事而是一组服务的编排。这时候如果没有一个统一的入口业务代码会被 Agent 的细节淹没。试想一下你的下单流程里既要判断用户意图又要查库存又要算价格还要做风控校验。如果不收口每一处业务逻辑都需要拼接不同的模型参数、不同的工具地址、不同的错误返回格式。Agent-Reach 的价值恰恰在于业务方只需要知道发给一个网关网关负责把请求触达给正确的 Agent完全不用关心背后是哪个模型、哪套工具链、哪个 Agent 在工作。1.2 调度是 Agent 的命脉Continue 与 Break 的决策点很多人理解 Agent 调度以为只是按关键词路由到一个 Agent——这其实是把 Agent 当成了普通 API 网关。真实的 Agent 调度要复杂得多因为一个请求进来不是命中一个 Agent 就结束了而是 Agent 在执行过程中会不断产生继续还是停止的决策点。举个例子一个客服维修 Agent 在处理用户问题时它可能需要先判断用户描述是否完整不完整就要多轮追问完整之后可能要调用诊断工具来定位故障类型诊断结果可能又把控制权交回给对话 Agent 去生成回复。这个链条里每一步都存在跃迁的可能对话 Agent 跳到诊断 Agent诊断 Agent 又触发配件查询 Agent。这种 Agent 间的路由跃迁如果全部靠提示词里的你现在可以调用另一个 Agent来实现几乎一定是失控的因为你没法统一管理跃迁的代价和权限。Agent-Reach 在这套逻辑里的作用是把每个 Agent 的跃迁决策从提示词里的软性暗示改造成网关里的硬性判定。Agent 不再直接看到其他 Agent 的存在而是向网关请求一次触达由网关决定这次触达是否被允许、被路由到哪个实例、消耗多少配额。这也是我们把项目名字里带上 Reach 的原因——它管理的是每个 Agent 的触达边界。1.3 Agent-Reach 的定位连接、配额与兜底我给 Agent-Reach 定的核心职责概括下来是三个词连接、配额、兜底。连接统一所有 Agent 的入站与出站协议业务方只对接一个网关Agent 之间不互相直连。配额给每个 Agent、每个租户、每种工具分配调用额度防止某个 Agent 的热点请求把整体资源池打满。兜底当路由匹配失败、Agent 超时、工具调用出错时网关负责降级或者返回可解释的错误而不是让脆弱的调用链暴露到业务层。实际开发时我们用了 Python 的 FastAPI 做网关主体原因很简单生态成熟连 OpenAI SDK、向量数据库、消息队列都很顺异步支持也足够好Agent 调度这种 IO 密集型场景非常吃异步。不过选型这件事我在后面会展开讲这里先不跑偏。2. Agent-Reach 的路由核心意图识别与后置校验的分层设计2.1 路由层不执行任务只做触达Agent-Reach 的第一层是路由层。这一层做的不是解析用户意图的全部语义而是做一个粗分类 参数抽取的最小集。我们用了一个小模型做分类通常是一个 7B 到 14B 的开源模型部署成本低速度快。它会输出两个东西一个是目标 Agent 的 ID一个是期望的调用类型是查询、是执行还是对话。这个设计是有意为之的。很多团队会非常自然地想既然要路由干脆让最强的模型来做意图识别准确率高。但实际跑下来路由请求的并发量是模型业务请求的 5 到 10 倍以上。意图识别一旦成为热点资源瓶颈后续所有 Agent 都会跟着排队。用一个小模型先做粗分类把高并发的触达决定挡在前面再用具体 Agent 内部的精模型去做复杂业务理解这样成本曲线就健康很多。路由结果的可靠性问题我们后来专门做了处理——路由层只是触达的入口建议不是最终决策。真正的校验发生在后置层。2.2 后置校验层约束输出与自省路由层给出目标 Agent 之后请求进入 Agent-Reach 的后置校验层。这一层的作用是确保 Agent 的输出真的符合约定而不是看起来合理但没法用。我们给每个 Agent 注册了输出 SchemaJSON Schema后置校验层会做两件事格式校验和语义校验。格式校验是硬性的比如字段缺失、类型不对、枚举值超出范围直接拦截语义校验则相对软性比如要求 Agent 在回复中附带置信度分数当分数低于阈值时网关不直接返回结果而是触发一次自省重写——把之前的结果和当前上下文一起送回给 Agent要求它重新组织一次回答。这个过程中最容易被忽略的是重写不能无限循环。我们给每次自省设了最大重试次数默认 2 次超过就返回一个置信度不足的明确错误。宁可让业务方明确知道这次判断不可靠也不要让网关无限次消耗资源然后把一个实际上不可用的结果返回出去。2.3 代价模型工具箱触达的 ROI 排序路由还有一个细节让 Agent-Reach 的价值变得非常实——对工具触达的代价排序。几乎所有多 Agent 系统背后都有一堆工具查天气、查库存、调支付、发短息、跑算法模型。不同工具的调用代价天差地别查一次天气可能只有几毫秒而调一次复杂风控模型可能要几秒钟的 GPU 时间。如果把所有工具都交给 Agent 随意挑选最省事的执行路径往往是最贵的那个。Agent-Reach 在工具触达上做了一个便宜的代价模型每个工具注册三样属性单次调用成本分钟级求平均、失败率、平均响应时间。当 Agent 请求帮我实现某个目标时网关会优先提供代价最小的工具组合路径而不是把全部工具都塞进提示词。这个机制的收益你跑一个月就能直观感受到月末账单下降至少在 20% 到 30%而且响应延迟也稳定很多。工具类型单次成本级别失败率平均响应路由优先级内存查询0.001 元级0.1%5ms最高数据库查询0.01 元级0.5%80ms高第三方 API0.1 元级3%600ms中大模型推理1 元级8%2s低代价模型帮我解决了一个很实际的打架场景同样是查用户订单状态一个 Agent 选择直接从数据库读另一个 Agent 非要先请求 LLM 理解一遍订单上下文再去查。显然后者更智能但也更贵、更慢。有了代价排序智能被约束在了必要的场景里。3. 容量与超时如何防止一个 Agent 吃光整个平台的预算3.1 配额粒度设计Agent-Reach 的核心任务之一是容量管理。我们早期只对模型 API 的 Token 数做了配额结果发现根本不够用。因为在实际运行中真正的资源瓶颈不只是 Token还有工具调用次数、内存向量检索量、外部 API 的免费额度。如果一个 Agent 疯狂调用第三方搜索 API即便 Token 消耗很少账单照样会失控。所以我把配额拆成了四类维度Token 配额区分输入和输出输出配额更紧。工具调用配额每个 Agent 每分钟最多调用多少工具。会话并发配额同一个 Session 下最多同时允许多少个 Agent 在跑。租户总配额所有 Agent 共享的硬上限。配额粒度很重要的一点是要区分往返配额和费率配额。前者说的是总量封顶后者说的是速率限制。两个都不设系统一定会被小概率的突发流量击穿。我们用的是令牌桶算法做速率控制每个 Agent 桶容量 200每秒补充 50这样短促的突发脉冲可以扛住长期超过则会稳定限流。3.2 快速失败与慢速热点另一个容量管理心得是尽量让失败来得快一点。很多人把超时时间设置得很宽松以为能提高成功率结果反而把整个系统的吞吐拖垮了。原因在于并发资源是有限的一个占用 30 秒的慢请求在等待期间吃掉了连接池、线程和内存等它最终失败或者成功时后面排队的请求已经不耐烦超时了。我在 Agent-Reach 里设了分层超时路由层超时500ms过了就视为不可路由。单 Agent 执行超时默认 15s业务方可以按 Agent 注册时覆写。工具调用超时默认 3s工具跑不完就放弃。总链路超时默认 30s包含所有跃迁、自省、后置校验的开销。这套数字不是拍脑袋定的。我们压测的时候发现绝大多数正常请求的链路总耗时集中在 4 到 8 秒之间15 秒的 Agent 超时给模型留下了足够的思考和工具调用时间又不至于拖垮集群。如果某个 Agent 频繁触发超时那就说明它本身有问题需要从提示词或者工具逻辑上优化而不是试图靠无限延长超时来掩盖。3.3 熔断与降级宁可无响应不可错响应记住一句我吃了很多亏才总结出来的话Agent 系统的崩溃不是线性的而是雪崩式的。当一个 Agent 因为依赖的第三方 API 变慢而积压时所有后续请求会同时等在这个薄弱点上。而 Agent 之间又存在调用链关系一个上游 Agent 慢下游 Agent 会连续重试重试又进一步放大压力。如果没有熔断机制整个平台会在几分钟之内被一个上游故障拖垮。Agent-Reach 的熔断逻辑我参考了经典的 Hystrix 思路但针对 Agent 场景做了简化。每个下游依赖工具、子 Agent维护一个滑动窗口统计最近 20 秒内的失败率。失败率超过 50%就进入熔断状态接下来的请求直接快速失败不再真实触达下游。熔断状态持续 10 秒后尝试放一个探测请求成功则逐步恢复失败则继续保持熔断。这个机制最值得称道的是它把错误响应隔离在了可控范围内。当熔断发生时Agent-Reach 返回的是一个标准的 AgentUnavailable 错误而不是一个由模型生成的、看似合理但实际没有经过工具校验的幻觉结果。业务方拿到错误可以优雅降级比如提示用户稍后重试但绝不会把错的结果当成真的接受下来。对 B 端系统来说**宁可无响应不可错响应**是一条必须刻在架构里的底线。4. 记忆与缓存让 Agent-Reach 具备触达历史的能力4.1 上下文压缩与摘要回填多 Agent 场景下的记忆比单轮对话复杂得多。单个 Agent 的记忆可以简单依赖模型的上下文窗口但多 Agent 协作时每个 Agent 看到的上下文只是全局上下文的一个切片缺失部分需要由网关补全。Agent-Reach 在记忆层面做的事是把对话历史切分成两层即时消息层和长期记忆层。即时消息层保留最近 20 条原始消息直接进上下文。长期记忆层则维护一个摘要库每过一定轮次比如 10 轮就对历史进行摘要并把摘要回填到下一次请求的上下文里。这个做法大家可能觉得稀松平常真正难的是摘要的粒度控制。摘要不能只提炼业务结论还要保留关键约束信息比如用户明确表示过我不想要推荐、这个订单不要拆分这类否定性指令。一旦摘要丢失这些约束Agent 的后续行为会变得非常毛糙。我自己的做法是要求摘要模型遵循一个固定模板用户身份的确认、明确的业务目标、以及所有否定/禁区信息。模板化的摘要缺点是稍微占 Token但换来的是约束的稳定传递这笔账很划算。4.2 缓存准入什么时候缓存不可用Agent-Reach 引入了缓存但缓存的适用范围比想象中小得多。原因很简单Agent 的输出严重依赖上下文上下文中任何一点变化时间、地点、用户语气都可能导致结果完全不同。缓存一个今天天气怎么样的问题很容易但缓存帮我推荐一条适合下雨天跑步的路线就非常危险因为用户的历史偏好、当前路况、时间因素都会影响答案。我的缓存准入策略是只有同一用户 同一 Agent 完全相同的请求参数时才允许命中缓存。不做语义相似度的模糊匹配缓存。语义相似匹配会带来一个隐蔽的问题——两个提问看似类似实际包含的约束细节不同一旦误命中缓存返回的是上一个问题的结果业务上就是一次真实的事故。缓存的生命周期也要严格控制。我把缓存头默认设置为 30 秒短生命周期把副作用控制在最低。实测下来缓存命中率虽然只有 10% 到 15%但恰好命中在最高频的查询类问题上整体延迟和上游 API 消耗都改善明显。4.3 记忆一致性短时记忆与长期记忆的分区记忆一致性是 Agent-Reach 后期迭代中我花时间最多的地方。一开始我们把记忆全部放在同一个 Redis 键里结果出现了严重的串味问题Agent A 把一段临时的中间推理状态写进了长期记忆污染了 Agent B 之后的判断。后来我们强制把记忆分成了三个区Scratchpad草稿区Agent 单次执行期间的临时推理过程生命周期 15 分钟用完即焚。SessionMemory会话区当前会话的上下文事实生命周期是会话时长比如 2 小时。ProfileMemory画像区跨会话的长期用户事实只有在 Agent 明确表达出用户长期偏好时才写入。三个区的写入权限是分离的。Agent 默认只能读写 Scratchpad 和 SessionMemoryProfileMemory 的写入必须通过网关的专门 API。这样一个 Agent 即使跑偏了也不会轻易把错误的用户画像写进长期记忆损坏面被约束在了短时范围内。5. 实战踩坑记录从 Demo 到稳定运行的三个教训5.1 坑一路由条件重叠导致 Agent 循环调用上线第一周就遇到一个让我挠头的问题系统的请求量毫无征兆地翻了好几倍但业务量并没有涨。排查链路之后发现是两个 Agent 之间发生了循环路由。客服 Agent 在判断用户是否需要人工服务时把请求路由到了人工值班 Agent而人工值班 Agent 在发现没有空闲人工时又调用客服 Agent 协助回复。两个 Agent 互相把请求抛给对方加上重试机制链路彻底打结。根因是路由层两个 Agent 的条件重叠了客服 Agent 的意图分类涵盖用户情绪不稳定人工值班 Agent 也涵盖了这个场景导致一批请求在两者之间无限徘徊。我给的修复方案有两层。第一层是在路由条件设计上做排他性约定给每个 Agent 声明明确的路由白名单意图和路由黑名单意图重叠部分必须在注册时解决。第二层是网关级的循环检测——Agent-Reach 为每次请求维护一条调用链路径当同一个 Agent ID 在链路中出现两次时立即终止路由返回一个 RoutingLoop 错误。这个错误宁可让用户感知到也不能让系统默默空转。5.2 坑二重试机制导致重复触达重试是个经典的工程陷阱。我们的一个支付 Agent 在调用第三方支付接口时偶尔会超时于是在网关层加了自动重试。结果某个时刻第三方接口其实已经处理成功了只是响应延迟网关的重试请求又触发了一次扣费。用户被扣了两次钱投诉直接打到了负责人那里。这个问题在 Agent 场景里尤其危险因为 Agent 的工具调用天然就是拟人的它不像普通 API 调用那样有严格的幂等设计。修复分了两步短平快的一步把非幂等的工具调用类型明确标记为 NoRetry网关对这类工具不自动重试只返回超时错误让业务方决定如何人工处理。进阶的一步Agent-Reach 引入了一个工具调用意图指纹机制。每次工具触达时网关根据会话 ID、Agent ID、工具名称和输入参数生成一个哈希指纹。重试时先检查这个指纹在窗口期内是否已经出现过如果出现过网关返回上一次的执行结果而不是重复触达。指纹机制的语义其实相当于给每个工具调用上了幂等锥Idempotent Key只是名字换了一下效果一模一样。这个机制我强烈建议所有做 Agent 工具链的人尽早加上越晚补越疼。5.3 坑三缓存污染上下文还有一次比较隐蔽的事故是关于缓存和上下文的互相污染。我们的记忆区设计里有一个细节Agent-Reach 会把命中缓存的请求直接短路返回不再经过 Agent 执行。这看起来是好事但有一次因为缓存键设计漏掉了会话 ID导致用户 A 的问询结果被返回给了用户 B。那次的排查过程让我意识到Agent-Reach 的缓存不能只做字符串级别的键匹配必须在缓存键里绑定主体的边界——用户 ID、租户 ID、Agent ID、会话 ID一个都不能少。代码里我强制用一个结构化的缓存键对象而不是手工拼接字符串从源头杜绝漏字段。这是我给所有基础设施开发者的忠告凡是会跨用户共享状态的组件都要把隔离性放在性能之前。一个听起来很慢的隔离检查远比一次数据串味事故便宜得多。6. 向生产环境演进Agent-Reach 的扩展方向6.1 企业级能力权限、审计与租户隔离Agent-Reach 跑通之后我把它推到了生产的边缘这时才发现需要补齐的能力远不止路由和配额。第一个是权限。不是每个 Agent 都有资格调用所有工具。企业内部会有非常敏感的接口比如读取用户手机号、修改订单状态。这类工具必须在工具层做权限校验而不是等 Agent 去自觉遵守。Agent-Reach 里我加入了一个权限标签机制每个工具标记访问所需的最小角色每个 Session 标记它的授权范围工具触达时网关做一次校验未授权直接拒绝。第二个是审计。Agent 与普通代码最大的区别在于它具备自主性一次错误操作的影响可能来自于模型判断层面的偏差。这时候如果没有任何审计追溯问题将变成一团迷雾。Agent-Reach 对每一次路由决策、工具调用、重写行为和配额消耗都写了结构化日志保存 30 天。出事故时可以直接回放这个 Agent 当时看到了什么上下文、基于什么做了这个判断、网关为什么允许了这次触达全部有迹可循。第三个是租户隔离。SaaS 场景下不同客户的 Agent 跑在同一个集群里Agent-Reach 必须保证租户 A 的 Agent 不会访问到租户 B 的工具和数据。我把租户 ID 放进了每一个上下文的头部字段并在路由层、配额层、缓存层三层强制校验任何一层发现租户不一致直接中断链路。6.2 与现有系统融合事件驱动与人工兜底成熟的业务系统很少会完全围绕 Agent 重构App 还在数据库还在旧的微服务也还在。Agent-Reach 要做的是融入而不是替代。我用消息队列做了事件驱动的削峰——Agent 触达外部系统时不直接同步发起 HTTP 调用而是先把请求发到消息队列由业务侧的工作节点异步消费。异步化的好处是网关能容纳更大的吞吐波动但代价是响应链路变长了。所以对我这类对实时性要求不高的业务场景客服、运营、数据分析异步完全够用如果是对实时性极高的场景交易风控、实时推荐我会让 Agent-Reach 走同步调用的专用通道用更严格的配额来控制。人工兜底也是个必须做好的环节。Agent 不是百分百可靠我们的运营体系里保留了一条人工处理链路。Agent-Reach 在检测到 Agent 连续两次自省仍无法达到置信度阈值时会主动把工单转给人工作台同时附上 Agent 的完整推理过程和原始输入让人工介入有上下文可依。转人工不是一个羞耻的回退而是一种务实的设计。6.3 关于未来的一点判断最后说点我对 Agent 基础设施走向的判断。Agent-Reach 这类项目本质上就是 Agent 时代的操作系统内核随着上层 Agent 数量越来越多、边界越来越细连接层的价值会越来越大。而且我判断未来的 Agent 框架会越来越薄真正厚重的部分会沉淀在网关这类基础设施里——因为模型会持续升级但工程上的稳定性、可观测性和成本控制永远是 AI 应用落到生产环境时最稀缺的能力。如果你正在规划自己的 Agent 基础设施我的建议是别急着上最炫的多 Agent 协作框架先把触达的连接层做好把路由、配额、记忆、缓存和审计这五个基本功打扎实。这些事没有模型那么有噱头但它们决定了你的 Agent 系统能不能在真实业务里站得住。