OpenClaw/Trae/Claude Code的Rules、Skills与MCP机制

经过前两个版本的迭代后,agent-plus继续进化成像 OpenClaw等一样的agent——agent-claudecode,新增了80行左右的代码,为了解决 agent-plus遗留的问题。

如果不知道讲什么请看上一篇:Agent进化:nanoAgent记忆与规划双突破

先回顾下 agent-plus未解决的问题以及新的解决方式:

未解问题 解决方案 新概念
工具是硬编码的 外部配置文件动态加载工具 MCP(Model Context Protocol)
没有行为约束 声明式规则文件注入prompt Rules
规划是被动的 把规划注册为 Agent 可自主调用的工具 “规划即工具 Plan as Tool”

工具集的扩充

agent-claudecode 在之前的基础工具上扩充了一些更常用的工具,成自己的核心工具集;这些新增的工具也不是随意选取的,它能让自己的能力大增。

base_tools = [
    {"type": "function", "function": {"name": "read", "description": "Read file with line numbers", "parameters": {"type": "object", "properties": {"path": {"type": "string"}, "offset": {"type": "integer"}, "limit": {"type": "integer"}}, "required": ["path"]}}},
    {"type": "function", "function": {"name": "write", "description": "Write content to file", "parameters": {"type": "object", "properties": {"path": {"type": "string"}, "content": {"type": "string"}}, "required": ["path", "content"]}}},
    {"type": "function", "function": {"name": "edit", "description": "Replace string in file", "parameters": {"type": "object", "properties": {"path": {"type": "string"}, "old_string": {"type": "string"}, "new_string": {"type": "string"}}, "required": ["path", "old_string", "new_string"]}}},
    {"type": "function", "function": {"name": "glob", "description": "Find files by pattern", "parameters": {"type": "object", "properties": {"pattern": {"type": "string"}}, "required": ["pattern"]}}},
    {"type": "function", "function": {"name": "grep", "description": "Search files for pattern", "parameters": {"type": "object", "properties": {"pattern": {"type": "string"}, "path": {"type": "string"}}, "required": ["pattern"]}}},
    {"type": "function", "function": {"name": "bash", "description": "Run shell command", "parameters": {"type": "object", "properties": {"command": {"type": "string"}}, "required": ["command"]}}},
    {"type": "function", "function": {"name": "plan", "description": "Break down complex task into steps and execute sequentially", "parameters": {"type": "object", "properties": {"task": {"type": "string"}}, "required": ["task"]}}}
]

其中重点说下 edit和改进后的read 。

edit:用约束引导LLM行为

def edit(path, old_string, new_string):
    try:
        with open(path, 'r') as f:
            content = f.read()
        if content.count(old_string) != 1:
            return f"Error: old_string must appear exactly once"
        new_content = content.replace(old_string, new_string)
        with open(path, 'w') as f:
            f.write(new_content)
        return f"Successfully edited {path}"
    except Exception as e:
        return f"Error: {str(e)}"

在替换字符串时,old_string 必须在文件中仅出现一次,因为出现多次不知道应该替换哪一处。使用这种防御性编程防止LLM替换了不该替换的子串,大大降低了误编辑的概率。

设计工具的启示:用工具的约束来引导 LLM 的行为,比在 prompt 中告诫"小心编辑"可靠得多。约束是硬性的,prompt 是软性的。

read:行号+分页

def read(path, offset=None, limit=None):
    try:
        with open(path, 'r') as f:
            lines = f.readlines()
        start = offset if offset else 0
        end = start + limit if limit else len(lines)
        numbered = [f"{i+1:4d} {line}" for i, line in enumerate(lines[start:end], start)]
        return ''.join(numbered)
    except Exception as e:
        return f"Error: {str(e)}"

该版本升级了read函数,这个版本支持offset和limit分页读取,并且每行加上了行号,行号可以让LLM更靳准的定位。

Rules:给agent立人设、立规矩

Rules放在 .agent/rules/目录下,agent启动初始化时加载并注入到 system prompt中。

RULES_DIR = ".agent/rules"

def load_rules():
    rules = []
    if not os.path.exists(RULES_DIR):
        return ""
    try:
        for rule_file in Path(RULES_DIR).glob("*.md"):
            with open(rule_file, 'r') as f:
                rules.append(f"# {rule_file.stem}\n{f.read()}")
        return "\n\n".join(rules) if rules else ""
    except:
        return ""

