Claude Code 与 OpenCode:90 分钟速成课
15 个概念,覆盖真实使用中的 80%
这是一门实用速成课。没有灌水,也不推销。读完后,你会知道在任一工具里该用什么、什么时候用,以及需要更深入时去哪里查。
让其他内容都串起来的核心洞见是:agentic coding 看起来披着 coding tool 的外衣,本质上是 context-management 问题。 几乎所有「高级技巧」都可以归结为同一件事:在正确时间把正确的信息放进模型,把错误的信息挡在外面。请带着这个视角阅读每一节。
前置要求:2026 年 AI Prompting。 本页假设你已经掌握那里的 13 个概念:像同事一样 briefing(概念 1)、context 是整个游戏(概念 4)、thinking mode(概念 5)、neutral framing(概念 6)、iterate loop(概念 7)、models checking models(概念 13)。那就是纪律。本页展示的是当模型能接触你的 filesystem 时,这套纪律长什么样。
Claude Code 和 OpenCode 是同一个想法的两种实现:大体相同的 vocabulary,略有不同的 keybinds。
两个工具,不是一个。这是有意设计。 这里的纪律必须能超越任何单一工具。pricing、access restrictions、model preference 和 strategic shifts 都不应该让你已经学会的东西搁浅。把每个概念同时放进两个工具,也是检验这个概念是否真实的最强方式:如果某个 technique 只在 Claude Code 中可用,它就是 Claude Code trick;如果它在两边都成立(同样形状、不同 keybinds),它就是 agentic coding 的真实机制。当前沿模型性能是约束时,选择 Claude Code;当 flexibility、cost control 或 openness 是约束时,选择 OpenCode。OpenCode 还自带一组免费模型,不需要创建账号也能使用。无论用哪边,你构建的 skills 都是同一套。重点在这里,不是折中。
截至 2026 年 5 月。两种工具发布都很快:config schemas、command names 和 install commands 会变。如果你还没有安装工具,安装说明在对应官方文档页:Claude Code、OpenCode。拿不准其他细节时,也先从这些页面开始。
两种工具都更新频繁;因此,每次开始 session 前,先运行
claude update和opencode upgrade,使用最新版本。
默认背景:你能舒服地使用命令行,用过 git,读写过 JSON config。你不需要有 LLM coding agents 的经验,本页就是为此准备的。如果 MCP、hooks 或 LLM 与外部工具之间的 protocol layer 对你还很新,读下去时会从上下文里逐步掌握。
本页中 Claude Code 与 OpenCode 不同的地方都有 switcher。选择一次后,本页所有 switcher 都会同步,并在下次访问时保留。
本页是 crash course,即一次阅读覆盖真实用法的 80%。关于下列主题的完整处理(rules-file hierarchy、plan mode 深入、skill anatomy、subagent orchestration、hook events、CI/CD、session management),请看 Chapter 14: Working with General & Coding Agents 和 Chapter 17: Claude Code for Teams, CI/CD & Advanced Configuration。crash course 是地图;那些章节是地形。
Part 6 有一个完整 worked example:同一个真实任务端到端跑两次,一次在 Claude Code,一次在 OpenCode。如果你更适合从观察中学习,可以先跳到那里,再回来补概念。
Part 1: Foundations
前三个概念在两个工具里完全相同。命令或 keybind 不同时,正文会直接指出差异。
1. What these tools actually are
多数人的 mental model 是「懂代码的 chatbot」。这是错的,而这个错误本身就是问题。
chatbot 回答问题。Claude Code 和 OpenCode 会采取 actions。它们读取你的文件、编辑文件、在你的机器上运行命令、访问网络,并把这些步骤串起来直到任务完成。你给 brief,它们工作,你 review。
思维转换是:停止打问题,开始写 brief。"How do I add auth?" 是 chatbot prompt。"Add email/password auth to this Express app using bcrypt and JWT, store users in the existing Postgres users table, write tests, don't touch the OAuth code" 才是 agentic-coding prompt。第二个会工作;第一个只会得到一段游走的独白。
这就是 AI Prompting 的概念 1(novice vs. power user),只不过对象从 PDF 变成了文件。同样的 brief 形状,风险更高,因为模型会真的行动。
两个工具的默认设置不同,但基础不变。Claude Code 属于 Anthropic,搭配 Claude models,开箱体验打磨得更好。OpenCode 是 open-source、model-agnostic(Claude、GPT、Gemini、本地模型都可以),并且能配置到 tool-level permission。按你的 model preference 和 config control 需求选择;本速成课后面的内容两边都适用。
还没安装任何一个? 继续读之前,先拿 canonical one-liner。后面的章节假设你可以按一个键并看到工具响应。auth、IDE plugins 和 troubleshooting 都在官方文档里。
# macOS / Linux / WSL — recommended (auto-updates)
curl -fsSL https://claude.ai/install.sh | bash
# Windows PowerShell
irm https://claude.ai/install.ps1 | iex
# macOS Homebrew (no auto-update — run `brew upgrade claude-code` periodically)
brew install --cask claude-code
# npm fallback
npm install -g @anthropic-ai/claude-code
Full reference: code.claude.com/docs.
安装后,在任何你想工作的 folder 中打开 terminal,输入 claude(或 opencode)。你就进入了第一个 session。从这里开始,本页每个概念都是你可以在那个 session 里尝试的东西。
2. Plan mode (the most underused feature)
两个实现略有不同,但想法完全相同:在让模型写任何东西之前,强制它先产出一份你能 review 的 written plan。
按 Shift+Tab 循环 permission modes。第一次会进入 auto-accept;第二次进入 plan mode。在 plan mode 中,模型可以读取,但不能写入:不能编辑文件,也不能运行 shell commands。
无论哪边,这个动作都会让你慢下来,但慢的两个原因其实会加速:
- 它会在误解变贵之前抓住误解。 plan 是 contract。如果模型误读 brief,你会在 plan 中看到,而不是在一个需要回滚的 200 行 diff 中看到。
- 它会让第二轮代码更好。 预先写好的 plan 会把 relevant context(file paths、function names、intended approach)压缩成一份干净 artifact,implementation phase 可以依靠它。没有 plan 时,模型同时 reasoning 和 writing,而 reasoning 会输。
经验法则:任何超过 10 分钟的改动,都先走 plan mode。更大的 features,可以让模型把 plan 保存到 markdown 文件(docs/plans/feature-x.md),方便之后 resume 或喂给 fresh session。
Plan mode 是两个 prompting 概念合体:think hard(概念 5)加上 contract,outline before drafting(概念 7)加上 filesystem。编辑 plan,而不是编辑 diff。
3. Permissions discipline
两个工具在采取 action 前都会请求 approval。两个工具也都允许全局跳过 approvals:Claude Code 有 --dangerously-skip-permissions,OpenCode 可以设置 "permission": "allow"。至少一开始不要这样做。
有效的模式是:前几个 sessions 先手动批准,观察哪些 actions 足够安全可以 auto-approve,然后把它们写进 config。
.claude/settings.json:
{
"permissions": {
"allow": [
"Read",
"Edit",
"Write",
"Bash(npm test)",
"Bash(npm run lint)",
"Bash(npm run build)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)"
],
"deny": ["Bash(rm -rf *)", "Bash(npm publish *)", "Bash(git push *)"]
}
}
然后安装一个 notification helper。让 agentic coding 感觉快的模式,不是执行更快,而是你可以走开。启动一个长任务,切去做别的工作,等收到 ping 再回来。如果你并行运行多个 sessions(这是真实存在、也真的能提升生产力的做法),notifications 就是你跟踪哪一个需要你介入的方式。
Claude Code 有 cc-notify 这类社区 helper。OpenCode 的 desktop app 会原生发送系统通知;如果用 TUI,可以写一个 plugin 订阅 session.idle,然后 shell out 到 osascript(macOS)或 notify-send(Linux)。
Part 2: Context management

