Killer Code

用 Cursor 构建 Cursor:一个真实案例

使用 Cursor AI 构建 Cursor 本身的详细案例研究,包括挑战、失败和 AI 辅助开发的经验教训。

用 Cursor 构建 Cursor:一个真实案例

以下是我如何使用 Cursor 来构建 Cursor 的例子。以及 AI 模型失败和需要人工审查的地方!

挑战:添加 /compress 命令

我想添加一个 /compress 命令来总结对话中的所有消息。这很有用,因为你可以手动决定重置上下文窗口,特别是在较长的对话之后。

我描述了我想要的行为。这是我的第一个提示:

"在 @src/commands/ 中添加一个新命令来 /compress 当前聊天。该 /compress 命令应该查看聊天中的所有消息,然后调用选定的模型进行 LLM 调用来总结和压缩成单个消息,清除上下文窗口。"

注意我是如何标记 @src/commands/ 的,这样它就会将其他斜杠命令的示例拉入上下文!

初始实现

因为客户端有类型检查、代码检查和测试设置,Cursor 代理能够进行一系列更改然后验证其输出。有一些错误,它看到了结果并修复了。

当 Cursor 生成代码时,我在编辑器内审查差异以确保看起来没问题。经过几轮来回,代码看起来基本正确,测试通过了,所以我在本地试运行。

它工作了! 太好了...现在只需要完善一下并创建 PR。

第一个问题:内存泄漏

清理了代码,创建了 PR,并请求了一些审查(因为我对这个代码库还很陌生)。Cursor Bugbot 在 PR 上运行并告诉我存在内存泄漏 🤦

是的,没想到这一点。我审查了它的建议,它是正确的,所以我在本地应用了更改。

架构审查

但后来我收到了队友的评论:

"总结提示是否应该在后端而不是客户端进行,这样我们就可以为多个客户端重用相同的逻辑?"

好观点。Cursor 生成的代码是正确的!但这并不意味着它是正确的架构。我同意他的建议,所以回去重构。

重构到后端

这是我在新聊天中的下一个提示(为了获得新的上下文窗口):

"将 @compress.tsx 移动到后端应用程序,这样我们就可以在不同客户端中使用此功能。遵循与后端 RPC 通信的现有模式。"

我再次标记了 @compress.tsx 以便它回到上下文中(记住,LLM 不会在聊天之间保留工作记忆)。我要求它遵循现有模式,希望这足够具体。

Cursor 去生成了一些代码。它添加了新的 protobuf(用于在客户端/服务器之间序列化结构化数据)和一个要调用的函数。它更新了客户端以与此新逻辑通信。

同样,代码看起来没问题,所以我要求它编写测试。后端测试需要运行本地 Docker 实例(来设置环境),所以它帮助我完成了设置(在终端中运行必要的命令)。

隐藏的 Bug

完成后,我启动了客户端来测试客户端/服务器之间的集成。我运行了 /compress 但它不工作。什么!?所有测试都通过了!代码检查通过了!这怎么可能?

LLM 可以欺骗你认为逻辑有效,即使它实际上并不工作。存在运行时问题,这是编译时检查没有捕获的。

我仔细重新阅读了代码。请记住,我对这个代码库还不熟悉,所以我仍在尝试了解存在什么。

发现现有逻辑

当我深入查看代理文件时,我注意到一些有趣的东西——已经有处理总结的现有逻辑!如果你达到上下文窗口限制(例如,使用 Sonnet 4 的 200K tokens),Cursor 代理可以自动为你总结现有对话。它也不使用你当前的模型来执行此操作,而是使用更小更快的 flash 模型。

这很有道理。但是等等...看看我原来的提示:

"调用选定的模型进行 LLM 调用来总结和压缩成单个消息,清除上下文窗口。"

AI 没有错,我告诉它使用选定的模型。我错了!

现在看看我添加后端逻辑的提示:

"将 @compress.tsx 移动到后端应用程序,这样我们就可以在不同客户端中使用此功能。遵循与后端 RPC 通信的现有模式。"

我说过要考虑这个逻辑是否可能已经存在于其他地方吗?没有。我告诉它创建新东西。

教训:意图很重要

现在,也许 AGI 会为我解决这个问题,但这正是你今天可能在使用 AI 模型时出错的地方。你的意图很重要!

有了这个发现,我回到了代理。事实证明,一些逻辑已经存在于后端,而且比我拥有的更好,所以让我们使用那个。

Cursor 能够删除它为后端开始的内容,检查现有逻辑,并决定如何向客户端公开它。在内部,后端已经可以 summarizeConversation(),但没有公共方法。所以 Cursor 更新了 protobuf 模式来添加一个新方法,然后可以从客户端调用。

调试和最终修复

仍然,我在本地运行了,但它不工作。某处有 bug。我要求 Cursor 帮助我添加一些日志来调试整个客户端/服务器的流程,然后再次运行。

我能够将原始终端输出传回代理进行审查。代理比我更快地发现了错误,并建议了修复。测试了...它工作了!🎉

现在我要求 Cursor 清理调试日志并帮助我编写 PR 摘要。我确认所有测试都通过了,我们现在准备好进行更多审查。

关键要点

这就是用 AI 编码的现实。它并不完美。你通过与这些模型合作来获得经验,了解:

  • 你能做好的部分
  • 代理能做好的部分
  • 你们如何一起工作

你学会在代理运行时审查工作。你依靠代码审查代理来验证输出并帮助你捕获狡猾的 bug。

经验教训

  1. 上下文管理: 为新任务使用新的上下文窗口
  2. 意图清晰: 具体说明你想要什么,但也要考虑现有解决方案
  3. 人工审查: 始终审查 AI 生成的代码,即使测试通过
  4. 架构优先: 在实现之前考虑更广泛的系统设计
  5. 一起调试: 使用 AI 帮助调试,但保持人工监督

关键洞察是 AI 是一个强大的工具,但它需要人工指导、审查,有时需要纠正。最好的结果来自人类专业知识和 AI 能力之间的协作。


来源和致谢

本文基于 Lee Robinson 在 Twitter 上分享的实战经验整理而成。

原作者: Lee Robinson
原始链接: https://x.com/leerob
发布日期: 2025年1月15日

感谢 Lee Robinson 分享这个宝贵的 Cursor 实战案例,展示了 AI 辅助开发的真实挑战和解决方案。