ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Slnmap:用Roslyn和MCP为AI构建.NET代码图谱

Slnmap:用Roslyn和MCP为AI构建.NET代码图谱 最近在试一个面向 .NET 代码库的 MCP 服务器项目叫 Slnmap。它底层用 Roslyn 解析解决方案和工程把 .NET 代码库变成结构化代码图谱再通过 MCP 协议暴露给 AI 助手调用。这类项目最值得看的不是又多了一个工具而是它解决了 AI 读取 .NET 项目时“看不懂结构、全靠猜”的老问题。如果你正在用 Claude Desktop、Continue、Cline 这类支持 MCP 的客户端写 C#或者想把 .NET 仓库接进 Agent 工作流这个项目值得花半小时跑一遍。下面我会按实际落地顺序拆先说它补了什么能力再说环境怎么准备、怎么接入、怎么验证最后给一批常见问题和排查链路。整个过程尽量让新手能复现也让有经验的读者能快速判断适不适合自己的仓库。1. 先搞明白Slnmap 到底给 AI 编程补了什么信息1.1 AI 看懂 .NET 代码的常见障碍普通代码问答工具理解一个 C# 项目时通常靠两种方式一种是直接把源码文本塞进上下文另一种是拿文件名、类名做字符串搜索。这两种方式在小型 Demo 里够用但一旦项目超过几十个文件模型很容易答错类所在的位置、漏掉接口实现关系或者把两个同名类型混淆。.NET 代码本身又有特殊性。一个解决方案里经常有多个 csproj彼此有 ProjectReference一个类可能实现了跨项目的接口一个方法可能被 JSON 序列化、反射、依赖注入间接引用。这些关系不是“搜索某个关键字”能看出来的必须靠编译器的语义分析才能拿到准确结果。Roslyn 恰好就是干这个的。所以在 AI 编程场景里真正缺的不是“能读文件”而是“能回答代码结构问题”这个接口有哪些实现类这个项目依赖了哪些项目某个符号定义在哪个文件哪一行。Slnmap 就是围绕这些需求设计的。1.2 Roslyn 解析和 MCP 协议组合的价值Slnmap 的思路可以拆成两层。第一层是代码图谱构建。它用 Roslyn 打开 .sln 或 .csproj加载语法树和语义模型然后提取出项目、文件、命名空间、类型、成员、引用关系等信息。这比正则匹配可靠因为 Roslyn 是在编译器层面解析代码。只要代码能通过编译语义分析符号之间的关系就是确定的。第二层是 MCP 服务化。MCP 的全称是 Model Context Protocol中文社区一般叫“模型上下文协议”。它定义了一种标准方式让 AI 客户端能调用外部工具、读取外部数据。Slnmap 把自己实现的代码查询能力注册成一个个 MCP 工具AI 需要时再调用而不是把所有代码都塞进上下文。这个组合的实际价值是模型不需要提前知道整个项目的全部细节它可以先问“这个仓库有哪些项目”再根据结果问“这个项目里有没有某个服务类”按需拉取。上下文占用小回答的依据也更准确。1.3 简单项目结构 vs 完整代码图要注意Slnmap 不是把整个仓库变成一张图片也不是生成一个给人类看的大型 SVG 图。它输出的应该是可供程序读取的结构化数据典型形式是 JSON内容大致包括解决方案下有哪些项目每个项目引用了哪些项目或 NuGet 包每个类型定义在哪个文件、属于哪个命名空间类、接口、枚举、方法、属性、字段之间的包含和引用关系接口的实现类、类型之间的继承关系、方法调用关系等。也就是说它更像“给 AI 提供代码库索引”而不是“画一张架构图给你看”。你拿到代码图谱后可以自己去生成可视化图表也可以直接让 AI 基于图谱回答问题。这里的判断标准是调用一个查询工具后返回结果里应该有明确的文件路径、符号全名、引用方向。如果返回结果只有文件名没有符号定位那只能算文本搜索不能算代码图谱。2. 能不能跑起来先看这几项环境条件2.1 运行环境SDK、MCP 主机和仓库路径想跑 Slnmap一般需要这几样东西。第一是 .NET SDK。因为 Slnmap 基于 Roslyn构建和运行都需要对应的 .NET 运行时和编译器接口。具体版本要以项目 README 为准。如果 README 里写了需要 .NET 8本机最好就用 .NET 8用更高版本通常兼容但遇到问题时会多一个变量。第二是一个支持 MCP 的客户端。常见选择有 Claude Desktop、Continue for VS Code、Cline 等。不同客户端注册 MCP server 的界面和配置文件不一样但核心都是告诉你“我要启动一个进程它的命令是什么参数是什么”。第三是目标代码仓库路径。Slnmap 通常处理本地文件系统。你要先 clone 或拉取一个 .NET 仓库到本地然后把绝对路径告诉它。它不会自己去远程 GitHub 拉代码MCP 服务器本身只是个本地进程。2.2 本地进程还是远程服务stdio 与 HTTP 差异MCP server 有两种常见连接方式stdio 和 SSE/HTTP。stdio 模式下客户端直接启动 Slnmap 可执行文件通过标准输入输出通信。这种方式配置最简单适合个人电脑上的 Claude Desktop。问题排查也比较直接你在终端手动跑一次就能看到启动日志和错误输出。SSE/HTTP 模式下Slnmap 作为一个本地或远程服务运行客户端通过 HTTP 接口访问。这种方式适合把代码图谱能力开放给多个客户端或远端 Agent但要处理端口、超时、鉴权、网络连通性。我一般建议第一次接入先用 stdio跑通后再考虑 HTTP。原因是 stdio 少一层网络问题出错时更好定位。如果配置后客户端提示连接失败、超时或连接被重置优先确认路径、权限和启动命令而不是先去改网络参数。2.3 先用一个小仓库确认基线这一步很容易被跳过但很值得做。不要一开始就把公司里那个几十个项目、几万文件的大型解决方案拿来测。第一次测试最好用一个单体小仓库比如一个 .NET 控制台项目、一个简单的 Web API 项目或者作者仓库里自带的示例测试项目。小仓库的好处是解析速度快输出结构简单结果容易对照源代码验证。如果小仓库都跑不通直接上大仓库只会得到一堆难排查的报错。我这个习惯是先把前面几步的环境信息记下来包括 SDK 版本、操作系统、仓库路径、MCP 客户端版本。一旦出现环境相关的问题这些信息能帮你快速判断是不是版本冲突。3. 从零接入安装、配置 MCP 主机与首次验证3.1 获取并构建 SlnmapSlnmap 是源码形式的开源项目所以你通常需要 clone 下来然后用 dotnet 命令构建。git clone https://github.com/your-username/Slnmap.git cd Slnmap dotnet restore dotnet build -c Release具体仓库地址和分支要以你看到的项目页面为准。构建成功后需要找到可执行文件的位置。如果项目发布成了 dotnet tool也可以直接安装dotnet tool install --global Slnmap如果项目提供了 npm 包分发那就会被拆成npx slnmap之类的方式。这里我不写死因为不同版本的发布方式差别很大。你只需要确认一件事你手上能不能生成一个可执行命令或可执行文件。这一步如果卡住后面的 MCP 配置无从谈起。构建时常见问题是 SDK 版本不匹配。报错一般会直接告诉你缺少哪个 TFM 或哪类 SDK。别急着改代码先看 README 推荐的版本。3.2 在 MCP 客户端里注册服务不同客户端的配置文件路径不同但结构比较接近。以 Claude Desktop 为例一般是修改claude_desktop_config.json在mcpServers节点下加一项。{ mcpServers: { slnmap: { command: /absolute/path/to/slnmap, args: [ --repo, /absolute/path/to/your-dotnet-repo ] } } }这里的command是你上一节构建出的可执行文件路径args是启动参数。不同版本的 Slnmap 可能用不同的参数名比如--solution、--path、--project需要看项目 README 的实际说明。续有经验后会有经验后会习惯把参数拆分得干净一点仓库路径单独传代码图缓存位置单独传日志级别单独传。这样出问题时不用猜参数。配置完成后需要重启 MCP 客户端让它重新加载配置。如果客户端有 MCP 服务管理面板也能在里面看到 Slnmap 是否注册成功。3.3 第一次请求应该问什么连接成功后先不要问复杂问题比如“帮我重构整个数据访问层”。第一次验证要问最简单、最结构化的问题。我建议先发一条类似这样的请求“请列出这个仓库里的解决方案、项目名称、每个项目的目标框架。”如果 Slnmap 正常工作AI 会调用对应的代码图谱工具然后返回一个项目清单。成功标准是项目名称对得上、目标框架字段存在、路径清晰。如果这条请求失败说明还没跑通不用继续测复杂能力。先记录报错信息再去排查。如果第一条成功再试第二条“找一下这个仓库里有哪些类实现了 IXxxService 接口分别定义在哪些文件。”这条能验证符号级查询能力。因为接口实现关系不是简单的字符串查找必须靠 Roslyn 语义模型。如果这一步结果准确说明 Slnmap 的代码图谱是有效的。4. 核心能力逐个拆项目结构、符号定位和依赖关系4.1 解决方案与项目结构查询Slnmap 最基础的能力是回答“代码库长什么样”。实际使用中这个查询是最常用的。拿到一个陌生仓库AI 需要先知道有哪些解决方案每个解决方案下有哪些项目项目是 Web 项目还是类库目标框架是 net8.0 还是 net48。这决定了后续很多判断。比如你让 AI 修改一个 API 接口它需要先知道接口定义在哪个项目依赖了哪个类库输出目录是不是同一个才能给出准确建议。如果模型连项目结构都不知道它就只能靠经验猜等于随机发挥。这类查询的返回一般会有层次关系解决方案 - 项目 - 项目文件路径 - 目标框架 - NuGet 引用列表。判断是否正确的标准是这些信息能否正确解释你仓库里的真实依赖。4.2 类型、成员与代码定位符号定位是代码图谱里最有实用价值的部分。普通文本搜索能找到“FileService”出现的位置但分不清哪一个是定义哪一个是引用哪一个只是注释里提到的单词。Roslyn 语义模型能区分这些所以 Slnmap 可以回答“FileService 类定义在哪个文件”“OrderService 有哪些公开方法”“CreateOrderAsync 方法的参数和返回值是什么”“IStockRepository 接口被哪些类实现”这些答案落到具体文件、具体行号或符号全名AI 拿到后才能继续深入阅读源码而不是在无关文件里打转。我实际测试时的体验是这类查询的准确性比大多数字符串搜索工具高很多因为它是“编译级”的。但要注意如果代码本身没有通过语义分析比如缺引用、缺 NuGet 包导致编译错误Roslyn 的语义模型可能只能拿回部分信息。所以别把“代码能解析”当成“代码一定能编译通过”来用。4.3 项目引用、程序集引用和调用关系.
返回列表