# LSP 代码智能 · 让模型用上语言服务器

> grep 只能按文本找，理解代码得靠语言服务器。grok 的 lsp 工具把 LSP（跳转定义、找引用、悬停、符号）接给模型，背后是一套用 async_lsp 管理多语言服务器进程、按扩展名路由、崩溃自动重启的引擎。

- 作者：David（道雾轩）
- 专栏：Grok Build 源码解读（https://daiw.org/manual/grok-build.md）
- 最后更新：2026-09-15
- 原文：https://daiw.org/manual/grok-build/lsp
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# LSP 代码智能 · 让模型用上语言服务器

[grep](https://daiw.org/manual/grok-build/read-and-search) 只能按文本匹配，但「这个函数在哪定义的、被谁调用了」这类问题，得靠**语言服务器**(LSP)。grok 的 `lsp` 工具就是把 IDE 级的代码智能接给模型。

## lsp 工具：六种操作

id `lsp`(kind `Lsp`，只读)。参数 `operation` + `file_path` + `line`/`character`(都 0 起)。操作：

- `goToDefinition`——跳到定义
- `findReferences`——找所有引用
- `hover`——看类型/文档
- `goToImplementation`——跳到实现
- `documentSymbol` / `workspaceSymbol`——列文件内/工作区符号

它的描述直接引导模型：「理解代码时优先用它，而不是 grep/read」。因为 LSP 给的是**语义**答案，grep 给的是文本猜测。

## 引擎：真的语言服务器进程

背后(`implementations/lsp/`)用的是成熟的 **`async_lsp`** crate，不是自己造轮子：

- **`LspManager`** 按**文件扩展名**把请求路由到对应的语言服务器(`.rs`→rust-analyzer、`.py`→pyright……);
- **`LspClient`** 真的**spawn 一个语言服务器进程**，用 JSON-RPC 走 stdio 通信；
- 每个操作转成一次 `async_lsp` 的 `LanguageServer` 调用，结果格式化成模型友好的文本。

```mermaid
flowchart LR
  M[模型: lsp goToDefinition] --> T[lsp 工具]
  T --> BK[LspBackend]
  BK --> MG[LspManager 按扩展名路由]
  MG -->|.rs| RA[rust-analyzer 进程]
  MG -->|.py| PY[pyright 进程]
  RA --> R[定义位置 → 格式化回模型]
```

## 生产级的琐事

把外部进程接进来，一堆事得兜住：

- **配置合并**：`~/.grok/lsp.json`(用户)→ `<cwd>/.grok/lsp.json`(项目)→ 插件配置，后者只补空缺。项目级服务器在**目录未受信**时会被丢掉(`filter_project_lsp_when_untrusted`)，防不可信仓库偷偷起进程。
- **崩溃自愈**：`restart_monitor` 在 `max_restarts`(默认 3)预算内自动重启崩掉的服务器。
- **诊断**：编辑后语言服务器报的错误/警告(带 `is_stale` 标记)会作为 [system-reminder](https://daiw.org/manual/grok-build/tool-registry) 回给模型——这也是[主循环](https://daiw.org/manual/grok-build/agent-loop)里 `LspDiagnosticsReminder` 的来源。启停有 `LspServerStarting/Ready/Crashed` 通知。
- **超时**：启动 15s、请求 30s、关闭 5s。
- **适配更多服务器**：新增了拉模式诊断(`textDocument/diagnostic`，给 Roslyn 这类从不主动推送诊断的服务器)、由客户端代办的 `workspace/didChangeWatchedFiles`、告诉服务器加载哪个解决方案的 workspace-open 扩展；`initialize` 返回的能力也不再丢弃，而是据此管理文档同步。

## 和《从 LLM 到 Coding Agent》对照

那本没有 LSP——因为它是「让 agent 真正读懂代码」的产品级加分项，不是 agent 的必需骨架。grok 把它做成一个可选但完整的子系统：一个薄工具 + 一套管理多语言服务器进程、路由、重启、诊断回灌的引擎。它让模型从「文本匹配」升到「语义理解」，是 grok 作为**编码** agent 的关键一环。

---

上一篇：[沙箱与权限](https://daiw.org/manual/grok-build/sandbox-permissions) · 下一篇：[Web 工具](https://daiw.org/manual/grok-build/web-tools)
