Claude Code 的10个实现技巧
本文是考察 Claude Code 引擎盖下如何工作的 15 部分系列的一部分。现在我们提炼关键洞察,并展望构建自己的编码代理。
本文是考察 Claude Code 引擎盖下如何工作的 15 部分系列的一部分。
我们从一个单一的打包 JavaScript 文件开始,最终形成了生产 AI 编码助手如何工作的完整思维模型。在这个过程中,模式出现了。决定在上下文中是有意义的。看似实现细节的东西揭示了自己是深思熟虑的设计选择。
架构讲述了构建可靠 AI 系统的故事。不是理论最佳实践,而是对真实问题的久经考验的解决方案。
1、循环是一切
Claude Code 的核心是一个看似简单的模式:
while (true) {
const response = await callAPI(messages);
messages.push(response);
if (response.stop_reason === "end_turn") break;
const results = await executeTools(response);
messages.push({ role: "user", content: results });
}
这是代理循环。它将一个无状态语言模型转变为自主演员。模型决定做什么。循环执行这些决定。结果反馈。循环继续直到模型发出完成信号。
每一个复杂的行 为都从这个基础中出现。多步骤任务、错误恢复、迭代改进,都因为循环保持运行。教训:从循环开始。一切其他都是细节。
2、模型是无状态的,你不是
Claude 在 API 调用之间没有记忆。它接收消息,生成响应,然后忘记。连续性的幻觉完全来自客户端维护和增长消息数组。
这种关注点分离是强大的。模型专注于推理。客户端处理状态、持久化和编排。两者都不需要理解对方的内部。
实际含义:你的代理的记忆是你的责任。模型需要的每一个上下文片段都必须在消息中。工具结果、文件内容、以前的决定,都明确包括。没有什么隐含的。
3、工具只是结构化输出
当 Claude 请求工具时,它不是执行代码。它产生描述它想要做什么的 JSON:
{
"type": "tool_use",
"name": "Read",
"input": { "file_path": "/src/main.ts" }
}
客户端解析这个,执行实际操作,并将结果作为消息发送回来。模型从未触碰文件系统。它从未运行命令。它只通过结构化数据建议行动。
这种设计实现了安全。客户端可以检查、验证和控制每一个操作。权限、钩子和日志都自然地插入执行边界。模型提议;客户端处置。
4、流式传输改变一切
批量 API 在技术上会工作。等待完整响应,然后处理。但流式传输改变了用户体验。
文本随着生成而出现。工具请求在响应完成之前到达。UI 保持响应。长时间操作感觉互动而不是冻结。
流式传输也实现了中断。用户可以在响应中途取消。代理可以在出错时中止。没有流式传输,你就承诺等待完成。
实现复杂性是真实的。SSE 解析、部分 JSON 积累、并发状态更新。但体验证明了努力是值得的。
5、权限是不可协商的
具有不受限制系统访问的 AI 是一个等待发生的安 全事件。Claude Code 的五级权限层次显示了如何正确做:
- 策略规则(企业覆盖)
- 命令行标志(会话配置)
- 用户设置(个人偏好)
- 项目设置(仓库约定)
- 本地覆盖(机器特定)
三个权限级别(允许、询问、拒绝)适用于每一层。级联确保高优先级规则可以强制安全,而低优先级规则允许自定义。
教训超出了权限。任何可配置的行为都受益于具有覆盖能力的分层默认值。
6、上下文是你的最稀缺资源
200,000 令牌上下文窗口听起来巨大,直到你读取几个大文件、运行一些搜索并积累工具结果。上下文填充得比你预期的快。
Claude Code 的上下文管理显示了解决方案:持续监控、积极缓存、主动压缩。系统实时跟踪令牌使用,缓存静态内容如系统提示,并在空间不足时总结旧对话。
提示缓存值得特别关注。缓存内容 90% 的成本减少从根本上改变了经济学。设计你的系统提示为稳定以便缓存工作。
7、委托胜过积累
一些任务需要读取二十个文件。如果主对话这样做,二十个文件的内容永远留在上下文中。如果子代理这样做,只返回摘要。
子代理提供上下文隔离。它们从头开始,在自己的空间工作,并返回压缩结果。主对话保持精简。复杂的探索发生而没有上下文膨胀。
模式广泛应用。任何生成大量中间数据的任务都应该考虑委托。生成子代理的成本与上下文节省相比是微不足道的。
8、可扩展性需要边界
MCP 服务器扩展 Claude Code 而无需修改其核心。钩子自定义行为而无需分叉代码库。两者都工作因为存在清晰的边界。
MCP 服务器通过 stdin/stdout 或 HTTP 上的 JSON-RPC 通信。它们对 Claude Code 的内部一无所知。它们只响应协议请求。
钩子通过环境变量接收上下文,并通过 stdout 响应。它们不调用 Claude Code 函数。它们只处理数据并返回决定。
这些边界实现了进化。Claude Code 可以在内部改变而不破坏扩展。扩展可以创新而不等待核心变化。
9、UI 不是事后想法
终端中的 React 听起来不寻常,直到你看到好处。组件、状态管理、声明式渲染,所有使 Web 开发高效的模式也适用于 CLI 开发。
UI 必须同时处理流式文本、权限提示、进度指示器和键盘输入。React 的模型自然处理这个。状态变化触发重新渲染。组件封装复杂性。
Ink 证明了好工具很重要。用原始转义码对抗终端会使代码库脆弱。基于 React/Ink 构建使它可维护。
10、可观察性实现一切
你无法改进你无法测量的东西。Claude Code 广泛检测:API 持续时间、工具执行时间、令牌计数、缓存命中率、错误频率。
这些数据为状态栏的实时显示提供动力。它为压缩系统的阈值决定提供信息。它通知优化努力。它帮助用户理解发生了什么。
遥测设计尊重隐私,关于使用的元数据而不关于工作的内容,同时仍提供持续改进所需的可见性。
原文链接: Claude Code Internals: Lessons Learned and What's Next
汇智网翻译整理,转载请标明出处