找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1863

积分

0

好友

251

主题
发表于 9 小时前 | 查看: 3| 回复: 0

Skills工作机制示意图:SKILL.md文件结构、提示词与执行脚本

在2025至2026年的技术语境下,“Skills”已不再是简单的“可复用提示词模板”,而是逐渐演化为一种 可移植的、可工程化治理的“过程性能力包”。它以文件夹为最小分发单元,核心包含 SKILL.md(YAML frontmatter + Markdown 指令)、可选的 references/(按需加载的知识库或规程)、assets/(模板与静态资源)以及 scripts/(可执行脚本)。这种结构通过 渐进式信息披露(progressive disclosure) 来显著降低上下文成本,同时提升了系统的可维护性与可审计性。

以AgentSkills规范为例,它将此模式标准化:系统启动时仅加载元数据(如namedescription),在技能被触发后加载 SKILL.md 的正文,最终在执行阶段才按需读取资源或运行脚本,极大地优化了资源加载效率。

OpenClaw(一个开源、可自托管的常驻Agent平台)则将“Skills”作为其核心扩展机制,并进行了显式实现:支持多目录技能加载与覆盖优先级、基于 metadata 的加载时过滤(如OS、二进制依赖、环境变量、配置等)、将“可用技能清单”以紧凑XML形式注入系统提示,以及与Slash Commands(/...)联动(可选择绕过模型,直接将命令分发到工具以获得确定性执行)。同时,围绕Skills构建的开放生态(如ClawHub注册中心、第三方Skills)也带来了显著的供应链安全与提示注入风险,促使社区和安全厂商提出 “将Skills视为不可信代码” 的运行与隔离建议。

如果你想了解更多关于AI Agent背后的架构思想,可以访问我们社区的 人工智能 板块进行深入探讨。

本文将从Prompt到Scripts的演进谱系出发,逐层解析其定义、作用与误区;系统分解Skill的组成、运行流程与LLM交互模式;并通过对比表和端到端示例,展示从意图识别到技能触发的完整技术链路。

原文链接:https://blog.csdn.net/qq_35082030/article/details/158510164

1. 从 Prompt 到 Scripts:可操作上下文的分层谱系

1.1 Prompt

定义:Prompt是一次模型推理的 “输入上下文集合” ,它通常包含:系统级指令、用户输入、对话历史、工具/函数定义、工具返回结果,以及可能的外部检索片段或记忆摘要等。它不是单一字符串,而是多段结构化内容在运行时拼装后的整体。

作用:Prompt的核心作用是把“任务意图 + 约束条件 + 可用能力边界 + 证据”对齐到一次或多次模型调用中。当前提示工程的研究与实践普遍认为:结构更清晰、约束更明确的输入,通常能降低模型的“幻觉”与任务偏航概率,但过度复杂的提示也可能带来收益递减。

示例(伪码)

prompt = [
  system("你是一个工程助理。遵循安全与权限规则。"),
  system("可用工具: search_web, fetch_url, run_script"),
  user("总结最近的 OpenClaw skills 安全事件,并给出缓解建议。"),
  tool_result("search_web", {...}),  // 后续回填
]
response = LLM.generate(prompt)

最佳实践:将Prompt当作 “输入合约(input contract)” 来设计:明确角色、目标、禁止事项以及可用工具边界;将可变信息(如证据、运行参数)从不可变的规范(如策略、格式)中分离,以减少“提示耦合”。

常见误区:把Prompt简单等同于“几段话术”;将所有背景信息一次性塞进上下文导致窗口膨胀;在缺乏证据时要求模型“给出权威结论”,从而诱发编造。

1.2 普通提示词

定义:普通提示词指以自然语言为主的指令或问答式输入,其输出期望也通常是自然语言。它强调“人类可读”,但对模型而言约束相对宽松。

作用:用于快速表达意图与初步评估模型能力;非常适合探索性对话、创意生成或粗略方案的讨论。

示例

请用中文解释 OpenClaw 的 skills 机制,说明它与 MCP、工具调用的关系,并给出工程化最佳实践。

最佳实践:采用 “任务 + 受众 + 约束 + 输出格式” 的四件套写法来减少歧义;将不可妥协的约束(如安全规则、权限要求、引用规范)写成显式规则。

常见误区:试图用一个“长句”提示词处理复杂工作流;隐藏“过程”只要求“结果”,导致模型在中间步骤难以自我纠错。

1.3 结构化提示词

定义:结构化提示词是指把输入/输出组织为明确结构,例如使用分隔区块、YAML/JSON、表格约束,或直接使用函数/工具调用的JSON Schema合约。在现代LLM API中,它往往与 “工具调用(tool/function calling)”“结构化输出(structured outputs)” 绑定。

作用:将部分“语言理解问题”转化为“接口调用问题”:模型只负责选择工具并生成合规参数,运行时负责执行与校验,从而大幅提升任务执行的确定性与可测试性。

示例(OpenAI风格工具定义,JSON Schema示意)

