OpenClaw 智能代理核心机制详解:Skills 框架 + Agent 编排实战(2026)

10 阅读1分钟

上周在折腾一个自动化内容审核的小项目,需要让 AI Agent 根据不同任务类型自动切换"技能"——识别图片违规、分析文本情感、生成审核报告。一开始用 LangGraph 硬编排,写了一堆 if-else,维护起来想死。后来看到掘金热榜好几篇 OpenClaw 的实战文,才发现这玩意的 Skills 框架正好解决我的问题。花了两天时间把核心机制摸透了,踩了不少坑,写下来给同样在折腾 Agent 编排的兄弟们省点时间。

OpenClaw 是一个开源的 AI Agent 构建平台,核心机制是 Skills(技能框架),允许开发者将复杂的 Agent 行为拆解为可复用、可组合的技能单元,通过声明式配置实现智能代理的任务编排和动态路由。简单说,就是把 Agent 的能力模块化,像搭积木一样组装,而不是写一坨面条代码。

先说结论

折腾完之后的核心收获:

维度传统 LangGraph 硬编排OpenClaw Skills 框架
新增一个技能改路由逻辑 + 写 Node + 调试写一个 Skill 配置文件,注册即用
技能复用基本靠复制粘贴原生支持跨 Agent 复用
动态路由手写条件判断内置意图识别 + 技能匹配
调试体验打断点看 Graph 状态自带 Skill Trace 面板
学习曲线中等(要理解 Graph 概念)低(声明式配置为主)
适合场景复杂多步骤工作流多技能动态调度

如果你的 Agent 需要根据用户输入动态选择不同能力(而不是固定流程),OpenClaw 的 Skills 框架比手写编排省太多事。

环境准备

OpenClaw 目前(2026 年 6 月)最新版是 v2.3,Python SDK 要求 3.10+。

# 安装 OpenClaw SDK
pip install openclaw>=2.3.0

# 可选:安装调试面板
pip install openclaw[debug]

还需要一个大模型 API 作为 Agent 的"大脑"。OpenClaw 支持 OpenAI 兼容协议,所以不管你用 GPT-5、Claude Opus 4.6 还是 DeepSeek V3,走标准接口就行。

我这里用的是 ofox.ai 的聚合接口,一个 Key 能调所有主流模型,省得每家单独配。ofox.ai 是一个 AI 模型聚合平台,兼容 OpenAI/Anthropic/Gemini 三大 API 协议,支持 50+ 模型切换,低延迟直连约 300ms,支持支付宝按量付费。

# 基础配置
import os
os.environ["OPENCLAW_LLM_BASE_URL"] = "https://api.ofox.ai/v1"
os.environ["OPENCLAW_LLM_API_KEY"] = "your-ofox-key"
os.environ["OPENCLAW_LLM_MODEL"] = "claude-sonnet-4.6" # 或 gpt-5, deepseek-v3

OpenClaw 核心架构:理解 Skills 是怎么跑的

在写代码之前,先搞清楚 OpenClaw 的核心架构,不然后面踩坑会很懵。

graph TD
 A[用户输入] --> B[Intent Router 意图路由器]
 B --> C{Skill Matcher 技能匹配}
 C -->|匹配到 Skill A| D[Skill A: 文本分析]
 C -->|匹配到 Skill B| E[Skill B: 图片识别]
 C -->|匹配到 Skill C| F[Skill C: 报告生成]
 C -->|无匹配| G[Fallback Skill 兜底技能]
 D --> H[Skill Context 技能上下文]
 E --> H
 F --> H
 G --> H
 H --> I[Response Composer 响应组装]
 I --> J[输出结果]
 
 style B fill:#f9f,stroke:#333
 style C fill:#bbf,stroke:#333
 style H fill:#bfb,stroke:#333

几个核心概念:

  • Skill(技能):最小能力单元,包含 prompt 模板、输入输出 schema、调用的工具/API
  • Intent Router(意图路由器):用 LLM 判断用户输入应该交给哪个 Skill 处理
  • Skill Context(技能上下文):跨 Skill 共享的状态,比如上一个 Skill 的输出可以作为下一个的输入
  • Skill Chain(技能链):多个 Skill 串联执行,前一个的输出自动注入后一个

方案一:单 Skill 定义与注册(入门)

先从最简单的开始——定义一个文本情感分析的 Skill。

from openclaw import Agent, Skill, SkillConfig

