标签 反模式 下的文章

Claude Code 官方最佳实践:50 条没人告诉你的“核心军规”

本文永久链接 – https://tonybai.com/2026/01/25/claude-code-official-best-practices-50-core-rules

大家好,我是Tony Bai。

在使用 Claude Code 的过程中,你是否遇到过这种情况:

有时候它简直是神,几秒钟就能重构一个复杂的模块;但有时候它又蠢得让人抓狂,甚至会一本正经地写出跑不通的代码,或者把你刚刚纠正过的错误再犯一遍。

为什么?是模型不稳定吗?

不,这通常是因为你的“打开方式”不对

Claude Code 本质上是一个运行在 CLI 环境中的自主智能体(Agentic Coding Environment)。它受限于一个核心物理法则:上下文窗口(Context Window)

  • 上下文满了,它就会“失忆”。
  • 指令不清晰,它就会“幻觉”。
  • 没有反馈,它就会“盲目自信”。

为了帮你跨越从“新手”到“高玩”的门槛,我精读了 Anthropic 刚刚发布的官方最佳实践文档,并结合实战经验,提炼出了这 50 条核心军规

掌握了它们,你就是指挥 AI 军团的编排者(Orchestrator)了。


基础心法——对抗熵增 (Foundational Tips)

核心逻辑: 上下文是稀缺资源,清晰度是最高杠杆。

  1. Clear Task Framing: 开局第一句话决定成败。明确告诉它:Role(角色) + Task(任务) + Context(背景)
  2. Front Load Instructions: 最重要的约束(比如“绝对不要修改配置文件”),必须放在 Prompt 的最前面。
  3. Verification (最高杠杆): 这是最重要的 Tip。 必须给 Claude 一个“验证它自己工作”的方法。
    • ❌ “修复这个 Bug。”
    • ✅ “修复这个 Bug,并编写一个测试用例来验证修复是否成功。”
  4. Provide Screenshots: 涉及 UI 修改,直接粘贴截图。Claude 现在的视觉能力极强,一张图胜过千言万语。
  5. Address Root Causes: 遇到报错,明确告诉它:“不要仅仅消除报错(Suppress),要解决根本原因。”
  6. Plan Mode (Shift+Tab): 复杂任务(涉及 >2 个文件)必须先进 Plan 模式。
    • Explore -> Plan -> Implement
  7. Review the Plan: 在它动手写代码前,先 Review 它的计划。这时候纠偏成本最低。
  8. One-shot vs Plan: 改个拼写错误?直接干。重构模块?必须 Plan。
  9. Specific Context: 不要让它通读整个仓库。用 @ 引用具体文件。
  10. Rich Content: 善用 cat error.log | claude,直接把日志管道喂给它。
  11. Clear Context: 任务做完了?立刻运行 /clear。不要在垃圾堆里盖新楼。
  12. Summarize Before Clear: 如果想保留记忆,先让它 /compact(压缩上下文),再继续。

工程化配置——给 AI 立规矩 (Configuration)

核心逻辑: 不要每次都手动教,把规则固化到文件里。

  1. CLAUDE.md 是宪法: 在根目录创建 CLAUDE.md,这是它每次启动必读的“员工手册”。
  2. Use /init: 运行 /init 命令,让 Claude 自动分析项目并生成初始的 CLAUDE.md。
  3. Prune Ruthlessly: CLAUDE.md 不要写废话!
    • ❌ “请写出优雅的代码。”(浪费 Token)
    • ✅ “使用 npm run test:unit 运行单元测试。”(高价值信息)
  4. Bash Commands: 在文档里告诉它项目特有的命令(如构建、部署脚本)。
  5. Code Style: 明确约定:用 Tab 还是 Space?用 TypeScript 还是 JS?
  6. Import Rules: 告诉它 @src/ 别名指向哪里,避免它瞎猜路径。
  7. Child Directories: 对于 Monorepo,可以在子目录放单独的 CLAUDE.md,它会自动继承。
  8. Permissions Allowlist: 别做“点点点”工程师。用 /permissions 把 ls, grep, npm test 加入白名单。
  9. Sandbox Mode: 对于不信任的任务,开启 /sandbox,让它在隔离环境中撒欢。
  10. Dangerously Skip: 只有在完全可控(断网/沙箱)时,才使用 –dangerously-skip-permissions。
  11. CLI Tools: 安装 gh (GitHub CLI),让 Claude 能直接提 PR、看 Issue。
  12. MCP Connect: 使用 claude mcp add 连接 Postgres 或 Notion。数据不再是孤岛。
  13. Learn CLI: 不知道怎么用某个工具?让 Claude 先运行 tool –help 自学。

