全能 Agent 养成记 腾讯云 AI Skills 最佳实践做 Agent 开发踩了大半年坑之后我现在的感受就一句话模型能力决定 Agent 的下限工具管理方式才决定 Agent 的上限。早期我写 Agent所有工具函数就是一把梭往代码里塞什么查数据库、发通知、读日志、调 API全堆在一个 service 层里。结果 prompt 越写越长工具描述越来越混乱模型经常在多轮对话里调错函数、传错参数。后来接触到腾讯云 AI Skills才意识到把工具升级成能力把能力沉淀成技能才是 Agent 工程化该有的思路。这篇文章我把在腾讯云上从零搭建 AI Skills、再把它接入到 Agent 工作流里的完整过程记录下来包括目录结构怎么设计、Schema 怎么写才不会被模型误用、本地调试和云端部署分别怎么落地、以及我实测遇到的一堆报错和排查思路。适合三种人看正在做 Agent 原型开发的、准备把 Agent 推到生产环境但被工具管理搞到头疼的、还有想搞明白腾讯云 AI Skills 到底能解决什么问题的。1. Agent 开发最大的坑不是模型是工具管理1.1 我早期项目里踩过的三个经典问题第一个问题是函数爆炸。Agent 一接业务工具函数从三五个涨到三五十个非常快。每个函数都要写 description、参数说明、返回值示例prompt 里塞得密密麻麻。模型上下文窗口有限工具描述太多的时候它反而会忽略掉关键函数直接凭幻觉瞎编一个结果。第二个问题是参数错乱。函数一多参数命名就容易撞车。比如时间范围这个参数有的函数叫start_time有的叫begin_date模型切换上下文的时候经常把别的函数参数带过来。轻则报错重试重则直接调用了错误的接口改了一堆不该改的数据。第三个问题是逻辑耦合。很多 Agent 框架把工具调用逻辑写在主进程里和业务代码搅在一起。一旦某个工具升级或者接口变更整个 Agent 都要跟着改回归测试一遍难受得要命。1.2 AI Skills 到底是什么它和普通函数调用有什么不同腾讯云 AI Skills 本质上是一个可独立部署、可被模型自动发现和调用的函数单元。你可以把任何一段能力封装成 Skill——不管是查数据库、算指标、发请求还是操作云资源——然后通过一套规范化的描述文件告诉模型这个 Skill 是干什么的、什么时候调用它、参数是什么格式、返回值长什么样。和普通函数调用比AI Skills 最大的区别在于三层解耦。第一层描述与实现解耦。函数的逻辑写在代码里而这个函数什么时候该被调用是写在 Skill 描述文件里的。模型看到一个 Skill 的描述就能决定是否调用它不需要理解内部代码。第二层本地与云端解耦。Skill 可以本地调试也可以打包部署到腾讯云上Agent 通过 HTTP 调用来触发不需要把 Skill 代码塞进 Agent 进程。第三层权限与逻辑解耦。Skill 可以在云端配置独立权限Agent 即使被注入恶意 prompt也只能调用授权范围内的 Skill不能顺手把你的数据库删了。对 Agent 开发来说这个抽象层级非常关键。你不需要再手工维护一份超大的 tools 列表塞到 prompt 里模型需要什么能力它会在 Skill 列表里自己找。该查天气的时候查天气该调内部接口的时候调内部接口上下文干净多了。2. 环境准备腾讯云账号、基础资源与本地开发环境2.1 账号注册与实名认证的避坑要点注册腾讯云账号没什么好说的官网走一遍流程就行。但我建议你从第一天就用子账号开发别用主账号直接跑调试。原因很现实AI Skills 调试期间免不了要创建、删除、更新各种资源主账号权限太大不小心误删了生产资源哭都来不及。我自己的做法是创建一个开发者子账号授权范围限定在需要用到的产品对象存储、容器服务、云函数等然后把 API 密钥单独生成一份放在本地环境变量里。这样即使密钥意外泄露攻击者能拿到的最多也就是那几个测试资源影响面可控。还有个小坑新注册账号在首次开发时经常遇到当前网络环境异常之类的提示这多半是风控拦截不是账号问题。换个网络环境或者过一段时间再试通常能解决。别反复高频触发验证容易被临时冻结。2.2 提前规划资源对象存储、二级域名与端口在开始写 Skill 代码之前有几个配套资源建议先规划好。对象存储COS桶是必须的。AI Skills 打包产物、依赖的静态文件、测试数据集我习惯统一放在一个 COS 桶里管理版本号用目录区分。好处是后续部署时可以直接从 COS 拉取产物不会因为本地文件丢失导致线上无法复现。二级域名这个很多人忽略但实际部署 Skill 回调、配置 webhook、给 Agent 提供稳定的调用入口时一个独立的二级域名非常实用。申请流程很简单在域名解析控制台添加一条记录把二级域名解析到云服务器的公网 IP等 DNS 生效就行。我推荐用skill.你的主域名.com这种命名一眼就能看出是干 Agent 的外呼入口。端口就更值得注意了。很多教程让你开放所有端口方便调试我强烈不建议这么干。我踩过的坑是为了省事放开防火墙结果服务器被扫描爆破被厂商告警整改。正确的做法是只对 Skill 实际需要监听的端口放行比如 3000、8080、443 这几个常见的而且尽量用 HTTPS 协议接入既安全又省后面配置回调的麻烦。2.3 本地开发环境与 SDK 安装本地环境我用的组合是Python 3.10 Node.js 18两个运行时都装好因为不同 Skills 可能用不同语言实现。Git 做版本管理Docker 做本地模拟运行。腾讯云相关 SDK 直接 pip 安装pip install tencentcloud-sdk-python common pip install cos-python-sdk-v5Node 环境下就用 npm 安装对应的 tencentcloud/ 包。装好之后把你的 SecretId 和 SecretKey 配置到环境变量里建议用.env文件管理不要直接写死在代码中。我平时还会装一个dotenv库本地调试时自动加载环境变量部署到云端后改为从控制台的环境变量配置读取代码里不需要任何改动。3. 从零构建一个 AI Skills完整实操流程3.1 Skill 的目录结构与核心配置文件我以一个真实的例子来讲做一个服务器状态巡检的 AI Skill让 Agent 在收到看看现在服务器怎么样这类指令时自动调用 Skill 去拉取 CPU、内存、磁盘等指标并返回摘要。一个标准的腾讯云 AI Skills 项目目录结构长这样server-inspector-skill/ ├── skill.yaml # Skill 核心描述文件 ├── schema.json # 输入输出参数 Schema ├── requirements.txt # Python 依赖 ├── main.py # 核心逻辑入口 ├── utils.py # 辅助函数 ├── tests/ │ └── test_main.py └── README.mdskill.yaml是这个 Skill 的身份证也是模型判断什么时候该调它的依据。我写得最认真的就是里面这一段描述信息name: server_inspector version: 1.0.0 description: | 用于检查服务器当前运行状态的技能。 当用户询问服务器健康度、CPU 使用率、内存占用、磁盘空间、负载情况时 可调用此技能。技能会自动收集关键指标并以结构化摘要返回。 runtime: python3.10 entry: main.handler timeout: 15注意 description 里的写法我会刻意写清楚什么时候该调用它和它返回什么样子这两个信息是模型做工具选择时的核心依据。太笼统的描述比如服务器检查模型容易用它去答无关问题太冗长的描述又浪费 token 还干扰判断。这叫技能发现优化属于 prompt 工程在 Skill 描述层面的延伸后面会专门讲。3.2 定义输入输出 Schema给 LLM 一张使用说明书Schema 是我认为最值得花时间的部分。模型能不能正确调用 Skill、能不能传对参数基本全靠 Schema 写得是否清晰。我的schema.json长这样{ name: server_inspector, description: 采集服务器关键运行指标返回 CPU、内存、磁盘和负载摘要, input: { type: object, properties: { server_ip: { type: string, description: 目标服务器 IP 地址必填形如 1.2.3.4 }, metrics: { type: array, items: { type: string, enum: [cpu, memory, disk, load] }, description: 需要采集的指标列表默认全部采集 }, duration: { type: integer, description: 指标统计时长秒表示最近多少秒的数据默认 60 } }, required: [server_ip] }, output: { type: object, properties: { status: { type: string, enum: [healthy, warning, critical] }, metrics_detail: { type: object, description: 各指标的具体数值 }, summary: { type: string, description: 简洁的中文摘要适合直接展示给用户 } } } }写 Schema 有三个实操心得。第一参数描述一定要写明格式和示例值形如 1.2.3.4这种提示能显著降低模型传错格式的概率。第二用枚举值限制可选范围比如指标列表只能从那几个里面选模型就不会传一个memory_usage_details这种你代码里根本不支持的指标名。第三必填字段要克制非必要不设必填给模型一点容错空间否则它为了满足必填项会编造参数。3.3 实现核心逻辑以服务器状态巡检为例main.py的核心逻辑我习惯写成校验参数—采集指标—计算状态—组织返回四步import json import psutil from datetime import datetime def handler(event, context): # 1. 解析并校验参数 payload event.get(payload, event) server_ip payload.get(server_ip) if not server_ip: return {status: error, message: 缺少参数 server_ip} # 2. 采集指标示例用本机 psutil实际可改为远程采集 cpu_percent psutil.cpu_percent(interval1) mem psutil.virtual_memory() disk psutil.disk_usage(/) load_avg psutil.getloadavg() # 3. 根据阈值计算健康状态 status healthy if cpu_percent 85 or mem.percent 85 or disk.percent 90: status warning if cpu_percent 95 or mem.percent 95: status critical # 4. 组织结构化返回 return { status: status, metrics_detail: { cpu_percent: cpu_percent, memory_percent: mem.percent, disk_percent: disk.percent, load_avg: [round(x, 2) for x in load_avg] }, summary: f服务器 {server_ip} 当前状态{status}。 fCPU 使用率 {cpu_percent}%内存 {mem.percent}% f磁盘 {disk.percent}%负载 {load_avg[0]:.2f}。 }这里有一个取舍实际生产环境我需要采集的是云上多台服务器不是本机。但我故意用了psutil做本机演示因为这样任何人都能跑起来。真正上生产时通常有两种改造方式一种是在 Skill 里用云厂商的监控 API 拉指标另一种是通过 SSH 或者 Agent 下发采集命令到目标机器上。两种方式我都试过如果你的服务器数量少于 20 台用云监控 API 最省事超过 20 台建议上专业的监控系统不要用这种每次临时拉取的方案费时费力。3.4 本地调试离线模拟与日志观察技巧Skill 写完之后先别急着部署在本地先模拟跑一遍。我一般会写一个调试脚本模拟云端的调用事件# debug_local.py import json from main import handler test_event { payload: { server_ip: 127.0.0.1, metrics: [cpu, memory, disk, load], duration: 30 } } result handler(test_event, {}) print(json.dumps(result, ensure_asciiFalse, indent2))跑一下看返回是否正常。这里推荐一个调试原则先测正常参数再测异常参数。比如不传metrics字段、传一个不存在的指标、server_ip传空字符串这些边界情况都要覆盖到。因为模型在真实调用时什么鬼参数都可能给你传出来你的 Skill 必须在参数不完美时也能优雅报错而不是抛一个堆栈让 Agent 一脸懵。本地调试时日志也很重要。我在代码里加了很多print或者logging部署到云端后这些日志会自动上报到日志服务里排查问题的时候非常关键。建议在每一个分支判断处都打一条日志比如参数校验通过开始采集 CPU磁盘使用率异常这种信息越细后面定位越准。3.5 打包上传与版本管理本地跑通之后把 Skill 打成 zip 包上传到腾讯云。我的打包命令是mkdir -p build/server_inspector cp main.py utils.py requirements.txt schema.json skill.yaml build/server_inspector/ cd build zip -r server_inspector.zip server_inspector/上传之后控制台会自动校验skill.yaml的格式并测试入口函数能否被正常加载。这个环节如果报错90% 是依赖缺失或者目录结构不对。比如requirements.txt里的包名没对上或者入口路径写成了main.handler但文件实际叫server.py。版本管理我习惯这样做每次修改代码后skill.yaml里的 version 递增一位同时在 COS 的对应目录保留历史产物。这样 Agent 在调用 Skill 时如果发现新版有问题我可以快速回退到上一个版本。这里提一句我在把 Skill 部署到容器镜像服务的实践里也用同样的思路管镜像版本latest标签永远只指代当前稳定的版本避免测试版本被误拉。4. Agent 与 AI Skills 的编排实战打造全能体验4.1 单 Skill 调用与多 Skill 路由的选择Skill 建好之后真正的重头戏是 Agent 怎么用。初期接入可以先做成单 Skill 直调Agent 收到意图直接调一个 Skill拿到结果返回。这个方案最简单适合 Skill 数量少、业务逻辑单一的场景。但如果你想做全能 Agent多 Skill 路由是绕不开的。比如我的 Agent 同时接入了server_inspector服务器巡检、data_sql_querier数据库查询、notification_sender消息通知、report_generator生成周报这几个 Skill。用户说帮我检查一下服务器如果异常就通知我Agent 就需要先调用巡检 Skill再根据巡检结果决定是否触发通知 Skill。这个时候Skill 列表里每个 Skill 的 description 就起决定性作用了。如果两个 Skill 的描述都写了一堆相似的内容模型极容易选错。我的经验是每个 Skill 的描述聚焦在它最能解决的问题上用当用户想要……时优先调用此技能这种句式减少歧义。4.2 让 Agent 学会拆任务规划-调用-汇总的闭环多 Skill 场景下我强烈建议在 Agent 的系统 prompt 里加一段任务拆解规则当收到复杂任务时请按以下步骤处理 1. 拆解任务为多个可并行或串行的子任务。 2. 判断每个子任务需要调用哪个 Skill。 3. 先调用依赖前置结果的 Skill再调用后续 Skill。 4. 汇总所有 Skill 的返回值组织成自然语言回答用户。 5. 如果某个 Skill 调用失败不要编造结果明确说明错误原因。这段规则让 Agent 从一个 prompt 干所有事变成了一个调度器协调多个能力单元。实测下来复杂任务的完成率明显提升。原因也好理解模型直接回答复杂问题容易出错但让它把问题拆成小块、每个小块调一个专项 Skill每个 Skill 都是确定性代码准确率自然高。这里我还做了个小优化在 Skill 的返回结果里加入一个debug_info字段记录原始数据、耗时、调用的指标列表。Agent 默认不展示这个字段但当用户追问这个状态是怎么判断的时Agent 可以读取debug_info来回答。这比让模型自己解释要靠谱得多因为它看到的是真实的计算依据不是它的推理。4.3 记忆与上下文控制长对话不跑偏的工程技巧Agent 用得越久越会发现上下文管理比 Skill 本身还重要。我的实践里有两个技巧很管用。第一个技巧是Skill 结果摘要化。大模型对话有上下文限制如果每次调用 Skill 都把完整的大 JSON 塞进对话历史聊不了几轮就爆 context 了。我建议在 Agent 层面把 Skill 返回的完整 JSON 只保留summary字段或者做一层轻量摘要再存入历史。完整细节放在一个独立存储里用户需要时再按需读取。第二个技巧是技能调用痕迹持久化。我建立了一张调用记录表记录每次 Agent 调用了哪个 Skill、传了什么参数、结果如何、用户是否满意。这张表有两个用途一是排障时回溯问题二是用来做数据积累后续可以基于它优化 prompt 和 Skill 描述。这个习惯帮我省了大量调试时间强烈推荐。4.4 安全与权限边界敏感操作的保护姿势Agent 一旦连接到真实业务系统安全问题就不能回避。我的做法分三层。第一层Skill 级权限隔离。腾讯云上可以为每个 Skill 配置独立的运行角色和权限范围。比如数据库查询 Skill 只授予 SELECT 权限通知发送 Skill 只授予发送权限互不交叉。这样即使某个 Skill 被恶意利用攻击面也有限。第二层敏感参数不落日志。代码里凡是涉及密码、密钥的字段一律在日志里打***。这个点很多人忽视等 Agent 上线后被审计发现问题就晚了。第三层人工审批兜底。对于删除类、变更类的高危操作我要求 Skill 不直接执行而是返回一个待确认状态Agent 把风险提示发给用户用户确认后才真正执行。这个设计虽然牺牲了一点自动化程度但在生产环境里非常必要。自动化和安全之间需要找一个平衡点我的选择是只读操作全自动写操作加人工确认。5. 实战中的常见问题与排查技巧实录5.1 高频报错速查表我把实际使用中遇到过的高频问题整理成一个清单方便你对照排查现象可能原因排查思路Agent 调用 Skill 时返回超时函数执行时间超过 timeout 设置检查skill.yaml的 timeout调大或者优化代码中耗时操作比如批量请求改并发Agent 总是选错 SkillSkill description 写得太模糊或重叠精简描述让每个 Skill 聚焦单一职责增加触发条件示例Skill 返回 400 参数错误Schema 定义与代码实际解析不一致对比 schema.json 和 main.py 的参数解析逻辑部署后调用报 502入口函数路径配置错误仔细检查 entry 配置是否与文件路径一致比如main.handler是否对应 main.py 里的 handler 函数本地可跑、云端找不到依赖requirements.txt 漏写了依赖或版本号不兼容在打包前用全新虚拟环境安装一遍 requirements 做验证5.2 关于外部服务接入的真实记录在把 Skill 接入外部依赖时最容易出问题的其实是配置管理。我举个例子用腾讯云服务器安装 Redis然后修改密码之后重启失败这个问题我身边至少三个人遇到。原因基本都是修改配置文件后没有重启服务、或者配置语法有问题、或者密码部分没有写到requirepass字段里。排查时先用redis-cli ping测一下服务是否存活再检查配置文件里的requirepass是否生效这两步能解决八成问题。还有一次我把一个 Skill 部署到 Docker 容器里推送到腾讯云容器镜像服务后一直启动失败。查了半天发现是本地镜像构建时用了错误的平台参数。解决办法是重新构建镜像显式指定平台架构。经验就是容器化部署时一定要关注基础镜像的架构和依赖环境别只看代码逻辑。这些问题在云端环境里表现得特别诡异但归根结底都是配置和环境的锅。5.3 性能优化与成本控制经验AI Skills 用得多了性能和成本问题也会浮现。几个实用的优化策略分享给你。一是冷启动优化。Skill 如果使用容器化部署冷启动时间可能达到秒级对用户体验影响大。我的做法是给高频 Skill 配置常驻实例或者使用轻量级运行时。低峰期再缩容兼顾成本和性能。二是减少无效调用。Agent 每次调用 Skill 都会有资源消耗如果用户只是闲聊不应该触发任何 Skill。我通过优化 Agent 的意图识别逻辑让它在确信需要时再调用避免无意义的空转。三是缓存复用。对于短时间内重复的查询请求可以在 Skill 层做一层内存缓存或者 Redis 缓存。注意设置合理的过期时间比如服务器巡检结果 30 秒内复用可以但超过 30 秒的信息可能已经过时了。这种缓存策略要结合业务容忍度来设计不能为了省一点成本返回旧数据。四是日志体积控制。云端日志按量计费全量打日志费用不低。我现在的策略是常规请求打摘要日志错误路径打完整堆栈关键节点打统计信息。既能排查问题又不至于让日志成本失控。6. 沉淀与扩展Agent AI Skills 的下一步实践建议做完整套实践我最大的体会是AI Skills 让 Agent 的开发模式从一个庞然大物变成了搭积木。每块积木独立开发、独立测试、独立部署Agent 只负责调度和表达。这种模式下团队协作效率明显提升——有人专攻数据类 Skill有人专攻通知类 Skill互不阻塞。后续我计划做三件事。第一把 Skill 的调用反馈数据接入到分析系统自动识别哪些 Skill 经常被调用、哪些技能长期闲置为优化提供依据。第二尝试把技能编排做得更动态让 Agent 在执行过程中根据中间结果动态调整后续步骤而不是每次都按固定流程走。第三探索多版本 Skill 的 A/B 测试机制同一个技能出两个版本让 Agent 随机使用并统计效果找出更优的那一版。最后再分享一个我自己的小习惯每次上线一个新 Skill我都会在真实环境里连续对话几十次故意用各种极端说法去触发它。比如本来该触发巡检 Skill 的场景我偏用模糊的话说帮我看一下这台机器最近是不是要出问题。这种测试跑下来能发现很多描述层面的歧义问题比单测有用得多。Agent 开发这件事本质上就是把不确定的模型行为和确定的能力单元缝合在一起。Skill 就是那个缝合点值得你把功夫花在它身上。