agent skill实战:结构设计 + 故障排查实战
<h2 id="前言">前言</h2><p>本文将使用一个例子“线上故障排查”,结合该例子,来详细讨论一下skill在实战中的应用</p>
<h2 id="skill的组成">skill的组成</h2>
<pre><code class="language-text">.
├── SKILL.md
├── references/
├── examples/
└── scripts/
</code></pre>
<ul>
<li>
<p>SKILL.md:主入口文件</p>
<ul>
<li>这个 Skill 是干什么的</li>
<li>什么时候触发</li>
<li>先读哪些参考资料</li>
<li>按什么顺序执行</li>
<li>输出结构是什么</li>
<li>哪些行为必须避免</li>
</ul>
</li>
<li>
<p>references/:参考资料目录</p>
<ul>
<li>规则和资料分离,维护更清楚</li>
<li>主文件不至于写成一坨</li>
<li>后面更新局部知识时,不用频繁改主 Skill</li>
</ul>
</li>
<li>
<p>examples/:示例目录,这个目录里通常放两类东西:</p>
<ul>
<li>标准输入示例</li>
<li>标准输出示例</li>
</ul>
</li>
<li>
<p>scripts/:脚本目录</p>
</li>
</ul>
<h2 id="skill实践">skill实践</h2>
<p>下面我们来说一个,线上故障排查的例子</p>
<pre><code class="language-text">.
├── SKILL.md
├── references/
│ ├── triage-playbook.md
│ ├── metrics-checklist.md
│ └── output-template.md
├── examples/
│ ├── alert-input.json
│ └── expected-analysis.md
└── scripts/
</code></pre>
<table>
<thead>
<tr>
<th>文件</th>
<th>示例路径</th>
<th>作用</th>
</tr>
</thead>
<tbody>
<tr>
<td>主 skill 文件</td>
<td><code>SKILL.md</code></td>
<td>定义触发条件、执行流程、边界、输出要求</td>
</tr>
<tr>
<td>排障手册</td>
<td><code>references/triage-playbook.md</code></td>
<td>存放排障原则、先后顺序、常见排查思路</td>
</tr>
<tr>
<td>指标检查清单</td>
<td><code>references/metrics-checklist.md</code></td>
<td>规定看哪些指标、哪些现象该重点关注</td>
</tr>
<tr>
<td>输出模板</td>
<td><code>references/output-template.md</code></td>
<td>统一分析结果结构,避免每次输出漂移</td>
</tr>
<tr>
<td>输入样例</td>
<td><code>examples/alert-input.json</code></td>
<td>给这个 skill 一个标准化输入示例</td>
</tr>
<tr>
<td>输出样例</td>
<td><code>examples/expected-analysis.md</code></td>
<td>演示符合预期的排障分析结果</td>
</tr>
</tbody>
</table>
<p>代码路径: skill实践</p>
<h2 id="使用方式">使用方式</h2>
<ul>
<li>
<p>使用claude code作为载体来使用skill,先将该项目移动到~/.claude/skills/下面</p>
</li>
<li>
<p>登陆claude code开始使用</p>
<p><img alt="watermarked-1" loading="lazy" src="https://img2024.cnblogs.com/blog/1416773/202604/1416773-20260428182346896-742974830.jpg" class="lazyload"></p>
</li>
<li>
<p>得到结果</p>
<p><img alt="watermarked-2" loading="lazy" src="https://img2024.cnblogs.com/blog/1416773/202604/1416773-20260428182354360-270027057.jpg" class="lazyload"></p>
</li>
</ul>
<p>当使用标准的输入数据</p>
<pre><code>{
"service": "order-service",
"env": "prod",
"time_window": "2026-04-24 14:05 ~ 14:12",
"alert_title": "订单服务 5xx 错误率升高",
"symptom": "/api/order/create 接口错误率从 0.3% 升到 18%",
"logs": [
"2026-04-24T14:06:13 ERROR order-service create order failed: dial tcp 10.21.4.15:3306: i/o timeout",
"2026-04-24T14:06:14 ERROR order-service query inventory failed: dial tcp 10.21.4.15:3306: i/o timeout"
],
"metrics": {
"5xx_rate": "0.3% -> 18%",
"p95_latency": "120ms -> 4.8s",
"db_connection_timeout": "持续升高",
"cpu": "无明显异常",
"memory": "无明显异常"
}
}
</code></pre>
<p>skill返回的答案通常是非常完整的,但是如果不给它这么全的数据的时候,结果会怎样?</p>
<h2 id="提供非标数据">提供非标数据</h2>
<p>本次不用标准数据,而是非常笼统的数据咨询,看看得到的结果是什么</p>
<blockquote>
<p>order-service出现了问题,订单服务 5xx 错误率升高,日志:2026-04-24T14:06:13 ERROR order-service create order failed: dial tcp 10.21.4.15:3306: i/o timeout</p>
</blockquote>
<p><img alt="watermarked-3" loading="lazy" src="https://img2024.cnblogs.com/blog/1416773/202604/1416773-20260428182403105-707386094.jpg" class="lazyload"></p>
<p>成功使用对应skill,开始分析</p>
<p><img alt="watermarked-4" loading="lazy" src="https://img2024.cnblogs.com/blog/1416773/202604/1416773-20260428182410717-492665181.jpg" class="lazyload"></p>
<p>证据链太少,并不能分析出根因以及对应的解决方案,如果还需要继续排查,就要不断的提供对应的数据</p>
<h2 id="添加数据查询工具">添加数据查询工具</h2>
<ul>
<li>
<p>为了让skill在排查的过程中,能够获取到新的数据,在/scripts下添加一个查询工具:获取mysql的状态<code>get_mysql_state</code></p>
</li>
<li>
<p>先告诉skill有工具可以调用,在SKILL.md中添加新的参考资料 <code>references/tools.md</code></p>
</li>
<li>
<p>在<code>references/tools.md</code>添加脚本使用方式</p>
</li>
</ul>
<p>再来看看效果:</p>
<p><img alt="watermarked-5" loading="lazy" src="https://img2024.cnblogs.com/blog/1416773/202604/1416773-20260428182416105-1547141752.jpg" class="lazyload"></p>
<p>skill启动之时,读取了参考资料,并且获取了mysql是否通畅的证据</p>
<h2 id="function-call-与-skill">function call 与 skill</h2>
<p>skill的简单使用已经介绍完毕了,下面来对比一下function call与skill,这俩之间在什么场景下去使用</p>
<p>与之前介绍过的function call :</p>
<ul>
<li>function call 实战:让 LLM 自动判断 pod 异常、调用日志工具并完成故障分析</li>
<li>别再写 if/else 了:让 LLM 自己决定调用哪个函数</li>
</ul>
<p>进行对比:</p>
<table>
<thead>
<tr>
<th></th>
<th>function call</th>
<th>skill</th>
</tr>
</thead>
<tbody>
<tr>
<td>定位</td>
<td>function call更合适出现在底层工具的建设中</td>
<td>skill是ai agent的强力助手</td>
</tr>
<tr>
<td>环境依赖</td>
<td>不依赖 Claude Code、openclaw 环境,可作为独立服务部署</td>
<td>需要claude code、openclaw等环境,不能独立存在</td>
</tr>
<tr>
<td>优化策略</td>
<td>需要不断修改代码来进行不断优化(不管是流程代码,还是prompt)更像是传统开发流程</td>
<td>通过更新 references 下的 markdown 文档即可优化策略,当然也会有script的优化</td>
</tr>
<tr>
<td>最佳场景</td>
<td>自动化、集成到现有系统</td>
<td>ai agent的优秀辅助、结构化分析问题</td>
</tr>
<tr>
<td>共同协作</td>
<td>skill 调用 function call 作为工具</td>
<td>function call 参考 Skill 的流程规范</td>
</tr>
</tbody>
</table>
<h2 id="总结">总结</h2>
<p>本文介绍了skill的基本自称以及用了一个实际例子作为案例剖析展现了如何使用skill</p>
<p>再次对比了function call与skill,在各自对应的环境起到的作用</p>
<h2 id="联系我">联系我</h2>
<ul>
<li>联系我,做深入的交流</li>
</ul>
<p><img alt="" width="500" height="200" loading="lazy" src="https://img2024.cnblogs.com/blog/1416773/202411/1416773-20241121135740959-1907948957.png#" class="lazyload"></p>
<p>至此,本文结束</p>
<p>在下才疏学浅,有撒汤漏水的,请各位不吝赐教...</p>
</div>
<div id="MySignature" role="contentinfo">
<p>本文来自博客园,作者:it排球君,转载请注明原文链接:https://www.cnblogs.com/MrVolleyball/p/19945966</p>
<div>本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。 </div><br><br>
来源:https://www.cnblogs.com/MrVolleyball/p/19945966
頁:
[1]