mcpField
S
serena

serena

github.com/massgen开发1.1k214 次安装20 周前更新
代码仓库

关于 serena

serena 是一项通过语言服务器协议分析进行符号级代码导航与编辑的技能。它帮助编码 Agent 在支持的语言中查找定义和引用、评估改动影响并精确修改代码。

主要功能

  1. 01查找符号及其定义
  2. 02追踪代码中的符号引用
  3. 03在符号位置插入代码
  4. 04重命名符号并编辑函数体
  5. 05通过 LSP 支持 30 多种语言

适用场景

  1. 01重构前追踪调用位置
  2. 02评估代码改动的影响
  3. 03定位无引用或未使用的符号
  4. 04精确添加方法或错误处理

MCP 相关

Serena 可通过直接 MCP 工具使用,涵盖符号查找、重构、项目引导和记忆操作等功能。该技能也介绍命令行访问方式,并建议在可用时优先使用直接 MCP 工具。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/massgen/massgen --skill serena

安装后在 Claude Code 中输入/serena确认已加载。

详细介绍

Serena:符号级代码理解

借助 Language Server Protocol (LSP) 提供的类 IDE 语义分析,在符号级别浏览和操作代码。

如何使用 Serena

你可以通过以下一种或两种方式使用 Serena:

选项 1:直接使用 MCP 工具(如果你的编排器已配置) 查看可用工具中是否有:

  • find_symbol、find_referencing_symbols - 查找符号
  • rename_symbol、replace_symbol_body - 重构
  • insert_after_symbol、insert_before_symbol - 精确插入
  • onboarding、activate_project - 理解项目
  • write_memory、read_memory - 保存上下文
  • 以及 25+ 个由 LSP 驱动的工具

如果你看到这些工具,请直接使用它们——它们提供完整的 Serena 功能!

选项 2:CLI 命令(始终可通过 execute_command 使用) 你可以使用以下命令运行 serena 命令:

execute_command("uvx --from git+https://github.com/oraios/serena serena <command>")

本技能重点介绍 CLI 使用模式。如果你有直接的 MCP 工具,请优先使用它们,以获得更好的集成体验。

用途

serena 技能可让你使用 Serena,这是一套编码 Agent 工具包,能将基于文本的大模型转变为具备符号感知能力的代码 Agent。与传统文本搜索(ripgrep)或结构搜索(ast-grep)不同,Serena 通过 LSP 集成理解代码语义。

主要功能:

  1. 符号发现:按名称查找 30+ 种语言中的类、函数、变量和类型
  2. 引用追踪:发现符号被引用或使用的所有位置
  3. 精确编辑:以极高精度在指定符号位置插入代码

Serena 在符号级别而非文本或语法级别运行,因此能够像 IDE 一样真正理解代码结构、作用域和关系。

何时使用此技能

当你需要符号级代码理解时,请使用 serena 技能:

代码导航:

  • 查找类、函数或变量的定义位置
  • 找出符号的所有使用位置(调用位置、导入、引用)
  • 理解代码依赖项及其关系
  • 通过函数调用追踪执行流程

代码理解:

  • 分析对函数或类进行更改的影响
  • 理解继承层次结构和类型关系
  • 识别死代码(从未被引用的符号)
  • 梳理整个代码库中的 API 使用模式

代码重构:

  • 重命名符号,同时追踪所有使用位置
  • 向指定类添加方法或字段
  • 在特定函数调用后插入错误处理
  • 修改已弃用函数的所有调用位置

以下情况优先选择 serena,而非文件搜索(ripgrep/ast-grep):

  • 需要理解符号语义(而不仅是文本模式)
  • 希望跨文件和模块追踪引用
  • 需要根据代码结构确定精确的插入位置
  • 正在处理复杂的多文件代码库

以下情况仍应使用文件搜索:

  • 搜索文本模式、注释或字符串
  • 查找待办事项、安全问题或文档
  • 需要更快、更简单的模式匹配
  • 不需要符号级精确度

语言支持

Serena 使用 LSP 服务进行语义分析。大多数常见语言均开箱即用:

  • Python(pyright、jedi)
  • JavaScript/TypeScript(typescript-language-server)
  • Rust(rust-analyzer)
  • Go(gopls)
  • Java(jdtls)
  • C/C++(clangd)
  • C#、Ruby、PHP、Kotlin、Swift、Scala 等 15+ 种语言

LSP 服务会为你正在使用的语言提供符号信息。

核心操作

1. 查找符号(find_symbol)

查找代码库中符号的定义位置。

**注意:**以下示例均使用简写形式 serena <command>。完整命令为:

uvx --from git+https://github.com/oraios/serena serena <command>
# Find a class definition
execute_command("uvx --from git+https://github.com/oraios/serena serena find_symbol --name 'UserService' --type class")

# Find a function definition
execute_command("uvx --from git+https://github.com/oraios/serena serena find_symbol --name 'authenticate' --type function")

