惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
云风的 BLOG
云风的 BLOG
G
Google Developers Blog
S
SegmentFault 最新的问题
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
美团技术团队
爱范儿
爱范儿
博客园 - 三生石上(FineUI控件)
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
DataBreaches.Net
F
Fortinet All Blogs
TaoSecurity Blog
TaoSecurity Blog
D
Docker
C
Cybersecurity and Infrastructure Security Agency CISA
K
Kaspersky official blog
宝玉的分享
宝玉的分享
腾讯CDC
Google Online Security Blog
Google Online Security Blog
Recorded Future
Recorded Future
T
The Exploit Database - CXSecurity.com
T
The Blog of Author Tim Ferriss
V
V2EX
S
Securelist
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
CERT Recently Published Vulnerability Notes
A
Arctic Wolf
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
Y
Y Combinator Blog
P
Proofpoint News Feed
T
Tor Project blog
AWS News Blog
AWS News Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The Last Watchdog
The Last Watchdog
博客园 - 聂微东
T
Threat Research - Cisco Blogs
B
Blog
Attack and Defense Labs
Attack and Defense Labs
L
Lohrmann on Cybersecurity
C
CXSECURITY Database RSS Feed - CXSecurity.com
阮一峰的网络日志
阮一峰的网络日志
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
N
News and Events Feed by Topic
博客园 - 司徒正美
H
Help Net Security
C
Cisco Blogs
C
Check Point Blog
S
Secure Thoughts

Steve Sun

【译文】我们现在是工厂工程师,不是产品工程师 【译文】循环工程的艺术 【译文】请不要搞个 【译文】自主长时运行编程 Agent 【译文】/goal + 损失函数:如何用一条指令在 30 小时内蒸馏一个产品 我怎么用 Hermes Agent 写代码 【译文】运行一个 AI-native 的工程团队 【译文】运行一个 AI-native 的工程团队 【译文】你可以直接这么说 【译文】你可以直接这么说 如何设计一个智能体(AI Agent) 如何设计一个智能体(AI Agent) 【译文】为什么你的"AI-First"策略很可能是错的 【译文】为什么你的"AI-First"策略很可能是错的 记忆的层级,和 AI 智能体的记忆管理 AI Agent 工具对比:MCP 为什么只是个过渡产物 AI Agent 工具对比:MCP 为什么只是个过渡产物 外部化的J人 外部化的J人 Omarchy 一些中文环境下的设置 Omarchy 一些中文环境下的设置 AI Agent + 产品经理 = 产品测试工程师 AI Agent + 产品经理 = 产品测试工程师 遇到 Linux 系统 Kernel Panic 了该如何应对 遇到 Linux 系统 Kernel Panic 了该如何应对 如何与「老登」相处 为什么不应该让AI生成单元测试
Cursor等AI编程工具的背后原理
2025-06-02 · via Steve Sun

在上一篇文章DeepWIKI 是如何工作的我分享了 DeepWIKI 可能的实现方式。文中留了一个问题:DeepWIKI 是如何将源代码仓库分块的?

这个问题的答案就是 AST 分块。

这篇文章我想分析一下两个软件开发辅助工具(Cursor, Cline)都是怎么实现「索引代码」的,其实它们和 DeepWIKI 的原理没有本质区别,都使用了 AST 分块的方法。

AST

Abstract Syntax TreeAST,抽象语法树)是源代码的树形表示,它反映了代码的语法结构。在代码分块时,AST 可以帮助我们更好地理解代码的语义边界。

AST 在各种编译、分析源代码工具中都广泛使用。例如前端的 Babel、TypeScript 编译器(TSC),就利用 AST 来将 es6 或者 TypeScript 代码转换成浏览器可理解的 js 代码。

下面是一个简单的例子,展示 AST 如何把 TypeScript 代码转换成树形结构,假设有一段 TypeScript 函数:

function greet(name: string) {
  return "Hello, " + name;
}

