关于 serena
serena 是一项通过语言服务器协议分析进行符号级代码导航与编辑的技能。它帮助编码 Agent 在支持的语言中查找定义和引用、评估改动影响并精确修改代码。
主要功能
- 01查找符号及其定义
- 02追踪代码中的符号引用
- 03在符号位置插入代码
- 04重命名符号并编辑函数体
- 05通过 LSP 支持 30 多种语言
适用场景
- 01重构前追踪调用位置
- 02评估代码改动的影响
- 03定位无引用或未使用的符号
- 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 集成理解代码语义。
主要功能:
- 符号发现:按名称查找 30+ 种语言中的类、函数、变量和类型
- 引用追踪:发现符号被引用或使用的所有位置
- 精确编辑:以极高精度在指定符号位置插入代码
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 | 与语言无关 |
| 了解作用域 | serena | LSP 语义信息 |
最佳实践
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 的情况
-
搜索文本/注释:请改用 ripgrep
# WRONG TOOL: Serena doesn't search comments serena find_symbol --name "TODO" # RIGHT TOOL: Use ripgrep for text rg "TODO" -
生成的代码:LSP 可能不会为自动生成的文件建立索引
- 使用 ripgrep 搜索构建产物和生成的代码
-
非常大型的代码库:符号索引可能较慢
- 使用 ripgrep 进行初步的广泛搜索
- 使用 serena 进行精确的后续搜索
-
没有类型信息的动态语言:语义信息有限
- 没有类型提示的 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 没有返回结果:
-
确认符号存在:使用 ripgrep 确认
rg "class MyClass" --type py -
检查语言服务器:确保已为该语言配置 LSP
serena status # Check LSP server status -
尝试不同大小写:符号名称区分大小写
serena find_symbol --name 'myclass' # Try different cases -
重建索引:强制 LSP 重新建立索引
serena reindex # Rebuild symbol index
引用过多
如果 find_referencing_symbols 返回数百条结果:
-
先使用文件搜索:通过 ripgrep 缩小范围
rg "MyClass" src/services/ # Limit to specific directory serena find_referencing_symbols --name 'MyClass' --path src/services/ -
按引用类型筛选:聚焦于特定的使用模式
# Look for imports only rg "from .* import.*MyClass" --type py -
优先查看近期变更:先检查 git 历史
git log --all -p -S 'MyClass' --since="1 week ago"
插入失败
如果 insert_after_symbol 失败:
- 确认符号存在:先找到该符号
- 检查语法:确保插入的代码有效
- 检查缩进:与周围代码风格保持一致
- 逐步测试:先插入小幅变更