Agent上云最佳实践:腾讯云+模型网关+AI Skills全解析

发布时间:2026/9/7 13:09:20
Agent上云最佳实践:腾讯云+模型网关+AI Skills全解析 最近团队在做一整套 Agent 服务目标很直接让 Agent 不光能聊天还能真正调用工具、做任务编排、处理长流程。前期在本地验证得很顺利但一上云就发现一堆问题——模型接入乱、技能复用差、部署流程散改完这个炸那个。折腾了一圈之后最后落到了“腾讯云基础设施 统一模型网关 技能包设计”的组合上也就是整套 AI Skills 的最佳实践路线。这篇把我们从架构选型到上线压测的完整过程以及中间踩过的坑全部梳理出来给正准备做 Agent 上云的同学一个可复用的参考。先说结论Agent 这个事儿框架选型只占 20%剩下 80% 的功夫都在工程化——模型出入口统一、Skill 拆分粒度、云端部署规范、状态持久化哪一块偷懒上线之后都会找补回来。1. 先定架构Agent、Skill、模型网关的边界到底怎么切1.1 Agent 不是“一个模型”而是一套系统很多人刚接触 Agent 开发第一反应是“找个聪明的模型把提示词写长一点”但真正做生产级 Agent 的时候这个思路会立刻撞墙。原因很简单大模型本身的职责是理解和生成而 Agent 的核心价值在“行动”——它要能读外部输入、调内部工具、记上下文、判断下一步做什么这些都不是模型单独能完成的。我当时画的系统边界是这样的模型层负责自然语言理解、推理、生成可以接不同的模型来平衡成本和质量。Agent 层负责任务解析、规划、工具调度、记忆管理是整个系统的大脑。Skill 层封装具体的能力比如查订单、发消息、算数学、检索知识库对外暴露统一的参数接口。基础设施层跑在云上包括服务器、容器、数据库、网络策略、域名证书。这套分层的好处是每一层都能独立演进。模型层今天用 A 家的明天发现 B 家更强换起来不需要动其他层Skill 层新增能力只需要按规范写一个技能包Agent 层代码不用改基础设施层做弹性扩容也不影响业务逻辑。1.2 Skill 和 Agent 的分工千万别把两者混为一谈热搜词列表里有个很典型的问题“skill 和 agent 的区别”。我们做第一版时也犯过这个错——把所有功能一股脑塞进 Agent 的逻辑里结果每个 Agent 都是“巨无霸”改一个功能要全量回归。后面我把它拆清楚了Agent是“调度者”负责理解用户意图、拆解步骤、决定调哪个 Skill、汇总结果。Skill是“执行者”负责具体的某个能力输入输出都是结构化的不关心用户的话术。用生活中的例子来类比Agent 是餐厅的前厅经理客人说要“一桌适合素食者的晚餐预算 300 以内”经理要拆解出位置、素食、预算三个条件然后分别叫后厨素食菜单 Skill、订位系统座位查询 Skill、收银台预算计算 Skill去处理。经理不需要自己会炒菜但他知道什么情况该叫哪个后厨。这个边界的直接收益是新加能力不用改 Agent 核心逻辑只写一个新 Skill 注册进去就行。这也是“AI Skills 最佳实践”里最重要的一条原则。1.3 为什么承载层选了腾讯云而不是继续本地跑本地开发环境跑通后我考虑过是否要自建机房或直接用裸金属但算了一笔账就放弃了模型侧网关需要稳定公网入口家里的网络和 IP 稳定性不够。Agent 要部署成可对外服务的形态必须有像样的域名、证书和端口管理。团队协作开发时测试环境、生产环境需要隔离本地搞这一套运维成本太高。腾讯云在这套架构里的定位是“承载底座”具体用到几类东西云服务器跑 Agent 主服务和模型网关容器镜像服务做 Skill 的打包分发二级域名和 HTTPS 证书统一入口Redis 做记忆和会话存储。下面按这几个模块逐个讲最佳实践。2. 云上环境准备服务器、域名、端口、镜像四个容易被细节卡住的地方2.1 服务器规格与镜像选型建议我们的 Agent 服务主要消耗在两部分模型网关的并发转发、Agent 主服务的逻辑编排。这两者都是 CPU 密集和内存敏感的GPU 倒不是必需品推理不在本地。所以我选了4核8G的配置起步系统镜像直接用Ubuntu 22.04 LTS。这里有个经验别一上来就买最大配也别买最小配。太小了跑几个 Docker 容器就内存告急太大了前期成本浪费。4核8G 足够支撑几百个并发请求的网关转发和几十个 Skill 同时调度真正不够时再横向加机器比一开始就上 16核32G 划算得多。我们当时跑 LiteLLM Proxy 和 Agent 主服务、Redis 容器总共内存占用在 5G 左右负载很健康。2.2 开放端口与安全组的正确姿势热搜词里有“腾讯云如何开放所有端口”这个我必须拎出来劝一句千万不要为省事直接放通全部端口。云服务器的安全组本质上是你的第一道防火墙全放通等于把自己裸奔在公网上早晚会被扫描和爆破盯上。正确做法是只开放需要公网访问的端口。比如 HTTP/HTTPS 的 80/443以及模型网关可能用到的自定义端口比如 4000。管理端口SSH只对办公网 IP 开放或者至少把默认端口改掉再配合密钥登录禁止密码登录。内网组件Redis、数据库不绑定公网也不要在安全组里放通。它们只能被同一私有网络内的应用访问。我在腾讯云控制台配安全组的实际规则是这样用途协议端口来源说明HTTPSTCP4430.0.0.0/0对外 HTTPS 入口HTTPTCP800.0.0.0/0可做 301 跳转到 HTTPS网关服务TCP40000.0.0.0/0LiteLLM Proxy 对外端口SSHTCP22公司固定公网 IP管理员远程登录每一条规则都要能说清用途配完截图留存。这样即使后面被人扫到端口也不至于直接被打穿。2.3 二级域名申请与 HTTPS 证书配置域名这块热搜词里有“腾讯云怎么申请二级域名”。实操流程其实不复杂但容易在“解析”和“证书”两步踩坑。我们的主域名有一个在腾讯云备案过的根域二级域名做的事情如下添加解析记录在 DNS 解析控制台给agent.example.com添加一条 A 记录指向云服务器的公网 IP。等待生效TTL 默认 600 秒一般几分钟内就能解析成功。用ping或者nslookup验证是否已经指向目标 IP。申请免费证书腾讯云有免费的 HTTPS 证书申请时验证域名归属。推荐用DNS 验证它会给你一条 TXT 记录添加到解析里等它校验通过即可。下载证书部署到 Nginx证书会给你pem和key两个文件放到服务器上在 Nginx 配置里指定ssl_certificate和ssl_certificate_key即可。这一步的关键提醒证书申请下来后一定要记得在到期前续期免费证书一般有效期一年。建议在手机上设个日历提醒或者写一个定时任务自动检测证书有效期避免过期导致整个 Agent 服务在用户端报“不安全连接”。2.4 容器镜像服务Docker 推送的正确流程Skill 以容器方式部署是我最推荐的方式因为隔离性好、依赖打包干净、扩容也方便。热搜词里“docker推送到腾讯云容器镜像服务”是这个流程的关键词。我当时的操作流程# 1. 登录腾讯云容器镜像服务 docker login ccr.ccs.tencentyun.com --username 你的腾讯云账号ID # 2. 给本地镜像打标签指向你的命名空间和仓库 docker tag agent-skill-order:latest ccr.ccs.tencentyun.com/your_namespace/agent-skill-order:latest # 3. 推送 docker push ccr.ccs.tencentyun.com/your_namespace/agent-skill-order:latest # 4. 服务器上拉取 docker pull ccr.ccs.tencentyun.com/your_namespace/agent-skill-order:latest # 5. 运行 docker run -d --name agent-skill-order --network my-agent-network \ -e REDIS_URLredis://internal-redis:6379 \ ccr.ccs.tencentyun.com/your_namespace/agent-skill-order:latest镜像仓库这里有一个点值得警惕登录凭证不要直接写在 Dockerfile 或命令历史里。腾讯云容器镜像服务的临时登录密码有效期很短但如果你用手动docker login凭证会缓存在服务器上。建议用专门的部署账号并把密码放到环境变量或密钥管理服务中发布流程通过 CI/CD 执行而不是每次手动登录。3. 模型接入统一入口LiteLLM Proxy 部署与最佳实践3.1 为什么中间要挡一层模型网关团队开发 Agent 的时候最痛苦的事不是写逻辑而是“模型接入到处都是”。有的 Skill 直接调 OpenAI 接口有的调国内模型商的接口有的走阿里云百炼代码里到处都是不同的 SDK、不同的鉴权方式、不同的超时处理。等你要给 Agent 换一个主力模型等于全项目大改。LiteLLM Proxy 解决的就是这个问题它把各种模型提供方的接口统一成一个 OpenAI 兼容的入口你只需要在它的配置里声明每个模型对应的 provider、api_key、model 名称之后所有代码都只面向这个代理调用。这个思路跟“数据库连接池”很像——应用不直接连各种数据库而是统一走连接池换数据库只需改连接池配置应用代码几乎不动。模型网关就是模型层的连接池。3.2 一份可直接抄作业的 proxy 配置我们用的 LiteLLM Proxy 配置核心大概长这样省略真实的 keymodel_list: - model_name: gpt-4o-mini litellm_params: model: gpt-4o-mini api_key: sk-your-key api_base: https://your-openai-compatible-endpoint - model_name: deepseek-chat litellm_params: model: deepseek/deepseek-chat api_key: sk-your-deepseek-key - model_name: qwen-plus litellm_params: model: openai/qwen-plus api_key: sk-your-qwen-key api_base: https://dashscope.aliyuncs.com/compatible-mode/v1 litellm_settings: drop_params: true set_verbose: false general_settings: master_key: sk-my-master-key database_url: postgresql://...几个要重点说明的配置项model_name是暴露给上层应用的别名litellm_params是真正路由需要的信息。这样上层 Agent 在代码里只写gpt-4o-mini或deepseek-chat后面要换供应商改配置重启代理即可应用层零改动。master_key相当于网关的管理员密码上层应用调用时在 header 里带上Authorization: Bearer sk-my-master-key。database_url用来存调用日志和预算数据建议配一个不然你很难知道每个 Skill 烧了多少 token、哪个模型经常超时。启动命令很直接docker run -d --name litellm-proxy \ -p 4000:4000 \ -v $(pwd)/config.yaml:/app/config.yaml \ ghcr.io/berriai/litellm:main-latest \ --config /app/config.yaml启动日志里看到Uvicorn running on http://0.0.0.0:4000说明网关已经就绪。用 curl 验证一下curl http://your-server-ip:4000/v1/models \ -H Authorization: Bearer sk-my-master-key能返回模型列表就说明代理正常工作。3.3 模型网关的优化与容错配置LiteLLM Proxy 能做的远不止“转发”。我在实践里比较依赖这几个能力成本控制可以在配置里设置每个模型的最大预算、每分钟请求数上限防止某个 Skill 出现 bug 时无限调用模型烧钱。负载均衡同一个模型配置多个 keyLiteLLM 会自动轮询和故障转移某个 key 配额用完了自动切下一个。重试与超时针对波动比较大的模型供应商设置合理的重试次数比如 2 次重试有指数退避避免流量高峰时雪崩。统一观测所有请求日志都从网关走可以按 Skill 维度统计 token 消耗、延迟、错误率。这个数据对后续优化 Skill 的提示词和参数非常关键。网关部署在腾讯云服务器上之后其他 Skill 容器访问它的地址就是http://litellm-proxy:4000这种容器间网络地址前提是你把它们放在同一个 Docker 网络里。这一点在编排的时候要提前规划好别各跑各的 bridge 网络后面联调互相访问不到。4. 从“能跑”到“好用”AI Skills 的设计与编排经验4.1 Skill 的最小闭环一个技能包该包含什么AI Skills 这个词在不同语境下含义略有差异但在我这套架构里一个 Skill 就是一个独立部署、暴露统一接口的能力单元。它内部可以调模型、可以写代码、可以访问数据库但对外只做一件事接收结构化输入返回结构化输出。我们用一个查询物流的 Skill 举例。它接收的参数是订单号返回的是物流轨迹。定义参数的时候用 JSON SchemaAgent 层根据这个 Schema 自动生成调用参数{ name: query_logistics, description: 查询订单物流轨迹, parameters: { type: object, properties: { order_id: { type: string, description: 订单号例如 SF1234567890 } }, required: [order_id] } }这里最考验设计功力的是description 字段。大模型不是程序员它不懂你的参数含义它靠 description 来理解应该传什么。比如上例中“订单号例如 SF1234567890”模型看到示例值就能更准确地从用户对话里提取参数。如果 description 写得太抽象模型就容易传错参数。Skill 内部实现则无拘无束Python、Node.js、甚至一个 shell 脚本都行只要按照约定监听请求、返回 JSON。我们统一用 FastAPI 写因为自动生成的接口文档能直接给调试用。4.2 技能路由Agent 怎么知道该调哪个 SkillAgent 要能工作就得有一个“能力注册表”——告诉它现在有哪些 Skill 可用。这个注册表本质上就是上面那种 JSON 描述Agent 层的实现是把用户意图和所有 Skill 的描述一起交给模型让模型判断调用哪个并产出参数。这个机制叫function calling / tool use。很多框架已经封装好了但它的上限不在于框架而在于 Skill 描述写得好不好。我们一开始吃过亏技能描述写得太笼统比如“查询订单”模型经常不知道该用哪个订单接口后来把所有 Skill 的 description 改成“何时应该调用 关键参数说明 示例”路由准确率从 70% 提到 95% 左右。这里有一个通用的写法模板可以套用当用户提到 业务动作 且满足 条件 时调用本技能。 参数 paramA 对应 用户说法里的什么信息。 示例用户说 “帮我查下订单 SF1234567890 到哪了”此时 order_id SF1234567890。描述越具体模型的判断越稳。这不是玄学而是大模型对“语义匹配”天然擅长你把匹配需要的语义信息给它它就能准确匹配。4.3 长任务编排多 Skill 如何串成一条流水线单技能路由解决的是“一次调用”但真正的 Agent 场景往往是多步编排。比如用户说“帮我把昨天订单里没发货的整理成表格并统计各物流公司的延误率”这个需求至少要三步调订单查询 Skill筛选出昨天未发货订单调物流查询 Skill批量获得每个订单的物流状态调数据分析 Skill汇总统计并生成表格。我用的是Step 模式给每个 Skill 定义输入、输出从上一步的输出里提取下一步需要的参数。编排层写成一个 DAG有向无环图描述Agent 根据用户意图动态选择路径。这里要特别注意中间结果的传递。上一步输出的是一个 JSON下一步需要从里面提取字段如果 Skill 返回格式不统一编排层就要写大量胶水代码。所以我们的规范是所有 Skill 返回值必须是{ status: ..., data: ..., message: ... }三层结构这样编排层只用关心data字段处理逻辑统一新增 Skill 基本不需要改编排代码。4.4 调试与测试的实操姿势Skill 开发中大家容易低估测试的复杂度。我之前吃过亏本地单测全通过一接 Agent 就怎么调都不对。后面总结了一套层次化测试方法单元测试给 Skill 构造各种边界输入验证输出格式正确。模型调度测试用一组典型的用户话术验证 Agent 是否准确路由到目标 Skill这一步最容易发现 description 写得不清楚的问题。全链路测试用户话术 - Agent 规划 - 多 Skill 编排 - 结果返回完整跑通记录耗时和中间每一步的输入输出。日志是整个调试的救命稻草。我们每个 Skill 的容器标准输出里都会打一行结构化日志包含请求 ID、Skill 名称、入参、出参、耗时配合腾讯云日志服务收集debug 的时候按请求 ID 一拉就出来完整链路。5. 记忆与状态持久化Redis 配置踩坑与正确方案5.1 记忆方案选型为什么最终落到 RedisAgent 要表现出“记忆力”核心是要有一个存储会话状态的地方。这个状态包括用户的长期偏好、当前多轮对话的上下文、某个长任务的执行进度。方案对比下来Redis 是最合适的中间方案内存读写快延迟到毫秒级不会拖慢 Agent 的响应。支持 TTL 过期会话数据可以自动清理不用手动删。数据结构丰富Hash 存会话、List 存历史记录、String 直接做缓存都能用上。部署简单一个 Docker 容器搞定腾讯云服务器内网直连没有额外成本。5.2 一个让我头疼一下午的坑修改 Redis 密码后重启失败热搜词里有一条很接地气“主要是我在腾讯云服务器上安装 redis但是我修改 redis 密码之后再重启 redis 就一直不……”——这正好是我踩过的同一个坑。事情是这样的Redis 默认配置里requirepass是空的客户端连接不需要密码。我修改配置加上密码后重启 Redis表面上看服务起来了但客户端连的时候一直报NOAUTH Authentication required。更诡异的是有一回配置改了之后 Redis 直接起不来了服务状态反复重启失败。根因有两个都很典型第一Redis 配置文件的权限和路径问题。如果你用systemctl管理 Redis配置文件通常要求属主是 redis 用户且权限不能被其他用户写。如果我在改配置时不小心用了错误的文件权限或者改了错误的配置文件路径Redis 启动时会拒绝加载。第二启用了保护模式。Redis 默认protected-mode yes在没有设置密码且绑定了公网地址时它只允许本机回环地址访问。我设置了bind 0.0.0.0但密码没配对日志里会频繁出现拒绝连接的记录看起来就像“重启后一直不行”。排查链路我从日志入手journalctl -u redis-server --no-pager -n 100日志里如果看到Configuration file /etc/redis/redis.conf的存在但无法解析或# Warning: requirepass is empty基本就是密码和绑定的问题。正确做法是# 1. 编辑配置文件 vim /etc/redis/redis.conf # 修改如下内容 bind 127.0.0.1 ::1 protected-mode yes requirepass 你的强密码这里最关键的修改是把 bind 设为 127.0.0.1而不是 0.0.0.0。原因很简单——Redis 不需要对公网暴露Agent 服务和 Skill 容器都在同一台服务器或同一内网通过容器的内网 IP 访问即可。绑定回环地址 开启保护模式 设置密码三层防护一起做才是稳妥的组合。然后重启并验证redis-cli -a 你的强密码 ping # 返回 PONG 即正常如果你是在 Docker 里跑 Redis那么要注意容器端口映射别直接-p 6379:6379暴露到公网正确做法是只让其他容器通过--network my-agent-network访问端口不映射到宿主机除非你确认安全组做了限制。5.3 会话设计与 TTL 策略Redis 配置好了之后还涉及会话结构怎么设计。我用的方案是Key 模式存储内容TTLsession:{session_id}多轮对话上下文30 分钟memory:{user_id}用户长期偏好30 天task:{task_id}长任务执行进度2 小时多轮对话上下文设置 30 分钟过期是因为超过这个时间用户大概率已经没在继续同一话题留着占内存没必要。用户长期偏好设 30 天覆盖“每次来都能记住我”的体验。这里有个技巧更新上下文时用 Hash 的 HGETALL HSET而不是读出来再整个覆盖。并发场景下如果两个请求同时写一个 key后写的会覆盖先写的导致上下文丢失。用 Hash 按字段更新能显著降低冲突概率。6. 上线前必看典型错误与安全加固清单6.1 “execution terminated due to error”长任务的隐藏杀手上线后最常碰到的报错之一就是agent execution terminated due to error。这句话翻译过来是Agent 在执行某个步骤时抛了异常整个会话中断了。常见触发场景Skill 接口超时Agent 等待 Skill 返回结果等超了直接终止。特别是调用外部 API 的 Skill如果外部服务不稳定很容易触发。参数解析失败模型返回的 tool_calls 参数是非法 JSON或者校验不通过Agent 无法继续。中间结果过大某一步返回了超大 JSON比如列表全量数据模型上下文塞不下报错终止。循环调用Agent 在一个步骤上反复调用同一个 Skill达到最大迭代次数后异常退出。逐个拆解对策给每个 Skill 调用设置超时和重试。超时设定在 10 秒以内重试 2 次还不行就降级返回“暂时无法处理”不要硬等。在 Agent 解析模型输出时做容错若 JSON 解析失败把原文截取一段重新让模型修正最多重试 1 次再失败就明确告知用户。给中间结果做截断和摘要。超过一定长度的 JSON先摘要再传给模型保留关键字段牺牲一点细节换稳定性。限制最大迭代步数比如 20 步超出就优雅结束并给出部分结果而不是让用户等一个永无止境的循环。日志层面要把每一步的耗时、token 数、调用是否成功都记录下来。这样出了terminated due to error你能快速定位是哪一步出的问题而不是面对一个黑盒。6.2 安全加固Agent 上云不能裸奔Agent 会对外暴露两个风险面HTTP 接口和内部基础设施。安全加固我从这两条线分别做对外接口层面鉴权网关必须校验请求头里的 Bearer token无 token 请求直接拒绝。频率限制按用户或 IP 限流防止被刷调用成本。LiteLLM Proxy 自带 rate limit 配置可以按模型维度设置。输入过滤对用户输入做敏感词检测和长度限制防止恶意长文本塞爆上下文、防提示词注入。内部基础设施层面数据库和 Redis 不绑定公网只在内网被服务访问安全组不放通数据库端口。所有管理端口用密钥登录不用密码登录。密码容易被爆破密钥对的安全性高得多。容器最小权限Skill 容器不要用 root 跑创建一个低权限用户执行挂载目录只读为主避免容器内被篡改。密钥管理API key、Redis 密码不要硬编码在代码或环境变量里用密钥管理服务统一存和轮换。6.3 上线后的监控与压测建议最后上线前建议做一轮压测。方法很简单用 wrk 或 JMeter 对网关接口发起并发请求重点观察100 并发时代理层响应延迟的 P95内存和 CPU 占用是否线性增长长时间跑是否出现内存泄漏。我压测的时候发现一个有意思的情况很多模型的并发瓶颈不在服务器而在模型供应商的限流。不像传统 Web 服务压测主要看服务端性能Agent 服务的瓶颈链条更长从网关到模型提供商再到 Skill 容器任何一环卡住都影响整体。所以压测时要把mock 模型和真实模型分组测先排除网关和 Skill 的自身瓶颈再测真实模型的极限在哪个并发量。监控指标建议至少覆盖这四项请求量、错误率、P95 延迟、模型 token 消耗。腾讯云自带的监控面板就能配不用额外搭 Prometheus但如果你想做更细致的按 Skill 维度统计那还是得在日志上多做文章。写到这里这套基于腾讯云的“AI Skills 最佳实践”基本算完整了。从架构分层、模型网关、技能包设计到 Redis 记忆、安全加固每一块都是踩过坑之后沉淀下来的。最后再分享一个我个人的体会Agent 项目最容易失控的地方不在技术而在“边界”。什么该交给模型推理什么该交给 Skill 精确执行什么该在网关层收口这三条线划清楚整个系统就稳了。后续如果有时间我还打算把多 Skill 编排的可视化调试、以及基于调用日志的 Skill 自动优化这两个方向再做深一点到时候再来更新。