{
  "tool": {
    "name": "search_web",
    "description": "在互联网上检索最新信息并返回结果列表",
    "parameters": {
      "type": "object",
      "properties": {
        "q": { "type": "string" },
        "recency_days": { "type": "integer" }
      },
      "required": ["q"]
    }
  }
}

这类 “用schema定义工具输入” 的机制是OpenAI与Anthropic文档中共同强调的能力形态:工具输入可被运行时校验,非法参数可直接失败并回传给模型,进入下一轮修正循环。

最佳实践:把“结构”用在真正需要确定性的地方(如工具参数、输出格式、可审计报告);对schema进行“向后兼容”设计(使用可选字段、版本号);将工具返回结果加工为“短而有效”的上下文,避免将大段原始日志直接塞回模型。

常见误区:认为“给了JSON schema模型就必然严格遵守”;在流式场景下错误地将工具调用JSON当作字符串拼接,造成半截JSON或非法JSON;误将“结构化提示”用作“更长的模板”,反而增加了token负担。

1.4 Command

定义:Command是 “绕过自然语言推理、直接驱动控制流” 的输入形式,典型表现是Slash Commands(/...)或CLI子命令。其语义更接近“操作系统命令”或“协议帧”,而非自然语言问答。OpenClaw文档明确将其交由Gateway处理:多数命令必须是以 / 开头的独立消息;并存在“directives”(如 /think/model/exec)这类会在进入模型前被剥离的控制指令。

作用

  1. 将“会话状态”(如模型选择、推理强度、是否允许exec、队列模式等)显式化、可控化。
  2. 在安全性与可预期性要求更高的场景下,将执行路径从“模型决定”改为“确定性分发”。OpenClaw甚至允许skill声明 command-dispatch: tool,使某些skill命令直接路由到工具而完全不经模型推理。

示例(OpenClaw)

/status
/skill pdf-processing ./input.pdf
/think high
/exec host=sandbox security=allowlist ask=on-miss

最佳实践:将命令系统当作 “控制平面API” 来设计:实施授权(allowlist)、审计、以及“默认拒绝(deny wins)”策略;让普通的自然语言交互只走“数据平面”(即模型推理与工具组合),避免将权限控制逻辑混入prompt。

常见误区:把commands当作“更强的prompt”,将敏感信息与权限开关暴露在群聊或不可信入口;将“命令执行成功”误判为“任务已安全完成”,忽视了命令链路可能带来的副作用(如环境被修改、凭据常驻、配置漂移)。

1.5 Metadata description

定义:Metadata description是 “给模型/运行时用于发现、筛选、触发与治理” 的紧凑描述层。在AgentSkills/Skill体系中,它通常位于 SKILL.md 的YAML frontmatter中(至少包含 namedescription),决定了“这个skill何时该被使用”。

OpenClaw在此基础上扩展了更强的运行时metadata:其技能解析器要求frontmatter的key多为单行,并建议 metadata 为单行JSON对象;metadata.openclaw 可声明依赖(需要哪些二进制文件、环境变量、配置)、平台限制(OS)、安装器规格,以及与 skills.entries.<name> 的注入和配置绑定。

作用

  • 发现与触发:启动时只加载 name/description,让模型以低成本“知道有哪些技能”,在匹配用户意图时再加载正文。
  • 过滤与治理:运行时根据metadata决定skill是否“eligible”(可用),例如缺少二进制依赖或环境变量则不加载,避免“模型看到不可执行能力”导致的失败循环。
  • 安全与权限边界:通过 disable-model-invocation 让skill不进入模型提示,仅允许用户显式调用;或通过 command-dispatch: tool 走确定性路径。

示例(一个合并“规范与OpenClaw门控”的SKILL.md头部)

---
name: web-research
description: 面向技术调研的证据检索与引用汇总。用户提到“最新/近况/对比/引用来源”时使用。
metadata: {"openclaw":{"os":["darwin","linux"],"requires":{"config":["web.enabled"]}}}
user-invocable: true
disable-model-invocation: false
---

最佳实践:将 description 写成 “可检索的触发器” (包含用户可能说的关键词及明确的使用边界);将平台/依赖要求写入metadata而非正文;为metadata添加版本号与作者信息,便于审计与回滚。元数据质量直接影响“技能检索是否被投毒或误选”,属于治理重点。

常见误区:description过于抽象(如“帮助你更高效”)导致检索泛化;metadata描述与实际行为不一致(例如声明“只读”却要求执行脚本);将复杂JSON放入OpenClaw不支持的多行frontmatter,导致解析失败。

1.6 Reference

定义:Reference是 “技能执行时按需加载的补充材料” ,典型形态是独立的Markdown文档、表单填写指南、API参考、政策/规范等。AgentSkills及Claude的最佳实践明确建议:SKILL.md 应类似目录(table of contents),详细材料应放到 reference.mdFORMS.mdexamples.md 等文件中,在需要时才加载。

