macOS、开发工具·

我发布了一个完全由 Claude Code 构建的 macOS 应用程序 [译]

我最近发布了一个用于调试 MCP 服务器的本地 macOS 应用程序 Context,几乎完全是由 Claude Code 构建的。

我最近发布了 Context,一个用于调试 MCP 服务器的本地 macOS 应用程序。我的目标是构建一个在该平台上感觉自然的有用开发工具,基于苹果的 SwiftUI 框架构建。自 2008 年以来,我一直在为 Mac 开发软件,但这次有所不同:Context 几乎 100% 是由 Claude Code1 构建的。 尽管在协助 Claude 开发软件的过程中仍需要技能和迭代,但在这个项目的 20,000 行代码中,我估计我手动编写的不足 1,000 行2

这是一次长篇文章,讲述我的历程、如何选择我的工具、这些工具的优缺点(截至目前),以及如何利用它们来最大化生成代码的质量,特别是如果你像我一样构建本地应用程序时。

  1. 从 Copilot 到 Claude Code
  2. 再开始一个新项目
  3. Claude Code 擅长写代码
  4. Claude Code 的 Swift 还不错,SwiftUI 做得很好
  5. 你可以直接说“让它更美丽”
  6. 上下文工程是关键
  7. 给代理预热
  8. 代理无法读取你的思维,他们需要规范
  9. “超思考并制定计划”
  10. 建立反馈循环
  11. Claude Code 能做的不止是写代码
  12. 构建高质量自动化现在(几乎)是免费的
  13. 未来的 IDE 将会大相径庭
  14. 我可以再次发布侧项目

1. 从 Copilot 到 Claude Code

Image 1: Claude Code 生成的 ASCII 艺术

我第一次使用 AI 编码工具的经历是尝试 GitHub Copilot,它内置在 VS Code 中。这是第一款此类工具,当时我非常惊讶:它只是一种自动补全,但效果出乎意料的好——它不仅仅是补全符号名称或函数签名,能够基于周围的上下文完成_整个函数实现_。这极大地提升了生产力,但仍然感觉大部分工作是自己在做。

之后事情开始迅速发展:Cursor 崛起,他们添加了 Agent Mode,新的竞争者如 Windsurf 也进入了这个领域。所有产品都倾向于“代理模式”的开发,模型不是使用一次性 LLM 响应进行自动补全,而是在循环中调用各种工具以完成更复杂的任务:获取你代码库的上下文、读取网页和文档、编译你的程序、运行测试、迭代构建/测试失败等等。

我在这段时间内并没有广泛尝试这些新工具,因为我当时并不积极参与侧项目,但在 2025 年 2 月,一个有趣的竞争者突然出现:Claude Code 并不是像其他工具那样的 VS Code 分支,而是一个完全在终端中使用的 IDE。它没有传统的代码编辑功能或过于复杂的 UI,主要聚焦于代理循环。一个用来输入提示的文本框,除此之外几乎没有其他功能。它并不是_增强_你的 IDE,而是_替换_你的 IDE。我并不完全相信这是理想的用户体验,但与已有的选择相比,这个想法令人耳目一新,所以我决定试一试。

2. 再开始一个新项目

Image 2: 我未发布的侧项目

与许多工作繁忙的工程师一样,我有一个庞大的未发布侧项目坟场。构建工作原型是可行的,但最后 20% 耗时耗力,过去 6 年我未能发布任何侧项目。

此时,我开始尝试 Claude Code 及其对 MCP(Model Context Protocol)服务器的支持。Anthropic 将 MCP 设计为一个开放标准,以允许代理访问工具和其他上下文来完成特定任务。例如,Sentry MCP 服务器 提供了允许代理获取包含堆栈跟踪和其他有用调试上下文的问题的工具,甚至可以调用 Sentry 自身的 bug 修复代理。

然而,构建和测试 MCP 服务器的体验却相当麻烦:MCP 服务器通过标准输入/输出流或通过 HTTP 使用 服务器发送事件(SSE) 与客户端通信,提供将响应流式发送给客户端的能力。这并不像调用 CLI 或使用 curl 向服务发送请求那么简单。虽然有一个名为 MCP Inspector 的首方工具可以让开发人员测试服务器功能,但作为一名多年 macOS 和 iOS 开发者,我想尝试构建一个本地应用程序来解决这个问题。我认为,这将是推动 AI 代理边界的绝佳学习体验,期待能够得到一个有用的产品。

3. Claude Code 擅长写代码