技能与自动化——扩展能力 (Skills & Automation)

核心逻辑: 把重复的流程封装成“技能”,把 AI 集成到流水线。

  1. Skills Definition: 在 .claude/skills/ 下创建 SKILL.md,定义可复用的能力。
  2. Domain Knowledge: 把复杂的业务逻辑(如“订单状态流转规则”)封装成 Skill,用到时才加载。
  3. Disable Model Invocation: 对于高风险 Skill,设置 disable-model-invocation: true,强制人工确认。
  4. Custom Subagents: 定义专门的 .claude/agents/security-reviewer.md。
    • 让它扮演“安全专家”,只负责 Review,不负责写代码。
  5. Delegate to Subagents: 在主会话中说:“用 security-reviewer 检查刚才的代码。”
  6. Install Plugins: 运行 /plugin,去市场找现成的技能包(如 Python 代码分析)。
  7. Code Intelligence Plugin: 必装!给 Claude 提供“跳转定义”和“查找引用”的能力(基于 LSP)。
  8. Hooks: 设置 .claude/settings.json 中的 Hooks。
    • 例如:每次 Auto-fix 后自动运行 Lint。
  9. Headless Mode: claude -p “prompt”。这是自动化的神器。
  10. CI Integration: 在 GitHub Actions 里用 Headless Mode 自动 Review PR。
  11. Structured Output: 使用 –output-format json,让脚本能解析 Claude 的回答。
  12. Fan-out Pattern: 批量修改 100 个文件?写个 Shell 脚本循环调用 claude -p。

避坑指南——反模式 (Anti-patterns)

核心逻辑: 识别“失败的味道”,及时止损。

  1. The Kitchen Sink Session: 试图在一个 Session 里修 Bug、写新功能、又写文档。
    • 后果: 上下文污染,智商直线下降。
    • 解法: 一事一议,做完就 /clear。
  2. Over-correcting: 纠正了两次还不对?
    • 后果: 错误路径被强化,越改越错。
    • 解法: 别纠缠!直接 /clear,优化 Prompt 后重来。
  3. The Trust-then-Verify Gap: 还没测试就觉得“看起来是对的”。
    • 后果: 生产环境事故。
    • 解法: 没有 Pass 测试的代码,一行都别信。
  4. The Infinite Exploration: 让它“调查一下代码库”,不给范围。
    • 后果: 读了几百个文件,Token 耗尽,还没开始干活。
    • 解法: 限制搜索范围,或者用 Subagent 去做调研。
  5. Vague Error Reporting: 只说“不行”或“报错了”。
    • 后果: Claude 只能瞎猜。
    • 解法: 粘贴完整的 Stack Trace。

高阶操作——神级技巧 (Pro Moves)

  1. Resume Session: 昨天没干完?claude –resume 接着聊。
  2. Rename Session: 用 /rename 给会话起个好名字(如 feat-login-oauth),方便找回。
  3. Rewind (Esc+Esc): 走错方向了?双击 Esc 回滚到上一步,比改代码快。
  4. Let Claude Interview You: 不知道怎么写 Spec?
    • Prompt:“我想做个 X 功能。请作为一个资深架构师,向我提问,直到你觉得信息足够写出 Spec 为止。”
  5. Self-Correction Loop: 让它自己改自己的作业。
    • Prompt:“分析你刚才生成的代码,找出 3 个潜在的 Edge Case,并修复它们。”
  6. Model Tier Selection: 简单的 Lint 修复用 Haiku(快且便宜),架构设计用 Opus(聪明但贵)。
  7. Parallel Sessions: 开两个终端。一个写代码(Writer),一个做 Review(Reviewer)。左右互搏,质量倍增。
  8. Develop Intuition: 最后的建议——多用。建立对“上下文容量”和“模型能力边界”的体感。