作用

  1. 将上下文窗口视为“公共资源”:只在需要时消耗token,优化资源使用。
  2. 让参考资料成为可审计的资产(支持版本控制、diff、评审)。
  3. 保持技能正文短小精悍,降低触发时的认知与token成本。

示例(目录结构,来自Claude最佳实践示意)

pdf/
├── SKILL.md
├── FORMS.md
├── reference.md
├── examples.md
└── scripts/
    ├── analyze_form.py
    ├── fill_form.py
    └── validate.py

最佳实践:reference应以 “可定位、可检索” 为第一原则:采用短段落、强标题、明确的输入输出示例;在 SKILL.md 中使用相对路径链接引用文件;将组织级的SOP(标准作业程序)或安全策略放入references,而非写进prompt模板。

常见误区:把reference当作“知识仓库倾倒点”,导致加载成本巨大;将敏感信息(如密钥、内网地址)放入reference,形成安全泄漏面;引用链过深(reference里再引用reference),使agent在执行时迷失方向。

1.7 Scripts

定义:Scripts是技能包内的可执行代码(Python/Bash/JS等),其关键点在于:脚本应被“执行”而不是“加载进上下文”。Claude的技能目录示例明确标注scripts为“executed, not loaded”。AgentSkills规范也把scripts/resources放在渐进式披露的第3层:仅在需要时才使用。

作用:将确定性的、复杂的步骤外包给传统程序执行,例如解析、校验、格式化、批处理等;从而提升任务的可测试性、可复现性,并降低“让模型凭token模拟执行”所带来的错误率。

示例(SKILL.md中声明可用脚本)

## Available scripts
- scripts/extract_citations.py — 从网页抓取结果中抽取主张与证据片段
- scripts/normalize_md.py — 把输出归一化为团队博客模板

执行规则:优先运行脚本,不要尝试在对话中“脑补执行”。

最佳实践

  • 运行脚本前先进行输入校验与最小权限设置(如workspace-only、deny-by-default)。
  • 将脚本视作供应链依赖进行治理:需要签名、审计、锁版本与CI验证。
  • 把“验证步骤”写进skill(例如 validate.py),形成反馈闭环,避免错误一路传播到最后一步。

常见误区:把scripts当作“更强的prompt”,允许其在宿主机上任意执行;从不审计第三方skills中的scripts;将“安装依赖”写成一条不透明的 curl | bash 指令,制造了典型的社会工程学攻击入口。

2. Skill:最新概念、组成与运行机制

2.1 “Skill”在 2026 语境下的严格定义

从规范与主流实现来看,一个“Skill”更接近如下定义:

Skill = 可发现的元数据 + 可执行/可操作的过程性指令 + 可选资源(references/assets/scripts) + 渐进式加载策略 +(可选)权限/环境门控。

AgentSkills规范给出了最小合约:skill是包含 SKILL.md 的目录;启动时加载 name/description,激活时加载正文,运行时按需加载resources。Claude、GitHub Copilot、VS Code等实现都围绕这一文件系统布局展开,并强调“目录名与 name 匹配、description要写清何时使用”。OpenClaw明确声明其skills文件夹兼容AgentSkills,并在运行时增加了额外的门控(gating)与命令联动机制。

2.2 Skill 的组成成分拆解

下面给出一个面向工程实现的“Skill组件清单”(非唯一标准,但与主流规范兼容)。

  • 接口(Interface):Skill对外至少暴露“何时使用(trigger)”与“如何调用(instructions)”。实践中,接口由两层构成:
    • 发现接口name/description(以及可选的trigger hints、兼容性信息)。
    • 执行接口:正文指令,告知agent需要使用哪些工具、需要读取哪些reference、要运行哪些scripts。
  • Schema(合约/结构)
    • 对“工具调用”的schema:通常是JSON Schema(OpenAI/Anthropic工具接口)或MCP的tool schema。
    • 对“skill输入”的schema:行业常见两种做法:1) 轻量做法:让skill在指令中要求模型先提取字段并以固定格式呈现;2) 强约束做法:将skill暴露为一个tool(SkillTool),用JSON Schema约束skill的输入参数,再由运行时装载skill正文与资源。
  • 能力描述(Capability description)description 是核心,它直接决定了检索命中的质量。学术综述将其视为“Pattern-1:Metadata-Driven Disclosure”的关键风险面:元数据写错会导致误检索或被投毒。
  • 输入/输出(I/O)
    • 输入:用户原始意图 +(可选)从对话中结构化提取的槽位参数 +(可选)执行上下文(workspace路径、会话状态、工具权限)。
    • 输出:对用户的自然语言结果 +(可选)结构化产物(JSON、补丁、文件、外部系统状态变更)。OpenAI的Responses API设计把“tool call”与“tool output”作为可关联的item(通过call_id),便于回放与评估。
  • 状态/上下文(State/Context):技能执行往往依赖于会话状态(已检索到的证据、已生成的artifacts、已运行的命令与返回码)。在工程实现上,常见做法是将其放入Agent state(LangGraph/LangChain语境)或由SDK提供的内置agent loop状态管理中。
  • 错误处理(Error handling):技能的价值之一在于 “把错误处理流程也固化下来” :例如命令失败时要收集stderr、调整参数重试、或回退到保守策略。相关研究指出:把“恢复(recovery)”当作一等技能,会带来对可治理性与可信度的更高要求(恢复skill必须至少与被恢复的skill同等可信)。

