Serena语义检索在AI CodeReview中的应用

1. Serena 介绍

Serena 是一个辅助大语言模型(LLM)进行代码分析的工具包。它提供代码语义检索代码编辑 功能,并通过 MCP (Model Context Protocol) 协议与大模型进行交互。

Serena 的核心能力构建于 Language Server Protocol (LSP) 之上。LSP 为各种编程语言提供专属的 Language Server,用于分析代码并提供语法、语义信息。Serena 利用 LSP,使大模型能够获取这些深层信息,从而摆脱纯文本分析的局限。

目前,LSP 已广泛支持各类主流后端语言,如 GoPHPPython 等。

本文将介绍如何将 Serena 作为 MCP 服务器,与 Claude Code 结合,在代码审核任务中发挥作用。

2. Serena 安装与配置

由于本次代码审核在本地环境进行,我们采用本地安装方式。

  1. 克隆 Serena 仓库 将 Serena 的源代码下载到本地。

    bash 复制代码
    git clone https://github.com/oraios/serena.git
  2. 为项目添加 MCP 工具 进入项目目录,执行以下命令,将 Serena 注册为 Claude 的一个可用工具。

    bash 复制代码
    claude mcp add serena -- uv run --directory /path/to/your/serena serena-mcp-server --context agent --project ($pwd)

    命令解析:

    • --directory /path/to/your/serena: 指定 Serena 工具的运行目录(即上一步 clone 的路径)。
    • --project ($pwd): 将当前项目目录指定为 Serena 的分析目标。

    注意 :请务必将 /path/to/your/serena 替换为你的实际代码路径。


环境依赖说明

  • Go 项目审核 :需确保本地环境中已安装 gogopls(Go 官方语言服务器)。
  • CI/CD 环境 :在 GitLab CI 等流水线中,推荐使用 Docker 方式运行。你需要基于项目提供的 Dockerfile 构建镜像,并确保镜像内已包含 claude code、go、gopls 等所有必要程序。

3. 核心能力对比:Serena vs. Claude Code文本查找工具

Serena 的优势在于其语义理解能力远超 Claude Code 原生的 grep 文本搜索工具。下面通过具体示例进行对比。

示例代码:

go 复制代码
// 文件: user_service.go
type UserService struct {
    db *sql.DB
}

func NewUserService() *UserService { /* ... */ }
func (s *UserService) GetUser(id int) *User { /* ... */ }

// 文件: user_controller.go
func (c *Controller) HandleRequest() {
    user := c.service.GetUser(123)  // GetUser 的一处引用
}

// 文件: user_test.go
func TestGetUser() {
    service.GetUser(1)  // GetUser 的另一处引用
}

get_symbols_overview:快速获取文件结构

此功能用于生成一个文件的代码结构摘要。

  • Serena 命令 : get_symbols_overview

  • 输出 (结构化) :

    json 复制代码
    {
        "symbols": [
            {"name": "UserService", "kind": "struct"},
            {"name": "GetUser", "kind": "method", "receiver": "UserService"},
            {"name": "NewUserService", "kind": "function"}
        ]
    }
  • 传统工具 : grep "func"

  • 输出 (纯文本) :

    go 复制代码
    func NewUserService() *UserService { /* ... */ }
    func (s *UserService) GetUser(id int) *User { /* ... */ }

核心差异

  • Serena : 能理解代码,清晰地区分方法函数结构体,并展示出方法与结构体的归属关系。
  • grep: 只能进行无差别的文本匹配,无法理解代码结构。

find_symbol:进行符号级别的精准查找

此功能允许根据名称、类型等信息精确查找代码符号。

  • 任务 : 查找 UserService 结构体及其所有方法。

  • Serena 命令 : find_symbol(name_path="UserService", depth=1, include_body=True)

  • 输出 (结构化) :

    json 复制代码
    {
        "symbols": [{
            "name_path": "UserService",
            "kind": "struct",
            "body": "type UserService struct { db *sql.DB }",
            "children": [{
                "name_path": "UserService/GetUser",
                "kind": "method",
                "body": "func (s *UserService) GetUser(id int) *User { /* ... */ }"
            }]
        }]
    }

能力对比

任务 find_symbol (Serena) grep / 原生工具
查找类的所有方法 find_symbol("UserService", depth=1) grep "func.*UserService" + 手动筛选
查找特定方法 find_symbol("UserService/GetUser") grep "GetUser" + 人工检查上下文
获取符号源码 include_body=True grep -A 10 "func GetUser" (行数不准)

find_referencing_symbols:实现精准的引用追踪

这是 Serena 最强大的功能之一,能精确找到一个符号在整个项目中的所有真实引用,过滤掉注释和字符串中的同名文本。

  • 任务 : 查找 GetUser 方法在项目中的所有调用。

  • Serena 命令 : find_referencing_symbols("GetUser", "user_service.go")

  • 输出 (结构化) :

    json 复制代码
    {
        "references": [
            {
                "file": "user_controller.go",
                "line": 10,
                "context": "user := c.service.GetUser(123)",
                "symbol_info": {"kind": "method_call"}
            },
            {
                "file": "user_test.go",
                "line": 15,
                "context": "service.GetUser(1)",
                "symbol_info": {"kind": "method_call"}
            }
        ]
    }

核心差异

特性 find_referencing_symbols (Serena) grep 等传统工具
准确性 真实的代码引用 包含大量注释、字符串等无关结果
上下文 提供调用处的完整代码行和文件信息 仅提供匹配行,上下文信息缺失
语义理解 能区分方法调用变量引用 无法区分,均为文本匹配
跨文件 自动扫描整个项目 需指定范围,容易遗漏

4. Serena 其他功能一览

除了上述核心功能,Serena 还提供了一套完整的工具集:

  • 文件操作 : read_file, create_text_file, list_dir, find_file
  • 代码搜索 : search_for_pattern, get_symbols_overview, find_symbol, find_referencing_symbols
  • 代码编辑 : replace_regex, replace_symbol_body, insert_after_symbol, insert_before_symbol
  • 记忆管理 : write_memory, read_memory, list_memories, delete_memory
  • 命令执行 : execute_shell_command
  • 项目管理 : activate_project, get_current_config
  • 流程控制 : onboarding, check_onboarding_performed, think_about_*

5. 总结

通过集成 Serena MCP,我们可以将大模型(如 Claude Code)的代码分析能力从传统的 "文本搜索" 升级为真正的 "代码语义理解"

在代码审核场景中,这意味着 AI 不再是简单的模式匹配器。它能够像开发者一样理解代码结构、追踪逻辑,从而提供更深层的洞察和更可靠的建议,显著提升 AI 代码审核的准确率和效率。

相关推荐
JELEE.12 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
QX_hao15 小时前
【Go】--反射(reflect)的使用
开发语言·后端·golang
小坏讲微服务15 小时前
Docker-compose 搭建Maven私服部署
java·spring boot·后端·docker·微服务·容器·maven
yuuki23323315 小时前
【数据结构】用顺序表实现通讯录
c语言·数据结构·后端
你的人类朋友16 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
史不了16 小时前
静态交叉编译rust程序
开发语言·后端·rust
码事漫谈17 小时前
C++中的多态:动态多态与静态多态详解
后端
码事漫谈17 小时前
单链表反转:从基础到进阶的完整指南
后端
与遨游于天地18 小时前
Spring解决循环依赖实际就是用了个递归
java·后端·spring