拓冰建站拓冰建站
首页 / 资讯中心 / 正文

腾讯云Agent养成记:AI Skills实战与避坑指南

1. Agent 不是开发出来的是养出来的这两年聊 Agent 的文章铺天盖地但真正上手做过的人都会有同感Agent 和传统软件完全不是一回事。传统软件是开发出来的——需求分析、架构设计、编码、测试一条瀑布走完交付一个确定性的系统。Agent 更像是养出来的——你给它一个目标、一套工具、一些边界规则然后在真实环境里不断喂反馈、调行为、补能力它才逐渐变得好用。我在腾讯云上前后折腾了一个多月把一套内部运维辅助 Agent 从能跑通 Demo迭代到基本可信任最大的感受是AI Skills 才是 Agent 能力养成的关键载体。没有 Skills 之前Agent 只是一个会聊天的模型外壳有了 Skills它才真正长出手和脚能去操作服务器、查日志、改配置、做巡检。这篇文章不打算复述官方文档我会把整个养成过程里我认为最有价值的部分拆开讲什么是 AI Skills、为什么它比传统 Function Calling 更适合做复杂 Agent、在腾讯云上怎么一步步搭起来、以及我在实际开发中踩过的坑和总结出的取舍标准。适合谁看如果你正准备用腾讯云做 Agent 类项目或者已经在做但觉得 Agent 行为不可控、能力难扩展这篇文章应该能帮你少走不少弯路。2. 从会聊天到会干活AI Skills 到底解决了什么问题2.1 先认清一个事实模型本身不会干活很多人第一次接触 Agent 时有个误解觉得大模型天生就会做事。实际上一个裸模型的能力上限就是理解意图 生成文本。你说帮我看看服务器负载它能回你一段关于如何查看负载的教程但它没办法真的 SSH 到你的机器上执行uptime。原因很简单模型活在参数空间里你的服务器不在那里。那传统做法是什么Function Calling / Tool Use。你把一批函数定义作为结构化 JSON 传给模型模型根据用户输入决定调用哪个函数、传什么参数然后你的代码去执行函数把结果回传给模型模型再组织语言回复用户。这套机制本身没问题OpenAI 的 tool calls、Claude 的 tool use 都是这个思路。但做到后面你会发现一个尴尬的情况函数列表越来越长模型的判断越来越飘。当你有几十个工具函数时模型在该用哪个工具这件事上的准确率会肉眼可见地下降而且每次请求都要把全部函数定义塞给模型Token 消耗相当可观。2.2 AI Skills 的定位带状态的能力单元腾讯云的 AI Skills 解决的就是这个问题。它不是一个简单的函数注册表而是一个带描述、带参数约束、带执行逻辑、带有限状态控制的能力单元。每个 Skill 都有自己的能力描述什么时候该用它参数 Schema需要哪些输入格式是什么执行逻辑实际去做什么不一定是模型生成而是你写好的确定性代码结果返回格式执行完给模型什么信息模型变成了一个调度中枢它要做的是理解用户目标然后从一组 Skills 里选出合适的组合并编排执行顺序而不是深入到每个工具的技术细节里去。这个转变非常关键。打个比方传统 Function Calling 像你雇了一个实习生你手把手告诉它先打开 Excel选中 A 列筛选大于 100 的行再导出 CSV——每一步都要你说清楚。AI Skills 则像你给这个实习生发了一本《岗位手册》上面写着数据处理这个能力涵盖哪些操作、输入输出是什么样你说一句把数据整理一下它自己知道该翻哪一章。2.3 Skill 和普通工具的本质区别可被理解、可被组合我在热词里看到很多人搜skill和agent的区别skill和agent的区别其实这两个东西不是同一层级的。Agent 是整体目标执行者Skill 是 Agent 的能力单元。没有 Skill 的 Agent 是光杆司令一身想法但没法落地Skill 越多、定义得越好Agent 能覆盖的任务边界就越宽。更重要的一个特性是可组合性。好 Skill 的标准不是功能多而是边界清晰、可被模型理解、可与其他 Skill 拼装。比如我有一个server_inspectSkill 负责采集服务器状态有一个config_diffSkill 负责对比配置差异组合起来就能做巡检之后自动报告配置漂移这种复合任务。模型不需要知道两种 Skill 的内部实现它只需要在目标拆解时把两者串起来。这一点直接决定了 Agent 的天花板。单个 Skill 是手编排逻辑是大脑而 Skills 的边界设计是骨架——骨架歪了后面再怎么填充能力都会别扭。3. 环境准备腾讯云上搭 Agent 运行时的几个决定3.1 服务器、镜像与运行时选型我用的是一台腾讯云轻量应用服务器2核4G 的配置跑 Agent 服务端加一个轻量数据库绰绰有余。操作系统选的 Ubuntu 22.04Docker 方式部署。之所以选 Docker 而不是裸机安装主要是环境隔离和回滚方便——Agent 的依赖更新频繁今天装一个 SDK 明天升一个模型接口版本裸机环境下很容易把系统搞乱Docker 里随便折腾出问题直接重建容器。镜像方面我自己打包了一个基于 Python 3.11 的运行时镜像装好了 FastAPI、OpenAI SDK、腾讯云 API 的 Python 包以及 LangChain 相关的编排库。有人会问为什么不直接用现成的 Agent 框架镜像我的观点是框架可以后加但运行时基础必须自己掌控否则出了问题你连排查的入口都找不到。3.2 模型接入走 API 还是走网关模型推荐直接走腾讯云的大模型服务API 风格兼容 OpenAI 格式迁移成本很低。但要注意生产环境不要每个服务都直连模型 API最好在前面加一层统一的模型网关。我自己用 LiteLLM Proxy 做了一层转发好处非常明显统一管理多个模型的 Key不用在代码里散落明文密钥可以按 Skill 配置不同的模型路由——比如简单分类任务用轻量模型省钱复杂推理任务才调用强模型方便做 Token 计数和成本核算我甚至把 LiteLLM Proxy 也容器化了和 Agent 主服务放在同一个 Docker 网络里内网访问不走公网安全性和响应速度都有保障。3.3 密钥管理与权限模型最容易被忽视的一步在腾讯云上做 Agent免不了要让它操作你的云资源——查服务器列表、改安全组规则、看监控数据等。这时候需要给 Agent 申请腾讯云的 API 密钥。非常重要的一条不要使用主账号密钥一定要创建子账号并只授予最小权限。我为了省事一开始直接用了主账号密钥后来想想都后怕。Agent 的提示词注入风险是真实存在的如果某个 Skill 在处理外部输入时不够严谨攻击者可能通过诱导让 Agent 调用高权限 API。子账号加 CAM 策略限制后即使出了安全问题影响面也被控制在最小范围。密钥的存储方式同样不能马虎。我的做法是放在环境变量文件里Docker 启动时注入而不是写死在代码或配置仓库中。Agent 领域有句实话安全问题通常不出在模型上而出在你给模型的那把钥匙太万能了。4. 第一个实战 Skill让 Agent 学会系统巡检4.1 场景定义与 Skill 拆解为了说清楚整个流程我用一个最典型的运维场景来演示让 Agent 定时巡检服务器并在发现问题时输出结构化报告。这个任务看起来简单但如果你直接写一个巡检函数里面同时包含 CPU、内存、磁盘、网络、进程检查再把结果一股脑丢给模型总结效果一定很烂。原因是输出信息太多太杂模型容易迷失重点而且这样的大而全函数难以复用。正确的做法是拆成多个单一职责的 SkillSkill 名称职责输入输出sys_resource_check采集 CPU/内存/负载服务器 IP、端口资源指标 JSONdisk_usage_check检查磁盘分区占用服务器 IP、告警阈值分区使用率列表service_status_check检查关键服务存活状态服务名列表各服务状态及 PIDreport_builder负责把上述结果汇总成报告模板各检查结果 JSON格式化报告4.2 Skill 定义的具体长什么样以sys_resource_check为例Skill 定义我一般用 YAML 写结构清晰且便于版本管理name: sys_resource_check description: 检查目标服务器的 CPU、内存和系统负载情况用于日常巡检或故障排查。 parameters: type: object properties: host: type: string description: 目标服务器 IP 或主机名 port: type: integer description: SSH 端口默认 22 default: 22 required: - host runtime: type: python entrypoint: run timeout: 30注意description字段。这个字段不是给人看的是给模型看的模型全靠它来判断什么时候该调用这个 Skill。所以要写清楚什么时候用、用了能拿到什么避免模糊表述。4.3 执行逻辑的代码骨架对应的执行代码是一个普通 Python 类核心逻辑就是 SSH 上去执行命令并解析结果import asyncio from asyncssh import connect class SysResourceCheck: async def run(self, host: str, port: int 22): async with connect(host, portport, usernamemonitor, client_keys[/keys/monitor]) as conn: result {} # CPU 负载 uptime await conn.run(uptime) result[load] parse_uptime(uptime.stdout) # 内存 free await conn.run(free -m) result[memory] parse_free(free.stdout) # CPU 核心数 cores await conn.run(nproc) result[cores] int(cores.stdout.strip()) return result代码本身没有太多魔法真正的关键在于返回结果一定要结构化。模型拿到的是干净 JSON而不是一大段人眼都懒得看的终端命令输出。我在实际项目里吃过亏起初直接返回原始命令输出模型有时候会把警告信息当成重要指标报告就偏了。后来严格规定每个 Skill 的输出 schema问题立刻少了很多。4.4 在 Agent 编排里注册这个 SkillSkill 写好后要在 Agent 主服务的配置里注册。我的注册文件长这样{ skills: [ { name: sys_resource_check, source: ./skills/sys_resource_check, enabled: true, models: [default], timeout: 30, retry: 1 } ] }注册之后Agent 启动时会自动加载所有 Skill 的描述信息并在每次对话时把这些描述提交给模型用于意图匹配。这里有个性能上的细节我会在后面专门讲——不是所有 Skill 都需要在每个请求中都提交描述对于数量较多的技能库需要引入索引或分组机制。5. 踩坑实录让 Agent 学会改 Redis 密码的完整排查链路5.1 一个很典型的看起来简单的需求热词里有一条非常接地气的场景主要是我在腾讯云服务器上安装 redis但是我修改 redis 密码之后再重启 redis 就一直不成功。这几乎是我见过最典型的 Agent 实操考题——看似只是改个配置重启服务实际上涉及配置文件解析、权限切换、服务管理、日志排查好几个环节。我拿这个场景做了一个 Skill名字叫redis_config_update目标是修改 Redis 配置项自动验证配置有效性并安全重启服务。开发这个 Skill 的过程不值得细讲但它暴露出来的问题很有代表性我拆成几个具体的坑讲。5.2 坑一配置文件里密码过期机制导致改完等于没改我在开发途中模拟了一个非常阴间的场景用户改了requirepass重启后 Redis 报WRONGPASS但配置明明写的没问题。排查了半天才发现是 Redis 6.0 的 ACL 机制在作怪——requirepass只作用于默认用户如果配置里还定义了其他 ACL 用户或者使用了masteruser之类的高可用参数密码不匹配的情况就会被隐藏。Agent 能不能发现这个如果 Skill 只是机械地改配置然后重启它是发现不了的。所以我给这个 Skill 加了一个配置预检环节重启之前先解析当前 Redis 配置里的 ACL 相关条目对比目标变更如果发现冲突就直接抛错不让 Agent 盲目执行重启。这个经验很重要Skill 的健壮性不体现在执行过程里而体现在对执行前提的校验上。你是在给一个不太懂行的实习生编写操作手册那就得把前置检查当作正式步骤写进去而不是默认操作者什么都懂。5.3 坑二systemd 和服务启动方式不一致导致重启报错腾讯云服务器上有时候 Redis 是源码编译安装的有时候是 apt 安装的还有时候是 Docker 跑的。不同的安装方式对应不同的启停命令apt 安装systemctl restart redis-server源码安装redis-cli shutdownredis-server /path/redis.confDocker 方式docker restart container这个 Skill 一开始只适配了systemctl遇到其他安装方式直接失败。后来我加了一层服务方式探测优先检测是否存在 systemd 服务单元再看有没有 Redis 进程最后看有没有匹配的容器拿到服务操作原语之后再执行对应的重启动作。有一次实测中Agent 在源码安装的 Redis 上执行systemctl restart redis失败后它自己从错误信息里学会了一个操作——先尝试找redis-server进程并 kill 再启动。虽然结果是好的但我立刻意识到这是运气成分如果进程不是 root 启动的kill 权限不够就会卡住。最终我把停机、启动两个动作拆成了独立步骤并给每个步骤注入了需要什么权限、可能遇到什么错误的提示信息。5.4 坑三重启后没有自动验证Agent 误判成功这是我踩过最值得分享的一个坑。最初的 Skill 执行完重启命令就结束了返回已重启。但如果你不验证 Redis 是否真的起来了Agent 就会把假成功当作真成功后续对话里一本正经地告诉用户改好了已生效。这个问题的本质是确定性操作执行完毕 ≠ 目标达成。后来我给 Skill 增加了验证步骤重启之后必须执行redis-cli -a newpassword ping拿到PONG才返回成功同时还要检查进程状态和端口监听情况只有全部通过才标记为SUCCESS。验证项命令预期结果失败处理连通性redis-cli -a $pass pingPONG返回失败附日志片段进程状态ps aux | grep redis-server进程存在返回失败附退出码端口监听ss -lntp | grep 6379端口监听中返回失败附网络状态这个执行后验证的习惯后来我用到了所有会影响系统状态的 Skill 上。改安全组规则后要调接口验证规则是否生效推送 Docker 镜像后要校验 digest没有验证环节的 Skill 就像没有测试的代码——你永远不知道它是不是在假装工作。6. Skill 编排策略什么时候拆什么时候合什么时候该让模型自己编6.1 拆分的边界单一职责但是要避免碎片化Skill 设计最容易走极端。一种极端是功能太粗一个 Skill 包罗万象模型拿到它就像拿了一把瑞士军刀但不知道当前该用哪个刀片另一种极端是拆得太细连获取当前时间都做成一个 Skill模型忙于在几十个 Skill 之间做选择反而忘了用户本来要干什么。我的经验是三个判断标准能不能独立验证。一个 Skill 执行完必须能明确判断成功或失败。如果某个子步骤没法独立验证就说明它不该独立成 Skill。会不会被多个上层任务复用。如果 A 任务和 B 任务都会用到同一个底层操作那这个底层操作就该单独拆出来。描述是否能让模型一眼看懂。给新 Skill 写描述时如果两句话说不清楚它做什么大概率是拆得有问题需要重新划分边界。6.2 编排的进化从固定 DAG 到模型自由组合我做 Agent 的第一版是硬编码工作流——用 LangChain 的SequentialChain把几个 Skill 按固定顺序串好流程完全确定。这样做的好处是可控坏处是一点都不智能同一个流程换个输入条件就卡壳比如如果磁盘没超过阈值就不用跑报告这种简单分支都要写一堆条件判断。后来切到模型自主编排模式我不再制定执行流程只把 Skill 列表交给 Agent 的 Planner 模块让它根据用户请求自己决定调用顺序和组合方式。效果完全是两种级别的体验。举个例子用户说最近服务器老卡帮我查查原因Agent 的决策过程大概是调用sys_resource_check看当前负载发现磁盘占用偏高调用disk_usage_check深入查一下顺着排查到某个日志文件巨大调用log_analyzer看具体是什么在写得出结论生成报告这个链路不是任何人预设的是模型自己根据中间结果动态调整的。这就是 AI Skills 和 Function Calling 最直观的体验差异——Function Calling 是一个点AI Skills 是一张网。6.3 给模型划红线Skill 的权限边界与禁止动作模型自主编排能力越强越需要严格的安全边界约束。我给每个 Skill 的 YAML 定义里加了一个constraints字段明确标注哪些事情不能做constraints: - 禁止在未确认用户意愿时重启生产服务 - 禁止修改防火墙规则中与现有服务相关的条目 - 禁止删除超过 7 天的日志文件 - 所有变更操作必须先执行风险预检有些开发者会觉得这些约束应该写在 System Prompt 里让模型遵守我不反对但强烈建议把安全约束写进 Skill 本身。原因是 System Prompt 太容易被忽略或遗忘而 Skill 的约束信息会随 Skill 一起在每次相关调用时被模型读取命中率要高得多。这就像给一个权限很大的人配了一本履职负面清单比在入职培训时口头讲一遍有效得多。7. 上下文管理Agent 的全能感来自记忆而不是窗口大7.1 对话记忆的分层设计做 Agent 时间长了你会发现用户对 Agent 的最高评价是它居然记得之前的事。这个记得不是靠把聊天记录全塞进上下文窗口而是靠分层记忆设计。我目前的方案是三段式短期记忆当前会话的完整对话记录直接进入上下文用于维持多轮对话的连贯性。工作记忆当前任务的关键信息比如正在操作的服务器 IP、排查中的问题现象、已执行过的操作清单用结构化 JSON 保存在内存或 Redis 缓存中任务结束即清理。长期记忆跨会话的持久化信息比如用户偏好生产环境的变更必须在凌晨执行、历史任务的常见问题、曾经踩过的坑的处理方案等存放在数据库中在会话启动时选择性注入。腾讯云上我用云数据库 MySQL 存长期记忆Redis 做短期缓存。为什么不用向量数据库因为 Agent 的长期记忆大多数是规则型知识而不是语义相似度检索能解决的比如这个用户的服务器偏好是精确匹配信息向量检索反而画蛇添足。7.2 上下文窗口的挤牙膏式管理另一个容易忽略的问题是 Token 上限。大模型的上下文窗口有限Agent 运行时上下文里不仅要放对话记录还要放每个 Skill 的描述和用户请求附带的数据。如果不做管理很快就撑爆了。我的策略是给不同内容排优先级系统指令和当前任务目标最高优先级不可裁剪与当前任务直接相关的 Skill 描述短期记忆里最近几轮对话长期记忆里高相关度的知识历史对话的压缩摘要当上下文接近上限时优先裁剪第 4、5 部分并触发一个摘要压缩动作把旧的对话摘要化只保留关键结论和尚未完成的事项。这个机制让 Agent 在长会话中依然能保持清醒不会聊着聊着忘记最初的任务目标。8. 性能与成本Token 不应该是你最大的账单8.1 Skill 描述的动态加载机制前面提到过Agent 启动时如果把全部 Skill 描述都塞进系统提示词每个请求都在为几十个 Skill 的定义买单——Token 消耗巨大而且模型的选择准确率反而下降。我的做法是两级过滤第一级粗粒度索引。每个 Skill 注册时打上标签如运维数据库网络容器等。用户请求进来后先用一个轻量分类模型判断请求属于哪些标签只加载这些标签下的 Skill 描述。第二级关键词预筛。在标签基础上再做一层关键词重叠检测——比如用户提到 Redis就优先加载 Redis 相关 Skill。这一层可以用传统文本算法实现不消耗模型 Token。这个优化做完单次请求的 Token 消耗大概降了 60% 以上同时模型选错 Skill 的概率也下降了。这算是我在成本控制方面最划算的一笔投入。8.2 Skill 内部的动作编排不是所有步骤都值得调一次模型初学者容易犯的一个错误是万物皆模型——连一个两个数相加的操作也要让模型决定调用什么函数。这既浪费 Token又增加延迟。我的原则是只有需要语义理解、任务拆解、结果总结的场景才调模型纯确定性逻辑直接写在 Skill 内部。比如巡检 Skill 里判断磁盘使用率是否超过 80%是纯代码逻辑不需要模型介入但根据这些指标写一段诊断建议就是模型的职责。这样 Skill 内部可以是一个简单状态机只有必要时刻才和语言模型交互一次。8.3 实测成本数据参考放一组我自己的实测数据供参考使用腾讯云混元大模型标准版Prompt 约 1.2K单次巡检场景优化项优化前优化后平均 Token/请求约 8500约 3400平均响应延迟约 8.2s约 3.5s月成本2000 次请求约 340 元约 136 元Skill 选择准确率约 82%约 94%成本只是一个维度响应延迟的降低带来的体验提升我认为更值。9. 多模型路由与降级策略别把所有鸡蛋放一个篮子里9.1 按任务难度路由到不同模型不同模型的强项和成本差异很大。一个成熟的 Agent 应该能够根据任务难度自动选择模型而不是所有请求都走最强的那个。我的路由策略是这样的意图识别和工具选择阶段用轻量模型如混元 turbo速度快成本低判断个大概足够了。核心推理和执行结果总结阶段用强模型如混元 pro这里需要真正的理解与生成能力。纯代码执行和确定性操作不走模型直接运行 Skill 内的代码。LiteLLM Proxy 在这里帮了大忙它可以配置模型路由规则。我在 Proxy 层写了一个简单的模型选择中间件识别请求体里的stage字段自动路由到对应的模型实例。9.2 模型不可用时的降级路径再稳定的云服务也有概率出问题。我在代理层加了一个降级机制当强模型连不上时自动降级到次一级模型同时给 Agent 返回一个警告标记。Agent 收到这个标记后的行为是对于非关键任务如闲聊、信息查询正常处理即可。对于需要强推理的任务如复杂的故障诊断向用户明确说明当前推理能力受限结果可能有误差。这个机制保障了 Agent 在一次实测中即使混元主模型 API 异常整个服务依然没有挂掉只是部分高难度问题暂时无法处理。对于生产级 Agent这种容错能力我认为比任何花哨功能都重要。10. 养成记Skill 库的持续迭代方法10.1 把每个失败案例变成新的 Skill 或约束Agent 上线只是起点真正的养成发生在日复一日的使用和反馈中。我维护了一个failures/目录每次 Agent 在某类任务上表现不佳我都会做一次复盘把问题归类后转化为改进动作。最常见的结果有三种模型不知道该调用哪个 Skill→ 说明 Skill 描述写得不清晰需要优化描述或拆分边界。模型调对了 Skill 但参数给错→ 说明参数 Schema 不够严格需要增加参数校验或枚举约束。Skill 执行了但结果不对→ 说明 Skill 内部的执行逻辑有 bug 或遗漏边界条件需要补逻辑。这套复盘机制跑了一两个月Agent 的成功率提升非常明显。一开始它连查磁盘空间这种简单活儿都要犯糊涂现在已经能独立处理分析日志定位异常源并给出优化建议这种复合任务了。10.2 版本的回归测试给 Agent 建一个题库Agent 改动最怕的是修好一个问题带崩三个功能。因为模型行为有随机性同一个改动对多个用例的影响很难一次看全。我的做法是维护一组回归测试用例大概四五十条覆盖 Agent 的常见任务。任何 Skill 变更或模型配置调整后先在这组用例上跑一遍对比每条用例的结果是否符合预期。不需要全部通过才上线但要看清楚每个失败项是不是可接受的回归。这套机制让我敢大胆迭代不用担心改坏了什么。而且随着测试用例覆盖的场景越来越多Agent 的质量基线也在稳步提升。11. 最后再分享几个我反复用到的细节Skill 描述要写什么时候该用而不是我是什么。很多文档里的例子喜欢写该工具负责系统监控但模型真正需要的答案是当用户提到服务器慢、负载高、内存不足、CPU 飙高时使用此工具。描述越贴近用户的自然表达模型的选择就越准确。所有对外命令必须做超时控制。SSH 连接可能卡住Docker 操作可能排队。我所有 Skill 的执行逻辑都套了asyncio.wait_for或signal.alarm硬性规定最长执行时间超时就返回错误。没有超时控制的 Skill 是隐形的服务杀手。写日志比什么都重要。Agent 的不确定性意味着你必须能看到它每一步在做什么、为什么这么做。我在编排层打了详细的结构化日志记录每一次模型决策、每一个 Skill 的入参与出参。排查问题时这堆日志就是我唯一的可信依据。这次在腾讯云上做 Agent 的经历最有价值的收获不是代码和配置而是一个认知Agent 的养成没有终点它需要你像带新人一样反复打磨、不断纠偏。AI Skills 提供的是能力单元而把这些能力组织成一个可靠系统的能力才是做 Agent 真正的门槛。希望这篇分享能帮你把这条路走得顺一点。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门