2.3 Skill 的运作流程:触发、解析、执行、回调与结果整合

下面用一个“兼容AgentSkills/OpenClaw”的通用流水线描述技能生命周期(阶段名与OpenClaw/AgentSkills的术语对齐)。

flowchart TD   A[Discover: 扫描技能目录] --> B[Index: 仅加载name/description等元数据]   B --> C{Match: 与用户意图匹配?}   C -- 否 --> D[继续普通对话/工具调用]   C -- 是 --> E[Activate: 加载SKILL.md正文]   E --> F{Need refs/assets?}   F -- 是 --> G[Load refs/assets: 按需读取文件]   F -- 否 --> H[Execute: 进入Agent Loop]   G --> H   H --> I{Need scripts/tool calls?}   I -- 工具调用 --> J[Tool call -> 执行 -> tool result回填]   I -- 运行脚本 --> K[Run script -> stdout/stderr -> 回填]   J --> H   K --> H   H --> L[Integrate: 汇总结果与证据]   L --> M[Respond: 输出给用户 + 可选产物]

这一流程与AgentSkills的 “渐进式披露三层结构” 一致:先元数据,再正文,再资源;也与OpenClaw的“加载/过滤/注入/执行/回填”流程相吻合。

在OpenClaw中,上述阶段还会叠加若干运行时细节:

  • 多来源与覆盖优先级:bundled(内置) → ~/.openclaw/skills(用户目录) → <workspace>/skills(工作区目录),同名skill可被更高优先级的覆盖。
  • Load-time gating:读取 metadata.openclaw.requires(bins/env/config)来决定skill是否eligible(符合条件);并支持在一次agent run内注入环境变量,结束后还原。
  • Prompt 注入策略:把“可用技能清单”以紧凑XML列表形式注入系统提示,并有确定的字符成本公式,便于估算token开销。
  • Slash command 联动user-invocable 为true的skill会暴露为slash command;并可配置为“转发给模型”或通过“command-dispatch: tool”进行确定性执行。

2.4 Skill 与大模型的交互模式:同步/异步、流式/批量

  • 同步 vs 异步
    • 同步:模型发起工具调用,运行时立即执行并回填结果,再让模型生成最终响应;这是传统函数调用/agent loop的默认形态。
    • 异步:长耗时任务(如网络爬取、代码编译、批处理)常被放入后台队列或进程;OpenClaw的exec支持前台/后台模式以及配套的process工具来管理后台会话。工程建议是:把异步任务当作 “第一类控制流” 来处理,否则技能一旦遇到长任务就会出现超时、截断或上下文漂移。
  • 流式 vs 批量
    • 流式:模型边生成边产出工具调用片段、或边生成边汇总结果;流式对“结构化输出”的要求更苛刻,容易出现半截JSON,需要修复策略。
    • 批量:将多个tool call规划好后批量执行,再一次性把关键结果回填;在强调效率与可复现性的技能里更常见。
  • 与 MCP 的关系:MCP(在LLM生态中通常指Model Context Protocol)把“工具/资源/提示”等能力以标准化的JSON-RPC客户端/服务器架构暴露给Host应用;它解决的是 “怎么连接工具与数据源” 的N×M集成问题,而Skills更偏向 “教agent怎么用这些工具完成标准作业程序(SOP)”

2.5 示例实现:一个最小 Skill 引擎(伪码)与序列图

下面给出一个“最小技能引擎”的伪码,它体现了AgentSkills的5步最小要求(discover → load metadata → match → activate → execute)。

class SkillIndexItem:
  name: string
  description: string
  path: string
  metadata: map

class SkillEngine:
  def discover(skills_dirs) -> list[SkillIndexItem]:
    items = []
    for dir in skills_dirs:
      for skill_dir in list_subdirs(dir):
        if exists(skill_dir+"/SKILL.md"):
          fm = parse_yaml_frontmatter(skill_dir+"/SKILL.md")
          items.append(SkillIndexItem(
            name=fm.name,
            description=fm.description,
            metadata=fm.metadata,
            path=skill_dir
          ))
    return items

  def eligible(item, runtime_env) -> bool:
    # OpenClaw 风格:按 OS/bins/env/config 门控
    return satisfies(item.metadata, runtime_env)

  def match(user_msg, index_items) -> SkillIndexItem?:
    # 最简:embedding/关键词;工程上应加投毒防护与阈值
    return best_semantic_match(user_msg, index_items)

  def run(user_msg):
    index = [i for i in discover(dirs) if eligible(i, env)]
    skill = match(user_msg, index)
    if not skill:
      return llm_generate(normal_prompt(user_msg, index))

    full = read_file(skill.path+"/SKILL.md")          # Activate
    prompt = build_prompt(user_msg, index, full)     # 注入 skill 清单 + 正文
    while True:                                      # Agent loop
      out = llm_generate(prompt, stream=True)
      if out.is_tool_call:
        result = execute_tool(out.tool_name, out.args)
        prompt.append(tool_result(out.call_id, result))
      else:
        return out.final_text

