ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

腾讯云实战:打造带AI Skills的智能体Agent

腾讯云实战:打造带AI Skills的智能体Agent 相信不少做 AI 应用的朋友最近都有同感单独调大模型的 API 写个聊天机器人已经不够“解渴”了真正值钱的是让模型能自己动手干活。GitHub 上那些 Agent 项目星星涨得飞快但真到自己上手搭一个能跑业务、能查数据库、能操作 Redis 的智能体很多人还是卡在“Demo 五分钟上线两小时”的尴尬里。这篇文章我打算用一套完整的实战记录讲讲我在腾讯云上从零搭一个带“AI Skills”能力的 Agent 的整个过程。所谓 AI Skills你可以直接理解成给 Agent 装上的“专业工具包”让大模型不再只是聊天而是能调用外部工具、查询数据、写文件、操作容器服务。整个项目用到了腾讯云的云函数、容器镜像服务、Redis、API 网关和二级域名绑定这些能力后面我会把每个环节的选型理由、踩坑细节和可复现的步骤都拆开讲清楚。如果你正准备开始搞 Agent 开发或者已经在做 Agent 框架选型、想了解 Skill 和普通工具调用到底有什么区别这篇内容应该能帮你省下不少试错时间。哪怕你只是想把一个现成的 Agent 项目部署到云上跑起来文中的操作路径也能直接照抄。1. 完整设计与架构拆解这个 Agent 项目到底在解决什么问题1.1 一个 Agent 项目里真正的“骨架”是什么网上很多 Agent 教程喜欢把重点放在“怎么调大模型 API”上但实际做项目你会发现模型调用只是最外层的一环。一个能真正跑业务的 Agent通常由四层组成第一层是调度内核。它负责接收用户的问题拆解成任务再决定调用哪个 Skill、按什么顺序调用、最后怎么把多个结果拼成回答。这一层对应的就是 Agent 框架里的 Planner 和 Executor很多开源项目比如 Microsoft Agent Framework、LangChain、或者你自己写的简单状态机干的都是这件事。第二层是 Skill 注册中心。Agent 能不能干活取决于它注册了多少可用的 Skill。每个 Skill 本质上是“一段自然语言描述 一个可执行的函数/接口/容器服务”。模型通过描述判断什么时候该调它然后由框架去执行真正的代码。第三层是底座服务。Skill 不是凭空跑的它要访问 Redis 做记忆存储、要访问对象存储存文件、要调内部 API 拿业务数据。腾讯云在这一层提供了非常完整的基础设施这也是我选它做项目底座的主要原因。第四层是入口与暴露方式。Agent 做出来不是给自己在终端里玩的你得给它一个 HTTP 接口、一个前端对话页面甚至一个公众号或企微机器人入口。这里就涉及 API 网关、域名、鉴权这些工程问题。我的项目定位很明确做一个“能处理日常运维和内容生成任务”的个人全能 Agent。比如我丢给它一句话“检查一下服务器 Redis 的内存占用然后写一份今天的巡检摘要发给我”它要能自动完成 Redis 命令执行、结果分析、报告生成三个动作。这种需求在纯聊天机器人时代是不可想象的但在 Agent Skills 的架构下就变成了一个非常典型的编排任务。1.2 为什么我在这个阶段选择了腾讯云而不是自建整套环境Agent 项目迭代速度非常快今天想的架构可能过两周就要推倒重来所以底座一定要选“上手快、运维轻、弹性够用”的。我最终选择腾讯云核心原因是它在三个维度上刚好匹配了这类项目的节奏。首先是计算资源的弹性。Agent 的调用量非常不稳定可能白天没人用晚上你写了个定时任务让它批量处理数据CPU 瞬间拉满。用云函数来做 Agent 的调度层冷启动虽然有一两百毫秒的延迟但对对话类场景完全无感而它能按调用次数计费这点比长期开一台 CVM 划算得多。其次是配套组件的完整性。Agent 做出来必然要接 Redis 做会话记忆要接对象存储存生成的文件要接容器服务跑一些重计算的 Skill。如果用自建环境这些组件每一个都要自己装自己维护光打通网络策略就能耗掉半天。腾讯云上这些服务都是开箱即用而且内网互通延迟很低。第三是调试链路的便捷性。云函数的日志、监控、链路追踪都是平台自带的出了问题直接在控制台看调用日志就行不用像自建 K8s 那样先排查半天 Pod 状态。对于个人开发者和五人以下的小团队这种“把精力花在 Agent 业务本身而不是底层运维”的体验非常关键。当然自建方案也不是一无是处。如果你的 Agent 项目已经进入稳定期、调用量非常固定、对成本极度敏感那租一台高配 CVM 自己跑 Docker 容器可能更划算。但作为项目初期的快速验证腾讯云这套组合拳是更理性的选择。2. AI Skills 的底层逻辑它和普通工具调用的区别在哪2.1 Skill 不是插件它是 Agent 的“能力契约”说到“AI Skills”不少人第一反应是“这不就是给 Agent 写插件吗”我在做这个项目之前也是这么理解的但真正上手之后才发现Skill 和传统意义上的插件有本质区别。传统插件是“硬编码”的调用方明确知道插件的输入输出格式代码里写死调哪个函数、传什么参数。但 Agent 场景下的 Skill 是“软契约”调用方是自然语言模型它不知道你的 Skill 内部是怎么实现的它只知道“这个 Skill 能解决什么问题、需要什么参数、返回什么结果”。所以一个合格的 Skill 定义必须包含三部分内容一是清晰的功能描述告诉模型“我擅长干什么”二是参数 Schema告诉模型“调用我需要提供哪些字段、每个字段的格式是什么”三是返回结果说明告诉模型“我执行完后会返回什么结构的数据”。这三部分合在一起就是模型和 Skill 之间的“能力契约”。我在项目里用了一个很简单但非常实用的定义方式每个 Skill 是一个 JSON 文件加一个 Python 函数。JSON 文件描述能力Python 函数实现逻辑。Agent 启动时自动扫描 Skills 目录把所有的 JSON 描述注入到系统提示词里模型就能“知道”自己有哪些工具可用。2.2 Skill 的分层设计基础原子能力 vs 业务编排能力在给 Agent 设计 Skills 体系时我犯过一个大错误把所有能力都堆在同一层。结果 Agent 在做复杂任务时频繁在多个 Skill 之间跳来跳去上下文一长就开始迷茫。后来我参考腾讯云开发者社区里一些项目经验把 Skill 分成了两层原子 Skills 和编排 Skills。原子 Skills 是最小可执行单元比如“查询 Redis 指定 key 的值”“调用文本摘要 API 生成摘要”“从数据库读当日订单量”。每个原子 Skill 只做一件简单的事参数少、逻辑清晰、容易测试。编排 Skills 则是把多个原子 Skills 按固定流程组合起来。举个实际例子“生成巡检报告”这个编排 Skill 内部会依次调用“检查 CPU 使用率”“检查内存使用率”“检查 Redis 连接数”“生成 Markdown 报告”四个原子 Skills。对模型来说它不需要关心内部能拆成几步只需要知道“调用这个 Skill我会得到一份完整的巡检报告”。这种分层带来的好处非常明显。一方面模型做决策的粒度变小了它只需要在“我该用哪个 Skill 达成这个目标”层面做判断而不是去思考“我该怎么组合这几个函数”。另一方面原子 Skills 可以复用不同的编排 Skills 之间共享底层能力代码不会重复。这一点在你后期扩展 Agent 能力时会感受特别深。2.3 实际定义我手写的一个 Skill 长什么样以一个我实际用过的“Redis 内存分析”Skill 为例它的 JSON 描述文件是这样的{ name: redis_memory_analyze, description: Analyze the memory usage of a specified Redis instance and return key-level memory statistics. Use this skill when user asks about Redis memory, key size, or memory fragmentation., parameters: { type: object, properties: { host: { type: string, description: Redis host address }, port: { type: integer, description: Redis port, default 6379 }, password: { type: string, description: Redis password if required }, sample_size: { type: integer, description: Number of keys to sample for memory analysis, default 100 } }, required: [host] }, returns: { type: object, properties: { total_memory_bytes: { type: integer }, key_count: { type: integer }, top_memory_keys: { type: array } } } }对应的 Python 实现函数我会封装成独立的文件通过装饰器注册到 Skill 管理器里。这样 Agent 的调度器在收到用户问题后会根据 description 里的关键词比如 memory、Redis自动匹配到这个 Skill再根据 parameters 生成调用参数最后把 returns 结构解析回对话上下文。这个过程中最大的坑在于“描述要写得足够精准”。如果你的 description 写得太宽泛模型会频繁误用写得太窄模型又不知道该在什么场景下调它。我后来总结的经验是描述里一定要包含“什么条件下用”和“什么条件下不用”比如“Use this only when the user explicitly asks about Redis memory details. Do NOT use this for general Redis connectivity tests.”这样模型误判的概率会大幅下降。3. 实操实录在腾讯云上完整部署一个带 Skills 的 Agent3.1 前置准备账号、依赖和项目骨架我不是第一次在腾讯云上部署东西但这套 Agent 项目的准备过程仍然有不少细节值得记录。你在动手前建议先把下面三件事准备好第一是账号和密钥。你需要一个腾讯云账号然后在访问管理里创建一个子用户授予云函数、API 网关、容器镜像服务、Redis 这几个产品的操作权限生成 SecretId 和 SecretKey。这里提醒一句密钥千万别写进代码仓库我习惯放在环境变量里或者用云厂商的密钥管理系统。很多同学项目跑不起来最后发现是权限配置不对而不是代码有问题。第二是项目目录结构。我习惯把 Agent 工程拆成四个子目录core放调度内核和提示词管理skills放所有 Skill 的 JSON 文件和实现代码gateway放 HTTP 入口和鉴权逻辑config放环境和依赖配置。这样的结构在本地调试和在云端部署时非常统一不会出现“本地能跑上云就炸”的尴尬。第三是依赖确认。我的 Agent 框架层用的一个轻量 FastAPI 加自定义调度器模型调用走的是 OpenAI 兼容接口所以依赖并不多fastapi、uvicorn、redis、requests、pydantic。特别说明一下我没有用很重的 Agent 框架因为对于这种 Skills 比较固定、流程相对可控的项目自己维护调度逻辑反而更灵活。3.2 第一步用云函数承载 Agent 调度层Agent 的调度层是一个无状态服务非常适合用云函数来跑。我创建了一个 HTTP 类型的事件函数入口方法接收 POST 请求请求体是用户的自然语言输入函数内部完成“解析意图 - 匹配 Skill - 调用 Skill - 生成回答”这个循环最后把回答以 JSON 格式返回。这里有一个关键工程点云函数的执行时长限制。如果你用的是默认配置函数最长执行时间可能是 15 秒或 60 秒但 Agent 在做多轮 Skill 调用时单次请求完全可能超过这个时间。我的处理方法是把超时时间调到 300 秒同时在代码里加了一个流式输出的机制先把“正在调用哪个 Skill”的状态返回给前端避免用户端看起来像卡死。再分享一个提升冷启动体验的小技巧。云函数默认的运行时环境是很轻量的但如果你代码里 import 了pandas、numpy这类比较重的库冷启动时间会明显变长。解决办法是尽量用轻量替代方案比如用纯 Python 的csv模块替代pandas做简单表格处理用orjson替代json做序列化。实测下来冷启动时间能从两秒左右降到三百毫秒以内。3.3 第二步给 Agent 接上 Redis实现记忆与状态管理任何一个值得用的 Agent 都必须有记忆能力。用户上午跟 Agent 说“我喜欢简洁的回答风格”下午再问问题Agent 应该还记得这个偏好。这种长期记忆我选择放在 Redis 里。Redis 在腾讯云上有托管实例创建过程很简单几分钟就能拿到一个内网地址。但我在配置时踩了一个非常经典的坑创建实例时设置的初始密码和我在应用里实际使用的密码不一致导致 Agent 调用 Redis 时一直报NOAUTH Authentication required错误。排查了很久才发现问题。后来我的做法是在腾讯云 Redis 控制台把密码重置一次然后把新密码写进云函数的环境变量里代码里统一从os.getenv(REDIS_PASSWORD)读取而不是硬编码。这样以后密码再变只需要改环境变量重新部署不用动代码。Redis 里我主要存三类数据对话历史用 List 类型按会话 ID 存储、用户偏好用 Hash 类型存储、Skill 执行缓存用 String 类型TTL 设置为 10 分钟。这套设计让 Agent 在多轮对话中表现得像是有“记忆”一样而不是每次都是第一次见面。3.4 第三步把重计算 Skill 容器化推送到腾讯云容器镜像服务Agent 项目里不是所有 Skill 都适合跑在云函数里。我有一些数据处理类的 Skill 依赖特定的底层库或者需要一次性跑几分钟的大任务这类 Skill 更适合打成一个 Docker 镜像部署到容器服务里通过 HTTP 接口被 Agent 调度层调用。容器镜像的打包和推送流程我已经很熟了但在云环境下有一个额外的动作需要做镜像要推送到腾讯云容器镜像服务 TCR而不是本地 Docker Hub。这一步的目的是让你的 Skill 服务镜像跟 Agent 调度层在同一个云网络内内网拉取速度快也不占公网带宽。推送命令很简单登录 TCR 之后打 tag 再 push 就行docker login ccr.ccs.tencentcloud.com -u YOUR_TCR_USERNAME -p YOUR_TCR_TOKEN docker tag my-agent-skill:latest ccr.ccs.tencentcloud.com/my-project/my-agent-skill:latest docker push ccr.ccs.tencentcloud.com/my-project/my-agent-skill:latest推送成功后我在容器服务里创建了一个简单的 Deployment暴露一个内网 ServiceAgent 调度层通过内网地址调用这个 Skill 的接口。整个过程顺下来之后你会明显感觉到“Skill 可以独立部署、独立扩容”这件事对 Agent 项目有多重要——你可以针对一个高频 Skill 扩到 10 个实例而低峰期缩到 1 个成本控制非常灵活。3.5 第四步开放安全端口与二级域名绑定Agent 做出来之后我得让它能被外部访问。这里涉及两个高频的配置动作开放端口和申请二级域名。先说端口开放的坑。很多人在腾讯云安全组里“开放所有端口”图省事这个习惯非常危险。我的经验是只开放必要端口80/443 给 HTTP 入口如果你有 SSH 需求那再加一个指定来源 IP 的 22 端口。这样即便服务有漏洞攻击面也被限制在最小。再说二级域名。你在腾讯云可以给云函数或 API 网关绑定一个自定义域名这个域名是腾讯云给你分配的二级域名比如xxx.service.tcloudbase.com。配置路径是API 网关 - 自定义域名 - 添加域名然后在域名解析里加一条 CNAME 指向腾讯云给你的目标地址。整个流程大概十分钟就能搞定。绑定完之后有个非常关键的操作开启 HTTPS。腾讯云提供免费 SSL 证书申请和部署都在控制台点几下就能完成。Agent 的外部接口是对话入口传输内容可能包含敏感信息不用 HTTPS 的话数据在公网传输就是裸奔这个风险千万别冒。4. 调试与部署中的高频问题排查实录4.1 经典报错速查表我在这套项目里前前后后跑了快一个月把遇到过的典型报错整理成了下面这个速查表很多问题你大概率也会碰到。报错信息根因分析解决方案agent execution terminated due to errorAgent 调度层在调用 Skill 时抛出了未捕获异常多发生在模型参数生成不符合 Skill 预期时在 Skill 调用入口统一加 try/except把异常转成友好错误返回给模型NOAUTH Authentication requiredRedis 连接时未提供密码或密码错误检查环境变量中的 REDIS_PASSWORD 是否和腾讯云控制台一致重置后重建连接502 Bad Gateway云函数调用容器 Skill 接口时网络不通或超时确认容器服务的内网地址正确检查云函数和容器是否在同一 VPCInvalid parameter: model模型 API 参数不兼容可能是接口地址或模型名称写错统一用 OpenAI 兼容格式检查 base_url 是否指向正确的网关地址timeoutSkill 执行时间超过云函数或容器服务的超时阈值把重任务拆成异步任务或将超时时间调到合理范围避免无脑拉满其中agent execution terminated due to error是最让人头痛的因为它的信息非常模糊不爆出具体是哪一个 Skill 调用失败。我最后是通过在调度层给每次 Skill 调用加了 request_id 追踪才把问题定位到“模型生成参数时把字符串传给了整数字段”这个原因上。4.2 Redis 密码修改后一直重启的连环坑这个坑我必须单独拿出来讲因为它太典型了。有段时间我想把 Redis 密码从弱密码换成强密码在腾讯云控制台点完“重置密码”后Redis 实例状态变成了“重启中”然后一直卡在那个状态业务侧不断报连接错误。排查过程也很折腾。后来发现原因在于控制台重置密码后实例需要一次重启来加载新配置而我在应用侧还是用旧密码去连连接失败后云函数会自动重试重试的压力又让实例负载升高延长了重启时间形成了恶性循环。正确的操作顺序应该是先在应用配置里停掉对 Redis 的调用或者把环境变量暂时指向一个测试实例再在控制台重置密码等实例状态稳定为“运行中”后再更新应用环境变量并重新部署。如果你像我一样赶时间可以考虑直接新购一个 Redis 实例配置好密码和网络策略后切换连接地址再退掉旧实例这样风险更小、变更更干净。4.3 Skill 选择过于激进把日志记录下来调试过程中我还有一个很深的体会Agent 的调度逻辑是不可完全预测的同一个问题问十次模型可能会选不同的 Skill 组合。为了不让问题“灵异复现”我早期就设计了一个 Skill 调用日志表每次调度都会记录用户输入、匹配到的 Skill 名称、模型生成的参数、Skill 执行结果、耗时。这个日志表在调试阶段救了我很多次。有一次 Agent 突然对一个简单问题回答错乱查日志发现它调用了一个和问题完全无关的 Skill原因是我把这个 Skill 的 description 写得太宽泛模型产生了误匹配。如果没有日志这种问题根本无从查起。强烈建议每个做 Agent 项目的朋友都提前搭好这种“行为审计”机制它是 Agent 可维护性的底线。5. 从“能用”到“好用”我的调优心得与扩展建议5.1 提示词和 Skill 描述是最大的性能杠杆同样的 Agent 内核同样的模型 API为什么有人做出来效果很好有人做出来像个智障我自己的经验是90% 的差距在提示词和 Skill 描述的编写质量上。模型选择用哪个 Skill完全依赖它“读”到的描述文本。所以每次调试遇到“Agent 就是不用某个 Skill”的情况我的第一反应不是去改代码而是重写这个 Skill 的 description。有一个技巧非常有效在描述里加入一两个典型场景的提问示例。比如原来的描述是“Retrieve weather data for a city”改成“Retrieve weather data for a city. Example: when user says What is the weather in Beijing?, this is the skill to use.” 模型命中率会明显提高。另外系统提示词里要明确告诉 Agent“不确定的时候怎么做”。我在提示词里加了一句“If you are unsure which skill to use, ask the user a clarifying question instead of guessing.”这样做虽然看起来降低了“智能感”但实际体验反而更好——至少不会出现用户问天气、Agent 去查数据库这种离谱错误。5.2 成本控制请求合并与模型分级Agent 项目跑起来之后成本问题很快就会浮现。尤其是“多轮 Skill 调用 长上下文”这种组合Token 消耗量比普通聊天高出几个量级。我做了两个调整来控成本效果都非常明显。第一是请求合并。遇到一个编排 Skill 需要连续调用多个原子 Skill 的场景原来 Agent 会分多轮发起模型请求每轮都要把完整上下文作为输入重新计算Token 消耗非常高。我改为在调度层提前定义好编排流程一次模型请求直接生成所有子步骤的参数再按顺序执行Token 消耗能降 40% 左右。第二是模型分级。简单的任务比如“把这段文本翻译成英文”用便宜的轻量模型复杂的编排任务比如“分析巡检报告并给出优化建议”才用旗舰模型。我在 Agent 内核里加了一个“任务复杂度评估”步骤根据 Skill 的数量和参数个数决定走哪个模型通道。目前实测下来总体成本降了将近一半体验几乎没有下降。5.3 后续扩展从个人助手到业务 Agent这套项目的架构做完之后我最大的感受是Agent AI Skills 这套模式完全可以复用到业务场景里而不只是个人玩具。你可以把“生成日报”做成一个编排 Skill绑到企业微信机器人上每天早上定时触发也可以把“客户问题分类”做成一个原子 Skill接到客服系统里由 Agent 先做一轮过滤和分诊。所有的 Skills 都是可插拔的你要做的只是针对新的业务场景写新的 Skill 实现Agent 内核本身基本不用动。腾讯云这套底座的价值在这个阶段就体现得非常充分了云函数的弹性、容器服务的编排能力、Redis 的记忆存储都是现成的你不需要重新搭基础设施只需要专注在“给 Agent 装什么新 skills”这个业务问题上。写在最后一些关于 Agent 工程的真心话项目做到后期我越来越觉得 Agent 开发的难点压根不在模型和框架而在工程化能力。你把两条 Skill 串成一条流程很容易但要让这条流程在并发高、网络抖、依赖挂的情况下还能稳定跑就需要在日志、超时、异常处理、成本控制这些“不性感”的地方下功夫。我个人在实操过程中最大的体会是一定要从最小的闭环开始切。第一版不要追求大而全的 Agent先让它能做好一件小事比如“查 Redis 内存并生成报告”把调度、Skill 注册、日志链路、云端部署全跑通再去加第二个、第三个 Skill。每一步都要确保能单独验证、能回滚。等你积累了十几个 Skills 之后会发现 Agent 的能力完全是“叠加涌现”的而不是靠一个大一统的设计堆出来的。最后再分享一个小技巧给你的 Agent 起个名字并且在所有提示词里统一用这个名字跟它对话。这看起来是小事但当你调试 Agent 的对话记忆时会发现一个固定的角色标识能让很多问题更容易复现和定位心理上的“代入感”也会让你更愿意持续迭代它。动手试试吧给云服务器也顺便加一层 Redis 的安全策略把公网端口收一收再让 Agent 跑起来你会感受到这套体系的强大之处。
返回列表