ARTICLE DETAIL

资讯详情

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

用 AI Skills 构建全能 Agent:从零搭建到云上落地实践

用 AI Skills 构建全能 Agent:从零搭建到云上落地实践 这两天我把一个只会聊天的 AI 小 demo 拆开重做在腾讯云上用 AI Skills 重新搭了一套全能 Agent 的底座。说“全能”不是夸张而是这套架构把意图识别、工具调用、多轮记忆、任务编排拆成一个个独立的 SkillAgent 在运行时按需动态调度。以前最头疼的是任务稍微复杂一点主函数里就堆满 if-else每加一个能力就要动一次核心逻辑改完还担心把别的功能带崩。换成 AI Skills 之后新增能力变成“加一个 Skill 文件夹”Agent 自己决定什么时候用它这套方案我认为是目前在云上做 Agent 开发比较靠谱的落地方式。它能解决什么问题一句话让你从“写死流程”变成“定义能力池”。Agent 本身只负责规划、决策和串联具体的查询、解析、通知等脏活累活全部下沉到 Skill。适合正在找 Agent 开发学习路线、不想从零搭框架的人也适合已经在云上有业务系统、想快速接入 AI 能力的人。下文会把我的完整落地过程包括参数选择、部署链路、回填的坑全部写出来。1. 需求与选型为什么用 AI Skills 养 Agent1.1 一个真实场景工单自动分流与处理先说下项目要做什么。背景是团队每天要处理大量重复咨询希望做一个 Agent 自动完成“理解问题、查状态、给结论、通知负责人”这条链路。一开始有两个方案第一个是传统对话机器人用意图分类 固定问答库好处是可控坏处是遇到没见过的表达直接哑火第二个是纯函数调用式 Agent把工具全部硬编码进大模型调用循环里好处是灵活坏处是每加一个工具就要改一遍主逻辑而且 Prompt 越来越长模型经常不知道该用哪个工具。最后选了腾讯云 AI Skills。核心原因有三个第一Skill 是声明式封装模型通过描述自动发现能力新增工具不动主逻辑第二每个 Skill 有独立的日志、监控、版本出问题能单独回滚第三云上托管免去我自己搭服务、做负载均衡的麻烦。如果你只是想本地做个 demo直接写函数调用没问题但一旦要考虑生产环境和多人协作Skill 这种方式更稳。1.2 AI Skills 到底是个什么东西一个带“标签”的工具箱很多人第一次听到 AI Skills 会以为它是某个 AI 应用模板其实不是。我的理解是AI Skills 是一种把 AI 能力封装成标准化技能单元的运行时方案。每个 Skill 由两部分组成一部分是给模型看的“说明书”也就是元信息描述包含这个技能叫什么、能做什么、入参出参长什么样另一部分是给机器执行的“肌肉”也就是真正的处理函数可以是云函数、HTTP 请求或者容器内的一段逻辑。打个比方它很像一个贴了标签的工具箱。传统函数调用是“你把所有工具一字排开写代码告诉模型什么时候用哪个”AI Skills 则是“工具箱摆在模型面前每个抽屉贴着说明书模型自己判断该拉开哪个抽屉”。这个区别看似不大实际体验差别非常大当 Skill 数量从 3 个涨到 30 个硬编码的调用逻辑几乎无法维护而 AI Skills 只需要保证每个 Skill 的描述足够清晰即可。2. 动手前规划环境、模型与 Skill 的拆分方式2.1 环境初始化账号、CLI 与目录结构我在实际操作中的流程如下。先在腾讯云控制台开通云端环境AI Skills 的运行时我更推荐直接基于云托管来做方便拉镜像也方便后续扩容。接着在本地安装云开发 CLI 或云托管 CLI执行登录后关联到项目环境。然后初始化目录结构每个 Skill 一个子目录里面放 manifest 配置和处理函数。依赖方面我用的是 Python 运行时所以主要装模型 SDK、redis、requests 这几个包。模型 API Key 和云账号密钥全部放环境变量不要写进代码。这套流程本身不复杂但如果你在团队里还涉及 git 协作建议把 Skill 目录单独建一个仓库用 MR 方式合入新 Skill。这样每次新增能力都有 review 记录出问题也找得到是谁改的。我自己吃过一次亏刚开始图省事直接在一个大仓库里改结果上线前回滚把同事的新功能也一起带回去了后来才老老实实拆库。2.2 模型选型与关键参数先算账再动手模型选型上我当时用了一个比较务实的策略意图识别和工具调用这些“控制面”用能力更强的最新模型因为判断错一个动作后面全错而具体执行过程中的文本总结、格式清洗这些“数据面”任务用更轻量的模型成本低、响应快。如果你接多家模型供应商可以在本地先加一个统一网关把 key 管理和模型路由集中起来类似 litellm proxy 那套思路不过当时为了减少链路故障点我直接把腾讯云的模型服务接入进来。配置方面有几个参数很关键。函数内存512MB 起步如果 Skill 里要做文档解析或大文件处理建议 1GB否则内存不够会直接被杀进程。函数超时默认 3 秒肯定不够Agent 场景建议 30-60 秒但超时时间越长意味着冷启动影响越大需要根据实际压测调整。并发上限不要直接拉满先设一个合理值比如 50观察耗时和错误率再逐步上调。模型 temperature工具调用场景建议 0-0.2太高会让模型“发挥创造力”乱传参数。为什么很在意这些数值因为 Agent 的一次任务可能会连续调用多个 Skill每个 Skill 多 500ms整个任务的响应时间就会被放大好几倍每个模型多输出 200 个 token成本也会翻着跟头涨。养成一个“会过日子”的 Agent第一步就是把这些参数控制在合理范围内。2.3 Skill 目录设计先拆“手和脚”再装“大脑”落地之前我先列了一张能力清单。这个 Agent 至少需要task_planner把用户一句话拆成可执行的子任务data_query查询业务数据库或 Redis 缓存doc_parser解析上传的 PDF、Word 文件api_caller调用内部业务系统的 HTTP 接口notify通过企业微信或邮件把结果推给负责人。每个 Skill 的目录结构我统一成下面这种方便脚本扫描和部署skills/ ├── task_planner/ │ ├── manifest.json │ └── handler.py ├── data_query/ │ ├── manifest.json │ └── handler.py └── ...设计原则就三条职责单一、入参扁平、错误信息必须让模型看得懂。职责单一好理解一个 Skill 只做一件事入参扁平是指尽量用字符串和简单 JSON 结构不要传嵌套对象因为模型生成复杂参数时经常出错错误信息必须是“人话”比如“数据库连接超时请 1 分钟后重试”而不是抛一个堆栈让模型自己去猜。3. 核心实现把 Agent 的“大脑”和“手脚”写出来3.1 意图识别与任务规划 Skill别再写一堆 if-else整个项目里最核心的是 task_planner。它做的事情很简单接收用户原始输入让模型输出一个结构化任务列表。以下是我在 manifest.json 里写的描述这段描述直接决定了模型什么时候会调用它、以什么格式调用{ name: task_planner, description: 将用户的复杂请求拆解为多个可执行的子任务。仅当输入包含多个步骤或需要串联多个工具时调用若用户只问简单问题不要调用本技能。, input_schema: { type: object, properties: { user_request: { type: string, description: 用户原始请求全文 } }, required: [user_request] }, output_schema: { type: array, items: { type: object, properties: { step_id: { type: integer }, action: { type: string }, reason: { type: string } }, required: [step_id, action, reason] } } }然后在 handler 里我设置了两层校验第一层是模型返回的 JSON 能不能正常解析解析不了就打回重试第二层是步骤里的 action 字段是不是在已注册的 Skill 列表里不在就提示模型重新组织。这两层校验看着简单实际帮我挡住了很多线上事故。为什么要让模型先输出结构化列表而不是直接生成最终步骤因为拆解成子任务后每个子任务可以被单独记录、重试、展示进度这比一次生成长篇结果要可控得多。另一个关键点是在描述里明确调用条件。如果你不写“仅当输入包含多个步骤时调用”模型会在简单问题上也绕一圈规划响应变慢且多花 token。实测下来加上这一句约束规划 Skill 的调用次数能下降 40% 左右。3.2 工具调用与结果解析让 Agent 学会真正“动手”task_planner 规划之后轮到 data_query、doc_parser 这些工具型 Skill 上场。模型会以 JSON 格式给出要调用的 Skill 和参数Agent 运行时负责真正执行。这个环节最容易出问题的不是执行本身而是参数校验和结果回传。模型给的参数可能丢字段、给错类型不能直接把参数透传给内部接口。我写了一个统一的校验函数凡是入参不符合 schema 的统一返回给模型重新生成def validate_and_execute(skill_name, arguments, registered_skills): skill registered_skills.get(skill_name) if not skill: return {error: fskill {skill_name} not found, available: {list(registered_skills.keys())}} errors validate(arguments, skill.input_schema) if errors: return {error: finvalid arguments: {errors}, please check input_schema} return skill.execute(arguments)关于返回结果有一句话值得记住给模型的返回结果一定要截断。有的 API 返回几 MB 的 JSON全部塞进上下文模型会“看不过来”而且会直接撑爆 token 窗口。正确做法是只保留关键字段、把长列表聚合统计必要时写个 summarize 函数先生成一版摘要再回传。我们调过的一个业务接口原始响应有 8000 多行截断成 20 行以内的统计信息之后整个链路稳定非常多。3.3 多轮记忆与上下文管理别让 Agent 做“金鱼”Agent 的一个大坑是上下文管理。第一版我直接把历史消息全部传进去跑几天后发现两个问题一是会话越长 token 成本越高二是模型经常被早期错误信息误导。后来我改成两层记忆短期记忆保留最近 10 轮对话存在 Redis 里key 设计为 agent:session:{session_id}:history长期记忆则每次任务结束后把重要结论和用户偏好写入长期存储后续会话先检索再拼进上下文。Redis 存取的时候要注意设置过期时间一般会话级数据 24 小时足够不然会积累大量垃圾 Key。上下文裁剪也不要简单“丢最旧消息”因为用户经常在几轮对话后补充关键条件。我的策略是窗口超长时对最早的消息做一次摘要压缩而不是直接丢弃这样既控制 token 又保留关键信息。3.4 编排与调度让 Agent 自己决定干活顺序接下来是整个 Agent 的调度骨架。我用了一个比较轻量的循环把用户输入交给大模型让它返回“下一步动作”动作可能是调用某个 Skill也可能是直接回答。如果是调用 Skill则执行、把结果反馈给模型再让模型继续判断直到模型认为任务完成或到达最大步数。伪代码如下while step max_steps: action model.decide(user_input, memory, skills) if action.type finish: break if action.type call_skill: result execute_skill(action.skill_name, action.arguments) memory.append(summarize(result))这个模式有点像 ReAct但没有那么重的框架约束。很多人分不清 harness 和 agent 的区别我自己的理解是agent 是里面的决策内核决定“下一步干什么”harness 是外面的壳和观察层负责把 agent 的一举一动记录下来并控制执行边界。AI Skills 在这套设计里同时承担了两部分Skill 调用循环是 harness模型决策是 agent而每个 Skill 的日志就是观察数据。4. 部署上线从本地到腾讯云的完整链路4.1 构建镜像并推送到容器镜像服务本地跑通后下一步是上云。我选择的是云托管加容器镜像的方式好处是环境一致本地能跑的上云基本也能跑。先写一个精简的 DockerfileFROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD [python, main.py]然后构建并推送镜像推送前先登录容器镜像服务在控制台拿到你专属的仓库地址docker build -t my-agent:v1 . docker tag my-agent:v1 ccr.ccs.tencentyun.com/命名空间/my-agent:v1 docker push ccr.ccs.tencentyun.com/命名空间/my-agent:v1这里要提醒一句具体仓库地址以控制台显示为准不要照抄占位符。镜像优化上我踩过一个坑第一版直接把全套依赖装进镜像镜像体积有 2GB 多推送半小时冷启动还慢。后来改成多阶段构建基础镜像换成更精简的版本只保留运行需要的依赖体积直接降到 400MB 以内。如果你的镜像里有模型文件注意分离不要把几个 GB 的模型打进业务镜像用对象存储挂载或者启动时拉取会合理得多。4.2 申请二级域名、配置 HTTPS线上接口必须走正规域名部署到云托管后会生成一个默认域名但生产环境还是要用自己的域名。我在实际操作中申请了二级域名步骤比较简单先在一个已备案的一级域名下去云解析控制台添加一条 A 记录主机记录填 agent-demo记录值为服务的访问入口 IP 或负载均衡地址然后在服务配置里把自定义域名绑上去申请 SSL 证书并开启 HTTPS。整个过程在控制台操作不需要自己部署证书文件。这里提醒一点如果你的服务需要对外暴露回调接口域名解析和 HTTPS 的配置一定要提前做否则后续对接企业微信、钉钉这类第三方应用时回调地址必须是公网可访问的合法域名直接暴露 IP 的接口很容易被拦。另外回调接口建议固定一个清晰的路径前缀比如 /api/skills/callback后面接白名单也好配。4.3 上线前压测与监控把短板提前揪出来正式上线前我做了两轮压测。第一轮是把每个 Skill 单独压先摸清单个能力的天花板看谁是最慢的瓶颈第二轮是整个 Agent 链路压模拟用户连续提交任务。我的实测结果大概是这样压测场景并发数平均响应P95错误率单 Skilldata_query30420ms780ms0.1%单 Skilldoc_parser102.3s3.8s0.8%全链路工单分流204.1s6.2s1.2%看完数据你会发现doc_parser 明显是短板所以后来给它单独加了资源配额和超时重试。监控方面我接入了云日志每个 Skill 的执行结果、耗时、调用参数都打点后续查问题基本靠它。建议日志里把 session_id 带上这样一次 Agent 任务的所有步骤都能串起来看。5. 线上回填常见问题与排查技巧实录5.1 Redis 改完密码重启失败的完整排查项目上线后第一次出幺蛾子正好是 Redis。我在腾讯云服务器上改了 Redis 的 requirepass 配置然后执行 systemctl restart redis结果服务一直起不来客户端连接全部失败。排查过程大概是这样第一步看日志journalctl -u redis 或查看 redis.log定位到启动阶段报错的具体行第二步检查 config 文件是否有语法问题requirepass 后面如果带了特殊字符没加引号解析会直接报错第三步检查 systemd 服务文件看有没有引入环境变量覆盖了关键配置。还有一个很常见的坑改完密码后 Redis 能启动但客户端还没改于是一直报 NOAUTH 认证失败。这不是重启失败而是连接失败。需要把项目里的连接配置、监控采集器、定时任务脚本全部同步更新最好把密码收敛到密钥管理服务或环境变量里避免散落各处。另外如果你改了持久化文件目录记得检查目录属主Redis 进程没有写权限会直接退出这种问题日志里通常会有 Permission denied 提示。5.2 Agent 执行中断先看日志再看回调与网关拦截“agent execution terminated due to error” 这句话我上线后见了很多次。刚开始看到它很慌后来发现它只是告诉你 Agent 在执行过程中因为某个异常被终止了真正的问题藏在日志里。定位步骤一般是先看编排器日志确认是哪个 Skill 触发的、模型下一步动作是什么再看 Skill 执行日志区分是参数错误、依赖服务不可用还是模型返回的 JSON 解析失败最后看模型调用日志确认是不是上下文超长被截断或触发了内容安全策略。有一次我发现 Agent 调用内部接口时频繁失败查了一圈发现是 WAF 策略把合法回调路径给拦了。当时的第一反应是关掉 WAF但后来想想不对直接关防护等于把线上服务裸奔。正确做法是把固定的回调路径加入白名单、调整防护等级、补充合法请求的识别规则既不影响安全又能让 Agent 顺畅调用。如果你也遇到网关层拦截先看拦截日志再决定加白还是改请求逻辑别图省事直接关闭安全防护。5.3 问题速查表症状可能原因处理方式Redis 启动后一直认证失败客户端配置未同步新密码更新所有连接配置密码纳入环境变量Redis 重启后进程消失持久化文件权限不对检查目录属主赋予 redis 用户写权限Agent 报执行终止Skill 参数校验失败或依赖超时定位日志区分类型补校验和重试回调接口被拦截WAF 策略误伤合法路径加白固定路径调整防护配置响应变慢、token 暴涨上下文未裁剪全部历史塞入模型做窗口截断加摘要压缩镜像推送耗时过长镜像体积太大多阶段构建精简依赖冷启动慢依赖多、实例池不足预留实例减少启动时初始化这张表里有一条值得展开上下文未裁剪导致响应变慢的问题最难查因为报错不明显只有成本和耗时悄悄上涨。我当时是在监控面板里发现 token 消耗异常才回过神。所以建议从第一天起就把模型调用次数和 token 消耗作为指标之一接入监控别等到账单炸了才开始看。6. 从“能跑”到“好用”指标度量与后续扩展6.1 三个接地气的质量指标养 Agent 不能靠感觉我最后实际盯三个指标。第一个是任务完成率用户提的需求最终有没有被 Agent 正确完结按 Skill 链路统计看哪一环掉链子。第二个是单任务耗时从用户提交到最终回复的端到端耗时超过 10 秒的任务我会单独分析判断是模型推理慢还是某个 Skill 卡住。第三个是单任务成本把模型 token 费用加云资源费用平摊到每个任务这个数字很直观能帮你判断哪些流程该简化、哪些 Skill 该做结果缓存。这三项指标配合同一个监控面板看问题基本不会藏太久。如果你刚开始做建议先只抓任务完成率这一个指标把它跑稳了再追求成本和速度。千万不要一上来就追求所有指标完美否则你会陷入无休止的调参循环反而忘了 Agent 的核心是要把事办成。6.2 后续扩展方向从单 Agent 到多 Agent 协作这套架构的扩展性比硬编码好很多。我现在正在做的几个事一是接入更多内部系统比如让 Agent 能直接查询文件系统状态、解析磁盘分区信息做故障分析这可以往“数据恢复辅助判断”的方向延伸先让 Agent 读元数据再交给专业工具处理二是把单一 Agent 升级成多 Agent 协作master Agent 负责任务分发worker Agent 各自盯一类 Skill像 harness 和 agent 分离的思路一样职责边界会更清晰三是接私有知识库把 FAQ、操作手册通过 RAG 方式注入上下文让 Agent 的回答更贴近业务。以上这些方向都建立在“Skill 化”的基础上核心没有变化只是能力池越来越大。我的体会是养好一个 Agent不是把它训练成一个无所不知的大脑而是给它搭好一套随时能长出新能力的手脚。框架选型、参数调优、日志监控这些东西虽然琐碎但恰恰是决定 Agent 能不能从 demo 走向生产的关键。最后再分享一个我从实践中总结的小技巧每个 Skill 的 description 是写给模型看的不是写给同事看的里面一定要写清楚“什么时候用、什么时候不用、入参格式是什么”。另一个技巧是大模型返回的结果一定要做长度限制和内容截断尤其在回传给下一轮推理之前。这两点做对了Agent 的稳定性和成本都会有立竿见影的改善。
返回列表