小结:从 直觉 到 方法论

刚开始使用 Claude Code,你可能靠的是直觉。但要在大规模工程中稳定产出,你必须依靠方法论

这 50 条军规,就是从“抽盲盒”走向“工业化生产”的桥梁。掌握了它们,你就不再是被动的 User,而是这支硅基军团的 Commander

资料链接:https://code.claude.com/docs/en/best-practices


深度实战:构建你的“AI 原生工作流”

Tip 只是冰山一角。真正的威力在于将这些技巧组合成一套“开发工作流”

在我的极客时间专栏AI 原生开发工作流实战中,我将带你实战演示:

  • CLAUDE.md 实战:如何从零编写一个完美的、模块化的项目宪法?
  • 驾驭Claude Code:实现工作流自动化
  • 从“AI使用者”进化为规范驱动开发的“工作流指挥家”

别再用蛮力写代码了。扫描下方二维码,学会用 AI 的杠杆。


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

Go 的“显式哲学”为何在接口上“食言”了?—— 探秘隐式接口背后的设计智慧

本文永久链接 – https://tonybai.com/2026/01/14/go-explicit-philosophy-implicit-interfaces-design-wisdom

大家好,我是Tony Bai。

“Go 倾向于显式、冗长的代码,而不是‘魔法’。那么,为什么接口实现却是隐式的呢?这让理解代码变得困难多了,简直让我抓狂。”

前不久,一位 Gopher 在 Reddit 上发出了这样的灵魂拷问。这不仅仅是一个新手的问题,它触及了 Go 语言设计中最有趣、也最常被误解的一个矛盾:在一个崇尚“显式”的语言里,为什么最核心的抽象机制(接口)却选择了极致的“隐式”?

相比于 Java 的 implements 或 Rust 的 impl for,Go 的这种“只要方法匹配,就自动实现”的 Duck Typing 风格,确实显得格格不入。

是 Go 的设计者们“双标”了吗?还是这背后隐藏着某种更深层的、我们尚未完全领悟的智慧?本文将带你深入 Go 的设计哲学,揭开这个“反直觉”设计背后的真相。

显式实现的“原罪”——被倒置的依赖

要理解 Go 为何选择隐式,我们首先要看看“显式实现”带来了什么问题。在 Java 或 C# 中,如果你想让你的类实现一个接口,你必须在定义类的时候就显式声明:

// Java
public class MyReaderImpl implements MyReaderIntf { ... }

这看起来很清晰,但它引入了一个致命的耦合:生产者(具体类型)必须知道消费者(接口)的存在。

这意味着:

  1. 你无法为第三方类型实现接口:如果你使用了一个第三方库的结构体,而你想让它实现你自己定义的接口,你做不到。因为你无法修改第三方库的源码去加上 implements MyInterface。
  2. “上帝接口”的诞生:为了规避第1点,库的设计者倾向于预定义庞大的、包罗万象的接口(如 IUser),强迫所有实现者都去依赖这个庞大的契约。这导致了接口定义的早产不必要的依赖

Go 的设计者们敏锐地捕捉到了这一点。他们认为,接口应当由消费者(Consumer)定义,而不是生产者(Producer)。

解耦的艺术——消费者定义的接口

Go 的隐式接口,彻底反转了这种依赖关系。

在 Go 中,具体的类型(如struct)不需要知道接口的存在。它只需要专注地实现它该有的方法。而接口的定义,可以发生在任何时间、任何地点,通常是在使用方(调用者)的代码中。

正如 Reddit 上高赞评论所言:

“Define interfaces at the receiving end.”(在接收端定义接口)

