
为什么塞满提示词反而让 Claude Code 变笨很多开发者在接手大型遗留项目时第一反应往往是“把上下文喂饱”。我们习惯性地编写长达数千字的 System Prompt试图将项目背景、API 文档、代码规范甚至数据库 schema 一股脑塞进对话窗口。直觉告诉我们模型知道得越多干活越准。但现实往往令人沮丧。当你真的把几万行文档扔给 Claude Code期待它像资深架构师一样理解全貌时它却可能突然变得“智障”陷入死循环、产生幻觉或者明明有现成的工具却视而不见开始胡编乱造代码。这种反差并非模型能力不足而是我们作为工程师的“控制欲”在作祟。我们习惯了面向接口设计喜欢二分断点调试却忽略了 LLM 的认知机制更像是一个需要探索环境的智能体而非一个静态的知识库。Claude Code 核心团队在复盘早期工程实践时曾提到他们最早也尝试过传统的 RAG检索增强生成方案结果索引检索 bug 频发反而剥夺了 Agent 的自主性Agency。真正的转折点在于思维模式的转变从“被动接受投喂”转向“主动探索发现”。与其在外围通过 RAG 强行注入碎片化的上下文不如直接给 Agent 一把好用的“铲子”比如 Grep 搜索工具让它自己在代码库里挖掘所需信息。这就是渐进式披露Progressive Disclosure的核心逻辑不一次性塞满上下文而是让 Agent 通过工具和文件系统按需、递归地发现它需要的信息。在这种模式下模型不仅精准找到了目标代码更关键的是它在搜索的过程中自动建立起了关于该任务的完整认知上下文。这种由 Agent 自主构建的上下文远比我们人工拼接的片段要精准且连贯。这也成为了后续 Skills 设计原则和整个 Harness 工程的基石。渐进式披露让 Agent 自己“找”答案渐进式披露不仅仅是一个概念它是解决复杂项目上下文爆炸的终极方案。在传统开发流中我们倾向于把所有可能的依赖都列出来生怕模型漏掉什么。但在 LLM 的工程实践中过多的前置信息反而会干扰模型的注意力机制导致“迷失在上下文中”。想象一下如果你被关在一个小黑屋里解一道复杂的数学题你希望手边有什么是一堆杂乱无章的草稿纸和公式书还是一支笔和一个可以按需查阅资料的终端对于 Claude Code 而言后者才是高效工作的环境。拒绝静态 RAG拥抱动态探索传统的 RAG 方案试图在对话开始前就计算出“最相关的片段”但这在动态变化的代码库中几乎是不可能的任务。代码是活的依赖关系是网状的。当你强行截取一段代码发给模型时往往丢失了它所在的调用链和上下文语义。Claude Code 的做法是最小化初始上下文最大化探索能力。在启动会话时只提供最核心的系统指令和基础工具集。当模型遇到未知符号或未理解的模块时它被鼓励甚至被训练去调用grep、rg(ripgrep) 或glob等工具去查找定义。这个过程是递归的模型收到任务“修复用户认证模块的漏洞”。模型不知道AuthService的具体实现于是调用grep -r class AuthService。找到文件后模型读取关键片段发现调用了TokenValidator。模型再次调用工具查找TokenValidator的定义。最终模型在脑海中Context Window 中拼凑出一条完整的逻辑链并给出修复方案。在这个过程中模型不仅仅是“读取”了信息它是“理解”了信息的获取路径。这种通过行动建立的认知比被动接收文本要深刻得多。配置支持自主探索的工具集要实现这一点关键在于工具集Tool Set的配置。很多开发者为了“安全”或“简洁”会限制模型可用的工具只开放read_file。这实际上是在自断臂膀。一个高效的 Claude Code 配置应当包含以下探索型工具全局搜索grep或rg用于快速定位函数定义、引用和关键词。文件遍历glob或find用于了解项目目录结构和文件分布。内容预览head/tail用于快速查看文件开头通常是导入和类定义或结尾而不必加载整个大文件。在.claude/settings.json或相关配置文件中确保这些工具处于可用状态。不要担心模型会“乱搜”现代模型在经过适当引导后非常擅长制定搜索策略。它们会像经验丰富的开发者一样先搜定义再看引用最后读实现。实战案例 在一个拥有 500 文件的微服务项目中开发者试图让模型重构一个深层嵌套的支付回调逻辑。错误做法手动复制了 10 个相关文件的内容粘贴进对话框。结果模型混淆了不同版本的参数定义生成的代码无法运行。正确做法清空对话框只告诉模型“请分析payment/callback目录下的逻辑必要时使用搜索工具定位依赖。”模型首先扫描了目录结构然后针对processPayment函数进行了全局搜索自动识别出它依赖的三个外部服务接口并逐一读取了最新定义。最终生成的重构方案不仅逻辑正确还顺带修复了一个潜在的竞态条件。工具设计的艺术顺应直觉而非强制格式有了探索的能力接下来就是如何让模型“愿意”且“正确”地使用这些工具。这是构建 Agent 最微妙也最艺术的环节。很多团队在设计 Tool Set 时容易陷入“强制格式”的误区试图用复杂的 Schema 约束模型的行为结果往往适得其反。别让模型“被迫”遵守规则最好的工具设计不是让模型**“被迫”按照你的格式输出而是顺应它的直觉让它在遇到困难时“本能”**地想要拿起这个工具。Claude Code 团队曾分享过一个经典迭代案例他们希望增加一个“向用户提问对齐”的能力。第一次尝试复用现有的ExitPlanTool加了一个参数让模型顺便提问。结果 Agent confused 了不知道该先写计划还是先提问导致意图纠缠幻觉失控。第二次尝试在 System Prompt 里规定语法要求模型输出[?]来表示提问。结果命中率极低模型经常漏掉符号或者自己发明新语法。第三次尝试单独设计了一个干净的AskUserQuestion工具。Agent 可以随时自主调用调用时前端弹窗阻塞直到用户回答。效果立竿见影。这个案例告诉我们原子化、意图单一的工具远比多功能的大杂烩好用。当工具的职责足够纯粹时模型调用的决策成本最低准确率最高。从 Todo 到 Tasks适应模型能力的进化工具设计不是一劳永逸的随着基座模型能力的提升旧的工具可能会变成负担。在 Claude Code 早期模型容易在长任务中迷失。团队为此设计了TodoWrite工具让模型维护一个待办列表并每隔几轮对话提醒它。这在当时很有效。但随着 Opus 4.5 等更强模型的出现情况变了。新模型不需要被频繁提醒多余的系统消息反而成了干扰甚至限制了模型动态调整计划的能力。更重要的是在多 Subagent 协作场景下单个 Todo 列表成了瓶颈。于是Tasks系统应运而生。持久化与共享Tasks 存储在~/.claude/tasks任何 Session 和 Subagent 都能读写。即使 Session 关闭重启任务状态依然保留。依赖管理引入了任务依赖关系Task A 未完成Task B 不能开始保证了复杂项目的执行顺序。跨会话广播一个 Subagent 更新了任务状态所有正在运行的 Session 都能实时感知。这种演进体现了工具设计的核心原则工具应服务于模型当前的认知瓶颈而不是固守过去的经验。对于现在的开发者而言在使用 Claude Code 处理大型项目时应善用其内置的任务管理机制而不是试图用简单的 Prompt 去模拟复杂的状态跟踪。面向缓存命中率被忽视的性能与成本优化在讨论 Agent 效率时大多数人只关注 Token 的总消耗量却忽视了Prompt Caching提示词缓存对成本和响应速度的巨大影响。这是进阶使用中必须掌握的关键点。LLM API 的缓存机制通常基于前缀匹配。你可以把 Context 想象成搭积木底层是 System Prompt 和 Tool Schema中间是历史对话顶层是当前问题。只要你动了底层的一块积木比如修改了 System Prompt 或工具列表上面所有的积木之前聊过的几十万 Tokens都要重新全价计算缓存瞬间失效。教训一不要动态修改工具集很多工程师的直觉是“按需加载工具”。当前任务是读文件就只给读工具下一任务是写文件再动态添加写工具。这听起来很省 Token但在缓存视角下却是灾难。如果在会话中途修改工具集意味着 System Prompt 部分发生了变化导致之前积累的所有对话历史缓存失效。正确的做法是保持工具集稳定用工具模拟状态转换。Claude Code 的Plan Mode就是一个绝佳范例。进入计划模式时并没有移除“写文件”等危险工具而是通过发送一条系统消息作为用户消息或工具结果的一部分告知模型“当前处于计划模式只读”。同时EnterPlanMode和ExitPlanMode本身就是两个可用的工具。这样底层的 Tool Schema 始终不变缓存命中率得以最大化。教训二懒加载与 Tool Search随着 MCPModel Context Protocol生态的扩张一个 Agent 可能接入几十个甚至上百个工具。如果将所有工具的详细描述一次性塞进 Prompt光描述就可能消耗数万个 Token不仅昂贵而且极易撑爆上下文窗口。解决方案是工具懒加载Tool Lazy Loading初始状态下只加载核心工具和轻量级的“存根”Stub。Stub 只包含工具名和defer_loading: true标记。提供一个ToolSearch原子工具。当 Agent 发现需要某个未加载的工具时自主调用ToolSearch来检索并加载完整的工具定义。这种机制保证了 Prompt 前缀的稳定性只有在真正需要时才付出额外的 Token 代价是处理大规模工具集的标准工程范式。教训三安全的上下文压缩Cache-Safe Forking当对话历史过长需要压缩时 naive 的做法是开启一个新 Session用不同的 System Prompt 调用 API 生成摘要。这完全破坏了缓存。高阶玩法是Cache-Safe Forking使用与主对话完全相同的 System Prompt 和工具定义。将主对话的所有历史消息附上。仅在最后追加一条压缩指令例如“请总结上述对话为简短摘要”。由于前缀完全一致这部分请求可以直接命中缓存只有最后的压缩指令是新计算的 Token。这不仅节省了成本还保证了压缩过程能利用到之前所有的上下文信息避免信息丢失。大型代码库的轻量级启动策略综合上述原则针对被复杂项目上下文拖累的开发者我们可以总结出一套可直接复用的轻量级启动策略。这套策略的核心思想是“少即是多”通过精心的配置和引导让 Claude Code 在大型项目中发挥最大效能。1. 初始化极简 System Prompt不要在启动时编写长篇大论的项目介绍。你的 System Prompt 应该只包含角色定义如你是一个资深后端工程师。核心行为准则如优先阅读代码再修改不确定时先搜索。必要的工具集声明保持静态包含搜索、读取、编辑等基础工具。错误示范“本项目是一个基于 Spring Boot 的电商系统包含订单、用户、支付三个模块。数据库使用 MySQL缓存用 Redis。订单模块的逻辑是……省略 2000 字”正确示范“你是一个专注于代码质量和可维护性的工程师。在修改任何代码前请先使用 grep 或 glob 工具定位相关定义和引用确保理解上下文。遇到不确定的业务逻辑先读取源码验证不要猜测。”2. 交互引导式探索在提出具体需求时采用“目标 探索路径”的提示方式。场景修复一个偶发的库存扣减错误。推荐 Prompt“我们需要修复InventoryService中的库存扣减逻辑目前存在并发下的超卖风险。请先使用grep搜索deductStock方法的所有实现和调用处。检查是否存在锁机制或事务控制。根据搜索结果分析潜在的竞态条件并提出修复方案。”这种提示词明确了指令同时赋予了模型探索的权限和路径避免了模型因缺乏上下文而胡乱建议。3. 状态管理利用 Skills 固化最佳实践对于团队内部常见的操作模式将其封装为Skills。不要事无巨细地规定每一步怎么做而是重点记录**“坑在哪”**Gotchas。例如创建一个/refactor-safeSkill其中包含“在执行重构前必须先运行单元测试套件若涉及数据库变更需检查迁移脚本兼容性。”Skills 中的description字段至关重要它决定了模型何时自动触发该技能。写得清晰准确能让模型在特定场景下自动激活防御机制。4. 持续迭代观察与调整Agent 工程没有银弹。你需要观察模型在实际工作中的表现它是否频繁调用错误的工具可能是工具描述不够清晰。它是否在简单任务上花费过多 Token可能是 System Prompt 过于冗长。它是否忽略了关键文件可能需要调整搜索策略或增加特定的 Glob 模式。通过不断的微调你将逐渐摸索出最适合自己项目节奏的协作模式。结语让 Claude Code 变强的从来不是我们塞进去多少文档而是我们赋予它多少探索的自由。渐进式披露不仅是一种技术策略更是一种与 AI 协作的哲学信任模型的推理能力提供合适的工具然后退后一步看它如何像人类专家一样去理解和解决问题。在这个 AI 赋能开发的新时代最优秀的开发者不再是那些记得最多 API 的人而是那些最懂得如何设计“ harness驾驭装置”让 Agent 在复杂的代码迷宫中自如穿梭的人。试着放下对“全知全能”的执念用轻量、动态、可探索的方式去引导你的 AI 伙伴你会发现代码编写的效率和乐趣都将提升到一个全新的维度。