Learn Claude Code Agent 开发 | 5、按需技能加载:领域知识不用全塞系统提示

Learn Claude Code Agent 开发 | 5、按需技能加载:领域知识不用全塞系统提示

整体概述

技能加载核心实现引入了按需技能加载机制,核心思想是:

"用到什么知识, 临时加载什么知识" -- 通过 tool_result 注入, 不塞 system prompt。
Harness 层: 按需知识 -- 模型开口要时才给的领域专长。

这解决了领域知识注入的核心痛点:避免把所有领域规则都塞进系统提示导致token浪费和上下文臃肿,实现了"需要什么知识再加载什么知识"的轻量化知识管理。


解决的核心问题

之前的知识注入方式的缺陷:

  1. 把所有领域规则(git约定、测试规范、代码审查清单等)全塞进系统提示太浪费token
  2. 10个技能每个2000token就是20000token,大部分和当前任务毫无关系
  3. 技能越多系统提示越臃肿,反而会稀释核心指令的权重

核心架构设计

复制代码
两层注入机制:
┌─────────────────────────────────────────────────┐
│ Layer 1 (低成本,常驻系统提示):                  │
│ System prompt                                    │
│ +--------------------------------------+         │
│ | You are a coding agent.              |         │
│ | Skills available:                    |         │
│ |   - git: Git workflow helpers        |  ~100 token/skill
│ |   - test: Testing best practices     |         │
│ +--------------------------------------+         │
└─────────────────────────────────────────────────┘

当模型调用 load_skill("git") 时触发第二层注入:
┌─────────────────────────────────────────────────┐
│ Layer 2 (按需加载,仅在需要时注入):              │
│ tool_result                                      │
│ +--------------------------------------+         │
│ | <skill name="git">                   |         │
│ |   Full git workflow instructions...  |  ~2000 token
│ |   Step 1: ...                        |         │
│ |   Step 2: ...                        |         │
│ | </skill>                             |         │
│ +--------------------------------------+         │
└─────────────────────────────────────────────────┘

核心创新:

  1. 分层注入:第一层只在系统提示放技能的名称和描述(非常轻量),第二层需要时才加载完整技能内容
  2. 技能文件化 :所有技能都以 skills/<技能名>/SKILL.md 的形式存储,支持YAML frontmatter元数据
  3. 完全兼容现有架构:技能加载只是新增一个普通工具,核心循环不需要做任何修改

逐段解析

1. SkillLoader 类 ⭐ 核心组件

python 复制代码
class SkillLoader:
    def __init__(self, skills_dir: Path):
        self.skills_dir = skills_dir
        self.skills = {}
        self._load_all()  # 启动时扫描所有技能文件

    def _load_all(self):
        """递归扫描skills目录下所有SKILL.md文件"""
        if not self.skills_dir.exists():
            return
        for f in sorted(self.skills_dir.rglob("SKILL.md")):
            text = f.read_text()
            meta, body = self._parse_frontmatter(text)
            name = meta.get("name", f.parent.name)  # 优先用frontmatter里的name,没有就用目录名
            self.skills[name] = {"meta": meta, "body": body, "path": str(f)}

    def _parse_frontmatter(self, text: str) -> tuple:
        """解析YAML frontmatter(---分隔的元数据部分)"""
        match = re.match(r"^---\n(.*?)\n---\n(.*)", text, re.DOTALL)
        if not match:
            return {}, text
        meta = {}
        for line in match.group(1).strip().splitlines():
            if ":" in line:
                key, val = line.split(":", 1)
                meta[key.strip()] = val.strip()
        return meta, match.group(2).strip()

    def get_descriptions(self) -> str:
        """Layer 1:生成系统提示里的技能描述列表,非常轻量"""
        if not self.skills:
            return "(no skills available)"
        lines = []
        for name, skill in self.skills.items():
            desc = skill["meta"].get("description", "No description")
            tags = skill["meta"].get("tags", "")
            line = f"  - {name}: {desc}"
            if tags:
                line += f" [{tags}]"
            lines.append(line)
        return "\n".join(lines)

    def get_content(self, name: str) -> str:
        """Layer 2:返回完整的技能内容,通过tool_result注入"""
        skill = self.skills.get(name)
        if not skill:
            return f"Error: Unknown skill '{name}'. Available: {', '.join(self.skills.keys())}"
        return f"<skill name=\"{name}\">\n{skill['body']}\n</skill>"

设计亮点

  • 零依赖解析:用正则手动解析frontmatter,不需要引入PyYAML等额外依赖
  • 自动扫描 :启动时自动递归扫描 skills目录下所有 SKILL.md,新增技能只需要加文件,不需要改代码
  • 灵活命名:技能名优先用文件里的元数据,没有就用目录名,使用方便
  • 标签支持:支持给技能打标签,方便模型理解技能的适用场景

2. 系统提示动态生成