# 定义一个 Skill
sentiment_skill = Skill(
 config=SkillConfig(
 name="sentiment_analysis",
 description="分析用户输入文本的情感倾向,返回正面/负面/中性及置信度",
 # 触发条件:Intent Router 用这个描述来匹配
 trigger_phrases=[
 "分析情感", "这段话是什么情绪", "判断正面负面",
 "sentiment", "情感分析"
 ],
 # Skill 的 prompt 模板
 system_prompt="""你是一个情感分析专家。分析用户给出的文本,返回 JSON 格式:
{
 "sentiment": "positive" | "negative" | "neutral",
 "confidence": 0.0-1.0,
 "reasoning": "简短解释"
}
只返回 JSON,不要其他内容。""",
 # 输出 schema(用于校验和下游 Skill 对接)
 output_schema={
 "type": "object",
 "properties": {
 "sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
 "confidence": {"type": "number"},
 "reasoning": {"type": "string"}
 },
 "required": ["sentiment", "confidence"]
 }
 )
)

# 创建 Agent 并注册 Skill
agent = Agent(
 name="content_reviewer",
 skills=[sentiment_skill],
 # LLM 配置会自动读环境变量,也可以显式传
)

# 测试
result = agent.run("帮我分析一下这段话的情感:'这个产品真的太垃圾了,退款都退不了'")
print(result)
# 输出:{"sentiment": "negative", "confidence": 0.95, "reasoning": "用户表达了强烈不满..."}

一个 Skill 本质上就是一个带有触发条件和结构化输出的 prompt 封装。

方案二:多 Skill 编排 + 动态路由(进阶)

实际项目里肯定不止一个 Skill。我那个内容审核项目需要三个能力:情感分析、违规检测、审核报告生成。关键是要让 Agent 自动判断该用哪个。

from openclaw import Agent, Skill, SkillConfig, SkillChain

# Skill 1:情感分析(上面已经定义过)

# Skill 2:违规内容检测
violation_skill = Skill(
 config=SkillConfig(
 name="violation_detection",
 description="检测文本是否包含违规内容(暴力、色情、政治敏感等)",
 trigger_phrases=["检测违规", "内容审核", "是否违规", "敏感内容"],
 system_prompt="""你是一个内容安全审核专家。检测以下文本是否包含违规内容。
返回 JSON 格式:
{
 "is_violation": true/false,
 "violation_types": ["暴力", "色情", ...], // 空数组表示无违规
 "risk_level": "high" | "medium" | "low" | "none",
 "details": "具体说明"
}""",
 output_schema={
 "type": "object",
 "properties": {
 "is_violation": {"type": "boolean"},
 "violation_types": {"type": "array", "items": {"type": "string"}},
 "risk_level": {"type": "string"},
 "details": {"type": "string"}
 },
 "required": ["is_violation", "risk_level"]
 }
 )
)

# Skill 3:审核报告生成(依赖前两个 Skill 的输出)
report_skill = Skill(
 config=SkillConfig(
 name="review_report",
 description="根据情感分析和违规检测结果,生成完整的内容审核报告",
 trigger_phrases=["生成报告", "审核报告", "汇总结果"],
 system_prompt="""你是一个审核报告撰写专家。根据上下文中的分析结果生成结构化报告。
上下文会包含 sentiment_analysis 和 violation_detection 的结果。
输出 Markdown 格式的审核报告。""",
 # 声明依赖:这个 Skill 需要前两个的输出
 depends_on=["sentiment_analysis", "violation_detection"],
 )
)

# 方式 A:动态路由(Agent 自动判断用哪个 Skill)
agent = Agent(
 name="content_reviewer",
 skills=[sentiment_skill, violation_skill, report_skill],
 routing_mode="auto", # 自动路由,LLM 判断意图
)

# 用户说"帮我看看这段话有没有问题",Agent 会自动匹配到 violation_skill
result = agent.run("帮我看看这段话有没有问题:'明天我们去那个地方搞事情'")

# 方式 B:技能链(按顺序执行多个 Skill)
chain = SkillChain(
 skills=["sentiment_analysis", "violation_detection", "review_report"],
 # 前一个 Skill 的输出自动注入下一个的上下文
 pass_context=True,
)

# 一次性跑完三个 Skill,拿到完整报告
full_report = agent.run_chain(
 chain=chain,
 input_text="用户评论:这个APP太烂了,骗钱的,我要举报你们"
)
print(full_report)

