【企业级龙虾】OpenClaw Skills 动态加载架构深度解析:几百个 Skills 如何可控挂载到上下文

【企业级龙虾】OpenClaw Skills 动态加载架构深度解析:几百个 Skills 如何可控挂载到上下文关键词 OpenClaw Skills 动态加载 System Prompt 上下文预算 架构设计 适读人群 想看懂 OpenClaw skill 机制 准备做大规模 skills 管理 想做性能与成本优化的开发者 本文基于 OpenClaw 官方 Github 源码 进行分析 所有分析均有源码引用 确保 100 准确 OpenClaw 对 skills

大家好,我是讯享网,很高兴认识大家。这里提供最前沿的Ai技术和互联网信息。




本文基于 OpenClaw 官方 Github 源码 进行分析,所有分析均有源码引用,确保100%准确。

OpenClaw 对 skills 的处理不是“全量塞给模型”,而是一个分层漏斗:

  1. 多来源发现(workspace / managed / bundled / extra / plugin 等)
  2. 来源内限流(默认每次加载上限 200)
  3. 资格过滤(enabled、allowlist、OS/bin/env/config 条件)
  4. 优先级合并覆盖(同名 skill 后者覆盖前者)
  5. 模型挂载预算(默认最多 150 个 + 30k chars)
  6. 动态刷新(文件监听 + snapshot version)

一句话:先把“能用的”筛出来,再把“该给模型看的”压到预算内。


如果 workspace/skills 下有几百个目录,直接全塞进上下文会出 3 个问题:

  • Token 爆炸(成本高、上下文拥堵)
  • 模型决策噪音变大(“技能过载”)
  • 文件扫描成本高(启动/首轮响应慢)

  • 核心加载:src/agents/skills/workspace.ts
  • 可用性判定:src/agents/skills/config.ts
  • 监听与版本:src/agents/skills/refresh.ts
  • 会话更新挂钩:src/auto-reply/reply/session-updates.ts
  • 运行时挂载:src/agents/pi-embedded-runner/run/attempt.ts
  • 系统提示拼装:src/agents/system-prompt.ts
  • 插件技能来源:src/agents/skills/plugin-skills.ts

OpenClaw 的 skill 来源包括:

  • 内置:bundled skills
  • 托管:CONFIG_DIR/skills
  • 工作区: /skills
  • 个人 agents:~/.agents/skills
  • 项目 agents: /.agents/skills
  • 扩展目录:skills.load.extraDirs
  • 插件声明目录:plugin manifest 中声明的 skills 路径

合并顺序(低 -> 高):

extra < bundled < managed < agents-personal < agents-project < workspace

即:workspace 同名 skill 最终优先级最高
这让“项目本地覆写公共 skill”成为可能,非常实用。




1)来源扫描限流(第一层)

workspace.ts 中默认限制:

  • maxCandidatesPerRoot = 300
  • maxSkillsLoadedPerSource = 200
  • maxSkillFileBytes = 256KB

这意味着它不会无限递归地扫目录,也不会吃下超大 SKILL.md


2)可用性过滤(第二层)

即使被发现,也未必进入候选:

  • skills.entries. .enabled === false -> 直接排除
  • bundled allowlist 不通过 -> 排除
  • metadata 条件不满足(OS/bin/env/config)-> 排除
  • 可结合远程节点能力(如 remote macOS)判定

3)模型挂载预算(第三层)

进入 system prompt 前再次压缩:

  • maxSkillsInPrompt = 150(数量上限)
  • maxSkillsPromptChars = 30_000(字符预算)

  • 能不能用(依赖/配置/平台)
  • 是否允许(enabled/allowlist/filter)
  • 能不能塞进预算(数量 + 字符)

所以“合适”指的是运行时可用且预算友好,不是“语义最像”。


时序图(首轮,通常无 snapshot)

User Message -> initSessionState -> ensureSkillSnapshot

 -> ensureSkillsWatcher -> buildWorkspaceSkillSnapshot -> loadSkillEntries(多来源) -> shouldIncludeSkill(资格过滤) -> applySkillsPromptLimits(150 + 30k预算) -> session.skillsSnapshot = { prompt, skills, version } 

-> runEmbeddedAttempt

 -> resolveSkillsPromptForRun(snapshot优先) -> buildEmbeddedSystemPrompt(skillsPrompt挂载) -> LLM 执行

时序图(后续轮次,动态刷新)

SKILL.md add/change/unlink 

-> watcher(chokidar) -> bumpSkillsSnapshotVersion(workspace)

Next Message -> ensureSkillSnapshot

 -> version变了 => 重建snapshot -> version没变 => 复用snapshot 

-> runEmbeddedAttempt(直接复用snapshot.prompt)


很多人以为“没用到就即时丢弃”。实际上不是单点,而是多阶段:

  • 扫描阶段:目录过大、文件过大、无 SKILL.md 被丢弃
  • 资格阶段:不满足 metadata / config 条件被丢弃
  • 挂载阶段:超过 maxSkillsInPromptmaxSkillsPromptChars 被丢弃
  • 调用阶段disable-model-invocation 的 skill 不进入模型技能块

所以它更像分层减压系统,不是“模型先看全量再自己忽略”。


如果你已经进入“技能很多”的阶段,建议按这个顺序调:

  1. 先按业务域拆目录,减少单 root 混杂度
  2. skills.limits.maxSkillsLoadedPerSource(慎增)
  3. skills.limits.maxSkillsInPrompt(通常 80~150 区间更稳)
  4. 维持 maxSkillsPromptChars 的预算意识,避免 system prompt 过重
  5. skillFilter(agent/channel 级)做软隔离:让不同入口只看相关技能
  6. 对“不能被模型直接触发”的技能加 disable-model-invocation
  7. skills 不是越多越好,越多越会加重模型认知负担,skills 是需要精简的

  • 误区1:skills 目录里有,就一定进上下文
    -> 错,至少要过资格过滤 + prompt 预算。



  • 误区2:同名 skill 会并存
    -> 错,会按优先级覆盖,最终 Map 只留一个。



  • 误区3:改了 SKILL.md 必须重启
    -> 错,有 watcher + version,下一轮可刷新。



  • 误区4:包含语义检索层(比如 Top-K 策略)
    -> 错,没有语义检索和全文检索层,这点比较反常识。



小讯
上一篇 2026-04-19 10:45
下一篇 2026-04-19 10:43

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/266266.html