Roog's BLOG & TOOLS

[系统已在线] :: 2026-01-30 16:10:21 :: 终端 v1.0

Claude Code 基础分享II - SKILL COMMAND COMPACT 一切都是上下文

在我个人粗鄙的理解中,所有,所有这一切

都是上下文

什么是上下文?

上下文,是claude code 与你交互时,所有信息的总和,包括你发送的prompt,claude code的回复,claude code执行的命令,claude code编辑的文件,claude code的思考过程,claude code的计划文件,所有这些全都是上下文。

Anthropic讨论过关于上下文的是如果运转的,他们将不断对话,运转,思考这一过程中产生的全部可供Agent参考内容称之为“上下文窗口”(Context Window)。


上下文窗口

简单讲上下文就是claude code与你交互时,所有信息的总和,也是Agent Model在和你交互的过程中所看到的一切。

模型本身部署在云端,通过claude code这个工具和你交互,如我上文中提到的,除去你的prompt之外,model 会试图通过claude code获取更多的上下文信息,比如阅读 你之前书写的代码,文档,执行某条命令来查看环境信息(比如–version 或者 –help),claude 甚至会在你的prompt没有叙述足够的内容时,主动想你问询,以确保能它理解了你的要求。

上下文窗口的大小是一个非常重要的概念,对于claude sonnect 它有 200k 和 1m两种选择,对于opus模型是200k,大多数第三方模型(例如GLM4.7 KIMI k2 等等)都是200k。

这意味着当前Agent 正在运作过程中的对话极限,模型无法将注意力关注在无线的上下文中,这就好像你上周一中午吃的什么你已经不记得了一样。

因此,上下文窗口的大小决定了claude code能够记住多少历史信息,从而影响到它的表现和能力。

但需要注意的是,模型并非会对所有上下文都保持高度的注意力,它会根据当前任务的需要,选择性地关注某些上下文,忽略其他不重要的信息。 有时候因为这种特性会导致模型无法准确的理解你想要表达的意图,因此保持上下文的简洁和相关性非常重要。


压缩上下文

当我们完成了一系列任务时,当前会话中的上下文可能会变得非常庞大,我们可以执行压缩上下文的操作, 当在同一会话中,claude code会自主发现上下文目前接近窗口极限值并执行压缩。 这通常会在上下文极限窗口低于10%时出发,而且claude code会在合适的时机执行压缩,以确保上下文窗口不会被填满且工作尽量不被打断。

手动压缩命令:

/compact

执行完成后效果如下图:

img.png

在执行/compact 命令后,claude code会根据你的提示词对之前的工作做出总结。通常来说,思考过程,工具调用结果,文件修改记录等等不重要的内容被忽略,claude code会尝试将这些信息压缩到一个更简洁的格式,以便于后续的交互和理解。

你可以把这一过程理解为,输入/compact 后,系统会调用一个默认提示词,对上下文进行总结,然后删除旧的上下文,只保留总结后的上下文。


init 与 CLAUDE.md

前面在介绍基础使用时,我们提到过,/init 和 CLAUDE.md 以及它的作用。

它被放置在项目的根目录,一般来说会用于书写项目的大体作用,代码书写规范和风格,如何驱动开发(例如TDD)等项目相关的内容。 如果你的团队不希望提交这份文件,那么你可以将其加入.gitignore中。

其实除了CLAUDE.md之外,claude code还支持另外两个文件,分别是CLAUDE.local.md和~/.claude/CLAUDE.md

CLAUDE.local.md 是本地的项目文件,如果你的团队已经维护了一份CLAUDE.md在代码仓库中,那么你可以根据你的定制化需求额外书写CLAUDE.local.md作为CLAUDE.md的补充,以覆盖CLAUDE.md中不适用提示词。

以linux为例 ,~/.claude/CLAUDE.md 是跨越项目的提示词,它通常用于书写一些通用的且仅属于你个人的操作习惯,代码风格或者是在这台电脑上Agent工作时的注意事项。


slash command 斜杠命令

前面在介绍基础使用时,我们提到过,/init 和 /compact 事实上是claude code内置的命令,像这样的命令还有很多输入/help可以查看所有的命令,效果如下:

img_1.png

按下tab键即可在 general commands custom-commands 中切换

  • general是一般的快捷键
  • commands 就是slash command,一切预载的斜杠命令
  • custom-commands 是用户自定义的命令,是的我们可以书写自己的slash command,让我们来举个例子:

custom slash commands 用户自定义的斜杠命令

简单讲,构建一个slash command 可以替代你一直输入重复的上下文。 我来举个简单的例子:

在coding工作中,我们常常需要使用git commit 提交代码,并且要认真书写一段 commit message 来描述我们本次提交的内容包含什么,这种工作通常很机械, 但同时,有需要伴随一定的代码审视和逻辑总结,这非常适合agent帮你做。

