ARTICLE DETAIL

资讯详情

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

从零构建全能AI Agent:Skills设计到腾讯云部署实战

从零构建全能AI Agent:Skills设计到腾讯云部署实战 刚开始接触 Agent 开发时我被自己的一个认知偏差狠狠教育了一回——我以为把大模型 API 接进对话框再加个工具调用的开关它就能自动变成什么都会干的助手。结果真到用的时候让它分析一下服务器日志顺手画张架构图它确实知道日志文件在哪但下一秒不是去执行分析脚本而是给我写了一篇如何分析日志的教程。那一刻我彻底明白模型再聪明手上没有趁手的工具一样干不了活。后来我把重心放到了 Skills 上——给 Agent 装配一套套操作手册 可执行脚本的技能包然后在腾讯云上完成了整套部署和运维。这篇复盘整理了完整链路从如何设计一套适合自己业务的 Skills 组合到云服务器初始化、二级域名配置、HTTPS 证书、安全组规划再到 Redis 密码修改、容器镜像推送这些真实的踩坑现场。如果你正准备在腾讯云上做一个真正能落地的 AI Agent这篇文章能帮你少走一大半弯路。1. 先把概念掰开Skills 不是插件是 Agent 的操作手册这个误区我必须先讲清楚。很多人以为给 Agent 装 Skills 就像给手机装 App装上就能用。实际上两者差别很大App 是人直接点的而 Skills 的调用方是 Agent 自己——它要能读懂技能的描述判断当前任务适不适合用这个技能知道怎么传参数最后还要能处理脚本的输出。这中间的每一个环节都会决定技能能不能被正确触发。1.1 为什么光有大模型不够决策与执行之间的断层LLM 本身只会想不会做。当你在自然语言里提出一个具体任务模型擅长的是拆解步骤、给出建议而不是真的去执行命令、读取文件、调用服务。要弥补这个断层业界先后走过几个阶段先是 Function Calling让模型可以从预设函数列表里挑一个并给出参数然后是 MCP 这类协议把外部工具以标准接口暴露给模型再往上一层就是 Skills——它把工具从一个孤立的 API 函数升级成一套完整的、自包含的工作包。我自己的理解是Skills 与 Function Calling 最大的不同在于Function Calling 是给模型一把螺丝刀而 Skills 是给模型一整套工具箱加说明书。一个 Skill 里不仅有可执行脚本还有它自己的描述文档、依赖清单、使用示例。Agent 在决定调用它之前会先读完说明文档搞清楚这个技能适用于什么场景、输入输出是什么样再去执行。这种设计让技能本身具备了很强的自解释能力也让整个 Agent 体系可以无限扩展——只要技能包足够多、描述足够准确Agent 就能覆盖越来越多的场景。1.2 Skill 的标准形态目录、SKILL.md、脚本与依赖Skill 的目录结构虽然没有绝对统一的标准但社区里比较公认的约定参考早期 Claude Code 的 Agent Skills 文档格式一般长这样my-skill/ ├── SKILL.md # 技能说明书Agent 优先读取的部分 ├── src/ │ └── action.py # 实际执行逻辑的脚本 ├── requirements.txt # 依赖清单 └── examples/ └── demo-input.md # 示例输入帮助 Agent 理解用途这里的核心是 SKILL.md。它通常带一段 YAML 格式的元信息再配合正文描述。举个例子我之前写的一个架构图生成技能SKILL.md 长这样--- name: architecture-diagram description: 根据系统组件、调用关系的文字描述生成架构图文件。 当用户提到服务拓扑、模块关系、系统架构图时优先使用。 不适用于数据流图之外的其他图表比如流程图、时序图。 input: text: 系统架构的文字描述尽量包含组件名和依赖方向。 output: path: 生成的图片文件路径 --- # 架构图生成技能 1. 将 input.text 写入临时 markdown 文件 2. 调用 src/action.py --input temp.md --format png 3. 返回生成的图片路径这段描述里最有价值的是不适用于什么——这一点很多人会忽略。我在实测中发现只要在 description 里写清楚适用与不适用场景Agent 的调用准确率能明显提升因为它不再把流程图、时序图这类相似任务也错误地路由到这个技能上。1.3 热词里那些 Skills 从哪来官方、社区与自建热词里出现了不少乱七八糟的技能名比如前端开发 skills结构图 skillssuperpower skills等等。这些技能的来源基本可以归为三类官方发布的技能集合。例如 Claude 推出的 Superpowers Skills 这类打包好的技能库特点是覆盖面广、质量稳定适合直接当作起点。社区开发者维护的 skills 仓库。知名的有 Baoyu 的 skills 项目、各类 codex skills 集合等。社区技能的好处是五花八门总有你没想到的冷门场景但质量参差不齐使用前要自己 review。自己从零写的技能。这是最推荐的一种方式也是我反复修改最多的部分。自己的业务场景只有自己最清楚一个针对性强的私有技能比十个通用技能更管用。选择技能时我的标准很简单描述清晰、职责单一、依赖尽可能少。一个技能如果脚本要装一堆依赖或者它的职责边界模糊到连自己都不知道什么时候该被调用那最终结果一定是 Agent 胡乱调用或者干脆不调用。技能宁缺毋滥这是我跑了一段时间后最深的感受。2. 设计全能 Agent的技能组合先从场景拆解开始全能 Agent这个说法很容易让人上头总觉得技能加得越多越好。但我做了好几个月的实际体验是全能的本质是有针对性地覆盖高频场景而不是把一切可能的技能都塞进去。开始设计技能组合前先认真拆解一下你的 Agent 到底要给谁用、解决什么问题、每天大概要处理什么任务。2.1 先给 Agent 定位你的全能指什么我给自己 Agent 定位的使用者是我自己核心用途是围绕我的日常开发和工作流做辅助因此拆出来四个方向每个方向配一到两个核心技能不贪多方向技能名称典型场景核心产出编码开发code-generator生成可运行的代码文件、补丁代码文件或 diff图表生成architecture-diagram把系统描述转成架构图Mermaid 源码 PNG数据处理csv-insight分析表格数据、生成报告Markdown 报告部署运维deploy-check检查服务状态、日志关键词健康检查报告拆完之后你会发现Agent 每次能干活其实都是具体的一两个技能在起作用。真正让它显得全能的是 Agent 自己能在复杂任务里判断先用哪个技能、再衔接哪个技能。举个例子我让它做一次完整的服务梳理它会先调架构图技能画出当前服务拓扑再调 deploy-check 技能检查每个服务的健康状态最后把两张结果结合起来给出一份总结。这就是技能组合的价值而不是靠某一个技能包打天下。2.2 从零写一个自有技能以架构图为例写自有技能时我建议从最简单的脚本开始。还是拿架构图技能当例子我实际的动作脚本其实很短核心逻辑是两件事#!/usr/bin/env python3 import argparse, subprocess, pathlib def main(): parser argparse.ArgumentParser() parser.add_argument(--input, requiredTrue) parser.add_argument(--format, defaultpng, choices[png, svg]) args parser.parse_args() # 先把文本文件里的 Mermaid 代码渲染成图 out pathlib.Path(args.input).with_suffix(. args.format) cmd [mmdc, -i, args.input, -o, str(out)] if args.format svg: cmd.append(-t, default) subprocess.run(cmd, checkTrue) print(f图表已生成: {out.resolve()}) if __name__ __main__: main()整个技能的核心就两件事一是让 Agent 把用户的自然语言描述整理成 Mermaid 语法二是用mmdc这个命令行工具把语法渲染成 PNG 或 SVG。为什么选 Mermaid 而不是 draw.io 这类图形工具因为 Mermaid 是文本即结构LLM 生成起来非常自然文件可以进 Git 做版本管理改起来也方便不用手动拖拽。写这个技能时我踩了一个很典型的坑最开始我把 SKILL.md 的 description 写得太宽泛叫生成各类图表结果 Agent 在用户要流程图时也调用它生成的却是架构图风格的输出。后来我把 description 明确改为根据系统组件、调用关系的文字描述生成架构图不适用于流程图和其他类型图表误调用率立刻降了下来。2.3 技能之间的编排别让 Agent 只会单打独斗单技能能解决的问题终究有限真正的全能 Agent需要在一连串动作里灵活编排多个技能。从我实践来看编排模式有三种顺序调用。比如先拉取日志 - 再分析异常 - 最后画趋势图每个技能的输出自然成为下一个技能的输入。条件分支。Agent 看到 deploy-check 返回的检测结果后如果发现异常就走告警技能如果正常就输出报告。并行调用。有些任务之间没有依赖关系比如同时生成前端代码和结构图可以并行执行节省时间。要让 Agent 学会编排技能描述里也可以加一段典型使用链路说明比如在 SKILL.md 里写本技能经常与 deploy-check 搭配使用。我实测下来这种显式的链路提示比单纯依赖模型自己推理要稳定得多。3. 在腾讯云上把 Agent 真正跑起来服务器、域名、安全组技能体系设计好之后下一步就是让它能在公网上稳定运行。这一节我会完整走一遍腾讯云上的部署链路云服务器选型与初始化、二级域名申请与 HTTPS 配置、安全组规划。热词里好多人搜腾讯云怎么申请二级域名和腾讯云如何开放所有端口这两个问题我在真实项目中都处理过尤其第二个是必须纠正的坏习惯。3.1 云服务器选型与初始化Agent 服务的资源需求取决于你的技能脚本有多重。如果你只是跑一些 Python 脚本、调用外部 API那 2C4G 就够用但如果要本地跑稍微大一点的模型推理或者同时处理多个技能任务建议至少 4C8G。硬盘我给的是 100G SSD因为 Docker 镜像、日志、模型缓存都会占空间太小会频繁报警。初始化时我一般按这个顺序装环境# 更新系统包 sudo apt update sudo apt upgrade -y # 安装 Docker用于运行 Agent 服务和各类依赖 curl -fsSL https://get.docker.com | sh sudo systemctl enable --now docker # Node.js 与 Python sudo apt install -y nodejs npm python3 python3-pip git # Mermaid 渲染组件架构图技能会用到 npm install -g mermaid-js/mermaid-cli为什么强调用 Docker 承载 Agent 服务而不是直接在宿主机裸跑原因很简单Agent 的服务会频繁迭代依赖会变版本会升级。Docker 把环境固化在镜像里推送到镜像仓库后在任何一台服务器上都能一键拉起而且技能脚本要执行外部命令容器本身是一层很好的隔离边界避免 Agent 误操作影响宿主机。这一点在后面讲镜像推送时还会再提到。3.2 二级域名申请、解析与 HTTPS 配置腾讯云怎么申请二级域名这个问题的答案其实很简单二级域名不是申请来的而是你拥有一个主域名之后在云解析控制台里添加一条解析记录即可。很多人卡住是因为第一步就买域名去了实际上如果你已经有一个域名不管在哪个平台买的只要把 DNS 解析托管到腾讯云 DNSPod就可以直接添加子域名。具体步骤在腾讯云控制台搜索云解析 DNSPod添加你的主域名如果还没添加过。在域名下点击添加记录主机记录填agent记录类型选 A记录值填你的云服务器公网 IPTTL 默认 600 秒即可。保存后等待 1-5 分钟生效本机用nslookup agent.你的域名.com验证解析是否成功。拿到二级域名后下一步就是配 HTTPS。这一步我在早期偷懒跳过结果 WebSocket 连接被浏览器拦截、部分接口被运营商指指点点搞得很难受。现在我用的是 Caddy因为它自动申请和续期证书配置文件极短对个人项目非常友好。一个 Caddyfile 就能搞定agent.你的域名.com { reverse_proxy 127.0.0.1:8080 }Caddy 会自动从 Lets Encrypt 申请证书并配置 HTTPS重启之后域名就能直接以https://agent.你的域名.com访问了。如果你偏好 Nginx 腾讯云免费 SSL 证书的组合也可以但需要手动下载证书、在 Nginx 里配置证书路径、再每月设置自动续期比较繁琐。对大多数从零开始的 Agent 项目我建议直接用 Caddy。3.3 安全组为什么我劝你别开放所有端口热词里那串腾讯云如何开放所有端口真的是个危险信号。腾讯云的安全组是云服务器的第一道防火墙默认情况下只放行了 22 端口和 ICMP。很多人跑起服务来发现外网访问不通第一反应就是去开放所有端口这是典型的本末倒置。正确做法是只放行真正需要的端口。我目前的放行策略如下端口用途是否对外开放22SSH 登录仅限办公 IP80HTTP 跳转 HTTPS是443HTTPS 服务是8080Agent 服务 API按需或走 Nginx 反代4000Litellm 网关仅内网6379Redis禁止对外开放在腾讯云控制台配安全组的路径是云服务器实例 - 安全组 - 配置规则 - 入站规则。把上面这个表按你的实际需求填进去比全部放行安全一个量级。尤其 Redis、数据库这类服务一旦暴露在公网上扫描机器人分分钟教你做人。我之前就因为图省事把 6379 开放过结果第二天日志里全是暴力破解尝试还好密码够复杂才没出事。4. 部署运维踩坑现场Redis 密码修改与镜像推送的完整复盘部署流程走通之后真正的考验才刚刚开始。热词里有人提到在腾讯云服务器上安装 redis修改 redis 密码之后再重启 redis 就一直不这个问题我在生产环境里撞见不止一次。下面我把完整排查链路写出来同时也把 Docker 镜像推到腾讯云容器镜像服务时最容易卡住的几个点一并讲透。4.1 最经典的坑改了 Redis 密码重启后服务起不来问题描述很典型Redis 原本运行正常在 redis.conf 里设置了requirepass新密码然后重启结果服务直接崩了或者看起来起来了但客户端全部连接失败。我当时的排查链路是这样的第一步看服务状态和日志systemctl status redis journalctl -u redis -n 50 --no-pager日志里最关键的信息往往是这两种之一。一种是配置语法报错比如Bad directive or wrong number of arguments这通常意味着配置文件里有非法指令或者从文档里复制的配置带了不可见字符另一种是权限问题比如Opening config file /etc/redis/redis.conf: Permission denied多半是配置文件被移动过、属主不是 redis 用户。第二步检查 systemd 启动参数指定的配置文件路径是不是你改的那个systemctl cat redis | grep ExecStart这一步特别容易翻车。很多人下载安装包后自己编译redis 实际跑的是/usr/local/redis/redis.conf但你改的是/etc/redis/redis.conf。改的文件根本没被加载那不管怎么改服务行为都不会变。第三步检查 redis.conf 里daemonize和 systemd 是否冲突。如果你用了daemonize yes而 systemd 的 Redis 服务本来就要求前台运行那重启时会出现端口被占用、进程启动后又退出等一系列诡异现象。在 systemd 环境里daemonize必须设为no。第四步验证新密码是否被正确加载redis-cli -a 你的新密码 ping # 期望返回 PONG修完之后我还会顺手检查一下业务端的连接配置因为服务本身没问题不代表调用方没问题。很多改完密码后一直连不上的案例最后都发现是业务代码里的 Redis 连接字符串没有同步更新。如果你是用 Docker 跑的 Redis还需要额外确认容器内加载的配置路径和宿主机挂载路径是否一致。我习惯把 redis.conf 放到/data/redis/redis.conf启动命令里显式加redis-server /data/redis/redis.conf并且在 healthcheck 里同步更新密码否则镜像重启会导致健康检查一直失败。4.2 腾讯云容器镜像服务推送镜像的完整操作Agent 服务用 Docker 化之后推送镜像到腾讯云容器镜像服务TCR是必须掌握的技能。最常见的报错是denied: requested access to the resource is denied十有八九是登录时凭据搞错了——腾讯云容器镜像服务的登录密码不是你的账号密码而是控制台里单独申请的访问凭证。完整操作命令如下# 1. 登录用户名是账号 ID密码是访问凭证 docker login ccr.ccs.tencentyun.com --username 你的账号ID --password 你的访问凭证 # 2. 给本地镜像打上仓库地址的 tag docker tag my-agent:latest ccr.ccs.tencentyun.com/agent-project/agent-service:v1.0.0 # 3. 推送 docker push ccr.ccs.tencentyun.com/agent-project/agent-service:v1.0.0 # 4. 在服务器上拉取运行 docker pull ccr.ccs.tencentyun.com/agent-project/agent-service:v1.0.0 docker run -d --name agent -p 8080:8080 ccr.ccs.tencentyun.com/agent-project/agent-service:v1.0.0这里的坑主要在两端一是 tag 必须包含完整的仓库地址前缀否则 docker push 会误判成推送到 Docker Hub二是命名空间要先在控制台创建好并且登录用的账号要有对应命名空间的读写权限。推送成功后记得在服务器上确认拉取的是最新版本。我吃过一次亏本地推了 v1.0.0服务器上还在用 old 版本排查半天才发现是拉取命令里写死了旧版本号。后来我在部署脚本里一律用docker pull后再用docker-compose up -d --force-recreate来更新避免版本混乱。4.3 Agent 服务的健康检查与自动拉起部署完成后别指望服务永远不挂。Agent 服务偶尔会因为外部 API 超时、技能脚本崩溃、内存不足等原因退出这时候全靠人肉重启是不现实的。我的做法是用 docker-compose 定义健康检查和自动拉起策略services: agent: image: ccr.ccs.tencentyun.com/agent-project/agent-service:latest restart: unless-stopped healthcheck: test: [CMD, curl, -f, http://localhost:8080/healthz] interval: 30s timeout: 5s retries: 3restart: unless-stopped保证进程退出后自动重启healthcheck定期探测健康接口一旦连续失败就会标记为 unhealthy方便你在监控告警里及时感知。日志方面我会在容器日志里输出结构化 JSON配合腾讯云日志服务或者简单的journalctl -u docker来排查问题。5. 生产环境选型沉淀编排层、模型网关与持续迭代当一个 Agent 稳定跑起来技能也开始积累了这时候再回头看剩下的工作已经不是写技能那么简单而是整个系统的选型与治理。这个章节聊聊我的一些沉淀重点讲模型网关和编排层的选择以及上线后怎么让 Agent 越用越顺手。5.1 模型网关的必要性为什么我在生产环境用 Litellm ProxyAgent 服务不能只绑定一家模型供应商原因很现实不同任务对模型的性价比要求不同。简单分类任务用廉价小模型就够复杂代码生成需要顶级大模型。为了统一管理多个模型端点我在生产环境部署了 Litellm Proxy提供一个 OpenAI 兼容的网关层。一份最小的配置文件大概长这样model_list: - model_name: cheap-llm litellm_params: model: openai/xxx api_key: os.environ/XXX_API_KEY - model_name: strong-llm litellm_params: model: anthropic/claude-sonnet-4-xxx api_key: os.environ/ANTHROPIC_API_KEY启动命令docker run -d \ --name litellm \ -p 4000:4000 \ -v $(pwd)/config.yaml:/app/config.yaml \ ghcr.io/berriai/litellm:main-latest \ --config /app/config.yaml --port 4000部署之后Agent 服务只跟http://127.0.0.1:4000打交道切换模型、加限流、查用量都只改网关配置不动业务代码。对于 Agent 这种需要频繁调用模型的服务来说这个解耦非常值得。5.2 Agent 编排层选型框架、平台还是自己写现在市面上的 Agent 编排方案非常多从 LangGraph 这类开发框架到 Coze 这类可视化平台再到自己写一个简单的工具循环选择很多。我的建议是别一开始就上重框架先用自己的方式跑通最小闭环。一个最简的自写工具循环核心逻辑无非是把用户问题发给模型 - 模型返回工具调用指令 - 执行对应技能 - 把执行结果发回模型 - 模型生成最终回答。这套逻辑写起来不到一百行代码但能让你对 Agent 的运作机制有实实在在的理解。等技能数量多了出现复杂的条件分支、人机协同或者状态持久化需求时再迁移到 LangGraph 这类框架也不迟。如果你偏向平台化腾讯云开发者社区里也有不少 Agent 编排的实践文章关键看你的团队里有没有人愿意长期维护这套系统。我的个人体会是对个人开发者和中小团队基于脚本和轻量框架自建可控性和迭代速度往往比拖拽式平台更好。5.3 上线之后才是开始技能使用率、版本管理与迭代技能上线只是起点。我每隔一周会做一次技能运行数据的回顾重点看三个指标每个技能的调用次数、成功率、平均耗时。日志统一用 JSON 格式输出方便直接用命令行分析docker logs agent --since 7d | grep skill_name | jq group_by(.skill_name) | map({skill: .[0].skill_name, count: length})通过这套简单统计我发现过一个问题某个技能调用量很高但成功率一直徘徊在 60% 左右。回看日志才发现是这个技能的 SKILL.md 里对输入参数的描述太模糊Agent 传了几种不同的格式脚本经常解析失败。后来我把参数格式的示例写得更明确成功率直接拉到了 90% 以上。技能也要做版本管理。我会把整个 skills 目录放进 Git 仓库每次修改 SKILL.md 或脚本都提交一次并写上 changelog。改描述、改脚本后要重新测试一遍典型调用路径因为模型对于新描述的响应方式可能发生变化。这个过程没有终点但正是它让全能 Agent一点点名副其实。我现在还在持续扩展新的技能最近在把内部的接口文档自动生成技能也接入进来。如果你也想做自己的全能 Agent我的建议是先选一条高频核心链路比如日志分析 架构图生成把它跑稳定跑顺畅再逐步扩充技能库。每加一个新技能前都认真写清楚它的适用边界和依赖条件这样积累出来的 Agent 才会越来越像一个真正靠得住的工作伙伴而不是一个什么都会一点、但什么都不精的玩具。
返回列表