让我先说,Claude Code (使用最新的 Sonnet 4 和 Opus 4 模型)在编写代码方面_真的_很不错。当然它不是最顶尖的 1% 程序员,但我会说 Claude 的输出质量明显优于平均开发者。给出有关你要实现的功能描述时,Claude 可以:

  • 在你的项目中定位和读取与该功能相关的现有源代码
  • 理解代码风格和设计模式
  • 阅读你提供的额外文档或规范
  • 生成代码来实现该功能
  • 生成测试以验证该功能的行为
  • 构建你的程序并运行测试
  • 迭代编译器错误和测试错误,直到构建和测试通过
  • 查看屏幕截图或控制台日志,识别并修复错误(稍后会详细说明)

Image 3: Claude 为我的应用编写 Swift 代码

令人难以置信的是,它所需的时间仅为人类实现整个功能的一小部分。设想一下,招聘一位对你的项目毫无了解的新员工,并在几分钟后让他们发布完整的功能。

4. Claude Code 的 Swift 还不错,SwiftUI 做得很好

我决定使用最新的苹果开发技术来构建我的应用程序:Swift 6.1 和 macOS 15.5 上的 SwiftUI。因为我想看看 Claude 在写 Swift 方面的表现,毕竟相较于像 Python 或 JavaScript 这样更加普及的语言,Swift 的训练数据少得多。

好消息是,Claude 能够使用大多数 Swift 语言特性,直至 Swift 5.5,当时引入了 Swift 并发。Swift 并发对语言是一次重大变革,我认为即使是人类也很难正确使用。Claude 在选择现代框架和旧版等效框架时也经常会混淆。它很多时候会在有更现代的 Swift 替代方案时使用旧的 Objective-C API,或者在 SwiftUI 应用中使用 AppKit/UIKit。

生成的 SwiftUI 代码通常工作得相当不错:它通常是 UI 的准确(但有点丑陋的)表现形式,进一步的迭代可以将其转变为真正感觉良好且可用的设计。

Image 4: 我的 macOS 应用,Context

Claude 生成 UI 代码时常常遇到的问题是一个根本上与 Swift 自身有关的问题:UI 代码的类型表达通常复杂到编译器无法在合理的时间内检查类型。解决方案是将视图主体重构为更小的表达式,幸好 Claude 在这一点上表现出色,不会破坏实现——当看到输出中的编译器错误时,它有时甚至会自行这样做。

你可以通过创建一个 CLAUDE.md 文件,包含使用现代 API 的基本说明,来让 Claude 避免常见的陷阱。以下是我项目的 CLAUDE.md 文件 中的一部分内容:

* 除非存在仅在 AppKit 中支持的功能,否则目标是使用 SwiftUI 构建所有功能。
* 以符合 macOS 平台的习惯方式设计 UI,并遵循苹果人机界面指南。
* 使用 SF Symbols 进行图标设计。
* 使用最新的 macOS API。由于没有向后兼容的限制,该应用程序可以针对最新版本的 macOS 使用最新的 API。
* 使用最现代的 Swift 语言特性和惯例。目标是 Swift 6,并根据需要使用 Swift 并发(async/await,actors)和 Swift 宏。

即使这组相对简单的规则也会产生合理的结果,但你可以更进一步:例如,Peter Steinberger 的 agent-rules 库包含可以添加到代理中的规则,既包括一般的编码指南,也包括更好地编写 Swift 代码 的更具体指导。

如果你有兴趣自己评估代码质量,可以查看以下这些来自我项目的示例:

5. 你可以直接说“让它更美丽”

如果 Claude 第一次没有生成一个设计良好的 UI,你可以直接告诉它_“让它更美丽/优雅/可用”。我发现这样的结果在付出很少努力的情况下令人惊讶地好。你也可以更有条理地首先要求它“提出如何使此 UI 更美丽的建议”_,这将生成一系列设计调整供你选择。

如果你发现 UI 错误或想要调整的 UI 元素,你可以直接将屏幕截图拖放到 Claude Code 中(或 ⌘+V 粘贴)。虽然这种方式在某种时候可能有更好的自动化解决方案,但目前这在任何前端平台上都能很好地工作。

6. 上下文工程是关键

随着主流 AI 的出现,业界迅速定义了一项新学科:提示工程。提示工程的观点是你必须仔细设计提示,以获取最佳质量的模型输出。虽然这在当时可能是正确的,但在我的经验中,我发现使用更新模型时,提示工程并不是关注的重点。

如今的模型在处理不完美输入和理解你的意图方面表现得更好,这得益于模型的提升以及它们结合了思维链(CoT)提示。你可以用模糊的描述、不完整的句子和拼写语法错误提示模型,它仍然能合理好地理解你的请求并将问题分解成一系列步骤。

当使用 Claude Code 或类似工具时,你将不断面对的限制是上下文窗口。两个最新的 Anthropic 模型(Sonnet 4 和 Opus 4)都具有 200k 的上下文窗口,这意味著它们能够同时处理 200k 个标记的文本。每次提示和回应都会消耗更多的上下文,而模型在上下文窗口的末尾表现通常较差