对应的交互序列如下:

sequenceDiagram   participant U as User   participant G as Gateway/Agent Runtime   participant M as LLM   participant T as Tools/Sandbox   U->>G: message   G->>G: discover+load metadata (name/description)   G->>G: match & activate (load SKILL.md)   G->>M: prompt (skills index + skill body)   M-->>G: tool_call(args)   G->>T: execute tool / script   T-->>G: tool_result(stdout/stderr/data)   G->>M: tool_result (call_id关联)   M-->>G: final answer (integrated)   G-->>U: response

该序列与OpenAI的 “tool calls与outputs通过call_id关联” 的实践一致,也符合OpenClaw的“Gateway组装prompt、工具在sandbox/host执行、结果回填”的架构形态。

3. 机制对比:Prompt / Memory / MCP / Skills

  • Prompt 更像“当前对话的瞬时指令”,优势是低门槛与即时性,劣势是不可持久与难治理。
  • Skills“可版本化的SOP包” ,在一致性、可复用性、可审计性上更强,但引入了供应链与权限治理成本。
  • MCP 的核心价值在于 “标准化连接外部工具/数据(协议层)” ,而Skills的核心价值在于 “标准化可复用过程(方法层)” ;二者互补:MCP提供“手”(能力),Skill提供“操作手册”(方法)。
机制 定义 持久性 可编程性 可组合性 调用延迟 示例场景
提示词(Prompt) 一次推理的输入上下文集合(系统/用户/历史/工具结果等) 低(默认随会话消失) 低到中(主要靠提示工程) 中(可拼接模板,但易冲突) 低(单轮调用) 快速问答、头脑风暴、一次性总结
记忆(Memory) 跨轮保存的对话/状态/检索片段(短期或长期),供后续调用检索 中到高(取决于存储与策略) 中(需要检索、压缩、冲突处理) 中(可被多个技能/工具复用) 中(检索+融合) 个性化助理、长任务跟踪、跨会话项目协作
MCP Model Context Protocol:以 JSON-RPC 标准化“LLM 应用 ↔ 外部工具/数据源”连接 中(server/connector 常驻) 高(工具/资源以协议暴露) 高(多 server 组合) 中(网络/鉴权/执行) IDE 接入代码库、企业系统连接(CRM/DB/工单)
Skills 以目录为单位的可移植能力包:SKILL.md +(可选)references/assets/scripts;渐进式披露加载 高(版本化、可共享) 高(可运行脚本/约束流程) 高(可同时加载多个 skill) 中到高(匹配+激活+执行) 代码评审 SOP、自动化报表、受控的数据处理流水线

备注:这里的“MCP”在LLM场景下通常指Anthropic提出的Model Context Protocol。

4. 框架演进:从 LLM 到 OpenClaw

  • LLM → Tool Calling → Agent 的演进,本质是在把“控制流”从人类手工操作(写提示、点按钮)转移到运行时(agent loop),再用更强的结构(skills/workflow)把不确定性收束到可治理范围。
  • OpenClaw“产品化差异” 在于:它把agent变成了常驻的基础设施(多入口聊天应用 + 本地执行 + 可安装技能市场),因此其主要挑战从“能不能做事”转向 “能不能在开放生态里安全地做事”
阶段 架构层级 控制流 状态管理 扩展性 典型实现/开源项目 适用场景 优缺点
LLM 单次生成 人工组织 prompt 低(主要靠对话历史) 通用对话 API / 提示工程总览 问答、生成、分析 👍简单;👎不可控、难复现
工具调用 LLM + tools 模型选择工具、运行时执行 中(工具结果回填) OpenAI function calling;Claude tool use 结构化参数调用、RAG、自动化步骤 👍更确定;👎工具描述/返回需精心设计
Agent LLM + tool loop 运行时循环直到 stop condition 中到高(state/checkpoints) 中到高 LangChain Agents;OpenAI Agents SDK(内置 agent loop) 多步任务、交互式执行 👍会规划迭代;👎易循环/漂移,需护栏与评估
多 Agent 协同 多 agent + 路由/对话协议 分工、handoff、协作对话 高(跨 agent 协作状态) Microsoft AutoGen(多 agent 对话框架) 复杂项目拆解、角色协作 👍并行与分工;👎状态与一致性更难、成本更高
增强记忆的 Agent agent + 长短记忆 控制流同 agent,但记忆参与决策 高(长期存储+检索) 中到高 LangGraph/LangChain memory;Generative Agents 架构 个性化助理、长周期任务 👍连续性强;👎隐私与污染风险、需压缩与治理
Workflow / Manus workflow 引擎 + agent(或 agent 平台) 更显式的图/流程/约束,或“CodeAct”式执行 高(强状态机/虚拟环境) LangGraph 图式编排;Manus(行动引擎/工作流执行) 可重复业务流程、端到端交付 👍可控、可观测;👎搭建成本高、需要更多工程能力
OpenClaw 常驻 agent 平台 + skills 市场 + 本地执行 Gateway 命令/指令 + agent loop + 可选确定性分发 高(session、workspace、插件槽等) 很高(skills、plugins、registry) OpenClaw(自托管、聊天入口、多工具与技能) 个人/小团队自动化、跨应用操作 👍“能做事”的可用性强;👎安全面巨大、供应链与权限治理是硬问题

