关于 context-mode
context-mode 是面向 Agent 的操作技能,要求将可能产生大量输出的命令和文件读取交由专用工具处理,以减少会话中的冗余上下文。
主要功能
- 01按输出风险选择执行工具
- 02用 ctx_execute 运行命令
- 03用 ctx_execute_file 分析文件
- 04支持索引与检索文档
- 05提供浏览器数据处理流程
适用场景
- 01运行测试并控制输出进入上下文
- 02分析日志、数据文件或源代码
- 03检索已索引的外部文档
- 04处理 Playwright 页面快照
MCP 相关
该技能指导 Agent 使用 context-mode 的 MCP 工具,包括 ctx_execute、ctx_execute_file、ctx_index 和 ctx_search。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mksglu/ context-mode --skill context-mode安装后在 Claude Code 中输入/context-mode确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/anti-patterns.mdpatterns-javascript.mdpatterns-python.mdpatterns-shell.md详细介绍
Context Mode:所有大型输出的默认模式
强制规则
<context_mode_logic> <mandatory_rule> 所有命令默认使用 context-mode。只有输出量确定很小的操作才使用 Bash。 </mandatory_rule> </context_mode_logic>
Bash 白名单(可直接安全运行):
- 文件修改:
mkdir、mv、cp、rm、touch、chmod - Git 写入操作:
git add、git commit、git push、git checkout、git branch、git merge - 导航:
cd、pwd、which - 进程控制:
kill、pkill - 包管理:
npm install、npm publish、pip install - 简单输出:
echo、printf
其他所有操作 → ctx_execute 或 ctx_execute_file。 任何会读取、查询、获取、列出、记录日志、测试、构建、比较差异、检查或调用外部服务的命令都属于此类。这包括所有 CLI(gh、aws、kubectl、docker、terraform、wrangler、fly、heroku、gcloud 等)——这类工具有成千上万个,我们无法一一列出。
不确定时,使用 context-mode。 每多占用 1 KB 不必要的上下文,都会降低整个会话的质量和速度。
决策树
About to run a command / read a file / call an API?
│
├── Command is on the Bash whitelist (file mutations, git writes, navigation, echo)?
│ └── Use Bash
│
├── Output MIGHT be large or you're UNSURE?
│ └── Use context-mode ctx_execute or ctx_execute_file
│
├── Fetching web documentation or HTML page?
│ └── Use ctx_fetch_and_index → ctx_search
│
├── Using Playwright (navigate, snapshot, console, network)?
│ └── ALWAYS use filename parameter to save to file, then:
│ browser_snapshot(filename) → ctx_index(path) or ctx_execute_file(path)
│ browser_console_messages(filename) → ctx_execute_file(path)
│ browser_network_requests(filename) → ctx_execute_file(path)
│ ⚠ browser_navigate returns a snapshot automatically — ignore it,
│ use browser_snapshot(filename) for any inspection.
│ ⚠ Playwright MCP uses a SINGLE browser instance — NOT parallel-safe.
│ For parallel browser ops, use agent-browser via execute instead.
│
├── Using agent-browser (parallel-safe browser automation)?
│ └── Run via execute (shell) — each call gets its own subprocess:
│ execute("agent-browser open example.com && agent-browser snapshot -i -c")
│ ✓ Supports sessions for isolated browser instances
│ ✓ Safe for parallel subagent execution
│ ✓ Lightweight accessibility tree with ref-based interaction
│
├── Processing output from another MCP tool (Context7, GitHub API, etc.)?
│ ├── Output already in context from a previous tool call?
│ │ └── Use it directly. Do NOT re-index with ctx_index(content: ...).
│ ├── Need to search the output multiple times?
│ │ └── Save to file via ctx_execute, then ctx_index(path) → ctx_search
│ └── One-shot extraction?
│ └── Save to file via ctx_execute, then ctx_execute_file(path)
│
└── Reading a file to analyze/summarize (not edit)?
└── Use ctx_execute_file (file loads into FILE_CONTENT, not context)
各工具的使用场景
| 场景 | 工具 | 示例 |
|---|---|---|
| 调用 API 端点 | ctx_execute | fetch('http://localhost:3000/api/orders') |
| 运行会返回数据的 CLI | ctx_execute | gh pr list、aws s3 ls、kubectl get pods |
| 运行测试 | ctx_execute | npm test、pytest、go test ./... |
| Git 操作 | ctx_execute | git log --oneline -50、git diff HEAD~5 |
| 检查 Docker/K8s | ctx_execute | docker stats --no-stream、kubectl describe pod |
| 读取日志文件 | ctx_execute_file | 解析 access.log、error.log、构建输出 |
| 读取数据文件 | ctx_execute_file | 分析 CSV、JSON、YAML、XML |
| 读取并分析源代码 | ctx_execute_file | 统计函数、查找模式、提取指标 |
| 获取网页文档 | ctx_fetch_and_index | 为 React/Next.js/Zod 文档建立索引,然后搜索 |
| Playwright 快照 | browser_snapshot(filename) → ctx_index(path) → ctx_search | 保存到文件,在服务器端建立索引,然后查询 |
| Playwright 快照(单次处理) | browser_snapshot(filename) → ctx_execute_file(path) | 保存到文件,在沙盒中提取内容 |
| Playwright 控制台/网络 | browser_*(filename) → ctx_execute_file(path) | 保存到文件,在沙盒中分析 |
| MCP 输出(已在上下文中) | 直接使用 | 不要重新建立索引——内容已加载 |
| MCP 输出(需要多次查询) | 使用 ctx_execute 保存 → ctx_index(path) → ctx_search | 先保存到文件,再在服务器端建立索引 |
| 清除已建立索引的知识库内容 | ctx_purge(confirm: true) | 永久删除所有已建立索引的内容 |
自动触发条件
遇到以下任一情况时,即使没有人要求,也要使用 context-mode:
- API 调试:“访问此端点”“调用 API”“检查响应”“查找响应中的错误”
- 日志分析:“检查日志”“有哪些错误”“读取 access.log”“调试 500 错误”
- 运行测试:“运行测试”“检查测试是否通过”“测试套件输出”
- Git 历史:“显示最近的提交”“git log”“有哪些变更”“比较分支差异”
- 数据检查:“查看 CSV”“解析 JSON”“分析配置”
- 基础设施:“列出容器”“检查 Pod”“S3 存储桶”“显示正在运行的服务”
- 依赖项审计:“检查依赖项”“过时的软件包”“安全审计”
- 构建输出:“构建项目”“检查警告”“编译错误”
- 代码指标:“统计行数”“查找 TODO”“函数数量”“分析代码库”
- 查找网页文档:“查阅文档”“查看 API 参考”“查找示例”
语言选择
| 场景 | 语言 | 原因 |
|---|---|---|
| HTTP/API 调用、JSON | javascript | 原生 fetch、JSON.parse、async/await |
| 数据分析、CSV、统计 | python | csv、statistics、collections、re |
| 使用管道的 Shell 命令 | shell | grep、awk、jq、原生命令 |
| 文件模式匹配 | shell | find、wc、sort、uniq |
搜索查询策略
- BM25 使用 OR 语义——匹配更多词条的结果会自动获得更高排名
- 每个查询使用 2-4 个具体的技术词条
- 索引了多个文档时,始终使用
source参数,以避免不同来源之间相互干扰- 支持部分匹配:
source: "Node"可匹配"Node.js v22 CHANGELOG"
- 支持部分匹配:
- 始终使用
queries数组——在一次调用中批量提交所有搜索问题:ctx_search(queries: ["transform pipe", "refine superRefine", "coerce codec"], source: "Zod")- 切勿多次单独调用 ctx_search()——将所有查询放入一个数组
外部文档
- 外部文档始终使用
ctx_fetch_and_index——对于不属于你的包,切勿使用cat或通过本地路径调用ctx_execute - 对于托管在 GitHub 上的项目,使用原始 URL:
https://raw.githubusercontent.com/org/repo/main/CHANGELOG.md - 索引完成后,在搜索中使用
source参数,将结果限定为该特定文档
关键规则
- 始终使用 console.log/print 输出发现。 只有 stdout 中的内容会进入上下文。没有输出 = 浪费调用。
- 编写分析代码,而不只是转储数据。 不要使用
console.log(JSON.stringify(data))——先分析,再打印发现。 - 输出内容要具体。 打印包含 ID、行号、确切值的错误详情,而不只是数量。
- 对于需要 EDIT 的文件:使用常规 Read 工具。context-mode 用于分析,而不是编辑。
- 仅限 Bash 白名单命令:使用 Bash 进行文件变更、git 写入、导航、进程控制、包安装和 echo。其他操作均通过 context-mode 执行。
- 切勿使用
ctx_index(content: large_data)。 使用ctx_index(path: ...)在服务端读取文件。content参数会将数据作为工具参数传入上下文——仅用于较小的内联文本。 - Playwright 工具(
browser_snapshot、browser_console_messages、browser_network_requests)始终使用filename参数。 否则完整输出会进入上下文。 - 不要重复索引已在上下文中的数据。 如果 MCP 工具在之前的响应中返回了数据,该数据已加载——直接使用,或先保存到文件。
沙盒数据工作流
<sandboxed_data_workflow> <critical_rule> 使用支持保存到文件的工具时:始终使用 'filename' 参数。 切勿将大型原始数据集直接返回到上下文。 </critical_rule> LargeDataTool(filename: "path") → mcp__context-mode__ctx_index(path: "path") → ctx_search() </sandboxed_data_workflow>
无论来源工具是什么(Playwright、GitHub API、AWS CLI 等),都应使用这一通用模式来保留上下文。
示例
调试 API 端点
const resp = await fetch('http://localhost:3000/api/orders');
const { orders } = await resp.json();
const bugs = [];
const negQty = orders.filter(o => o.quantity < 0);
if (negQty.length) bugs.push(`Negative qty: ${negQty.map(o => o.id).join(', ')}`);
const nullFields = orders.filter(o => !o.product || !o.customer);
if (nullFields.length) bugs.push(`Null fields: ${nullFields.map(o => o.id).join(', ')}`);
console.log(`${orders.length} orders, ${bugs.length} bugs found:`);
bugs.forEach(b => console.log(`- ${b}`));
分析测试输出
npm test 2>&1
echo "EXIT=$?"
检查 GitHub PR
gh pr list --json number,title,state,reviewDecision --jq '.[] | "\(.number) [\(.state)] \(.title) — \(.reviewDecision // "no review")"'
读取并分析大型文件
# FILE_CONTENT is pre-loaded by ctx_execute_file
import json
data = json.loads(FILE_CONTENT)
print(f"Records: {len(data)}")
# ... analyze and print findings
浏览器与 Playwright 集成
任务涉及 Playwright 快照、截图或页面检查时,始终通过文件 → 沙盒处理。
Playwright 的 browser_snapshot 会返回 10K–135K 个 token 的无障碍树数据。不带 filename 调用会将所有数据转储到上下文中。将输出传给 ctx_index(content: ...) 会将其作为参数再次传入上下文。这两种做法都不正确。
关键要点:browser_snapshot 有一个 filename 参数,可将内容保存到文件,而不返回到上下文。ctx_index 有一个 path 参数,可在服务端读取文件。ctx_execute_file 可在沙盒中处理文件。这些操作都不会触及上下文。
工作流 A:快照 → 文件 → 索引 → 搜索(多个查询)
Step 1: browser_snapshot(filename: "/tmp/playwright-snapshot.md")
→ saves to file, returns ~50B confirmation (NOT 135K tokens)
Step 2: ctx_index(path: "/tmp/playwright-snapshot.md", source: "Playwright snapshot")
→ reads file SERVER-SIDE, indexes into FTS5, returns ~80B confirmation
Step 3: ctx_search(queries: ["login form email password"], source: "Playwright")
→ returns only matching chunks (~300B)
上下文总量:约 430B,而非 270K 个 token。实际节省 99%。
工作流 B:快照 → 文件 → 执行文件(一次性提取)
Step 1: browser_snapshot(filename: "/tmp/playwright-snapshot.md")
→ saves to file, returns ~50B confirmation
Step 2: ctx_execute_file(path: "/tmp/playwright-snapshot.md", language: "javascript", code: "
const links = [...FILE_CONTENT.matchAll(/- link \"([^\"]+)\"/g)].map(m => m[1]);
const buttons = [...FILE_CONTENT.matchAll(/- button \"([^\"]+)\"/g)].map(m => m[1]);
const inputs = [...FILE_CONTENT.matchAll(/- textbox|- checkbox|- radio/g)];
console.log('Links:', links.length, '| Buttons:', buttons.length, '| Inputs:', inputs.length);
console.log('Navigation:', links.slice(0, 10).join(', '));
")
→ processes in sandbox, returns ~200B summary
上下文总量:约 250B,而非 135K 个 token。
工作流 C:控制台与网络(数据量大时保存到文件)
browser_console_messages(level: "error", filename: "/tmp/console.md")
→ ctx_execute_file(path: "/tmp/console.md", ...) or ctx_index(path: "/tmp/console.md", ...)
browser_network_requests(includeStatic: false, filename: "/tmp/network.md")
→ ctx_execute_file(path: "/tmp/network.md", ...) or ctx_index(path: "/tmp/network.md", ...)
重要:为什么必须同时使用 filename 和 path
| 方式 | 上下文开销 | 正确吗? |
|---|---|---|
browser_snapshot() → 将原始内容放入上下文 | 135K 个 token | 否 |
browser_snapshot() → ctx_index(content: raw) | 270K 个 token(翻倍!) | 否 |
browser_snapshot(filename) → ctx_index(path) → ctx_search | 约 430B | 是 |
browser_snapshot(filename) → ctx_execute_file(path) | 约 250B | 是 |
关键规则
调用
browser_snapshot、browser_console_messages或browser_network_requests时,始终使用filename参数。 然后通过ctx_index(path: ...)或ctx_execute_file(path: ...)处理——绝不要使用ctx_index(content: ...)。数据流:Playwright → 文件 → 服务端读取 → 上下文。绝不要:Playwright → 上下文 → ctx_index(content) → 再次进入上下文。
子 Agent 的使用
子 Agent 会通过 PreToolUse hook 自动获得基于上下文模式的工具路由。无需在子 Agent 提示词中手动添加工具名称——hook 会自动注入。只需用自然语言描述任务。
反模式
- 通过 Bash 使用
curl http://api/endpoint→ 50KB 内容会涌入上下文。改用ctx_execute搭配 fetch。 - 通过 Bash 使用
cat large-file.json→ 整个文件会进入上下文。改用ctx_execute_file。 - 通过 Bash 使用
gh pr list→ 原始 JSON 会进入上下文。改用ctx_execute搭配--jq过滤器。 - 将 Bash 输出通过
| head -20管道传递 → 其余内容会丢失。使用ctx_execute分析全部数据并输出摘要。 - 在捕获前缩减
ctx_execute的上游输出 →ctx_execute负责捕获,ctx_search负责筛选;合并这两个阶段会丢弃索引无法看到的数据。参见references/anti-patterns.md§8。 - 通过 Bash 运行
npm test→ 完整测试输出会进入上下文。使用ctx_execute捕获并总结。 - 调用
browser_snapshot()时未提供filename参数 → 135K 个 token 会涌入上下文。始终使用browser_snapshot(filename: "/tmp/snap.md")。 - 调用
browser_console_messages()或browser_network_requests()时未提供filename→ 整个输出会涌入上下文。始终使用filename参数。 - 将任何大型数据传给
ctx_index(content: ...)→ 数据会作为参数进入上下文。始终使用ctx_index(path: ...)在服务端读取。content参数仅用于你自行编写的少量内联文本。 - 调用 MCP 工具(Context7
query-docs、GitHub API 等)后,再将响应传给ctx_index(content: response)→ 上下文用量会翻倍。响应已经在上下文中——直接使用,或先保存到文件。 - 忽略
browser_navigate的自动快照 → 导航响应包含完整的页面快照。不要依赖它进行检查——另行调用browser_snapshot(filename)。 - 认为
ctx_stats会重置或清除内容 →ctx_stats是只读的(仅显示统计信息)。使用ctx_purge(confirm: true)永久删除所有已索引内容。