腾讯云AI Skills实战:构建全能Agent的技能设计与编排指南
1. 为什么我把 Agent 的技能单独拎出来做先说个背景。我手上有好几个 Agent 项目最早做的时候走了不少弯路。起初的想法很简单把大模型的对话能力接上工具调用让 Agent 能查天气、能算数学、能调数据库。但真正跑起来才发现模型输出是概率性的同一个功能今天能用明天抽风是常态更别提把工具逻辑、提示词、参数校验、失败重试全堆在一个 Agent 工程里代码很快就烂成一锅粥。后来我梳理了一下问题就出在技能和Agent没有分层。打个比方Agent 像一个厨师技能就是他的刀工、火候、调味手法。你不能让厨师每次做菜的时候再去现学刀工那样出菜质量极不稳定。正确做法是先把刀工练成肌肉记忆厨师只管根据菜单调配。这个肌肉记忆落到工程上就是 AI Skills。腾讯云的 AI Skills 本质上是把 Agent 的一个完整能力闭环——从意图识别、参数抽取、工具执行到结果规整——封装成独立可复用的单元。它不只是简单的函数调用而是一套带描述、带输入输出协议、带错误处理策略的能力包。我最初在本地用 LangChain 搭过类似的东西但每次都要自己处理服务发现、鉴权、可观测性、版本管理这些问题累得够呛。迁到腾讯云 AI Skills 之后这些基础设施层面的活儿基本都能省掉我可以把精力集中在技能本身的逻辑打磨上。这篇文章就围绕我在腾讯云上从零构建全能 Agent的完整过程展开目标是让你看完之后能照着搭出一套自己的技能体系。会涉及技能怎么设计、Agent 怎么跟技能配合、服务怎么部署、上线后怎么调优排障以及我在实测中踩过的那些文档里不会写的坑。先给一个整体视角一个完整的 Agent 项目在腾讯云上大概分四层——接入层负责对话与权限调度层负责意图路由技能层负责具体能力执行数据层负责记忆与状态。AI Skills 落在第三层但它的设计质量直接决定第二层能不能把意图分清楚。所以这篇文章把重点放在技能层和它跟调度层的衔接上。2. 技能设计先想清楚三个问题再做很多人的做法是拿到需求就开始写代码结果技能做出来要么太宽泛什么都接不住要么太窄换个场景就废了。我在动手之前会先回答三个问题这三个问题基本决定了技能的边界和质量。2.1 这个技能的最小职责单元是什么技能不能贪大。我见过有人把一个文档处理技能做成能读取、转换、摘要、翻译、问答、对比的六合一模块结果每个子功能都是半吊子意图一多模型就糊涂。我的实践是一个技能只解决一件事但这件事要做得深入。举个例子如果 Agent 需要处理 Excel 报表我不会做一个通用的报表技能而是拆成报表数据校验报表指标计算报表格式标准化报表异常标注四个技能。每个技能只吃一种输入、产一种输出、只依赖一类工具。这样做的直接好处是Agent 路由意图时非常清晰模型只需要根据技能描述和输入参数判断调用哪个几乎不会歧义。另一个隐藏好处是排障方便——某个技能出问题时影响面被局限在一个小模块里不会拖垮整个 Agent。2.2 技能的输入输出协议怎么定输入输出协议是技能设计的核心也是跟大模型交互的契约。腾讯云的 AI Skills 支持自定义参数结构和返回结构我的建议是参数尽量扁平类型尽量明确描述尽量带示例。因为模型做参数抽取时依赖的是参数名和描述文字描述里带示例能大幅提升抽取准确率。我当时设计一个图表生成技能时最初的参数结构是嵌套的{ data: { xAxis: [一月, 二月], series: [ {name: 销量, values: [100, 150]} ] }, chartType: bar, title: 月度销量 }实测下来模型抽取这种嵌套结构时经常漏填或者填错层级成功率只有七成左右。后来我把参数结构改成扁平化并给每个字段加了示例值{ series_names: [销量, 利润], x_labels: [一月, 二月, 三月], series_values: [[100, 150, 130], [30, 45, 40]], chart_type: bar, title: 月度经营数据 }成功率直接干到九成半以上。核心原因在于文本型大模型对平铺的、自上而下填充字段这件事的把握度远高于递归地构造嵌套对象。这个经验我后来在多个技能里反复验证过结论一致。2.3 技能要不要带状态这是个容易被忽略的问题。技能默认应该是无状态的——每次调用都是独立的输入、执行、返回完事儿。但有些场景确实需要跨多次调用的状态比如多轮对话里用户先问我上个月电费多少再问那这个月呢两个问题如果被路由到同一个查询技能模型需要知道这个月指的是哪个月份这其实是对话上下文的职责不应该由技能自己记状态。我的原则是技能本身不做记忆只接收上下文参数。如果 Agent 需要连续对话调度层负责维护会话上下文并把相关的历史摘要作为参数传给技能。这样技能还是无状态的但用户体验上是有状态的。这个分工特别重要否则技能一多状态管理就会变成一场灾难。3. 在腾讯云上把技能跑起来从云端配置到本地联调腾讯云的 AI Skills 功能在云端控制台里就能完成技能的生命周期管理——创建、配置、发布、监控。但我不建议直接在页面上写完所有东西更顺滑的方式是本地开发调试好逻辑再同步到云端。这样迭代速度快出问题也容易定位。3.1 创建技能的第一步描述文档比代码重要后端逻辑再完备如果技能描述文档写得稀烂Agent 也调不对。我把技能描述当成跟大模型沟通的说明书写清楚这几个要素这个技能是干什么的一句话尽量包含动作和对象什么情况下应该调用它正例和反例都写反例尤其重要输入参数的定义和示例输出的格式约定出错时可能返回的状态码和含义腾讯云控制台里有一个技能描述编辑区支持 Markdown 格式。我强烈建议在这里写一份结构化描述不要随手糊两行。你花在描述上的时间会在线上意图识别准确率上十倍赚回来。我当时写在线查询技能的描述反例部分帮了大忙。我写的是本技能仅用于查询不用于计算和汇总。若用户询问总计、平均值、同比增长等计算类需求请调用【指标计算】技能不要调用本技能。就这么一句话把查询和计算两类技能的误调用率从 25% 压到了不足 5%。3.2 本地脚手架用腾讯云 SDK 把技能逻辑跑通云端的技能函数最终是要被执行引擎调用的对应到代码层面就是一个标准的 HTTP 服务接收技能请求参数执行逻辑返回结构化结果。我习惯用 Python FastAPI 写这个服务框架。from fastapi import FastAPI, Request from pydantic import BaseModel from typing import List, Optional app FastAPI() class ExcelQueryRequest(BaseModel): sheet_id: str row_range: Optional[str] None filters: Optional[List[dict]] None class QueryResult(BaseModel): success: bool rows: Optional[List[dict]] None message: Optional[str] None error_code: Optional[str] None app.post(/excel/query, response_modelQueryResult) async def query_excel(req: ExcelQueryRequest): try: # 具体查询逻辑连接腾讯云对象存储、读取 Excel、执行过滤 result execute_query(req) return QueryResult(successTrue, rowsresult) except Exception as e: return QueryResult(successFalse, messagestr(e), error_codeQUERY_FAILED)这个脚手架有两个好处一是本地起服务就能用 Postman 直接打接口测试不需要每次都推上云端二是后续把服务打包成容器镜像推到腾讯云容器服务或者在云函数里托管都是同一套代码迁移成本极低。3.3 联调阶段最容易忽略的鉴权问题腾讯云的 AI Skills 在远程调用技能时默认会做身份校验。联调时最常见的问题是配置了技能服务地址但请求一直返回 401 或者 403。原因不外乎两类一类是签名问题。云端调用时会在请求头带上签名信息你的服务端必须用腾讯云提供的 SDK 或密钥对签名做校验。如果你只是想先联调通建议先在技能配置里选开发模式该模式下云端会附带一个调试用的凭证服务端拿这个凭证校验即可。另一类是网络隔离问题。如果你的技能服务部署在私有网络里云端执行引擎访问不到。解决办法是把服务通过负载均衡暴露到云端可访问的入口或者打通内网通道。很多人在这一步卡一整天其实检查一下安全组的入站规则、负载均衡的后端服务健康检查是否通过就能找到问题。我当时卡在健康检查上——负载均衡配好了后端服务也起来了但技能调用还是报服务不可达。查了半天才发现是健康检查路径配错了我写的是/healthFastAPI 默认没这个路由负载均衡判定后端不健康流量自然进不来。4. Agent 与技能的协同路由、编排与上下文传递技能只是零件Agent 才是整机。技能设计得再完美如果 Agent 不知道怎么路由、不会编排多技能协作照样发挥不出战斗力。4.1 意图路由的两种策略各有适用场景训练 Agent 路由意图业界基本是两条路线基于模型分类和基于语义检索。基于模型分类适合意图数量少10 个以内、边界清晰的场景。你可以让大模型从技能列表里选一个返回这种方案实现简单但意图一多模型容易混淆相近技能。基于语义检索适合技能数量多、意图边界模糊的场景。把每个技能的描述向量化存入向量数据库用户请求先做向量检索召回 Top3 技能再交给模型做精排。腾讯云的向量数据库和 AI Skills 能直接打通不用自己维护整套检索服务。我实际项目里技能超过 15 个之后纯模型分类的准确率明显下降尤其是我上面提到的查询和计算这类语义相近的技能。后来切到向量召回 模型精排的混合方案整体意图路由准确率提升了将近 20 个百分点而且新增技能只需更新向量索引旧技能完全不用动。如果你的技能清单在持续生长我建议一步到位用混合方案。4.2 多技能协作把顺序依赖设计成显式状态机单技能调用好处理难的是多个技能协作完成一个复杂任务。比如分析上季度各区域销售数据并生成可视化看板拆开就是查询技能取数 → 计算技能汇总 → 图表技能画图 → 报告技能排版。我早期实现多技能协作是纯提示词驱动让大模型自己决定先调哪些技能。结果就是经常漏调步骤或者数据还没算完就开始画图最终输出牛头不对马嘴。后来我改成显式状态机的方案Agent 维护一个任务状态每完成一个技能就更新状态下一个技能依赖前一个技能的产出。调度层根据状态决定现在该调用哪个技能而不是让模型自由发挥。这个改动直接把我这边的复杂任务成功率从四成拉到了八成以上。class ReportPipelineState: def __init__(self): self.current_step query self.steps { query: excel_query_skill, aggregate: metric_calc_skill, chart: chart_generate_skill, report: report_layout_skill, } def next_step(self): order list(self.steps.keys()) idx order.index(self.current_step) if idx len(order) - 1: self.current_step order[idx 1] return self.steps[self.current_step] return None这个设计模式说白了就是流水线每个技能是工位状态机是传送带产品经过一个工位处理完就流动到下一个。缺点是需要预先定义好流水线的节拍和顺序但好处是每一步都可观测、可回滚、可重试对于生产环境来说这些特性比灵活性重要得多。4.3 上下文传递不要一股脑全塞给技能多技能协作必然涉及上下文传递。最常见的错误是把所有历史对话、中间数据全部拼到技能请求里导致请求体越来越大模型处理速度越来越慢费用也越来越高。我的经验是在传给技能之前调度层先做上下文裁剪只保留当前步骤必需的参数和上一步的可验证输出摘要其余全部丢弃。比如图表生成技能我就传给它维度列表、指标数值和图表类型不传对话历史和用户原话。这样技能自己处理得干净Agent 路由得也快。上下文传递有个要注意的细节技能 A 的输出作为技能 B 的输入时字段名必须对得上。腾讯云的技能描述里对输入输出字段做了很严格的类型约定如果技能 A 返回的是字符串型数字123技能 B 声明接收整数型 123调度层需要做一次显式类型转换。我在调度层加了个字段映射的配置项避免每次更换技能都要改代码。5. 上线后的问题排查与进阶调优技能上线只是开始真正花时间的是上线后根据监控反馈持续调优。这里分享几个我踩过的坑和反复验证有效的优化手段。5.1 一次完整的排查链路从日志到根因有一次我发现某个技能的生产成功率从 95% 掉到了 80%界面上的错误提示只有两个字超时。直接看日志发现日志里技能执行耗时在 15 秒到 30 秒不等而我配置的技能超时时间是 10 秒。第一反应是后端服务变慢了。但看服务本身的监控CPU、内存都正常慢查询也没有。后来把日志粒度打到调用链级别才发现慢的不是我自己的逻辑而是技能里调用的下游 API 响应变慢了——某个第三方接口从原来的平均 200ms 涨到了 8 秒。排查链路走到这里根因就清楚了第三方接口因为上游链路拥堵响应时间出现长尾。解决办法是在技能代码里给下游调用加超时熔断from tenacity import retry, stop_after_attempt, wait_exponential retry(stopstop_after_attempt(3), waitwait_exponential(multiplier1, min2, max10)) def call_downstream_api(data): response requests.post(DOWNSTREAM_URL, jsondata, timeout3) response.raise_for_status() return response.json()加上超时重试之后单个下游调用最多等 3 秒就失败重试三次累计最长等待约 15 秒。虽然没有完全消除超时但至少不会再无限期等下去而且重试大概率能等到下游恢复。这个调整让成功率回到了 93% 左右。剩余 2% 的失败率主要是因为某些第三方接口持续 10 秒以上不恢复这属于上游的稳定性问题不是我能完全解决的。这个案例给我的启示是技能排查要有从请求入口到下游依赖的全链路追踪能力否则你根本不知道时间花在哪个环节。腾讯云的自定义监控和日志服务配合调用链追踪基本能把每个技能的耗时打点做出来强烈建议早点把这块配好别等出事再搭。5.2 Token 消耗优化的三招实操Agent 跑起来之后成本大头基本是模型调用。尤其是多技能协作场景每个步骤都要跟模型交互Token 消耗像流水一样。我实测下来以下三个招数对降本立竿见影。第一招技能描述做精简。技能描述太长会占用大量 Token而且模型处理冗长描述时反而抓不住重点。我之前有个技能描述写了 1200 字精简到 400 字之后每次调用的 Token 消耗直接少了三分之一意图识别准确率反而还升了。精简的原则是保留调用场景、参数示例、反例砍掉各种跟调用决策无关的背景介绍。第二招模型分级调用。不是所有技能调用都需要最强的模型。我配了模型路由简单技能如格式转换、字段抽取用更快更便宜的模型复杂技能如多条件检索、报告生成用强模型。粗算一下这招能省下 20% 到 30% 的调用成本。第三招结果缓存。对确定性输出的技能比如查询历史统计数据、获取静态配置加上一层 Redis 缓存相同参数的请求直接命中缓存。我这边几个高频查询技能加了缓存之后调用量减少了将近一半后端压力也小了两全其美。5.3 技能安全输入校验和敏感信息治理Agent 的每个技能入口本质上就是一个可被外部请求触发的 API。安全这块我在上线前重新过了一遍重点是两点。第一点是输入校验。腾讯云不太希望你技能里出现任意代码执行或者超长文本注入所以我自己额外加了输入白名单和长度限制。所有技能入口都做两轮校验第一轮是结构校验字段类型、枚举值、长度必须符合协议第二轮是语义校验比如日期必须晚于 2020 年、金额不能为负数。这样就算大模型被用户提示词带偏了技能层面也能兜底。第二点是敏感信息治理。Agent 在调用技能时可能会在日志中记录业务数据这些数据里可能混有用户隐私或内部业务信息。我做的配置是日志脱敏匹配手机号、身份证号、银行账号、密钥的字段在落盘前打星号。这个配置在腾讯云的日志服务里可以直接设置不用自己改代码。6. 我养成的全能 Agent最终长什么样说了这么多方法论最后用一个实际的工程快照收尾。我的这个 Agent 上线跑了快三个月目前接了 23 个技能覆盖数据查询、统计分析、图表生成、报告撰写、信息检索、任务提醒六大类。架构上是典型的接入层 调度层 技能层 数据层四层结构。接入层是微信公众号和网页端两个入口共用一套鉴权和会话管理。调度层用的就是前面说的向量召回 模型精排混合路由配合显式状态机做多技能编排。技能层跑在腾讯云容器服务上每个技能独立部署、独立伸缩技能之间互不影响。数据层用的腾讯云数据库存会话记忆和技能执行记录Redis 做结果缓存。上线以来我监控了几个核心指标意图路由准确率做到了 92%技能执行成功率做到了 94%端到端平均响应时长控制在 3 秒以内。这个结果肯定不算完美但已经能稳定支撑日常业务使用。回头看整个搭建过程我最深的体会是Agent 的能力边界不是模型决定的是技能体系的完善度决定的。模型再聪明没有扎实的技能支撑就像一个智商很高但没有任何生活经验的人聊什么都头头是道真让他干点实事就露馅了。技术选型上如果你已经决定用腾讯云生态那 AI Skills 几乎是必选项——它跟账号体系、日志、监控、容器服务之间的打通能省下大量自研中间件的时间。如果你还在观望我的建议是先拿一两个业务场景做试点把技能设计和意图路由这两块的感觉找到再逐步扩大技能清单。这套方法论即使以后换平台核心思路也是通用的。