首页 / 资讯中心 / 文章详情

智能体平台生产化实践:任务编排、工具管理与全链路监控

智能体平台生产化实践:任务编排、工具管理与全链路监控 ★ FEATURED ARTICLE
平台这个东西说来也怪——Demo阶段跑得飞起的智能体一旦进了生产环境就各种幺蛾子。要么任务执行到一半模型超时要么工具调用把外部接口打崩要么出了问题根本没法查是哪一步错的。去年我们团队把分散在各业务项目里的智能体脚本收拢成一个统一平台核心就是解决三件事任务编排、工具管理、运行监控。这篇文章就把整套设计思路和落地细节完整梳理一遍不绕弯子直接讲我们怎么拆的、怎么做的、踩过哪些坑。先说清楚它能解决什么问题。你如果只是写几个脚本调大模型API那不需要平台但如果你要支撑几十个业务方、上百个智能体任务、几十种外部工具还要求出问题能追踪、能回滚、能审计那就必须有平台。这套东西适合两类人看一类是要从零搭智能体中台的技术负责人另一类是正在改造现有AI应用、想知道生产化还差哪些环节的开发者。下面全部基于我们的真实实践方案取舍也都附了理由可以直接拿去用。1. 平台整体架构为什么不能只靠模型API硬扛1.1 设计原则面向流程而不是面向对话很多人对智能体平台的第一印象是对话机器人平台这其实是个误区。生产级平台的核心对象不是会话而是任务——一个任务可能是一篇研报的自动生成、一批工单的自动分类、一条短视频的自动剪辑分发。任务天然有状态、有依赖、有失败重试、有执行耗时而对话只是任务的一种交互形态。所以我们的第一原则就是以任务为中心建模所有能力都围绕任务的完整生命周期设计。从任务创建、排队、调度、执行、重试、归档到审计每一步都要有迹可循。这个思路直接决定了后面编排引擎和监控体系的方向。如果只盯着对话你会发现对话挂了你不知道任务挂没挂任务挂了你也说不清是模型的问题还是工具的问题。1.2 四层架构接入、编排、执行、监控各管一摊我们最终落地的架构分四层每层职责单一、接口清晰这为后面排障省了大力气。接入层统一API网关负责租户隔离、密钥管理、流量控制。所有业务方通过一个入口提交任务平台内部再路由到具体执行单元。编排层这部分是平台的大脑。负责解析任务定义DAG、维护任务状态、调度节点执行、处理分支与重试。状态全部持久化到数据库进程挂了可以从断点恢复。执行层跑具体活的地方。包括模型网关统一封装各家大模型API、工具运行时负责拉起工具调用、沙箱环境隔离不可信代码。执行层是无状态的可以水平扩容。监控层包括日志采集、链路追踪、指标监控Prometheus Grafana、告警通知。这一层不是可有可无的装饰品而是生产环境排障的第一现场。为什么这么分核心原因是故障域隔离。模型网关挂了不应该影响任务调度工具运行时抖动不应该拖垮整个平台。四层独立部署、独立扩缩容这是我们踩过单体应用故障蔓延的坑之后总结出来的硬教训。2. 任务编排引擎从人肉串流程到DAG自动化2.1 编排模型选型为什么DAG是主力设计任务编排时我们对比过三种模型线性链路、DAG有向无环图、状态机。线性链路最简单就是一步接一步适合先查库再调模型再写回这种固定流水线。但生产环境很快会发现真实任务没那么乖巧——比如生成视频脚本这个任务可能同时要拉舆情数据、查历史爆款文案、调图像模型生成分镜三个子任务互不依赖串行执行就白白浪费了并行时间。线性链路做不了并行聚合。状态机适合复杂交互场景比如客服机器人要处理多轮对话状态流转但状态机的建模成本高对大部分业务团队来说学习曲线陡峭而且状态爆炸后很难维护。所以我们选了DAG为主、状态机为辅的混合方案常规业务任务用DAG表达重交互场景单独用状态机实现。DAG表达任务清晰直观节点之间天然支持并行而且拓扑排序的调度算法非常成熟轮子不用自己造。2.2 节点类型与上下文传递编排放到落地层面我们定义了五类节点模型节点调用大模型可配置模型名称、温度、最大Token等参数。工具节点调用平台工具中心里的某个工具比如发邮件、查数据库、执行代码。条件分支节点根据上游结果判断走哪个分支比如判断生成内容是否合规。并行聚合节点把多个并行子任务的结果汇总再喂给下游。这个节点在处理数据采集、多路分析场景里是神器。人工审批节点生产环境杀招之一。高风险动作比如自动发信、扣费、删除数据必须挂人工审批不然出了事故连挽回的机会都没有。上下文传递是个容易被低估的设计点。每个节点执行完会产生一段输出下游节点可能需要拼接这些上游数据作为输入。我们为每个任务维护一个上下文对象按节点ID存取数据同时设定单条数据大小上限超过阈值自动摘要或丢弃。真实场景里最常见的问题是上下文越攒越大最后超出模型的上下文窗口所以策略上要够用就好而不是把所有中间结果全都塞进去。2.3 一份可落地的任务编排定义示例DAG定义我们用YAML描述存储到数据库平台解析后调度执行。下面是一份真实任务舆情报告自动生成的简化定义id: report_gen name: 舆情报告自动生成 version: 1.3 timeout: 3600 retry: 2 nodes: - id: collect_data type: tool tool: fetch_news params: topic: 智能体平台 days: 7 - id: analyze_sentiment type: llm model: gpt-chat-model params: temperature: 0.3 max_tokens: 2000 dependencies: [collect_data] - id: risk_check type: tool tool: sensitive_check params: content: ${analyze_sentiment.output} dependencies: [analyze_sentiment] - id: approval type: human_approval params: reviewers: [ops-team] dependencies: [risk_check] - id: deliver type: tool tool: send_email params: to: business-ownerexample.com content: ${risk_check.output} dependencies: [approval]这个定义里有几个值得注意的点dependencies字段声明依赖关系调度器据此做拓扑排序。analyze_sentiment依赖collect_data两个节点之间无依赖的部分天然并行。${node_id.output}是上下文引用语法平台在节点执行前从上下文里取出对应数据注入参数。高风险节点deliver前挂人工审批这是生产环境防止模型抽风导致一封错误邮件发出去的保命措施。timeout是整条链路的超时每个节点也可以单独设超时防止单个步骤拖垮整个任务。重试策略上我们的经验是幂等工具可以放心重试比如查询操作非幂等工具比如创建订单、发送消息要配合幂等键使用。每次任务执行时生成一个全局唯一的execution_id工具调用时带上这个ID作为幂等键这样即使下游重复调用也能通过查重避免重复操作。2.4 调度与并发队列不是越深越好任务调度我们用了优先级队列加并发控制。平台里跑着大量任务模型调用是昂贵资源外部工具接口也有速率限制无脑全开并发只会把下游服务打爆。实操中给每个租户设置并发上限比如单租户最多同时跑20个任务队列里超出额度的任务排队等待。同时设置全局线程池大小模型节点和工具节点分开配额。这样做的直接好处是一个业务方的突发流量不会占用其他业务方的资源平台整体稳定性好控制得多。3. 工具管理把外部能力变成平台一等公民3.1 工具注册中心的三件套工具管理模块我们做了很久因为它的复杂度被很多人低估了。表面上看工具就是一个API调用但生产环境要考虑工具怎么声明、怎么鉴权、怎么限流、怎么审计、怎么灰度上线、怎么在调用失败时快速降级。我们为每个工具建立注册记录包含三件套接口schema、鉴权配置、运行时配置。接口schema用JSON Schema描述入参出参模型判断该调用哪个工具时就是靠schema理解工具能力的。鉴权配置存放密钥、凭证密钥一律加密存储运行时动态注入绝不出现在日志里。运行时配置包括超时时间、重试次数、并发限制、熔断阈值。工具接入流程是开发者提交工具声明 - 平台自动校验schema合法性 - 测试环境连通性验证 - 管理员审核 - 上线。这个流程解决了谁都能乱接、接了没人管的问题。3.2 代码与配置管理Git系Web工具为何是标配智能体平台里经常会有一类工具是操作代码仓库的比如自动提交变更、分析代码、解析版本差异。要支撑这类工具底层代码管理底座的选择很重要。传统SVN只有一个中央仓库分支模型笨重Web端查看历史差异的体验也一般。现在的团队协作基本都转向Git系工具。除了SVN目前主流的Web端代码管理工具有三类GitLab自托管功能最全、Gitea轻量资源占用小社区活跃、Gitee国内托管开箱即用。如果你需要内网部署GitLab Community Edition和Gitea是首选。GitLab的优势在于一体化的CI/CD能力代码仓库、流水线、制品库都能在同一个平台里管适合智能体平台里那些自动化改代码-跑测试-发版本的复杂任务。Gitea则胜在极简一个几百MB的二进制文件就能跑起来对小团队或者只需要基础代码托管和版本查看的场景非常友好。我们的实际选型是对轻量工具链和配置类仓库用Gitea对核心业务代码库用GitLab各取所长。这类工具在智能体平台里扮演的角色远不只是存放代码——它们承担了版本溯源和变更审计的职责。当智能体自动改完代码后我们必须能回答谁改的、改了什么、能不能回滚。Git系工具的Web界面天然支持查看不同版本、对比差异、回溯历史这些能力直接复用到智能体的变更审计链路里。3.3 工具版本管理线上的永远是稳定版本工具本身也是要迭代的。我们的工具中心支持一个工具多个版本并存每个版本有独立的schema和运行配置。线上任务通过工具名 版本号引用具体版本绝不默认指向最新版。为什么这么设计因为工具实现是有可能带bug的如果所有任务默认用最新版一次工具升级可能让几十条线上链路同时挂掉。我们的做法是新版本工具先在小流量任务上灰度观察一段时间的成功率稳定后再推广到全部任务。线上出问题需要回滚时只需把引用版本指向上一个稳定版本立刻生效。工具鉴权也有讲究。一个平台接了几十个工具每个工具的密钥如果都放在任务配置里那就是灾难。我们做了凭证托管密钥统一存平台工具调用时按租户维度动态注入。每个租户归属于哪些工具的哪些权限在工具中心统一管理做到调用有记录、越权有拦截。3.4 工具熔断与降级工具调用失败是常态不失败才奇怪。我们为每次工具调用配置了熔断器连续失败N次比如5次熔断器打开后续请求快速失败不再打到下游。熔断器半开后放少量流量试探恢复正常则关闭熔断。这个机制救过我们一次。某个外部数据服务凌晨升级出问题接口持续5xx熔断器及时打开平台整体没有受影响其他依赖该服务的任务也能快速感知失败并走降级路径。没有熔断器的话所有任务都会卡在等待响应上然后集体超时连锁反应下来整个平台都要瘫痪。4. 运行监控体系用Prometheus和Grafana搭出全程可观测性4.1 Trace ID贯穿全链路排障的第一步生产环境排障最怕的就是任务失败了但说不出失败在哪个环节。我们从设计第一天就要求全链路携带trace_id——用户发起请求时生成整个任务执行生命周期一直透传任务记录里存、日志里带、指标里带、工具调用里带。实现上平台打印每一条日志时都自动注入trace_id和node_id。这样一条日志的查法是先用trace_id筛出某个任务的全部日志再按node_id和时间排序就能完整还原什么时候进了哪个节点、调了多少次模型、每个工具返回了什么。这个能力在分布式排查里是刚需没有它你只能对着时间戳猜。4.2 指标体系设计别什么都埋要埋有用的监控指标的设计直接决定你排障的速度。我们根据智能体平台的特性把指标分成四类指标分类典型指标类型选择任务类任务执行总数、任务成功率、任务排队时长Counter / Gauge模型类模型调用延迟、Token消耗量、模型报价估算Histogram / Counter工具类工具调用次数、工具成功率、工具失败原因分布Counter平台类队列积压数、线程池使用率、任务超时数Gauge / Counter指标类型的选择有讲究。比如任务执行总数是只增不减的用Counter当前队列积压数会上下波动用Gauge模型延迟是持续时间用Histogram这样能直接P50/P95/P99延迟。Token消耗用Counter可以统计一个周期的总消耗用于成本核算。我们用Python往Prometheus暴露指标核心代码大致长这样from prometheus_client import Counter, Histogram, Gauge, generate_latest TASK_TOTAL Counter(agent_task_total, Total tasks submitted, [tenant, status]) MODEL_LATENCY Histogram(agent_model_latency_seconds, Model call latency, [model], buckets(0.1, 0.5, 1, 2, 5, 10, 30)) TOOL_SUCCESS Counter(agent_tool_calls_total, Tool call count, [tool, result]) QUEUE_DEPTH Gauge(agent_queue_depth, Current queue depth, [tenant]) # 任务结束时打点 TASK_TOTAL.labels(tenanttenant_id, statussuccess).inc() # 模型调用结束记录耗时 MODEL_LATENCY.labels(modelmodel_name).observe(elapsed_seconds)有几个实践心得提供给大家指标label不是越多越好。我们一开始给指标加了host、version、tenant、model等一堆label结果Prometheus存储告警查询也变得很慢。后来砍掉host这种高基数label只保留tenant、model、tool这种维度有限的label问题立刻缓解。任务耗时分布建议用Histogram而不是summary因为Histogram可以跨实例聚合summary无法做到。告警规则要配合人工经验逐步收敛。刚开始我们把所有指标都配上告警结果告警风暴运维疲劳最后重要的告警反而被忽略。收敛成任务成功率低于99%、队列积压超过1000持续5分钟、工具失败率高于10%这三条核心规则后告警有效性大幅提升。4.3 Prometheus告警规则的一个实操案例接上面的指标我们看一条真实告警规则怎么配。假设我们需要监控任务成功率# 每5分钟统计一次成功率 sum(rate(agent_task_total{statussuccess}[5m])) / sum(rate(agent_task_total[5m])) * 100 99写成告警规则文件就是groups: - name: agent-platform rules: - alert: TaskSuccessRateLow expr: | sum(rate(agent_task_total{statussuccess}[5m])) / sum(rate(agent_task_total[5m])) * 100 99 for: 10m labels: severity: page annotations: summary: 任务成功率低于99%持续10分钟for: 10m这句值得细说。如果去掉这个持续10分钟的条件微小的瞬时抖动就会频繁触发告警。生产环境里很多告警疲劳都是因为没加for字段导致五分钟抖一下、十分钟又抖一下人就被磨疲了。我个人的建议是所有告警规则默认都加上for: 5m或for: 10m除非是核心业务中断这种必须秒级响应的场景。4.4 Grafana面板让数据看起来就有结论Grafana部分的核心是配置数据源和设计面板。Prometheus数据源配置很简单填服务地址即可关键是面板怎么设计才高效。我的经验是每个面板遵循一排一个大问题的原则。第一个panel放任务执行趋势横轴时间、纵轴任务数success、failed、timeout用不同颜色折线展示第二个panel放P95模型延迟第三个panel放工具成功率排名用来快速定位是哪个工具在拖后腿一行放Queue深度和租户并发占用。排障的时候从上往下看一遍就能回答现在整体跑得好不好、瓶颈在哪、谁该背锅。Grafana的Variables功能建议一定用。配置一个tenant变量后面板左上角就可以切换租户各业务方的数据一眼区分。没有Variables的时候每个租户都要单独建面板维护成本成倍增长。4.5 日志与指标之间的桥还是trace_id日志和指标如果只能各自看各自的排障还是费劲。我们的做法是Grafana里做一个从指标跳到日志的联动。比如你在Grafana面板上看到某段时间任务成功率陡降点一下就能跳转到对应trace_id的日志查询页直接看失败原因。实现上就是在Grafana的panel里配置一个Data link用模板变量把当前时间段的trace_id带到日志平台查询。这一点做完了以后排障速度肉眼可见地提升。之前找问题是猜-查-再猜现在是从全局趋势定位大概时间点再顺着trace_id直达现场整个过程从小时级缩短到分钟级。5. 生产环境的那些坑以及怎么填5.1 模型提供商抖动必须有超时和熔断双层保险大模型API的响应时间在生产环境极度不稳定同样的请求高峰期可能要等20秒甚至直接连接超时。我们在模型网关上设置了硬超时默认60秒可按节点覆盖超时后自动重试一次重试仍然失败则放弃并抛异常。同时配合熔断器连续失败就快衰减防止模型API抖动把平台的线程池占满。这个坑最容易被忽视的地方是模型调用超时选择跟普通HTTP一样设个5秒那生产环境基本等于全挂。大模型生成几百个token本身就要几十秒超时要按实际情况放宽而不是跟着默认值走。5.2 工具调用时长失控所有工具必须设硬超时工具调用比模型调用更难控制因为外部系统你说了不算。我们踩过一个大坑一个查询工具正常跑1秒结果某天数据源端表数据膨胀单次查询跑了15分钟平台上几十个并发任务全部卡死在这个工具上队列爆掉。后来我们强制要求工具注册时必须配置超时时间默认5秒最长不超60秒运行时强制执行。同时配合信号量控制到达超时直接返回失败绝不做无上限等待。这个改造上线后类似的卡死问题再没出现过。5.3 Token消耗失控配额与成本熔断智能体任务里模型调用Token消耗是隐性成本炸弹。任务跑得多的时候月底账单出来才知道烧了多少。我们做了每租户、每任务的Token配额控制同时按模型单价实时估算成本超过阈值自动降级比如从大模型降级到快速模型或熔断。Token消耗指标单独埋点每天定时汇总生成成本报表。没有这个能力你根本没法回答老板平台跑一个月要花多少钱这个灵魂拷问。5.4 上下文窗口溢出别把所有中间结果堆给模型任务链路长了以后上下文里塞的东西会越来越多最终超出模型上下文窗口报错。我们的解法是上下文注入前先做裁剪只保留当前节点真正需要的上游字段确实需要全量上下文的长任务定期对历史结果做摘要压缩。这个逻辑在编排引擎里做成公共组件各任务复用省了一堆重复代码。5.5 监控数据本身也可能压垮你指标采集的量和维度过大Prometheus内存会先爆掉。史上是血泪教训我们曾经给每个工具实例加一个label结果一扩容就是几十个新序列Prometheus查询直接超时。给几个具体的容量建议label的基数控制在几百以内杜绝UUID、主机名这类高基数值。采集频率默认15秒即可没必要5秒。努力做到指标都有用途没有配任何告警或面板的指标直接不采集。5.6 功能上线灰度、回滚、保留现场平台内任何一个新功能升级都按金丝雀→小流量→全量的方式走。具体是先在一组内部测试任务上跑观察新版本编排引擎的日志和指标确认无误后再放量。出问题时靠版本回滚机制快速恢复同时保留出事时的完整执行快照包括上下文、日志、指标方便事后复盘。保留现场这一点太重要了。很多线上问题你没办法让用户复现而执行快照让你能在出错后复盘模型当时收到了什么输入、返回了什么内容、工具为什么失败。6. 最后几个小建议再分享几条更偏软的经验。第一智能体平台前期不要想着把功能做全先跑通一个真实业务场景把编排、工具、监控这三个环节都真实地用起来再横向铺开。我们把第一个业务方接入的时间从预估两个月压缩到了三周就是因为先聚焦了一个高频小任务把链路全打通了再复制。第二平台文档不能只写接口说明要写清楚什么场景该用什么方式编排工具接入的审核要点是什么告警响了先看哪几个面板。我们内部把排障流程做成了checklist新人照着走也能在半小时内定位大部分问题。第三给平台留出扩展点。任务类型、工具协议、模型供应商这三块未来一定会变接口设计上把新增做成常态操作而不是每次都要改平台代码。这决定了平台能走多远。
阅读完成 · 觉得有帮助?
咨询建站