如果你只内化本速成课的一节,就内化这一节。这里的内容在两个工具里完全相同,只有命令名偶尔不同。
这是 AI Prompting 的概念 4(context is the whole game)的增强版。那里,bad context 让你得到更差的答案。这里,它会给你更差的答案,也会给你更差的 codebase。同样的纪律,后果会叠加。
4. Context rot is real
context window 是模型一次能持有的文本量。现代 models 有巨大的窗口:几十万 tokens,有时甚至一百万。听起来像无限,其实不是。
需要理解两件事:
真实使用会比你想象中更快填满窗口。 几个 code files、一段 stack trace、你粘贴的一些 docs,再加 30 轮 conversation,在你意识到之前就会吃掉几万 tokens。你的 laptop 不会显示 fuel gauge。
Recall 在窗口填满很久之前就开始退化。 研究(以及你自己只要留意就会看到的经验)显示,token counts 升高后,模型会明显更差地记住上下文早期的具体细节。模型并不是准确地忘记。它只是停止正确加权那些信息。症状包括:忽略你 20 条消息前说过的 constraint、重复已经做过的工作、幻觉出一个早先明明读对过的 function signature。
还有财务维度。 每条消息都会重新计费整个 context window:一个 50K-token conversation 在 debug session 中被 ping 20 次,就是 100 万 input tokens,每一轮都收费。按 token 计费的 API(多数 OpenCode setups、raw Anthropic API)会直接伤钱包;subscription tiers(Claude Code Pro/Max)则表现为 rate-limit hits。无论哪种,臃肿 context 都会在你最需要持续工作时耗尽预算。
结论很朴素但实际:少而刻意使用的 context,胜过把更多 context 倒进去祈祷。
5. /clear and /compact
两个命令,两种情况。
清空 conversation,重新开始。 切换到无关任务时使用。旧 context 是 irrelevant noise,只会干扰新任务。
- Claude Code:
/clear - OpenCode:
/new(也有/clearalias)
总结 conversation,保留 summary,丢掉其余内容。 当你深陷同一个长任务、context 已经膨胀,但又不能丢掉线索时使用。
- 两个工具都是:
/compact(OpenCode 中也 aliased 为/summarize)
你可以指导 compact 保留什么:/compact keep the API contract decisions and current file paths。
两者不能混用。/clear 是「新 conversation」。/compact 是「同一个 conversation,少一点包袱」。选错会丢掉重要 context,或者保留没用 context。
6. Resume sessions
conversations 会被保存。两个工具都允许 resume,想法相同,命令不同:
- Claude Code:
claude --resume,然后从列表中选择一个 session。 - OpenCode: 在 TUI 内使用
/sessions(也 aliased 为/resume)切换 saved sessions。
这在两种模式下很重要:
- 明天接着做。 长 features 很少能一次坐完。resume 让你停止时不会丢失模型对项目的 working memory。
- 运行多个 branches。 你可以 resume 任意 session,而不只是上一个。一个 session 可以深入 backend 任务,另一个在 frontend 上工作,然后来回切换。
如果你有保存好的 plan 文件(docs/plans/feature-x.md),即使 fresh session 也可以用一条消息补上上下文:"read docs/plans/feature-x.md and continue from step 4." Resume 更快,但 plan 文件是 safety net。(完整模式,包括何时 resume、何时 fork、bad turn 后如何恢复,见 Chapter 17 § Session Management: Resume, Fork, and Recovery。)
两边都有 rewind,而且都能回滚 file changes。 在 Claude Code 中,按两次 Esc(double-tap Esc),或运行 /rewind,会打开 previous user messages 列表;选中一条后,可以选择恢复 code、conversation,或两者都恢复。这能工作,是因为 Claude Code 会在每次 prompt 前 checkpoint 模型的 file edits。在 OpenCode 中,/undo 会 rewind 上一条 user message,并 revert 该轮的 file changes;/redo 会反转上一次 /undo。它底层用 git,所以项目必须是 git repo。一个真正的差异是:Claude Code 的 checkpointing 跟踪模型的 file edits,但不跟踪由 bash commands 改动的文件(模型运行的 rm 或 mv 不在 checkpoint 中);OpenCode 基于 git 的 /undo 会 diff 整个 working tree,因此也能捕获 bash 驱动的改动。两者都能从 bad prompt 中救你;当 bad turn 包含会触碰文件的 shell commands 时,尤其应使用 OpenCode 的 /undo。
三个命令的快速决策规则:
Diagnostic: when context goes bad
Context rot 有可见症状。留意这些信号:
- 模型反复道歉却没有进展。
- 它重写同一段代码,但没有实质变化。
- 它引用不存在的 variables、files 或 functions。
- 它与同一 session 里你之前说过的 constraint 冲突。
- 每次回复越来越长、越来越含糊、越来越恭顺。
看到这些时,停止输入。 本能上想「再补一个 clarifying prompt」是错的;那只是在已经污染的 context 中继续加入更多污染内容。正确动作是 reset 和 re-brief。如果 conversation 还有有用核心,就运行 /compact;如果确实应该重新开始,就运行 /clear(或 OpenCode 的 /new)。花 5 分钟 reset,比和一个 context 已经中毒的模型争论 1 小时便宜。
Diagnostic: when context costs spike
Cost discipline 就是 context discipline;只是你在钱包里感受到它。每一轮都会重新计费整个 context,所以同样的 bloat 既伤 recall,也伤账单。无论你用哪个 provider,前期遇到的 surprise bills 大多落在五种症状里:
Symptom: token usage spiked suddenly mid-session
→ Cause: rules file or system prompt changed, breaking cache hits.
Fix: revert the change, or accept the cache miss as a one-time cost.
Symptom: each turn costs noticeably more than the previous one
→ Cause: context is growing without bound. Files keep getting read in,
exploration output is accumulating, conversation is long.
Fix: /compact with a "keep architectural decisions and current
file paths" hint.
Symptom: model is over-explaining, producing walls of text
→ Cause: reasoning effort is too high for the task; or the prompt
invites narration.
Fix: turn the reasoning effort down; ask for "code only,
minimal commentary."
Symptom: monthly bill is much higher than expected
→ Cause: running a frontier-tier model on tasks an economy-tier
model would handle correctly.
Fix: route mechanical work (codemods, tests, formatting) to the
cheaper tier; reserve the frontier model for planning and
hard reasoning. See Part 8 Pattern 1 for the split.
Symptom: cache hits suddenly dropped from ~70% to ~10%
→ Cause: the system prompt, CLAUDE.md, or the first user message
changed structure. Cache matches prefixes byte-for-byte.
Fix: stabilize what comes first; let the variable content
come later.
大多数都能通过一次 config change 恢复。五种症状下面的机制相同,也正是 Part 2 一直强调的:稳定、窄的 context 更便宜,recall 也比 sprawling context 更好,而且每一轮都是如此。
Part 3: The rules file
7. CLAUDE.md / AGENTS.md, done well
两个工具都会在每个 session 开始时,把 project-root markdown 文件加载进 context。它最接近 project-level system prompt。
不要从零开始写这个文件。 在 fresh project 中,在任一工具运行 /init。模型会扫描你的 folder,并为你起草文件。之后你的工作是毫不留情地删除不需要的部分:这是 editing task,不是 authoring task。下面所有内容都在讲保留什么、删掉什么。(beginner-level walkthrough: Chapter 14 § CLAUDE.md and AGENTS.md。advanced——multi-file hierarchy、glob-scoped rules、team conventions: Chapter 17 § The CLAUDE.md Configuration Hierarchy。)
Claude Code 使用 CLAUDE.md。OpenCode 使用 AGENTS.md。迁移时注意:OpenCode 也会 fallback 读取 CLAUDE.md,前提是不存在 AGENTS.md;如果两个文件都存在,AGENTS.md 胜出,CLAUDE.md 被忽略。如果你已经维护了一个 CLAUDE.md,OpenCode 会自动读取它,除非你设置 OPENCODE_DISABLE_CLAUDE_CODE=1 完全 opt out。若只想部分禁用,OPENCODE_DISABLE_CLAUDE_CODE_PROMPT=1 只跳过 rules-file fallback,OPENCODE_DISABLE_CLAUDE_CODE_SKILLS=1 只跳过 skills fallback。这是两个工具之间最大的 portability win。
几乎每个人都会犯的错误,是把这个文件当 documentation:塞进 architecture overviews、完整 coding standards,以及 codebase 的每个小怪癖。结果是一个 20,000-token 文件,在每个任务里吃掉你的 context budget,即使这个任务 90% 内容都无关。记住 Part 2:这个文件里的任何内容,每一条消息都要付费,不管它是否 relevant。
正确模型是目录,不是百科全书。 目标是低于大约 2,500 tokens。更深的 context 用 on-demand references:
CLAUDE.md。@filename 语法会在相关时自动加载 referenced files:
# Project: my-app
## Stack
Next.js 14, TypeScript, Postgres, Drizzle ORM.
## Commands
- `npm run dev`: start local server
- `npm test`: run vitest
- `npm run db:migrate`: apply migrations
## Critical rules
- Never edit files in `src/generated/`. They're rebuilt by codegen.
- All API routes use the auth middleware in `src/lib/auth.ts`.
- See @docs/conventions.md for naming and folder rules.
- See @docs/db-schema.md for table structure.
同样形状也适用于非软件项目。 写 reports 的 consultant、做 lesson plans 的 teacher、跑 operations 的 small-business owner:rules file 在任何 domain 中都应该是「目录,不是百科全书」。写作/content 项目的例子(CLAUDE.md 或 AGENTS.md,形状相同):
# Project: blog-and-newsletter
## What this is
A folder of drafts, research, and published posts. I write a weekly newsletter and occasional long-form posts.
## Where things live
- `drafts/`: in-progress posts, one per file
- `research/`: source notes and clippings, organized by topic
- `published/`: shipped posts (do not edit)
## Critical rules
- Never edit anything in `published/`. Fixes go in a new draft with a correction note.
- Footnotes go in `[brackets]` inline; we resolve them to numbered footnotes only at publish time.
- Tone: conversational, no bullet lists in body copy.
原则与 my-app 版本相同:紧凑、声明式,只写模型无法通过看 folder 自己推断出来的东西。
对于每一行你想添加的内容,问自己:「如果我删掉它,模型会不会犯一个本来不会犯的错?」如果答案是否,删掉。不要告诉模型用 TypeScript:它能看见 .ts 文件。告诉它无法推断的东西:codegen folder、auth pattern、以前咬过你的问题。
这个文件应该从真实失败中生长,而不是从想象中的失败中生长。把它 commit 到 git。让团队继续补充。
Part 4: Personalizing your tool
两个工具里都有四类 extension。decision tree 完全相同:
这些全都是 context-management tools。Custom commands 和 skills 会按需注入正确 context。Hooks 和 plugins 不消耗 tokens 就能强制执行规则,而不必依赖模型「记住」。Subagents 会隔离 context,防止噪声进入 main thread。同一个问题,不同形状。
8. Slash commands
slash command 是带有好记 shortcut 的 saved prompt。两个工具都支持,形状非常相似。
先指出一个值得注意的 gotcha: commands 在 session start 时加载一次。如果你在 mid-session 创建新 command(无论是自己写文件,还是让模型写),它不会出现在 autocomplete 中,直到你退出并重新进入 CLI。下面两个 folders 在这一点上的行为相同;创建后都要 restart session。
Markdown files in .claude/commands/ (project) or ~/.claude/commands/ (personal). Example .claude/commands/review.md:
Review the current diff for:
1. Bugs and edge cases
2. Test coverage gaps
3. Naming and readability
4. Adherence to @docs/conventions.md
Be specific. Quote the lines you're commenting on.
这个 /review command 就是 AI Prompting 的概念 6 在工作中落地。
AI models 喜欢同意你。你只说 "review my diff",没有任何 instructions,就会得到 looks good、well-structured、nice naming,不管事实如何。
上面的四点 checklist 会阻止这种情况。模型不能只说 "looks good"。它必须逐项检查,并指出失败发生在哪一行。
两边都用 /review 调用。两边都支持 $ARGUMENTS(OpenCode 还增加 positional $1、$2 等)。OpenCode 还支持 !`shell command`,可以把 command output 注入 prompt,并通过 agent: plan / subtask: true frontmatter 把 command route 到特定 agent 或 subagent。这对把 review workflows 留在 main context 外很有用。
一个非软件例子。 /standup command 用于多数团队每天都会做的 ritual。保存为 .claude/commands/standup.md(或 .opencode/commands/standup.md):
Read yesterday's note in `journal/`. Produce a 4-line standup:
1. What I shipped yesterday (1 line)
2. What I'm working on today (1 line)
3. Blockers (1 line, "none" if clear)
4. One thing I learned (1 line)
Tone: telegraphic. No filler.
现在,每次输入 /standup,它都会从昨天的 notes 生成一份干净的 status update。形状与上面的 /review 一样,只是 domain 不同。同样技巧也适用于 /digest(把 email folder 转成 action items)、/draft-reply(为这个 path 下的 email 写一封礼貌回复),以及任何你已经输入同一套 instructions 超过两次的 chores。
两个工具里的统一测试是:如果你发现自己把同一段 instructions 输入超过两次,它就应该成为 command。深版内容(folder layout、frontmatter、argument passing、何时把 command 提升为 skill)在 Chapter 14 § Teach Claude Your Way of Working。
Note (Claude Code, 2026): 截至 2026 年,slash commands 和 skills 已经统一。
.claude/commands/中的文件仍然可用,并会显示为 slash commands,但新的工作越来越多地进入.claude/skills/,因为 skills 支持更多能力(auto-invocation、subagent execution、file-path filters)。把两者看作连续谱。
9. Skills
skill 是 custom command 的大号 sibling。想法相同,都是 packaged expertise,但它有三个有意义的升级,而且两个工具完全一致:
- Auto-invocation。 模型在每个 session 开始时读取 skill descriptions,并在任务匹配时调用正确 skill。
- Progressive disclosure。 skill 有一个
SKILL.md文件(entry point),并且可以 reference 同一 folder 中的其他 files。只有SKILL.md会 upfront 加载;其余内容按需加载。这就是 context-management 原则变成 file format。 - Frontmatter controls。
SKILL.md顶部的 YAML 用于配置 behavior。
file format 已经趋同。为一个工具写的 skill,大体也能在另一个工具里工作。
.claude/skills/extract-transcript/SKILL.md:
---
name: extract-transcript
description: Extract a clean transcript from a YouTube video URL. Use when the user provides a YouTube link and asks for the transcript, captions, or text of the video.
---
# Extract YouTube transcript
1. Take the URL from the user's message.
2. Run `yt-dlp --skip-download --write-auto-sub --sub-format vtt "$URL"`.
3. Convert the VTT to plain text: strip timestamps, deduplicate overlapping captions.
4. Save to `transcripts/{video-id}.txt`.
For formatting conventions (paragraph breaks, speaker labels), see `references/style.md`.
是的,这两段 byte-identical。OpenCode 也会 fallback 读取 ~/.claude/skills/ 和 .claude/skills/,所以你已经为 Claude Code 写过的任何 skill,都能不改动地在 OpenCode 中工作。
description 是最重要的字段:模型就是用它判断 skill 是否适用。模糊的 descriptions("helps with videos")会到处触发;具体的 descriptions("Use when the user provides a YouTube link...")只会在相关时触发。
保持 SKILL.md 本身短小:低于大约 200 行是不错的规则。把深度内容推到同一目录的 reference files 里,并在正文中链接。这样 quick task 只为 overview 付费;deep task 可以拉入所需 references。(基础 walkthrough(skill 是什么、何时激活、progressive disclosure 如何工作)见 Chapter 14 § The Concept Behind Skills 和 Building Your Own Skills。team/CI variant(frontmatter fields、glob-scoped activation)见 Chapter 17 § Custom Skills with Frontmatter。)
不要从零开始写 skills。 Claude Code 自带一个 skill-creator skill,可以正确 scaffold 新 skills。因为同样 fallback 机制,只需安装一次,两个工具都能调用它。(注意:file discovery 是共享的,但 skill bodies 如果引用 Claude Code-specific tools,可能需要轻微编辑才能在 OpenCode 中干净运行。对于新的 agents,也就是 OpenCode 中的另一个概念,请使用 opencode agent create 交互式 scaffolder。)
还有一个模式:串联小 skills,不要构建 monoliths。 一个「weekly content digest」skill 同时 research、write、format 和 review,会比四个独立 skills(research、draft、format、review)更难维护,也更差。handoff 通常通过 filesystem 完成:research 把 output 写到 tmp/research.md,然后指示 draft 读取它;draft 写到 tmp/draft.md,依此类推。你也可以直接 prompt 模型按顺序运行它们("use the research skill, then draft a post from the output"),但 file-based pipeline 更能跨 /clear 持久化,也更容易 debug。不管哪种,每个 skill 都只聚焦自己的步骤。reusability 很好,但真正收益是 per-step context isolation:format skill 不需要加载 research notes,research skill 也不需要知道 formatting conventions。同一个原则,应用在比 subagents 更小的粒度上。
10. Hooks (Claude Code) / Plugins (OpenCode)
Skills 是 probabilistic:模型决定是否调用它们。Hooks 和 plugins 是 deterministic:它们在特定 events 上每次都会触发,不需要模型判断。
想法相同,machinery 不同。这是两个工具差异最大的地方。进入 tabs 前先说明命名:Claude Code 也有一个单独叫 "plugins" 的东西(把 commands、skills 和 hooks 打包在一起的 bundles)。本节不是讲那个。这里的 "hook" 始终指 Claude Code lifecycle hook,"plugin" 始终指 OpenCode event module。它们在各自工具中占同一个位置:deterministic guardrail。
Hooks 是附着在 .claude/settings.json lifecycle events 上的 shell commands。大 events 包括:SessionStart、UserPromptSubmit、PreToolUse(exit code 2 blocks)、PostToolUse。结构有三层:event(PreToolUse)、按 tool name 过滤的 matcher group(Bash)、以及运行的 handler。handler 的 if 字段会进一步匹配实际 command,所以只有需要时才 spawn handler。例子:不管模型当时怎么想,都 block rm -rf:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(rm -rf *)",
"command": "echo 'Blocked dangerous command' >&2; exit 2"
}
]
}
]
}
}
if: "Bash(rm -rf *)" filter 负责匹配;到 command 运行时,这个 tool call 已经是已知的 rm -rf,所以 command 只需要拒绝(exit code 2 会 block)。当 hook 确实需要检查 tool input(而不只是匹配它)时,Claude Code 会把 input 作为 JSON 通过 stdin 传给 command,command 用 jq 读取。下面的 placeholder example 会展示这一点。
一个非软件例子:不要发布仍含 placeholder markers 的 drafts。 假设你有时会在 drafts 中留下 [TODO] 或 [FIX] markers,并在 publish 前忘记解决。hook 可以 block 任何写入 published/ 的操作,如果文件仍包含 placeholder:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "jq -e '(.tool_input.file_path | test(\"/published/\")) and (.tool_input.content | test(\"\\\\[TODO\\\\]|\\\\[FIX\\\\]\"))' >/dev/null && { echo 'Refusing to publish draft with TODO/FIX markers' >&2; exit 2; }; exit 0"
}
]
}
]
}
}
这个例子需要看文件内部,所以它不只是 rm -rf block。matcher 捕获每个 Write;command 把 Claude Code 通过 stdin 传来的 JSON 直接 pipe 进一个 jq test,同时检查两件事,并且只在两者同时为真时 block:file_path 位于 published/ 下,且 content 包含 placeholder marker。[TODO] 出现在 drafts/ 文件中可以通过;published/ 中的 clean file 可以通过;只有带 marker 且准备写入 published/ 的文件会以 exit code 2 被拦下。模型写文件,hook 检查;如果 placeholder 漏了出去,模型必须先解决它,文件才能 ship。
trade-off 是真实的:OpenCode plugins 更强;Claude Code hooks 更简单。
任何能写 bash 的人,都能在 5 分钟内写一个 Claude Code hook,并把它 ship 到 repo,不需要 Node toolchain。OpenCode plugins 需要 Bun 或 Node、npm dependencies,以及 TypeScript 或 JavaScript fluency。对于一行检查("block rm -rf"),shell 的成本更低。对于需要 structured logging、async work 或多个 event subscriptions 的事,JS/TS module 确实更干净。选择约束与你正在构建的东西匹配的工具。
在 production codebases 上运行这些工具的人,有一个有用模式:不要在 write time block,在 commit time block。 让模型完成工作(mid-edit 打断会让它困惑),然后在 commit step 上运行 hook/plugin,检查 tests、types、formatter。如果失败,就强制模型回到 fix loop。
把 hooks/plugins 用在你需要 100% 成立的事情上。把 skills 用在你希望模型大多数时候记得的事情上。
11. Subagents
subagent 是一个拥有自己 context window 的隔离 agent instance。你把任务 delegate 给它;它在私下工作;它返回 summary。它的 file searches、log dumps 和 exploratory reads 永远不会碰到你的 main thread。
从 context-management 的角度看,这很重要:最污染 context 的任务,就是「explore the codebase to find where X happens」。这种任务会把几十个 files 拉进 context,其中大多数最终都不需要。放进 subagent,main session 只看到结论("X happens in src/services/billing.ts:142"),而不是整个搜索过程。
两个工具都内置 read-only Explore subagent(此外还有其他 subagents;OpenCode 还自带一个更泛用的 General subagent),用于 codebase exploration,避免污染 main thread。在 Claude Code 中,plan mode 会自动 delegate 给 Explore:你大多会在无意识中用到它,模型本身甚至可以在被要求时 self-enter plan mode。在 OpenCode 中,Plan agent 也可以用同样方式 auto-invoke subagents(subagent delegation 是普通 primary-agent capability);也可以显式用 @explore 调用。不过进入 Plan mode 本身,需要用户通过 Tab 明确切换。
对于 custom subagents:
.claude/agents/doc-fetcher.md:
---
name: doc-fetcher
description: Fetches and summarizes external library documentation. Use when the user references a library and we need to understand its current API.
tools: WebFetch, Read, Write
---
You are a documentation researcher. Given a library name and a topic, fetch the official docs, extract only the API surface relevant to the topic, and write a focused summary to `tmp/docs-{library}.md`. Don't paste full pages: extract the patterns and signatures we need.
一个非软件例子:research subagent。 假设你有一个装满长 PDF 的 folder(industry reports、legal contracts、academic papers),想让 agent 提取 focused summary,但不想把整个 document 拖进 main thread:
---
name: pdf-summarizer
description: Reads a long PDF and writes a focused summary. Use when the user references a PDF and wants the key points without dumping the whole document into the conversation.
tools: Read, Write
---
You are a research summarizer. Given a PDF path and a question, read the document, extract only the passages relevant to the question, and write a focused summary to `tmp/summary-{pdf-name}.md`. Do not paste full pages: pull out the patterns, claims, and quotes the user actually needs.
形状与上面的 doc-fetcher 相同,只是 domain 不同。200 页 PDF 不会进入 main conversation;只有答案回来。
Invocation 在两个工具里相同。两边都能根据 subagent description auto-invoke(这也是你最常用的路径:写好 description,让模型在任务匹配时选择正确 helper)。两边也都支持在 prompt 中用 @subagent-name 显式调用;OpenCode 在 autocomplete 中更明显地展示这一点,但 Claude Code 同样接受。默认用 auto-invocation;当你想确保某个特定 subagent 运行时(或当多个 candidates 的 description 容易混淆时),使用 @name。
两个工具里完全相同的一条总规则是:如果某个任务涉及大量阅读,而这些阅读不会进入最终答案,它就应该放进 subagent。(Chapter 14 § Subagents and Orchestration 会讲如何编写自己的 subagent,并把它们串起来。)
Part 5: Connecting to the world
12. MCP, used honestly
MCP(Model Context Protocol)是一种标准化方式,用来把 external tools(Slack、Notion、你的 database、GitHub 等)暴露给 agent。Claude Code 和 OpenCode 都用同一个 protocol 支持 MCP。为一个工具写的 server,也能在另一个工具中使用。
configuration shape 只是表面不同:
Typically configured via the CLI (claude mcp add ...) or in .claude/settings.json.
两个工具里的 pitch 都是真的:把 agent 连接到你的 tools,意味着它能在你的工作上采取行动,而不只是谈论工作。读取 Linear ticket、发布 Slack update、查询 production read-replicas:这些都合理。
也要诚实说明,两边都一样:MCP 不总是正确答案,一些 experienced users 已经从 heavy MCP use 转向 simple CLIs。原因是:MCP server 会把底层 tool 抽象成一组 fixed operations,而每个 operation 都会提前以 tool description 的形式支付 context cost。CLI 就只是 CLI:agent 可以读它的 --help,组合 flags,pipe outputs,并 improvises。对于 stateless tools(GitHub、AWS、Jira),gh、aws 和 jira CLIs 往往比 MCP equivalents 更灵活。
OpenCode docs 明确提醒这一点:MCP servers 会增加 context,因此你应该谨慎启用。它们警告说:"Certain MCP servers, like the GitHub MCP server, tend to add a lot of tokens and can easily exceed the context limit."
一个可用的 working model:把 MCP 用在 stateful 或 auth-heavy services 上,也就是 protocol layer 确实在做重要工作的地方(Playwright 是标准例子:管理 browser session 很难)。其余场景用 CLIs。不要因为 MCP servers 存在就安装十个;只有确实有理由时才安装一个。
Part 6: A complete worked example, twice
这是本速成课其他部分都指向的章节。一个真实任务,所有概念,两个工具。同样八个 decisions,在 Claude Code 和 OpenCode 中并排展示,所以你能看到真正不同的地方有多少。
你不会写一行 code。任何有 laptop 和 folder of files 的人都能跟着做:manager、teacher、small-business owner、student。任务使用一个小团队的 meeting notes,但同样适用于 school committee、volunteer group、freelance practice,或任何保留 notes 并需要从中提取 action items 的人群。
Your task
你有一个叫 notes/ 的 folder,里面有 5 个 files:上周团队会议记录。它们很乱。有的会议把 action items 放在 ## Action Items 下。有的用 ## Todos。一个用小写 ## todo。还有一些把 action items 藏在其他 sections 深处。一些 bullets 标了 [private] 或 [HR],不应该进入任何公开内容。
你想要一个干净文件 开始前,把这些文件复制进 weekly-actions.md,列出每个 action item,按 owner 分组,并带回源 meeting 的 link。private 内容不能泄露。任何 item 都不能丢。如果有 deadlines 落在 public holiday 上,你还想收到 warning。📁 Get the five starter files first (click to expand)
notes/ folder。这个 example 是围绕它们设计的:每个 file 都承担特定角色,所以如果跳过一个,下面某一步就会停止工作。(不想设置 folder?也可以把 5 个 files 直接 paste 到 tool chat 中,并要求它把这些内容当作 notes/ 的内容。)notes/2026-12-07-monday-team-meeting.md# Monday Team Meeting - 2026-12-07
Attendees: @sara, @diego, @priya, @marcus
## Discussion
Reviewed last month's customer satisfaction scores. Renewals are down slightly in the small-business segment.
## Action Items
- @sara: draft a revised welcome email by Dec 18
- @diego: check spam-folder reports with our email vendor by Dec 16
- @marcus: pull renewal numbers for the last two quarters and share with the team
- @sara: finalize offer terms for the new account manager [HR]notes/2026-12-08-customer-feedback.md# Customer Feedback Review - 2026-12-08
Attendees: @sara, @amara, @marcus
## Summary
Read through the top twenty customer comments from last week. Three themes came up: pricing page is confusing, the call-back service is slow, and the FAQ on the website is out of date.
## Todos
- rewrite the pricing page in plain language
- @marcus: log a complaint with the call center vendor about response times
- look into why the FAQ has not been updated in six months
- @amara: draft a customer note explaining the upcoming changes
- review all printed brochures for outdated photos and pricingnotes/2026-12-08-q1-planning.md# Q1 2027 Planning - 2026-12-08
Attendees: @sara, @diego, @amara, @lukas
## Initiatives
We walked through the four candidate initiatives for Q1.
### Year-end promotional campaign
Time-bound: wraps before the holiday break.
#### Action Items
- @amara: finalize the year-end promotional brochure by Dec 25
- @lukas: confirm placement with paid media partners by Dec 20
### Onboarding overhaul
Top priority next quarter.
## todo
- @diego: write the project brief by Jan 15
- @sara: own messaging and visual directionnotes/2026-12-09-all-hands-prep.md# All-Hands Prep - 2026-12-09
Attendees: @sara, @marcus
## Agenda
Walked through the December all-hands agenda. Most slides are in good shape; a couple still need owners.
## Next Steps
- @marcus: set up the video call and record a practice run
- @sara: finalize the Q4 numbers slide
- @sara: prepare the bonus and compensation talking points [private]
- @marcus: book the venue for the team holiday dinnernotes/2026-12-11-vendor-review.md# Vendor Review - 2026-12-11
Attendees: @sara, @amara, external partner
## Summary
Confidential contract negotiation with our printing and fulfillment vendor. Details under NDA.
## Action Items
- @sara: circulate the revised contract to the vendor [private]
- @amara: draft the internal announcement once terms are agreed [private]
- @sara: review the legal redlines on the new pricing schedule [private]
How to read this section
本章的八个 context-management decisions,会在下面按编号逐步出现。每一步都有同样形状:
- What you do:你实际输入或按下的内容
- Why:用一段话说明这个 decision 买到了什么
- What changes in OpenCode:另一个工具中的版本
如果某一步写着 "identical in OpenCode",那行可以跳过,继续往下。
Decision 1: Trim the rules file
What you do (Claude Code). 在 project folder 中打开 Claude Code。运行 /init。它会创建一个叫 CLAUDE.md 的文件,而且通常太长。删除大部分,只留下这些:
# weekly-rollup
## Layout
- `notes/`: meeting notes, one file per meeting
- `weekly-actions.md`: the rollup we are creating
- `plans/weekly-rollup-plan.md`: the plan we will save and reuse
## Critical rules
- Action items can appear under `## Action Items`, `## Todos`, `## Next Steps`, or `## todo` (one meeting uses lowercase). Look at all heading levels, not just the top.
- Owners are written as `@name`. Items with no owner go to an "Unassigned" section.
- Never include any bullet tagged `[private]` or `[HR]`.
Why. 这个文件会在每条 message 开始时被读取。放进这里的任何内容,每一轮都要付费。所以它必须短:只保留模型无法通过看 folder 自己推断出来的内容。尤其是 privacy rule,它不可能自己猜到。
What changes in OpenCode. 文件名是 AGENTS.md,不是 CLAUDE.md。内容相同,目的相同。(如果你已经有以前留下的 CLAUDE.md,OpenCode 也会读取它;不必重命名。)
Decision 2: Plan before writing
What you do (Claude Code). 按两次 Shift+Tab。这会把模型放进 plan mode:它可以读你的 files,但不能改任何东西。然后输入:
Read every file in notes/. Produce weekly-actions.md grouped by
owner. For each item include the action, the source filename, and
the meeting date. Skip anything tagged [private] or [HR]. Do not
lose any action items.
模型思考一分钟,然后返回一份 written plan,准确说明它打算怎么做。
Why. 这是两个工具里最常被低估的功能。读 plan 只要 30 秒。revert 坏改动要久得多。你总是希望先看到 plan。(基础:Chapter 14 § Hello Claude 会介绍两个工具中的 plan mode;Chapter 17 § Plan Mode vs Direct Execution 会深入讲什么时候值得用,什么时候只是拖慢。)
What changes in OpenCode. 按 Tab,从 Build agent 切到 Plan agent。brief 和 result 完全相同,只有 keystroke 不同。
Decision 3: Push back on the plan
What you do (Claude Code). 仔细读 plan。它大概率会有两个问题。
第一个:它只会提到 top-level headings(## Action Items、## Todos)。但你的一份 meeting file(Q1 planning notes)把 action items 藏在 ### Year-end promotional campaign 下,下面还有 #### Action Items。plan 会漏掉这些。
第二个:它不会说明如何处理没有 owner 的 action items(旁边没有 @name,比如 customer-feedback file 中的 "rewrite the pricing page in plain language")。这些会静默消失。
你 push back:
Two changes. (1) Look at all heading levels, not just the top.
Some action items live under sub-headings. (2) Items without an
owner go to an "Unassigned" section at the bottom; never drop
them.
模型会更新 plan。你要求它把最终 plan 保存到 plans/weekly-rollup-plan.md,这样下周五可以复用。
Why. plan 是 contract。你在这里抓问题,成本为零,而不是等文件已经写完后再清理。
What changes in OpenCode. 完全相同。
Decision 4: Let it do the work
What you do (Claude Code). 按 Shift+Tab 离开 plan mode。告诉模型继续执行。
它会读取 5 个 files,写入 weekly-actions.md,按 owner 分组,丢掉 [private] 和 [HR] bullets,把 orphan items 放进 Unassigned section。你看着它完成。
Why. 到这一步之前你一直很谨慎。现在让它工作。因为你先 plan 过,第一次执行大多就是正确的。
weekly-actions.md 应该位于 project root,与 notes/ 同级,而不是在 notes/ 里面。如果模型把它写进 notes/,说明 Decision 1 中 CLAUDE.md 的 Layout section 缺失或被忽略。现在就修正:Decision 6 的 safety net 会在 root-level weekly-actions.md 中 grep filenames;如果文件在错误位置,它找不到。
What changes in OpenCode. 第一次写文件时,OpenCode 会要求你 approve 每次 file write。你可以同意,也可以在 opencode.json 里 pre-approve 常见 actions,让后续运行更顺。
Decision 5: Summarize when the conversation gets long
What you do (Claude Code). conversation 现在已经很长。模型读过每一份 meeting note,很多 raw content 仍然坐在它的 memory 里,包括一些它正确跳过的 private bullets。你不再需要那些内容。输入:
/compact keep the heading rules, the owner list, and the
private/HR exclusion rule
conversation 会被 summary 到只剩你指定保留的部分。
Why. 长而杂的 conversation 会让模型更差,不是更好。它也更贵。清掉已经不 relevant 的内容,尤其是 private content:这种内容不该在 memory 里停留比必要更久。
What changes in OpenCode. 命令完全相同。
Decision 6: Set a safety net for committing
What you do (Claude Code). 在把工作保存到 git 前,你想确认没有 meeting 被意外跳过。你会添加一个 Claude Code hook:一个在每次 commit 前自动运行的小 safety net。
这是本章唯一要求你自己 paste config block,而不是让模型写的地方。原因有两个,都是从教训中学来的。
(1) "Hook" 是 ambiguous。 如果你告诉模型 "create a hook",Claude Code 可能会去写 git hook(.git/hooks/ 中的 file),而不是 Claude Code hook(.claude/settings.json 中的 entry)。这两者不同;你要的是第二个。
(2) 模型会试图聪明,结果静默破坏 safety net。 你的 CLAUDE.md 要求跳过 [private] 和 [HR] items。如果你问得模糊,模型会读到这条规则,然后「好心」把同样的 filter 烘进 hook script。这样 vendor-review meeting(每个 bullet 都是 [private])会被安静忽略,hook 永远不会触发。这个 hook 的目的恰恰是抓住这种情况。要求模型为自己已经被要求遵守的规则写 watchdog,是一个必输局。
安全动作就是直接 paste 配置。
打开 .claude/settings.json(如果不存在就创建),并原样 paste 这段:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(git commit *)",
"command": "for f in notes/*.md; do grep -q \"$(basename $f)\" weekly-actions.md || { echo \"Missing: $f\" >&2; exit 2; }; done"
}
]
}
]
}
}
换成 plain English:matcher 表示「watch Bash tool」;if 把范围缩小到 git commit commands;command 循环遍历每个 .md file in notes/,在 weekly-actions.md 里 grep 它的 basename,如果任一文件没被提到,就以 code 2 退出(从而 block commit)。没有 content filters,没有 [private] checks,没有 exceptions。只有 filenames。这正是重点。
现在告诉模型 commit。safety net 触发:Missing: notes/2026-12-11-vendor-review.md。原因是逻辑上的:那次 meeting 中每个 action item 都标了 [private],而 Decision 1 的 rules 要求丢掉这些内容;所以 rollup 构建时没有任何东西可从该 file 写入,filename 也就没出现。hook 不知道这些;它只看到 file 没被提到,于是 block。
模型读取 error,然后给 rollup 打一个 placeholder entry,显式命名该 file,例如:
## From 2026-12-11-vendor-review.md
- All items confidential — see meeting owner.
filename 现在出现在 weekly-actions.md 中,hook 的 grep 找到它,commit 通过。没有 private 内容泄露进 rollup;audit trail 保持完整。
你在这个 loop 里什么都没做。safety net 抓住了错误,模型自己修正了。
Why. 你希望每次都为真的事情,不应该依赖模型记住。它们应该自动检查。而且检查应该放在模型不能安静改写来取悦自己的地方:这就是为什么这一项是 paste,不是 prompt。
What changes in OpenCode. OpenCode 把这些叫 plugins,而不是 hooks,并且它们写成一个小 JavaScript file。想法相同、结果相同、同样遵循 paste-don't-prompt 逻辑。创建 .opencode/plugins/check-rollup-complete.js(folder 可能还不存在),并 paste 这段:
// .opencode/plugins/check-rollup-complete.js
import { readdirSync, readFileSync } from "fs";
export const CheckRollupCompletePlugin = async ({ $ }) => {
return {
"tool.execute.before": async (input, output) => {
if (
input.tool === "bash" &&
output.args.command?.startsWith("git commit")
) {
const rollup = readFileSync("weekly-actions.md", "utf8");
const missing = readdirSync("notes")
.filter((f) => f.endsWith(".md"))
.filter((f) => !rollup.includes(f));
if (missing.length) {
throw new Error(`Missing from rollup: ${missing.join(", ")}`);
}
}
},
};
};
同样形状:列出 notes/ 中每个 file,检查每个 basename 是否出现在 rollup 中,缺任何一个就 throw。里面没有 [private] filter。行为与 Claude Code 版本完全一致:missing file,commit blocked,模型修复自己。
hook/plugin 深度内容(exit codes、matcher syntax、完整 event list)在 Chapter 14 § Hooks and Extensibility;OpenCode 侧见 Plugins: Putting It All Together。
Decision 7: Send a side-task to a helper
What you do (Claude Code). 一些 action items 有 "by Dec 25" 或 "before year-end" 这样的 deadlines。你想标出任何落在 public holiday 上的 item,方便 owner 调整。输入:
Use the doc-fetcher helper to look up the 2026 international
public holidays list and write the dates to tmp/holidays-2026.md.
一个单独 helper 会离开主线程,fetch 一页很长的 web page,只提取 dates,并写到一个小文件。你的 main conversation 只看到小文件,不看到长网页。
模型随后读取 rollup 中的 deadlines,对照 holidays,并在 brochure deadline 旁增加 note:⚠ falls on Christmas Day。
Why. 直接 fetch web page 会把大量文本倒进 conversation,让它变慢、变乱。派 helper 做这件事,意味着只有答案回来,不带噪声。
What changes in OpenCode. 你可以直接输入 @doc-fetcher 调用 helper;它会显示在 autocomplete 中。同一个 helper,更容易调用。
Decision 8: Save what you learned
What you do (Claude Code). 这是周五 ritual;你每周都会做一次。不应该下周五还记住今天所有 decisions。因此你要求模型把它们保存为 skill:
Create a skill at ~/.claude/skills/weekly-meeting-rollup/SKILL.md
based on what we just did. Include: the four heading variants,
the all-headings rule, the private/HR exclusion, the Unassigned
section, the missing-file check, and the holiday cross-reference.
下周五,你只需要输入 "do the weekly rollup",模型就会自动拉入这个 skill。你今天做出的每个 decision,都会免费继续应用。
Why. 这就是 payoff。本周完成的工作不只服务本周;它教会了模型以后如何永远做这件事。
What changes in OpenCode. skill 保存到略有不同的 folder(~/.config/opencode/skills/...),但 file 本身 byte-for-byte identical。在两个工具之间复制它,都会工作。这是本章 thesis 最强的证明。
What just happened
回看这 8 步。你没有写 code。你不需要知道 API 是什么。你真正做的是 8 个管理模型注意力的小动作:告诉它看什么、什么时候 plan、什么时候忘记、什么时候 delegate、什么时候停止相信自己,以及什么时候记住。
这就是整章内容。
再看两个工具真正差了多少:
- rules file 的文件名不同(
CLAUDE.mdvsAGENTS.md) - 进入 plan mode 的 keystroke 不同(
Shift+TabvsTab) - safety-net file 的语言不同(JSON vs JavaScript)
- 结尾 skill 的 folder 不同(但 file 相同)
仅此而已。
thinking 才是工具。configs 只是装饰。学会这样思考,你的技能就能熬过任何工具更替。
Part 7: Where to run it, and how to grow
13. Terminal, IDE, or desktop?
两个工具都可以在多个地方运行。
Claude Code: terminal、VS Code / JetBrains plugins、Claude desktop app,以及用于 async work 的 cloud-hosted variants。
OpenCode: terminal(TUI 是旗舰体验)、desktop app(macOS/Windows/Linux beta)、通过 ACP support 的 IDE extension、通过 SDK 的 web interface,以及 GitHub 和 GitLab integrations。
按你正在做什么来选。greenfield development 且需要大量 file editing 时,IDE plugins 很难被击败:你能看着 diff 发生。long-running tasks 需要 notifications 和 parallel sessions 时,terminal 就很好。non-coding work 和 scheduled jobs 时,desktop apps 更舒服。
无论用哪个工具,强烈建议:从 terminal 或 IDE plugin 开始。 一旦你理解底层在发生什么(模型读了哪些 files、运行了哪些 commands、做了哪些 decisions),其他 interface 都会变成你能读懂的 thin wrapper。如果你从高度抽象 UI 开始,当事情 sideways 时会很难 debug,因为你不知道什么可以 sideways。
14. Build a personal context library, slowly
当你有几个项目都在使用任一工具后,会发现自己在每个 rules file 中写类似内容:code style、commit conventions、testing philosophy。停止 copy-pasting。
把 shared parts 放到 home config,并从每个项目的 rules file reference 它们:
~/.claude/:
# CLAUDE.md
@~/.claude/style/typescript.md
@~/.claude/style/commits.md
## Project-specific
[only the things unique to this project]
同样想法也适用于 skills。commit-message skill 或 code-review skill 放在 ~/.claude/skills/(OpenCode 也会读取)或 ~/.config/opencode/skills/ 中,会自动在所有项目中可用。
纪律是:不要提前构建这一切。 很容易想花一个周六设计完美 personal setup。要克制。每个 entry 都应该来自真实 failure:模型做错过一次,或你第三次输入同一句话。Build from regret, not from imagination。从真实 friction 长出来的 library 会小而有用;提前设计的 library 往往又大又没人用。
15. Memory beyond the basics
内置 resume 加维护良好的 rules file,已经覆盖多数人的多数场景。如果你需要更多(跨 past conversations 搜索、persistent project notes、能在 /clear 后保留下来的知识),有几个选择:
- 项目中的
notes/folder,让 agent 在 major work 后写 structured notes。便宜、durable、可 grep。效果出奇地好。两个工具里都不需要任何 setup。 - memory MCP server。 已经有几个实现;它们给 agent 一个 explicit save/recall API。两个工具都能用。
- 对 conversation history 做 vector search,用于「我以前解决过这个吗」这类查询。生态中有 tool-specific implementations,可以查对应 ecosystem pages。
按你真正想记住什么来选。如果是「这个 codebase 的 decisions and gotchas」,notes/ folder 就够了。如果是「我跨所有项目告诉过模型的一切」,才需要更重的东西。不要安装你还没有问题需要它解决的 infrastructure。
Part 8: Composing Claude Code and OpenCode
前面几部分把 Claude Code 和 OpenCode 当作 alternatives:选一个,学会它。这是有意的:在复杂化之前,每个概念都必须在任一工具中成立。但掌握 fundamentals 后,更有意思的问题是 composition。两个工具一起用于同一个 project,不只是某个工具失败时的 fallback。它是一种不同工作方式,值得单独讲 mechanics。
The substrate: git worktrees
先讲 patterns 之前的 operational layer;没有它,任何组合都不安全。
两个工具都支持 parallel sessions,但如果两个 agents 同时编辑同一文件,last write wins,你会得到 stomped diffs。修复方式是 git worktrees:每个 worktree 是同一 repo 在不同 branch 上的 checked-out copy,共享同一个 .git directory。两个 agents 位于两个 worktrees,可以并行编辑不同文件,不会碰到同一路径。
# from your main repo directory
git worktree add ../myproject-backend feature/auth-core
git worktree add ../myproject-frontend feature/auth-ui
# now you have two parallel working dirs, two branches
cd ../myproject-backend && claude
# in another terminal
cd ../myproject-frontend && opencode
工作结束后,用 git worktree remove ../myproject-backend 移除 worktree。
file-edit rule 分三层:
| Pattern | Verdict |
|---|---|
| 两个 sessions 同时编辑同一个 file | Bad:last write wins,另一个 session 的 edits 会丢失 |
| 两个 sessions 编辑不同 directories | Good:没有 contention,parallel speedup 真实存在 |
| 一个 session edits、commits,再 hand off 给另一个 | Acceptable:commit 就是 handoff artifact |
Rule of thumb: 先保持一个 task 一个 session。只有当你能清楚指出每个 session 拥有哪些 files 时,才增加第二个。两个 agentic sessions 之间 context-switching 的 cognitive cost 真实存在;只有当工作确实能 partition 时才划算。
让这一切可工作的 shared layer,是项目的 rules 和 skills。两个工具都读取同一个 CLAUDE.md 和同一个 .claude/skills/ directory(Concepts 7 和 9 已覆盖)。项目 conventions 只有一个 source of truth;两个工具消费它。
Pattern 1: Plan / Execute split
agentic coding 中昂贵的认知工作是 planning:读取 codebase、决定 approach、预判 edge cases。便宜的机械工作,是执行一个已经存在的 plan。pricing 也反映了这一点:frontier-tier models 每 token 成本大约比 economy-tier models 高一个数量级,而它们真正值得这个价,是在 planning 上,不是在 implementation 上。
composition 如下:
- 在 plan mode 中打开 Claude Code(Concept 2)。给 brief。让它产出 plan。
- 把 plan 保存到
docs/plans/feature-x.md。 - 在单独 worktree 中打开 OpenCode,指向 economy-tier model(当前 setup 见 opencode.ai/docs/providers)。第一条消息:
read docs/plans/feature-x.md and implement it. - OpenCode 做 file edits、运行 tests、修复 lint。
- (可选)再次打开 Claude Code,在 merge 前 review diff。
plan file 是 contract。它能在 session loss 后保留,编码 architectural decisions,也让便宜 session 不必重做昂贵 thinking。这个 pattern alone 往往能给团队带来大部分他们希望通过「切到便宜模型」得到的 cost savings,同时不牺牲 frontier-model planning 的质量。
Pattern 2: Cross-model review
这是 AI Prompting 的概念 13,从 habit 升级成 architecture。那里你把同一份 draft 丢进两个 chat windows;这里是两个 coding tools cross-check 彼此的 diffs。
不同 models 有不同 blind spots。写出一段 code 的模型,是这段 code 最差的 reviewer,因为它拥有产生原始错误的同一套 blind spots。来自不同 family 的模型(different training data、different reasoning habits)会抓到 author 漏掉的东西。
composition 如下:
- Tool A(任意模型)在自己的 worktree 实现 feature。
- Tool B(不同模型,最好来自不同 family)读取 diff,并把 critique 写到
docs/reviews/feature-x.md。reviewer 不编辑,只产出文字。 - Tool A 读取 review,并决定哪些 points 要处理。
这比听起来更有用。运行在便宜 economy models 上的 reviewers,能抓到很多真实价值:missing edge cases、security oversights、naming inconsistencies、dead code。运行一次 review pass 的美元成本很小;merge 后才发现 bug 的时间成本很大。
当 reviewer 和 implementer 来自不同 model families 时,效果最好:Claude review Claude 会漏掉 GPT 或 DeepSeek 能抓到的东西,反过来也一样。same-family review 仍然比没有 review 强,但价值来自 diversity,而不只是 review 这个动作。
What stays single-tool
composition 有 overhead。两个工具意味着两份 configs、两套 permission lists、两套 notification setups。对于多数短任务(一个 function、quick refactor、bug fix),single session 比跨工具 orchestrating 更快、更简单、更便宜。
当任务足够大,planning 能与 implementation 真正分离;当整个任务都用 frontier model 会浪费;或当独立 review pass 的价值超过成本时,再使用 composition。其他情况,Parts 1–7 的 single-session discipline 就是正确动作。
composition 本质上,是你停止把一个 tool 和一个 model 当作工作单位,开始把 agentic coding session 当作单位后自然出现的做法。
How to actually get good at this
读完这个 crash course 不会让你擅长 agentic coding。使用它才会,而路径是这样的:
你从手动开始。你感受到 friction:每个 approval prompt,每个 "wait, why doesn't it know X." 这些 friction 就是 curriculum。每个 friction 都映射到上面 15 个 concepts 之一:
- "Why does it keep forgetting the auth pattern?" → rules file 缺失或臃肿。
- "Why did it just delete my migrations folder?" → permissions 不够紧。
- "Why is it so slow after an hour?" → context rot;你需要
/compact。 - "Why am I typing the same thing every Monday?" → 那就是 skill。
- "Why did my tests pass locally but break in CI?" → 那就是 hook 或 plugin。
- "Why does exploring the codebase always pollute my conversation?" → 那就是 subagent。
当你遇到问题时再构建 response,而不是提前构建。你的 rules file 应该先有 10 行,然后 12 行,然后 20 行:每一行都由它现在能防止的一个 mistake 赚来。你的 skills folder 应该先有一个 skill,再有十个。你的 hooks/plugins 应该因为没有它们时某件事坏过而存在,不是因为有人说 hooks powerful。
80/20 不是背下 15 个 concepts。它是能足够快地发现某个问题属于哪一类,从而拿起正确 tool。这个 noticing 才是真技能,只能通过花时间观察 agentic coding tools 在真实工作上成功和失败来获得。
The portability dividend. 一旦你在一个工具中建立了这种 noticing,它会迁移。上面的 friction-to-concept map 在 Claude Code 和 OpenCode 中完全相同。先选一个开始,学会它具体 config;当你因为成本、model preference、license,或一个尚不存在的新工具而决定切换时,knowledge 会跟着你走。configs 会变。thinking 不会。
从一个 project 开始。凡是 non-trivial 的事都用 plan mode。看住 context。剩下的会自己长出来。
Quick reference
The 15 concepts in one line each
- Tools take actions, not just answers. 写 brief,不要只提问。
- Plan mode(CC 中 Shift+Tab,OC 中 Tab 到 Plan agent)。任何写入前先做 read-only investigation。
- Permissions discipline。 从手动开始,逐步 codify allow/deny。永远不要 auto-approve
rm -rf。 - Context rot is real。 recall 在 window 填满前很久就退化,而且每一轮都会重新计费整个 context。
/clearvs/compact。 新任务 vs 同任务减负。选错会丢错东西。- Resume sessions。 不用重新解释即可接着做;与 saved plan files 搭配。
CLAUDE.md/AGENTS.md是目录。 低于约 2,500 tokens,references 按需加载。- Slash commands。 当你反复输入同一件事时,用 name 触发 saved prompts。
- Skills。 模型根据 description auto-invoke 的 saved expertise;通过
SKILL.md加 references 实现 progressive disclosure。 - Hooks (CC) / Plugins (OC)。 lifecycle events 上的 deterministic guardrails。生产里不是 optional。
- Subagents。 用于 noisy reads 的隔离 context windows(codebase exploration、doc fetching)。
- MCP, used carefully。 external tools 的标准 protocol;对 stateless services,CLIs 往往胜过 MCP。
- Where to run。 从 terminal 或 IDE plugin 开始,这样能看见 agent 在做什么。
- Personal context library, slowly。 跨项目共享 configs;build from regret, not imagination。
- Memory beyond basics。 内置 resume 加良好 rules file 对多数人足够。需要更多时用
notes/folder。
Command quick-ref
| Want to... | Claude Code | OpenCode |
|---|---|---|
| Initialize project rules file | /init | /init |
| Enter plan mode | Shift+Tab (twice) | Tab (cycle to Plan agent) |
| Wipe conversation, start fresh | /clear | /new (or /clear) |
| Summarize and continue | /compact | /compact (or /summarize) |
| Resume a saved session | claude --resume | /sessions (or /resume) |
| Jump back to a previous message | Esc Esc (or /rewind) | /undo |
| Roll back the model's file edits | Esc Esc (checkpointing) | /undo (needs git) |
| Roll back bash-command file changes | (not tracked) | /undo (whole-tree diff) |
Redo (reverse the last /undo) | (not bundled) | /redo |
| Share session | /share | /share |
File location quick-ref
| What | Claude Code | OpenCode |
|---|---|---|
| Project rules | CLAUDE.md | AGENTS.md (also reads CLAUDE.md as fallback) |
| Project permissions | .claude/settings.json | opencode.json |
| Project commands | .claude/commands/*.md | .opencode/commands/*.md |
| Project skills | .claude/skills/<name>/SKILL.md | .opencode/skills/<name>/SKILL.md (also reads .claude/skills/) |
| Project hooks/plugins | .claude/settings.json (hooks block) | .opencode/plugins/*.{js,ts} |
| Project subagents | .claude/agents/*.md | .opencode/agents/*.md |
| Personal/global rules | ~/.claude/CLAUDE.md | ~/.config/opencode/AGENTS.md |
| Personal commands/skills/agents | ~/.claude/{commands,skills,agents}/ | ~/.config/opencode/{commands,skills,agents}/ |
| MCP servers | .claude/settings.json (mcp block) | opencode.json (mcp block) |
Extension type decision tree
Need to do the same thing repeatedly, manually?
→ Slash command (CC) / Custom command (OC)
Want the model to apply expertise automatically when a task matches?
→ Skill
Need something to happen every single time, no model judgment?
→ Hook (CC) / Plugin (OC)
Need a chunk of work done in isolation so it doesn't pollute main context?
→ Subagent
When something feels wrong
Model apologizing without progress, rewriting the same code,
hallucinating variables, contradicting earlier constraints?
→ Context is poisoned. Stop typing. Run /compact or /clear.
Don't try to fix it with another prompt.
Flashcards Study Aid
Quiz: 50 Questions on the 15 Concepts
一套覆盖本速成课每个概念的完整题库。每个 session 会显示一批新的 18 道题,所以重做时会看到新材料。先在上方选择你的工具,让答案落在你的 toolchain 上。