4.1 重点:OpenClaw 的机制解剖、信息来源与不确定性

信息来源(相对确定)

  • OpenClaw官方仓库与文档明确其定位:运行在用户自有设备上、通过已有聊天渠道交互;并强调Gateway是控制平面(control plane)。
  • Skills文档明确:兼容AgentSkills;多目录加载与覆盖优先级;load-time gating(bins/env/config);会话快照/热更新;以及把技能清单注入系统prompt的方式。
  • Slash Commands文档明确:命令由Gateway处理;directives会在模型看到消息前被剥离;skill可作为命令暴露,并可配置为直接dispatch到工具。
  • ClawHub文档明确:作为公开registry,提供版本化存储与发现;支持install/update/publish/sync;并描述了默认开放上传与“GitHub账号至少1周”之类的审核策略。
  • Plugins文档明确:插件加载的目录/ID规则、配置schema校验、以及若干安全护栏(例如路径不能逃逸、安装依赖时 --ignore-scripts)。

公开资料稀少或仍在变化的部分(需要保留不确定性)

  • “技能匹配/检索”的具体算法(embedding、关键词、阈值、是否有对抗投毒防护)通常不会在产品文档里详述;相关研究提到metadata-driven disclosure的风险,但具体实现策略依赖各平台。
  • 多agent/远程节点/沙箱与权限的组合细节在快速迭代,且安全修复频繁;因此任何“架构推断”都应以源码与版本为准,并配套验收测试。

在不完整信息下的合理架构推断(可验证)
基于官方文档,“OpenClaw的核心循环”可以被验证性地理解为:

  1. Gateway接收消息并先做command/directive解析。
  2. 构建会话级上下文(含技能清单XML、工具策略、可选激活的skill正文)。
  3. 调用外部模型。
  4. 若模型发起工具调用,则在sandbox/host执行并回填结果。
  5. 进入下一轮直到产出最终响应。
  6. 会话状态与技能快照在session维度管理。

你可以用两类 “可验证建议” 来验证/替代上述推断:

  • 验收测试(黑盒):构造一个只含2个skill的环境(一个可用、一个因缺少bin/env被gating),观察系统提示内skills list是否包含/不包含它,并用 /context detail(OpenClaw提供的上下文可视化命令)确认token分布与注入内容。
  • 替代实现(白盒):若不使用OpenClaw,也可用 “OpenAI Agents SDK + MCP + AgentSkills文件夹” 搭建同构系统:SDK提供agent loop与handoffs,MCP提供工具/数据接入,AgentSkills提供可移植SOP包。这种组合式架构设计是 后端 & 架构 领域值得深入探讨的实践。

安全重点:OpenClaw及其skills生态的公开事件显示:开放registry与“markdown指令 + 可执行脚本”的组合会形成显著的供应链攻击面;多家安全报告与新闻指出了恶意skills、信息窃取等风险,并提出了隔离建议;Microsoft的安全博客也明确建议将OpenClaw视为 “带持久凭据的不可信代码执行环境” ,仅在隔离环境中运行。

5. 端到端示例:两个完整场景

下面两个示例分别覆盖:

  • 示例一:信息检索 + 工具调用(强调结构化工具与证据汇总)。
  • 示例二:多步骤任务自动化(强调command显式触发 + scripts确定性执行 + 结果整合)。

5.1 示例一:技术调研与证据汇总(自动触发 Skill)

目标:用户问“最近 OpenClaw Skills 的安全事件有哪些?我该如何安全使用?”系统自动触发 web-research skill:先检索、再抓取、再抽取证据、最后按模板输出“主张-证据-建议”。这一类workflow对“可信引用”敏感,适合用skill固化流程并用工具做检索与抓取。

Skill目录结构(示例)

web-research/
├── SKILL.md
├── references/
│   ├── source_policy.md
│   └── output_template.md
└── scripts/
    ├── extract_claims.py
    └── dedupe_sources.py

SKILL.md(核心片段)

---
name: web-research
description: 当用户要求“最新/近况/引用来源/对比”时,执行证据驱动的技术调研并输出可追溯引用。
---

