Cline AI 助手令人着迷
原文由 Michael Lynch 于 发布,订阅该博客
昨天我试用了Cline AI 助手,结果一下子就陷入了长达五小时的恍惚状态,只能目不转睛地盯着 Cline 帮我修 bug。
作为一名专业开发者,这种体验既让人着迷,又让人恐惧。着迷的是,AI 已经达到了如此高的水平;恐惧的也正是这一点——在一个 AI 写代码比我又好又快的世界里,我不知道自己还能扮演什么角色。
在这方面我算是后知后觉了,我意识到大多数开发者已经把 AI 工具更深入地融入了自己的工作流,但我想把自己的所见分享给那些还没体验过的人。
我以前也用过 AI 工具
Cline 并不是我第一次使用 AI。
过去两年里,我一直在尝试各种大语言模型助手。最近半年,随着模型已经能够稳定地生成正确的代码,我使用它们的频率也大大增加了。
我用Kagi作为搜索引擎,它的 Ultimate 套餐可以无限制地使用所有主流大模型。我主要通过 Kagi Assistant 功能与大模型交互,它其实就是一个与大模型聊天的网页界面。

我的搜索引擎Kagi为所有主流大模型提供了一个好用的网页聊天界面。
利益披露:我参与了 Kagi 的众筹,所以对他们有一笔我自己也说不清的财务投入。
用 AI 工具让我觉得自己才像是机器人
我最近发现的问题是,AI 工具让我觉得自己变成了机器。我只是机械地在编辑器和聊天界面之间来回复制代码,然后说一句“没起作用”,再贴上报错信息,如此反复四五遍。


聊天机器人大模型一直在为一个 bug 提供错误的修复方案,还得经过多次催促才肯给出完整的解决方法。
肯定有工具能解决这个问题
我意识到,肯定有比我现在这种方式更好的 AI 集成方案。
我需要一个工具来接手我这个“来回复制代码和报错信息”的角色。
我隔了一年试了两次Sourcegraph Cody,两次都挺失望的。让它直接在原地修改代码,确实比在浏览器和编辑器之间来回粘贴要好,但 Cody 又慢又多 bug,最后我还是回到了在网页浏览器里来回粘贴代码的老办法。
最近我看到了几篇关于Cline的博文,出于几个原因,它听起来很吸引人:
- 代码是开源的。
- 它能与 VS Code 集成,而 VS Code 是我的主力编辑器。
- 它可以处理本地文件编辑、执行命令,并根据命令输出进行迭代。
- 如果我愿意,它还允许我使用本地部署的大模型。
- 它不像许多其他 AI 助手那样,非要充当购买 AI API 访问权限的中间商。
缺点是,Cline 似乎除了烧投资人的钱之外,并没有别的收入来源。所以,它的可持续性可能存疑,不过眼下用着倒没问题。
词语幻觉:检验 AI 助手的完美测试程序
最近我一直想要一个能扫描我博客中“词语幻觉”的工具。这是Matt Might 所说的文本中未能察觉的重复单词现象,例如:
Many readers are not aware that the
the brain will automatically ignore
a second instance of the word “the”
when it starts a new line.
我在博客里经常犯这种错误,而且往往要到校对后期甚至发布之后才发现。
Matt Might 分享过一个查找词语幻觉的 Perl 脚本,但它比较简陋,由于 Markdown 格式字符的干扰,在我的博客上产生了大量误报。
我让 Kagi Assistant 用 Python 写一个能识别 Markdown 的版本,但它一直在生成有 bug 的代码。
我意识到这正是检验 Cline 的完美测试用例,因为这个问题很容易定义。我应该可以不断向 AI 助手展示我期望行为的测试用例,然后它就能不断修改代码,直到测试通过。
这也是一个用Zig来写的借口,因为我希望这个工具能在大量文件上尽可能快地运行,而且我很喜欢用 Zig。
定义问题
我的工具主接口很简单:它需要接收文件内容作为一个字符串(在 Zig 中是 [] const u8),然后生成一个包含重复单词及其对应行号的列表。
基础的主接口看起来是这样的:
pub const DupeWord = struct {
line_number: u32,
word: []const u8,
};
pub fn FindAdjacentDupes(allocator: std.mem.Allocator,
input: []const u8) !ArrayList(DupeWord) {
// TODO: Implement this.
}而这是我最初的单元测试:
test "FindAdjacentDupes" {
// Don't consider distinct words to be duplicates.
try testFindDupes("cat dog", &[_]DupeWord{});
// Find simple dupes.
try testFindDupes("cat cat", &[_]DupeWord{
.{ .line_number = 1, .word = "cat" },
});
}
fn testFindDupes(input: []const u8, expected: []const DupeWord) !void {
const allocator = testing.allocator;
var result = try FindAdjacentDupes(allocator, input);
defer {
for (result.items) |item| {
allocator.free(item.word);
}
result.deinit();
}
try testing.expectEqual(expected.len, result.items.len);
for (expected, 0..) |expected_dupe, i| {
try testing.expectEqual(expected_dupe.line_number, result.items[i].line_number);
try testing.expect(std.mem.eql(u8, expected_dupe.word, result.items[i].word));
}
}Cline 的初步成果
大约 30 秒、花了 0.09 美元的大模型额度后,Cline 就让测试通过了:

