
1. 从操作手册到可执行能力SkillForge 到底在解决什么问题企业里最尴尬的一类资产就是那些躺在 Confluence、飞书文档、语雀或者某个共享盘里的操作手册。写的时候兴师动众评审、盖章、发版号结果真到出事的时候值班的人还是靠群里吼、靠老员工记忆、靠翻聊天记录。手册本身没错错在它只能被人读不能被机器执行更没法证明我确实按手册做了。SkillForge 这个项目干的就是把这种死文档编译成 Agent 能直接调用、能自证合规、还能随环境变化自己迭代的 Skill。注意这里的三个关键词可证明、可进化、Agent 能力。可证明意味着每次执行都有据可查、有断言可验可进化意味着手册改了、环境变了Skill 能跟着更新而不是变成新的技术债Agent 能力意味着它不是给人看的文档而是给 Agent 调用的结构化能力单元。我接触过不少团队做 Agent卡点几乎都一样模型很聪明工具也接了一堆但一到按公司规范处理线上故障这种场景就露馅。因为规范是自然语言写的模型每次理解都可能不一样今天这么干明天那么干审计根本过不了。SkillForge 的思路是把 Runbook运维操作手册当作源文件经过一层编译产出带前置条件、执行步骤、后置断言、回滚路径的 Skill 包。Agent 调用的时候不是读文档然后自由发挥而是加载 Skill 然后按契约执行。这套东西适合谁三类人最该看一是手里攥着一堆 SOP 却不知道怎么喂给 Agent 的平台工程师二是被Agent 执行结果不可复现折磨的 SRE 和运维负责人三是正在做 Agent 框架与编排、需要一套能力注册与评估机制的技术负责人。哪怕你现在只是用 Codex Skill 或者豆包 Skill 做点小工具理解这套编译思路也能让你的 Skill 从能跑变成敢上生产。2. 整体设计思路为什么是编译而不是检索2.1 检索式方案的天花板在哪里现在主流做法是 RAG把手册切块、向量化Agent 遇到问题就检索相关段落塞进上下文让模型照着做。这套方案上手快但用在操作类场景有三个绕不过去的坑。第一个坑是步骤顺序不可控。手册里先停流量再改配置和先改配置再停流量向量检索可能把两段都召回模型一抖就选错顺序后果可能是线上直接雪崩。第二个坑是缺少可验证的完成条件。检索回来的是文字Agent 执行完没人知道到底做没做对只能靠人再去看一眼。第三个坑是版本漂移。手册更新了向量库没同步Agent 还在按老版本执行这种事故最难查。SkillForge 选择编译路线本质是把理解这件事从运行时前移到构建时。构建时由人或者强模型把自然语言手册翻译成结构化 Skill 定义运行时 Agent 只负责按结构执行不再做语义猜测。这就好比数据库的预编译语句SQL 解析一次之后反复执行都是确定行为而不是每次重新解析字符串。2.2 编译管线的四个阶段整条管线我拆成四段每段都有明确的输入输出契约。解析阶段输入是原始 RunbookMarkdown、Word 甚至截图 OCR 都行输出是中间表示 IR。IR 里把手册拆成触发条件、前置检查、执行步骤、验证断言、回滚步骤五类节点。这一步是整个项目最脏最累的活因为企业手册的写法千奇百怪有的用编号列表有的用表格有的干脆是一段散文。绑定阶段把 IR 里的每个动作节点绑定到具体的工具或脚本。比如重启订单服务要绑定到具体的 K8s API 调用或者 Ansible playbook检查磁盘使用率要绑定到具体的监控查询语句。绑定信息单独存和 IR 解耦这样同一份手册在不同环境可以绑不同的实现。断言生成阶段这是可证明的核心。每个执行步骤后面要挂至少一条后置断言断言必须是机器可判定的比如服务健康检查返回 200、磁盘使用率低于 80%、订单表主键无重复。断言写不出来说明这一步本身就没定义清楚编译直接报错。打包阶段产出 Skill 包包含 Skill 元数据、IR、绑定表、断言集、版本号和签名。Agent 加载的是这个包不是原始文档。2.3 为什么可进化要单独设计很多团队做 Skill 是一次性的做完就冻结。但企业环境天天变IP 会变、服务名会变、阈值会变。SkillForge 把进化能力做进设计里靠的是两样东西执行反馈回流和断言漂移检测。执行反馈回流是指每次 Skill 执行的结果成功、失败、断言命中情况都记录下来形成执行轨迹。当某个断言连续多次失败但人工确认业务正常时系统会标记这个断言可能过时了提示重新校准。断言漂移检测则是定期用当前环境跑一遍所有断言发现哪些已经不再成立。注意进化不等于自动改 Skill。任何对 Skill 语义的修改都必须经过人工确认或者至少是强模型加人工复核否则 Agent 自己改自己的执行逻辑风险不可控。3. 核心细节解析IR 设计与断言体系3.1 中间表示 IR 的字段设计IR 是整个编译管线的中枢设计得好不好直接决定后面顺不顺。我建议的字段结构如下这是我在实际项目里反复调整后比较稳的一版。字段类型说明是否必填skill_idstring全局唯一标识建议用 领域.对象.动作 命名是triggerobject触发条件含事件类型和匹配表达式是preconditionsarray前置检查列表每条含检查项和期望值是stepsarray执行步骤每步含动作、绑定引用、超时是assertionsarray后置断言每步至少一条是rollbackarray回滚步骤结构同 steps是blast_radiusenum影响范围单实例/单服务/全站是ownerstring责任人用于审批和告警是blast_radius这个字段容易被忽略但它决定了 Skill 能不能自动执行。影响范围是全站的 Skill我一般强制要求人工二次确认哪怕断言全过也不让 Agent 自己拍板。3.2 断言怎么写才算可证明断言是 SkillForge 区别于普通 Skill 的灵魂。写断言有个硬标准必须能被一段确定性代码判定真假不能依赖模型判断。反例服务恢复正常——什么叫正常模型说正常就正常这不行。正例curl -s localhost:8080/health返回 JSON 中status字段等于UP且响应时间小于 500ms。这个断言可以写成一个函数返回布尔值没有任何歧义。断言分三类我建议每类都覆盖到状态断言检查某个资源当前状态如 Pod 副本数、数据库连接数。副作用断言检查操作产生的副作用如配置中心里某个 key 的值已更新。负向断言检查不该出现的情况没出现如错误日志里没有新增 ERROR 级别记录。负向断言最容易被漏掉但恰恰是它最能兜住操作看似成功实则埋雷的情况。比如重启服务后健康检查过了但日志里开始刷连接超时负向断言就能抓住。3.3 绑定层的解耦设计绑定层我强烈建议用逻辑动作名 环境实现的两级映射。IR 里只写逻辑动作名比如restart_service具体到某个环境才映射到kubectl rollout restart deployment/order-svc -n prod。这样做的好处是同一份 Skill 可以在测试环境和生产环境复用只是绑定表不同。测试环境绑到 mock 实现生产环境绑到真实 API。切换环境只换绑定表IR 和断言完全不动。绑定表本身建议用 YAML 管理纳入版本控制。每次绑定变更都走 PR 评审这样谁在什么时候把重启命令从 A 改成 B永远查得到。4. 实操过程从一份真实 Runbook 到可执行 Skill4.1 准备一份可编译的 Runbook不是所有手册都能直接编译。我总结了一份可编译 Runbook的最低要求达不到的先做人工整理。步骤必须是有序的不能是可以按任意顺序执行。每步必须能对应到一个具体动作不能是评估情况这种纯认知活动。必须有明确的完成标志哪怕是看到日志出现 XXX。必须有回滚方案没有回滚的操作不允许编译成自动 Skill。拿一份订单服务内存告警处理的手册举例原始版本可能是这样的散文当订单服务内存使用率超过 85% 时先确认是否有大促流量如果是正常流量增长则扩容如果是内存泄漏则重启并保留堆转储。这段文字人看得懂但机器没法直接执行。编译第一步就是把它拆成判定树先查流量指标分支到扩容或重启重启前先触发堆转储。4.2 编译命令与产物结构假设 SkillForge 的 CLI 叫forge一次典型编译长这样forge compile \ --source runbooks/order-memory-alert.md \ --env prod \ --output skills/order-memory-alert \ --strict--strict表示任何一步缺断言或缺回滚都直接失败不允许产出半成品。这个开关在 CI 里必须开本地调试可以关掉看警告。编译产物目录结构skills/order-memory-alert/ ├── skill.yaml # 元数据、版本、签名 ├── ir.json # 中间表示 ├── bindings.prod.yaml # 生产环境绑定表 ├── assertions.py # 断言实现 └── traces/ # 执行轨迹运行时写入assertions.py里每个断言是一个纯函数输入是执行上下文输出是布尔值加证据。证据很重要断言失败时要能说清楚我查了什么、看到什么、期望什么不然排查全靠猜。4.3 断言函数的写法示例def assert_memory_below_threshold(ctx): 后置断言内存使用率低于 70% value ctx.metrics.query( container_memory_usage_ratio, labels{service: order-svc, env: prod} ) return { passed: value 0.70, evidence: f当前内存使用率 {value:.2%}阈值 70% }注意这里返回的是字典而不是裸布尔值。证据字段在断言失败时会直接进告警内容值班的人一眼就知道差多少不用再去翻监控。4.4 执行时的加载与校验流程Agent 执行 Skill 不是拿到就跑中间有三道校验。第一道是签名校验确认 Skill 包没被篡改版本和审批记录对得上。第二道是前置检查把 preconditions 全部跑一遍任何一条不满足直接拒绝执行不允许边执行边检查。第三道是影响范围确认如果 blast_radius 是单服务以上触发人工确认流程。三道校验都过了才进入执行。执行过程中每步结束立即跑该步的断言断言失败就停在原地不继续往下走同时触发回滚建议。这个失败即停的策略是我踩过坑之后定下来的早期版本允许继续执行结果一个中间步骤失败后面全乱套回滚都不知道从哪回。5. 评估体系怎么证明 Skill 本身是靠谱的5.1 评估的三个维度Skill 编译出来不是终点还得证明它靠谱。我从三个维度做评估对应热词里的 Evaluation。正确性在受控环境里跑一遍断言是否全部通过。这是最基本的但只跑一遍不够要跑多次看稳定性。鲁棒性故意注入故障比如让某个依赖超时、让某个断言必然失败看 Skill 能不能正确停在失败点并给出合理回滚建议。鲁棒性差的 Skill 在真实故障里会帮倒忙。可复现性同样的输入和环境多次执行结果是否一致。如果每次执行路径都不一样说明 Skill 里还有依赖模型自由发挥的地方得回去改。5.2 评估用例的组织评估用例我建议按场景 预期结果组织存成 YAML。- name: 内存告警-正常扩容路径 input: alert: order-svc-memory-high traffic: normal_growth expect: path: [check_traffic, scale_up, assert_memory_below_threshold] final_status: success - name: 内存告警-泄漏重启路径 input: alert: order-svc-memory-high traffic: flat expect: path: [check_traffic, dump_heap, restart_service, assert_memory_below_threshold] final_status: success评估跑的时候对比实际执行路径和预期路径路径不一致即使最终状态是 success 也要报警因为可能走了非预期分支。5.3 断言漂移的定期检测前面提到可进化落地手段就是定期跑断言漂移检测。做法很简单写个定时任务每天凌晨用当前生产环境跑一遍所有 Skill 的断言只跑断言不跑执行步骤把失败的断言汇总成报告。连续失败超过阈值比如 7 天的断言自动创建工单让人复核。是环境真的变了要改断言还是业务本身出问题了人工判断。这个机制能抓住很多手册早就过时但没人更新的隐性债务。提示漂移检测只跑断言不跑执行所以是只读操作可以放心在生产环境跑。但要注意断言里如果有写操作比如触发一次健康检查会打日志要评估日志量。6. 常见问题与排查技巧实录6.1 编译期常见报错报错信息根因解决思路step without assertion某步没写后置断言补断言写不出来说明这步定义不清unbound action: xxx逻辑动作名在绑定表里找不到检查绑定表拼写或补绑定rollback missing for destructive step破坏性操作没回滚补回滚补不出来就别自动执行ambiguous precondition前置条件表述有歧义改写成可判定的表达式circular dependency in steps步骤依赖成环拆 Skill 或调整顺序6.2 运行期典型故障断言全过但业务异常。这种情况一般是断言覆盖不够漏了某个关键维度。排查方法是把这次执行的轨迹和业务异常时间线对齐看哪个环节没被断言覆盖补上。Skill 执行到一半卡住。多半是某个绑定动作超时但没设超时时间。所有绑定动作必须设超时超时后按失败处理并触发回滚。我一般把超时设成正常耗时的 3 倍既给足余量又不至于卡死。回滚执行失败。这是最麻烦的说明回滚本身也需要断言和演练。我的做法是回滚步骤也要在评估环境里定期演练不能等到真出事才第一次跑回滚。版本对不上。Agent 加载的 Skill 版本和审批版本不一致通常是缓存问题。Skill 包加载时强制校验版本哈希对不上就拒绝加载。6.3 几条踩坑换来的经验第一条别追求一次编译全自动。企业手册质量参差不齐纯自动编译出来的 Skill 十有八九有坑。我的做法是自动编译出草稿人工过一遍 IR 和断言确认后再打包。人工这一步省不得。第二条断言宁少勿滥。早期我恨不得每步挂五条断言结果执行慢、误报多值班的人开始无视告警。后来精简到每步一到两条最关键的反而更受信任。第三条Skill 粒度要适中。一个 Skill 干一件事别把整个故障处理流程塞进一个 Skill。粒度太粗回滚困难粒度太细编排复杂。我的经验是一个 Skill 对应 3 到 7 个执行步骤比较合适。第四条执行轨迹一定要留全。每次执行的输入、每步的输出、每条断言的证据全部落盘。出问题的时候这些轨迹就是唯一的真相来源比任何日志都管用。7. 和现有 Agent 生态怎么接SkillForge 产出的 Skill 包是标准化的理论上可以接到任何支持工具调用的 Agent 框架上。接入点就一个Agent 加载 Skill 包后把 steps 注册成可调用工具把 assertions 注册成执行后的校验钩子。和 Codex Skill、豆包 Skill 这类现成方案比SkillForge 多出来的是编译管线和断言体系。如果你的场景只是个人用的小工具直接用现成 Skill 就够了没必要上这套重装备。但如果是企业级、要过审计、要多人协作的场景编译加断言这套东西省不掉。Agent 记忆这块也值得说一句。Skill 执行轨迹本身就是一种高质量的记忆素材比对话历史结构化得多。把轨迹喂给 Agent 做长期记忆下次遇到类似场景它能直接参考历史执行路径而不是从零推理。这块我还在摸索目前的做法是把成功轨迹按 skill_id 归档检索时优先召回同 Skill 的历史成功路径。最后分享一个我自己的体会SkillForge 这类项目的价值不在于让 Agent 更聪明而在于让 Agent 的行为更可预期。企业敢把操作权限交给 Agent前提是每一步都能被证明、被追溯、被回滚。把手册编译成 Skill本质上是在给 Agent 划一条它不能越过的轨道轨道之内随便跑轨道之外一步都别想动。这条轨道修得越扎实Agent 能承担的责任就越大。