Image 5: Claude Code 的自动压缩指示器

Claude 甚至会展示一个指示器,显示你剩余的上下文量,在此之后它将进行“压缩”。压缩意味着它将总结当前的对话,并使用该总结为新的上下文窗口提供基础,以便你能继续提示。压缩并不完美——可能会遗漏之前对话中的重要细节,或使用先前错误中低质量的上下文来种子新的上下文。

在使用有限的上下文标记的情况下,生成最高质量的输出,换句话说,上下文工程 是有效使用编码代理的主要挑战。

7. 给代理预热

有一个我称之为“预热”代理的过程,在这个过程中,我让代理在直接执行任务之前,先读取额外的上下文,以提高其产生良好输出的机会。

默认情况下,它将读取用户范围和项目范围内的 CLAUDE.md 文件中的内容,但你可以通过要求它读取特定文档或源代码来引入额外的任务专用上下文。这是我最近用来让它读取一些现有源代码和网络规范的提示:

读取 DXTTransport.swift、DXTManifest.swift、DXTManifestView.swift、DXTConfigurationView.swift、DXTUserConfiguration.swift、AddServerFeature.swift 和 AddServerView.swift,以了解如何实现从 DXT 包中添加服务器。

然后阅读关于 manifest.json 格式的文档,链接如下:https://raw.githubusercontent.com/anthropics/dxt/refs/heads/main/MANIFEST.md

阅读完这些源后,总结你的理解。

然后,Claude 将使用 SearchRead 工具查找和读取源文件,并使用 Fetch 工具从 GitHub 下载 Markdown 文件。要求它总结强迫它思考并理解来源的内容,这样后续任务的性能会得到改善。

当你的代码使用第三方依赖或模型知识截止日期之后可能引入的新 API 时,预热尤其重要。像 Context7llm.codes 这样的工具旨在将文档格式化为模型可以处理的纯文本格式。

8. 代理无法读取你的思维,他们需要规范

在请求 Claude 构建功能时,拥有详细的规范非常重要,以引导模型。没有充分的努力,Claude 将无法构建任何非平凡的特性。AI 产品演示习惯上强调 1 句提示产生“完整的应用程序”,但如果你想要的不仅仅是一个原型,你需要一个实际的规范。

规范不需要写得很好。你甚至可以像语音转写一样乱说(我仍然更喜欢打字,但任何方式都可以)。以下是我给 Claude 写的一个规范示例,以构建我应用程序中的新功能:

Image 6: 我给 Claude 实现 Anthropic 的 DXT 包格式支持的规范

这看似相当多,但我能够打完这些内容的速度远快于自己实现这个功能的速度。

9. “超思考并制定计划”

Claude 往往会在背景不足的情况下直接跳入实现,这会产生质量较差的结果。另一个为代理预热的策略是要求 Claude 使用其扩展思维模式先做一个计划。扩展思维是通过一组魔法关键词激活的:“think” < “think hard” < “think harder” < “ultrathink。”这些并不仅仅是对模型的建议——它们是激活不同级别扩展思维的特定短语。Ultrathink 消耗最多的标记,但将产生最佳结果。如果你希望对计划进行迭代,明确包含指示在提示中,在计划被用户接受之前不进行实现,将会有所帮助。

我通常强烈建议阅读 Anthropic 的 Claude Code: 编码代理的最佳实践 文章。这里我讨论的许多技术都在该文章中有所涵盖,阅读它应该被视为在使用 Claude Code 或任何编码代理时的必读材料。

10. 建立反馈循环

当 Claude 能够独立驱动反馈循环,使其能够进行变更、测试变更并收集上下文以尝试另一轮时,它最有用。关键循环包括:

  • 构建。Claude 应该知道如何编译你的应用。Claude 知道如何通过 swift build 编译 Swift 包,但对我 macOS 应用程序目标而言,它往往无法找出正确的 xcodebuild 调用。 XcodeBuildMCP 解决了这个问题,为模型提供了简化的工具集来构建和运行应用程序。
  • 测试。Claude 应该能够构建并运行测试并查看测试输出。再次,Claude 能通过 swift test 内置实现这一点。我尚未测试它是否可以运行应用程序/UI 测试,但我怀疑可能也需要 XcodeBuildMCP。
  • 修复错误。Claude 已经知道如何通过添加调试日志来调试问题。问题在于它无法像用户那样与应用进行交互,以使应用处于发出正确日志的状态。你需要人工与应用进行交互,并将控制台中的日志复制粘贴给 Claude。这没问题,但意味着除非你事先编写单元测试或 UI 测试来封装行为,否则它无法完全自主地修复问题。像 playwright-mcp 这样针对浏览器应用的自动化解决方案存在,但我不清楚是否有经过良好测试的本地开发等效方案。
  • 修复用户体验问题。我之前提到过,你可以将屏幕截图粘贴到 Claude 中,以便它迭代 UI。你可能能使用像 Peekaboo 这样的工具来自动拍摄屏幕截图,但你仍然面临的问题是你需要人工与应用进行交互以首先将其置于正确状态。