这带来了前所未有的灵活性:

  • 事后抽象:你可以先写具体的实现代码。等到某一天,你发现需要对这部分逻辑进行抽象或测试时,你可以在调用方就地定义一个接口,而无需修改原有的具体类型代码。
  • 小接口哲学:因为接口是消费者按需定义的,所以 Go 鼓励定义极小的接口(如 io.Reader 只有一个方法)。如果必须显式声明,开发者会倾向于定义大接口以减少声明的繁琐,而隐式接口则让 interface{ Read(…) } 这种微型契约变得轻量且自然。

这就是隐式的代价换来的价值:彻底的解耦。 它打破了“实现”与“抽象”之间的强绑定,让代码的演进变得更加自由。

测试与 Mock 的天堂:只 Mock 你关心的

在 Java 或 C# 这样的显式接口语言中,如果你要测试一个依赖了 Database 类的函数,你通常面临两个选择:

  1. 引入 Database 所在的庞大包。
  2. 为了测试,不得不为 Database 定义一个包含其所有方法的 IDatabase 接口,哪怕你只用了其中一个 Query 方法。这被称为“接口污染”。

而在 Go 中,隐式接口允许我们在“测试现场”定义接口。这被称为“最小化 Mock”

假设有这样一个场景:我们需要编写一个 WeatherReporter(天气播报员),它依赖一个庞大的第三方天气 SDK 来获取数据。

第三方库代码(我们无法修改,且很庞大):

// thirdparty/weather.go
type HeavyWeatherClient struct { ... } // 包含几百个方法
func (c *HeavyWeatherClient) GetTemp(city string) float64 { ... } // 我们只用这一个
func (c *HeavyWeatherClient) GetHumidity() float64 { ... }
func (c *HeavyWeatherClient) GetWindSpeed() float64 { ... }
// ... 还有几百个其他方法 ...

我们的业务代码:

// reporter.go
// 注意:这里我们直接接受具体的 HeavyWeatherClient,或者任何实现了 GetTemp 的东西
func ReportTemperature(client interface{ GetTemp(string) float64 }, city string) {
    temp := client.GetTemp(city)
    if temp > 30 {
        fmt.Println("It's hot!")
    }
}

我们的测试代码(Test 文件):

在测试中,我们完全不需要引入那个庞大的 thirdparty 包,也不需要 mock 那几百个无关的方法。我们只需要在测试文件里定义一个极小的接口:

// reporter_test.go

// 1. 定义一个只包含我们所用方法的“本地接口”
// 甚至都不需要给它起名字,匿名接口也可以
type mockFetcher struct{}

func (m *mockFetcher) GetTemp(city string) float64 {
    return 35.0 // 返回一个假数据
}

func TestReportTemperature(t *testing.T) {
    mock := &mockFetcher{}

    // 2. Go 的隐式特性发挥作用:
    // mockFetcher 并没有显式声明实现了任何接口,
    // 但它拥有 GetTemp 方法,所以它可以被传入 ReportTemperature!
    ReportTemperature(mock, "Beijing")

    // 验证逻辑...
}

注:关于 Mock 与 Stub 的严谨区分

细心的读者可能发现,严格来说,上例中的 mockFetcher 更像是一个 Stub (桩)——它只返回固定数据,不验证调用行为。但在 Go 社区的工程实践中,我们习惯将这类用于替换真实依赖的测试替身统称为 Mock。为了方便理解,本文沿用了这一通俗叫法。

这就是“天堂”的含义:你可以忽略对象 99% 的复杂性,只为你关心的那 1% 编写 Mock。这种按需定义 (Ad-hoc) 的能力,让 Go 的单元测试变得极其轻量和纯粹,彻底摆脱了对重型 Mock 框架的依赖。

警惕:不要为了测试而“预定义”接口

这里有一个新手常犯的错误:为了方便测试,在生产代码中为每一个 Struct 都配对写一个 Interface(例如 type UserServiceImpl struct 和 type UserService interface)。