针对这个场景,我们可以构建一个slash command,每次输入 /git-action:git-commit 时,让claude code帮你完成git commit操作,包括书写commit message,同时会自动将修改的文件添加到git中。

  • 第一步 我们需要再项目的根目录(或者系统的用户目录)下的 .claude文件夹下创建一个commands文件夹,你所有的slash command 都应该放置在该文件夹下,这是claude code的规格。
  • 第二步 在commands文件夹下创建一个git-action文件夹,然后在git-action文件夹下创建一个git-commit.md文件(markdown文件),这个文件就是我们的slash command的实现文件。 img_2.png
  • 第三步 书写我们的提示词,我将会向你展示我输写的提示词,这仅仅是一个例子,你可以根据自己的需求进行修改。
---
name: git-commit
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*)
description: 创建一个 git commit
---

使用简体中文创建一个 git commit ,message 的模板如下:


{git分支名称}: {简短描述}

- 详细描述
- 详细描述...

注意,不要添加模型信息,ai信息等内容,message应专注于提交内容的描述。
详细内容的描述应简洁明了,避免使用过于复杂的术语或冗长的句子。
除非明确需求,否则不要提交非代码文件(例如.gitignore)

$ARGUMENTS

如你所见,提示词的头部有这些可选的字段

  • name: my-skill(仅仅是个名字)
  • description: 这个技能做什么
  • disable-model-invocation: true 是否禁用模型调用,如果你选择false,那么claude code也有权调用这个slash commands
  • allowed-tools: Bash(git add:), Bash(git status:), Bash(git commit:*) 叙述你允许它使用哪些工具,从而不用一直yes yes yes的允许
  • hooks: 生命周期钩子,这个暂时不展开聊

当你准备好了这一切,我们重启claude code,你就可以发现这个新的slash commands。

事实上如果你足够聪明的话,上面讲述构建slash command的描述刚好就是提示词,你可以让claude code帮你弄好这个文件😂,和agent一起工作真的很酷不是吗。 img_3.png

然后我们按两下ctrl + c退出,再重启 claude code, 并且输入 /git 他就会自动提示你这个命令了,如下图。

img_5.png

当你执行这个命令,就能看到 claude code帮你做git commit 操作啦。

img_6.png

当然,根据你发现claude code工作结果的不同,你可以反复尝试调整你的提示词或者md文件,直到你对它的工作满意满意为止。

然后你会发现这东西有一点点缺点,每次你都要手动输入命令才能触发这段特殊的提示词,它自动触发的并不足够好,事实上,claude code有一套专门的思路来处理这个场景, 他就是Skill. 在Anthropic的官方文档中,目前skills已经和slash command合并了,他们被一起称为Skills.


SKILLS

Skills是claude code的内置功能,它允许你创建一个特殊的提示词。

事实上,skills 的书写方法和 slash command的书写方法基本一致。

并且和slash command 一样,你可以选择把它放在项目目录中,或者是全局

位置路径适用于
个人~/.claude/skills//SKILL.md你的所有项目
项目.claude/skills//SKILL.md仅此项目
插件<plugin>/skills//SKILL.md启用插件的位置

它的原字段如下:

字段必需描述
name技能的显示名称。如果省略,使用目录名称。仅小写字母、数字和连字符(最多 64 个字符)。
description推荐技能的作用以及何时使用它。Claude 使用它来决定何时应用该技能。如果省略,使用 markdown 内容的第一段。
argument-hint自动完成期间显示的提示,指示预期的参数。示例:[issue-number] 或 [filename] [format]。
disable-model-invocation设置为 true 以防止 Claude 自动加载此技能。用于你想使用 /name 手动触发的工作流。默认值:false。
user-invocable设置为 false 以从 / 菜单中隐藏。用于用户不应直接调用的背景知识。默认值:true。
allowed-tools此技能处于活动状态时 Claude 可以使用而无需请求权限的工具。
model此技能处于活动状态时要使用的模型。
context设置为 fork 以在分叉的子代理上下文中运行。
agent设置 context: fork 时要使用的子代理类型。
hooks限定于此技能生命周期的钩子。有关配置格式,请参阅钩子。

SKILLS 最大优势在于 “渐进式加载” 这意味着claude code不会一次性将你书写的所有SKILL 加载到内存中,而是按需加载。 当它完成任务时,发现你有一个可能合适的技能,他会先读取原字段的名称和描述,然后试图理解该skill是否符合目前的工作,如果符合才会渐进式的继续加载一部分。 这样它就为你节省了相当多的上下文窗口,让claude code可以更专注于当前任务,而不是被过多的技能所干扰。

同样的渐进式加载也有副作用,当你的名称和描述不够清晰时,claude code可能无法正确理解你的意图,从而导致技能无法被正确加载或者每次都加载。


