个人评测 | Cursor 免费平替:Roo Cline + DeepSeek-v3/Gemini-2.0 + RepoPrompt AI 辅助编程
软件工程领域自诞生起,其中就无时无刻不在翻涌着由时代所掀起惊涛骇浪。
二十年前的前端工程师还被称为“切图仔”,如今这个岗位被要求管理庞杂的 Vue/React 项目;十五年前大家围在一台电脑前仔细琢磨一个事务如何进行 SQL 调优,现在 Spark / Clickhouse / Postgres 等等成熟方案技术选型琳琅满目;十年前用一个下午仔细琢磨各种 man <linux_command>
写出一个优雅的 shell 脚本,现在仅需 5 分钟跟 AI 交代清楚需求...
大语言模型的推广与应用落地,似乎将这次软件工程领域的大浪推到从未有过的高度——深处大浪中的程序员们——是焦虑的,担心被 AI 抢了饭碗——又是幸运的,因为相比其他人,总能最先、最准确、最容易地理解、学习、应用时代最前沿的科技。
摘要: 文章首先介绍了在 VS Code 中使用插件 Roo Cline 以达到和 Cursor 类似功能的方法。接着,介绍了如何使用 Repo Prompt 这款软件,在网页版 Claude Pro 中体验类 Cursor 的功能(相比调用 API ,使用网页版费用更加可控)。最后,以一个 AI 辅助编程实例讨论了这类工具的局限性,最终提出三点结论:(一)小型项目使用 AI 事半功倍,但是每一个 prompt 不应提出太多需求,复杂需求应在多轮对话中逐步提出;(二)对复杂项目而言,市面上的 AI 暂难以处理;(三)在 AI 实际操作中,“人类能够精准指出问题所在”这一点,十分重要。
Cursor 是什么?
2023 年初,四名麻省理工的学生 Michael Truell、Andrew Brown、Aman Sanger 和 Alex Gu 创立了 Cursor。这款编辑器一经推出就引起了开发者的强烈关注。
Cursor 本质上是在 VS Code 的基础上深度定制的代码编辑器。它继承了 VS Code 的所有优点,包括插件生态和熟悉的界面,但在此基础上通过集成 Claude 等大语言模型,创造了更智能的编程体验。
与 GitHub Copilot 等代码补全工具不同,Cursor 开创性地引入了"对话式编程"概念。你不仅能获得智能代码提示,更能与 AI 进行多轮对话,让它理解完整的业务上下文。这种革新让它远超 GitHub Copilot 、豆包 MarsCode 等竞品,成为真正的"AI 结对编程"工具。
但是现在 Copilot / MarsCode 等产品也在行为上逐渐接近 Cursor 。
Cline 和 Roo Cline
然而 Cursor 的高昂订阅费让许多开发者望而却步。在社区的不断探索下,一个名为 Cline 的开源项目应运而生。
Roo Cline 是 Cline 的改进版本,它巧妙地将多个大语言模型(如 DeepSeek、Claude、Gemini)整合进了 VS Code。用户只需安装这个插件,就能在熟悉的编辑器中获得类似 Cursor 的 AI 辅助体验。
这种方案既保留了开源的灵活性,又让开发者能够自由选择不同的 AI 模型。虽然在集成度上可能略逊于 Cursor,但"一分钱一分货",对于个人开发者来说已经足够实用。
此外,无需额外维护一个 IDE 也是 Cline 相比 Cursor 更具吸引力的地方。
如何“免费”使用?
Google Gemini 2.0 flash thinking
Google 为所有开发者提供了 Gemini 的免费调用方式:只要频率不高于每分钟 15 次即可——对于 AI 辅助编程而言足矣。
在 https://ai.google.dev/gemini-api/ 中可以获取免费的密钥。
DeepSeek-v3
相信关注科技新闻的朋友都会听过国内的 DeepSeek 模型。
进入 https://www.deepseek.com/ 注册登陆,即可获得 500 万 tokens 的免费额度,对于“重度”编程而言,也够用好几天的了。
实测 DeepSeek-v3 在 RooCline 中的表现是强于 Gemini 的。
在 Roo Cline 中使用
在 VS Code 中下载 Roo Cline 后,在设置中,选择相应的模型,输入 API Key 即可。
接下来只需要和 Cursor Composer 一样,在 VS Code 中输入你的需求, at 你的文件/路径即可。
Roo Cline 的玩法很多,配置了合适的 Rule 的 Roo Cline 能力会大大增强。因每个人有每个人最常用的场景,这里没有通用的推荐,所以不做详细讨论。
RepoPrompt 在网页版中使用 Claude 3.5 Sonnet
尽管因为太昂贵,我们不想接入 Claude API ,但是我们可以在网页版中使用付费额度固定的 Claude Pro 来使用“最适合编程”的 Claude 3.5 Sonnet 模型。
在 https://repoprompt.com/ 下载 Repo Prompt 。
用 Repo Prompt 打开你的项目,在其中选择你要附带上的(你要给 AI 阅读/修改的)文件,接着书写提示语,如下图所示。
如上:
- 首先我在 Repo Prompt 中打开我的项目
- 我在 Instructions 中,勾选了
File Tree
、XML Whole
以及Project Manager
三个前置 Prompt File Tree
将整个项目的目录结构自动整理成文本XML Whole
是 Repo Prompt 这个软件的精髓,它会要求 Claude 输出一个 xml 格式的内容,之后我们可以直接拿这个 xml 格式输入回 Repo Prompt ,从而方便地将 Claude 带来的代码修改 code diff 应用到我们的项目中Project Manager
是我自定义的提示语- 接着我在下方粘贴了 pytest 的报错
- 在下半部分 Selected Files 中,我勾选了一些我想上传的文件
这些都完成后,点击下方 Copy ,你的剪贴板中即获得了上面所说的全部内容,直接粘贴给网页版 Claude Pro 即可。
如上, Claude 产生了一个 XML 代码块,我们只需要将其 Copy 到 Repo Prompt 的 Apply > XML Input
中即可。
Repo Prompt 自动解析该 XML ,与本地文件对比,并且将代码对比展示给我们。我们审核代码后,即可选择是否应用这些改动。
实例:人类多加一句话,让 AI 表现越迁一个级别
最近编程遇到的一个问题,大概如下。
async def mock_get(*args, **kwargs):
mock = AsyncMock()
mock.status = 200
if "/item/" in args[0]:
mock.json.return_value = {
... # 省略
}
else:
mock.text.return_value = "<html><body>Test content</body></html>"
return AsyncMock(__aenter__=AsyncMock(return_value=mock))
async def mock_head(*args, **kwargs):
mock = AsyncMock()
mock.status = 200
return AsyncMock(__aenter__=AsyncMock(return_value=mock))
crawler.session.get = AsyncMock(wraps=mock_get)
crawler.session.head = AsyncMock(wraps=mock_head)
问题的表现是:我的 pytest 测试无法通过。
因此,我将代码与 pytest 返回的错误一起发送给模型(试了种方法,包括上文提到的 Roo Cline + DeepSeek/Gemini 、 Repo Prompt + Claude Pro )。
最终他们全部都陷入了一种诡异的循环,修正了 A 错误就产生了 B 错误,修正了 B 错误就产生了 A 错误...如此往复。
于是我停下来调用 API ,恢复到“原始的”人工 Debug :我发现,问题的根本在于 AsyncMock
没有正确注入到我的 class 中。于是我多加入了下面这句话:
It seems that the way I mock async result
in pytest is not correct.
There must be something wrong.
Please focus on helping me fix the mock logic:
...
结果是, AI 没有陷入到无尽的错误循环中,而是集中于优先处理上述我提到的问题,在本轮修改后,我仅需手动修改一些小的 attribute 错误,所有 pytest 便全部通过。
def _create_mock_response(self, status=200, json_data=None, text_data=None):
"""Helper to create consistent mock responses"""
mock = AsyncMock()
mock.status = status
mock.__aenter__.return_value = mock
if json_data is not None:
mock.json = AsyncMock(return_value=json_data)
if text_data is not None:
mock.text = AsyncMock(return_value=text_data)
return mock
这个经历与我之前的经验也完全契合,这里总结下:
- AI 的输出是有限的,若在一次对话中给它设置过多目标,则往往顾此失彼,一个都做不好;限制本轮对话的目标,则大大减少了 AI 所需搜索的空间
- AI 有很多种原因会让其陷入死循环: LLM 服务端很可能维护了一个 Cache ,类似的请求会命中 Cache 得到相同的答案,因此如果你用同样的提问得到了错误的答案,一定不要原封不动的重试,完全是浪费; 此外 AI 其实并不知道什么是对的、什么是错误,完全取决于你给它的反馈
总而言之,我目前能给出的参考是:
- 小型项目使用 AI 事半功倍,但是每一个 prompt 不应提出太多需求,复杂需求应在多轮对话中逐步提出;
- 对复杂项目而言,市面上的 AI 暂难以处理,但若是项目解耦较好,能够拆解成一个一个的小部分,应用 AI 辅助是可观的选择。并且对于一些业务代码, AI “照猫画虎”的能力往往是惊人的:它所提供的 “添加一条新业务的方案” 往往很优雅,其能很好地使用你项目中的自定义的
utils
(前提是你有其他业务代码也应用了这些utils
,相当于给 AI 举了个例子如何使用),开发者仅需 review + fix lint 即可; - 在 AI 实际操作中,“人类能够精准指出问题所在”这一点,十分重要,无需赘言。非专业人士写一个玩具 APP 是可行的,但是实际工程化的项目没有专业人士指引, AI 依然很难完成。
转载可私信后台。