Agent skills 工程实践:为什么“抽取公共层”在传统软件设计里是美德,在 Agents & Skills 里却经常变成毒药?
最近在搭建基于大模型的 Agent 系统时,踩了一个非常典型的坑,也因此和 Grok 深入聊了几轮,意外发现这个话题其实戳中了很多人在 Agent 工程化过程中的共鸣痛点。
简单一句话总结:
传统软件设计追求 DRY(Don't Repeat Yourself),把通用逻辑抽到公共层,让具体模块保持轻量;
但在 LLM Agent + Skills 的世界里,过度抽取到公共层(比如 agents.md 的系统提示)反而会导致遵守率暴跌、焦点丢失,甚至严重干扰原本很明确的 Skill 逻辑。
下面用一个真实的业务场景来说明这个反直觉的现象,以及为什么会这样,以及目前最务实的应对方式。
场景:订单异常处理的 Skill 集群
假设我们有一个订单异常处理的 Agent,需要处理多种异常类型(超时未发货、重复扣款、地址异常、库存负数……),每种异常对应一个 Skill。
最初的实现方式(传统软件思维)
每个 Skill 里都有一段几乎一模一样的登录逻辑:
# Skill: 超时未发货处理
1. 登录 SQL 工单平台(账号:xxx,密码:yyy,两步验证,session 保持,错误重试 3 次)
2. 查询订单表,筛选超时订单
3. 生成工单并提交
重复代码太多 → 抽取! 于是我们把登录相关规则全部挪到 agents.md(全局系统提示)的最前面:
全局规则 - 工单平台操作规范
任何涉及 SQL 工单平台、数据库查询、工单提交的操作,必须严格遵守以下登录流程:
- 使用账号 xxx / 密码 yyy
- 完成两步验证
- 保持 session 有效,若失效则重试 3 次
- 登录失败时抛出明确错误,不得继续执行后续步骤
- 业务订单的背景知识 ...
看起来 DRY 了,优雅了。
然后问题来了:遵守率崩了
- 简单 Skill(只有登录 + 一件事)还算正常
- 稍微复杂一点的 Skill(多步查询 + 判断 + 写工单 + 通知)就开始各种“失忆”: ** 直接跳过登录就去查表 ** 用错账号/环境 ** 在第 7 步突然想起来要登录,于是插入一个不合时宜的步骤 ** 甚至把登录规则当成“背景知识”而不是“必须执行的第一步”
最讽刺的是:把登录规则放回每个 Skill 开头后,效果立刻恢复,甚至比原来更好。
为什么会出现“越抽象越差”?
核心原因其实和大模型的注意力机制、上下文优先级、指令跟随偏好高度相关:
1.注意力稀释 & Recency Bias
全局规则放在 prompt 最前面,当 Skill 本身很长时,后面的具体指令会占据模型绝大部分注意力。 前面的规则逐渐变成“背景噪声”,模型“知道有这个规则,但不觉得现在要用”。
- 缺乏强触发锚点
放在 agents.md 里的规则是静态声明,没有和“当前 Skill”强绑定。 而原来每个 Skill 里写一遍,等于把“先登录”这件事放在了当前上下文最显眼的位置,触发强度完全不同。
- 噪声累积 & 焦点漂移
复杂 Skill 本身已经塞了很多业务逻辑、分支、格式要求。 再叠加几百 token 的公共规则,整体上下文变“脏”,模型容易在无关细节上纠结,或者直接跳过某些步骤。
- 当前 LLM 的指令忠诚度规律
模型对 局部、显式、重复出现 的指令遵守度,远高于 全局、抽象、只出现一次 的规则。 这和传统软件的 DRY 原则几乎完全相反。
一句话:在 LLM prompting 里,DRY 经常是反模式,尤其是对那些需要严格顺序的流程性任务。
目前社区和实践中最有效的应对策略
| 优先级 | 做法 | 适用场景 | 重复度 | 遵守率提升 | 维护成本 |
|---|---|---|---|---|---|
| ★★★★★ | 每个相关 Skill 开头显式写 3-5 行核心登录指令(“必须先完成登录,使用 xxx 账号……”) | 当前大多数中小型系统 | 中 | 最高 | 最低 |
| ★★★★☆ | agents.md 只保留最弱约束(“涉及工单/数据库操作前,确保已登录”),具体细节放 Skill 里 | 想尽量减少重复 | 低 | 高 | 低 |
| ★★★☆☆ | 把“登录”做成独立 Tool(login_sql),Skill 里强制写“第一步:call login_sql tool” | Skill 数量多、流程标准化 | 无 | 很高 | 中 |
| ★★☆☆☆ | 代码层动态注入:在生成 Skill prompt 时自动插入登录段落 | 使用代码生成/模板化 Skill | 无 | 高 | 中 |
| ★☆☆☆☆ | 多轮 / 子 Agent 拆分:登录交给基础设施 Agent,业务 Skill 只接收已登录状态 | 超大型系统 | 无 | 最高 | 高 |
最务实的起步建议:
先挑 2-3 个最常出问题的复杂 Skill,把 agents.md 里的登录相关全部删掉,只在这些 Skill 开头手动加回简洁的登录指令。 跑几轮相同 case 对比,你会明显看到“干扰消失、准确率回升”。
总结
传统软件设计:把通用部分抽到公共层,让具体实现保持轻量 → 美德
LLM Agent 工程:把关键步骤抽到公共层,往往让具体 Skill 失去焦点 → 毒药
在当前大模型的能力阶段,宁可局部重复,也别让关键动作被全局规则稀释掉。
等未来模型的上下文窗口更大、长上下文理解能力更强、或者有更好的“全局记忆”机制,这个规律可能会变。
但至少在 2025-2026 年,这几乎是 Agent 工程实践里最硬的一条经验教训。