# agent启动时加载
rules = load_rules()
if rules:
    context_parts.append(f"\n# Rules\n{rules}")
    print(f"[Rules] Loaded {len(rules.split('# '))-1} rule files")

rules的本质

roles是项目级的 system prompt扩展。它解决了一个关键问题:不同项目、不同团队、不同场景对 Agent 的要求不同。与其每次在对话中反复叮嘱"记得遵守 pep8规范",不如写一次规则文件,永久生效。用声明式文件定制 Agent 的行为边界。
所以现在的 agent-claudecode 由之前的 agent-plus只有 基础指令+记忆 的两层 system prompt拼接 升级到了四层拼接。

agent-claudecode system prompt = 基础指令 + Rules(项目规则) + Skills(技能描述) + Memory(历史记忆)

Skills:可插拔的技能注册

Skills 是 .agent/skills/ 目录下的 JSON 文件,以列表摘要的形式注入 system prompt

SKILLS_DIR = ".agent/skills"

def load_skills():
    skills = []
    if not os.path.exists(SKILLS_DIR):
        return []
    try:
        for skill_file in Path(SKILLS_DIR).glob("*.json"):
            with open(skill_file, 'r') as f:
                skills.append(json.load(f))
        return skills
    except:
        return []

if skills:
    context_parts.append(f"\n# Skills\n" + "\n".join([f"- {s['name']}: {s.get('description', '')}" for s in skills]))
    print(f"[Skills] Loaded {len(skills)} skills")

关于 Skill 的文件格式: 在 OpenClaw / Claude Code 的实际实现中,Skill 的标准格式是 Markdown(每个 Skill 目录下有一个 SKILL.md,里面详细描述执行步骤、最佳实践、示例代码等)。但 nanoAgent 原始仓库中采用的是 JSON 格式,所以代码里用 json.load() 来解析。这不影响理解核心思路——不管是 Markdown 还是 JSON,本质都是"把技能描述加载出来注入到 system prompt"。格式只是载体,思想是一样的。

MCP:让agent拥有无限工具的协议

MCP(Model Context Protocol)是一个开放标准,它定义了 LLM 与外部工具之间的通信协议,任何遵循这个协议的工具服务都可以即插即用地接入Agent。

agent-claudecode中的MCP实现


MCP_CONFIG = ".agent/mcp.json"

def load_mcp_tools():
    if not os.path.exists(MCP_CONFIG):
        return []
    try:
        with open(MCP_CONFIG, 'r') as f:
            config = json.load(f)
            mcp_tools = []
            for server_name, server_config in config.get("mcpServers", {}).items():
                if server_config.get("disabled", False):
                    continue
                for tool in server_config.get("tools", []):
                    mcp_tools.append({"type": "function", "function": tool})
            return mcp_tools
    except:

all_tools = base_tools + mcp_tools; agent的本地基础工具集加上 mcp服务提供的工具集,组成agent所能使用到的所有工具集合。

不过在 nanoAgent的MCP实现中,实际是简化版的MCP,它只是实现了“工具注册”的demo,没有实现mcp的工具执行(通过网络调用远程mcp服务的能力),实际调用时会走到 else分支语句:Error: Unknown tool,agent-claudecode的实现虽然不完整,但它展示了 MCP 集成的核心思路:工具定义与工具实现的分离。在完整实现中,那个 else 分支会变成一个 MCP 客户端调用。

规划即工具:规划从手动触发到自主决策,让agent成为真正的六边形战士

agent-claudecode中将 plan注册为工具,这意味着LLM遇到复杂问题的时候可以主动调用plan工具进行任务拆解,化整为零,各个击破,无需用户干预。与算法中的分治算法思想类似。

agent-claudecode总结

  • loop:agent如何自主运行?
  • tools: agent如何作用于世界
  • memory: agent如何回忆过去
  • planning: agent如何规划未来(应对复杂任务)
  • rules: agent如何遵守约束?
  • skills: agent如何掌握做事的方法
  • mcp:agent如何获得新工具

这7层架构是当今主流Agent框架的共同架构,nanoAgent用不到300行代码将这个架构完成的展现了出来。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