这是一个反模式(Anti-pattern)。 Go 的哲学之一是不要在生产者(Producer)端定义接口,要在消费者(Consumer)端定义接口。如果你在生产代码中定义了一个只被自己实现的接口,你只是在增加代码的复杂度和阅读成本,而没有带来任何解耦的实际价值。

正确的做法

  • 如果 UserService 是你自己写的,且逻辑简单(纯逻辑,无 I/O),直接测试 Struct 本身即可,不需要接口
  • 如果 UserService 确实包含数据库操作,需要被 Mock,那么请在调用它的人那里(或者在测试文件里)定义接口,而不是在 UserService 旁边定义一个“没用”的接口。

记住:接口通过解耦来促进测试,但不要为了测试而强行制造接口。

如何应对“隐式”带来的困扰?

当然,提问者的困惑是真实的:“我怎么知道这个结构体实现了哪些接口?”

这种“不可知性”确实是隐式接口的副作用。但在 Go 的工程实践中,我们有成熟的应对方案:

  1. IDE 的力量:现代 IDE(如 GoLand, VS Code,甚至是安装了插件的Vim等)已经完美解决了这个问题。简单的“Find Usages”或“Go to Implementations”就能列出所有匹配的接口。工具弥补了人类肉眼的局限。
  2. 编译期断言:如果你是库的作者,你需要向用户保证你的类型(比如*MyStruct)实现了某个标准接口(例如 io.Writer),为了防止未来修改代码时不小心破坏了这个契约,你可以使用这行经典的“黑魔法”代码:
// 这是一道“编译期防线”
var _ io.Writer = (*MyStruct)(nil)

细心的读者可能会发现,这行代码强制 MyStruct 所在的文件 import 了 io 包。没错,这确实引入了依赖。

但与 Java 强制性的 implements 不同,Go 的这种耦合是可选的防御性的。

  • 它不是程序运行的必要条件,而是一个写在源码里的“编译期测试用例”
  • 它通常只用于向标准库或核心框架的稳定接口看齐。对于业务层那些灵活的、消费者定义的接口,我们通常不需要写这行代码,从而保持代码的纯净与解耦。

小结:显式的代码,隐式的契约

回到最初的问题:Go 违背了“显式”的哲学吗?

答案是:没有。Go 追求的是“行为”的显式,而非“类型分类”的显式。

Go 让你显式地编写方法,显式地处理错误,显式地进行类型转换。但在“谁实现了谁”这种元数据层面,Go 选择了隐式,因为它认为“鸭子类型” (If it walks like a duck…) 才是对软件组件交互最自然、最解耦的描述。

Go 的隐式接口,不是为了省去敲 implements 这几个字母的懒惰,而是一场关于软件架构解耦的深谋远虑。它赋予了 Go 语言一种独特的“结构化动态性”——既有静态语言的安全,又有动态语言的灵活。这,正是 Go 设计哲学的精妙所在。

资料链接:https://www.reddit.com/r/golang/comments/1pa6t2m/go_prefers_explicit_verbose_code_over_magic_so


你的接口设计习惯

Go 的隐式接口虽然灵活,但也给了开发者极大的自由度。在你的项目中,你是习惯先定义接口再写实现(顶层设计),还是先写实现再按需提取接口(事后抽象)?你是否也曾陷入过“接口定义泛滥”的陷阱?

欢迎在评论区分享你的设计心得或踩坑故事! 让我们一起探讨如何用好这把“双刃剑”。

如果这篇文章解开了你对 Go 接口的困惑,别忘了点个【赞】和【在看】,并转发给你的开发伙伴,一起感受 Go 的设计之美!


还在为“复制粘贴喂AI”而烦恼?我的新专栏 AI原生开发工作流实战 将带你:

  • 告别低效,重塑开发范式
  • 驾驭AI Agent(Claude Code),实现工作流自动化
  • 从“AI使用者”进化为规范驱动开发的“工作流指挥家”

扫描下方二维码,开启你的AI原生开发之旅。


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 AI原生开发工作流实战 从 0 开始构建 Agent Harness Go语言精进之路1 Go语言精进之路2 Go语言第一课 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com
这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats