十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

腾讯云AI Agent实战:从零搭建全能Agent与AI Skills最佳实践

腾讯云AI Agent实战:从零搭建全能Agent与AI Skills最佳实践 我做了几年大模型应用开发一个越来越强烈的体会是单纯把大模型接入业务和真正把它变成能干活的生产力工具中间差着十万八千里。去年我主导落地了一个内部知识库问答Agent最初效果惨不忍睹模型经常答非所问遇到复杂指令就“罢工”。直到后来我彻底重构了架构把核心逻辑拆成一个个独立的AI Skills配合腾讯云的部署环境才真正体会到什么叫“Agent养成”。这篇博文就围绕这个项目把我从0到1搭建全能Agent、沉淀AI Skills的最佳实践完整拆解出来。内容会覆盖概念认知、架构设计、腾讯云环境准备、Skill开发细节、Agent记忆系统、安全上线和性能调优哪怕你之前没碰过Agent开发照着这套思路也能少踩很多坑。1. 核心概念与项目思路解构1.1 什么是Agent什么又是AI Skills先说个容易混乱的点很多人把Agent和AI Skills当成一个东西其实完全不是。打个比方Agent像是一家公司的老板负责接收任务、拆解计划、调动资源、检查结果而AI Skills则是这家公司里的专业员工每个员工只擅长一个具体领域比如查天气、算数学、读PDF、调数据库。老板自己不会干所有活但他知道什么任务该派给哪个员工以及怎么把多个员工的工作成果串联起来。从技术实现的角度Agent的核心能力是“决策与编排”它依赖大模型的推理能力能够理解用户意图把复杂目标拆解成子任务然后选择并调用合适的工具。而AI Skills本质上是一组“被结构化定义的、可复用的能力模块”。一个Skill通常包含触发条件、输入参数、执行逻辑、输出格式和异常处理。可以简单粗暴地理解为Skill是Agent的“手”模型是Agent的“大脑”大脑负责想手负责做。这个区分特别重要因为它决定了整个项目的架构方式。如果所有业务逻辑都堆在Agent主流程里一旦需求变化改动就是牵一发动全身但如果按Skill维度拆分每个能力独立演进、独立测试、独立部署Agent只负责调度整个系统的可维护性和可扩展性会好很多。我见过很多失败的项目本质都是“把Agent做成了一个大而全的单体应用”所以设计之初就要有“Skill化”的意识。1.2 项目要解决的真实痛点我做这个项目的起因很实际。团队内部有个知识管理系统沉淀了大量文档但检索困难新同事入职后查找资料特别痛苦经常在群里问一些文档里明明写了答案的问题。当时试过直接用开源问答系统效果不理想因为文档格式五花八门有Word、PDF、Markdown还有一堆Excel表格纯向量检索召回率低答案经常张冠李戴。更深一层的痛点是“Agent能力无法积累”。我之前用LangChain写过几个自动化脚本每次新需求都要重写一遍逻辑没有沉淀出可复用的东西。比如“读取表格数据”“解析日期范围”“生成周报模板”这种功能换个项目就得复制粘贴再改极其低效。AI Skills的引入正是为了解决这个问题把常用能力模块化像搭积木一样组合新项目直接复用开发成本断崖式下降。还有一个隐藏在背后的需求是“非技术人员能用起来”。Agent如果只是给开发者自己玩价值有限但我这个项目的用户是运营和市场同事他们不会写提示词也不会调API。所以整个设计必须足够“傻瓜化”——用户用自然语言说需求Agent自动匹配Skill去执行。这个目标倒逼着我把Skill的触发逻辑和参数解析做到足够稳健这也是我后面会用大量篇幅讲的部分。1.3 为什么选择腾讯云作为基座选腾讯云不是拍脑袋。第一项目需要部署一个长期运行的线上服务国内云厂商的合规和稳定性都是硬指标腾讯云的备案流程、实名认证体系相对成熟和微信生态的集成也方便第二腾讯云的CVM云服务器、COS对象存储、Lighthouse轻量应用服务器等产品对中小团队比较友好按量计费模式适合项目初期的成本控制第三我实际用下来它的安全组、防火墙配置文档清晰API兼容性好和主流的Agent框架比如LangChain、Semantic Kernel衔接顺畅。当然选型也考虑过其他方案但最终让我定下来的是“整体生态的完成度”。从服务器到对象存储从域名解析到HTTPS证书腾讯云基本都覆盖了在一个控制台里就能完成所有资源管理省去了多平台跳转的麻烦。尤其是二级域名配置和SSL证书申请这两块腾讯云的交互设计对新手相当友好这在后面的实操部分会详细演示。2. 环境搭建与基础设施选型2.1 服务器配置建议与成本控制Agent项目对服务器的要求取决于你跑的模型规模和并发量。如果你用的是云端大模型API比如腾讯混元、OpenAI、Claude等服务器只承担业务逻辑编排和API转发压力不大但如果你要部署开源模型比如Qwen、Llama就需要考虑GPU服务器了。我当时的场景是混合架构核心对话走云端API部分敏感数据的向量化走本地模型。最终选了腾讯云Lighthouse轻量应用服务器2核4G的配置带宽5Mbps系统盘60GB SSD。这个配置跑Agent编排服务、Redis缓存、MySQL数据库完全够用普通API调用场景下并发20左右没有压力。成本大概每个月一百多块测试阶段完全能接受。磁盘那块我想提醒一句建议系统盘和数据盘分开数据盘单独购买云硬盘挂载。别问我怎么知道的我第一次图省事所有数据塞系统盘后来磁盘满了一次差点把数据库搞崩。还有一个容易被忽略的点服务器的系统镜像建议选Ubuntu 22.04 LTS而不是CentOS原因是现在的Agent生态工具对Ubuntu的兼容性明显更好很多框架依赖的Python版本和系统库在CentOS上都要额外折腾。2.2 域名、备案与二级域名配置如果你只是自己测试玩用IP访问没问题但正式项目强烈建议配置域名。原因很直接很多Agent框架的回调机制、OAuth认证、HTTPS证书都要求域名地址用IP地址会出现各种奇奇怪怪的跨域和回调失败问题。腾讯云上申请域名很简单在“域名注册”里搜索购买即可.com域名一年几十块。购买后需要做实名认证通常几分钟到几小时不等。这里有个容易被卡住的流程域名备案。如果你的服务器在中国大陆地域域名必须完成ICP备案才能正常解析访问备案审核一般需要7-20个工作日所以一定要提前规划别等上线前才想起来。二级域名的配置比很多人想象中简单。我建议按模块拆分api.你的域名.com作为后端API入口files.你的域名.com作为上传文件的服务域名。添加二级域名的方法是进入“域名解析”控制台添加记录主机记录填api之类的二级域名前缀记录类型选A记录值填服务器的公网IP地址。TTL默认600秒即可解析生效一般几分钟。提示如果你用了CDN或者负载均衡记录类型就要改成CNAME并指向对应的域名别死记A记录。2.3 安全组与端口开放的正确姿势腾讯云的服务器默认安全组策略只开放22和80等少数端口你要跑Agent服务通常需要开放更多端口。但这里我强烈建议你不要图省事把所有端口全部暴露到公网那是找打。正确做法是分场景开放服务对外提供的HTTP/HTTPS端口比如8000、443源地址填0.0.0.0/0因为需要公网访问SSH管理端口源地址改成你当前的公网IP或者干脆改成非默认端口比如22022大幅降低被暴力破解的概率内部组件端口比如Redis的6379、MySQL的3306永远不要对公网开放只允许内网访问。在腾讯云控制台“安全组”的入站规则里可以逐条配置。我踩过的坑是改了安全组规则后用telnet测试端口明明通了但服务还是连不上排查半天发现是服务器内部防火墙UFW没放行里外两层都要设置。所以记住一个排查顺序先确认服务本身在监听ss -lntp再看云控制台安全组最后看系统防火墙三层都放行才能真正通。3. AI Skills 的设计与开发实战3.1 Skill 的结构化设计方法论一个合格的Skill绝对不是“一段提示词”那么简单。我总结了一套结构每个Skill包含以下核心字段{ name: document_analyzer, description: 分析上传的文档内容提取关键信息并生成结构化摘要, triggers: [分析文档, 总结文档, 提取要点], input_schema: { file_url: {type: string, required: true, description: 文档的存储URL}, doc_type: {type: string, required: false, enum: [pdf, docx, md, txt]}, summary_length: {type: integer, required: false, default: 500} }, execution: python_function_or_prompt_template, output_format: markdown, error_handling: retry_parse_and_log }这套设计的核心思想是让Agent“看一眼”就知道这个Skill能干什么、需要什么输入、返回什么格式。特别是description和triggers两个字段直接影响Agent能不能在复杂的对话场景中准确选中这个Skill。在开发过程中我发现一个特别容易踩的坑Skill的description写得过于宽泛。比如你写“处理文档”那Agent在用户说“这个PDF帮我看看”的时候就无法确定是否要调用它但如果你写成“将PDF、Word等文档转换为纯文本并提取其中的标题、作者、关键词”Agent在80%的情况下都能做出正确的工具选择。3.2 用“渐进式披露”解决复杂Skill的提示词困境Agent开发里有个经典矛盾你的Skill任务越复杂需要的提示词就越长但大模型处理超长提示词时性能和稳定性都会下降而且容易被用户的无关输入带偏。我用的方案是“progressive disclosure”翻译成人话就是“分阶段披露提示词”。具体做法是Skill的提示词模板拆成两段。第一段是很短的“快速判断提示词”只包含核心指令和触发条件用于Agent的第一轮工具调用。当Agent确定调用这个Skill之后第二段“详细执行提示词”才会被完整加载包含完整的步骤、规则、few-shot示例以及所有边界情况和注意事项。举个例子我的meeting_minutes_generatorSkill第一段提示词只是“分析会议记录提取主题、结论和待办事项按Markdown格式输出”但当它被正式调用时第二段详细提示词才包含输出模板、发言角色识别逻辑、时区分辨规则、敏感信息过滤等完整指令。这种设计让每个Skill既能快速响应又能处理复杂任务是Agent从demo走向生产环境的关键优化之一。3.3 工具调用范式让大模型学会“用”SkillSkill无论如何设计最终都需要一个机制让大模型“调用”它。目前业界主流有几种方式Function CallingOpenAI/混元等商业API原生支持、JSON模式输出、以及LangChain等框架的Tool Abstraction。我这边用的是腾讯云AI大模型平台的Function Calling能力整体体验比较稳定。Function Calling的核心逻辑是这样的你把所有可用Skill的name、description、input_schema等信息作为参数传给模型API模型在理解用户意图后会返回一个结构化的JSON指明它决定调用哪个函数以及传入什么参数。你的代码只需要解析这个JSON执行对应的函数把结果喂回对话模型组织成自然语言回复。实际开发中我建议把Function Calling封装成通用模块import json from tencent_cloud_llm import ChatModel def agent_execute(user_input, skills): client ChatModel(api_keyAPI_KEY, modelhunyuan-turbo) # 把所有skill的定义转为function列表 functions [skill.schema for skill in skills] response client.chat_with_functions( messages[{role: user, content: user_input}], functionsfunctions ) # 解析模型决定调用的function call json.loads(response.function_call) skill find_skill_by_name(skills, call[name]) result skill.execute(**call[arguments]) # 将结果返回模型生成最终回复 final_msg client.chat(请根据工具结果回答用户 str(result)) return final_msg这段代码看着简单但它包含了一个重要的架构决策模型和Skill执行是解耦的。模型只负责“决定”不负责“实现”真正干活的是后端的Skill函数。这样即使模型升级或者换厂商只要Function Calling的协议不变整个Agent系统就只需要做很小的迁移。3.4 用代码实现一个真实的数据查询Skill为了让你更直观地理解Skill开发我分享一个实际项目里的database_queryerSkill它负责把用户的自然语言查询转换成SQL并查询MySQL数据库。这个Skill的执行逻辑分三步。第一步用LLM把用户问题转成SQL把你需要回答的数据库查询需求转换成合法的SQL语句只允许执行SELECT查询。 数据库表结构如下 {table_schema} 直接输出SQL语句不要做任何解释。第二步Python代码执行SQL并处理错误import pymysql def execute_sql(sql): conn pymysql.connect( hostlocalhost, useragent, passwordxxx, dbknowledge_base, charsetutf8mb4 ) try: with conn.cursor() as cursor: cursor.execute(sql) result cursor.fetchall() return {success: True, data: result} except Exception as e: return {success: False, error: str(e)} finally: conn.close()第三步把查询结果和用户原始问题一起交给模型生成最终的自然语言回复。这里有个我总结的小技巧——SQL生成一定要加“护栏”用提示词明确禁止INSERT、UPDATE、DELETE操作还能在代码里用正则再过滤一遍危险关键词双保险。这个Skill上线后内部同事可以直接问“上个月合同金额排前五的客户有哪些”Agent自动生成SQL查询后组织成表格回复。整个体验比让同事学SQL不知道友好多少倍。不过要注意的是自然语言转SQL在复杂查询场景下准确率会下降所以初期建议限制在单表查询和简单联表复杂报表需求还是交给专职数据分析师更靠谱。4. Agent 的核心记忆系统与上下文管理4.1 为什么记忆对Agent如此重要如果你用过不带记忆的Agent一定会碰到这个崩溃时刻用户刚说“我叫张三”下一句问“我叫什么”Agent回答“我不知道”。这种割裂感让Agent看起来像个患有严重健忘症的客服根本无法承担真实业务。从底层逻辑看大模型本身是无状态的它只根据当前输入的上下文生成回复。要实现跨会话、多轮对话的记忆必须在模型之外构建一层记忆系统。我把记忆分成三层短期记忆当前会话上下文、工作记忆用户在当前任务中提供的关键信息、长期记忆跨会话的用户偏好和历史事实。三层记忆分别用不同的存储介质和更新策略。4.2 短期记忆上下文窗口的极致利用短期记忆最简单就是直接把历史对话记录拼进当前请求。但这里的难点是控制上下文窗口长度尤其是对话轮数多、Skill返回结果长的时候很容易把上下文撑爆。我的策略是“滑动窗口 摘要压缩”双机制。滑动窗口就是只保留最近N轮对话比如12轮更早的全部丢弃。但光丢弃还不够因为重要的信息可能藏在早期对话里。所以我在每轮对话结束时会让模型生成一个“运行摘要”把用户偏好、已完成的事实、未完成的待办全部浓缩成几句话连同最近几轮完整对话一起作为上下文。这样即便上下文窗口有限重要信息也不会丢失。def build_context(history, current_question): # 保留最近10轮完整对话 recent history[-10:] # 用LLM对更早的历史生成摘要 old_summary summarize(history[:-10]) context old_summary \n.join(recent) current_question return context4.3 长期记忆用向量数据库存储“Agent的日记”长期记忆的作用是让Agent记住用户的历史偏好。比如用户在前几次对话中反复强调“报告格式用中文、表格呈现”那新会话中Agent应该自动遵循这个偏好。我使用的是向量数据库腾讯云向量数据库或开源的Milvus均可存储长期记忆。流程是每次对话结束后把关键信息用户ID、事实、偏好、实体关系抽取出来通过Embedding模型转成向量存入向量数据库。新对话开始时取用户当前输入做向量检索找出相似度最高的若干条历史记忆注入系统提示词。这个方案在实际使用中效果显著用户普遍反馈“Agent像换了个人真的记住我了”。不过长期记忆也要注意隐私合规和数据保鲜两个问题。隐私层面敏感信息必须脱敏后才能入库数据保鲜层面要定期清理过期记忆否则用户已经改变的偏好会被陈旧记忆污染造成严重的错误回复。我设置了一个90天的TTL超过期限的记忆自动归档或删除。4.4 记忆一致性与多Session并发控制当多个用户同时使用Agent时记忆串号是一个致命问题。开发时我做过一个简单的Session管理器核心思路是每次请求必须携带session_id记忆读写都严格按session_id路由到各自的存储空间隔离用户数据。class SessionManager: def __init__(self): self.sessions {} def get_context(self, session_id): return self.sessions.get(session_id, {}) def update_context(self, session_id, key, value): self.sessions.setdefault(session_id, {})[key] value这里还有个容易忽视的性能问题如果用纯内存存Session服务一旦重启数据全丢用户表现为“重置了”。所以生产环境我建议用Redis做Session存储设置过期时间自动清理不再活跃的会话兼顾数据持久化和内存控制。Redis的HSET、EXPIRE命令组合起来实现一个带自动过期的Session存储不过几十行代码。5. 常见问题排查与性能调优实录5.1 Agent 输出不稳定的“元凶”与对策Agent开发里最让人头疼的问题就是“输出的随机性”。同一个问题上午回答对下午回答错同一个事实换个时间线问语气都不对。这不是玄学根本原因在于大模型的温度参数temperature设置和提示词设计。我的经验是给Agent定义一个“默认模式”日常对话temperature设置为0.3代码生成类Skill设置为0.1只有创意写作类场景才允许调高到0.8以上。低温度能显著降低幻觉概率让输出贴近“事实”。如果是在Function Calling场景有些平台有一个temperature参数叫top_p要配合着一起调两者同时为1.0时代码输出比较稳定。另一个元凶是提示词中的“模糊指令”。比如你告诉模型“结果尽量准确一些”这话等于没说正确做法是给出明确的判断标准比如“只有当检索文档中出现确切的数字、日期、人名时才可以作为事实引用否则必须标注‘未能确认’”。把标准写清楚模型的稳定性会有质的飞跃。5.2 工具调用失败重试、降级与兜底策略在生产环境里Skill调用失败是常态不是你代码写得不好而是外部依赖总会出问题。文件解析失败、数据库连接超时、API限流……每一种失败都需要妥善处理。我设计了一个三层容错机制。第一层是重试。对于偶发性的网络问题和限流采用指数退避算法重试最多3次每次间隔翻倍1s、2s、4s。第二层是降级。比如某个Skill依赖第三方API当API不可用时回退到本地缓存的结果或者给用户返回一个简化版本的回答。第三层是兜底。当Skill彻底失败时Agent必须优雅地告诉用户“我尝试了但出错了”并提供可操作的下一步建议而不是甩出一段堆栈日志。我特别想强调兜底策略的重要性。很多Agent项目一遇到错误就崩溃或者瞎回答让用户体验非常糟糕。但如果能提前设计好“对不起我遇到了技术问题。你可以尝试刷新重试或者换个说法来描述需求”至少能保住用户对产品的基本信任。5.3 性能优化响应延迟从8秒降到1.5秒响应速度直接决定Agent能不能落地。我第一次搭好原型时一个简单问答平均要8秒用户根本无法接受。后来做了三件事降到了1.5秒。第一件事是Skill并行调用。Agent在多数场景下需要调用多个Skill如果串行执行时间就是各个Skill的总和后来我把能并行的Skill请求用asyncio.gather并发执行时间从加和变成了最大值效果立竿见影。import asyncio async def handle_multiple_skills(skills, params): tasks [asyncio.create_task(skill.execute(**p)) for skill, p in zip(skills, params)] results await asyncio.gather(*tasks) return results第二件事是流式输出。不要等整个回复生成完才给用户用SSEServer-Sent Events让模型边生成边返回用户的感知延迟会从“等待8秒后一口气出结果”变成“2秒后开始出字”体感好了不止一个量级。第三件事是提示词瘦身。很多Skill的提示词能精简掉一半。我做了个统计上下文多塞1000个token响应时间就要增加300-500毫秒所以提示词里只保留和当前任务强相关的信息背景知识和品牌故事这类东西能删就删。5.4 腾讯云部署的典型故障排查清单在腾讯云上线Agent服务的过程中我遇到过几类高频问题整理成速查表遇到类似问题可以直接对照排查。症状可能原因排查命令/方法服务端口通但访问超时安全组未放行该端口控制台检查安全组入站规则服务偶发断连腾讯云防火墙与系统防火墙叠加冲突sudo ufw status检查系统防火墙域名解析不生效DNS缓存未刷新dig 你的域名查看解析结果HTTPS证书过期未配置自动续期使用腾讯云免费证书的自动续期功能数据库连接数打满连接池未复用代码中用连接池替代每次新建连接Agent回复极慢模型API限流检查控制台配额改用异步批量调用上传大文件失败Nginx上传体积限制修改client_max_body_size还有一个常被忽略的细节如果你在腾讯云上绑定了域名并配置了HTTPS但后台服务的请求还是走HTTP浏览器会拦截混合内容导致API请求失败。解决方法是后端也统一改用HTTPS或者在前端配置一个反向代理来中转。6. Skill 生态的运营与持续优化6.1 从“能用”到“好用”Skill迭代的地板与天花板Skill上线只是第一步真正的挑战在于持续迭代。我建立了一套“数据驱动演进”的机制核心是记录每一次Agent回答的反馈数据用户有没有点赞、有没有追问、有没有直接放弃对话。每个月用这些数据对Skill的运行效果做一次复盘找出高频失败场景针对性优化提示词或调整执行逻辑。一个很典型的案例是周报生成器Skill最初版生成的周报太模板化用户反馈“像机器翻译”后来我在提示词里加入了“基于用户本周的实际任务记录写出有具体数据支撑、语气自然的总结”这一条质量提升明显。这种迭代是永无止境的每次优化都能带来真实体验的提升。6.2 Skill 的去中心化发布与复用当你的Skill积累到一定数量后管理就成了问题。这个项目的中后期团队已经有十多个Skill散落在不同代码库里调用关系混乱。后来我引入了一个Skill仓库概念每个Skill都按照统一规范打包带版本号用Git管理Agent服务启动时动态加载所有已注册的Skill。这个做法的好处是新的Agent项目立项后开发人员不需要从零写Skill而是先查Skill仓库找能复用的模块拼装组合即可效率提升非常明显。举个例子后来我们做了一个报表自动化Agent70%的能力直接复用了已有的数据查询、Excel导出、邮件发送等Skill真正需要新开发的只有20%剩下10%是参数调试。6.3 安全、合规与“Responsible Agent”Agent越“全能”它带来的安全风险就越大。一方面如果你的Agent能访问数据库、能发邮件、能操作业务系统那么它的权限控制就是生死线。我的经验是最小权限原则每个Skill只授予完成自身任务所需的最小权限数据库账号只读API密钥用环境变量隔离禁止在提示词里泄露任何敏感配置。另一方面Agent的价值观对齐也需要关注。模型可能被提示词注入攻击恶意用户可能通过巧妙的输入诱导Agent执行非预期操作。我的应对是双层联动首先在提示词层面加入“你是企业内部助手禁止泄露系统配置、禁止执行任何涉及金钱或隐私的操作”之类的护栏指令其次在Skill执行层面用代码做二次校验比如检测到SQL语句不是SELECT开头就直接拒绝。技术手段和社会工程学手段结合才能最大程度保障Agent的安全可靠。7. 总结与个人经验分享项目从零到上线最后稳定运行我最大的感悟是做Agent和带团队很像不要把希望全寄托在“老板”模型身上而是要精心组建一支“能打的队伍”AI Skills每一名成员都目标清晰、职责单一、反馈及时。模型负责聪明地调度Skill负责可靠地执行两者配合才能让Agent真正变成“养成”起来的全能存在。如果让我给准备入坑的人三个建议第一Skill化思维是第一位的先画清楚能力图谱再写代码第二尽快把项目放到真实环境里跑用真实用户的反馈迭代别在demo阶段停留太久第三记忆系统和错误处理一定要提前设计它们决定了Agent是“看起来聪明”还是“真的可靠”。最后分享一个小技巧在每次对话或Skill执行完成后主动让Agent在日志中记录一段“决策理由”比如“我选择调用database_queryer Skill因为用户明确提到了合同金额查询”。这些日志积累起来是优化Agent决策逻辑最宝贵的数据资产。你自己试过之后就会发现——Agent养成记的下一个精彩章节往往是这些看似不起眼的细节写就的。
返回列表