# Find a variable definition
execute_command("uvx --from git+https://github.com/oraios/serena serena find_symbol --name 'API_KEY' --type variable")

使用场景:

  • 修改类之前定位其定义
  • 查找函数的实现位置
  • 了解常量的定义位置
  • 在带类型的语言中追踪类型定义

输出格式:

File: src/services/user_service.py
Line: 42
Symbol: UserService (class)
Context: class UserService(BaseService):
2. 查找引用(find_referencing_symbols)

查找符号被使用、导入或引用的所有位置。

# Find all usages of a class
execute_command("serena find_referencing_symbols --name 'UserService'")

# Find all call sites of a function
execute_command("serena find_referencing_symbols --name 'authenticate'")

# Find all reads/writes of a variable
execute_command("serena find_referencing_symbols --name 'API_KEY'")

使用场景:

  • 重构前进行影响分析
  • 查找函数的所有调用位置
  • 跟踪跨模块的 API 使用情况
  • 识别未使用的符号(零引用)
  • 了解数据流和依赖关系

输出格式:

Found 12 references to 'authenticate':

1. src/api/routes.py:34
   authenticate(user_credentials)

2. src/middleware/auth.py:18
   from services import authenticate

3. tests/test_auth.py:56
   mock_authenticate = Mock(spec=authenticate)
...
3. 精确插入代码(insert_after_symbol)

以精确的方式在指定的符号位置插入代码。

# Add a method to a class
execute_command("""serena insert_after_symbol --name 'UserService' --type class --code '
    def get_user_by_email(self, email: str) -> Optional[User]:
        return self.db.query(User).filter_by(email=email).first()
'""")

# Insert error handling after a function call
execute_command("""serena insert_after_symbol --name 'database_query' --code '
    if result is None:
        raise DatabaseError("Query returned no results")
'""")

# Add a field to a dataclass
execute_command("""serena insert_after_symbol --name 'User' --type class --code '
    email_verified: bool = False
'""")

使用场景:

  • 向现有类添加方法
  • 插入验证或错误处理
  • 向数据结构添加字段
  • 注入日志记录或监控代码
  • 实现缺失的功能

安全特性:

  • 遵循缩进和代码格式
  • 保持语法有效
  • 将代码准确放置在作用域内
  • 保留现有代码结构

工作流模式

模式 1:安全重构

更改函数签名或行为时:

# Step 1: Find the function definition
serena find_symbol --name 'process_payment' --type function

# Step 2: Find all call sites
serena find_referencing_symbols --name 'process_payment'

# Step 3: Analyze impact (review output)
# [Review all usage locations to understand impact]

# Step 4: Make changes with confidence
# [Update function and all call sites based on findings]
模式 2:添加功能

使用新方法扩展类时:

# Step 1: Locate the class
serena find_symbol --name 'PaymentProcessor' --type class

# Step 2: Verify no conflicts
serena find_symbol --name 'process_refund' --type function

# Step 3: Insert new method
serena insert_after_symbol --name 'PaymentProcessor' --type class --code '
    def process_refund(self, payment_id: str, amount: float) -> bool:
        # Implementation here
        pass
'
模式 3:了解依赖关系

分析代码关系时:

# Step 1: Find class definition
serena find_symbol --name 'DatabaseManager' --type class

# Step 2: Find all usages
serena find_referencing_symbols --name 'DatabaseManager'

# Step 3: For each usage, find what symbols use that code
# [Repeat reference tracking to build dependency graph]
模式 4:检测死代码

识别未使用的代码时:

# Step 1: Find symbol definition
serena find_symbol --name 'legacy_auth_handler'

# Step 2: Check references
serena find_referencing_symbols --name 'legacy_auth_handler'

# Step 3: If zero references (except definition), mark for removal
# [If output shows only the definition, symbol is unused]

与 file-search 集成

Serena 和 file-search(ripgrep/ast-grep)是互补工具。请结合使用:

何时组合使用工具

先使用 ripgrep,再使用 serena:

# 1. Find potential matches with ripgrep (fast, broad)
rg "authenticate" --type py

# 2. Narrow to specific symbol with serena (precise)
serena find_symbol --name 'authenticate' --type function
serena find_referencing_symbols --name 'authenticate'

先使用 serena,再使用 ripgrep:

# 1. Find symbol definition with serena
serena find_symbol --name 'UserService'

# 2. Search for related patterns with ripgrep
rg "UserService\(" --type py  # Find direct instantiations
rg "class.*UserService" --type py  # Find subclasses
互补优势
任务最佳工具原因
查找字符串字面量ripgrep基于文本,速度快
查找 TODO/注释ripgrep基于文本
查找符号定义serena感知符号
查找所有引用serena具备语义理解
查找代码模式ast-grep感知语法
在符号处插入代码serena定位精准
跨语言搜索ripgrep与语言无关
了解作用域serenaLSP 语义信息

