腾讯云上构建多技能AI Agent:AI Skills设计、部署与排错实战

📅 发布时间:2026/9/7 17:03:56
腾讯云上构建多技能AI Agent:AI Skills设计、部署与排错实战
这段时间我在腾讯云上把一个只会聊天的机器人磨成了一个能写代码、能查日志、能自己生成报告的多技能 Agent。期间踩了一堆坑也把一套“AI Skills”的设计方法和部署流程跑通了。今天写这篇是给同样想在云服务器上“养” Agent 的朋友一份可以直接上手的路线图里面不只讲概念更多是我在腾讯云上实操时验证过的配置和排查经验。这篇内容主要讲四件事Agent 和 AI Skills 到底是什么关系Skills 怎么设计才能让模型不乱调用在腾讯云上怎么把整套东西跑起来以及我实际运行中遇到的报错和排查思路。适合正在做 Agent 开发、想给自己的机器人加技能、或者想从零搭一个带工具调用的自动化助手的同学。如果你已经跑通了多工具 Agent可以直接跳到第 4 节看看有没有你没踩过的坑。1. 先把思路捋清楚Agent 和 AI Skills 到底是什么关系1.1 从“会聊天”到“会干活”大模型的本质是文本生成器。你让它写一首诗、总结一篇文章它很擅长但你要它帮你读一下服务器日志、执行一段 Python 脚本、把结果写进某个文件它做不到。因为它不掌握“执行”的能力。Agent 解决的是“决策”问题它负责理解用户意图、拆解任务、决定下一步调用什么工具、最终把结果组合成人话。而 AI Skills 解决的是“执行”问题它把一个个具体能力封装成标准模块Agent 按需加载。打个比方大模型是大脑Agent 是坐在办公室里的调度员AI Skills 是调度员手边的工具箱。调度员不需要知道电钻内部怎么工作他只要知道“需要打孔的时候去工具箱第三层拿电钻按一下开关就行”。对应到技术实现上Agent 不需要知道查日志的脚本怎么写它只需要知道“有个技能叫 log_inspector当用户问日志相关问题时调用它传一个 service 参数”。最近总有人问 skill 和 agent 的区别。我的回答很直接Skill 是能力单元Agent 是使用能力单元并做决策的实体。同一个 Skill 完全可以让多个 Agent 复用比如“python_executor”这个技能放到编程助手 Agent 里它能用放到数据分析 Agent 里它也能用。把能力抽象成 Skill本质上是为了复用和隔离复杂度。1.2 为什么用 AI Skills而不是把所有逻辑塞进 Prompt很多初学者和我刚开始一样喜欢把操作步骤、代码模板、注意事项全写进 System Prompt。刚开始还行一旦技能超过三四个Prompt 就变得巨大。每次请求都在烧 Token模型也经常“顾头不顾尾”后面的步骤容易忘。Skills 的思路是把“怎么做”从 Prompt 里挪到独立文件里Prompt 里只保留“技能名 一句话描述”模型看到任务时再按需读取技能详情。这么做有几个实实在在的好处每个技能可以单独维护、单独测试。哪个技能挂了就修哪个不会影响其他功能。技能文件可以全部放进 Git做版本管理。我之前重构过一版日志分析技能改坏了随时能回滚。新增能力只需要加一个文件夹不需要改 Agent 主程序。对就是这么简单。模型按需加载不被无关的说明干扰。技能多了以后如果全塞进 Prompt模型反而不知道选哪个。“按需加载”是 Skills 的核心价值。你在电脑上装了很多软件但操作系统不会把所有软件都驻留内存用到哪个才启动哪个。AI Skills 也是一样的道理。1.3 为什么选腾讯云当训练场跑 Agent 其实不一定需要很高配置的服务器因为推理通常走云端大模型 API本地服务器主要承担 Agent 调度和 Skills 执行。我用的是腾讯云轻量应用服务器2核4G系统 Ubuntu 22.04磁盘 60G日常跑 Agent 加十几个常用技能完全够用成本也不高。选腾讯云还有几个很实际的原因。第一安全组和系统防火墙可以协同控制端口安全性容易做。第二如果你顺便把 Redis、MySQL、对象存储也放到同一个云账号下内网互通延时低后续扩展方便。第三云监控可以直接盯着服务器和 Agent 进程出问题不用自己造轮子。把 Agent 部署在云上的另一个好处是它可以 7x24 小时挂着变成一个真正的“后台助理”。本地笔记本一关Agent 就没了云服务器没这个问题。2. AI Skills 的设计规范练好基本功2.1 一个 Skill 的标准长相一个 Skill 就是一个文件夹里面至少包含一个 SKILL.md 和若干可执行脚本。SKILL.md 是给大模型看的说明书用 Markdown 写清楚这个技能能做什么、什么时候用、输入输出是什么、有哪些注意事项。脚本是真正干活的可以是 Python、Shell 或 Node.js。依赖和测试也放在同一个目录下方便整体迁移。我常用的一个技能目录长这样skills/ ├── python_executor/ │ ├── SKILL.md │ ├── main.py │ └── requirements.txt ├── log_inspector/ │ ├── SKILL.md │ ├── main.py │ └── requirements.txt └── ops_load/ ├── SKILL.md ├── main.py └── requirements.txtSKILL.md 的头部建议写一个 YAML 格式的元信息块。这里用我一直在用的 python_executor 举例--- name: python_executor description: 当用户需要执行 Python 代码、计算数值、格式化数据或处理文件时使用。 --- # Python 执行器 执行一段用户提供的 Python 代码返回 stdout 和 stderr。 ## 输入参数 - code: 必填要执行的 Python 代码字符串 - timeout: 选填超时秒数默认 30 ## 使用注意 - 代码在沙箱中运行禁止访问生产环境敏感密钥。 - 如果代码超过 500 行拆成多个子任务。对应 main.py 的核心逻辑很简洁import json import subprocess import sys def execute(code: str, timeout: int 30): try: result subprocess.run( [sys.executable, -c, code], capture_outputTrue, textTrue, timeouttimeout, ) return json.dumps({ status: ok, stdout: result.stdout[-2000:], stderr: result.stderr[-1000:], }) except Exception as e: return json.dumps({status: error, message: str(e)})这里有两个最佳实践一是脚本要有独立入口输入输出尽量结构化二是返回值控制在合理长度内。我之前试过把完整 stdout 全返回给 Agent结果上下文没几轮就被塞满了。现在统一只保留 stdout 末尾 2000 字符大部分场景都够用。2.2 写 Skill 描述的三条经验第一描述要写“触发条件”而不是实现原理。模型是根据 description 决定要不要调用这个技能的所以你要写“当用户提到日志、报错、排查问题时使用”而不是写“读取 /var/log/app.log 文件”。后者让模型很难判断什么时候该调。第二参数能少就少必填和可选分开。一个技能如果要求五个参数模型在生成参数时很容易缺胳膊少腿。我的经验是核心参数控制在一到三个并且给足默认值。比如查日志的技能默认读今天的 error 级别日志用户只要传一个 service 名就够。第三必须定义失败返回格式。我统一用{status: error, code: ..., message: ...}。这样模型拿到报错时能分辨是传参错了还是技能内部炸了。如果技能抛一个裸异常出来模型经常会一脸懵进入瞎编模式。2.3 技能目录怎么分类才不打架技能多了以后分类管理很重要。我按领域拆了几个子目录code 类Python 执行、Shell 执行、代码检索、Git 操作ops 类查日志、看进程、重启服务、磁盘告警data 类读写数据库、操作表格、生成报表fetch 类请求外部 API、抓网页正文、订阅 RSS分类的原则是“单一职责”。查日志和重启服务看起来都属于运维但如果放进同一个 Skill 里模型调用时就会纠结我是把这两个都执行还是只执行其中一个保持单一职责一个 Skill 只做一件事模型的选择成本最低。很多人问编程类的 AI Skills 到底哪些最有用。我自己的体验是执行 Python 代码、检索项目代码、跑测试用例这三个技能的回报最高。尤其是“执行 Python 代码”几乎能覆盖格式化、计算、数据处理、临时脚本运行等一大堆杂事。你可以优先把这几个技能打磨好再考虑扩展。3. 在腾讯云上从零跑通一个带 Skills 的 Agent3.1 服务器与网络准备我用的轻量应用服务器配置是 2核4GUbuntu 22.04。Agent 主程序用 Python 3.10 FastAPI 写的通过 HTTP 接口对外提供服务。拿到服务器后第一步不是装环境而是先配置网络访问。腾讯云控制台有“防火墙”配置默认情况下只放行了 SSH、HTTP、HTTPS 等常用端口。如果 Agent 要跑在某个自定义端口上比如 8000你需要手动放行。很多新手会搜“腾讯云如何开放所有端口”但我强烈不建议这么干。正确做法是只放行你实际用到的端口。我的做法分两步在腾讯云控制台的防火墙规则里放行 TCP 8000 端口。在服务器内部执行sudo ufw allow 8000/tcp把系统防火墙也放行。这里有个很容易踩的坑控制台安全组放行了但 Ubuntu 自带的 ufw 没开外部请求依然进不来。两边要同步。配置完端口后先在本机自测一下curl -I -m 5 http://127.0.0.1:8000/health通了再让外部访问。如果后面想用域名访问可以去申请一个二级域名解析到服务器公网 IP再用 Nginx 把 80/443 端口的请求转发到本机 8000。Nginx 配置不复杂但要注意 DNS 解析生效需要时间别解析完立刻报错就以为配置错了。3.2 Agent 主程序的骨架我的 Agent 主程序目录结构大致是这样agent/ ├── app.py # FastAPI 入口 ├── config.yaml # 端口、模型、Redis 配置 ├── agent_core.py # Agent 调度逻辑 ├── skills/ # 所有技能 └── memory/ # 会话内存主程序的核心任务是接收用户消息把它交给 Agent 调度逻辑Agent 根据任务调用对应 Skills最后把结果返回给用户。大模型接入我用的是腾讯云混元大模型 API。密钥写进.env文件通过环境变量读取不要硬编码到代码里。代码里封装一个统一的 chat 函数方便以后切换不同模型import os import requests def chat(messages): resp requests.post( https://api.hunyuan.cloud.tencent.com/v1/chat/completions, headers{Authorization: fBearer {os.getenv(TENCENT_LLM_API_KEY)}}, json{model: hunyuan-turbo, messages: messages}, timeout30, ) return resp.json()[choices][0][message][content]至于 Agent 框架市面上有一堆比如 LangChain、LangGraph、AutoGen、CrewAI。我这里以 LangChain 为例原因是它的 Tool 机制和 AI Skills 的思路天然对应每个 Skill 包装成一个可调用的 Tool挂到 Agent 上就能用。如果你用其他框架只要支持“注册外部工具”思路是相通的。3.3 把 Skills 挂载进 Agent挂载的核心逻辑分三步扫描技能目录读 SKILL.md 的元信息动态导入 main.py 的执行函数再统一包装成 LangChain 的 StructuredTool。伪代码如下import yaml from pathlib import Path from langchain.tools import StructuredTool def load_skills(skills_dirskills): tools [] for skill_path in Path(skills_dir).iterdir(): if not skill_path.is_dir(): continue meta yaml.safe_load((skill_path / SKILL.md).open(encodingutf-8)) entrypoint load_skill_entrypoint(skill_path) # 动态导入 main.py tools.append( StructuredTool.from_function( funcentrypoint, namemeta[name], descriptionmeta[description], ) ) return tools这里有个关键点真正暴露给模型的只有工具名和 description。模型能不能在正确时机调用这个技能完全取决于你写的 description 够不够清楚。所以前面 2.2 节强调的“触发条件式描述”在这里会直接影响整体效果。另外我建议给每个工具统一加一个超时参数比如超时 60 秒就强制终止。否则某个技能卡住了整个 Agent 都会等在那里用户体验非常糟。3.4 联调让 Agent 干一件真事配置好以后我做的第一件“真事”是让 Agent 查一下服务器负载然后生成一份 Markdown 报告保存到文件。这条任务在 Agent 内部大致会走三步模型判断需要ops_load技能调用脚本读取uptime、free -m、df -h。拿到负载数据后模型判断需要python_executor技能让模型生成一段写 Markdown 表格的 Python 代码并执行。执行成功模型汇总结果返回给用户。理想很丰满现实很骨感。第一次联调大概率会失败而且失败方式五花八门模型把两个技能混在一起一个都没调好生成的 Python 代码缩进错误或者技能返回了超长文本把上下文撑爆。这些都是正常的。我的建议是联调时先把错误信息原样反馈给模型让它自己尝试修正。因为 Agent 的核心能力之一就是根据错误调整行为。如果修了两次还不行再去检查技能脚本本身的问题。跑通之后一定要记录一两个“成功案例”。后面改技能、调描述、加参数都拿这些案例做回归测试极大节省时间。4. 常见问题与排查技巧实录4.1 一眼看穿 “agent execution terminated due to error.”这个报错是 Agent 运行中最常见的本质是技能执行链中某一步抛了未捕获异常。可能是技能脚本内部出错可能是参数解析失败也可能是大模型调用超时。我的排查顺序固定是这样先看服务端日志journalctl -u agent -n 100 --no-pager。把技能单独拿出来手动执行确认脚本本身没问题。比如python main.py --input {code: print(11)}。用一个固定 prompt 让 Agent 只调用单个技能排除多技能协作时的链路问题。我后来给所有技能的入口都包了一层 try/except最后统一返回结构化错误。比如超时了返回{status: error, error_type: timeout, message: ...}。这样模型看到的是可读的错误信息而不是一堆裸异常修复路径清晰得多。4.2 LLM 传参和 Skill 参数表对不上这个问题的表现是模型调技能时参数里带了一些 description 里没定义的字段或者漏掉必填参数。比如 python_executor 要求code字段模型却传了一个script字段进去。原因多半是模型没有严格按 SKILL.md 的参数说明来。解决思路是双保险在 SKILL.md 里把参数名和必填项写清楚不给模型自由发挥的空间。在工具层用 JSON Schema 做参数校验校验失败就返回“参数校验失败需要的字段是 code”Agent 收到这个反馈后通常会重新读技能说明再生成一次正确参数。LangChain 的 StructuredTool 本身就支持args_only和handle_tool_error之类的配置。配好之后80% 的传参问题都能自动兜住。剩下 20% 靠日志定位。4.3 依赖服务连不上Redis 密码坑我给 Agent 加了 Redis 作为会话记忆存储。第一次改完 Redis 密码后碰到一个非常诡异的坑重启 Redis 之后Agent 一直报鉴权失败。先用redis-cli -a 新密码 ping测试返回 PONG说明服务端没问题。但是 Agent 的会话存储一直读不了。排查到最后发现是 Agent 的 config.yaml 里还写着旧密码。这个坑看起来很蠢但很典型。Redis 不像 MySQL 那样会提示你要改连接串它只会默默拒绝你。改完密码后服务端和客户端两边都要同步确认。现在我把所有连接类配置统一放在 config.yaml并加了注释改密码后必须同步更新这里避免下次再犯。4.4 端口和防火墙导致的“技能超时”很多技能要访问外部接口比如请求自家 API 或第三方服务。当技能一直超时很多人第一反应是代码出问题实际上一大半情况是端口根本没通。我整理了一个速查表每次排查按这个来现象可能原因排查命令外部访问超时安全组未放行腾讯云控制台检查防火墙规则本机能连外部不能系统防火墙拦截sudo ufw statussudo ufw allow 8000/tcp域名解析不对DNS 记录未生效dig 你的域名 short服务没监听进程没起来或端口被占用ss -lntp | grep 8000别以为云控制台放行就万事大吉Ubuntu 默认的 ufw 也可能拦你。每次配置完端口先用curl -I -m 5 http://127.0.0.1:8000/health自测通了再让外部访问能省很多排查时间。4.5 上下文太长技能调用链乱掉技能多了以后另一个问题是对话轮数变长模型容易“失忆”忘了之前调过哪个技能然后重复调用或者开始胡说。我目前的处理方案是三层加一个 memory 模块定期对历史对话做摘要只保留最近几轮完整对话。在 Agent 调度逻辑里设置“工作记忆区”每次技能调用的输入输出只保留压缩后的摘要不把完整日志塞回上下文。如果任务复杂拆成子任务。每个子任务只允许调用相关技能避免模型一把梭。这套方案不能说完美但在我目前的技能数量下稳定性提升非常明显。下一步我打算根据技能调用的成功率动态调整 description让模型优先选成功率高的技能。5. 一些让我少走弯路的实战习惯5.1 先手工后自动化任何新 Skill我都会先手工运行一遍脚本确认结果正确后再挂到 Agent 上去。这样 Agent 调用失败时我能立刻判断是脚本的问题还是 Agent 调用方式的问题不会两头都在猜。5.2 给每个 Skill 写测试技能上线一个月后环境一变之前跑得好好的脚本可能悄悄坏掉。我现在要求每个核心技能至少有一个测试用例比如pytest skills/python_executor/test.py。可以用系统定时任务每天跑一遍出问题早上就能看到。5.3 控制技能的数量和体积别头脑一热堆二三十个技能。技能越多模型做选择时的出错率越高。我的建议是先把 5 到 8 个高频技能做到极致再加新的。技能体积也尽量精简一个技能目录撑死几百行代码超过就拆。5.4 保留“失败轨迹”每次 Agent 报错我会把当时的用户输入、模型输出、技能输出完整存一份日志。这些日志是最好的测试集。后面调整 prompt 或技能描述就拿这些历史失败案例跑一遍看修复效果。比凭空想象“模型为什么会错”高效得多。我在实际使用中还有一个体会不要总想着把 Agent 做成一个什么都会的万能工具先把它养成一个“在固定场景下比人工更稳定”的工具再慢慢扩技能。这个思路看起来慢实际上走得最快。以上是我在腾讯云上练 Agent 和 AI Skills 的完整记录希望对你有用。