资讯动态

AI Agent落地:用Skills与工程工作流让智能体从能聊到能干

发布时间:2026/10/14 5:24:25 来源:尧图企业网站定制
做AI Agent落地这件事我踩过最大的坑不是模型能力不够而是工作流太随意——让Agent自由发挥结果就是它今天能用Python帮你写脚本明天就能对着数据库瞎猜字段名后天在生成代码时把接口文档里的参数写错两个。后来我从工程化的角度重新想这件事核心思路是不要把Agent当一个人而是把它当成一个有技能的实习生。你需要给这个实习生一本操作手册、一套工具清单、一个验收标准才敢让它独立干活。这套东西就是标题里说的Skills给 AI Agent 配一套工程工作流。简单来说Skill 是一份可以被加载、执行、校验的标准化能力单元工作流则是把这些Skill串成规划—执行—检查—修复—回归的闭环流水线。本文面向的是已经跑通了大模型基础调用、想进一步把Agent用进真实项目的开发者目标只有一个让你的Agent从能聊变成能干。1. Skills体系的核心设计思路1.1 为什么必须给Agent配置技能而不是甩给它一个Prompt很多人刚开始接触Agent开发时都有一个错觉Prompt写得足够详细模型就能完成复杂任务。试过几次就会发现完全不靠谱。Prompt本质是一段自然语言指令它没有强制结构没有校验逻辑也没有回退机制。你今天让它分析日志文件它可能真的写了段Python脚本去执行明天你让它分析日志文件它可能会给你输出一大段日志分析方法论然后什么也不做。这种不确定性在工程场景里就是灾难。我自己的转型点是做了一个内部日志分析工具。最初版就是一个大模型调用给它一段日志路径和一句帮我找出异常原因。效果不稳定同一个Agent同样的问题昨天和今天的结果可能完全不一样。后来我开始设计Skills体系把分析日志这个行为拆成固定组件一个技能清单文件描述这个技能做什么、什么时候用、输入输出是什么一个可执行的脚本实际去读取日志、做正则匹配、生成统计结果一个提示词模板告诉大模型怎么调用这个技能、怎么解读输出一组测试用例验证技能在当前环境下能不能跑通。这样一来Agent不再自己临场发挥而是在一个受控框架里做选择这个任务匹配哪个技能、该技能是否可用、输出应该按什么格式返回。Prompt不再是唯一的大脑它变成了一个决策器而Skill是肌肉记忆。1.2 工程工作流与零散Skill的本质区别单纯有Skills还不够。如果你只是给Agent配了20个Skill但没有定义调用顺序、失败重试规则、状态记录方式那Agent依然是一盘散沙。工程工作流解决的是多步复杂任务如何稳定推进的问题。一个完整的工程工作流通常包含几个固定节点任务理解与拆解Agent根据用户输入判断当前任务类型列出候选Skill列表执行计划生成确定先调用哪个Skill、后调用哪个Skill、哪些步骤可以并行Skill调度执行按照计划调用技能记录每个步骤的输入输出结果校验检查输出是否符合预期格式、是否满足验收条件自动修复校验失败时Agent读取错误信息尝试绕行方案或重新执行人工确认与回归测试关键操作前暂停等待确认完成后跑回归测试。这套流程的本质是把之前完全交给模型的判断力拆解成一个个可测试、可回滚、可审计的工程环节。你不再依赖模型临场发挥不犯错误而是依赖工作流即使某个环节出错也能被及时拦截或自动修正。我在这套机制上做了一个模拟项目X一个带后端API、前端页面和MySQL数据库的跨平台系统给Agent配置了代码变更技能、接口测试技能、数据库巡检技能和错误日志分析技能然后把它们串成一条变更上线工作流。最初半天时间换来的是系统性崩溃Agent按照自己的顺序乱改代码加入工作流后它必须按先读设计文档→再改代码→再跑测试→再提交变更记录的顺序走每一步都留痕整个流程稳定了很多。2. 技能清单与工作流编排的落地拆解2.1 一个标准Skill包应该包含哪些文件Skills的落地需要一套统一格式。我参考了几种开源Agent框架的插件设计结合自己做内部案例的经验最终固定下来这样一个目录结构skill_name/ ├── skill.yaml # 技能元信息名称、描述、入参、出参、权限 ├── execute.py # 技能核心逻辑实际执行的脚本 ├── PROMPT.md # 给LLM看的说明什么场景用、怎么用、注意什么 └── tests/ ├── test_01.py # 冒烟测试 └── fixtures/ # 测试用静态数据skill.yaml是整个技能的中枢。一个示例name: db_schema_inspector description: 连接MySQL数据库读取指定表的字段结构、索引和行数输出JSON格式的schema信息。 version: 1.0.0 author: internal_team inputs: table_name: type: string description: 需要检查的数据库表名 required: true db_name: type: string description: 数据库名称 required: true default: app_db outputs: schema_json: type: string description: 表结构JSON包含字段名、类型、是否为空、默认值、索引信息 execution: language: python entry: execute.py timeout: 30 allow_network: false allow_filesystem: - /tmp/skill_cache为什么这么设计因为LLM本身不擅长记忆精确的参数名称和调用约束。把输入输出用结构化配置文件声明清楚Agent在调用前先读取yaml知道自己该填什么参数、会拿到什么结果出错的概率大幅下降。而且yaml本身是文本格式模型可以直接读取解析不需要额外写解释器。PROMPT.md也是必不可少的部分。yaml解决的是技能对外接口定义问题PROMPT.md解决的是模型该怎么判断是否使用这个技能的问题。我习惯在里面写清楚三件事触发场景什么类型的用户问题应该调用此技能什么类型的问题不要调用调用前的检查项比如数据库是否可达、字段名是否疑似不存在输出格式说明模型拿到脚本返回的内容后如何整理给用户需要保留哪些字段哪些字段不能编造。2.2 工作流状态机设计从自由调用到受控执行Skill包定义好后工作流本身需要做成一个可运行的状态机。我最开始没有用状态机纯粹在代码里写死了一个执行序列第一步A、第二步B。一旦中途出现问题整个流程就卡死了。后面改成状态驱动每个步骤有明确的输入输出和转移条件Agent才能在异常时做出下一步选择。一个基础的工作流状态集合可以这样定义状态含义可能的下一个状态INIT任务刚创建等待拆解PLAN_DONE / TASK_REJECTEDPLAN_DONE执行计划已生成READY_TO_EXECUTEREADY_TO_EXECUTESkill列表确认完毕EXECUTINGEXECUTING单个Skill执行中SKILL_SUCCESS / SKILL_FAILED / SKILL_TIMEOUTSKILL_SUCCESSSkill执行返回等待校验VALIDATE_OK / VALIDATE_FAILEDVALIDATE_FAILED校验失败准备修复或更换方案RETRYING / PLAN_DONE / TASK_FAILEDTASK_FAILED多次重试失败任务终止无TASK_DONE任务成功结束无状态机的好处是Agent的每一次行为都记录在案。失败时可以直接定位到具体是哪个Skill出了问题、卡在哪个状态而不是黑盒里凭空猜测。在实际运行中我还会在状态切换时写一条日志包括时间戳、当前状态、触发事件、Skill输出摘要。这样最终复盘的时候整个任务链路一目了然。2.3 权限隔离与敏感操作闸口AI Agent一旦接通工程工作流最怕的不是它不会干而是它在不该执行操作的时候乱执行。我见过一个Agent在调试数据库时误执行了清空某个表的命令起因只是它判断这个表没数据可以考虑重置。所以权限隔离是Engineering workflow的底线不是可选项。我的经验是给Skill分三个等级只读级可以读取配置、日志、数据库schema、代码片段不允许写入沙箱级可以在隔离环境中执行脚本、操作临时文件不允许触碰生产环境生产级可以修改真实服务配置、变更数据库、发布程序但每次执行前必须人工确认。在状态机里加入HUMAN_CONFIRMATION_REQUIRED状态。当Agent判断当前操作属于生产级它不直接执行而是暂停输出一张操作单等待人点击确认后才继续。实测下来这套规则大约让每个任务增加30到60秒的等待时间但换回的是极高的安全性。对于涉及资金、权限、生产数据变动的场景这一步绝对不能省。3. 实操案例为某跨平台系统配置代码审查与自动修复工作流3.1 需求定义与Skill选型为了讲清楚完整流程我用一个具体的虚构案例来做演示。假设现在有一个内部系统叫某跨平台系统它是一个前后端分离项目前端使用现代JS框架后端是Python API服务数据库是MySQL。我需要给Agent配一套代码提交前自动审查的工作流要求Agent在每次代码变更提交到主干分支之前做四件事检查代码是否满足项目编码规范检查新增的接口是否与数据库表结构匹配检查是否有明显的安全隐患比如拼SQL、硬编码密钥如果发现问题自动给出修复建议但真正的代码修改必须等待人工确认。基于这些需求我选定了四个Skillcode_style_checker用项目统一配置的lint工具对代码做静态检查输出问题列表api_db_schema_inspector读取代码中的API查询语句对比数据库表结构输出字段匹配情况security_scanner对diff代码做正则扫描识别疑似密钥、危险函数调用、非参数化SQL查询autofix_suggester根据前三步的输出生成修复补丁patch并评估影响范围。这四个Skill都在前面讲过的标准skill包结构里实现。每个执行完输出统一为JSON格式带上status、summary、issues[]三个字段方便工作流统一收集和展示。3.2 工作流的具体执行过程整个工作流顺着状态机跑下来实际过程大致如下。第一步任务理解。Agent读取用户输入的代码变更描述以及关联的commit message识别出这是一个代码提交前审查任务。它从技能库里匹配到这四个Skill然后在计划里标记依赖关系先跑代码风格检查和安全扫描再跑数据库结构匹配最后才生成修复建议。第二步并行执行低风险技能。code_style_checker和security_scanner是只读型技能没有网络权限只读取代码仓库的diff内容可以并行执行。我在这里做了一层并发控制最多同时跑两个技能避免模型上下文被太多输出塞满。执行完毕两个技能返回了JSON格式的问题列表。第三步数据库结构匹配。api_db_schema_inspector需要连数据库。这里要注意它的skill.yaml里配置了allow_network: true但目标地址被限定为测试库的内网地址。工作流会先检查当前Agent运行所在环境是否允许访问该地址不允许就直接标记SKILL_FAILED而不是尝试绕过网络限制。第四步汇总与校验。Agent把这四个Skill的输出汇总后按严重级别排序阻止合并级别的问题比如拼接SQL、把密钥写进了代码、警告级别的问题比如函数命名不规范、提示级别的问题比如注释缺失。然后生成一份审查报告。第五步自动修复建议。autofix_suggester读取之前的issues为每个可自动处理的问题生成一份格式化的补丁建议。比如发现了硬编码密钥它会建议把密钥移到环境变量并给出修改后的代码片段。但补丁不会直接应用——工作流在这个节点设置了HUMAN_CONFIRMATION_REQUIRED会暂停等待开发者手动确认。实际跑下来这套流程给我的收益非常明显过去人工要花20分钟检查的提交Agent能在一两分钟内给出初步结论人工只需要看它生成的报告和补丁建议即可效率提升非常大。当然完全自动的修复还没有启用因为代码变更牵一发而动全身人工闸口是必须守住的。3.3 实操中的三个关键参数在整个过程中有几个参数很容易被忽略但对效果影响极大。上下文窗口预算。每个Skill执行结果都会进入Agent上下文。如果一次审查有几百个风格问题全都塞给模型上下文很快就爆了。我在工作流里给每个Skill的输出设置了截断上限默认最多返回20个最高优先级问题超过部分只统计数量不展开细节。这样既保留了关键信息又避免了token浪费。模型温度参数。涉及代码审查和修复建议的场景我把模型温度调成了0.2。温度太高模型会创造性地改出一些风格迥异的代码温度太低它可能只会机械套模板。0.2是我在多个项目里实测下来比较稳妥的值既能准确复述代码又能给出合理建议。超时控制。Skill执行不能无限等待。我统一设置了30秒超时超时后会主动杀掉子进程把状态标记为SKILL_TIMEOUT然后让Agent决定是否重试。这是针对底层工具挂死、数据库连接超时这类问题最直接有效的保护手段。4. 常见问题与排查技巧实录4.1 Skill执行成功但返回了明显错误的内容这是我在给Agent接Skills时遇到的第一个高频问题。表现是脚本正常执行完了exit code是0但输出的内容跟期望的完全不符。找了半天原因发现脚本里有个细节它读取的配置文件路径写的是相对路径而Agent工作目录在不同执行环境下不一样导致读到了旧配置。排查方法很简单在Skill包加一个诊断模式python execute.py --self-test--self-test会读取测试夹具里的样本数据输出结果与预期结果做比对。只要每次新增或修改Skill后先跑一次自检这个坑基本能避开。后来我把自检也集成到了工作流启动环节所有Skill先跑一遍冒烟测试全部通过才允许被Agent调用。经验是不要相信退出码0就等于正确。判断一个Skill执行成功与否一定要结合实际输出内容做校验。最简单的方式是检验输出JSON里是否包含关键字段字段缺失或类型不对直接判失败。4.2 Agent在多个Skill之间来回切换上下文被塞爆当一个任务触发了五六个Skill每个Skill都有长输出时LLM的上下文极快触顶。最初我的做法是把所有输出都塞进下一轮对话效果很差模型注意力被无关细节干扰指令遵循率明显下降。后来我做的改进是引入中间结果摘要器。每当一个Skill执行完成工作流不是把原始输出直接丢给模型而是先让模型生成一个不超过150字的摘要只保留结论、关键数据点、风险项。后续的决策判断都基于摘要进行。原始输出会存入文件夹只在需要追溯时读取。这样做的副作用是模型可能会在摘要过程中丢失一些细节。所以我给摘要器加了个约束涉及风险等级为Critical的信息不得省略如果原始输出中有多个Critical问题摘要必须以列表形式全部列出。实测下来上下文占用减少了大约60%而关键信息的保留率基本没有下降。4.3 数据库结构检查误报api_db_schema_inspector这类技能经常出现误报常见原因是代码里的查询语句写法多样。同一个功能可以用ORM方法、原生SQL、存储过程等不同方式实现简单的正则匹配很难覆盖全。我解决这个问题的思路是宁可漏报也不要误报。因为误报太多开发者会失去对Agent审查的信任最终放弃使用。在Skill内部我加了一道确认步骤当正则匹配到潜在问题时不直接判断为错误而是把候选字段名拿去数据库字典里做一次存在性验证。只有字段确实不存在才判定为真问题。如果字段存在则标记为疑似但不确认留给人工判断。这条经验可能和一般人想的不太一样——做AI Agent工程化不是为了让它显得什么都会而是让它坦诚知道自己不确定什么。保持输出可靠比输出全面重要得多。4.4 Agent与外部工具的服务握手问题Agent调用外部工具最常见的错误不是逻辑错误而是网络连接、认证失败、服务未启动这类环境问题。我在状态机里做出一个重试策略当Skill返回SKILL_FAILED且错误信息中包含connection refused、timeout、auth expired等关键字时工作流自动重试一次并在重试前用一个小脚本检测目标服务端口是否可达。# 端口连通性检查示例 nc -z -w 3 db.internal.example 3306这个检查脚本简单但实用。如果端口可达但认证失败那基本就是凭据过期如果端口不可达那就是环境问题。根据不同的失败原因Agent会选择直接重试还是上报给人工而不是盲目反复重试浪费时间。如果同一个Skill连续失败三次以上工作流会强制终止整条链路并生成一份失败报告。这样做的原因是大概率不是偶发问题再重试只会浪费时间和token。停下来把现场信息留给开发者处理才是工程化的正确态度。5. 我的实操心得与后续扩展方向5.1 实际用下来最值得保留的三个习惯第一个习惯是每个Skill都要有独立测试数据。不要用真实数据去测试因为真实数据里混合了太多干扰因素根本无法判断是Skill逻辑问题还是数据问题。我维护了一个fixtures/目录里面都是精简过的样本数据专门用于自检。这个习惯帮我节省了大量调试时间。第二个习惯是保留每个步骤的原始输出。“Agent生成的结果再漂亮如果无法追溯推导过程就是个黑盒。”我把执行记录按任务ID分目录存储每次执行都保存入参、出参、状态流转日志。一旦线上出了问题我可以直接回放Agent当时做了什么。第三个习惯是灰度优先。不要一开始就把所有Skill都接入生产工作流。我通常会在一个隔离的模拟项目X环境里跑一两天观察成功率、误报率、执行耗时稳定之后再把Skill逐步提升权限接入真实项目。对一个新Skill我个人的最低标准是10次测试中至少8次正确才考虑让它进入真实工作流。5.2 后续还可以往哪些方向扩展Skills体系一旦跑通扩展空间非常大。最常见的方向是让Skill支持多模态输入输出例如让Agent能够调用截图识别技能把前端页面截图转成UI元素列表再交给测试Skill做对照分析。这个方向在很多前端自动化测试场景里非常有用。另一个方向是跨Agent共享技能库。当Skill包格式固定后团队内部可以建一个共享仓库不同项目复用同一套代码检查、数据库巡检、日志分析技能。只需要在仓库里更新一份新配置所有Agent下次启动时就能自动获取最新版本的Skill不需要逐个项目修改。还有一个我自己比较推崇的方向是让Skill具备自我进化的能力。当某个Skill反复失败且失败模式统一时Agent可以先记录下这个模式然后生成一份升级请求报告——它不自己改Skill而是把问题定位清楚后交给人来处理。这样你的Agent系统会在使用中不断变稳而不是越用越乱。我给Agent配这套Skills工程工作流最初只是为解决AI回答不稳定的痛点做到后面发现它带来的最大变化不是回答更准了而是整个研发协作方式变了Agent从什么都能聊几句变成了在特定边界内可靠执行开发者从盯着它每一步变成了只在关键节点把关。如果你也在做Agent落地我建议不要从复杂的通用智能开始先挑一个具体到不能再具体的场景给它配一个Skill再串一条最基础的工作流跑通后再一点点加东西。这条路走得不快但每一步都稳。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