举个例子:我书写了一个excel导出api如何书写的skill,它的内容如下:

---
name: wrote-export-excel-api
description: 描述了如何通过使用 maatwebsite/excel 来书写符合项目规范的导出API。仅适用于非CSV的导出,CSV完全可以使用PHP自带的csv输出能力,不必要使用此技巧。
disable-model-invocation: false
---


# maatwebsite/excel 使用指南

本文档总结了项目中 maatwebsite/excel 的使用方式和代码风格规范。

## 依赖版本
composer.json :
"maatwebsite/excel": "^3.1"

## 项目使用概况

- **使用场景**: 仅用于 Excel 导出,不涉及导入功能
- **文件格式**: 统一使用 XLSX 格式
- **导出方式**: 使用 `Excel::download()` 直接下载
.......

然后放在正确的目录:

--- .claude
   |--- skills
       |--- ExportExcelAPI
            |--- SKILL.md

你在claude code终端输入

/skill

就能查看到该skill了。 img_4.png

其实利用skills你能做更夸张的事情,让我来举个例子:

claude code并不擅长数学运算,甚至会经常算错,你可以写一个skills,来帮助它解决数学计算问题:

首先让我们书写一个php脚本,用来给claude code提供一个简单的数学计算工具,可以进行加减乘除等基本运算,记住,这只是一个简单的演示。


SKILLS的简单示例

下面是一个用来给claude code提供数学计算工具的示例:它是一个php脚本,我们的skill就是让claude code能够利用这个脚本进行简单的数学运算。

---
name: calculate-tool
description: 提供了一个简单的数学计算工具,可以进行加减乘除等基本运算。
disable-model-invocation: false
---

# calculate-tool(最小演示)

这是一个给 Claude Code(cc)用的 **stdio 工具**示例。

**规则只有一条:**
Claude 往 stdin 写一段 JSON
你的脚本从 stdin 读 JSON 并在 stdout 回 JSON


## 目录结构
calculate-tool/
  calculate-tool.php
  skill.md
## 工具输入(stdin)

### 固定格式(op 模式):
{
  "op": "add|sub|mul|div",
  "a": 1,
  "b": 2
}

- 含义:
    - op:运算类型(加/减/乘/除)
    - a、b:两个数字
      工具输出(stdout)

- 成功:
{ "ok": true, "result": 3 }
- 失败(示例):
{ "ok": false, "error": "division by zero" }

然后书写一下这个脚本

#!/usr/bin/env php
<?php
/**
 * calculate-tool.php (minimal demo)
 *
 * stdin:  {"op":"add|sub|mul|div","a":1,"b":2}
 * stdout: {"ok":true,"result":3}
 */

declare(strict_types=1);

$raw = trim(stream_get_contents(STDIN) ?: '');
if ($raw === '') {
    echo json_encode(["ok" => false, "error" => "empty stdin"]) . PHP_EOL;
    exit(1);
}

$req = json_decode($raw, true);
if (!is_array($req)) {
    echo json_encode(["ok" => false, "error" => "invalid json"]) . PHP_EOL;
    exit(1);
}

$op = $req["op"] ?? null;
$a  = $req["a"]  ?? null;
$b  = $req["b"]  ?? null;

if (!in_array($op, ["add","sub","mul","div"], true)) {
    echo json_encode(["ok" => false, "error" => "op must be add|sub|mul|div"]) . PHP_EOL;
    exit(1);
}
if (!is_numeric($a) || !is_numeric($b)) {
    echo json_encode(["ok" => false, "error" => "a and b must be numbers"]) . PHP_EOL;
    exit(1);
}

$a = (float)$a;
$b = (float)$b;

switch ($op) {
    case "add": $result = $a + $b; break;
    case "sub": $result = $a - $b; break;
    case "mul": $result = $a * $b; break;
    case "div":
        if ($b == 0.0) {
            echo json_encode(["ok" => false, "error" => "division by zero"]) . PHP_EOL;
            exit(1);
        }
        $result = $a / $b;
        break;
}

echo json_encode(["ok" => true, "result" => $result]) . PHP_EOL;

我们来试一下 :

img_7.png

实时上这只是一个演示,你可以利用功能更强大的cli工具完成和更优秀的技巧完成更加不可思议的事情,让我举个例子:

  • 基于Agent的CI/CD ?
  • 自动代码审查?
  • 基于ffmpeg的视频压缩/剪裁/字幕?
  • 链接到你的本地mysql帮助你完成数据查询/构建?
  • ….所有你能想象的到的事情,它都可以。

关于slash command和skills,其实构建过程都是在写提示词,关于提示词,其实Anthropic有一个非常好的如何书写提示词的文档。如果你有时间,应该读读这篇文章。

Tags: