Claude-Code-智能体编程-一-
Claude Code 智能体编程(一)
原文:Agentic Coding with Claude Code
译者:飞龙
贡献者
作者简介
Eden Marco 是 Google Cloud 的 LLM 专家和 LangChain 大使,拥有多年软件工程和云架构经验。他是 Orca Security 的首批工程师之一,拥有以色列理工学院计算机科学学士学位,并在 Reichman University 任教。Eden 基于真实世界的经验创建实用的、生产就绪的课程。
审稿人简介
Pablo Garner 是 Champions (UK) plc 的 IT 和 AI 主管,负责基础设施建设和 AI 驱动的内部平台开发。他在 IT 和计算领域拥有八年以上经验,专注于应用 AI、自动化和云架构。他正在完成 NVIDIA AI 工程师六级课程,并作为外部红队研究员为 Anthropic 的 AI 安全研究项目做出过贡献。Pablo 构建智能体驱动系统,并在 p4blo.dev 分享他的工作,专注于实际 AI 实施。
感谢 Packt 团队给我担任技术审稿人的机会,也感谢我的伴侣 Jade 和孩子们 Storm 与 Saint 的支持与鼓励。
Iago Cavalcante 是一名充满热情的软件开发者,关注技术对人们生活和业务产生的影响。他使用 Elixir、React、React Native、Vue.js 和 TypeScript 进行开发,专注于可扩展性和代码质量。他居住在巴西贝伦,共同创立了 DevsNorte,这是一个致力于发展当地技术生态系统的社区。他相信回馈社区:分享和向他人学习越多,作为专业人士和个体成长得就越多。他参与开源项目协作并撰写技术文章以分享知识。他是 Enzo 的骄傲父亲,也是 Karla 的丈夫,他将家庭视为每一项成就背后的基石。他热爱交流想法、倾听不同观点并持续学习。
通过实战学习更进一步
如果您想超越从书籍中学习基础知识,请查看我们的实战研讨会,它们提供来自全球知名讲师的清晰、实时、实用的指导,并有机会解答您的疑惑。
新研讨会每两周新增一次。
扫描下方二维码查看即将举办的研讨会并注册以获取独家优惠和折扣。
前言
生成式 AI 和编码代理正在迅速改变软件的构建方式。Claude Code、Cursor 和 LangChain 深度代理等工具不再局限于简单的基于提示词的交互。它们可以在整个代码库中操作,集成外部工具,并执行长时间运行的多步骤工作流。随着这些系统变得越来越强大,理解它们如何工作以及如何控制它们变得至关重要。
本书专注于建立对 Claude Code、代理工作流以及使现代编码代理高效运行的底层概念的深刻且实用的理解。贯穿全书的核心主题是上下文工程,它解释了代理在推理和行动时如何构建、管理和使用上下文。随着代理变得更加复杂和工具驱动,恰当的上下文处理直接影响性能、成本、可靠性和一致性。
在本书中,您将学习 Claude Code 如何与代码库交互,如何对其进行配置以供日常使用,以及如何使用 Model Context Protocol (MCP) 对其进行扩展。您将探索 GitHub Actions 自动化、结构化规划、多代理工作流、子代理、输出样式和代理技能。本书还深入探讨了架构层面的主题,包括深度代理如何运作以及长时程工作流在实践中如何实现。
本书不仅关注表层用法,更旨在帮助您理解这些系统的设计原理以及它们为何会表现出此类行为。通过将实用示例与深层架构洞察相结合,旨在赋予您有效使用现代编码代理的技能,以及随着领域持续演进所需的适应性理解。
本书适读对象
本书面向希望超越基于聊天的 AI,利用 Claude Code 和 MCP 构建代理化、自动化开发工作流的开发人员和工程师。适合具有软件工程经验的应用程序开发人员,他们希望将上下文感知的 AI 代理集成到终端和 IDE 中,自动化复杂的编码任务,并设计可扩展的多代理系统。
对于与现代开发工作流紧密协作的 AI 工程师和生成式 AI 从业者,本书也将大有裨益。
为了最大程度地利用本书,您应具有使用 Python 或 TypeScript 编写和调试代码的经验,熟悉 Git 和开发环境的使用,并理解 LLMs、RAG 和代理等核心生成式 AI 概念。本书非入门级读物,假设读者具备软件开发经验。
本书内容
-
第 1 章,《上下文工程》,介绍上下文工程并解释其在构建现代 AI 代理时为何至关重要。涵盖上下文如何从提示词工程演变而来,如何在复杂系统中增长,以及不当的上下文处理如何影响性能和成本。本章还探讨系统提示词以及使用
Claude Code进行实用上下文管理的方法。 -
第 2 章,《
Claude Code要点》,提供Claude Code的实用介绍,并解释其如何与代码库交互。涵盖项目初始化、CLAUDE.md文件、权限和上下文管理。本章还介绍MCP、规格驱动设计,并开始构建贯穿全书的 HookHub 项目。 -
第 3 章,《
Claude Code入门——核心命令速览》,专注于配置Claude Code以供日常使用。涵盖定价和认证、斜杠命令、用户级和项目级配置,以及与Cursor的集成。本章还探讨钩子、检查点、自定义命令,以及语言服务器协议的作用。 -
第 4 章,《使用
MCP服务器和插件扩展Claude Code》,解释Model Context Protocol及其如何标准化 AI 应用程序与外部工具之间的集成。涵盖MCP架构,包括主机、客户端和服务器,并演示如何配置本地和远程MCP服务器。本章还涉及上下文管理、性能考量和基于插件的扩展。 -
第 5 章,《使用
Claude Code和GitHub自动化开发工作流》,探讨Claude Code与GitHub之间的集成。涵盖仓库配置、拉取请求和议题自动化,以及用于工作流执行的GitHub Actions。本章还解释YAML工作流文件如何定义事件驱动的自动化。 -
第 6 章,《
Claude Code规划与多代理工作流》,探讨使用规划和协调多代理执行的结构化代理工作流。解释规格驱动开发如何提高可预测性,以及多个代理如何在同一代码库中协作。 -
第 7 章,《使用
Claude Code子代理》,介绍Claude Code子代理,并解释它们如何实现结构化和隔离的工作流。涵盖自定义子代理配置、上下文流,以及使用无限代理循环模式进行并发执行。 -
第 8 章,《创建和自定义输出样式》,探讨输出样式如何塑造
Claude Code的响应。涵盖创建和限定自定义样式的作用域、诸如YAML之类的结构化格式,以及在样式定义中自动化行为。本章还解释如何管理角色和会话配置。 -
第 9 章,《理解代理技能》,探讨代理技能作为扩展 AI 代理能力的机制。涵盖基础概念、在
Claude Code和LangChain DeepAgent中的实用用法,以及调用技能时的内部上下文流。本章以一个真实的实现示例结束。 -
第 10 章,《使用
Claude Code桌面版》,解释如何在桌面应用程序中使用Claude Code。涵盖本地模式和云模式之间的切换、使用Git工作树运行并行代理,以及跨环境协调特性分支。 -
第 11 章,《理解深度代理》,探讨深度代理及其在长时程任务执行中的作用。定义深度代理的特征,并分析
LangChain深度代理框架,包括其架构和执行模型。
如何最大程度利用本书
本书假设读者具备软件开发经验和生成式 AI 概念。开始阅读前,您应能熟练使用 Python 或 TypeScript 编写和调试代码,从终端运行程序,并操作代码库。需要具备基本的 Git 知识,如克隆仓库和提交更改。您还应了解虚拟环境和环境变量。
需要熟悉 大语言模型 (LLMs) 以及代理、RAG 和 ReAct 等核心概念。您应曾与 LLM 交互过,并至少构建过一个简单的代理。本书不涵盖入门级编程或生成式 AI 入门主题。
为跟随实操示例,您需要一个配备 Node.js 和简单 Next.js 设置的开发环境(早期章节会介绍)。您还需要访问 Claude Code 并完成相应的认证和定价配置。部分需要安装和配置 GitHub CLI、操作 GitHub 仓库并使用 GitHub Actions。后续章节涉及配置本地和远程 MCP 服务器,以及在 Cursor 和 Claude 桌面应用程序中运行 Claude Code。
建议您按照示例逐步操作,并在介绍配置时进行尝试。本书内容循序渐进,多章依赖于前文建立的项目和设置(包括 HookHub 项目)。
本书包含的示例和截图改编自作者的原始课程材料,引用了为教学目的创建的代码库。
免责声明
本书为独立出版物,与 Anthropic, PBC 或其任何子公司或关联公司无任何关联、背书、赞助或官方关联关系。“Claude”、“Claude Code” 和 “Anthropic” 为 Anthropic, PBC 的商标或注册商标。书中提及的所有其他商标均为其各自所有者的财产。
作者为 Google LLC 员工。然而,本书为个人项目,不代表 Google LLC、Google Cloud、Alphabet Inc. 或其任何子公司或关联公司的观点、意见或官方立场。本书未获 Google 以任何形式背书、赞助或官方关联。“Google”、“Google Cloud” 及相关标识为 Google LLC 的商标。
本书内容仅基于作者的个人经验、独立研究和公开文档。书中表达的观点、意见和解读仅代表作者个人,不代表 Anthropic PBC、Google LLC 或任何其他组织的官方立场、策略或意见。
尽管已尽最大努力确保所呈现信息的准确性和完整性,作者不对内容的完整性、准确性、可靠性或适用性作出任何明示或暗示的保证或陈述。AI 工具及其相关 API、功能和特性发展迅速,本书信息出版后可能过时。
对于因使用或依赖本书所含信息而直接或间接引起的任何损害、损失或后果,作者和出版商概不负责。建议读者查阅 Anthropic 官方文档 docs.anthropic.com 以获取最新、最权威的信息。
下载示例代码文件
本书包含完整的可下载代码包,涵盖所有章节使用的示例项目和文件。建议下载该代码包,以便顺利跟随学习并试验示例。
将该代码包作为实践起点。对其进行修改、扩展,并在阅读各章节的过程中应用所学,创建自己的变体。
获取代码包
如果您直接从 Packt 购买了本书:
-
访问
packtpub.com -
点击 个人资料图片 并选择 您的订单
-
找到本书并点击 下载代码
如果您从 Amazon 或任何其他渠道合作伙伴处购买了本书:
-
访问 packtpub.com/unlock 或扫描以下二维码
-
搜索本书
-
注册或登录您的免费 Packt 账号
-
上传购买凭证并在本地下载代码包
使用须知: 您可自由使用和修改此代码用于个人学习和非商业项目。
下载彩色图片
我们还提供包含本书所用截图和图表彩色版本的 PDF 文件。您可在此下载:packt.link/gbp/9781806022595。
本书约定
本书使用多种文本约定。
CodeInText:表示文本中的代码词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 X/Twitter 账号。例如:“通过初始化 CLAUDE.md 文件来完成此操作,以便将其添加到项目上下文中。”
代码块如下所示:
add_context() {
local context_ref="$1"
grep -qxF "$context_ref" "$CLAUDE_MD" || echo "$context_ref" >>
"$CLAUDE_MD"
}
任何命令行输入或输出均按如下方式书写:
npx create-next-app@latest
粗体:表示新术语、重要单词或屏幕上出现的单词。例如,菜单或对话框中的单词会以此形式出现在文本中。例如:“暂时选择 Yes,并选择本会话期间不再询问。”
警告/重要提示
警告或重要说明显示为此样式。
提示/技巧
提示和技巧显示为此样式。
联系我们
欢迎读者反馈。
一般反馈:若您对本书任何方面有疑问或有一般性反馈,请发送邮件至 customercare@packt.com,并在邮件主题中注明书名。
勘误:尽管我们已竭尽全力确保内容准确,但错误难免。若您发现本书有误,烦请报告给我们。请访问 www.packt.com/submit-errata,点击 提交勘误 并填写表单。
盗版:若您在互联网上发现我方作品的任何非法副本,烦请提供网址或网站名称。请联系 copyright@packt.com 并附上相关链接。
有意成为作者:若您在某主题有专长,并有意撰写或参与著作,请访问 Packt 官网了解详情。
分享您的想法
读完《Agentic Coding with Claude Code》后,我们非常期待听到您的想法!扫描下方二维码直达本书的 Amazon 评价页面,分享您的反馈。
您的评价对我们和技术社区至关重要,将帮助我们确保持续提供优质内容。
随书免费福利
本书附带免费福利,旨在支持您的学习并帮助您有效应用所学知识。立即激活以获取即时访问权限(激活步骤见“如何解锁”部分)。
以下是购买本书可即时解锁的福利速览:
如何解锁
扫描二维码(或访问 packtpub.com/unlock),按书名搜索,确认版本,然后按照页面步骤操作。
第一部分:上下文工程与 Claude Code 基础
在第一部分中,您将建立对上下文工程的清晰实用理解,并知晓其在使用现代 AI 编码代理时的重要性。我们将探讨从简单的提示工程转向结构化上下文管理如何改变代理的设计与使用方式。您将探索上下文的创建方式、其随时间增长的机制,以及管理不善对性能、成本和可靠性的影响。
在奠定概念基础的同时,您将直接上手使用 Claude Code。通过指导性示例,您将了解它如何解读代码库、构建工作上下文,并将该上下文应用于实际开发任务。读完本部分,您将对 Claude Code 的理论与日常操作有扎实的理解。
本部分包含以下章节:
-
第 1 章,上下文工程
-
第 2 章,Claude Code 要义
-
第 3 章,Claude Code 入门——核心命令巡礼
1 上下文工程
上下文工程简介
在本节中,我们将深入探讨什么是上下文工程。如果你一直在使用 AI 代理,可能还涉及 Cursor 和 Claude Code 等编码代理,或者你甚至为公司或个人用途开发过 AI 代理,你可能知道这一切归根结底就是向 LLM 发送一个提示词,并在其周围进行大量的工程化工作。
称 Cursor 和 Claude Code 等应用仅仅是围绕 LLM 的封装确实有几分道理。然而,构建真正优秀的封装需要大量的深度知识和大量的工程工作。另一个常用于指代这种环绕系统的术语是 agent harness(代理框架/挽具)。框架是围绕 LLM 的编排层。它负责管理工具调用、控制代理循环、处理错误、执行护栏机制,以及最重要的是,决定在每一步将什么上下文发送给模型。
在实践中,大多数真正的工程工作并不在 LLM 调用本身内部,而是在其周围。模型调用通常很简单。决定代理能否可靠工作的是周围系统如何管理状态、工具、记忆和上下文。这是因为对 LLM 的调用总是伴随着上下文,而这些上下文来自各种来源和正在进行的进程。
例如,上下文可能来自多个地方:
-
它可以来自应用程序的开发者
-
它可以来自用户
-
它可以来自用户的过往交互、工具调用或其他外部数据
每天都会增加新的上下文来源,上下文的数量也在不断增加。将正确且相关的上下文发送给 LLM 并不像早期我们想象的那么简单。
从提示词工程到上下文工程
在早期,我们认为提示词工程就足够了。我们以为编写一些花哨的提示词就能解决问题,给我们想要的结果。然而,问题在于提示词是静态的,而上下文是极其动态的。
如果上下文是动态的,那么构建正确的上下文也需要一个动态系统。这不再仅仅关乎编写静态提示词。这就是我们进入上下文工程领域的原因。它是提示词工程的自然演进,但它是一个深得多的概念。
为什么上下文对代理至关重要
我们都知道 “垃圾进,垃圾出” 这句格言。这是代理系统表现不如预期的最常见原因之一。它们只是没有被提供正确的上下文。
LLM 无法读取我们的思想。我们需要给它们正确的信息。顺便说一句,这不总是仅指信息或数据。有时我们需要给它们正确的工具,以便它们获取其他信息、采取行动并为我们执行任务。
图 1.1 – LLM 上下文窗口(改编自 LangChain 讨论的概念,www.langchain.com)
LLM 在推理方面变得越来越强。我们有了工具调用,并且可以构建运行工具、调用工具、获取输出并循环直到任务完成的 AI 代理。
图 1.2 – LLM 工具调用循环(改编自 LangChain 讨论的概念,www.langchain.com)
然而,当涉及到长期运行和复杂的任务时,我们经常会累积来自工具调用的反馈。
这导致上下文窗口不断增长,被工具调用结果和中间输出填满。
图 1.3 – 多轮对话中的上下文增长(改编自 LangChain 讨论的概念,www.langchain.com)
这会导致几个问题:
-
上下文窗口可能超出其大小限制
-
成本和延迟增加
-
代理性能开始下降
如果不采取措施,这种退化是不可避免的。最近的讨论探讨了长上下文在实践中为何会失败,以及随着无关或冲突信息的累积,退化如何逐渐显现。欲了解更深入的讨论,请参阅 Dan Breunig 的这篇优秀博客 “How Long Contexts Fail” (www.dbreunig.com/2025/06/22/how-contexts-fail-and-how-to-fix-them.html)。如果允许上下文在没有结构、选择或控制的情况下增长,代理系统中将开始出现各种问题,例如:
-
上下文中毒:当工具调用或 LLM 调用产生的幻觉进入上下文并开始影响未来的输出
-
上下文混淆:当不必要的上下文影响响应,即使它与任务无关
-
上下文冲突:当上下文的不同部分相互矛盾
在下一节中,我们将讨论更好的上下文工程技术。其中一些技术由应用程序开发者实现,例如在 Claude Code 等工具中。其他技术则在用户端。
作为 Claude Code 的用户,我们对最终发送给 LLM 的上下文以及我们收到的回答有很大影响。这意味着即使是非开发人员,如果想从 AI 系统和 AI 代理获得更好的响应,也需要理解上下文工程。
Claude Code 等编码代理是上下文工程技术如何同时应用于开发者端和用户端的绝佳例证。这正是我们将在下一节中探讨的内容,以及如何更好地设计我们的上下文。
Claude Code 及其上下文工程策略
在本节中,我们将讨论 Claude Code、其上下文工程理念,以及 Claude Code 如何应对这些挑战。Claude Code 通过实现所有四种方法来应用这些上下文工程策略,它们如下:
-
编写上下文:持久化记忆系统
-
选择上下文:智能上下文检索与注入
-
压缩上下文:高效的上下文表示与摘要
-
隔离上下文:多代理与作用域上下文管理
Figure 1.4 – Categories of context engineering (adapted from concepts discussed by LangChain, www.langchain.com)
让我们从第一个策略开始。
策略 1:编写上下文与持久化记忆
第一个策略是编写上下文及其持久化记忆架构。Claude 拥有多层记忆系统,Claude Code 实现了三层记忆层级,在使用 Claude Code 编码时,能跨会话持久化上下文。
-
首先是项目记忆 (
./CLAUDE.md)。这是团队共享的上下文,包含项目架构、规范或与特定项目相关的任何内容。这类记忆受版本控制,所有团队成员均可访问。# Project Context ## Architecture Overview This is a microservices application using: - Node.js with Express for API services - React with TypeScript for frontend - PostgreSQL with Prisma ORM - Redis for caching ## Coding Standards - Use functional components with hooks - Implement error boundaries for all route components - Follow RESTful API conventions - Write unit tests for all business logic -
然后是用户记忆 (
~/.claude/CLAUDE.md)。这存储在用户的主目录下的claude目录中的CLAUDE.md文件内。它包含该用户在所有项目中的个人偏好和快捷方式。它不会提交到 GitHub,且专属于特定用户。每个用户在此处的值都不同,且会跨越所有 Claude Code 会话持久保存。# Personal Development Preferences ## Code Style - Always use explicit return types in TypeScript - Prefer const assertions over type annotations - Use descriptive variable names, avoid abbreviations ## Workflow Shortcuts - When writing tests, use Jest with React Testing Library - Always run `npm run lint` before commits - Prefer composition over inheritance -
最后是动态记忆导入。这些允许我们使用
@符号和语法从其他记忆文件导入内容。这类似于将常规上下文加载到 Claude Code 中,但这一次我们可以拥有包含特定信息的专用记忆文件,并在我们的记忆文件中引用它们。# In any CLAUDE.md file @path/to/memory/file.md @./relative/path/context.md @~/global/user/context.md
我们还可以通过编写脚本,根据 Git 分支动态更新上下文来自定义行为。然后将此脚本连接到上下文切换钩子,构建更具适应性的工作流。
一个需要牢记的重要细节是,我们应避免重复向 CLAUDE.md 追加相同的上下文引用。如果脚本在每次运行时仅使用 >>,文件将因重复条目而无限增长。为防止这种情况,我们添加了一个小的保护措施,在追加前检查上下文引用是否已存在。
以下是避免重复导入的改进版脚本:
# Script to dynamically update context based on git branch
#!/bin/bash
# context-switcher.sh
# Dynamically load relevant context based on user query
# Safe against duplicate imports
CLAUDE_MD="CLAUDE.md"
# Create CLAUDE.md if it doesn't exist
touch "$CLAUDE_MD"
add_context() {
local context_ref="$1"
grep -qxF "$context_ref" "$CLAUDE_MD" || echo "$context_ref" >> "$CLAUDE_MD"
}
# --- Branch-based context ---
branch=$(git branch --show-current 2>/dev/null)
case $branch in
"feature/auth-"*)
add_context "@./context/auth-system.md"
;;
"feature/payment-"*)
add_context "@./context/payment-flow.md"
;;
"hotfix/"*)
add_context "@./context/production-hotfix.md"
;;
esac
# --- Query-based context ---
user_input="$1"
if [[ -n "$user_input" ]]; then
if [[ $user_input == *"database"* || $user_input == *"migration"* ]]; then
add_context "@./context/database-context.md"
elif [[ $user_input == *"API"* || $user_input == *"endpoint"* ]]; then
add_context "@./context/api-context.md"
elif [[ $user_input == *"frontend"* || $user_input == *"component"* ]]; then
add_context "@./context/frontend-context.md"
fi
fi
关键变化在于 add_context 辅助函数。它使用 grep -qxF 检查上下文引用是否已存在于 CLAUDE.md 中。如果存在,则不追加任何内容。这使得脚本具有幂等性,可安全地在每次提交提示词时运行。
然后我们将此脚本连接到钩子:
{
"hooks": {
"UserPromptSubmit": {
"command": "./scripts/context-switcher.sh \"$PROMPT\"",
"description": "Dynamically load relevant context based on branch and user query"
}
}
}
通过此设置,上下文切换变得动态,且随时间推移保持稳定。
策略 2:智能上下文检索
第二个策略是智能上下文检索,通常通过动态上下文发现实现。
Claude 会自动浏览文件夹以查找有用的上下文文件。如果我们位于子文件夹中,它也会从父文件夹拉取上下文,但在有更具体信息可用时,会优先使用具体信息。它还会优先考虑最近使用和频繁访问的信息。
这是应用层面的上下文工程,由 Claude Code 开发者实现此逻辑。不过,用户也可以使用 /memory 命令自行添加持久化上下文。例如:
/memory add Always use descriptive variable names
Claude 会提示询问此记忆应存储在项目级还是用户级,并自动更新相应的 CLAUDE.md 文件。这使用户无需手动编辑上下文文件即可影响未来行为。
根据所使用的工具,不同的上下文会被传播给 LLM。例如,当 Claude Code 即将编辑文件时,它会自动记起先检查现有代码风格、在创建新函数前查找现有函数等事项。这是与编辑工具相关的上下文。
另一个例子是,当 Claude Code 即将运行终端命令时,它会记起不同的事项,例如在运行命令前检查是否有现有的 npm 脚本,或在执行前确保文件路径存在。
策略 3:上下文压缩
第三个策略是上下文压缩,关乎高效的上下文表示。Claude Code 包含内置压缩命令。
-
/clear命令重置当前上下文窗口的对话历史,同时保留底层的项目记忆和用户记忆。当正在进行的对话走向无益,或您想在不丢失系统已学到的项目知识的情况下开启全新交互时,这非常有用。 -
/compact命令将现有对话总结为更短的形式。它保留关键决策和重要信息,丢弃次要细节,而不是抛弃所有内容。这种压缩后的历史占用更少的上下文窗口,从而降低成本和延迟,并为模型腾出更多空间处理新输入。
策略 4:使用子代理隔离上下文
第四个策略是上下文隔离。为此,Claude Code 使用子代理。每个子代理在其独立的上下文窗口中运行,不会继承主代理完整的对话历史。此策略旨在为不同任务提供不同的专业版 Claude Code,每个版本拥有自己的聚焦知识库。
与其让 Claude Code 试图一次性用所有信息处理所有事情,不如创建专门的子代理,作为不同领域的专家。我们可以有一个主 Claude 代理,充当管理者并委派任务。我们可以有一个代码审查代理,专注于代码质量和安全;一个测试代理,专注于编写和运行测试;还有一个研究代理,专注于查找信息和最佳实践。示例如下:
// 代码审查代理 – 聚焦上下文
Task(
description: "Code review",
prompt: "Review this PR focusing only on security and performance",
subagent_type: "code-reviewer"
)
// 研究代理 – 广泛上下文
Task(
description: "Research implementation",
prompt: "Find best practices for OAuth2 implementation",
subagent_type: "general-purpose"
)
这很有帮助,因为如果没有隔离,Claude Code 会试图一次性用所有可能的信息处理所有事情而感到困惑。有了隔离,每个专家都有特定的知识范围,并利用它有效地完成工作。
上述语法仅为演示目的的说明性简化。Claude Code 目前并不使用这种确切格式。实际上,定义子代理需要包含前言部分的 YAML 配置,我们将在本书后面介绍。
系统提示词及其重要性
在本节中,我们将讨论系统提示词及其在上下文工程中的重要性。您可能在 X 和 LinkedIn 上读过无数遍:系统提示词很重要,您应该研究它们、迭代它们,使其变得非常好。说“拥有一个好的系统提示词”可能是 AI 工程中最通用的建议。
有几个公开仓库收集了知名 AI 代理使用的系统提示词示例。这些仓库通常汇总公开共享或公开讨论过的提示词。许多示例聚焦于编码代理,如 Claude Code、Cursor 和 Devin,但也可能包含其他代理风格系统的提示词。
引用这些仓库的目的不是为了验证每个提示词的真实性,而是为了说明在实践中,大型、结构化且经过精心设计的系统提示词通常是什么样子。
本节的目标不是详细分析每个提示词或解释每种使用的技术。我们可以专门写一整本书或开一门课程来讲系统提示词。
我的重点是向您展示系统提示词很重要。系统提示词在不断演进。随着 LLM 演进,系统提示词也随之演进。大量工程精力投入到了策划这些提示词并使其变得越来越好。这是一个迭代过程。
编写系统提示词的最佳实践
让我们谈谈策划和编写系统提示词时的一些最佳实践。这就像给某人指路。
如果我们说“往那边走”,他们会困惑,不知道该去哪里。但如果我们给他们一本 50 页的手册,里面有每一个可能的转弯和街道,我们用信息淹没了他们,他们仍然到不了需要去的地方。
所以,我们要清晰、具体,并给予刚好足够的信息让他们到达目的地。困难的部分在于找到那个最佳平衡点。
系统提示词的“黄金区间”
编写系统提示词时,我们要寻找 Anthropic 所谓的 黄金区间。不要太模糊,也不要太详细,恰到好处。
您可以把这想象成一个刻度。在最左边,提示词太具体。在最右边,提示词太模糊。我们想要的正是正中间。
Figure 1.5 – 系统提示词的黄金区间(来源:Anthropic, "Effective Context Engineering for AI Agents," https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents )
让我们细分分析。
过度具体提示词的问题
在最左边,我们有非常具体的提示词。这里的核心问题是我们将 LLM 视为确定性状态机,而不是智能代理。我们硬编码逻辑。
例如,我们可能会说:如果用户意图是事故解决,问三个后续问题。为什么恰好是三个?两个够不够?万一需要五个呢?
我们还看到穷举枚举,试图列出每一种可能的升级场景。这不可能完成,且强迫模型走预设路径,可能与实际输入不匹配。这也变成了维护噩梦,因为每个新边缘情况都需要修改提示词。
那时,如果一切都是预设的,也许我们甚至不需要自主代理。也许确定性工作流就足够了。
过度模糊提示词的问题
在光谱的另一端,我们有非常模糊的提示词。这里的核心问题是它们为一致性行为提供的信号不足。
在这些提示词中,我们经常看到没有可执行的指导。例如,考虑以下提示词:
你是一家面包店的助手。你应该以符合公司品牌原则和精髓的方式尝试解决客户的问题。如果需要,升级给人工。
那些原则是什么?
还有错误的共享上下文假设。提示词假设模型了解公司、品牌和客户服务规范,但实际上它并不了解。
我们还看到未定义的边界,如“如果需要,升级给人工。”何时需要?模型无从得知。
没有系统地解决问题的框架或结构。这导致行为不一致,同一个问题在不同运行中产生截然不同的处理方式。本质上,提示词在说“做正确的事”,却不定义什么是“正确”。
优秀的中间地带提示词长什么样
现在看看中间地带。考虑以下示例:
你是 Claude 面包店的客户支持代理。
你专门协助客户处理订单和回答关于面包店的基本问题。使用可用工具高效且专业地解决问题。
你可以访问订单管理系统、产品目录和店铺政策。你的目标是在可能的情况下快速解决问题。在提出解决方案前,先通过理解完整情况开始,如果不理解,请提出后续问题。
响应框架:
- 识别核心问题 – 透过表面投诉,理解客户真正需要什么
- 收集必要上下文 – 在响应前,使用可用工具验证订单详情、检查库存或审查政策
- 提供清晰解决方案 – 提供具有现实时间线的具体后续步骤
- 确认满意度 – 确保客户理解解决方案,并知道如果需要如何跟进
指导原则:
- 当存在多种解决方案时,选择最简单且能完全解决问题的一个
- 如果用户提到订单,在建议后续步骤前检查订单状态
- 调用
human assistance tool
- 对于法律问题、健康/过敏紧急情况,或需要超出标准政策的财务调整的情况,调用
human assistance tool
- 察觉用户语气中的沮丧或紧迫感,并以适当的同理心回应
您可以看到以下几点:
- 这里我们首先提供清晰的身份和范围。这立即建立了边界。是客户支持,不是市场或销售。涵盖订单和基本问题,不涉及复杂业务运营。
2 Claude Code 要点
本章将通过演示其在实践中的工作方式,帮助您熟悉 Claude Code。我们不会直接跳入高级功能,而是从构建对系统本身的理解、它所使用的术语以及它与代码库交互的方式入手。在此过程中,您将看到 Claude Code 如何观察项目、构建上下文,并利用该上下文来协助编码任务。
核心原则
-
我们也赋能而非限制。 我们不规定在每种情况下必须使用的确切工具,而是定义一个目标,例如高效且专业的解决方案。这里的启发式方法是,我们信任代理在需要时选择合适的工具。
-
我们也提供推理框架而非流程图。 此处遵循一个四步响应框架:识别核心问题、收集必要上下文、提供清晰的解决方案、确认客户满意度。这种框架应适用于各种场景,而非僵化的分支逻辑。
-
最后,我们也确立了清晰的边界和原则。 例如,如果有多种解决方案,选择最简单的一个。这是一种启发式方法,而非规则,类似于计算机科学中的贪婪算法。
过于具体的提示词试图替 LLM 思考,且在情况不符合脚本时会失效。模糊的提示词则没有给 LLM 提供足够的工作素材。
中庸的提示词利用了现代 LLM 真正擅长的能力:识别模式并将通用原则应用于特定情境。它能很好地处理新情况,因为它教授的是原则而非规则。它很高效,因为它不浪费词汇。每条准则都涵盖多种场景。原则经过压缩,且不存在重叠或相互矛盾的指令。
摘要
在本章中,我们介绍了上下文工程,并解释了为什么它对于构建可靠且可扩展的 AI 代理至关重要。我们探讨了上下文与静态提示词的区别、上下文的来源,以及为何不管理上下文会导致性能下降、幻觉和行为不一致等问题。以 Claude Code 为实际案例,我们探讨了四种核心上下文工程策略:通过持久化记忆写入上下文、动态选择相关上下文、压缩上下文以保持可控、以及使用专用子代理隔离上下文。我们还讨论了系统提示词的作用,展示了有效的提示词如何在过于僵化和过于模糊之间取得平衡。至此,您应该对现代 AI 代理如何管理上下文以及开发者和用户如何影响其行为有一定了解。在下一章中,我们将在此基础上进一步构建,开始处理更高级的代理工作流,使用 HookHub 项目来探索 Claude Code 如何协调任务、管理上下文,以及超越简单的单步交互进行操作。
在下一章中,我们将深入了解 Claude Code 及其与代码库的交互方式。
获取本书的 PDF 副本、代码包等
扫描二维码(或访问 https://packtpub.com/unlock)。按名称搜索本书,确认版本,然后按照页面上的步骤操作。
注意: 请准备好发票。直接从 Packt 网站购买不需要发票。
2 Claude Code 要点
本章将通过演示其实际工作方式,帮助您熟悉 Claude Code。我们不会直接跳入高级功能,而是从构建对系统本身的理解、它所使用的术语以及它与代码库交互的方式入手。在此过程中,您将看到 Claude Code 如何观察项目、构建上下文,并利用该上下文来协助编码任务。
我们首先设置一个简单的 Next.js 项目并将其与 Claude Code 集成。这为我们探索 CLAUDE.md 文件、权限系统以及为何有意识地管理上下文至关重要等概念提供了实用途径。我们还将探讨如何通过 Model Context Protocol (MCP) 使用外部工具扩展 Claude Code,以及这在日常工作流中能实现什么。
本章还介绍了规格驱动设计,作为在编写任何代码之前指导 Claude 行为的一种方式。通过创建和引用规格说明,我们可以影响所获得结果的质量和一致性。作为这一过程的一部分,我们开始构建一个名为 HookHub 的项目。您在此构建的 HookHub 项目将贯穿全书,并在我们后续进入更高级的代理工作流时充当共享参考点。
本章将涵盖以下主题:
-
设置 Next.js 项目
-
将 Playwright MCP 连接到 Claude Code
-
使用规格驱动设计
-
使用规格驱动设计实现主页面
好了,让我们开始吧!
安装 Claude Code
在继续之前,请确保您的机器上已安装 Claude Code。
Claude Code 现在提供原生安装程序,可检测您的操作系统并自动安装相应版本。请遵循官方安装指南:
https://code.claude.com/docs/en/setup#native-install-recommended
安装程序会根据您的机器类型处理设置和更新。安装完成后,您可以通过运行以下命令进行验证:
claude --version
确认 Claude Code 安装正确后,继续进行下面的 Next.js 设置。
本章中的所有终端命令均在 macOS 上演示。如果您使用 Windows,应在 WSL(Windows Subsystem for Linux)或同等的类 Unix Shell 环境中运行这些命令。这可确保 npx、npm、claude 和其他 CLI 工具等命令按示例所示运行。
设置 Next.js 项目
在本节中,我们将手动设置 Next.js 项目。虽然可以提示 Claude 创建 Next.js 项目,但我由于本地权限问题和需要预先处理的配置,选择手动操作。对于倾向于让 Claude 操作的读者,只要给予正确的语法,Claude 完全有能力运行这些 Bash 命令。
我们首先设置一个 Next.js 项目。您可以遵循官方 Next.js 安装指南 (https://nextjs.org/docs/app/getting-started/installation) 或粘贴以下命令:
npx create-next-app@latest
从以下截图可以看出,我们位于 project/HookHub 分支。
我们粘贴命令并搭建 Next.js 项目。您将看到如下所示的继续选项:
edenmarco@Edens-MacBook-Pro-2 claude-code-crash-course % npx create-next-app@latest
Need to install the following packages:
create-next-app@15.4.6
Ok to proceed? (y)
粘贴命令后,您可能会遇到错误。这是因为当前用户没有在系统上全局安装包所需的权限。
有两种解决方法。一种是使用 sudo 运行命令。另一种是调整 npm 权限,以便在无需提升权限的情况下进行安装。为求简便,我们使用 sudo 重新运行命令,这将授予必要的权限。
使用正确权限执行后,Next.js 项目搭建成功进行。系统将提示您确认配置选项。选择默认选项并继续。随后将安装依赖项并生成 Next.js 项目的样板代码。
安装完成后,进入新创建的项目目录:
cd hookhub
现在启动开发服务器:
npm run dev
如果您尝试从错误的目录运行服务器,命令将会失败。请确保在运行命令前位于项目目录内。
服务器成功启动后,在浏览器中打开 http://localhost:3000。您应该会看到默认的 Next.js 样板应用程序。
此时 Next.js 项目已在本地运行,准备好与 Claude Code 集成。再次运行命令后,我们创建 hookhub 项目。对提示选择 Yes 并安装所有必需依赖。设置完成后,你将看到 Next.js 项目的样板代码。
运行并验证应用
一切就绪后,我们进入 hookhub 目录并使用 npm run dev 运行项目。
Next.js 应用现已运行。打开 localhost:3000,你将看到标准的 Next.js 样板应用程序,如下图所示:
图 2.2 – 默认 Next.js 应用在 localhost:3000 上运行
初始化 Claude Code
在进一步更改之前,返回 Claude Code 并为其提供项目上下文。这通过初始化 CLAUDE.md 文件来完成,以便将其添加到项目上下文中。
Claude Code 通过 Cursor 集成打开。我个人倾向于将 Claude Code 置于中央、代码编辑器置于右侧,如图所示。此设置使 Claude Code 能充当主要驱动力。
图 2.3 – 通过 Cursor 集成打开的 Claude Code
使用 Claude Code 初始化项目的第一步是运行 /init 命令。无论项目是全新的还是已包含许多文件,均适用。执行 /init 时,Claude 会扫描文件、检查其内容,并开始生成对代码库的思考。
Claude 识别技术栈、主要内容和目录结构。所有这些信息均被记录在 CLAUDE.md 文件中,稍后将在本书中探讨。这些 Markdown 文件最终将分布在项目各处,以支持上下文工程。这些文件的目的是随每次请求向 LLM 发送高质量上下文。这使 LLM 能更容易地生成准确且有用的代码。
当 Claude 运行时,其状态显示为 Booping。
图 2.4 – Cursor 集成中的 Booping
在此语境下,Claude 正在分析仓库、探索目录结构并读取文件内容。之后,将创建一个任务来分析代码库结构,并执行一系列批量命令以列出和读取文件。
请记住,对于较大项目,此过程可能耗时更长。完成后,Claude 将基于收集的信息准备创建 CLAUDE.md 文件,并生成如下内容:
图 2.5 – 包含项目概览和命令的生成的 CLAUDE.md 文件
如你所见,已创建 CLAUDE.md 文件,包含项目结构及相关详情。
为保存文件,Claude 请求权限。我们可以允许其写入文件并继续编辑而无需进一步提示,或拒绝更改(若想修改或丢弃)。此权限系统适用于每个新文件或编辑。
在 Cursor 中打开更改
保存文件以继续...
是否要对 CLAUDE.md 进行此编辑?
1. Yes
2. Yes, and don't ask again this session (shift+tab)
3. No, and tell Claude what to do differently (esc)
这是实践安全代理编码的重要组成部分。允许不受限制的访问会迅速导致意外的文件更改和错误。保持控制可确保更安全的工作流。
暂时选择 Yes 并选择本会话不再询问。Claude 完成流程并创建 CLAUDE.md 文件。
CLAUDE.md 文件的内容
该文件包含项目架构、结构和基本信息,例如:
-
项目目标
-
要解决的业务问题
-
项目如何运行
-
使用的框架,包括 Next.js
-
文件夹和目录结构
从此时起,每当向 Claude Code 发送提示时,它首先加载相关的 CLAUDE.md 文件。这些文件随项目变化动态演变。发生重大更新时,可再次运行 /init 命令,并根据需要添加额外的 CLAUDE.md 文件。
随着更多元数据和结构信息的提供,Claude 能表现得更一致并生成更高质量的结果。
Claude Code 现在提供专用安装程序,可自动处理设置和更新。若出现问题,重新运行安装程序通常可解决。
退出当前会话并重启后,将出现一个名为 security review 的新命令。该命令引入一个子代理,旨在协助安全审查和针对常见漏洞的渗透测试。它分析你的代码库并标记常见问题,如不安全模式、错误配置,以及与 OWASP Top 10 风险一致的漏洞。
子代理将在 第 3 章 中深入探讨。
将 Playwright MCP 连接到 Claude Code
我们首先在 Google 中搜索 Playwright MCP。对于不知情者,Playwright 是一种浏览器自动化工具,可使用模型上下文协议 (MCP) 连接到 Claude Code。若你不知道什么是 MCP,不必担心,本书将深入介绍。甚至还有整章专门讲解 MCP。
你可以将 MCP 视为我们可以为 Claude Code 配备的外部能力。在该仓库中,有关于如何将 Claude Code 连接到 Playwright MCP 的说明。向下滚动并找到以下命令:
claude mcp add playwright npx @playwright/mcp@latest
复制该命令并粘贴到终端。此时,我们正在使用 Claude Code 命令行界面 (CLI)。
图 2.6 – 在终端中运行 Claude Code CLI
在终端中,我们按如下方式输入命令:
edenmarco@Edens-MacBook-Pro-2 claude-code-crash-course % claude mcp add playwright npx @playwright/mcp@latest -s user
如你所见,我们将 MCP 名称指定为 playwright,并使用 npx @playwright/mcp@latest,这是 Claude Code 拉取仓库并运行代码的位置。运行的代码即 Playwright MCP,这赋予了 Claude Code 浏览器自动化的额外能力。
我们还添加了 ‑s user 标志。这确保 MCP 对我们打开的每个 Claude Code 实例均有效,因为它应用于用户作用域。通过这样做,我们利用了 Claude Code 的层级系统,这将在后续章节深入探讨。
验证 MCP 连接
现在,我们再次打开 Claude 并输入 /mcp。按 Enter 后,我们应该看到所有连接到 Claude Code 的 MCP 服务器。
图 2.7 – 在 Claude Code 中验证 MCP 服务器连接
我们可以看到 playwright MCP,也可以看到另一个名为 context7 的 MCP,它是之前配置的。这是另一个有用的 MCP,稍后将讨论。
使用 Playwright MCP 打开浏览器
为验证 Playwright MCP 集成,我们在 Claude Code 中输入 open browser 并添加 cnn.com。此时,我们再次遇到权限系统,类似如下所示:
图 2.8 – Playwright MCP 打开浏览器的权限提示
Claude Code 通过工具使用请求提示我们,询问是否可以运行 Playwright 工具导航到 URL cnn.com。
这是一个已连接到 Claude Code 的外部工具,而非内置工具。内置工具包括编辑文件、创建文件或删除文件等。与之前一样,选择 Yes,并选择不再针对该特定工具询问。
浏览器打开,我们进入 cnn.com。Claude Code 利用 Playwright MCP 进行浏览器自动化并打开了该网站。
当我们想要测试用户界面或执行 UI 自动化时,这变得非常有用。
使用 Cursor Rules 作为额外上下文
接下来,打开浏览器搜索 cursor directory,或直接访问 cursor.directory/。Cursor Directory 是一个寻找有用 Cursor Rules 的地方。这些规则允许通过 Markdown 文件向 Cursor 提供额外上下文,例如 AI 编码助手的人设 —— 比如让它表现得像一位专精特定领域的资深开发者。
这些 Cursor Rules 同样适用于 Claude Code。要在实践中看到这一点,请寻找一个 Next.js 的 Cursor Rule,选中一个并按图示复制它。
Figure 2.9 – 浏览 Cursor Directory 寻找 Next.js Rules
创建前端记忆上下文
我们回到 Cursor 并将其添加到 CLAUDE.md 文件中。我们已经拥有 Claude 之前创建的 CLAUDE.md 文件。我们还拥有一个更广泛的记忆系统,可向 Claude 提供额外上下文。
在此例中,我们想给它 Cursor Rule 和一位精通 Next.js 的专家人设,目标是产出更好的结果。我们首先创建一个名为 memory 的目录,然后在其中创建一个名为 frontend 的子目录。在里面,我们创建一个名为 CLAUDE.md 的文件,并粘贴之前复制的 Cursor Rule。
提到的记忆文件不会被 Claude 自动加载。这是有意为之。Claude 默认仅自动加载特定的 CLAUDE.md 文件。在本章中,我们首先搭建记忆结构。在 第 3 章 中,我们将配置这些记忆文件何时以及如何被加载以影响回复。
我复制的规则包含如下内容:"You are a senior frontend developer and an expert in React, Next.js, JavaScript, TypeScript, HTML, CSS…" 等等。实际上,我们赋予了 Claude Code 一个与我们使用的技术栈更契合的聚焦人设。
在之前的 CLAUDE.md 文件中,我们告知它我们使用 Next.js 技术栈。在该 CLAUDE.md 文件中,我们赋予它一个人设。
此时,显然上下文对 LLM 至关重要。于是我们向 Claude 提出以下问题:
What are you expert in?
你可能期望它背诵自己是前端工程、Next.js、TypeScript 及 CLAUDE.md 中所写一切的专家。然而,回复可能令人惊讶。
回答返回了一个通用声明:
Figure 2.10 – 未加载项目上下文时的通用 Claude 回复
如你所见,它说 "expert AI assistant specialized in software engineering and coding tasks",没有任何特定于 Next.js 或前端的内容。这看起来像是文件未生效。
然而,这是设计使然。Claude 拥有一套自动加载 CLAUDE.md 文件的系统,这将在 第 3 章 中深入探讨。还有其他称为记忆文件的文件,不会被自动加载。
相反,我们可以根据上下文显式告诉 Claude 何时加载它们。这为上下文工程打开了大门,本书将对此进行探索。
思路是我们可以配置 Claude 仅在需要时加载前端上下文。例如,在设计或构建 UI 时、仅处理 TypeScript 文件时、在特定目录中工作时,或请求明确与前端工作相关时加载它。
这赋予了我们根据需求定制 Claude 行为的自由。本书将演示这一点,其中一个提示是可以使用钩子来实现。我们可以引用其他文件的上下文,处理记忆有多种方式,将在本书后续章节深入探讨。
使用规格驱动设计
在本节中,我们不采用氛围编程,而是使用所谓的 spec-driven design。这将在本书后续详细阐述,但核心思想是创建一个描述应用程序、用例或业务用例,以及可能的非功能性需求的规格文件。
我们创建的规格文件应指示 Claude 在编码时引用该规格文件。这有助于优化上下文窗口并改善结果。
开始时,我们按 Shift + Tab 切换到 Claude Code 的 plan mode。Plan mode 专为这类任务设计,我们希望进行只读工作、做一些调研,并规划 Claude 将要做的事。
我输入了以下提示,请求 Claude 帮助为一个名为 HookHub 的项目编写规格文件。
I want you to help me write a spec file for a project I am building. It's called "hookhub". It's a place where cool open source Claude hooks are displayed and browsed. Search on Claude hooks and write an initial spec for this. Remember it's an MVP ATM and we need only the functionality of displaying the hooks. Hooks are found in GitHub repositories, they have name, category, description and link to repo. The main page should display the hooks in a grid-like view.
如提示所示,我
-
将
HookHub描述为展示和浏览开源 Claude hooks 的场所 -
请求 Claude
search for Claude hooks并编写初始规格 -
阐明这是一个
MVP,功能仅限于展示 hooks -
指定 hooks 位于
GitHub repositories中,包含名称、类别、描述和仓库链接 -
说明
main page should display the hooks in a grid view
这是完整提示。没有花哨技巧,也未应用提示工程。
提交提示后,Claude 仅使用只读工具。此阶段不发生写入或编辑操作。
由于我们在 plan mode 下工作,粘贴提示前还需选择模型。使用 plan mode 时,通常倾向于具有深度推理能力的重量级模型。为控制使用哪个模型,我们运行 /models 命令并确保选中最新版 Opus。撰写时,这是可用于深度推理的最先进模型。粘贴提示时,我们仅看到文本的代表性显示而非实际文本。
Claude 开始调研 Claude hooks。它使用网络搜索工具,查询与开源 Claude Code hooks 相关的内容,并请求获取 Anthropic 文档的权限,我们批准后继续。
调研步骤完成后,Claude 提出类似以下的计划:
Figure 2.11 – HookHub MVP 规格的 Claude 建议计划
计划包含:
-
创建涵盖项目概览的规格
-
MVP 范围
-
Claude Code hook 的数据模型
-
UI 和 UX 需求
-
技术架构
-
用户故事
-
未来考量
此时,我们批准该计划。Claude 随后进入 write mode 并请求将文件写入 hookhub/SPEC.md。拒绝并指示 Claude 将规格写入 spec 目录下,文件命名为 CLAUDE.md。
I want you to write it into a spec directory and make this a CLAUDE.md file
Claude 再次响应并准备在 spec/CLAUDE.md 下写入文件。批准此操作并允许编辑。
Claude 首次提供待办事项列表。Claude 开始遍历任务和请求。我们根据提示批准这些操作。
Claude 创建 spec 目录并生成 CLAUDE.md 文件。我们将在本书后面更详细地介绍待办事项,但重要的是要注意,它们在结果质量中起着主要作用。这是 Claude Code 作为编码代理表现良好的原因之一。具体来说,Claude Code 表现为一种深度代理,能够处理需要大量推理的长期、多步骤任务。深度代理以及 Claude 如何融入这一类别将在本书后面介绍。
审查生成的规格说明书
流程完成后,我们现在有了一个新的 CLAUDE.md 文件。
图 2.12 – CLAUDE.md 中的 HookHub 产品规格说明书
该文件包含项目概览、愿景以及大量信息,这些信息将帮助 Claude 在实现过程中进行开发。
规格说明书提供了有用的上下文,例如钩子类别、钩子对象结构以及应用程序的外观。它还包括构建项目所需的步骤。此文档将被添加到代码库中,并将帮助 Claude 在实现过程中产生更好的结果。
至此,你应该了解使用 LLM 帮助生成规格说明书是一种常见模式。其他高级模式将在本书后面介绍。
最后,将 spec 目录移动到 memory 目录下。
此时,你的结构应如下所示:
memory/
├── frontend/
│ └── CLAUDE.md
└── spec/
└── CLAUDE.md
这使得所有长期上下文都可以在一个地方存放,并在需要时重复使用。
根据规格说明书实现主页面
在实现任何内容之前,我们切换模型并使用 Sonnet。在提示词中,我们编写以下内容:
Can you please help me implement the main page grid as specified in the spec file?
然后我们使用 @ 符号标记规格说明书文件。我们拥有的规格说明书文件是 spec/CLAUDE.md。我们需要标记该文件以将其附加到上下文中。
每次我们发出提示、获得结果,然后再发出另一个提示,我们都在不断填充上下文。随着时间的推移,这会导致我们与 Claude 之间进行多次来回迭代。
如果我们继续使用同一个会话而不做任何处理,最终会填满上下文窗口。一旦发生这种情况,结果质量就会开始下降。
有几种方法可以处理这个问题。本书后面将介绍自定义命令,它们有助于清理或总结上下文窗口,同时保留有用的部分。目前,我们使用一种简单、朴素的技术。Claude Code 还提供内置命令,如 /clear 和 /compact,用于在不重启会话的情况下管理上下文窗口。这些命令之前已介绍过,我们稍后将重温它们。目前,重启会话以最直接的方式为我们提供了一个干净的环境。
我们通过运行 /exit 退出当前的 Claude Code 会话。之后,我们再次打开 Claude,导航到 HookHub Next.js 项目,并从那里打开它。此时,上下文是新鲜且空的。
我们再次编写提示词:Can you please implement the main page, a grid of the hooks, as specified in the spec file?
这一次,我们注意到找不到文件引用。原因是在 HookHub 目录中打开 Claude Code,但 memory 目录仍位于项目的根目录下。
为了修复这个问题,我们在层级结构中向上移动 memory 目录,使其位于 hookhub 下。完成此操作后,文件引用将按预期工作。在此移动后,memory 目录不再位于速成课程的根层级。它现在位于 HookHub 项目目录内部。
运行实现
我们再次编写提示词,根据规格说明书实现网格。Claude 现在开始繁重的工作。它创建一个待办事项列表,并开始实现列表中的每个任务。
将出现一个批准文件写入的请求,例如创建 Hooks.ts 文件。批准后,实现将继续并需要一些时间才能完成。
实现完成后,钩子卡片组件被创建,Claude 继续执行剩余步骤。然后它运行代码检查以捕获潜在错误。完成后,我们将看到实现内容的摘要,包括卡片组件、Hero 区域、页眉和其他相关部分。
图 2.13 – 代码生成后的 Claude 实现摘要
在浏览器中刷新应用程序,你将看到一个 Claude Code 钩子卡片网格。
图 2.14 – 基础 Next.js 应用程序
这是一个基础的 Next.js 应用程序。虽然某些功能(如搜索)尚未实现,但其他功能已就绪。总体而言,它提供了一个可供我们继续构建的可靠骨架。
在本书后面,我们将探索用于 AI 编码的高级代理工作流。这包括动态启动多个子代理、迭代 UI 组件和使用元提示。该项目将作为这些实验的基础。
此时,我们将代码提交到代码库以便共享。我们运行 git status,添加所有文件,并确认未包含任何密钥或环境变量。
然后我们使用诸如 initial project 之类的消息提交更改,并将它们推送到代码库。
从代码库中,你可以导航到 project/hookhub 分支,查看文件,并从此提交拉取确切的代码。还提供了一个命令,以便你可以克隆代码库并在本地完成所有设置。要访问代码库链接,请按照前言中下载示例代码文件部分的步骤操作。
完成本章所有步骤后,你的 HookHub 项目应具有以下结构:
hookhub/
├── app/
├── components/
├── memory/
│ ├── frontend/
│ │ └── CLAUDE.md
│ └── spec/
│ └── CLAUDE.md
├── package.json
├── next.config.js
└── ...
如果你的结构与此匹配,则你已正确设置好进入下一章的环境。
总结
在本章中,我们通过逐步完成设置和工作流的每个步骤,为使用 Claude Code 奠定了实用基础。我们没有直接跳入高级功能,而是专注于理解 Claude Code 如何观察项目、如何通过 CLAUDE.md 文件构建上下文,以及如何依赖显式权限安全运行。这项基础工作至关重要,因为你从 Claude Code 获得的结果质量直接取决于你提供的上下文、结构和控制的质量。
我们还了解到如何使用 MCP 扩展 Claude Code 的内置功能,外部工具(如 Playwright)如何融入工作流,以及为什么规格驱动设计有助于产生更一致、更可预测的结果。此处创建的 HookHub 项目不仅仅是一个示例,它是一个可工作的基线,将在我们探索更高级的代理工作流时重复使用。本章介绍的每个概念都是我们将在此基础上构建的内容,而不是从头开始重温。
在下一章中,我们将介绍定价和身份验证、斜杠命令、用户和项目级配置,以及与 Cursor 的集成。
获取本书的 PDF 副本、代码包等
扫描二维码(或访问 packtpub.com/unlock)。按名称搜索本书,确认版本,然后按照页面上的步骤操作。
注意: 请准备好发票。直接在 Packt 网站购买不需要发票。
3 Claude Code 入门——核心命令速览
在本章中,我们将从开始使用 Claude Code 过渡到为其配置日常用途。目标是帮助您熟悉 Claude Code 在实践中的行为方式、如何在会话中控制它,以及如何对其进行设置,使其在各个项目中保持一致。
我们将简要介绍定价和认证,以便您在开始前选择合适的设置。之后,我们将重点关注您将持续使用的部分:用于管理会话和上下文的斜杠命令、用户级和项目级的配置,以及直接在 Cursor 等 IDE 中运行 Claude Code。然后,我们将在这些基础之上构建使长流程更安全、更可靠的功能,包括用于自动化的钩子、通过 CLAUDE.md 文件实现的记忆、通过检查点实现的回溯,以及用于可重复、定义明确的工作流的自定义斜杠命令(技能)。
技能可以使用 /技能名 语法手动调用,这也是旧版文档有时将其称为技能的原因。在内部,它们现在统一归属于 Skills 系统。
本章将涵盖以下主题:
-
Claude Code 的定价和计划
-
使用斜杠命令控制 Claude Code
-
在 Claude Code 中使用钩子
-
理解 Claude Code 中的记忆
-
Claude Code 中的回溯功能
-
Claude Code 中的技能
Claude Code 的定价和计划
在本节中,我们将讨论运行和使用 Claude Code 的定价选项及不同计划。我们从认证开始,因为您的认证方式也决定了代币使用的计费方式。
本节提到的定价和计划详情在撰写时是准确的。由于订阅层级、使用限制和计费政策可能会发生变化,请始终参考官方 Claude 定价页面以获取最新信息:claude.com/pricing
图 3.1 – Claude Code 认证选项屏幕
Claude Code 提供三种主要的认证和支付代币使用的方式。
图 3.2 – Claude Code 订阅和 API 计费的登录方式
选项 1:使用 Anthropic API 密钥
其中一种选择是使用 Anthropic API 密钥进行认证。这采用按量付费的计费模式,用量通过 Anthropic 控制台追踪。此选项适合偏好基于用量计费,或希望在订阅前评估 Claude Code 的用户。
在遵循本书内容时,若使用 Anthropic API 密钥方式,用量将取决于调用 Claude Code 的频率以及所使用的模型。
如果您选择此选项,请选择 API 密钥认证方式,并通过您的 Anthropic 组织授权 Claude Code。随后,Claude Code 将自动在终端中生成并配置 API 密钥。完成后,Claude Code 将按按量付费模式运行。
使用 Anthropic API 时需注意的事项
使用 API 密钥时,监控代币消耗非常重要。这可以直接在 Claude Code 内部通过 /cost 命令完成。该命令仅在 Claude Code 使用 Anthropic API 密钥认证时可用。它会显示消耗的代币数量及其分布情况。
图 3.3 – 使用 /cost 命令监控代币用量
相同信息也可通过 Anthropic 控制台获取。费用为零是因为尚未使用任何代币。只需输入任意内容,收到输出后,再次输入 /cost 即可。
图 3.4 – 运行提示词后的更新代币用量
请记住,定价因所用模型而异。例如,使用 Opus 产生的代币成本高于其他模型。
使用 API 密钥时的重要注意事项
使用 API 密钥需要谨慎。存在意外泄露密钥的风险,这可能允许他人以您的名义消耗代币。极端情况下,这可能导致意外的高额费用。
此外,本书涉及代理、子代理和编排模式的使用,所有这些都可能消耗大量代币。如果配置错误,可能会同时触发许多代理,从而显著增加成本。
降低此风险的一种方法是在 Anthropic 控制台中设置支出限额。Anthropic 允许您为账户定义使用限额,超出后将不再提供服务。有关配置这些限额的详细信息,请参阅 Anthropic 设置页面(platform.claude.com/settings/limits)。
选项 2:使用 Claude 订阅
如果您遵循了 第 2 章 中的设置,您正在使用选项 2,即通过 Claude 订阅进行认证。我们将在本书中始终使用此选项,即通过 Claude 订阅进行认证。通过这种方式,您可以将现有的 Claude 订阅直接连接到 Claude Code。这提供了无缝集成,并具有可预测的月度计费。
Claude 目前提供以下订阅层级:
-
免费版 – 0 美元/月(不包含 Claude Code 访问权限)
-
专业版 – 20 美元/月
-
Max 5x – 100 美元/月
-
Max 20x – 200 美元/月
Claude Code 访问权限从专业版及以上计划开始提供。
在本书中,我使用的是 Max 5x 计划,它提供比专业版更高的使用限额,同时对于常规开发工作流仍具成本效益。
现在,与前一个选项不同,使用订阅计划时,费用监控的行为也不同。由于 Claude Code 的使用包含在订阅中,因此无需使用 /cost 追踪代币级别的成本。定价是固定的,尽管根据计划不同,使用限额仍然适用。
图 3.5 – 使用 /usage 命令查看订阅用量
此选项下的可用模型
使用 /models 命令可查看可用模型。Claude Code 目前支持 Opus、Sonnet 和 Haiku:
-
Claude Opus:Claude Opus 是能力最强的模型,非常适合复杂任务和深度推理。它拥有 200K 代币的上下文窗口,通常用于深度规划或研究任务。由于成本较高,Opus 通常不用于编写大量代码。
-
Claude Sonnet:Claude Sonnet 在智能、速度和成本之间取得了平衡。它同样拥有 200K 代币的上下文窗口,是本书中用于代码生成的主要模型。凭借其平衡性,Sonnet 在编写和修改代码时承担了大部分繁重工作。
-
Claude Haiku:速度最快、最轻量的模型。它非常适合简单任务、快速迭代以及速度比深度推理更重要的低延迟工作流。
模型本身由 Anthropic 托管和提供服务。对于企业环境,也可以通过受支持的第三方云提供商访问,例如 AWS Bedrock、Google Cloud Vertex AI 或 Microsoft Azure。这种设置通常被需要集中计费、云特定的合规控制、区域部署选项或通过现有云基础设施进行治理的组织所使用。
订阅计划和定价
Claude 提供多个订阅层级。
- 免费计划
定价计划
-
Pro 计划
-
Max 5x 计划
-
Max 20x 计划
引入速率限制是为了防止滥用,例如共享凭证或滥用系统。这些限制适用于 Pro 和 Max 计划。
对于大多数用户,尤其是爱好者,建议从 Pro 计划开始。只有在需要更高使用量时,升级到 Max 计划才有意义。
确切的使用限制难以量化,这并非 Claude Code 独有。AI 编码代理的定价是整个行业持续面临的挑战。定价模式的变化导致开发者社区感到沮丧,这一领域仍在不断演变。
本节旨在阐明可用的定价选项,帮助您了解使用 Claude Code 时的计费方式,以便选择最适合您需求的方案。
选项 3:使用第三方云服务商
Claude Code 还可以通过受支持的第三方云平台进行身份验证,例如 Amazon Bedrock、Microsoft Azure AI 或 Google Cloud Vertex AI。在这种情况下,计费和用量管理由所选云服务商管理,而非通过 Claude 订阅或 Anthropic API key。有关支持的第三方集成详情,请参阅官方文档:https://code.claude.com/docs/en/third-party-integrations
使用斜杠命令控制 Claude Code
斜杠命令 是在 Claude Code 聊天中控制 Claude Code 功能和设置的主要方式。当我们输入 / 时,Claude Code 会显示可用命令列表,如下图所示:
Figure 3.6 – Listing available slash commands in Claude Code
当我们与 Claude Code 进行大量对话时,对话历史会变得非常长,这会拖慢速度并导致上下文腐烂,这将在书中后面讨论。这也会花费更多费用,甚至如果 Claude 需要记住太多内容而感到困惑。
为了应对这种情况,有两个命令:
-
/clear,它擦除一切并重新开始,就像一张白纸 -
/compact,它创建重要内容的简短摘要,保留关键信息,并移除额外细节
使用 /clear 和 /compact 有助于 Claude 保持专注并随时间推移更好地工作。这就是上下文工程的实际应用(参见 Chapter 1)。
让我们从零开始会话。为此,我们需要运行 /clear。
另一个值得注意的命令是 /agents,它有助于管理专用子代理。子代理 可以被视为为特定任务创建的专家助手,例如代码审查员、调试员或架构师。
它们拥有自己的上下文和工具,并作为多代理工作流的一部分使用。子代理和这些工作流将在后面的实操部分中介绍。
接下来是 /config 命令。/config 命令打开 Claude Code 的配置面板,显示设置和偏好。运行此命令后,您将看到如下所示的设置:
Figure 3.7 – Claude Code settings panel with configuration options
例如,我们可以看到 Auto-compact 已启用。这意味着当 Claude 检测到对话接近令牌限制或判断这是压缩上下文的好时机时,会自动运行 /compact。还有使用待办列表、检查点等设置。我们不会在此逐一介绍;完整且最新的设置列表请参阅官方 Claude Code 文档(https://code.claude.com/docs/en/settings)。
除了各个选项本身,重要的是这些设置如何被组织和应用。Claude Code 提供了一个细粒度的配置系统:
-
用户级设置,存储在主目录下的
.claude/settings,适用于每个Claude Code实例 -
项目级设置,存储在项目目录中的
.claude/settings.json,仅适用于该项目,可与团队共享 -
本地设置,允许个人微调而不影响共享的项目设置
这种结构使得维护全局默认值、应用项目级指南并保留个人偏好成为可能。全书中展示的设置均可根据个人和团队需求通过这些设置文件进行配置。
最后,我们来看 /cost。由于此设置使用 Claude Pro 订阅,因此此处不显示成本监控,因为订阅包含 Claude Code 使用量。/cost 命令在您使用 Anthropic API key 时变得更加相关。
将 Claude Code 与 IDE 集成
在结束本节之前,让我们看看如何将 Claude Code 与 IDE 集成。在本例中,我们将把它与 Cursor IDE 集成。打开斜杠菜单并选择 IDE 以将 Claude Code 集成到 Cursor 中。这将直接在 IDE 中安装 Claude Code 扩展。
安装完成后,我们可以在 Cursor 中看到 Claude Code 扩展。
Figure 3.8 – Claude Code extension inside the Cursor editor
您会注意到右上角的 Claude Code 图标。这是大多数开发者在实践中使用 Claude Code 的方式。Claude Code 通常通过 Cursor 扩展打开,因此它直接在 IDE 内部运行。这使我们能在编辑器中工作,更清晰地查看差异,并将所有内容保持在一个地方。我们将在全书中使用此设置。
我们还有 /mcp 命令,用于管理 MCP 服务器。通过此命令,我们可以添加、移除和列出所有已配置的 MCP 服务器。
此时,尚未配置任何 MCP 服务器。MCP 服务器提供可添加到 Claude Code 的额外功能。它们可能来自经过验证的供应商或开源项目,并能有效地用额外的工具和能力扩展 Claude Code。
MCP 本身是一个深度话题。全书中,我们将把 MCP 服务器的集成和使用作为工作流的一部分。目前,假设您熟悉 MCP 服务器的基本概念。
在 Claude Code 中使用钩子
钩子是 Claude Code 中的一项强大功能。它们是在 Claude Code 工作流的特定节点自动运行的逻辑。
Figure 3.9 – Hook configuration and security warning in Claude Code
例如,钩子可以在工具使用前或后运行,或在 Claude 完成工作时运行。它们有助于自动执行诸如格式化代码、运行测试或阻止不安全编辑等任务。通过这种方式,钩子确保这些操作无需人工干预即可一致地发生。
钩子是构建可靠工作流的关键部分,我们将在本书后面花费大量时间进行实操。简要预览一下,钩子还可以用于触发 Claude 的子代理。每个子代理都在自己的上下文中运行,并拥有自己的工具集,这为更复杂和强大的工作流打开了大门。
创建通知钩子
现在让我们配置第一个钩子。在本节中,我们将构建一个简单的通知钩子,每当 Claude 完成输出生成时播放声音。
所有相关代码均可在仓库的 project/hooks‑notification 下找到。在继续之前,请克隆仓库并检出 project/hooks‑notification 分支。
初始化环境
请按以下步骤操作:
- 确保仓库包含所有必需工件,包括声音文件。除音频记录外移除所有内容,以便从头开始设置。
初始化 Python 环境并配置 Hook
2. 初始化 Python 环境
由于 Hook 是 Python 脚本,需要初始化 Python 环境并安装依赖。使用 uv 初始化环境:
提示
此处使用
uv,这是 Astral 公司开发的快速 Python 包和环境管理器。若未安装uv,请参考官方文档安装:docs.astral.sh/uv/.
uv init
此命令会创建虚拟环境和主文件。
3. 重命名并运行主文件
将主文件重命名为 play_sound.py,然后运行:
uv run play_sound.py
这将确认环境设置正确。
4. 重新打开 Claude Code 并验证 Hook 尚不存在
运行一个提示词,确认会产生响应但不播放声音。
5. 让 Claude Code 编写 Hook 脚本
使用以下提示词:
I want you to please write a python script that is going to play the sound @ulala.wav, every time the script runs.
让 Claude 编写一个每次运行时都播放录制声音的 Python 脚本。
自定义通知声音
Hook 不依赖特定的声音文件,它只是播放脚本指向的任何文件。本节示例引用 @ulala.wav,但你可以替换为任何你喜欢的音频文件。
如果选择其他文件,请将其放在项目中(例如 hooks/ 或 assets/ 文件夹下),并更新脚本以使用新的文件名或路径。
查看建议的更改。
Figure 3.10 – Reviewing and approving hook file changes in diff view
6. 批准文件编辑
Claude 显示 diff 视图,高亮显示新增和删除的行,并请求编辑 play_sound.py 的权限。选择批准选项:
Choose one of the approval options:
1. Approve once
2. Approve for the rest of the session
3. Reject and provide different instructions
选择“Approve for the rest of the session”会更新本地设置,使 Claude 在本会话中不再针对该文件请求权限。此权限步骤是一项安全措施,因为 Claude Code 会直接修改文件。
7. 安装所需依赖
脚本使用 pygame 播放音频。运行以下命令安装:
uv add pygame
8. 测试脚本
再次运行脚本,确认声音播放正常:
uv run play_sound.py
9. 打开 Hook 配置,将脚本注册为自动化动作
打开斜杠菜单,输入 /hooks,从提供的列表中添加新 Hook:
-
PreToolUse – 工具执行前
-
PostToolUse – 工具执行后
-
Notification – 发送通知时
-
UserPromptSubmit – 用户提交提示词时
-
Stop – Claude 结束响应前
此步骤是必需的,以便 Claude Code 知道何时以及如何自动运行脚本,而不必每次手动执行。
10. 选择 Hook 事件
选择 Stop 事件,它在 Claude 完成响应前触发。这确保脚本在输出生成后立即运行,适合通知风格的 Hook。虽然存在其他事件,但目前该事件符合我们的需求。
11. 配置 Hook 命令
将命令设置为:
uv run play_sound.py
如果脚本在文件夹中(如 hooks/):
your/path/to/play_sound.py
这确保脚本在虚拟环境中运行。选择项目作用域,使 Hook 仅应用于此项目。
12. 查看生成的配置
系统将创建一个 .claude 目录,其中包含一个设置文件,Hook 配置以 JSON 格式存储:
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "uv run /Users/edenmarco/GithubProjects/claude-code-crash-course/play_sound.py"
}
]
}
]
}
}
空的 "matcher": "" 字段表示该 Hook 适用于该类型的所有匹配事件。在此例中,它会在每个 Stop 事件上触发,无需额外过滤。
配置指定了事件类型、可选的匹配器,以及 Claude 完成输出时要运行的命令。
13. 重新加载 Claude Code
退出并重新打开 Claude Code,以加载新设置。
14. 验证 Hook
输入任意提示词,确认每当 Claude 完成响应时都会播放声音。这确认了 Hook 按预期工作。
此时,Hook 已完全配置。在 Cursor 中打开 Claude Code 并输入任意提示词:
hello how are you?
一旦 Claude 完成响应,通知声音应自动播放。
这确认了:
-
Python 环境已正确初始化
-
脚本执行成功
-
Hook 已注册并在 Stop 事件上触发
如果没有声音播放,请重新检查 Hook 配置,确保命令路径正确。
关于 Hook 与可扩展性的说明
此 Hook 不接收任何参数,但 Hook 可以配置为接收上下文信息。这可能包括用户输入、工具调用或其他运行时细节。Hook 最好组织在专用的 hooks 目录中,因为它们的功能类似于可复用的工具。
Hook 还可以产生影响 Claude Code 后续行为的输出。它们可以阻止动作、修改行为,甚至触发子代理。更高级的 Hook 用法将在本书后面介绍。此示例仅作为简单入门。
技能继续按前文描述工作。内部上,命令已统一在技能的概念下。现有的 .claude/commands/ 文件完全受支持,而 .claude/skills/ 下的等效技能定义行为相同。技能增加了可选结构、支持文件,并提供了对何时以及如何调用 Claude 的更多控制。更多关于技能的内容将在 Chapter 9 中介绍。
在继续之前,值得注意的是 Hook 是 Claude Code 提供的几种扩展行为机制之一。虽然 Hook 在特定执行点运行,但其他功能侧重于控制上下文和持久化,我们将通过记忆系统进一步探索这些功能。
最佳实践
保持生产环境 Hook 轻量级。 Hook 会自动运行并可能频繁执行,因此繁重的脚本可能引入不必要的延迟。对于简单通知,极简的系统命令(如 macOS 的
afplay sound.wav或 Linux 的aplay sound.wav)通常比加载带有外部依赖的完整 Python 运行时更快。如果可能,请为高频 Hook 优先选择轻量级命令。
理解 Claude Code 中的记忆
在 Claude Code 中,记忆是指一种系统,允许 AI 保留并重用重要信息(如设置、规则和上下文细节)跨编码会话。记忆的目的是提高工作流效率并随时间保持一致性。
记忆主要通过称为 CLAUDE.md 的特殊文件来管理。这些文件存储指令和偏好,Claude Code 在每个会话开始时加载它们,并用于指导整个交互过程中的行为。
记忆类型
Claude Code 中的记忆是细粒度的,可以在不同层级定义:
存储层级
用户内存
用户级内存存储在用户的主目录下的 ~/.claude/CLAUDE.md 中。此文件通常包含适用于所有项目的个人偏好,例如编码风格偏好、常用工作流、快捷方式及其他应保持一致的习惯,无论项目如何变化。
项目内存
项目级内存存储为项目目录中的 ./CLAUDE.md 文件。此内存通常包含团队共享的规则和项目特定上下文,如编码标准、架构决策及仅适用于该项目的常用工作流。
托管策略(组织级内存)
由 IT 或 DevOps 团队管理的组织级指令。这些文件存储在系统级路径中(例如 macOS 上的 /Library/Application Support/ClaudeCode/CLAUDE.md,Linux/WSL 上的 /etc/claude‑code/CLAUDE.md,或 Windows 上的 C:\Program Files\ClaudeCode\CLAUDE.md)。此内存用于公司级编码标准、安全策略和合规要求,适用于组织内的所有用户。
Claude Code 如何读取内存?
Claude Code 采用分层方法加载内存。从当前工作目录开始,它会递归向上搜索父目录以定位相关内存文件。所有发现的适用内存文件都会被加载到会话中并组合形成工作上下文。
这种设计允许 Claude Code 支持分层配置。全局偏好设置可与项目级规则共存,发生冲突时,更具体的指令会覆盖更宽泛的默认设置。
Claude Code 内存层级
Claude Code 将内存组织为多个层级,每个层级服务于不同目的。较高层级优先级更高,不能被较低层级覆盖:
Level 1 – 托管策略(最高优先级)
组织级规则,由 IT 或 DevOps 团队管理
-
位置:系统管理路径(例如 macOS 上的
/Library/Application Support/ClaudeCode/CLAUDE.md) -
范围:整个组织
-
覆盖行为:不可被覆盖
Level 2 – 用户内存
此文件记录适用于所有项目的个人偏好
-
位置:
~/.claude/CLAUDE.md -
范围:仅个人
Level 3 – 项目内存
此文件定义项目的共享规则和约定
-
位置:
./CLAUDE.md或./.claude/CLAUDE.md -
范围:团队共享并提交至版本控制
Level 4 – 项目规则
对于大型项目,内存可拆分为特定主题的规则文件
-
位置:
./.claude/rules/*.md -
范围:团队共享并提交至版本控制
Level 5 – 项目本地内存
允许对特定项目进行个人覆盖
-
位置:
./CLAUDE.local.md -
范围:仅个人,自动被 Git 忽略
同一层级发生冲突时,更具体的文件(更接近当前工作目录)优先级更高。
向上发现机制
启动时,Claude Code 从当前工作目录开始搜索内存文件,并继续向文件系统根目录方向搜索。
例如,以下目录结构:
/Users/edenmarco/
├── .claude/
│ └── CLAUDE.md
└── Desktop/
└── my-company/
├── CLAUDE.md
└── frontend/
└── CLAUDE.md
若从以下路径启动 Claude Code:
/Users/edenmarco/Desktop/my-company/frontend/
会加载以下内存文件:
frontend/CLAUDE.md(当前目录)
my-company/CLAUDE.md(父目录)
~/.claude/CLAUDE.md(用户级内存)
这三个文件组合形成有效上下文。
嵌套内存文件的懒加载
位于当前工作目录下方的内存文件不会立即加载。只有当 Claude Code 访问这些子目录中的文件时,才会懒加载这些内存文件。
例如,若在项目根目录启动 Claude Code,backend/ 目录内的内存文件不会被加载,直到 Claude Code 开始处理该目录下的文件。
在 Claude Code 中添加和编辑内存
可使用井号(#)字符添加内存,这会提示 Claude Code 将信息存储在相应内存文件中。对于较大幅度的修改,可使用 /memory 命令直接在代码编辑器中打开内存文件。
建议的最佳实践是保持内存文件简洁明确。过度填充模糊或过多信息会浪费 Token、引入困惑并降低结果质量。
使用内存可减少重复指令,确保跨会话输出一致。这使交互更高效、更聚焦,同时保留重要上下文。
若曾使用过 Cursor,此概念类似于 Cursor 规则。
使用 /init 初始化内存
Claude Code 还提供 /init 命令,可基于现有代码库初始化新的 CLAUDE.md 文件。运行时,Claude 会检查项目文件并生成包含相关上下文信息的 CLAUDE.md 文件,以支持未来交互。
本节主要侧重概念而非实操示例,后续章节将演示实际用法,帮助理解内存在真实工作流中的运作方式。
实操示例:在现有项目中使用内存
为进一步说明内存的实际工作原理,我使用一个为 LangChain 项目创建的现有仓库。该项目旨在从 LinkedIn 和 X 平台抓取信息并生成破冰话术。更多详情请访问 github.com/emarco177/IceBreaker。这是一个使用 LangChain Agent 构建的实用示例,非常适合演示 Claude Code 的能力。
我们首先将仓库克隆到新目录并在 Cursor 中打开。本示例中目录命名为 tmp3。打开后可查看完整项目结构,这是一个基于 LangChain 技术栈构建的 Python 项目。
Figure 3.11 – Cloned IceBreaker repository opened in Cursor
随后打开 Claude Code 并将其固定在界面中。当提示时,批准 Claude Code 访问和分析项目文件的请求。
第一步是运行 /init 命令为项目创建 CLAUDE.md 文件。运行初始化过程会导致 Claude 扫描仓库中的所有文件。它会识别技术栈、已安装包、所需环境变量及整体结构。基于此分析,Claude 生成捕获此信息的 CLAUDE.md 文件作为项目内存。
Figure 3.12 – Claude scanning repository files to generate CLAUDE.md
此过程中,Claude 会列出目录、搜索文件,并通过模式匹配和内容检查快速分析。读取文件后,它会生成建议的 CLAUDE.md 文件。
Figure 3.13 – Generated CLAUDE.md file with project overview and architecture details
生成的文件包含诸如如何使用 pip 安装依赖、如何运行项目以及主要组件概览等详细信息,包括抓取、摘要和代理逻辑。一经批准,该文件将成为项目记忆的一部分。
从现在起,发送给 Claude 的每个提示词都将包含此 CLAUDE.md 文件的内容作为上下文的一部分。
验证项目记忆
为确认记忆功能正常工作,我们首先重置对话以消除先前聊天记录的任何影响。使用 /clear 命令,然后再次提问。例如,我曾询问 Claude 项目使用的技术栈:
What stack am I using for this project?
输出应如下所示:
Based on the codebase analysis, your project uses this tech stack:
Backend Framework: Flask (Python web framework)
AI/LLM Framework: LangChain with OpenAI GPT models (GPT-4o-mini for agents, GPT-3.5-turbo for content generation)
Data Sources: Scraping (LinkedIn), Twitter API, Tavily (web search)
Package Management: Pipenv
Code Quality: Black (formatting), isort (import sorting), pylint (linting)
Testing: pytest
Output Parsing: Pydantic models
Frontend: HTML templates with Flask templating
Environment: Python 3.10+
The core architecture is a LangChain-powered AI pipeline that combines social media data scraping with LLM-based content generation.
Claude 在无需调用任何工具的情况下提供了准确的回答。这些信息是在初始化期间 Claude 分析文件时推断出来的。
至此,我们可以确认 Claude 依赖的是存储的记忆,而非聊天记录。
添加和使用记忆条目
现在让我们看看如何添加新的记忆条目。此时,如果我们提出一个问题,例如 What do I like to eat?,Claude 会生成类似以下的回答:
> what do i like to eat?
I don't have any information about what you like to eat. I can only see your codebase files and project structure, but there's no personal information about your food preferences in this ice breaker application repository.
If you'd like to share what you like to eat, I'd be happy to help with any related coding tasks!
为了让 Claude 能够回答这个问题,我们使用井号语法添加一条记忆条目。在本例中,我们声明我们喜欢吃披萨,并将该条目存储在项目记忆中:
# I like to eat pizza
添加此信息后,清除对话并再次提出相同的问题,Claude 现在将能够利用存储的记忆正确回答:
> what do i like to eat?
Pizza
如果我们想添加另一条记忆条目,重复相同的过程并添加一条声明偏爱汉堡的新条目。这一次,该条目被存储在用户记忆中,位于 ~/.claude/CLAUDE.md。清除对话并再次尝试提问。Claude 将正确回忆起这两种偏好:
> what do i like to eat?
Based on your CLAUDE.md files, you like to eat both Hamburger (from your global preferences) and Pizza (from your project-specific memory).
同样的方法可用于其他类型的持久化信息,例如偏好的编码风格、常用工具,或我们希望 Claude 在跨项目和跨会话中记住的反复出现的工作流约定。
使用多个记忆文件
随着项目的增长,单个 CLAUDE.md 文件可能会变得庞大且难以管理。Claude Code 支持在代码库中分布使用多个 CLAUDE.md 文件。Claude 会递归遍历目录结构,并将所有相关的记忆文件加载到上下文中。
这使得记忆能够以结构化的方式进行组织。例如,服务端上下文可以位于一个区域,前端上下文位于另一个区域,而 DevOps 或 Claude 专用规则则位于别处。这种方法使记忆更易于维护且更具针对性。
结合钩子使用时,这种设置能实现更高级的行为。例如,根据正在进行的工作类型,可以附加不同的记忆文件。上下文切换钩子可以在处理数据库代码时附加数据库相关的记忆、在处理 UI 组件时附加前端上下文、或在处理后端逻辑时附加 API 相关的记忆。
这种级别的控制允许根据用户输入和工作流需求动态定制记忆,为更高级和灵活的上下文管理模式打开了大门。
Claude Code 中的倒带功能
在本节中,我们将探讨 Claude Code 的检查点和倒带功能,该功能允许您在编码会话中安全地撤销更改。Claude Code 会自动跟踪每个提示词创建的文件修改,使得在需要时可以回滚不需要的编辑。
要触发倒带,请按两次 Esc 键或使用 /rewind 命令。
倒带功能的优势与重要性
该功能的价值显而易见:
-
在尝试更大或更激进的更改时提供安全网
-
允许在不丢失工作代码的情况下探索替代实现
-
使从错误中恢复变得快速且可预测
-
通过让撤销操作变得简单,降低了纠正 AI 生成错误的成本
-
增强了用户在使用 AI 辅助编码时的信心
-
通过降低使用 AI 工具的感知风险,鼓励更广泛的采用
-
它与 AI 恢复成本 (CAIR) 指标密切相关(
www.blog.langchain.com/the-hidden-metric-that-determines-ai-product-success/),该指标衡量用户从 AI 错误中恢复的难易程度,并在课程后面重新探讨
倒带功能在 Claude Code 最初发布几个月后引入。
图 3.14 – Claude Code 发布时间线及倒带功能引入
社区强烈呼吁倒带功能,且在它成为原生功能之前,已有多个开源工具尝试提供类似功能。如今,倒带功能直接内置于 Claude Code 中,且直观易用,几乎无需解释。为了解实际上倒带功能是如何显示和工作的,让我们简要回顾一下使用它的界面上下文。
实战中的倒带使用
在撰写本书时,Claude Code 运行的是 2.1 版本。界面包含若干近期更新,包括视觉优化和 Sonnet 4.5 的使用,后者是 Anthropic 针对编码任务优化的最新模型。您还会注意到界面底部有一个自定义状态行。这是用户自定义的,将在本书后面介绍。
为了演示倒带功能,我们从一个简单的 Next.js 示例开始:
- 向 Claude Code 提问,例如:
How do I bootstrap a Next.js project?
提示词在本地执行。设置完成后,使用 npm run dev 运行应用程序并在浏览器中打开。正如预期的那样,这将生成标准的 Next.js 样板应用程序。
-
然后我们有意对代码库应用一系列简短的增量更改。此处的目的不是评估用户界面的质量,而是模拟一个真实的开发工作流,其中更改可能稍后需要撤销。在我的示例中,我将执行以下操作:
-
首先,提示 Claude Code 为 HooksHub 创建一个具有视觉差异化风格的着陆页
-
接着,提示 Claude Code 添加一个常见问题解答 (FAQ) 部分
-
最后,提示 Claude Code 添加一个页脚部分
-
图 3.15 – 使用 Claude Code 生成的 HooksHub 着陆页
每个提示词都会导致文件编辑,这些编辑可通过 diff 视图查看,且每项更改都会即时反映在正在运行的应用程序中。
添加页脚后,显而易见,尽管该功能正常工作,但结果比预期更沉重、视觉上更具主导性。这是一个自然的节点,此时撤销更改比手动编辑代码或发出修正提示词更为合适。
3. 要还原更改,请使用 /rewind 命令调用倒带功能
这将打开当前会话的时间线,显示迄今为止发出的所有提示词,并指示哪些提示词导致了文件修改。
图 3.16 – 使用 /rewind 命令查看会话历史记录和文件更改
仅生成解释的提示词显示时不带关联的文件更改,而修改文件的提示词则清晰地显示受影响的文件和行。
4. 为您的示例选择最后添加的提示词
在本例中,选择添加页脚的那个提示词。将向您显示三个选项:
-
还原代码和对话,将文件和聊天上下文同时重置至该时间点
-
还原对话,保留文件更改不变
-
还原代码,保留对话历史不变
在实践中,同时还原代码和对话是最常见的选择,因为它能将项目恢复到干净一致的状态。仅还原代码在您希望保留对话上下文并重新处理实现时很有用。
5. 为了演示这一点,仅还原与页脚相关的代码更改
页脚立即从应用程序中移除。之所以有效,是因为 Claude Code 在应用任何文件编辑之前会自动创建一个检查点。
每个导致代码更改的提示词都会创建一个新的检查点。这些检查点跨会话持久化,并保留长达 30 天,为实验和迭代提供了安全网。
由于对话历史仍然存在,现在可以发出后续提示词,例如 create a footer, make it minimalistic(创建一个页脚,使其极简化)。Claude Code 利用现有上下文正确解析引用,并生成了更轻量的实现。刷新应用程序确认更新后的页脚更符合预期设计。
虽然倒带功能强大,但它也有局限性
-
Claude Code执行的Bash命令不被跟踪,无法还原 -
在
Claude Code外部进行的手动编辑不会被检查点捕获 -
倒带功能不能替代
Git等版本控制系统 -
检查点应被视为本地、短期的撤销功能,而非永久历史记录
正确使用时,倒带功能能显著降低实验成本。它鼓励探索,降低更改风险,并使与 Claude Code 的迭代开发更安全、更高效。
Claude Code 中的自定义斜杠命令(由 Skills 提供支持)
在本节中,我们将回顾如何在 Claude Code 中创建自定义斜杠命令。此功能非常强大,因为它赋予了开发者高度的灵活性,可定制和扩展 Claude Code。我们将通过定义一个用于创建 Git 提交信息的技能来创建一个自定义斜杠命令。更高级的技能将在 第 7 章 中介绍。
创建技能
我们将从一个干净的项目开始,并切换到 custom‑commands 分支。要创建技能,首先在项目中创建一个 .claude 目录(如果尚不存在)。在其中创建一个 skills 目录。
-
每个技能都定义为其自己的目录:
.claude/skills/commit-code/ -
在该目录中,创建一个名为以下内容的必需文件:
SKILL.md技能定义为 Markdown 文件。元数据使用位于
SKILL.md顶部的 YAML 前言声明,包含在---分隔符之间。文件正文包含实际的提示词,以 Markdown 编写。 -
为文件添加标题。此标题显示在斜杠命令菜单中。
-
编写命令提示词:
Review the files that have changed, and create a commit with a commit message summarizing the changes made. Always try to give short and concise messages that convey the business logic.我请求
Claude Code查看已更改的文件,并创建一个提交,其提交信息总结所做更改,始终尝试给出简短且简洁的信息以传达业务逻辑。
虽然提示词本身很短,但 Claude Code 能够推断并执行多项操作。它可以使用 Git 命令检查已更改的文件,审查差异,并创建提交。这演示了单个技能如何封装一系列动作。
执行技能
要测试该命令,打开 Claude Code 并输入 /。新的 commit‑code 命令应出现在列表中。执行它将导致 Claude Code 运行 Markdown 文件中定义的提示词。
Claude Code 还会检测 .claude 目录中的未跟踪文件,并询问是否应添加它们。任何批准的决定将存储在 settings.local 中。随后 Claude 将根据检测到的更改提出提交信息,并显示相应的 Git 命令。
但如果生成的提交信息不够描述性怎么办?我们不继续执行,而是停下来改进技能。
使用 $ARGUMENTS 改进技能
前往开头添加的初始提示词并更新命令提示词。在我的示例中,我要求 Claude Code 通过引入 $ARGUMENTS 占位符来接受用户提供的提示。
我们在调用技能时可以传递参数。参数通过 $ARGUMENTS 占位符获取。
调用技能时,技能名称后面跟随的任何内容都将替换 $ARGUMENTS 占位符。更多相关内容将在 第 9 章 中介绍。
Review the files that have changed, and create a commit with a commit message summarizing the changes made. Always try to give short and concise messages that convey the business logic.
Use user hints to be the message main subject $ARGUMENTS
进行此更改后,再次执行 /commit‑code 并提供与技能相关的主题提示:
/commit-code custom code
Claude Code 现在应生成更具描述性的提交信息,反映请求的更改。
批准后,提交被创建,由 Claude 共同编写。然后我们通过运行 git push 将更改推送到远程仓库,并在项目的 custom‑commands 分支中验证提交。
您也可以通过以下步骤创建并执行额外的技能:
-
创建一个带有适当标题的新命令文件
-
定义一个基于用户输入产生输出的提示词
-
附加参数,以便命令可在运行时接受动态值
重启 Claude Code 后,新命令变为可用,并可使用用户提供的输入执行。这展示了技能如何支持动态和灵活的行为。
通过上下文工程改进自动生成的提交信息
早些时候,我们讨论了上下文工程。为了使其更具体,让我们看一个直接取自 Claude Code 文档的具体用例:
---
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*)
description: Create a git commit
---
## Context
- Current git status: !`git status`
- Current git diff (staged and unstaged changes): !`git diff HEAD`
- Current branch: !`git branch --show-current`
- Recent commits: !`git log --oneline -10`
## Your task
Based on the above changes, create a single git commit.
此示例展示了一种技能,它执行与生成提交消息相同的任务,但方式更稳健、更安全、功能更丰富。理解这种方法为何更好,有助于阐明上下文工程、工具控制和代理设计在实践中是如何结合在一起的。
在技能中,我们可以运行 Shell 和 Bash 脚本。这意味着我们可以将任意代码作为命令的一部分来执行。因此,我们可以发起 HTTP 请求、运行容器,或执行任何可用代码表达的其他操作。这实际上消除了技能能力的大多数限制。
在这个特定的斜杠命令示例中,配置首先定义了一组允许使用的工具。这通过限制代理被允许使用的工具来限制其范围。
如果你有实现代理的经验,这符合最小权限原则。其理念是界定代理的范围,使其仅拥有执行任务所需的最小能力集合。对于生成提交消息的情况,必要的操作仅限于诸如 git add、git status 和 git commit 等命令。
以这种方式限制工具集可以提高安全性。在早期较简单的 commit-message 命令中,未应用此类限制,这意味着代理可以访问 Claude Code 中所有可用的工具。在这种情况下,如果上下文被污染(例如,通过恶意输入),代理可能会在系统上执行意外操作。这是文档示例成为更强大、更安全设计的原因之一。
此示例还演示了深思熟虑的提示工程。上下文被显式定义并精心构建。在生成提交消息之前,命令会执行一系列 Git 命令,例如 git status、git branch 和 git log。这些命令提供了关于仓库状态和待提交变更的精确上下文。
从这个角度来看,该工作流与检索增强生成非常相似。首先,系统通过运行 Git 命令收集上下文来检索相关信息。一旦该上下文可用,生成步骤就会产出提交消息。
这说明了检索和生成是如何在一个定义良好的单一命令中结合的。它还展示了前面讨论的多个概念,包括上下文工程、工具限制和代理设计,是如何以实用且可扩展的方式结合在一起的。
总体而言,这种方法为利用 Claude Code 中的技能构建更安全、更强大的工作流开辟了广阔的可能性。
位于 --- 分隔符之间的部分称为前置元数据,并在提示词主体之前进行求值。
总结
在本章中,你学习了如何在基础之上配置和使用 Claude Code。我们从高层介绍了认证和定价,如何使用斜杠命令控制 Claude Code,以及如何将其直接集成到 IDE 中以获得更流畅的工作流。你探索了配置选项、用于自动化的钩子、通过 CLAUDE.md 文件实现的记忆,以及上下文如何在会话间加载和复用。我们还考察了用于安全撤销变更的检查点和倒带功能,以及用于封装可重复工作流并进行适当工具作用域划分的技能。至此,你应该了解 Claude Code 在实践中是如何运作的,如何使其保持安全和可预测,以及如何塑造其行为以支持更高级、长期运行的开发工作流。
在下一章中,我们将探讨模型上下文协议 以及它如何标准化 AI 应用程序与外部工具之间的集成。
获取本书的 PDF 副本、代码包等
扫描二维码(或访问 packtpub.com/unlock)。按名称搜索本书,确认版本,然后按照页面上的步骤操作。
注意:请准备好发票。直接从 Packt 网站购买不需要发票。
第二部分:扩展 Claude Code:协议、自动化与结构化工作流
在本书的第 2 部分中,重点从个人使用转向结构化扩展和自动化。你将了解 Claude Code 如何通过模型上下文协议 (MCP) 连接到外部工具和服务,以及这些集成是如何被负责任地配置和管理的。我们将通过 GitHub 工作流和事件驱动执行来探讨自动化在实践中是如何运作的。
随着系统变得更加复杂,结构变得至关重要。你将探索基于规划的开发、协调的多代理工作流,以及用于隔离上下文以实现更安全执行的子代理。你还将了解输出样式和配置模式如何塑造行为并强制一致性。在本部分结束时,你将能够设计出深思熟虑、受控且可扩展的工作流。
本部分包含以下章节:
-
第 4 章,《使用 MCP 服务器和插件扩展 Claude Code》
-
第 5 章,《使用 Claude Code 和 GitHub 自动化你的开发工作流》
-
第 6 章,《Claude Code 规划与多代理工作流》
-
第 7 章,《使用 Claude Code 子代理》
-
第 8 章,《创建和自定义输出样式》
4 使用 MCP 服务器和插件扩展 Claude Code
模型上下文协议 (MCP) 为 AI 应用程序提供了一种标准化方式,通过通用接口连接到工具、数据源和服务。开发者无需为每个宿主应用程序构建单独的集成,只需在 MCP 服务器中实现一次功能,即可跨任何兼容 MCP 的客户端复用。MCP 的引入旨在解决这一集成挑战。这一抽象层实现了互操作性、可移植性和生态系统增长。在 Claude Code 的语境下,MCP 变得尤为重要,因为它使开发者能够以结构化且可复用的方式,为编码代理扩展额外的工具、能力和集成。
在本章中,你将了解什么是 MCP、为何创建它以及它在实践中如何工作。你将探索 MCP 解决的集成问题,并考察其核心架构组件:宿主、客户端和服务器。通过实际演示,你将把 MCP 服务器连接到 Claude 和 Cursor 等 AI 应用程序,配置本地和远程 MCP 服务器,并理解工具如何通过协议暴露和调用。
你还将考察重要的运维因素。尽管 MCP 功能强大,但它也带来了与上下文管理、性能和执行效率相关的挑战。本章探讨了减少上下文污染的上下文工程策略、合理界定 MCP 配置作用域,以及在会话中动态管理服务器的方法。此外,你将了解 Claude Code 插件如何将 MCP 服务器和相关组件打包成可复用、可共享的单元,从而实现团队级的标准化。
本章的总体目标是帮助你建立扎实的 MCP 概念和实践基础。在最后,你将不仅理解 MCP 如何实现跨平台工具集成,还将掌握如何在真实世界的 AI 系统中负责任地配置和管理它。
这一知识很重要,因为 MCP 正迅速成为基于代理架构中的基础层。随着 AI 开发转向工具增强和自主系统,理解 MCP 的架构、优势和权衡,将使你能够设计可扩展、高效且可互操作的 AI 应用程序。
在本章中,我们涵盖以下主题:
-
为什么需要 MCP?
-
MCP 核心架构
-
MCP 实战
-
将 Claude Code 连接到 MCP 服务器
-
MCP 作用域速查表
-
MCP 生态系统中的上下文工程
项目级 MCP 配置
MCP 的当前局限性
使用 Claude Code 插件管理配置
虽然本书以 Claude Code 为核心,但 MCP 是一个跨平台协议,受多种 AI 开发工具支持。为了演示方便,本章在部分示例中使用了 Cursor。其底层概念保持一致,适用于使用 Claude Code 的场景。
为什么需要 MCP?
MCP 得到了快速普及,引发了广泛讨论,并涌现了大量 MCP 服务器实现。许多 AI 应用(包括 Claude Code 和 Cursor 等工具)都在其系统中集成了 MCP。
在详细定义 MCP 之前,了解它所解决的需求至关重要。
集成问题
设想一个 AI 智能体,设计用于执行发送 Slack 消息、读取和发送电子邮件、查询数据库等操作。要启用这些能力,必须直接实现所需功能。这涉及使用 Slack 或 Gmail 等 API,并编写自定义代码将这些集成封装为智能体可访问的工具。
图 4.1 – 智能体通过 API 与 Slack、Gmail 和数据库集成
在许多情况下,需要自定义实现。例如,电子邮件集成可能会有意排除 Gmail API 的删除端点,以防止意外数据丢失。因此,集成逻辑是根据特定需求量身定制并手动实现的。
框架可能提供内置工具。例如,框架可能包含一个涵盖完整 API 接口的预实现 Gmail 集成。此类工具可开箱即用,满足通用需求。然而,无论使用内置工具还是自定义工具,都必须在特定的智能体环境中集成功能。
一旦实现,智能体就能发送邮件、发布 Slack 消息或执行数据库查询。该集成在该特定智能体内生效。
可移植性挑战
假设该智能体被广泛采用,其他团队希望在不同环境中使用其功能。
例如,考虑一个最初构建用于在 Cursor 环境中运行的智能体。在此设置中,智能体通过各自的 API 与 Slack、Gmail 和数据库等外部服务集成。下图说明了这种架构。
图 4.2 – 智能体与 Cursor 环境及其 API 集成耦合
在这种情况下,智能体与 Cursor 环境紧密耦合。与 Slack、Gmail 和数据库的集成是专门为该设置实现的。
现在假设我们要将相同的智能体能力集成到 Claude Code 中。尽管功能在概念上相同,但集成无法直接复用。因为实现是专门为我们的智能体编写的,所以必须为 Claude Code 重新创建集成。
因此,发送 Slack 消息、与 Gmail 交互或执行数据库查询等类似能力需要为新环境重新实现。如果我们想集成到 Cursor 怎么办?
图 4.3 – 为 Claude Code 环境重新实现智能体集成
扩展对 Cursor、Bolt、GitHub Copilot 或其他 AI 代码助手等其他环境的支持需要重复此过程。每次新增集成都会引入额外的实现工作。相同的功能必须为每个目标系统单独适配。
MCP 作为抽象层
可移植性挑战造成了一个反复出现的集成问题。每当相同功能需要在不同环境中使用时,开发人员都必须从头重建集成。
MCP 通过引入额外的抽象层来解决这一问题。软件工程中有一条著名原则:
“我们可以通过引入一个额外的间接层来解决任何问题。”
—— Andrew Koenig
这一想法与软件工程基本定理密切相关,该定理指出,许多复杂的系统问题可以通过增加一个抽象层来简化。MCP 服务器即服务于此目的。
开发人员不再将功能分别集成到每个智能体中,而是将实现一次性集成到 MCP 服务器中。支持 MCP 的智能体随后可以直接连接到该 MCP 服务器。
图 4.4 – MCP 服务器作为外部服务的统一集成层
采用这种方法,兼容性只需实现一次。一旦能力通过 MCP 服务器暴露,它们就可以在任何支持该协议的平台上使用。最初为 Cursor 实现的能力可兼容 Claude Code 和其他支持 MCP 的环境,无需额外的集成逻辑。
开发人员无需为每个平台重写或复制集成代码。任何支持 MCP 的系统都可以连接并无缝使用该功能。
网络效应与生态增长
MCP 的增长反映了类似社交平台的网络效应。用户基数较小的社交应用提供的价值有限。随着采用率提高和用户贡献内容,系统变得更有价值,形成增长的强化循环。
MCP 也出现了类似动态。随着采用率提高和更多 MCP 服务器的开发,生态系统不断扩大。不断增加的实现拓宽了可用集成和能力的范围,提升了协议的整体效用。
奠定这一基础后,下一步是探究 MCP 的核心架构及其在实践中的运作方式。
MCP 核心架构
MCP 标准化了应用程序向 大语言模型 (LLMs) 提供上下文的方式。上下文可以采取多种形式。它可能包含追加到提示词的额外信息、要调用的工具规范,甚至提示词本身。
图 4.5 – 连接主机、客户端和 MCP 服务器的 MCP 核心架构
从这个意义上讲,上下文涵盖了塑造 LLM 响应方式的支持数据和操作指令。
一旦此类标准被广泛采用,它就能在 AI 应用中实现强大且可扩展的集成开发。
MCP 的优势
MCP 文档 (modelcontextprotocol.io/) 强调了采用 MCP 的几大优势:
-
首先,MCP 支持广泛的集成、工具和数据源生态系统,可模块化地连接到由 LLM 驱动的应用程序。例如,作为 AI 驱动的编码智能体,
Claude Code利用 MCP 通过结构化工具集成扩展其能力。 -
其次,MCP 降低了对特定 LLM 供应商或 AI 应用提供商的耦合。开发人员可以将核心功能实现为工具,并通过 MCP 服务器暴露它们。这些工具随后可跨不同供应商和主机应用程序复用,无需修改。
-
开源框架(如 LangChain)解决了 AI 工程中一些重叠的挑战。然而,MCP 与 LangChain 处理这些问题的方式不同,且它们的解决方案并不直接重叠。例如,两者都可能支持可扩展性,但其机制和架构含义有所不同。
MCP 的核心组件
MCP 架构由三个主要组件组成:MCP 主机、MCP 服务器和 MCP 客户端。
MCP 主机
MCP host 是支持 MCP 的 AI 应用程序。示例包括 Claude Desktop、开发环境(如 Claude Code 或 Cursor)以及专用 AI 代理。这些应用程序通过 MCP 进行增强,将它们连接到原生不可用的额外工具、数据源或产品。
图 4.6 – MCP 主机通过 MCP 客户端连接到 MCP 服务器
MCP 服务器
MCP servers 向 MCP 主机暴露功能。这些功能可能包括以下内容:
-
访问外部工具,例如调用 API 以检索天气信息
-
数据库搜索功能
-
知识资源,如 PDF 或大型文本
图 4.7 – MCP 服务器向 MCP 主机暴露工具、数据库和外部 API
MCP 服务器充当网关或代理,根据 MCP 规范暴露这些工具、资源和提示。
图 4.8 – MCP 服务器充当网关,提供对外部资源的标准化访问
为了符合协议,MCP 服务器会实现特定的方法,例如以下方法:
-
listPrompts -
getPrompt -
listTools -
callTool -
listResourceTemplates -
进度通知机制
一旦实现,MCP 服务器即可连接到任何支持该协议的 MCP 主机。因此,一次编写的功能可跨多个主机应用程序复用。这种可复用性是 MCP 的核心架构优势。
MCP 客户端
MCP 客户端位于 MCP 主机内部。它使用 MCP 实现主机与 MCP 服务器之间的通信。
图 4.9 – 主机内的 MCP 客户端管理与 MCP 服务器的通信
例如,要将天气 MCP 服务器连接到 Claude Desktop,Claude Desktop 内部的 MCP 客户端会管理与该服务器的交互。客户端和服务器完全通过定义的协议进行通信。
MCP 客户端与 MCP 服务器之间存在一对一关系。单个 MCP 客户端无法与多个 MCP 服务器通信。因此,如果 MCP 主机需要连接到多个 MCP 服务器,它必须为每个服务器实例化多个 MCP 客户端,每个服务器一个。
图 4.10 – 多个 MCP 客户端将主机连接到不同的 MCP 服务器
这种结构完成了 MCP 的核心架构,并为构建可互操作、可扩展的 AI 应用程序奠定了基础。
MCP 实战
现在让我们演练一个添加和配置 MCP 服务器的实际示例。该演示展示了 MCP 启用的功能以及这些功能在实践中如何运作。该示例将实现天气检索功能的 MCP 服务器连接到两个不同的客户端:Claude Desktop 和 Cursor。
这两种情况使用的是同一个 MCP 服务器。配置细节单独讨论;此处重点关注服务器连接后的结果行为。任何支持 MCP 协议的客户端都可以使用此功能,包括 Claude Code、Claude Desktop、Cursor、Claude Code、Lovable 和其他兼容客户端。
未连接 MCP 服务器时的行为
在 Claude Desktop 中,开发者设置中最初未配置 MCP 服务器。例如,在未连接 MCP 服务器的情况下查询旧金山的天气时,语言模型通常会回答它无法访问实时天气信息。在某些情况下,它可能会尝试调用搜索工具以检索摘要信息。
没有 MCP,模型仅限于其训练数据,无法直接检索实时数据,除非通过通用的内置工具(如搜索)。
连接 MCP 服务器
配置天气 MCP 服务器后,它会出现在 Claude 的开发者设置中,并显示其运行时详情。
图 4.11 – 天气 MCP 服务器在 Claude 开发者设置中已配置
当再次查询旧金山的天气时,系统会提示请求权限在本地执行天气工具。工具执行需要批准,因为它可能涉及运行本地代码。与工具执行相关的安全考量将单独讨论。
安全警告: MCP servers can run code on your machine
MCP 服务器在本地运行代码,拥有与您的用户账户相同的权限。这意味着它们可以访问您系统上的文件、环境变量和网络资源。
添加 MCP 服务器前,请注意以下风险:
-
MCP 服务器可以在您的机器上执行命令,包括读取、修改或删除文件。
-
恶意服务器可能将敏感信息(如源代码、环境变量或 API 密钥)发送到外部服务。
-
来自 MCP 服务器的工具响应可能包含隐藏指令,从而影响模型行为。
像对待任何第三方依赖一样对待 MCP 服务器。尽可能审查源代码,从可信维护者处安装服务器,并避免使用提升的权限运行 MCP 服务器。
一旦授予 Claude Code 调用 MCP 工具的权限,将发生以下序列:
-
MCP 服务器包含检索天气数据的逻辑
-
服务器暴露一个名为
getForecast的函数 -
getForecast函数接受两个参数:纬度和经度 -
语言模型(Claude Sonnet 3.7)确定对应旧金山的纬度和经度
-
模型向
getForecast函数发出 MCP 调用 -
MCP 服务器执行该函数并返回响应
-
语言模型处理响应并生成最终答案:
图 4.12 – Claude 调用 MCP 天气工具并返回预测响应
结果是基于通过 MCP 服务器检索的实时数据生成的天气报告。
虽然检索天气数据是一个简单的示例,但底层机制支持任意逻辑。任何功能都可以在 MCP 服务器中实现。通过实现 MCP 协议,开发者使兼容的客户端能够通过工具调用来调用该功能。这将 AI 代理扩展到静态模型能力之外,并允许它们执行外部逻辑。
跨客户端复用同一 MCP 服务器
同一个天气 MCP 服务器可以连接到 Cursor。配置后,MCP 服务器会出现在 Cursor 设置的 MCP 选项卡中。
图 4.13 – Claude 调用 MCP 天气工具并返回预测响应
连接的服务器及其暴露的工具将被列出:
-
GetAlerts -
GetForecast
该配置还显示了用于运行服务器的命令,在本例中为 Node.js 服务器。在 Cursor Chat 中,使用代理模式时可使用 MCP 功能。
图 4.14 – 在代理模式下从 Cursor 调用 MCP 天气工具
当查询旧金山天气时代理会使用适当的参数调用 GetForecast 工具。在此配置中,Cursor 以 YOLO 模式运行,意味着工具会自动执行,无需人工批准。虽然这种方法很方便,但会带来安全隐患。
代理执行以下操作:
-
使用纬度和经度参数调用
GetForecast工具。 -
从 MCP 服务器接收天气数据。
-
判断天气预警可能也相关。
-
调用
GetAlerts工具检查旧金山的预警情况。 -
将响应编译成最终答案,同时包含天气状况和任何活动预警。
在本例中,单个提示词中调用了两个工具。代理自主决定调用哪些工具以及如何将其结果整合为连贯的回复。
天气示例演示了一种通用模式:MCP 使 AI 代理能够执行 MCP 服务器中定义的外部逻辑。支持 MCP 的客户端可以连接到这些服务器并调用其工具。
通过在服务器中实现 MCP 协议,开发者使其功能可被任何兼容的 MCP 客户端访问。这消除了静态模型知识施加的限制,并允许代理执行动态、实时和自定义操作。
将 Claude Code 连接到 MCP 服务器
我们从一个空项目和本书 GitHub 仓库中一个名为 project/MCP 的空分支开始。要访问该仓库,请遵循前言中下载示例代码文件部分的步骤。然后我们使用 /mcp 斜杠命令列出可用的 MCP 服务器。此时,未列出任何 MCP 服务器。
图 4.15 – 使用 /mcp 命令在 Claude Code 中列出可用的 MCP 服务器
有一个链接可通往 MCP 文档,其中解释了如何添加 MCP 服务器。有多种方法可以做到这一点:
-
通过文件添加 MCP 服务器
-
使用 CLI 添加 MCP 服务器
MCP 服务器可以通过文件添加;不过,推荐使用 CLI。CLI 通常是最新的,如果格式发生变化或 API 失效,使用 CLI 可确保兼容性。
通过 CLI 添加 Context7 MCP 服务器
Context7 (context7.com/) 为大量包提供最新文档。许多包(尤其是 AI 生态系统中的包,如 LangGraph)更新频繁,拥有最新文档可确保生成的代码与最新 API 保持一致。
Context7 索引了近 30,000 个 (github.com/upstash/context7) 包。
撰写本文时,该仓库拥有约 49,200 颗星。
要将 Context7 与 Claude Code 结合使用,需要 Claude Code 集成。命令如下:
claude mcp add --transport http context7 https://mcp.context7.com/mcp
该命令执行以下操作:
-
使用
claude mcp add -
指定 HTTP 作为传输方式
-
分配 MCP 名称
context7 -
提供 MCP 服务器的 URL
这是一个远程 MCP 服务器,意味着服务器不在本地运行。相反,它运行在 Context7 服务器上。
每次调用都会向远程服务器发送请求。这种方法具有以下优势:
-
服务可以轻松扩展
-
MCP 可从多个客户端访问
HTTP 传输和远程 MCP 服务器在以下 MCP 课程中有更详细的解释:www.udemy.com/course/model-context-protocol/。
将该命令复制并粘贴到终端中。执行前,添加 --help 标志以便您查看可用选项。
MCP 服务器作用域与配置
帮助输出显示可以配置 MCP 服务器的作用域。MCP 服务器可以存在于以下作用域:
-
用户作用域
-
项目作用域
-
会话作用域
也可以为环境变量或 HTTP 标头提供可选值。
图 4.16 – 使用 mcp add 命令向项目添加 MCP 服务器
在本例中,添加 MCP 服务器时选择了项目作用域。
执行后,将创建一个包含 Context7 MCP 配置的新文件。该配置指定了 HTTP 传输类型和 MCP 服务器的 URL。
{
"mcpServers": {
"context7": {
"type": "http",
"url": "https://mcp.context7.com/mcp"
}
}
}
要在本地运行 MCP 服务器而非远程运行,可以使用以下替代命令:
claude mcp add context7 -- npx -y @upstash/context7-mcp
该命令使用 npx 下载仓库并在本地执行。
重启 Claude Code 并启用 MCP 服务器
安装 MCP 服务器后,必须重启 Claude Code。退出会话,清空终端,再次启动 Claude。
图 4.17 – 重启后 Claude Code 检测并启用已配置的 MCP 服务器
启动时,Claude 将检测 mcp.json 文件并提示请求连接到已配置 MCP 服务器的权限。选择第一个选项以允许连接。
随后,Claude 会为当前用户会话创建一个 settings.local.json 文件。打开该文件可确认 Context7 MCP 服务器已启用,允许 Claude 在需要时查询它。
列出并检查已安装的 MCP 服务器
现在可以列出 MCP 服务器。我们可以看到 Context7 MCP 服务器已连接。
图 4.18 – 列出已安装的 MCP 服务器并检查已连接的 Context7 服务器
点击进入可看到它暴露了两个工具:
-
resolve-library-id -
get-library-docs
这些工具描述成为代理上下文的一部分,允许代理根据需要动态调用工具。例如,当请求最新的 LangGraph 文档时,代理首先调用 resolve-library-id 以获取适当的上下文 ID,然后调用 get-library-docs 以检索最新文档。
使用 Context7 MCP 服务器查询 LangGraph
我们可以提出以下问题,并指定应使用 Context7 MCP 服务器:
LangGraph 的最新版本是什么?
Claude Code 请求调用 Context7 MCP 工具的权限。我们批准该请求,权限会更新在 settings.local.json 中。
图 4.19 – 调用 Context7 MCP 工具检索最新 LangGraph 版本
MCP 服务器解析库 ID,然后发起另一个请求以检索文档。
根据 Context7 返回的文档,LangGraph 的最新版本报告为 1.2。
LangGraph 是一个活跃演进的框架。您可能会遇到比此处演示版本更新的版本;不过,此处讨论的架构概念和模式依然适用。
在项目记忆中持久化 MCP 服务器用法
我们将 Context7 配置为每次询问关于 LangGraph 的问题时都使用。为此,我们添加一条指令并将其保存到项目记忆中,以便跨会话持久化。
该指令已记录,并将创建一个Claude.md文件,包含以下条目:
When discussing LangGraph, always use context7 MCP
验证持久化 MCP 行为
我们可以重启 Claude、清除会话,并提出以下问题:
What is a LangGraph interrupt?
Claude Code 会自动选择 Context7 MCP 服务器。它会解析 LangGraph 库,检索相关文档和代码片段,并返回关于 LangGraph 中断的解释。
图 4.20 – Claude 自动使用 Context7 MCP 服务器解释 LangGraph 中断
由于 Context7 提供对当前文档和 API 的访问,生成的代码反映了最新的用法。
将 MCP 工件提交至版本控制
我们可以将生成的文件添加到 GitHub 仓库。我们使用提交信息context7 mcp提交更改,并通过以下命令推送到上游:
git commit -m "context7 mcp"
该提交可在本书的 GitHub 仓库中找到。要访问仓库链接,请遵循前言中下载示例代码文件部分的步骤。
MCP 作用域速查表
选择正确的作用域有助于保持环境有序,并防止不必要的配置泄露到无关项目中。下表总结了何时使用每种 MCP 作用域:
| 方面 | 项目作用域 | 用户作用域 | 会话作用域 |
| --- | --- | --- | --- |
| 配置位置 | 项目根目录下的.mcp.json | ~/.claude/settings.json | 通过‑‑mcp‑config标志启动或会话中途添加 |
| 可见性 | 项目中的每个人 | 仅你,跨所有项目 | 仅当前会话 |
| 提交到 Git? | 是 | 否 | 否 |
| 跨会话持久化? | 是 | 是 | 否 |
| 与团队共享? | 是 | 否 | 否 |
表 4.1 – MCP 作用域对比:项目、用户和会话
何时使用各种 MCP 作用域
以下指南说明了各作用域的常见适用场景。
-
项目作用域(
.mcp.json)-
当 MCP 服务器是项目共享开发环境的一部分时,使用项目作用域。
-
特定于此项目的数据库工具(例如项目的 Postgres MCP)
-
特定于项目的 API,如内部服务或预发布环境
-
整个团队需要的自定义工具,如部署脚本或测试运行器
-
与项目技术栈相关的文档服务器
-
-
用户作用域(
~/.claude/settings.json)-
将用户作用域用于个人工具或与您自己的凭据相关的工具。
-
个人生产力工具(Slack、Linear、Notion)
-
与您的凭据相关的工具,如带有您 PAT 的 GitHub 或电子邮件访问
-
您希望在所有项目中可用的通用服务器(例如 Tavily 搜索或 Context7 文档)
-
依赖您不想提交到仓库的机密信息的服务器
-
-
会话作用域(
‑‑mcp‑config/临时性)-
将会话作用域用于不应持久化的临时或实验性设置。
-
一次性调试服务器,如临时代理或模拟 API
-
您正在评估的实验性或不受信任的服务器
-
依赖短期令牌的服务器(OAuth 会话或临时凭据)
-
在运行期间动态启动服务器的 CI/CD 环境
-
MCP 生态系统中的上下文工程
在本节中,我们将介绍 MCP 生态系统中的上下文工程。示例使用 Claude Code,但这些概念适用于任何支持 MCP 的智能体系统。
图 4.21 – 有限 LLM 上下文窗口内的良好与不良上下文使用
上下文是智能体系统中最昂贵且最有限的资源,尤其是在智能体编码工作流中。上下文直接影响智能体性能。不良的上下文会导致智能体性能不佳。本讨论仅关注性能影响,故意排除定价和延迟考量。
图 4.22 – 上下文工程:通过仅加载必要上下文来减少 Token
上下文低效最隐蔽但影响最大的来源之一是 MCP 配置。MCP 功能强大,但如果不小心使用,会显著降低上下文效率。主要问题是 MCP 可能会用不必要的 Token 使上下文窗口膨胀,这些 Token 属于当前任务不需要的工具。
问题——过于通用的 MCP 配置
上下文低效问题的根本原因是过于通用的 MCP 配置。当 MCP 服务器配置过于宽泛时,智能体会在处理任何请求之前,将所有可用工具加载到其上下文窗口中。这在任何推理开始之前就消耗了宝贵的 Token,留给实际任务的空间更少。
图 4.23 – 过于宽泛的 MCP 配置导致的上下文窗口浪费
在 Claude Code 中,MCP 服务器通常使用mcp.json文件在项目层面进行配置。该文件加载多个 MCP 服务器及其所有关联工具。

浙公网安备 33010602011771号