# Web Research

## Rules
1) 先检索再下结论;2) 每个关键主张必须对应来源;3) 遇到相互矛盾的来源要并列呈现并说明不确定性。

## References
- references/source_policy.md
- references/output_template.md

## Procedure
1) 用 search_web 获取候选来源(优先官方/论文/权威媒体)
2) 用 fetch_url 抓取全文
3) 运行 scripts/dedupe_sources.py 去重
4) 运行 scripts/extract_claims.py 抽取“主张-证据片段”
5) 按模板生成最终报告,并附来源列表

该写法符合 “SKILL.md作为总览,细则与模板在references,确定性处理在scripts” 的最佳实践。

工具定义(结构化提示的一部分,示意)

[
  {
    "name": "search_web",
    "description": "检索最新网页并返回[{title,url,snippet,date}]",
    "parameters": { "type": "object", "properties": { "q": {"type":"string"} }, "required": ["q"] }
  },
  {
    "name": "fetch_url",
    "description": "抓取url正文并返回{text,meta}",
    "parameters": { "type": "object", "properties": { "url": {"type":"string"} }, "required": ["url"] }
  },
  {
    "name": "run_script",
    "description": "在沙箱内运行技能脚本,返回stdout/stderr/exit_code",
    "parameters": { "type": "object", "properties": { "path":{"type":"string"}, "args":{"type":"array"} }, "required":["path"] }
  }
]

这对应主流 “用JSON Schema描述工具输入” 的实践。

端到端时序图

sequenceDiagram   participant U as User   participant A as Agent Runtime   participant M as LLM   participant W as Web Tools   participant S as Sandbox (scripts)   U->>A: "总结最近OpenClaw skills安全事件并给建议(含引用)"   A->>A: match skills index ->> activate web-research   A->>M: prompt + web-research(SKILL.md)   M-->>A: tool_call search_web(q)   A->>W: search_web   W-->>A: results[]   A->>M: tool_result(call_id=1)   M-->>A: tool_call fetch_url(url...) xN   A->>W: fetch_url xN   W-->>A: pages{text} xN   A->>S: run_script(dedupe_sources.py)   S-->>A: deduped list   A->>S: run_script(extract_claims.py)   S-->>A: claims+citations   A->>M: tool_results merged   M-->>A: final report (claims + sources + mitigation)   A-->>U: response

关键实现片段(处理OpenAI Responses工具回填的思路,伪码)

resp = responses.create(input=prompt, tools=tools, stream=true)
for item in resp.items:
  if item.type == "tool_call":
    result = exec_tool(item.name, item.arguments)
    responses.submit_tool_output(call_id=item.call_id, output=result)

这里的关键是 “tool call与tool output分离,并用call_id关联” ,便于可观测性与评估。

5.2 示例二:多步骤任务自动化(显式 Command + 确定性 Scripts)

目标:用户在OpenClaw里用命令触发一个“发布说明自动生成”流程:从仓库拉取最近变更 → 根据模板生成release notes → 写入workspace文件并回传摘要。该例故意用 /skill <name> 显式触发,以展示“command作为控制平面”的作用。

Skill目录结构(示例)

release-notes/
├── SKILL.md
├── references/
│   └── notes_template.md
└── scripts/
    ├── git_log.sh
    └── render_notes.py

SKILL.md(含command相关frontmatter的OpenClaw风格示例)

---
name: release-notes
description: 为代码仓库生成发布说明;当用户说“发版说明/变更日志/release notes”或执行 /release-notes 时使用。
user-invocable: true
command-dispatch: tool
command-tool: exec
command-arg-mode: raw
---

command-dispatch: tool 表示:当用户用 /release-notes ... 触发时,不走模型推理路径,而是直接把命令分发到指定工具,以获得确定性(例如直接执行脚本入口)。此能力在OpenClaw的skills与slash commands文档中明示。

命令触发

/release-notes repo=. since="7 days"

端到端时序图

sequenceDiagram   participant U as User   participant G as OpenClaw Gateway   participant X as Exec Tool (sandbox/host)   participant P as Process Tool   participant F as Filesystem Tools   U->>G: /release-notes repo=. since="7 days"   G->>G: command parsing + authz   G->>X: exec("scripts/git_log.sh --since '7 days'")   X-->>G: stdout (commit list) + exit_code   alt long running     G->>P: track background session     P-->>G: status/result   end   G->>X: exec("python scripts/render_notes.py --template references/notes_template.md")   X-->>G: release_notes.md content   G->>F: write("release_notes.md", content)   F-->>G: ok   G-->>U: 摘要 + 文件路径 + 可选 diff

这里用到了OpenClaw文档中描述的exec(前台/后台)与process(管理后台会话)思路,以及slash command解析由Gateway执行的特性。

脚本片段示例(简化版)

