OpenCode LSP 自动诊断修复循环 移植指南 OpenCode 核心能力:LSP 实时诊断 → AI 自动读取 → 诊断→分析→修复 自主循环 目标工具:ZCode CodeBuddy
OpenCode LSP 自动诊断修复循环 移植指南
OpenCode 核心能力:LSP 实时诊断 → AI 自动读取 → 诊断→分析→修复 自主循环
目标工具:ZCode / CodeBuddy / AtomCode / KimiCode / Qoder
一、OpenCode 的 LSP 联动机制拆解
OpenCode 的"诊断→分析→修复"自动循环由三层组成:
┌─────────────────────────────────────────────────────────┐
│ Layer 1: LSP 客户端层 │
│ - 打开文件时自动匹配并启动对应 LSP 服务器 │
│ - 监听 textDocument/publishDiagnostics 推送 │
│ - 将诊断信息(错误码、行列号、severity)结构化存储 │
├─────────────────────────────────────────────────────────┤
│ Layer 2: AI 上下文注入层 │
│ - 每次对话前,自动将当前文件的 LSP 诊断注入系统 Prompt │
│ - 格式:文件路径 + 诊断列表(含 severity/消息/位置) │
│ - AI 无需用户手动贴日志,直接基于结构化诊断推理 │
├─────────────────────────────────────────────────────────┤
│ Layer 3: 自主修复循环层 │
│ - AI 生成修复代码 → 写入文件 → 触发 LSP 重新诊断 │
│ - 若诊断未清零,自动进入下一轮修复 │
│ - 直到 diagnostics 为空或达到最大迭代次数 │
└─────────────────────────────────────────────────────────┘
关键协议:LSP 的 textDocument/publishDiagnostics 通知是推送式的,客户端无需轮询,服务器在文件变更后主动推送诊断 cite🛠web_search:15#18:~:text=诊断信息是推送式的,语言服务器在文件打开或更改时发送诊断。
二、各工具移植可行性评估
| 工具 | LSP 原生支持 | 自动诊断→修复 | 移植难度 | 推荐方案 |
|---|---|---|---|---|
| CodeBuddy | ✅ 完整(官方插件+4.11.0 LSP 语义工具) | ✅ 已支持(“同一轮中注意到并修复”) | ⭐ 极低 | 直接配置使用 |
| ZCode | ⚠️ 插件体系含 LSP,但第三方评测称"暂不支持" | ❓ 未明确 | ⭐⭐ 低 | 写 LSP 插件或等官方更新 |
| AtomCode | ⚠️ 配置中有 [lsp] 段,默认关闭 |
❌ 无自动循环 | ⭐⭐⭐ 中等 | 启用 LSP + 自定义 Hook |
| KimiCode | ❌ 无 LSP 客户端 | ❌ 无自动循环 | ⭐⭐⭐⭐ 高 | lsp-mcp-server 桥接 |
| Qoder | ❌ 依赖外部 IDE 的 LSP | ❌ 无自动循环 | ⭐⭐⭐⭐ 高 | lsp-mcp-server 桥接 |
三、逐工具移植方案
1. CodeBuddy — 最接近 OpenCode,几乎零移植成本
CodeBuddy 官方已完整实现 LSP 联动自动诊断修复 cite🛠web_search:14#6:~:text=自动诊断:每次编辑后,语言服务器会自动分析更改并报告错误和警告。CodeBuddy Code 可以看到类型错误、缺失的导入和语法问题,无需运行编译器或 linter。如果引入错误,会在同一轮中注意到并修复。无需任何配置即可工作,且 4.11.0 版本新增了 LSP 语义工具 cite🛠web_search:14#14:~:text=新增 LSP 语义工具,提升 Agent 代码理解与导航能力。
配置方式:
# 1. 安装对应语言的 LSP 插件(以 C++ 为例)
codebuddy plugin install codebuddy-lsp-cpp
# 2. 确保语言服务器在 PATH 中
which clangd # 或 pylsp, gopls, rust-analyzer 等
# 3. 打开项目,自动诊断即生效
# CodeBuddy 会自动读取 diagnostics 并尝试修复
AscendC 场景适配:
CodeBuddy 的 LSP 插件体系支持自定义语言服务器 cite🛠web_search:14#6:~:text=你也可以为其他语言 创建自己的 LSP 插件。但 AscendC 没有现成的 LSP 服务器,需要:
- 用
clangd做基础 C++ 语法检查(.cpp文件) - 通过 Hooks 在保存后自动执行
bash build.sh捕获编译日志 cite🛠web_search:14#9:~:text=Hooks(钩子)…自动响应 CodeBuddy 事件 - 将编译日志通过 MCP 或 Hook 回传给 AI
// CodeBuddy 插件 hooks/hooks.json 示例
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash build.sh 2>&1 | tee /tmp/build.log"
}
]
}
]
}
}
2. ZCode — 插件化 LSP,需确认版本
ZCode 官方文档显示插件体系包含 LSP 组件 cite🛠web_search:14#13:~:text=LSP|语言服务,为对应语言提供补全、诊断等能力,但第三方评测(Version 0.15.1)提到"暂不支持LSP" cite🛠web_search:14#15:~:text=暂不支持LSP(语言服务器协议),代码智能提示功能相对有限。
可能原因:LSP 支持在较新版本(>0.15.1)中加入,或处于 Beta 阶段。
移植方案 A(官方已支持 LSP):
# 1. 创建 LSP 插件目录
mkdir -p ~/.zcode/plugins/ascendc-lsp
# 2. 编写 plugin.json
cat > ~/.zcode/plugins/ascendc-lsp/plugin.json << 'EOF'
{
"name": "ascendc-lsp",
"version": "1.0.0",
"components": {
"lsp": {
"command": "clangd",
"args": ["--background-index", "--clang-tidy"],
"fileTypes": [".cpp", "h"]
}
}
}
EOF
# 3. 在 ZCode 中启用插件
# 插件管理页面 → 启用 ascendc-lsp
移植方案 B(官方暂不支持 LSP):
使用 MCP 桥接 方案(见第 5 节通用方案),或等待 ZCode 官方更新。
3. AtomCode — 启用内置 LSP + 自定义 Hook
AtomCode 配置文件中有 [lsp] 段,但默认关闭 cite🛠web_search:14#10:~:text=[lsp] enabled = false auto_detect = false。
移植步骤:
# ~/.atomcode/config.toml
[lsp]
enabled = true # 启用 LSP
auto_detect = true # 自动检测语言服务器
# 手动指定 AscendC 相关语言的 LSP 服务器
[lsp.servers.cpp]
command = "clangd"
args = ["--background-index", "--clang-tidy", "--header-insertion=iwyu"]
[lsp.servers.python]
command = "pylsp"
args = []
自动修复循环:
AtomCode 目前没有内置的"诊断→修复"自动循环,需要通过 Subagent 或 Hook 模拟:
# ~/.atomcode/config.toml
[subagent]
enabled = true
initial_turns = 4
max_turns = 12
# 自定义 Hook:保存文件后自动读取 LSP 诊断
[hooks.on_save]
action = "read_diagnostics"
target = "lsp"
⚠️ AtomCode 的 Hook 语法需参考官方文档,以上为概念示例。
4. KimiCode — 无 LSP,必须用 MCP 桥接
KimiCode 没有 LSP 客户端,但支持 shell 模式(! 前缀执行命令,输出自动写入上下文)和高达 1M token 的长上下文 cite🛠web_search:4#0:~:text=shell 模式…命令输出会写入上下文。
移植方案:lsp-mcp-server 桥接
# 1. 安装 lsp-mcp-server(通用 LSP-MCP 桥接工具)
npm install -g tritlo/lsp-mcp
# 2. 配置 KimiCode 的 MCP(如果支持)
# 或在 KimiCode 对话中手动调用
# 3. 启动 LSP-MCP 桥接(以 C++ 为例)
npx tritlo/lsp-mcp cpp $(which clangd) --stdio
# 4. 在 KimiCode 中使用工具调用获取诊断
# 工具:get_diagnostics, get_code_actions, open_document 等
lsp-mcp-server 提供的工具 cite🛠web_search:15#8:~:text=get_diagnostics:获取打开文件的诊断消息(错误、警告) cite🛠web_search:15#15:~:text=支持10种语言24种代码智能功能:
| 工具 | 功能 |
|---|---|
get_diagnostics |
获取当前文件诊断(错误/警告) |
get_code_actions |
获取自动修复建议 |
open_document |
将文件加载到 LSP 服务器 |
get_completions |
代码补全 |
get_info_on_location |
悬停信息(类型/文档) |
KimiCode 中的使用流程:
# 在 Kimi Code 对话中
!npx tritlo/lsp-mcp cpp $(which clangd) --stdio &
# 然后让 AI 调用 MCP 工具获取诊断
# 由于 KimiCode 没有内置 MCP 工具调用框架,需要:
# 1. 手动执行命令获取诊断
!echo '{"jsonrpc":"2.0","id":1,"method":"textDocument/diagnostics","params":{"uri":"file:///path/to/kernel.cpp"}}' | npx tritlo/lsp-mcp cpp $(which clangd) --stdio
# 2. 将输出贴回对话,AI 分析并修复
局限:KimiCode 没有 OpenCode 的自动循环,每次需要手动触发 LSP 诊断并贴回结果。
5. Qoder — 依赖外部 IDE,需外部桥接
Qoder 本身没有内置 LSP 客户端,对比分析显示它"依赖IDE(LSP)" cite🛠web_search:15#9:~:text=Qoder|意图感知(行为预测)|否|依赖IDE(LSP)|基于数据飞轮的持续优化。这意味着 Qoder 的代码智能能力来自外部 IDE(如 JetBrains、VS Code)的 LSP。
移植方案:外部 IDE + lsp-mcp-server 桥接
工作流:
VS Code / JetBrains(含 LSP) ←──→ lsp-mcp-server ←──→ Qoder
↑ (MCP 协议)
└──── 诊断信息通过 MCP 暴露给 Qoder
配置步骤:
- 在 VS Code 中安装
lsp-mcp-server扩展 - 配置 MCP 服务器连接到 Qoder
- Qoder 通过 MCP 工具调用获取诊断并修复
// .mcp.json(Qoder 配置)
{
"mcpServers": {
"lsp-bridge": {
"type": "stdio",
"command": "npx",
"args": ["tritlo/lsp-mcp", "cpp", "/usr/bin/clangd", "--stdio"]
}
}
}
四、通用方案:lsp-mcp-server 桥接(适用于所有工具)
对于没有原生 LSP 支持的工具(KimiCode、Qoder、旧版 ZCode),lsp-mcp-server 是最通用的桥接方案 cite🛠web_search:15#15:~:text=lsp-mcp-server是一个连接Claude Code与语言服务器协议(LSP)的桥接服务器,提供语义化代码智能功能。
架构
┌─────────────┐ MCP 协议 ┌─────────────────┐ LSP 协议 ┌──────────────┐
│ AI 工具 │ ←──────────────→ │ lsp-mcp-server │ ←──────────────→ │ LSP 服务器 │
│ (任何工具) │ (stdio/sse) │ (桥接中间件) │ (stdio/tcp) │ (clangd等) │
└─────────────┘ └─────────────────┘ └──────────────┘
安装与配置
# 1. 安装 lsp-mcp-server
npm install -g tritlo/lsp-mcp
# 2. 配置任意 AI 工具的 MCP
# 支持 Claude Code、Cursor、VS Code、OpenCode 等任何支持 MCP 的工具
# 3. 启动桥接(以 AscendC 的 C++ 文件为例)
npx tritlo/lsp-mcp cpp $(which clangd) --stdio
MCP 工具列表(AI 可直接调用)
| 工具 | 功能 | 对应 LSP 方法 |
|---|---|---|
start_lsp |
启动 LSP 服务器 | — |
open_document |
打开文件分析 | textDocument/didOpen |
get_diagnostics |
获取诊断信息 | textDocument/publishDiagnostics |
get_code_actions |
获取修复建议 | textDocument/codeAction |
get_completions |
代码补全 | textDocument/completion |
get_info_on_location |
悬停信息 | textDocument/hover |
restart_lsp_server |
重启 LSP | — |
自动修复循环实现
# 伪代码:任何支持 MCP 的 AI 工具都可以实现此循环
async def auto_fix_loop(file_path, max_iterations=5):
for i in range(max_iterations):
# 1. 打开文件
await mcp.call("open_document", {"file": file_path})
# 2. 获取诊断
diagnostics = await mcp.call("get_diagnostics", {"file": file_path})
# 3. 若无诊断,退出循环
if not diagnostics:
print("✅ 无错误,修复完成")
break
# 4. AI 基于诊断生成修复
fix = await ai.generate_fix(diagnostics)
# 5. 应用修复
await mcp.call("apply_edit", fix)
# 6. 等待 LSP 重新诊断(推送式)
await asyncio.sleep(0.5)
return diagnostics
五、AscendC 场景的特殊适配
AscendC 算子开发没有现成的 LSP 服务器,需要组合方案:
方案:clangd(C++ 语法)+ 编译日志(CANN 语义)
Layer 1: C++ 语法检查
└─ clangd 分析 .cpp / .h 文件的语法、类型错误
Layer 2: CANN 编译检查(通过 Hook/MCP)
└─ 保存后自动执行 `bash build.sh`
└─ 解析 build.log 中的 CANN 错误码
Layer 3: AI 联合诊断
└─ 将 clangd 诊断 + CANN 编译错误 合并为统一诊断列表
└─ AI 基于合并诊断生成修复方案
实现方式(以 CodeBuddy 为例):
// CodeBuddy 插件配置
{
"lsp": {
"cpp": {
"command": "clangd",
"args": ["--background-index"]
}
},
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash build.sh 2>&1 | python3 /path/to/cann-log-parser.py"
}
]
}
]
},
"mcpServers": {
"cann-log-parser": {
"command": "python3",
"args": ["/path/to/cann-log-parser.py", "--mcp-mode"]
}
}
}
cann-log-parser.py 功能:
- 解析
build.log中的ERROR:行 - 提取错误码、文件路径、行号
- 转换为 LSP 诊断格式(
{uri, range, severity, message}) - 通过 MCP 暴露给 AI
六、各工具移植总结
| 工具 | 当前 LSP 状态 | 移植路径 | 自动修复循环实现 | AscendC 适配难度 |
|---|---|---|---|---|
| CodeBuddy | ✅ 原生支持(4.11.0+) | 直接配置 LSP 插件 + Hooks | 内置"同一轮修复" | ⭐ 低(需写编译日志 Hook) |
| ZCode | ⚠️ 插件体系含 LSP(Beta) | 写 LSP 插件或等官方 | 需自定义 Subagent 循环 | ⭐⭐ 中 |
| AtomCode | ⚠️ 配置中有 LSP,默认关 | 启用 LSP + 自定义 Hook | 需手动配置循环 | ⭐⭐⭐ 中高 |
| KimiCode | ❌ 无 LSP | lsp-mcp-server 桥接 | 手动触发(无自动循环) | ⭐⭐⭐⭐ 高 |
| Qoder | ❌ 依赖外部 IDE | 外部 IDE + lsp-mcp-server | 依赖外部 IDE 的循环 | ⭐⭐⭐⭐ 高 |
推荐优先级
- CodeBuddy:最接近 OpenCode 体验,优先使用
- ZCode:如果版本 ≥ 0.16+ 且 LSP 插件可用,次优选择
- 通用桥接:KimiCode / Qoder / 旧版工具统一使用
lsp-mcp-server
七、关键代码:CANN 编译日志 → LSP 诊断转换器
# cann-log-parser.py — 将 CANN build.log 转换为 LSP 诊断格式
import re
import json
import sys
def parse_cann_log(log_path):
diagnostics = []
# CANN 错误码正则
error_pattern = re.compile(
r'(?P<file>[\w/]+\.(cpp|h|json)):(?P<line>\d+):(?P<col>\d+):\s*'
r'(?P<severity>error|warning|note):\s*(?P<message>.+)'
)
with open(log_path, 'r') as f:
for line in f:
match = error_pattern.search(line)
if match:
severity_map = {
'error': 1, # LSP Error
'warning': 2, # LSP Warning
'note': 3 # LSP Information
}
diagnostics.append({
'uri': f"file://{os.path.abspath(match.group('file'))}",
'range': {
'start': {'line': int(match.group('line'))-1, 'character': int(match.group('col'))-1},
'end': {'line': int(match.group('line'))-1, 'character': int(match.group('col'))}
},
'severity': severity_map.get(match.group('severity'), 1),
'message': match.group('message'),
'source': 'CANN'
})
return diagnostics
# MCP 模式:通过 stdio 接收请求,返回诊断
if __name__ == '__main__' and '--mcp-mode' in sys.argv:
while True:
line = sys.stdin.readline()
if not line:
break
req = json.loads(line)
if req.get('method') == 'get_diagnostics':
log_file = req['params'].get('log_file', 'build/build.log')
result = parse_cann_log(log_file)
print(json.dumps({'id': req['id'], 'result': result}))
sys.stdout.flush()
将此脚本作为 MCP 服务器注册到任意 AI 工具,即可实现 CANN 编译日志的 LSP 化诊断回灌。
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐


所有评论(0)