11. Claude Code 能做的不止是写代码

由于 Claude Code 是一个包装通用模型的代理,你在迭代应用程序本身时,还可以使用它来帮助非编码任务,比如编辑文本或甚至按照建议功能来规划功能版本。

我发现的一个小功能非常有用,就是在我获得真实数据之前生成模拟数据。在构建 Context 时,我部分构建了一个 Swift MCP 客户端库的实现,但我想切换用于 UI 原型设计的思路。通常,生成_现实的_模拟数据的过程会非常繁琐,以至于我根本不会尝试,但 Claude 仅用几秒钟就生成了很棒的模拟数据。我与朋友分享的那些关于应用程序的第一张屏幕截图,虽然是模拟数据但看起来足够真实,这样你就能大致了解在实际 MCP 服务器中呈现数据时应用程序的样子

Image 7: Context 应用依靠 Claude 生成的模拟数据

特别是在 MCP 的情况下,模拟数据更为重要,因为当时大多数 MCP 服务器并未利用规范的绝大多数特性,只是在工具中使用,但我仍然需要一种方式来验证这些特性的 UI。

12. 构建高质量自动化现在(几乎)是免费的

发布应用程序的痛苦最后 20% 部分涉及到自动化发布过程,尤其是在 macOS 上,你必须应对签名、认证和打包的复杂过程。在早期项目中,这是我会尝试设置 fastlane 并围绕其构建一些简单的 Python 自动化的时刻。但这一次,经过几个小时的迭代,我让 Claude 为我编写了一个发布脚本,其功能如下:

  • 检查环境是否正确设置并安装了所需工具
  • 从 git 提交生成变更日志条目,将它们与手动书写的变更日志条目结合,并生成 HTML 发布说明
  • 构建应用程序、进行代码签名、进行认证并打包为 DMG
  • 生成 Sparkle 应用列表,以便向现有用户提供自动更新
  • 给发布打上标签并将其发布到 GitHub
  • 将调试符号上传至 Sentry 进行崩溃报告符号化

在脚本完全功能运行后,我只需一个简单的一行提示来美化 CLI 输出,最终我得到了:

Image 8: 运行我由 Claude 生成的构建和发布自动化脚本

这段 Python 代码有 2000 行,即便我手动编写,也绝对不会费心去自动化超过最关键的步骤,当然也不会花力气让输出看起来如此美观。这个脚本将为我节省每次发布几十分钟的手动工作,而这只是几段自然语言的规范和让 Claude 调试并修复我在运行脚本时发现的一些问题所需的努力。

13. 未来的 IDE 将会大相径庭

我在进行这个项目时想到,整个过程中只使用了两个工具,Claude Code 和 GitHub Desktop 用于查看差异。在大多数时间里,我并不需要典型编辑器的任何功能:文件树、源代码编辑器、扩展等等。我偶尔会使用 Xcode 进行手动编辑,但这种情况很少,且我仍然没有使用大部分与 Xcode 相关的功能(SwiftUI 预览、视图调试器等)。因为这是编码代理的_最差_状态,我不得不想象,未来的 IDE 完全不同于现在的样子。

Cursor、Windsurf 和 Copilot 都是从 VS Code 开始,并在各种方面有所不同,但它们都是将 AI 嵌入到一个在 AI 之前设计的编辑器中。从根本上来说,VS Code 与 20 年前的 JetBrains IDE 看起来没有很大不同。我还看到像 Warp 项目试图从现代终端仿真器向代理开发环境转型,但我不认为终端是理想的用户体验,尽管我非常喜欢使用 Claude Code。

我相信未来的 IDE 将专注于使开发人员能够预热代理的上下文并建立必要的反馈循环,以帮助代理成功完成其任务。 这种用户体验将显著不同——我无法准确预测如何,但我不认为源代码编辑器将是中心。

14. 我可以再次发布侧项目

整个旅程中让我最兴奋的事情不是我构建的应用程序,而是我再次能够满足我的编码冲动并发布经过打磨的侧项目。这就像我每天多出了 5 个小时,而我所付出的代价只是每月 200 美元。

原文链接:https://www.indragie.com/blog/i-shipped-a-macos-app-built-entirely-by-claude-code


© 2025 智人飞扬