
做过agent项目的同学应该都有同感一条看似普通的请求从用户在聊天框里敲下一句话到界面上吐出一个完整答案中间到底发生了什么外人根本看不出来。我最早听到“一次agent请求要经过12个服务”这个说法时觉得多少有点夸张直到自己接手了一个生产环境的多智能体系统排过几次跨服务的问题才真正理解这句话背后意味着什么。这篇文章我打算把这12个服务的分工、协作方式、超时预算和排障思路完整梳理一遍。如果你是做agent开发、微服务架构设计或者刚入门agent框架应该能从里面找到一份可以直接用的“服务链路地图”。我不会只罗列名词还会把每个服务出现的原因、去掉它会出什么问题、实战中常踩的坑一起讲清楚。1. 全景图一次请求到底经过了哪12个服务1.1 服务清单与一句话职责先把完整清单放在前面方便后面逐个展开。我按一次典型agent请求从入口到返回的顺序排列序号服务一句话职责1API网关统一入口、协议转换、SSL终结、全局traceId生成2认证鉴权服务身份确认、Token校验、权限范围判断3限流治理服务QPS限制、并发控制、熔断降级、配额管理4会话上下文服务多轮对话窗口维护、上下文压缩与持久化5任务规划服务把用户意图拆解成可执行的步骤序列6模型路由服务统一封装多模型接入、路由调度、故障切换7工具调用服务注册和执行外部工具校验参数并做权限检查8知识检索服务RAG召回、混合检索、引用溯源9记忆服务长期记忆读写、用户偏好存储、记忆压缩10业务集成服务对接内部订单/CRM/ERP等系统做字段映射与数据脱敏11异步任务服务处理长耗时任务、消息队列消费、任务状态管理12可观测审计服务链路追踪、日志聚合、指标采集、安全审计1.2 这些服务是按什么逻辑串联的很多人看到“12个服务”第一反应是有必要拆这么碎吗我当时也是这个反应。后来想明白一件事——agent请求和普通Web请求最大的区别在于它不止是“查数据”而是一个完整的“规划—调用—验证—生成”闭环。普通接口请求链路通常是“网关→业务服务→数据库”三五跳就结束了。agent请求不一样它要先确认身份再结合历史会话把一句含糊的话拆成明确步骤然后决定调用哪个模型、哪些工具、检索哪些知识最后可能还要触发一个异步任务整个过程还要全程记录审计日志。这12个服务其实就是把这个闭环拆成了四层接入与安全层负责“能不能进、是谁在进”会话与决策层负责“怎么理解、怎么规划”能力供给层负责“拿什么来回答、靠什么执行”执行与保障层负责“真正落地和事后追溯”。理解了这个分层就不会觉得这些服务是随意凑数的。2. 逐个拆解这12个服务分别在替你做什么2.1 接入与安全层API网关、认证鉴权、限流治理API网关API网关是第一个接收请求的服务它替你挡住所有与业务无关的脏活。Web端、App端、IM机器人、第三方开放API都会打到同一个入口网关做着最基础也最不能出错的几件事SSL证书卸载、HTTP/WebSocket/SSE协议的转接、Header清洗、IP黑白名单、跨域配置。为什么agent场景尤其依赖网关因为输出方式太复杂了。现在主流agent产品都要求流式输出前端要SSE或者WebSocket实时刷新用户体验才好。网关在这里的作用就是把内部服务的普通HTTP响应改造成符合前端要求的流式协议或者反过来把客户端的流式请求转发给内部服务。网关还有一个关键职责为每个进来的请求生成全局唯一的traceId。这个ID会通过Header透传到后面的所有服务是后面排查问题的基础。我有一次排一个“用户反馈回答很慢”的问题如果没有traceId光靠日志时间戳去对不同服务的日志几乎不可能定位到瓶颈。认证鉴权服务认证鉴权服务替你确认两件事你是谁你能干什么。传统Web场景下这套逻辑通常是登录后发个JWT每个接口校验一下就完事。但agent场景麻烦得多因为agent的特点就是“替用户执行操作”它可能要下单、要删数据、要发消息这些动作必须知道当前用户的权限边界。实际项目里我建议用带scope的授权token。比如用户授权agent“可以读取本月订单”但“不能执行退款”这些范围需要编码进token里。还有一类问题经常被忽略用户授权后agent正在执行一个长任务结果token在任务中途过期了任务立刻失败。这种坑我在生产里踩过不止一次解决思路是在长任务开始前做一次授权预检而不是等真正调用业务系统时才发现过期。如果涉及开放平台或自动化脚本防护认证环节还会接入人机校验服务确认发起请求的是真实用户而非自动程序这也能挡住很大一批恶意刷接口的行为。限流治理服务限流治理服务替你看住两样东西系统稳定性和钱袋子。模型调用和普通API不一样每次调用可能从几厘钱到几块钱不等而且大模型在高并发下容易产生长尾延迟一旦某个用户触发失控的逻辑循环不仅服务会抖账单也会非常难看。这里有个重点agent场景的限流不能只按QPS来还要按token消耗、工具调用次数、单用户并发数做多维配额。比如设置“单用户每分钟最多消耗50000 token”“单次任务最多调用20次工具”这种配额比单纯限制请求次数有效得多。熔断策略也要分级。模型网关超时了要熔断某个第三方工具接口大面积报错要熔断内部业务系统响应变慢也要熔断。而且熔断之后要快速失败给用户返回“当前服务繁忙请稍后再试”绝对不能无脑重试否则就是把一个故障放大成系统雪崩。2.2 会话与决策层会话上下文、任务规划、模型路由会话上下文服务很多人以为会话服务就是存聊天记录其实它更核心的工作是上下文工程。大模型的上下文窗口是有限的多轮对话加工具返回结果很容易就超了需要动态裁剪、摘要压缩、关键信息保留。比如用户说“继续”你需要从会话历史里捞出来他刚才在聊什么用户说“帮我查上个月的数据”你需要知道“上个月”在任务里对应的真实时间范围。这些状态都保存在会话上下文服务里一般用Redis存热数据冷数据落到对象存储或ES归档。上下文服务还要特别注意业务维度隔离。我就遇到过线上事故一个用户开了两个项目A项目里让agent记住了某套话术B项目聊天时竟然把A的内容带出来了原因就是会话key只用了userId没有带上projectId。会话隔离一定得按业务场景做完整不能让不同上下文串味。任务规划服务任务规划服务是agent的核心大脑。它替用户把一句模糊的话拆成可执行步骤。比如“分析本月销售数据并生成周报”Planner要拆出查订单数据、做聚合统计、分析趋势、生成图表、写成周报再把步骤传给后续服务执行。现在的实现主流是让LLM基于ReAct或Plan-And-Execute模式输出规划为了保证程序能解析通常会要求LLM输出结构化JSON再配合状态机来一步步推进。这里有两个必须注意的坑。一是循环控制要给Planner设置最大迭代步数否则遇到复杂指令它会陷入死循环我见过最夸张的一个任务循环了40多次费用损失相当惨痛。二是计划透明我建议在上生产环境时先把计划返回给前端展示等用户确认后再真正执行这样既安全体验也好。模型路由服务模型路由服务替你屏蔽不同大模型厂商的差异。上线早期可能只接一家模型等业务复杂了就会知道抽象层的重要性不同模型的API格式不一样、计费规则不一样、tool calling的格式更不一样。如果每个业务服务都直接连模型API改动一次模型供应商就要改一堆代码。模型路由要做的事情包括统一模型调用接口、维护模型健康状态、按成本和优先级做路由、超时自动切换备用模型。比如主模型是某个高精度大模型当检测到它响应超时可以自动把请求降级到另一个响应更快的模型保证用户体验不至于直接断掉。还有一个容易被忽略的点token计量。因为后续要跟客户对账、要看成本模型路由服务必须在每次请求结束时把input token、output token、模型名称、耗时这些字段记下来同步给可观测审计服务。2.3 能力供给层工具调用、知识检索、记忆服务工具调用服务工具调用服务替agent把“想法”变成“动作”。模型本身只能输出文本和结构化参数真正去查询天气、订酒店、调数据库必须靠工具。MCPModel Context Protocol就是近几年在这个领域里快速普及的一套标准化协议它把工具的发现、调用、返回格式做了统一类似“工具的USB接口”。工具调用服务做的事情不只是转发。它要先校验模型输出的参数是否符合工具定义还要做权限检查当前用户是否允许调用这个工具再做敏感字段脱敏最后才发起真实调用。工具返回的数据通常会很大必须设置返回上限。这里有个我在生产环境踩过的坑工具返回了10万token的数据直接把后续模型调用的上下文撑爆导致整个请求失败。后来加了策略工具返回体超过一定大小就截断或者让模型先对返回做摘要再进入下一轮。这是一个所有做agent的人都会遇到的隐藏炸弹早做早安心。知识检索服务知识检索服务替大模型补齐私有知识的短板。大模型训练完就“冻结”了不知道你公司最新的产品文档也不知道当前用户的实时数据。RAG检索增强生成的流程并不难理解拿到用户问题后先做query改写再到向量库或ES里召回相关片段重排后拼装成上下文让模型基于这些内容回答。这里我想强调一个口头禅回答质量差很多时候不是模型差而是召回质量差。向量召回擅长语义相似但精确匹配场景商品编号、人名、订单号必须靠BM25或者ES的精确检索。我在做企业知识库agent时默认采用混合检索策略把向量召回和关键词召回的结果做重排融合准确率提升非常明显。知识检索一定要保留引用来源ID。这样用户不仅能看到回答还能看到“依据来自哪篇文档”这对信任感和后续审计都很重要。记忆服务记忆服务和会话上下文服务容易混淆我做个区分会话上下文解决的是“这次对话聊了什么”记忆服务解决的是“这个用户长期以来的偏好和事实”。比如用户上次说“我公司简称星云科技北京分部”这次说“按之前的格式出一份报告”记忆服务就要把“星云科技”“北京分部”这些实体捞上来。记忆服务的核心挑战是“该记什么不该记什么”。我的策略是结构化信息和短文本用KV存储长文本经历用向量库定期由LLM对记忆做压缩和去重。比如用户连续聊了十次关于某个项目的内容记忆服务可以运行一次LLM总结把十个片段压缩成一个摘要存下来。记忆服务还有一个必须重视的问题隐私合规。用户聊天内容里可能包含手机号、身份证、住址写入记忆库之前一定要做脱敏。错记一个错误的偏好比记不住更麻烦因为错误的记忆会让后续所有回答都跑偏。2.4 执行与保障层业务集成、异步任务、可观测审计业务集成服务模型、工具、记忆都是“说”的能力业务集成服务才真正负责“做”。企业的订单、CRM、ERP接口五花八门有SOAP的、有老HTTP的、有各种私有协议的总不能让agent一个个直接去连。业务集成服务在这里充当BFFBackend For Frontend的角色把内部系统接口统一封装成agent友好的API做好字段映射、协议转换、数据脱敏。这个服务里最重要的原则是读操作可以自动写操作必须确认。用户让agent查个订单余额没问题但让agent删除一条数据或者发起付款一定要在界面里弹确认框走Human-in-the-loop流程。而且所有写操作接口必须做幂等。我在实际项目里遇到过消息重复消费导致同一封邮件发了两遍的情况幂等键就是在这种血泪教训里学到的。异步任务服务异步任务服务替你处理那些“等不起”的事。一次深入调研、一个周报生成、给100个客户批量发消息这些任务动辄几十秒甚至几分钟不可能让HTTP请求一直挂着等结果。规范做法是三步走任务服务收到请求后先创建一个任务记录返回给前端一个taskId任务丢进消息队列由消费者异步处理处理完成后更新任务状态通过Webhook或者SSE通知前端。任务状态机至少要包含pending、running、success、fail、timeout这五个状态。这里我必须强调生产幂等。消息队列消费端一定要对同一条消息做去重否则网络抖动导致的重复投递会让用户收到两遍一模一样的报告。我在实践中的做法是在任务表里维护一个messageId字段消费前先查询这个messageId是否已经处理过处理过就直接跳过。可观测审计服务可观测审计服务是整个链路的黑匣子。前面的服务再多如果没有一个统一平台把所有日志串起来出了问题就是大海捞针。技术栈一般就是OpenTelemetry做链路追踪Prometheus做指标采集ELK做日志聚合再叠一个审计日志系统。agent场景的可观测性比普通服务多几个维度模型名、token消耗、工具调用列表、每个步骤的耗时、Prompt摘要。这些信息对成本归因和质量分析非常关键。比如用户投诉“agent答错了”你可以拉出当时的模型版本、工具返回、记忆内容完全还原现场。审计日志还要注意脱敏。用户输入可能包含隐私信息全量落盘会带来合规风险。我的做法是日志里只记录脱敏后的内容或者对敏感字段做掩码处理只有授权的人才能查看全文。3. 服务之间怎么协作协议、上下文与超时预算3.1 同步还是异步一次请求的调用形态这12个服务不是所有请求都会串行跑一次实际调用形态更像是一个“主干加分支”的组合。主干上的API网关、认证、限流、会话、规划、模型路由是同步调用每步都要拿到结果才能走下一步。分支上的知识检索、记忆、工具调用会由Planner按需发起。异步主要发生在两个位置一是长耗时任务比如生成周报会立即返回taskId然后走消息队列二是工具调用里如果涉及人工审批审批流程本身是异步的agent会轮询审批结果。设计接口时我强烈建议内部服务统一用一套协议。HTTP/2或者gRPC都可以但不要混着用否则排查问题时会非常痛苦。服务间通信协议层必须明确包括序列化方式、超时时间、错误码规范。3.2 三个贯穿全链路的ID一次请求能跨十几个服务排查靠的是三个关键IDtraceId请求入口生成贯穿所有服务用于还原完整调用链。sessionId标识一段多轮对话用于会话上下文的读取和写入。userId标识操作者身份用于权限判断和审计。这三个ID必须通过请求Header或metadata透传到每个服务并且在日志里统一打印。我之前接手过一个系统网关生成了traceId但业务服务打印日志时没带出来导致每次排查问题都要靠猜效率极低。后来立了个规矩任何服务任何日志必须包含traceId和userId没有这两个字段的日志一律视为无效日志。3.3 一次请求的时间预算表agent请求因为涉及多轮模型推理和工具调用天然比普通Web请求慢。给前端设定合理的总超时非常重要。我分享一份实际生产中的时间预算参考服务/环节正常耗时超时阈值API网关转发5~20ms500ms认证鉴权10~50ms300ms限流治理1~5ms100ms会话上下文读取5~30ms200ms任务规划LLM调用500ms~5s10s模型路由生成1~8s15s工具调用100ms~10s10s知识检索50~300ms2s记忆读写20~100ms1s业务集成200ms~5s8s异步任务秒到分钟级不纳入同步超时可观测审计1~10ms200ms所以一次带工具调用的agent请求理想情况要3到15秒极端情况下可能超过20秒。这个数字看起来夸张但在LLM场景里其实是常态。如果不想让用户等太久一个是模型层优化另一个是把耗时的检索和工具调用并行化。3.4 超时、重试与降级的兜底原则链路长了任何一个环节抖动都可能拖垮整体。超时设计我遵循“整体兜底、局部设限”的原则客户端总超时一般设30秒超过就返回“任务处理中请稍后查看;内部每个服务都有各自的超时阈值谁也不许无限制等上下游。重试只允许在幂等接口上做而且必须用指数退避加随机抖动避免所有请求同时重试打垮下游。降级策略也要事先想好模型路由超时了可以降级到备用模型知识检索超时了可以不带知识直接回答工具调用超时了可以告诉用户“该功能暂时不可用”。降级的前提是先保证用户有响应而不是一直转圈。4. 为什么要拆成12个分布式架构的代价与收益4.1 拆分的三个真实驱动力很多人觉得拆12个服务是“过度设计”但从实际业务角度拆分的驱动力非常现实团队协作。12个服务通常对应不同的团队或不同的发布节奏。模型路由策略改版一周上三次业务集成接口一个月才改一次如果它们写在同一个服务里每一次小改动都要牵动整套系统回归发布效率会非常低。资源隔离。LLM推理和业务查询的负载特征完全不同。模型服务吃GPU和高并发连接业务集成服务更多是数据库和下游API调用。混在一起部署一旦某个模型接口抖动会连带把业务服务拖死。拆开后至少可以通过独立扩缩容防止互相干扰。安全边界。身份认证、工具权限、审计日志这几个服务的安全等级要求很高独立部署能避免业务代码的低级漏洞波及核心安全模块。比如工具调用服务要限制访问网络白名单而业务集成服务可能需要访问多个内部系统两者混在一起时网络策略就很难做到精细化。4.2 小团队或MVP阶段如何合并服务如果你的项目还在早早期日活不高团队也就两三个人硬套12个服务确实不理智。我建议按“三件套”合并第一个是接入服务把API网关、认证鉴权、限流、会话上下文合并成一个BFF服务负责所有的入口逻辑第二个是agent核心服务把任务规划、模型路由、工具调用、记忆服务合并在一起这是真正的业务大脑第三个是集成服务把业务集成、知识检索、异步任务、数据存储合并负责底层数据与外部系统交互。可观测性先不做独立服务直接统一打到一套日志平台。等并发量上来或者某个模块的发布频率开始拖累其他模块再按上面描述的边界逐步拆分。拆分不是目的解决扩展和维护问题才是。4.3 哪些边界一旦模糊就会出事有几个边界我是强烈不建议合并的。第一个是写操作确认机制也就是业务集成服务里的审批和幂等逻辑必须独立且清晰第二个是审计日志任何情况下都要保证完整不能在合并服务时把审计记录给吞了第三个是密钥管理所有模型API Key、业务系统账号密码必须独立管理绝不能散落在业务代码仓库里。5. agent链路的故障排查与避坑实录5.1 最常见的六类问题速查表症状可能原因第一步排查思路整体响应非常慢模型调用超时、工具调用超时拿到traceId看哪一跳耗时最长回答没有引用知识答得很空RAG召回为空或topK太小查知识检索日志里的召回数量和来源工具根本没执行参数schema不匹配、权限不足看工具调用服务的校验报错上下文串味、答非所问sessionId传递丢失或会话key不完整检查所有服务是否正确透传sessionId费用飙升账单失控Planner陷入循环、无配额限制查Planner迭代次数和模型路由的token统计用户反馈卡住但后端没日志请求在网关或负载均衡被丢弃查入口access log和上游连接超时5.2 一次排障过程实录说一个我印象很深的线上问题。用户反馈agent回答销售数据时一直用上一季度的数据还经常带出一些无关的历史记录。第一反应是知识检索召回错了但查了检索日志召回的内容是对的。后来我顺着traceId看了会话服务和记忆服务的日志发现问题的根因在记忆服务。这个用户的记忆库里存着一条“上次查看销售数据时关注华北区域”的旧偏好而当前会话根本没有提到区域限定。记忆服务在每次请求时把这条历史偏好强插进了上下文结果模型被带偏了。这块bug的根源是记忆写入策略太激进——什么内容都往长期记忆里写没有判断这条信息是否对后续对话有价值。后来我们调整了策略记忆写入前由LLM做一个价值判断只有与用户长期偏好相关、且稳定的信息才进入长期记忆。同时增加了记忆内容的可解释性每次插入记忆都会带一条来源说明方便在排障时追溯这条记忆是什么时候、从哪段对话里学到的。5.3 几条花真金白银换来的实操心得第一agent链路排障最忌讳没有traceId。只要链路超过3个服务第一件事就是把全链路日志打通宁可晚一周做业务功能也不能拖着不做可观测性。第二Planner的输出一定要用JSON Schema校验别相信大模型每次都规规矩矩输出。我在生产里见过模型把步骤里的type写成了Type直接导致解析报错。第三做任何工具调用都要假设它会失败而且要把失败信息清晰地回传给Planner让它重新规划而不是直接给用户扔一句“出错了”。第四模型路由的fallback链至少要留一个低成本的备用模型关键时刻真的能救命尤其是主模型厂商出现大面积故障时。这套12服务的链路并不是哪一个架构师拍脑袋定的而是从一个个线上事故里长出来的。每一跳服务背后都对应过一个具体的痛点或者是为了安全或者是为了成本或者是为了排查方便。真正重要的不是把这个链路背下来而是遇到问题时能顺着链路快速定位出是哪一个环节出了问题尽早恢复服务。