Cline 用以下实现更新了 FindAdjacentDupes:
pub fn FindAdjacentDupes(allocator: std.mem.Allocator, input: []const u8) !ArrayList(DupeWord) {
var result = ArrayList(DupeWord).init(allocator);
var it = std.mem.splitScalar(u8, input, ' ');
var prev_word: ?[]const u8 = null;
while (it.next()) |word| {
if (prev_word) |prev| {
if (std.mem.eql(u8, prev, word)) {
const dupe_word = try allocator.dupe(u8, word);
try result.append(DupeWord{
.line_number = 1,
.word = dupe_word,
});
}
}
prev_word = word;
}
return result;
}Cline 也走过一些弯路,比如把 const 写成 var,或是使用了已废弃的 API,但它能像人一样根据报错信息自我纠正。
这个实现显然还不完整,因为它没有处理 Markdown 格式、大写字母或标点等问题。我也没有给 Cline 看过任何行号不是 1 的测试用例,所以当前的实现把行号硬编码成了永远返回 1。
就是在那时,我入迷了
在 Cline 完成初步实现后,我不断编写新的测试用例,然后看着 Cline 更新代码来满足我的测试。
就是在那时,我彻底入迷了。我惊叹于竟然可以这样开发软件。我只需要告诉工具我想要什么,它就会完全按照我的要求去做。
这就是我在本文顶部展示的视频,演示了实际操作时的样子:
成果
那天剩下的时间我都在用 Cline 实现这个工具。现在我已经有了一个可用的重复单词查找工具。我把它叫做 wordword:
我用 wordword 在我的博客上找到了七处词语幻觉错误。
总共,我在OpenRouter上只花了 6 美元的额度,这相当于与 Cline 连续工作了五小时。
目前为止的收获
无人监督的工作并非最优,但便宜到无所谓
Cline 有一个选项,会在每一步之前提示你批准计划。我很快就厌倦了每五秒就点一次“Approve”,于是直接设置成了自动批准文件读取、文件写入和命令执行。
我发现,如果我不再盯着,Cline 偶尔会陷入死胡同,反复尝试注定失败的策略。
尽管如此,我还是大多让 Cline 在无人监督的情况下一直运行,直到它找到解决方案或达到 20 次尝试的上限。这些死胡同会消耗 API 额度,但也只是几美分的量级,所以我宁愿冒着浪费几美分的风险,也不愿去事无巨细地管着这个助手。
Cline 无条件地信任你,所以要谨慎措辞
Cline 表现最混乱的时候,往往是我不小心写出了行为错误的测试用例。
这是我写得过于仓促的一个测试用例:
// Detect duplicates after a heading
try testFindDupes(
\\## Foods
\\
\\These potatoes potatoes are the best!
, &[_]DupeWord{
.{ .line_number = 1, .word = "potatoes" },
}我不小心把行号写成了 1,而实际上应该是 3。
当我让 Cline 去让这个测试通过时,它有点崩溃了,绞尽脑汁想弄明白,明明应该是 3 的行号,要怎么硬说成是 1。
鼓励 Cline 添加调试打印语句
我注意到,大模型往往倾向于猜测解决方案,而不是停下来收集更多信息,去弄清一段代码为何会如此表现。
当我发现 Cline 陷入盲目尝试修复 bug 的循环时,我发现暂停它的工作、让它插入调试打印语句来验证它对代码的假设会很有帮助。Cline 会添加有用的调试输出,并且在宣布解决方案完成之前,还会记得把它们全部移除。
Kagi 肯定在我身上亏钱了
这是我第一次使用按量计费的大模型 API。我见过人们讨论 token 成本,但我一直没有直观的感受,因为 Kagi 基本上就是说:“别担心花多少钱。”
Cline 会在你进行的过程中,贴心地显示每个编程任务已经消耗了多少额度。

所以,我在 Kagi 每月 25 美元的无限套餐上肯定是占了大便宜。我用 Cline 五小时就花了 6 美元,而 Cline 还做了很多事来尽量减少 token 消耗。我每天都用 Kagi Assistant,经常在一次对话中就往聊天里粘贴十几次巨大的文件。现在看到了成本,我估计自己每天要让 Kagi 消耗 5 到 10 美元的 API 额度。
其他资源
大多数关于 AI 的文章都内容空洞,缺乏实用的经验。我发现以下几篇在展示可能性方面最有用:
- “Everything I built with Claude Artifacts this week”,作者 Simon Willison
- “How I Use ‘AI’”,作者 Nicholas Carlini
- “How I program with LLMs”,作者 David Crawshaw
随机一篇博客
评论
登录后参与讨论