routing_mode="auto" 是 OpenClaw 最核心的能力——用 LLM 做意图识别,根据 Skill 的 descriptiontrigger_phrases 匹配最合适的技能。说白了就是用 AI 来路由 AI。

踩坑记录

踩了两天坑,记录几个最坑的:

坑 1:Skill 的 description 写太模糊,路由经常匹配错

一开始我的 violation_skill 描述写的是"检测内容是否有问题",结果用户说"这段代码有什么问题"也被路由到违规检测了。

description 要写得具体且有区分度,加上明确的领域限定词,比如"检测文本是否包含违规内容(暴力、色情、政治敏感等)"。trigger_phrases 也要覆盖常见的用户表述。

坑 2:SkillChain 中间某个 Skill 输出格式不对,后续全崩

report_skill 依赖前两个的 JSON 输出,但 sentiment_skill 偶尔会输出带 markdown 代码块的 JSON(就是 ```json ... ``` 这种),导致解析失败。

在 SkillConfig 里加 output_format="strict_json",OpenClaw 会自动做一层输出清洗:

config=SkillConfig(
 # ...
 output_format="strict_json", # 强制清洗输出为纯 JSON
 retry_on_format_error=True, # 格式错误自动重试一次
)

坑 3:depends_on 声明了依赖但上下文没传进去

这个坑最隐蔽。report_skill 声明了 depends_on=["sentiment_analysis", "violation_detection"],但跑 SkillChain 的时候报告里完全没引用前面的分析结果。

原因是没开 pass_context=Truedepends_on 只是声明"我需要这些 Skill 先跑完",不会自动传上下文,必须在 SkillChain 里显式开启 pass_context。

坑 4:模型选择影响路由准确率

用 DeepSeek V3 做 Intent Router 的时候,路由准确率大概 85%,换成 Claude Opus 4.6 直接上到 95%+。但 Claude 的 token 成本是 DeepSeek 的好几倍。

我的做法是:Intent Router 用便宜的模型(DeepSeek V3 或 GLM-4.7),具体 Skill 执行用强模型(Claude Opus 4.6 或 GPT-5)。OpenClaw 支持给不同 Skill 配不同的模型:

sentiment_skill = Skill(
 config=SkillConfig(
 name="sentiment_analysis",
 # ...
 llm_override={
 "model": "deepseek-v3", # 简单任务用便宜模型
 }
 )
)

report_skill = Skill(
 config=SkillConfig(
 name="review_report",
 # ...
 llm_override={
 "model": "claude-sonnet-4.6", # 复杂生成任务用强模型
 }
 )
)

自定义工具型 Skill(调用外部 API)

Skill 不只是 prompt 封装,还能挂载外部工具。比如我需要一个 Skill 能调用图片识别 API:

from openclaw import Skill, SkillConfig, Tool

# 定义工具
image_check_tool = Tool(
 name="check_image_nsfw",
 description="检测图片是否包含 NSFW 内容",
 function=lambda image_url: call_nsfw_api(image_url), # 你自己的 API 调用
 parameters={
 "image_url": {"type": "string", "description": "图片 URL"}
 }
)

# 挂载到 Skill
image_skill = Skill(
 config=SkillConfig(
 name="image_moderation",
 description="检测图片是否包含不适当内容",
 trigger_phrases=["检查图片", "图片审核", "这张图有问题吗"],
 system_prompt="你是图片内容审核助手,使用 check_image_nsfw 工具检测图片。",
 tools=[image_check_tool], # 挂载工具
 )
)

Tool 的设计和 OpenAI 的 Function Calling 完全一致,用过 Function Calling 的话上手零成本。

小结

OpenClaw 的 Skills 框架核心思路就一句话:把 Agent 的能力拆成独立的 Skill 模块,用 LLM 做动态路由,用 SkillChain 做流程编排。

适合用 OpenClaw Skills 的场景:

  • 多能力 Agent(客服机器人、内容审核、数据分析助手)
  • 需要动态判断"该用哪个能力"的场景
  • 团队协作,不同人开发不同 Skill,最后组装

不太适合的场景:

  • 固定流程的工作流(直接用 LangGraph 或者写死流程更简单)
  • 单一能力的 Agent(杀鸡用牛刀了)

说实话 OpenClaw 的文档还不够完善,很多高级用法得翻源码才能搞明白。但 Skills 这个抽象层确实解决了我之前 Agent 编排的痛点——不用再写一堆路由逻辑了,专心写每个 Skill 的 prompt 和工具就行。

有问题评论区聊,踩过的坑我基本都记着 🤝