
自从开始折腾 Agent 开发我最大的感受就是搜一堆概念帖不如自己上手养一个。这次我在腾讯云上把一个只会“接 API 聊天”的 Demo逐渐养成一个能巡检服务器、写周报、回私域文档问题的“全能 Agent”过程中把 AI Skills、容器部署、Redis、域名解析这些环节完整走了一遍。这篇文章就是这次养成的完整复盘重点是腾讯云 AI Skills 的最佳实践。我会结合自己的踩坑经历把 Agent 和 Skill 的设计边界、云端基座搭建、技能封装逻辑、以及上云后常见的 Redis 密码失效、Agent 执行中断等问题的排查过程全部摊开讲。无论是刚入门的开发者还是已经跑过几个 Demo 想往生产环境推的人这篇都能帮你少走不少弯路。1. 先搞清楚你要养的 Agent 到底是个什么东西很多人在第一步就走歪了。我最早理解的 Agent 就是“调用一下大模型接口让它能聊天”后来才发现真正的 Agent 是“能自己决定调用哪个工具、按什么顺序执行任务”的系统。这个差异直接决定了后边所有的设计。1.1 Agent、Skill、Tool 三者的边界我以前也把这三个概念混成一团直到我把它们拆成三层才彻底想明白。Agent是调度决策层负责理解用户意图、拆解任务、决定调哪个 Skill、按什么顺序执行。它不关心底层细节只关心“下一步做什么”。Skill是能力封装层把一个完整的业务动作打包成可复用的能力模块。比如“查询服务器监控指标”是一个 Skill“生成巡检周报”是另一个 Skill。Tool是执行落地层是 Skill 内部真正去调用的外部接口或命令比如云 API、数据库查询、Shell 脚本。用一个生活类比Agent 是项目主管Skill 是公司里的 SOP 手册Tool 是真正干活的执行员工。主管不需要懂每个员工的技术细节它只需要知道“遇到什么情况翻哪本手册、让哪个员工干活”。这个分层最大的好处是当我新增一个能力时不用去改 Agent 的主流程只需要新增一个 Skill然后在 Skill 清单里注册一下就行。Agent 本身保持稳定扩展全靠 Skill。1.2 动手前先把任务清单列出来在选框架、写代码之前我建议你先拿出一张纸把你希望 Agent 干的活全部列出来。我当时写的是任务需要的外部工具Skill 类型依赖服务查询云服务器 CPU、内存、磁盘云监控 API数据查询型 Skill腾讯云 API 密钥定时巡检并输出报告定时触发服务流程编排型 Skill对象存储 / 消息推送回答私有知识库问题向量数据库检索增强型 Skill向量库 / Embedding 服务生成每日工作周报大模型 模板引擎内容生成型 SkillLLM API执行自动化测试脚本测试框架命令执行型 Skill服务器运行环境列完这张表你才会意识到Agent 的核心价值不是“会聊天”而是“把一堆零散能力串成一个自动化的闭环”。后面所有关于 Skill 的设计、部署、测试都以这张清单为原点。2. 腾讯云上搭第一台 Agent 宿主基座选型不能返工2.1 服务器配置与系统镜像的选择我选的是一台腾讯云标准型服务器4C8G系统镜像用的 Ubuntu 22.04 LTS。这个配置对跑一个 Agent 宿主服务加若干 Skill 来说不算奢侈也谈不上浪费。为什么不选 Windows不是 Windows 不行而是 Agent 生态、Docker 容器、Python/Node 运行时在 Linux 下的支持更顺手出问题搜到的解决方案也更多。在购买页有两个坑要注意带宽Agent 服务本身流量不大但如果你做的 Skill 要拉网页、传文件2Mbps 的小水管会非常难受我直接选了按流量计费峰值带宽拉高日常跑下来费用反而可控。安全组创建时默认只放行 22 端口SSH如果你打算直接用 IP 加端口访问 Agent 的 Web 界面会连不上。但我不建议现在就开放 80/443先把应用跑起来再统一用域名加 HTTPS 暴露这样更安全。2.2 用 Docker 镜像服务托管 Agent 运行环境我强烈建议 Agent 服务从一开始就用 Docker 容器化。原因很简单Agent 依赖的 Python 包、Node 模块、系统库非常多直接装在宿主机上换一台机器或者重装系统就是一场灾难。我的流程是这样的本地 Dockerfile 构建好镜像打上版本标签推到腾讯云容器镜像服务TCR然后在云服务器上拉取运行。构建和推送的核心命令长这样# 构建镜像注意平台参数避免在 ARM 服务器上拉 x86 镜像 docker build --platform linux/amd64 -t ccr.ccs.tencentcloud.com/my-agent/agent-core:v1.2.0 . # 登录容器镜像服务 docker login ccr.ccs.tencentcloud.com --username 你的账号ID # 推送镜像 docker push ccr.ccs.tencentcloud.com/my-agent/agent-core:v1.2.0提示TCR 的镜像仓库地址一般形如ccr.ccs.tencentcloud.com/命名空间/镜像名:标签。登录用户名不是你的登录邮箱是腾讯云账号 ID这个我当时找了好一会儿。在服务器上拉取时如果服务器和镜像仓库在同一个地域走内网地址会快很多这个细节在小带宽机器上尤其明显。2.3 二级域名、HTTPS 与公网暴露的正确姿势跑通之后总不能天天用http://IP:8080去访问 Agent 控制台。一方面 IP 难记另一方面浏览器对非 HTTPS 接口的限制越来越多Agent 要去调用摄像头、麦克风之类的能力时非 HTTPS 页面会直接拦掉。申请二级域名的方式很简单在腾讯云云解析 DNS 控制台添加一条 A 记录主机记录填agent记录值填你服务器的公网 IP这样agent.yourdomain.com就能解析过来了。然后把 80/443 端口在安全组里放行用 Nginx 做反向代理把域名转发到本机的 Agent 服务端口。一个最简 Nginx 配置大概是这样server { listen 80; server_name agent.yourdomain.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }之后再申请一张免费 SSL 证书把 80 端口的请求 301 跳到 443浏览器就不会再报不安全提示。域名解析加 HTTPS 这一套下来你的 Agent 才算有了一个“体面”的对外入口。3. AI Skills 的核心机制把“会聊天”升级成“会干活”3.1 Skill 不是 Prompt是可复用的能力包在腾讯云 AI Skills 的语境下Skill 本质上是一个结构化的“能力单元”它有明确的输入输出协议、错误处理逻辑和可观测性设计。它不是一段写死的 Prompt而是让 Agent 在运行时能稳定复用的“技能”。两者区别我用一个例子说明如果你让 Agent“帮我把服务器内存使用率查出来”纯 Prompt 的做法是把这句话直接丢给大模型让模型“自由发挥”结果它可能编一个假的数字给你。Skill 的做法是Agent 识别到这个请求属于“服务器状态巡检”技能然后按预设协议去调用云监控 API拿到真实数据再组织成回答。这个“不靠模型编、靠真实工具取数”的转变是 Agent 从玩具走向生产力的分水岭。3.2 我的第一个 Skill服务器状态巡检我设计的第一个 Skill 是“服务器状态巡检”任务定义很简单定时获取腾讯云服务器的 CPU 使用率、内存占用、磁盘利用率和公网带宽生成一份指标摘要。这个 Skill 的输入参数包括服务器实例 ID监控时间范围默认最近 5 分钟输出格式默认表格形式运行流程是三步调用云监控 API 拉取原始指标、对指标做简单聚合分析、把结果渲染成可读的文本报告。最核心的设计是超时控制云 API 偶尔会慢如果 15 秒内没返回Skill 必须主动报错并让 Agent 转而去走兜底逻辑不能无限等下去。我还给这个 Skill 加了简单的状态缓存。同一台服务器在 1 分钟内的指标不会重复请求直接命中缓存省了不少 API 调用次数。这个思路后来扩展到了很多其他 Skill 上效果很明显。3.3 Skill 的注册与编排让 Agent 知道“什么时候该用谁”有了 Skill还得让 Agent 知道“我有哪些技能、每个技能是干什么的”。这一步靠的是技能清单注册和描述信息。以函数调用型 Agent 为例每个 Skill 都会注册成一个“可被模型识别的工具函数”模型根据用户请求和函数描述来决定要不要调用。这里有一个非常重要的经验函数描述写得越精确模型选对的概率越高。别写“获取服务器监控数据”这种含糊描述要写“当用户询问 CPU 使用率、内存占用、磁盘空间、带宽等服务器运行指标时使用非此类问题不要调用”。错误描述获取服务器监控数据正确描述获取腾讯云服务器的 CPU 使用率、内存占用、磁盘空间、带宽等监控指标。适用于用户查询服务器健康状态、巡检、排障等场景。这个细节解决了我早期一个老大难问题模型经常在用户问“帮我写个周报”时去调用监控 Skill就是因为描述里没写清楚边界。后来我花了一下午把所有 Skill 的描述全部重写了一遍加了“适用于”“不适用于”字样误调用的概率直线下降。编排层面我建议你把复杂任务拆成多个 Skill 的串联。比如“生成巡检周报”这个任务实际上是“拉取一周监控数据”数据 Skill加“按照模板生成周报文案”生成 Skill加“推送周报到群机器人”通知 Skill三个 Skill 的组合。Agent 作为编排者负责把这三步串起来每个 Skill 只干一件事干完就返回值不越俎代庖。4. 一步步把 Agent 养起来完整链路复盘4.1 本地先跑通最小闭环再上云很多新手一上来就在生产服务器上写代码改一行重启一下效率极低。我的习惯是本地先跑通最小闭环再推到云端。最小闭环指的是Agent 进程能起来、能连上大模型 API、能正确调用一个 Skill、能返回结构化结果。我用的技术栈是 Python FastAPI一个非常精简的 Agent 宿主服务核心代码结构大概是这样的from fastapi import FastAPI from pydantic import BaseModel app FastAPI() class ChatRequest(BaseModel): message: str app.post(/chat) def chat(req: ChatRequest): # 1. 调用大模型让模型决定调用哪个 Skill intent llm_detect_intent(req.message) # 2. 根据意图分发到对应 Skill if intent query_server_status: result server_status_skill.run() else: result fallback_skill.run(req.message) # 3. 返回结果 return {reply: result}整个服务里不写死任何密钥所有 API Key 从环境变量读取。本地我用.env文件云端用 Docker 的环境变量注入。这个习惯最大的好处是代码可以直接推到公共仓库不用担心密钥泄露。4.2 记忆这关怎么过临时缓存与长期记忆分开管Agent 的记忆是我从头到尾都觉得棘手的问题。短期记忆好办在对话上下文里传就够了模型能记住前几轮的对话内容。但长期记忆不行比如 Agent 需要记住“用户上次把某个配置改成了什么”这个信息如果每次都要靠模型推理既费钱又不准。我的方案是分两层短期记忆直接放在会话上下文里随请求传给大模型。上下文超过阈值时做摘要压缩把前面的对话凝练成几句要点再继续。长期事实用 Redis 做 KV 缓存把一些固定知识存起来。比如服务器实例 ID 对应名称、用户常用配置、上次巡检结果这些数据每次 Skill 执行后同步更新到 Redis下次查询直接命中。这个方案让我 Redis 成了 Agent 的“第二大脑”。不过也正因为我把 Redis 用得比较重后面踩了一个改密码重启失败的坑这部分放到下一章详细讲。4.3 让 Agent 在云端常驻systemd 服务的配置参考如果直接用 Docker 跑 Agent容器退出后就什么都没有了。为了保证服务常驻我写了一个 systemd 服务来托管容器启动和自动重启。配置文件放在/etc/systemd/system/agent-core.service[Unit] DescriptionAgent Core Service Afterdocker.service Requiresdocker.service [Service] Restartalways RestartSec10 ExecStart/usr/bin/docker run --rm --name agent-core \ --env-file /opt/agent/.env \ -p 8080:8080 \ ccr.ccs.tencentcloud.com/my-agent/agent-core:v1.2.0 ExecStop/usr/bin/docker stop agent-core [Install] WantedBymulti-user.target启动服务后再执行systemctl enable agent-core服务器重启后 Agent 也会自动拉起。这个配置看起来简单但让我少操了很多心再也不用半夜爬起来手动重启容器了。5. 上云后撞上的三个大坑与完整排查过程5.1 Redis 改密码后重启一直失败问题出在“改了但没改全”这个坑我从一个技术群里看到过自己也实际遇到。场景是在腾讯云服务器上装了 Redis修改密码之后重启服务结果 Redis 一直起不来就算起来了客户端连接也报错。完整的排查链路是这样的先看 Redis 日志。在/var/log/redis/redis-server.log里发现了WRONGPASS invalid username-password pair和Cant handle RDB format version的报错这基本说明服务起来了但认证没过。检查 Redis 配置文件/etc/redis/redis.conf发现requirepass确实改了但masterauth没改。如果你的 Redis 开着主从同步从节点同步时用的是masterauth里的密码主节点改了密码从节点没同步改主从复制就会持续报错。进一步发现我之前用redis-cli改了密码后并没有把改动写回配置文件导致重启后 Redis 重新加载了旧配置密码还原成旧密码。最后还排查到一个隐藏问题Redis 的 RDB 持久化文件里可能记录了旧密码相关的数据版本格式不兼容导致加载失败。正确的修法分四步# 第一步停止 Redis 服务 systemctl stop redis-server # 第二步备份配置文件再修改 requirepass 和 masterauth cp /etc/redis/redis.conf /etc/redis/redis.conf.bak vim /etc/redis/redis.conf # 第三步删除可能损坏的 RDB/AOF 持久化文件之前先备份 cp /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bak # 第四步启动服务并用密码验证 systemctl start redis-server redis-cli -a 你的新密码 ping注意如果你只是临时改密码测试用CONFIG SET requirepass就行但如果要重启后仍然生效必须改配置文件。这是我这次踩坑最深的教训。5.2 Agent 执行中途terminated due to error超时和上下文爆掉是主因Agent 在跑复杂任务时经常会在某一个环节突然报execution terminated due to error.就断了。这种错误观感非常糟糕但好消息是绝大多数情况下问题不在大模型而是出在你自己写的调度逻辑上。我梳理出三个最可能的原因一是工具调用超时。某个 Skill 去请求外部 API外部服务响应慢了Agent 等待超过模型侧设定的超时时间任务被强制终止。解决办法是给每个 Skill 的请求设置独立的超时时间比如外部 API 请求不能超过 15 秒同时设置重试机制第一次失败后等待 3 秒再试一次。二是上下文长度爆掉。当你把很多轮对话、检索结果、中间步骤全部塞给模型时token 总数超过模型上下文窗口请求直接报错。解决思路是在每次循环后做上下文裁剪把不重要的历史内容压缩成摘要只保留关键信息。三是 Skill 内部没有异常处理。当某个 Skill 内部写了运行期错误比如调了一个不存在的字段、除数为 0异常会直接抛到 Agent 主进程导致整个任务中断。我在每个 Skill 的入口都加了一层 try-except把异常包装成标准错误信息返回给 AgentAgent 看到错误后可以转而去执行兜底逻辑而不是直接崩溃。这里有一个真实案例我的“巡检周报”Skill 在拉取一周监控数据时某天因为云 API 返回的数据格式临时变更字段名从cpu_usage变成了cpuUsed解析代码直接抛了 KeyError整个周报任务中断。后来我在异常捕获里加了一条日志把原始响应存下来才发现是字段名变了。这个教训说明Skill 里任何一步都不能假设外部数据格式永远不变。5.3 注册提示“网络环境异常”和安全组的正确配置法有朋友注册腾讯云账号时遇到过“您所处的网络环境异常无法进行注册”的提示。这种提示通常是风控系统判定当前网络出口存在风险和本地网络、浏览器指纹、运营商 IP 都有关系。我实测有效的排查步骤是先检查本地 DNS 是否被污染把 DNS 刷新一下不同系统的刷新命令不一样再换一个浏览器或无痕窗口试一次如果还不行换成手机热点登录。这些动作都解决不了就隔一段时间再试因为运营商出口 IP 可能被风控临时标记了。另一个和网络相关的关键操作是安全组配置。安全组是云服务器的第一道防火墙配置错了轻则服务不可访问重则把数据暴露在公网。我的建议是安全组入站规则只开真正需要用到的端口端口用途建议22SSH 远程管理建议改为仅允许自己的固定 IP 访问443HTTPS 访问 Agent 控制台开放给公网80HTTP 跳转到 HTTPS开放给公网也可不开放直接用 4436379Redis 默认端口禁止公网访问只允许内网或本机访问8080Agent 服务端口禁止公网直连只通过 Nginx 反代访问我自己就吃过亏Redis 默认端口 6379 如果对公网开放而且密码还是弱口令扫描器不到半天就能暴力破解。现在我的安全组规则是 6379 端口只允许服务器内网 IP 访问外部一律阻断。6. 把 Agent 从“演示品”养成“生产力”测试、安全、成本三件套6.1 自己搭建 Agent 做自动化测试Agent 这个系统比传统 Web 服务更难测因为它每一步都调大模型而模型输出有随机性。但你不可能每次都靠肉眼去验证结果所以一套自动化回归测试是必须的。我的做法是为每个 Skill 准备一组固定输入的测试用例断言输出中的关键字段是否合法。比如“服务器状态巡检”这个 Skill给它传入一台测试实例的 ID断言返回结果里包含cpu_usage、memory_usage、disk_usage三个字段且数值都在 0 到 100 之间。用 pytest 写起来很直接import pytest def test_server_status_skill(): result server_status_skill.run(instance_idins-test-001) assert cpu_usage in result, 返回结果缺少 CPU 使用率 assert 0 result[cpu_usage] 100 assert 0 result[memory_usage] 100 assert report in result[output_format]计这个测试挂到定时任务里每天跑一遍Skill 里的数据解析逻辑一旦被外部 API 变更破坏当天就能发现。这种“基础设施化”的保障让 Agent 的迭代速度反而比手工测试时代更快因为你有信心改了代码不会搞坏旧功能。6.2 安全加固密钥、权限和日志一个都不能少Agent 这类系统权限很大它可能要访问数据库、调用云 API、执行命令一旦被攻破攻击者相当于拿到了你线上环境的一把钥匙。所以安全加固我做得比较重。首先是密钥管理。所有 API Key、数据库密码、云密钥一律从环境变量注入不要写进代码或者配置文件里。更进一步可以用密钥管理服务来轮换密钥定期更换避免密钥泄露后长期有效。其次是权限最小化。给 Agent 调用的云 API 密钥只授予它真正用到的权限比如只读的云监控权限、只读的对象存储权限绝不给全量管理员权限。万一密钥泄露攻击者能做的事也被限制在很小的范围。第三是日志脱敏。Agent 的日志里经常会出现用户输入的敏感信息比如账号、手机号、token。我在日志模块里加了一层过滤凡是匹配手机号、身份证号、密钥特征的内容一律替换成***保证日志可以放心入库。6.3 成本控制钱要花在刀刃上Agent 跑起来之后最大的成本是大模型调用。我的经验是三个原则减少无效调用。能在 Skill 内部用规则解决的问题就不要调大模型。比如判断用户输入属于哪个意图如果关键词匹配能确定就别把文本丢给模型做识别。一次模型调用可能就是几厘钱但日积月累就是不小的数字。缓存优先。对于重复性高的查询类 Skill把结果缓存到 Redis设置合理的过期时间缓存命中后不调用模型只做简单格式化输出。我在“服务器状态巡检”上加了 1 分钟缓存后每天模型调用量下降了约 30%。分级使用模型。重要任务用更强、更贵的模型简单任务用便宜、快速的模型。比如巡检报告生成用高端模型保证质量日常闲聊和简单问答用轻量模型控制成本。只要在设计时把模型抽象成可配置项切换成本很低。7. 多 Skill 协作与后续扩展从“单兵”到“团队”当你的 Agent 积累了十几个 Skill 之后会遇到一个比我前面讲的任何问题都更“高级”的麻烦多个 Skill 之间怎么协作才不会互相打架。我现在的做法是给 Skill 增加依赖声明。比如“生成巡检周报”依赖“拉取监控数据”“拉取监控数据”依赖“获取服务器列表”。在执行时Agent 会先检查依赖链按顺序逐个调用而不是一窝蜂全启动。为了让这个编排过程可视化我干脆做了一个消息队列每个 Skill 执行完把结果写到队列里下一个 Skill 从队列取数据。这样一来单个 Skill 挂了不会影响其他 Skill整个流程还容易重试。关于多 Agent 协作我的建议是不要一开始就搞。多个 Agent 之间的通信、记忆共享、冲突处理复杂度是指数级上升的。先把一个 Agent 的 Skill 体系打磨扎实比盲目上多 Agent 架构务实得多。后续我计划扩展的方向有三个一是把长期记忆从 Redis 升级成真正的向量数据库让 Agent 能按语义检索历史决策记录二是接入语音输入输出让 Agent 通过电话或语音助手来触发三是给 Agent 加一层“自我保护”机制当它发现某个任务风险过高时主动停下来向用户确认而不是闷头执行。养一个 Agent 的过程跟带一个新人很像先给它定清晰的职责边界再给它配好趁手的工具中间犯了错不要急着骂去看日志、找根因、打补丁最后它就能替你扛起越来越多的事。我现在这台腾讯云服务器上的 Agent每天自动巡检、写周报、回常见问题已经稳定跑了一个多月。最让我欣慰的倒不是它变“全能”了而是它出问题时我都能在三十分钟内定位到根因——这种掌控感才是做 Agent 开发最值钱的东西。