经过 AST 工具的转换,它被抽象成下面的语法树结构:

  • SourceFile:
    • FunctionDeclaration
      • Identifier:“greet”
      • Parameter:
        • Identifier:“name”
      • Block:
        • ReturnStatement:
          • BinaryExpression:
            • StringLiteral:“Hello, "
            • Identifier:“name”

后续编译器就可以遍历这个语法树,按节点转换成 Javascript 代码。

理解了 AST,就大致可以理解 DeepWIKI、甚至是 Cursor 这种代码编辑器如何构建代码索引的。

Cursor

Cursor 的官方文档中,可以看到关于它如何索引用户代码的相关描述。

Cursor 会扫描用户代码仓库,计算文件哈希值并构建 Merkle 树,类似 Git 比较文件差异的原理,Cursor 用 Merkle 树来比较用户空间文件的差异,并且将用户修改过的文件以增量的方式上传到 Cursor 的服务器。

被上传的文件,会被分块并嵌入,存储在 Turbopuffer 数据库中。这就是将源代码构建成 RAG 的过程。

这里的分块使用了 AST 工具将代码先结构化成语法树,然后将序列化后的语法树节点切成小块,最后嵌入成向量存储起来。

Turbopuffer 中不仅存储了向量化后的代码,而且存储了一些元信息,如这段代码的行号,源文件路径等。

当 Cursor 试图补全用户代码或根据上下文生成新代码时,Cursor 会检索这个 Turbopuffer 数据库,匹配到相似度最高的向量并得到这段代码的文件路径、行号。之后 Cursor 在用户代码仓库中查找到对应的源代码并放入 LLM 的系统上下文里。最后 LLM 返回生成的新代码给 Cursor。

网友整理了这张流程图:

Cline

Cline 的官方博客 可以让我们窥见它的实现思路。

Cline 是一个辅助编码的 AI Agent。Cline 并不上传代码并构建 RAG,而是主张更安全、可靠的方式管理用户的代码仓库。

下面是开发者对 Cline 原理的介绍:

When you point Cline at a codebase, it doesn’t immediately try to read every file. Instead, it begins by understanding the architecture. Using Abstract Syntax Trees (ASTs), Cline extracts a high-level map of your code – the classes, functions, methods, and their relationships. This happens through our list_code_definition_names tool, which provides structural understanding without requiring full implementation details.

Cline 会使用它们的 list_code_definition_names工具将源代码转换成 AST。Cline 把这个 AST 当作整个源代码的「地图」。

当 Cline 自动执行任务时,它会分析当前要修改的文件,从文件构建 AST,从 AST 生成自然语言上下文(类似 DeepWIKI 把代码转换成文档)。并将上下文传给 LLM,让 LLM 决定下一步是该修改文件,还是需要查看另一个文件补充更多上下文。

如果说 Cursor 比较的是向量空间代码片段的相似度,Cline 就是将代码片段转换成自然语言的描述,然后让 LLM 通过语义的理解,在源代码仓库中搜寻线索,比较代码片段之间的语义相似度。

Cline 这种实现方式,显然更安全,企业用户不用担心 Cline 滥用源代码。但是副作用就是消耗了更多 Token。不断在不同文件之间获取上下文也花费更多时间。对于一些特殊情况,它甚至会在两个文件之间循环跳转,陷入死循环。

从我自身感受来说,Cline 在一些模型(Deepseek-r1, OpenAI-4o)的表现上比 Cursor 的 Agent 模式更好,因为 Cline 的语义理解比向量相似度更充分利用这些模型的自然语言能力。

但是对于专门为编程优化过的 Claude-Sonnet,则没有明显差异,这时就要看用户希望更高的安全性还是更快的响应速度。

小结

本文主要介绍了代码编辑器如何利用抽象语法树(AST)来构建代码索引和实现代码补全功能。

总的来说,AST 是理解代码语法结构的重要工具,不同的实现方式各有优劣。

扩展阅读