ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

企业大模型落地:模型网关、CLI与Agent自动化实战

企业大模型落地:模型网关、CLI与Agent自动化实战 企业里做大模型落地最容易被低估的一环不是模型选型也不是提示词调优而是网关这层看起来不起眼的中间件。我见过太多团队Demo 阶段直接在前端代码里硬编码一个 API Key跑得挺欢等到要接第三个业务方、要审计调用量、要按部门限流、要切换模型供应商的时候才发现整个调用链路是一团乱麻。这篇就聊聊我实际踩过的坑怎么用一套网关把模型调用管起来再配合 CLI 工具和 Agent 把日常开发里的重复劳动自动化掉。内容偏实战适合正在做企业级 AI 应用落地的后端、平台工程师也适合想搞清楚 Agent 和 CLI 到底怎么配合的技术负责人。1. 为什么企业一定要有模型网关这层1.1 直连模型 API 的三种典型翻车现场先说清楚问题不然网关就是个听起来很高级但不知道为啥要装的东西。我总结下来绕过网关直连模型 API 的团队基本都会撞上这三堵墙。第一堵墙是密钥管理失控。业务代码里散落着 API Key前端打包进去的、后端配置文件里的、测试脚本里的一旦要轮换密钥你得全仓库搜索替换漏一个就是安全事故。更麻烦的是你根本不知道哪个 Key 被谁用了、用了多少。第二堵墙是成本黑盒。财务月底问你这个月 AI 花了多少钱你只能去供应商后台看一个总数没法拆到具体业务线、具体用户。等到某个业务方偷偷跑了个批量任务把额度烧光你连是谁干的都查不出来。第三堵墙是供应商锁定。今天用 A 家的模型明天想试试 B 家的发现调用格式、鉴权方式、返回结构全不一样改造成本高到让你放弃。而模型迭代速度这么快锁死在一家基本等于慢性死亡。网关要解决的就是这三件事统一入口、统一鉴权、统一计量、统一路由。它本质上是一个反向代理但比普通反向代理多了模型语义——它懂 token 计费、懂流式响应、懂多供应商适配。1.2 网关到底该管哪些事一张职责边界表很多人一上来就想把网关做成万能层结果越做越重。我的经验是网关的职责要划清楚超出边界的坚决不做。职责该不该网关做理由鉴权与密钥托管必须做密钥绝不能下发到业务侧限流与配额必须做需要全局视角业务侧做不了用量计量与计费必须做统一口径避免各算各的多供应商路由与降级必须做这是网关的核心价值请求日志与审计必须做合规要求且便于排障提示词模板管理可以做但要注意版本管理复杂度业务逻辑编排不该做应该放在业务服务或 Agent 层复杂的数据后处理不该做网关要保持轻量和高吞吐这张表是我踩过坑之后总结的。早期我们把一堆业务规则塞进网关结果每次业务调整都要动网关发布风险极高最后又拆出去。网关要像水管只负责把水稳定地送过去不负责水的味道。1.3 一个最小可用网关的架构拆解一个能上生产的最小网关我建议包含这几个模块按请求经过的顺序排列接入层负责 TLS 终止、连接复用。用 Nginx 或者直接 Go 的 HTTP server 都行关键是别在这里做业务。鉴权模块校验业务方带来的内部 Token映射到具体的租户和配额。注意业务方拿的是你发的内部 Key不是供应商的 Key。路由模块根据请求里的模型标识、租户策略、当前供应商健康状态决定转发到哪家。适配层把统一的内部请求格式翻译成各家供应商的格式。这层是脏活累活但必须隔离好。计量模块解析响应里的 token 数累加到对应租户的账上。流式响应要特殊处理边转发边统计。日志与审计记录请求元数据。注意默认不要记录完整的提示词内容涉及用户隐私需要脱敏或按需开启。这套架构跑下来单机撑个几百 QPS 没问题。真到高并发瓶颈通常在适配层的序列化开销和日志写入后面会讲怎么优化。2. 网关核心模块的落地细节与踩坑2.1 鉴权设计内部 Key 和供应商 Key 必须彻底隔离这是我最想强调的一点。很多团队图省事直接把供应商的 API Key 发给业务方这是大忌。正确的做法是网关自己持有供应商 Key对外只发内部 Key。内部 Key 的设计我建议带上这几个信息租户 ID、环境标识测试/生产、权限范围能用哪些模型、过期时间。可以用 JWT 承载这些信息也可以用数据库存映射关系。JWT 的好处是无状态、校验快坏处是吊销麻烦数据库映射的好处是灵活坏处是每次请求都要查库得加缓存。我实际用的是混合方案JWT 里放租户 ID 和基础权限细粒度的配额和吊销状态放 Redis。校验流程是先验 JWT 签名拿到租户 ID再去 Redis 查这个租户的实时状态和剩余配额。这样既快又灵活。注意内部 Key 一定要支持一键吊销。我遇到过业务方把 Key 提交到了公开仓库如果没有快速吊销机制只能干等着被刷爆。2.2 多供应商路由怎么做到切换无感路由策略我分了三层从粗到细静态路由按模型名直接映射。比如请求gpt-4就走 A 家请求claude就走 B 家。这是最基础的。权重路由同一个模型可以配多个供应商按权重分流。比如 70% 走主供应商30% 走备用用来做灰度或者压测。故障转移主供应商返回错误或超时自动切到备用。这里有个坑不是所有错误都该重试。429限流和 5xx 可以重试400请求格式错重试多少次都一样纯属浪费。适配层的实现我建议定义一个统一的内部请求结构然后每个供应商写一个 adapter。核心字段就这几个model、messages、temperature、max_tokens、stream。返回结构也统一成content、usage、finish_reason。这样业务侧完全感知不到底层换没换供应商。# 统一请求结构的示意 class UnifiedRequest: model: str messages: list temperature: float 0.7 max_tokens: int 1024 stream: bool False # 每个供应商实现一个 adapter class ProviderAdapter: def to_provider_format(self, req: UnifiedRequest) - dict: raise NotImplementedError def from_provider_response(self, resp: dict) - dict: raise NotImplementedError2.3 流式响应的计量最容易算错的地方流式响应SSE的计量是个大坑。非流式请求响应体里直接带usage字段解析一下就行。流式请求token 数是分散在各个 chunk 里的而且很多供应商只在最后一个 chunk 才给 usage甚至有的根本不给。我的处理方式是双保险优先用供应商返回的 usage拿不到就本地估算。本地估算用简单的字符数除以系数中文大概 1.5 字符一个 token英文 4 字符一个 token虽然不准但用于内部计量足够了。还有个细节流式响应转发时如果客户端中途断开你得能感知到并且把已经产生的 token 计上。我见过有团队因为客户端断开就不计量结果被人恶意刷量。实现上监听连接的关闭事件在关闭时把当前累计的 token 落库。2.4 日志脱敏合规红线不能碰日志这块我的原则是默认只记元数据不记内容。元数据包括请求时间、租户、模型、token 数、耗时、状态码。这些足够排障和计费了。如果业务确实需要记录内容用于调试必须满足两个条件一是租户显式授权二是内容做脱敏处理。手机号、身份证、邮箱这些用正则替换掉。我一般会提供一个开关按租户粒度控制默认关闭。提示日志存储也要考虑成本。全量记录提示词量大了存储费比模型调用费还贵。建议设置保留期比如 7 天过期自动清理。3. CLI 工具把重复操作从鼠标里解放出来3.1 为什么企业开发场景特别需要 CLI网关搭好了接下来是日常开发效率的问题。我发现一个规律凡是需要在网页上点五六次才能完成的操作都应该有 CLI 版本。比如查某个租户的用量、临时调整配额、查看某个请求的日志这些操作如果每次都登录后台点一天下来浪费的时间很可观。CLI 的另一个价值是可脚本化。比如每天凌晨自动导出前一天的用量报表或者 CI 流程里自动检查配额是否充足这些用 CLI 几行脚本就搞定用网页后台根本没法自动化。3.2 用 CLI 管理网关几个高频命令的设计我设计的 CLI 工具命令结构是这样的gw 资源 动作 [参数]。举几个高频场景# 查看某租户当前用量 gw usage show --tenant team-a --period today # 临时调整配额 gw quota set --tenant team-a --limit 1000000 --expire 2025-01-01 # 查看最近的错误请求 gw log errors --tenant team-a --last 1h # 导出用量报表 gw report export --start 2024-12-01 --end 2024-12-31 --format csv这些命令背后就是调网关的管理 API。设计上要注意CLI 的鉴权用独立的管理员 Key和业务 Key 分开。管理员 Key 权限大要严格控制分发。3.3 自动化编程里的 CLI 集成让 Agent 调用工具CLI 真正发挥威力的地方是把它作为 Agent 的工具来用。Agent 本身不会查数据库但你可以给它一个 CLI 工具让它通过执行命令来获取信息。比如一个运维 Agent它的任务是根据告警自动排查。你可以给它这几个工具查网关日志的 CLI、查服务器状态的 CLI、重启服务的 CLI。Agent 拿到告警后自己决定先查什么、再查什么最后给出结论或执行修复。这里的关键是CLI 的输出要结构化最好是 JSON。Agent 解析 JSON 比解析人类可读的文本靠谱得多。所以我在设计 CLI 时都会加一个--json参数输出机器友好的格式。gw log errors --tenant team-a --last 1h --json # 输出: {errors: [{code: 429, count: 15, model: gpt-4}, ...]}3.4 CLI 安装与依赖问题的排查经验CLI 工具分发时依赖问题是最烦人的。我遇到过npm install -g报权限错误、报找不到可选依赖的情况。这类问题的排查思路是固定的先看错误信息里的关键词。如果是EACCES或permission denied那是权限问题要么用管理员权限装要么改 npm 的全局目录。如果是missing optional dependency通常是网络问题导致某个平台的二进制包没下下来可以尝试清缓存重装。# 清理缓存后重装 npm cache clean --force npm install -g packagelatest # 如果还是不行检查全局目录配置 npm config get prefixWindows 上还有个常见坑就是 PowerShell 的执行策略限制导致 npm 脚本无法运行。这个用Set-ExecutionPolicy调整一下就行但要注意这是系统级设置改之前跟团队确认。4. Agent 与自动化编程的配合方式4.1 Agent 到底是什么和普通脚本的本质区别很多人把 Agent 和脚本混为一谈其实区别很大。脚本是固定流程第一步做什么、第二步做什么写死了。Agent 是动态决策给它一个目标它自己决定用什么工具、按什么顺序、做到什么程度算完成。举个例子脚本版的日报生成是查数据库、拼字符串、发邮件。Agent 版的日报生成是你告诉它生成今天的运营日报它自己去想需要哪些数据、去调对应的工具、发现数据异常还会主动多查几个维度、最后组织成报告。这个区别决定了 Agent 适合流程不确定、需要判断的场景脚本适合流程固定、重复执行的场景。企业里两者都要有别指望 Agent 干所有事。4.2 Agent 的工具设计CLI 是最容易接入的一类给 Agent 设计工具我有个优先级CLI HTTP API 数据库直连。原因很简单CLI 是封装好的、有明确输入输出的、出错信息友好的。HTTP API 次之因为要处理鉴权、重试这些。数据库直连最不推荐Agent 生成的 SQL 很容易出问题。一个 Agent 工具的定义核心就三部分工具名、描述、参数 schema。描述特别重要Agent 靠描述来决定什么时候用这个工具。描述要写清楚这个工具做什么、什么时候用、参数什么意思。{ name: query_gateway_usage, description: 查询指定租户在指定时间段的模型调用用量。当需要了解成本或排查异常用量时使用。, parameters: { tenant: 租户ID, period: 时间范围如 today, last_7d } }4.3 Agent 的记忆与上下文管理Agent 跑多轮任务时上下文会越来越长成本和延迟都上去了。我的处理方式是分层记忆短期记忆当前任务的对话历史保留最近 N 轮超出的做摘要。长期记忆把重要的结论、用户偏好存到外部存储需要时检索回来。工作记忆当前任务的中间结果比如已经查到的数据放在一个结构化的 scratchpad 里。关键是别把所有东西都塞进上下文。我见过有 Agent 把整个数据库查询结果都塞进去一次调用几万 token成本爆炸。正确的做法是让 Agent 只保留结论原始数据放外部需要时再查。4.4 Agent 扛并发几个实际的瓶颈点Agent 扛并发比普通 API 难因为它一次任务可能调用多次模型、多次工具。瓶颈通常在这几个地方第一是模型调用的并发限制。供应商一般有 RPM每分钟请求数限制Agent 一次任务可能发十几个请求并发一高就撞限流。解决办法是在网关层做队列把超出的请求排队而不是直接拒绝。第二是工具执行的耗时。有些工具比如查大表很慢Agent 会卡在那里等。解决办法是给工具设超时超时就返回暂时不可用让 Agent 自己决定是重试还是换方案。第三是状态管理。多个 Agent 实例同时跑状态要共享不然会重复劳动。我一般用 Redis 存任务状态加分布式锁防止重复执行。瓶颈点表现解决思路模型限流429 错误增多网关排队 多供应商分流工具超时任务卡住工具级超时 降级返回状态冲突重复执行分布式锁 幂等设计上下文膨胀成本飙升分层记忆 摘要压缩4.5 Agent 安全别让它执行危险操作Agent 能调工具就意味着它能产生副作用。删数据、发消息、改配置这些操作一旦被 Agent 误触发后果严重。我的做法是分级授权只读操作Agent 可以直接执行比如查询、统计。低风险写操作需要二次确认比如发通知、创建任务。高风险操作禁止 Agent 直接执行只能生成建议由人确认后手动执行。另外所有 Agent 的工具调用都要有完整审计日志记录谁、什么时候、调了什么、参数是什么、结果如何。出了问题能追溯。5. 从 Demo 到生产的完整落地路径5.1 阶段划分别想一步到位我见过太多团队想一次性把网关、Agent、CLI 全做完结果拖了半年还没上线。正确的做法是分阶段每个阶段都有可交付的价值。第一阶段统一入口。只做最基础的网关把密钥收上来业务方通过网关调用。这个阶段的目标是能用不追求功能全。大概两周能搞定。第二阶段计量与限流。加上用量统计和配额管理让成本可见可控。这个阶段开始产生管理价值财务和老板会开始关注。第三阶段多供应商与降级。接入第二家供应商做路由和故障转移。这个阶段提升的是稳定性。第四阶段CLI 与自动化。把管理操作 CLI 化接入 Agent 做自动化运维。这个阶段提升的是效率。每个阶段之间可以间隔一两个月边用边迭代。不要为了架构完美而推迟上线生产环境的反馈比任何设计都值钱。5.2 上线前的检查清单网关上线前这几项必须过一遍密钥是否全部收归网关业务侧无残留限流策略是否配置防止单租户打爆全局日志脱敏是否生效抽查几条确认故障转移是否测试手动关掉主供应商验证监控告警是否接入错误率和延迟要有阈值告警回滚方案是否就绪出问题能快速切回直连这份清单我每次上线都会过救过好几次命。特别是故障转移不实际测一遍真出事的时候大概率是坏的。5.3 监控指标盯住这几个数就够了网关的监控不用面面俱到盯住这几个核心指标请求成功率按供应商、按模型拆分低于 99% 就要查。P99 延迟流式和非流式分开看流式看首 token 延迟。token 消耗速率突然飙升可能是被刷或者有 bug。配额使用率接近上限的租户要提前预警。各供应商错误分布某个供应商错误率上升考虑切流。这些指标用 Prometheus Grafana 就能搭起来不用搞太复杂。6. 几个我踩过的真实坑与应对6.1 流式响应下的超时设置设短了会误杀流式请求的耗时可能很长一个长文本生成跑几分钟很正常。如果网关的超时设成 30 秒会把正常请求掐断。我的做法是区分连接超时和读取超时连接超时设短5 秒读取超时设长比如 300 秒并且流式请求每收到一个 chunk 就重置读取超时。这样既不会误杀长请求又能及时发现真正卡死的连接。6.2 供应商返回格式变更导致的解析失败供应商升级 API 是常事有时候悄悄改了返回字段名你的适配层就崩了。应对方式是加防御性解析关键字段取不到时记录原始响应并告警而不是直接抛异常。同时适配层要有单元测试用真实的响应样本做回归。我一般会保存最近一周的响应样本每天跑一次解析测试。6.3 Agent 陷入死循环的终止策略Agent 有时候会陷入调工具、发现不对、再调、还不对的死循环。必须有终止策略最大步数限制 重复检测。最大步数比如 20 步到了就强制结束并返回当前结果。重复检测是看最近几步是不是在调同一个工具、同样的参数如果是就打断。这两个机制能挡住 90% 的死循环。6.4 配额计算的精度问题配额计算涉及浮点数容易出精度问题。比如 token 数累加用 float 加着加着就有误差了。我的做法是全程用整数token 数本来就是整数费用计算最后再转成小数展示。数据库字段也用 BIGINT 存 token 数避免精度丢失。7. 写在最后的一点个人体会这套东西我从零搭到跑顺前后花了大概四个月中间返工过两次。最大的体会是网关的价值不在技术复杂度而在它强迫你把混乱的调用关系理清楚。很多团队不是不会写网关是没意识到需要网关等到出事了才补代价大得多。另外CLI 和 Agent 这块别一上来就追求全自动。我建议先从半自动开始CLI 负责把信息查出来人来做决策跑顺了再让 Agent 接手决策。这样风险可控团队也有个适应过程。全自动听起来酷但真出了事背锅的还是你。最后分享一个我常用的小技巧给网关加一个影子模式新供应商接入时先把流量复制一份过去但不返回给用户对比两边的输出质量和延迟。跑一周没问题再正式切流。这个模式帮我避免了好几次线上事故强烈推荐。
返回列表