近日,一家名为 Sem 的初创公司正式发布了一项全新的代码理解原语——Sem(与公司同名),旨在解决传统语言服务器协议(LSP)在大型代码库、跨语言分析和历史追踪场景下的深层痛点。与 LSP 面向编辑器实时交互的设计不同,Sem 选择将“实体”(Entities)作为基本抽象单元,直接构建在 Git 版本控制之上,为开发者提供了一种更接近代码本质的分析方式。
从“语法”到“实体”:一场理解方式的迁移
LSP 的问世极大改善了开发者的编码体验,但其核心依赖对代码的即时语法解析和符号索引。当面对数千万行代码的 monorepo、混合语言项目或需要理解代码历史演变的场景时,LSP 的能力边界便暴露无遗。
Sem 团队认为,代码理解的真正基础不在于文件或函数,而在于“实体”——一个可独立存在、可跨版本追踪的代码单元。实体可以是变量、类、接口、模块,甚至是一个设计模式或架构概念。更重要的是,这些实体不是通过实时编译得来的,而是通过解析 Git 提交历史、差异(diff)以及符号变更动态重建的。
“我们不是要做另一个 LSP ,而是提供一个更底层的抽象——一个原语。”Sem 创始人兼 CEO Alex Chen 在发布声明中表示,“LSP 为编辑器而生,Sem 为代码本身而生。”
基于 Git 的实体图:让历史成为理解引擎
Sem 的核心创新在于将 Git 仓库视为“实体图”(Entity Graph)的持久化层。每一次提交、分支合并、文件重命名,都被转化为实体之间的关联变更。例如,当开发者修改一个函数并更新所有调用处时,Sem 的引擎会自动识别这些变更,并在实体图中创建“影响链”(impact chain),而非仅仅记录文件行的变化。
这一方法的优势体现在三个方面:
- 历史敏感性:传统代码分析工具在面对“这个参数为何被删除”的问题时,需要人工回溯 commit。Sem 的实体图直接记录了每个实体从诞生到消亡的全生命周期,支持“时间旅行”式查询。
- 跨语言融合:由于实体图不依赖特定语言的 AST,只要 Git 能追踪变更,Sem 就能理解——同一仓库中的 Python、TypeScript、Rust 代码可以被统一建模为实体,并分析它们之间的依赖关系。
- 增量理解:Sem 只需分析最新提交及相关的实体变化,不必每次重新扫描整个仓库,极大降低了大项目冷启动的成本。
与 LSP 并非替代,而是互补生态
尽管 Sem 被描述为“不是 LSP”,但团队明确表示二者并非零和竞争。LSP 仍然是为编辑器提供即时补全、跳转的最佳方案;而 Sem 更适合代码审查、架构重构、技术债务分析、合规审计等需要理解代码“为什么”的场景。
例如,在代码审查中,Sem 可以自动列出当前 PR 影响的所有实体,并给出每个实体的历史修改模式,帮助评审者快速判断变更是否合理。在大型重构时,开发者可以用 Sem 查询“所有违反依赖规则的实体”,并模拟出不同重构方案对实体图的影响。
“LSP 告诉我们代码现在是什么,Sem 告诉我们代码曾经是什么,以及它可能会变成什么。”一位参与测试的资深工程师如此评价。
开放性与挑战
目前 Sem 以开源 CLI 工具的形式发布,支持 Git 仓库的本地分析,同时提供 SaaS 版的实体可视化界面。团队计划在未来增加对 GitHub、GitLab 等平台的深度集成,并开放实体图的查询 API。
不过,业界也有审慎的声音。有分析指出,Sem 的学习曲线较高,实体定义需要团队约定规范;此外,对于频繁变动的、缺乏规范历史记录的仓库,实体图的准确性与及时性仍有待验证。对此,Sem 团队表示将持续迭代实体推理算法,并邀请社区贡献更多实体定义模板。
未来:代码理解的下一个十年
随着 AI 辅助编程的兴起,代码理解工具正从“辅助导航”走向“深层认知”。Sem 提出的“实体原语”或许正是这一变化的催化剂。当代码不再被视作扁平的文本行,而是由实体编织的复杂网络,理解和改进代码的方式可能会发生根本性转变。
正如 Sem 官网所言:“你无法改进你不理解的东西。我们让你理解代码的过去、现在和可能的未来。”