最佳实践

1. 从发现符号开始

始终先定位符号定义:

# GOOD: Find definition, then references
serena find_symbol --name 'MyClass'
serena find_referencing_symbols --name 'MyClass'

# AVOID: Searching for references without confirming definition exists
2. 使用特定符号类型

尽可能使用 --type 缩小搜索范围:

# GOOD: Specific type reduces ambiguity
serena find_symbol --name 'User' --type class

# LESS PRECISE: May match User function, User variable, etc.
serena find_symbol --name 'User'
3. 插入前进行验证

始终先查找符号,再插入代码:

# GOOD: Verify target exists first
serena find_symbol --name 'PaymentService' --type class
# [Review output to confirm correct class]
serena insert_after_symbol --name 'PaymentService' --code '...'

# RISKY: Inserting without verification
serena insert_after_symbol --name 'PaymentService' --code '...'
4. 查看引用数量

检查引用输出以进行影响分析:

# Find references and assess impact
serena find_referencing_symbols --name 'deprecated_function'
# If 50+ references, plan careful migration
# If 0 references, safe to remove
5. 结合使用 git diff

插入代码后,验证更改:

serena insert_after_symbol --name 'MyClass' --code '...'
git diff  # Review actual changes before committing

支持的语言

Serena 通过 LSP 集成支持 30 多种语言:

第 1 级(经过全面测试):

  • Python、JavaScript、TypeScript、Rust、Go、Java、C/C++

第 2 级(经过社区测试):

  • C#、Ruby、PHP、Kotlin、Swift、Scala

第 3 级(实验性):

  • Haskell、Elixir、Clojure、Erlang、Julia、R 等

完整列表和设置说明,请参阅 Serena 语言支持文档。

局限性

不适合使用 Serena 的情况
  1. 搜索文本/注释:请改用 ripgrep

    # WRONG TOOL: Serena doesn't search comments
    serena find_symbol --name "TODO"
    
    # RIGHT TOOL: Use ripgrep for text
    rg "TODO"
    
  2. 生成的代码:LSP 可能不会为自动生成的文件建立索引

    • 使用 ripgrep 搜索构建产物和生成的代码
  3. 非常大型的代码库:符号索引可能较慢

    • 使用 ripgrep 进行初步的广泛搜索
    • 使用 serena 进行精确的后续搜索
  4. 没有类型信息的动态语言:语义信息有限

    • 没有类型提示的 Python 精确度会降低
    • 没有 TypeScript 的 JavaScript 保证较少
已知边缘情况
  • 符号有歧义:多个同名符号可能需要手动区分
  • 宏生成的代码:C/C++ 宏可能会使 LSP 混淆
  • 循环依赖:可能影响引用跟踪的准确性
  • 项目不完整:缺少依赖项可能降低 LSP 的有效性

性能注意事项

Token 效率

Serena 专为高效使用 Token 的代码导航而设计:

# Traditional approach (inefficient)
execute_command("cat entire_file.py")  # 1000+ tokens
# [Search for symbol manually in output]

# Serena approach (efficient)
serena find_symbol --name 'MyClass'  # 50 tokens
# [Get precise location immediately]
速度特性
  • 符号查找:近乎即时(已建立 LSP 索引)
  • 引用查找:快速(使用索引时为 O(log n))
  • 代码插入:即时(直接修改文件)

与替代方案的比较:

  • Ripgrep:文本搜索更快(不具备语义理解能力)
  • AST-grep:速度相近(语法分析与语义分析)
  • Serena:初始启动较慢(LSP 建立索引),精准查询更快

故障排除

未找到符号

如果 find_symbol 没有返回结果:

  1. 确认符号存在:使用 ripgrep 确认

    rg "class MyClass" --type py
    
  2. 检查语言服务器:确保已为该语言配置 LSP

    serena status  # Check LSP server status
    
  3. 尝试不同大小写:符号名称区分大小写

    serena find_symbol --name 'myclass'  # Try different cases
    
  4. 重建索引:强制 LSP 重新建立索引

    serena reindex  # Rebuild symbol index
    
引用过多

如果 find_referencing_symbols 返回数百条结果:

  1. 先使用文件搜索:通过 ripgrep 缩小范围

    rg "MyClass" src/services/  # Limit to specific directory
    serena find_referencing_symbols --name 'MyClass' --path src/services/
    
  2. 按引用类型筛选:聚焦于特定的使用模式

    # Look for imports only
    rg "from .* import.*MyClass" --type py
    
  3. 优先查看近期变更:先检查 git 历史

    git log --all -p -S 'MyClass' --since="1 week ago"
    
插入失败

如果 insert_after_symbol 失败:

  1. 确认符号存在:先找到该符号
  2. 检查语法:确保插入的代码有效
  3. 检查缩进:与周围代码风格保持一致
  4. 逐步测试:先插入小幅变更

资源

评论

支持 Markdown