# scripts/git_log.sh
git log --since="$1" --pretty=format:"- %s (%h) by %an"
# scripts/render_notes.py (伪代码风格)
import sys
commits = sys.stdin.read().splitlines()
template = open("references/notes_template.md").read()
notes = template.replace("{{COMMITS}}", "\n".join(commits))
print(notes)

工程要点:这个例子刻意让 “关键步骤都在scripts里” ,把模型扮演的角色降到最低:模型不需要“幻想执行git”,而是读取脚本输出并做轻量整合。编写此类可执行脚本是工程实践中的重要一环,你可以在 技术文档 板块找到更多关于脚本编写和最佳实践的参考资料。

6. 结论与后续研究清单

6.1 结论

“Skills”的最新含义可以概括为:用标准化目录结构把“方法(SOP)”产品化,并用渐进式披露把上下文成本最小化;它与工具调用、MCP、记忆共同构成 “Agent工程栈” 的不同层次:MCP解决连接问题,工具调用解决接口与参数问题,Skills解决方法与一致性问题,记忆解决跨时间延续性问题。

OpenClaw则是这一工程栈的一种 “平台化落地” :它把skills、commands、plugins、registry、沙箱/工具策略与多入口聊天整合为常驻系统;其优势是 “非常接近真实生产力” ,其风险也同步放大为“真实的权限与供应链安全问题”。因此,对技术团队而言,OpenClaw更像一个值得研究的 “参照架构” ,而不是不加隔离就能直接引入企业内网的通用解决方案。

6.2 进一步研究与实现建议清单

  1. 为Skills引入CI/CD与评估飞轮:把每个skill当作软件包,建立版本号、变更日志、lint/validate(如 skills-ref validate)与回归评估;可参考相关评估框架,形成持续改进闭环。
  2. 把“元数据安全”当作一等问题:对 description 做质量门控(避免过宽、避免误导、避免注入式关键词堆砌),并对skill检索加入防投毒策略(阈值、白名单、交叉验证、多路检索)。
  3. 最小权限与分层隔离:工具策略坚持deny-wins原则;高风险工具(exec、browser、web_fetch/search)默认关闭或仅allowlist;运行时尽量使用sandbox;把凭据注入限制为“会话内、最小集合、可轮换”。
  4. 把Scripts当作供应链依赖治理:强制审计第三方scripts;拒绝不透明安装指令;对 curl | bash 等模式在执行层直接拦截或需要人工批准;对外部依赖锁版本并记录SBOM(软件物料清单)。
  5. 优先“确定性外包”:对解析、验证、格式化、diff、patch这类任务,优先编写脚本而不是让模型凭token模拟;并在skill中固化验证步骤与失败恢复路径。
  6. MCP + Skills的组合设计:用MCP暴露标准化工具/资源,把Skills作为“如何用这些工具”的SOP;在企业内可先部署私有MCP server与私有skills registry,避免直接接入开放市场。
  7. 对OpenClaw做“可验证的渐进式采用”:先在隔离环境验证commands/tool policy/sandbox;只引入少量自研skills;对ClawHub/第三方skills采取默认禁止策略;通过 /context detail 或类似可观测命令持续测量上下文与权限变化。
  8. 替代方案路线图:如果目标是企业级可控自动化,可考虑 “Agents SDK(agent loop)+ LangGraph(可控流程)+ MCP(工具接入)+ AgentSkills(SOP包)” 的组合式自建方案;用更小的攻击面获得OpenClaw式能力。

7. 写在最后

我正式的计算机教育始于本科,那时大部分时间在学习数据结构和编程语言,本质上是学习如何描述数字世界。起初非常抽象,从面向过程编程学起,直到接触面向对象编程才逐渐适应了这个世界的运作模式。

常听人说,程序=数据结构+算法。后来,我学习了算法和模型,算是掌握了数字世界的运作规律。算法为数据结构施加变换规则,类似物理定律约束物质状态的演化。这样,我们就能利用算法去改造和预测数字世界。

幸运的是,后来接触到了大模型。它其实也是模型,是算法的一个分支。但它的出现,带有 “工业革命” 的意味,因为大模型可以进行推理。数字世界的推理过程,和物理世界运用能量做功相似,是一个动态的过程。大模型的好处在于,我们能够越来越少地关心“能量消耗”的具体形式。类比现实世界,就像蒸汽机将化石燃料的能量转换为通用做功形式,避免了人类直接做功,或为特定活动精心设计能量转换装置。

因此,大模型的性能改进,实际上代表着我们在数字世界 “能量运用” 水平的高低。然而,人类的梦想不止于此,我们希望它不仅能够自行“做功”,而且越来越有自我意识地“做功”。这不正是物理世界中,人类出现所带来的变化吗?

换个角度看,这又何尝不是在数字世界中,构建我们所谓的 “人工智能” 呢?

兜兜转转,我们又回到了探索智能本质的起点。





上一篇:BCC32迁移Clang指南:关键差异解析与常见陷阱避坑
下一篇:小红书直播带货场景下的高并发流量控制架构设计实战复盘
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-3 22:39 , Processed in 0.380866 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表