python 复制代码
# Layer 1: skill metadata injected into system prompt
SYSTEM = f"""You are a coding agent at {WORKDIR}.
Use load_skill to access specialized knowledge before tackling unfamiliar topics.

Skills available:
{SKILL_LOADER.get_descriptions()}"""
  • 系统提示里动态注入可用技能的列表,每次启动自动更新
  • 明确告诉模型遇到不熟悉的领域时先调用 load_skill加载相关知识
  • 这部分非常轻量,每个技能只占几十token,10个技能也才几百token

3. 工具注册

和之前的版本相比,只新增了一个 load_skill工具,完全符合"加工具只加handler"的设计原则:

python 复制代码
TOOL_HANDLERS = {
    # ...其他基础工具不变...
    "load_skill": lambda **kw: SKILL_LOADER.get_content(kw["name"]),
}

TOOLS = [
    # ...其他基础工具不变...
    {"name": "load_skill", "description": "Load specialized knowledge by name.",
     "input_schema": {"type": "object", "properties": {"name": {"type": "string", "description": "Skill name to load"}}, "required": ["name"]}},
]
  • load_skill和其他工具完全平等,通过分发字典注册
  • 模型可以像调用bash、read_file一样调用这个工具
  • 返回的技能内容作为普通的tool_result进入对话上下文

4. 核心智能体循环

和之前版本的循环完全一致,没有做任何修改,完美体现了开闭原则:扩展功能不需要修改核心逻辑


5. 交互式主循环

和之前版本完全一致,仅提示符做了修改。


版本对比

组件 子智能体版(s04) 技能加载版(s05)
工具数量 5个(基础+task) 5个(基础+load_skill)
系统提示 静态固定字符串 动态注入技能描述列表
知识库 skills/*/SKILL.md 文件系统存储
知识注入方式 两层注入:系统提示(轻量)+ 按需加载(完整)
扩展性 新增知识需要改代码 新增技能只需要加SKILL.md文件

使用示例

bash 复制代码
python agents/s05_skill_loading.py
s05 >> What skills are available?
> load_skill: [显示所有可用技能列表]
s05 >> I need to do a code review -- load the relevant skill first
> load_skill (code-review): <skill name="code-review">
  # 代码审查规范
  1. 检查是否有类型标注
  2. 检查是否有单元测试
  3. 检查是否符合PEP8规范
  ...
  </skill>
s05 >> Load the agent-builder skill and follow its instructions
> load_skill (agent-builder): [加载智能体构建技能的完整内容]

核心设计思想和收获

技能加载机制建立了智能体领域知识管理的核心范式:

1. 按需加载,token效率最大化

不需要的知识永远不加载,10个技能每个2000token,之前需要20000token常驻系统提示,现在只需要几百token的技能列表,节省95%以上的token开销。

2. 知识和代码完全解耦

新增技能不需要修改任何代码,只需要在 skills目录下加一个 SKILL.md文件,运营人员也可以维护技能库,不需要开发参与。

3. 版本化管理方便

技能是纯markdown文件,可以用git做版本管理,支持回滚、diff、审核等工作流。

4. 可扩展性极强

可以支持任意领域的技能:代码审查、git规范、设计规范、安全检查、项目业务规则等等,完全不限制使用场景。

这种设计完美解决了"让智能体遵守特定领域规则"的需求,同时保持了架构的简洁性和扩展性,是生产级智能体系统的必备功能。

本内容参考开源项目 learn-claude-code

相关推荐
mit6.8242 小时前
we define first and then see
人工智能
金士镧(厦门)新材料有限公司2 小时前
稀土化合物:科技世界的隐形英雄
人工智能·科技·安全·全文检索·生活
ZzT2 小时前
飞书CLI开源:200+命令让Claude Code直接操控你的飞书
人工智能·llm·claude
NocoBase2 小时前
【2.0 教程】第 7 章:仪表盘,一眼看全局
人工智能·低代码·开源·无代码
桂花饼2 小时前
告别天价API!刚刚,Gemini 3.1 Flash-Lite 彻底杀死了大模型的“性价比之战”
人工智能·gpt·qwen3-next·sora2pro·gemini-3.1pro
Elastic 中国社区官方博客2 小时前
使用 TypeScript 创建 Elasticsearch MCP 服务器
大数据·服务器·数据库·人工智能·elasticsearch·搜索引擎·全文检索
Meya11272 小时前
告别机房 U 位管理内耗!这套系统让运维效率直接拉满 ✨
大数据·运维·人工智能
AC赳赳老秦3 小时前
OpenClaw SEO写手Agent实操:生成结构化文章,适配CSDN搜索规则
大数据·人工智能·python·搜索引擎·去中心化·deepseek·openclaw
禄亿萋3 小时前
基于多维协同注意力和特征融合的小目标检测方法
人工智能·目标检测·计算机视觉