ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Spring Boot接入本地AI代码评审:OpenClaw+DeepSeek+Ollama实战

2026/10/8 14:41:50 拓冰建站 浏览量
Spring Boot接入本地AI代码评审:OpenClaw+DeepSeek+Ollama实战 1. 项目背景与整体思路1.1 为什么我想给 Spring Boot 项目配上 AI 代码评审我一直在维护几个 Spring Boot 的中小型项目代码量不算特别大但该有的模块一个不少——Controller、Service、Mapper 层层分包还有 MyBatis 的 XML、DTO/VO 转换、Redis 缓存、定时任务、消息队列这些都混在一起。平时忙起来根本没时间做严格的自查更别提交叉 review 了。看着代码一天天长胖坏味道越来越多我心里其实一直在琢磨能不能让本地跑一个 AI帮我把代码过一遍直到我把 OpenClaw DeepSeek Ollama 这套组合搭起来之后第一次真的跑完一次自动 review那种感觉挺微妙的——像多了一个不需要睡觉的同事提交代码之后它就认真地翻代码指出问题还在关键行写上“这个循环里频繁查库建议改为批量查询”。那一刻我就知道这东西值得认真写一篇实操记录。这篇文章会面向两类读者一类是想给 Spring Boot 项目配上本地 AI 代码审查的开发者另一类是想搞清楚 OpenClaw、DeepSeek、Ollama 三者之间到底是什么关系、怎么配合的人。我会把完整的架构思路、部署步骤、提示词设计、常见问题都写出来过程尽可能真实包括我踩过的坑。1.2 OpenClaw DeepSeek Ollama 这套架构到底在解决什么问题很多人第一次看到这三个名词凑在一起直觉反应是这仨是不是重复了OpenClaw 是个框Ollama 也跑模型DeepSeek 也是模型到底谁是谁我用一个很直白的类比解释一下。把整条链路想成一家餐厅DeepSeek 是做饭的大厨负责真正“看懂代码、给出评审意见”Ollama 是给大厨准备的本地厨房让大厨能在你自己的服务器上干活不需要把菜送到外面的中央厨房也就是云端 APIOpenClaw 则是餐厅经理负责接单、传菜、整理大厨输出的内容再按照你定的流程把结果送回后厨——也就是你的 Git 工作流。换句话说OpenClaw 负责任务编排和流程控制DeepSeek 负责智力输出Ollama 负责本地模型托管和推理加速。这三者各管一段合在一起就能实现你在本地改完代码提交到 Git 仓库触发一次自动检查OpenClaw 读取变更的文件列表把 diff 和上下文交给 Ollama 上运行的 DeepSeek 模型模型给出评审意见OpenClaw 再把意见汇总成一份报告甚至还可以用 Webhook 把结果推送到企微群或者飞书群里。我把这套流程跑了快两个月最大的感受是它不像那些在线 AI 代码工具那样“黑盒”而是每个环节都能自己控制。模型放本地代码不出内网成本也几乎只有电费。如果你跟我一样对代码审查有持续刚需但不希望把代码扔给第三方服务这套方案会非常对胃口。2. 三大组件的选型分析与核心原理解读2.1 OpenClaw 是什么为什么我在这个场景里选它OpenClaw 是一个可编程的 AI 智能体框架它的定位是“让 AI 能操作真实工具、执行真实任务”。你可以把它理解成一个自带工具库的任务执行器它支持调用外部命令、读写文件、访问 HTTP 接口、与模型服务通信并且提供了一套技能Skill机制让开发者把常用的操作封装成可复用的单元。以我这次做代码 review 为例OpenClaw 的技能封装方式大概是这样的一个git_diff技能负责取 Git 仓库的变更内容一个review_prompt技能负责把 Java 代码的 diff 信息拼装成结构化的提示词附带项目上下文和代码规范一个send_report技能负责把 DeepSeek 返回的评审结论整理成 Markdown 报告写回本地目录或推送到消息接口。OpenClaw 的优势在于它的调度机制足够轻又有清晰的技能边界。它不是那种“什么都做但什么都不深”的通用助手而是支持你自己定义流程的智能体运行时。在实际使用中我发现它的稳定性比我自己之前用 Python 脚本加模型 API 拼出来的那一套要强很多因为容错和重试逻辑都是内建的不需要自己处理。2.2 DeepSeek 代码评审能力为什么够用DeepSeek 在代码生成和代码理解上的表现我做过对比测试。就拿 Spring Boot 的常见问题来说事务注解失效的场景、MyBatis 批量插入性能、Controller 层参数校验缺失、循环依赖预警等它都能给出有实际意义的判断不是那种万金油式的回答。我最满意的是它对“劣质代码坏味道”的敏感度。比如下面这段是我故意写的一个反面案例public ListOrderVO getOrderList(String userId) { ListOrder orders orderMapper.selectByUserId(userId); ListOrderVO result new ArrayList(); for (Order order : orders) { OrderVO vo new OrderVO(); vo.setId(order.getId()); vo.setUserName(userMapper.selectById(order.getUserId()).getUserName()); result.add(vo); } return result; }DeepSeek 的评审意见非常直接就指出循环中多次调用 userMapper 查询用户名属于典型的 N1 问题建议先批量查询用户信息再组装返回。它还会顺带提醒如果这个接口被频繁调用大量短连接查询会拖垮数据库连接池。要把 DeepSeek 调到这个水平用对提示词格式非常关键。我在 review 场景里把提示词固定成“角色定义 审查重点 输出格式”三段式结构稳定性和评审质量都有明显提升。具体怎么设计我后面会专门写一节。2.3 Ollama 在链路里扮演的角色以及它和 DeepSeek 的协同方式Ollama 是业界非常流行的本地模型运行工具它把 llama.cpp 这类推理引擎封装成了简洁的命令行和 API 服务。你只需要一个命令就能把模型拉下来运行还支持 OpenAI 兼容的接口格式这对接 OpenClaw 非常方便。我在这套架构里选择 Ollama核心原因是它简单、稳定、可控。模型文件全部落在本地磁盘启动之后监听默认端口 11434OpenClaw 可以直接把 Ollama 当作一个 OpenAI 兼容的服务来调用。DeepSeek 模型在 Ollama 生态里主要以量化版本提供。以我使用的 deepseek-coder 或 qwen2.5-coder 系模型为例普通 16GB 内存、8GB 显存的机器就能流畅跑 7B 级别的量化模型如果你有 24GB 显存可以考虑 14B 甚至更大的参数版本评审的细致程度会再上一个台阶。模型示例量化精度显存要求评审能力感受deepseek-coder:6.7bQ4_K_M6GB 左右基础问题识别清晰适合日常 reviewdeepseek-coder:14bQ4_K_M10GB 左右语义理解更强建议使用qwen2.5-coder:14bQ4_K_M10GB 左右中文注释理解好工程感强Ollama 还提供了模型常驻内存的机制调完一次之后下一次推理速度会明显加快。这个特性对频繁迭代代码、反复触发 review 的场景非常有用。实际上在部署实践中因为服务器在国内、拉取模型镜像慢的问题很常见Ollama 在 2025 年版本后提供了更友好的离线安装与配置方式这部分我在部署章节里单独说明。至少我在本机部署时完全绕开了网络下载模型的痛苦用镜像文件导入就能搞定。3. 本地完整部署与配置实操3.1 环境准备系统要求与依赖清单先说结论我这套方案对硬件要求不算苛刻。我实际跑通的设备是一台 32GB 内存的 Linux 工作站配了一块 12GB 显存的旧显卡模型用的 7B 量化版。如果你没有独立显卡16GB 内存的机器跑 3B~7B 版本也能出效果只是速度会慢一些。准备清单大致如下操作系统Ubuntu 22.04 / 24.04Windows 11WSL2也可以但建议 Linux 优先内存至少 16GB32GB 更舒服存储模型文件和项目代码预留 30GB 空间如果是离线安装包方式存放还要多留 20GB 给镜像缓存工具链Git、Java 17、Maven、Node.js 18OpenClaw 依赖 Node 运行代码仓库需要一个真实的 Spring Boot 项目或者临时 clone 一个开源项目来测试。依赖安装部分我直接讲关键节点。先确认系统已经装了 Node.js 和 npm然后全局安装 OpenClawnpm install -g openclaw/cli装完后验证一下版本openclaw --version如果这一步正常输出版本号说明主体环境已经就绪。接下来要处理 Ollama它是整个推理服务的地基。3.2 Ollama 安装、离线模型导入与模型路径调整Ollama 的常规安装方式很简单一行命令搞定curl -fsSL https://ollama.com/install.sh | sh但实际部署中国内网络拉取模型往往非常慢这也是很多人在网上搜“ollama下载慢”“ollama离线安装包”的核心痛点。我的建议是记住两条路一条是官方源适合网络顺畅的情况另一条是离线包导入适合服务器在公网环境下受限的场景。先讲离线导入。你需要在一台能正常访问外网的机器上下载模型文件格式是 GGUF 或者 Ollama 官方打包好的模型镜像。Ollama 支持通过 Modelfile 方式导入ollama create deepseek-coder-local -f ./ModelfileModelfile 里面可以这样写FROM ./deepseek-coder-6.7b-instruct-q4_k_m.gguf这样就会把本地 GGUF 文件注册成名为deepseek-coder-local的模型。之后运行的时候ollama run deepseek-coder-local只要能正常进入对话界面说明模型导入成功。再讲模型存储路径调整。默认情况下模型文件会放在~/.ollama/models如果你的系统盘空间比较紧张建议把模型目录迁移到其他分区。方法很简单设置环境变量OLLAMA_MODELS或者在 systemd 服务配置里指定路径。我实际操作时是在/etc/systemd/system/ollama.service里加了这么一段[Service] EnvironmentOLLAMA_MODELS/data/ollama-models然后重启服务systemctl daemon-reload systemctl restart ollama这样模型就稳稳地落在数据盘上再也不用担心系统盘被撑爆了。这里我特别想强调一件事很多人拉模型失败或者下载中断原因往往不是网速而是磁盘空间不足。模型文件动辄 4~8GB拉取过程会先下载到临时目录再解压如果临时目录空间不够就会一直卡在 99%。建议第一次安装前先检查df -h把空间留足。3.3 OpenClaw 初始化与 DeepSeek 模型接入配置OpenClaw 装好之后第一步是初始化它的配置目录openclaw init初始化完成之后会在当前用户目录下生成.openclaw/配置文件。里面最重要的一个文件是config.yamlOpenClaw 通过它来识别模型服务的接入方式。我直接把配置写成了指向本地 Ollama 服务model: provider: ollama endpoint: http://127.0.0.1:11434 model_name: deepseek-coder-local temperature: 0.2 max_tokens: 4096注意几个关键点。temperature我建议设在 0.2 左右代码评审需要稳定输出温度太高会出现“过度脑补”的情况就是模型会挑一些不存在的毛病还给出一些不痛不痒的建议。max_tokens设得稍大一些因为评审意见经常包含多段分析太小会被截断。配置好之后验证联通性openclaw test正常情况下OpenClaw 会向 Ollama 发送一个测试请求返回模型名称和响应时间。如果你的环境里 Ollama 和 DeepSeek 模型都在运行这个测试结果会非常直观。我最初忽略了这个测试步骤直接启动任务结果遇到接口路径不对的问题排查了很久才意识到是 endpoint 少了一个端口段。先测试联通可以省掉后面一大半麻烦。如果你想直接调用 DeepSeek 的在线 API 而不是本地模型配置方式是类似的model: provider: deepseek api_key: sk-xxxx model_name: deepseek-chat endpoint: https://api.deepseek.com不过在代码不落地的内网环境里本地 Ollama 始终是更安全的选择。两者切换也很方便改一下配置重启服务就行。3.4 给 Spring Boot 项目配置 Git 钩子与自动化触发模型和框架都就位之后下一步是把它挂到真实的开发流程里。最自然的做法是利用 Git 的 pre-commit 钩子每次提交代码前自动触发一次增量 review。在项目根目录下创建.git/hooks/pre-commit#!/bin/bash echo Running AI code review... openclaw run review --diff-only加了可执行权限chmod x .git/hooks/pre-commit--diff-only的含义是只审查本次提交涉及的变更文件而不是整个仓库这样可以明显缩短评审耗时也让评审意见更贴合本次改动。如果想做全量代码的健康检查可以用--full-scan参数跑一次完整分析适合定期做代码体检。另外一个常用的触发方式是接入 CI/CD 流水线。比如在 GitLab CI 里加一个 jobcode-review: stage: test script: - openclaw run review --diff-only only: - merge_requests这样每次发起合并请求时流水线会自动执行 AI 评审并把结果作为 pipeline 的一个环节展示出来。相比本地钩子这种方式更不依赖开发者的个人环境结果也更容易共享给团队。我的建议是本地钩子和 CI 两个都用本地钩子拿来做即时反馈CI 拿来做门禁和归档。前者让开发者提交前就能心里有数后者让团队有一个统一的评审记录沉淀。4. 核心环节实现提示词设计、技能封装与上下文管理4.1 代码评审提示词的固定结构我如何设计三层模板代码评审质量的高低百分之六十取决于提示词设计这句话一点都不夸张。同样的模型你用“帮我看看这段代码有问题吗”和用结构化的 prompt效果完全是两个量级。我最后固定下来的提示词模板分三层第一层是角色与目标定义。让模型明确它扮演的是“具备 10 年经验的 Java 架构师专注于 Spring Boot 工程质量”审查目标不是教学而是发现真实缺陷、给出修改建议。第二层是审查重点列表。我会明确告诉模型关注哪些方面这一层是提示词的核心因为它决定了模型的注意力分布。我实际使用的重点包括事务边界是否正确、是否存在 N1 查询、DTO/VO 使用是否清晰、异步线程安全性、异常处理是否合理、是否硬编码配置项、MyBatis 动态 SQL 是否有 SQL 注入风险等。第三层是输出格式约束。我要求模型的评审结果必须结构化为固定格式问题等级P0/P1/P2、问题位置文件名行号、问题描述、修改建议、修改示例代码。固定格式非常重要因为它决定了 OpenClaw 能否把结果自动化处理成报告。以下是简化版提示词我在 OpenClaw 技能里用的完整版本在此基础上增加了项目上下文你是一个资深 Java 技术专家擅长 Spring Boot 架构评审。 请基于以下代码变更内容进行代码审查。 审查重点 1. 事务注解使用是否合理事务边界是否正确 2. SQL 查询是否存在 N1 问题 3. 异常处理是否规范是否吞异常 4. 是否有明显的并发安全隐患 5. 是否存在配置硬编码 6. 接口参数校验是否完整 输出要求 - 必须按照“问题等级位置描述建议示例代码”的格式输出 - 等级分 P0必须修复、P1建议修复、P2优化建议 - 如果代码没有问题输出“本次变更未发现明显问题” 以下是变更内容 {diff_content}4.2 在 OpenClaw 里封装一个可复用的 review 技能OpenClaw 的技能机制简单说就是一个带参数入口的脚本。我创建了一个名为code-review-skill的技能目录里面包含三个关键文件skill.yaml技能元信息包括技能名、参数定义、模型配置run.sh执行入口负责调用 git、OpenClaw CLI、模型服务templates/review-prompt.md提示词模板与上一节的三层结构对应。run.sh的逻辑不需要很复杂核心就几步#!/bin/bash STAGED_DIFF$(git diff --cached) echo $STAGED_DIFF /tmp/review_diff.txt openclaw skill run code-review-skill \ --input /tmp/review_diff.txt \ --output review_result.md如果你对命令行比较熟也可以直接用 OpenClaw 内置的对话接口传参把 diff 拼进消息里发送openclaw run review 请审查以下变更$(cat /tmp/review_diff.txt)我个人偏好先把 diff 写文件再让技能读取因为 diff 内容可能很长命令行直接传参容易碰到长度限制或者转义问题。4.3 上下文越界问题如何让模型理解 Spring Boot 项目结构直接把 diff 丢给模型评审效果通常会打折扣。原因在于很多问题需要结合项目上下文才能判断。比如一个 Service 方法里直接调了另一个 Service 的方法如果 diff 里看不到被调用方的定义模型可能判断不出这是不是循环依赖。所以我在 OpenClaw 技能里加了一个可选参数--context它支持传入项目目录的 tree 结构以及几个关键配置文件的内容openclaw run review \ --diff mirror_diff.txt \ --context project_tree.txt \ --context pom.xml \ --context application.ymlOpenClaw 会把多个 context 文件按顺序拼接进提示词作为一个独立的上下文区段。这样模型在处理 diff 时能随时参考项目整体结构判断准确性会好很多。我在实践中的一个体会是上下文不是越多越好。之前我贪心地把整个核心模块的 Java 文件都塞进去结果模型反而被大量无关代码干扰输出质量明显下降。后来我把上下文限制在“项目树 核心配置 涉及变更文件的关联类列表”效果最好。这是一个需要反复调试的平衡点你可以在自己项目里试几轮找到最合适的范围。4.4 借助 FastAPI Ollama 补充自定义审查接口如果你不想每次都在命令行里操作也可以给这套系统包一层 HTTP 接口方便集成到你的内部工具平台或者 IDE 插件里。FastAPI 本身非常轻配合 Ollama 的 OpenAI 兼容接口实现一个审查 API 只需几十行代码。我写的简易接口大概长这样from fastapi import FastAPI, Request import requests import json app FastAPI() OLLAMA_URL http://127.0.0.1:11434/api/chat app.post(/review) async def review_code(request: Request): body await request.json() diff_content body.get(diff, ) messages [ {role: system, content: 你是资深 Java 架构师专注于 Spring Boot 代码审查。}, {role: user, content: f请审查以下代码变更\n{diff_content}} ] payload { model: deepseek-coder-local, messages: messages, stream: False } resp requests.post(OLLAMA_URL, jsonpayload) data resp.json() return {review: data[message][content]}然后启动服务uvicorn review_api:app --host 0.0.0.0 --port 8899这样做的好处是以后不管什么工具需要调用 AI 代码审查都只需要往/review发一个 POST 请求即可。比如可以接入 IDEA HTTP Client、Postman、内部管理系统甚至微信机器人。不过要注意如果这个服务暴露在公网一定要加鉴权至少加一个简单的 token 头否则别人可以白嫖你的算力。5. 真实评审效果与常见问题排查实录5.1 我用一个真实的 Spring Boot MyBatis 项目做了三轮测试为了验证整套系统的评审能力我从公司旧项目里抽了一个典型的订单模块包含 Controller、Service、Mapper 三层涉及 18 个 Java 文件。然后故意在代码里埋了几个常见的坑第一处是事务失效问题在同一个类中通过this.xxx()调用另一个带有Transactional的方法。第二处是 N1 查询在循环里逐条查用户表。第三处是参数校验缺失接收前端参数直接入库。第四处是硬编码状态码Magic Number 散落在代码里。三轮测试结果如下第一轮是纯 diff 输入不附带上下文。模型能发现 N1 和硬编码问题但事务失效问题没有识别出来因为它只看到了局部代码不知道调用关系的完整链路。第二轮加上项目结构和配置上下文后事务失效问题被准确识别了模型甚至点出了 Spring AOP 代理机制自调用会被 this 指向目标对象本身而不是代理对象所以事务注解不会生效。这个判断相当专业让我有点意外。第三轮我调整了提示词中的审查重点顺序把“事务边界”提到第一位结果模型不仅识别了原有问题还额外发现了一个线程安全问题某个 Service 里用了 SimpleDateFormat 作为成员变量在多线程环境下存在日期解析并发隐患。这一点是我自己都没注意到的。这轮测试之后我的结论是这套系统在“识别常见代码坏味道和常规缺陷”这个层面已经达到甚至超过普通中级开发者的评审水平但对项目业务逻辑的深层理解仍然有限比如业务规则矛盾、状态机迁移不合逻辑这类问题它很难发现。所以它适合当一道自动化防线不完全替代人工评审。5.2 常见问题速查表与排查技巧我在实际部署和日常使用过程中遇到过不少问题下面整理成一张速查表也是我在几次测试运维中最常被问到的问题。问题现象可能原因解决方案openclaw test 报连接失败Ollama 服务未启动或地址配置错误检查curl http://127.0.0.1:11434能否返回确认 config.yaml 的 endpoint评审速度很慢输出不完整模型较大机器显存不足换小尺寸量化模型或增大max_tokens关闭其他占用显存的应用模型回答与代码无关偏题提示词缺少角色约束和审查重点严格使用固定模板审查重点前置放在输出要求之前Git 钩子不生效钩子文件没有执行权限执行chmod x .git/hooks/pre-commit模型返回内容重复或死循环temperature 过高或上下文过长温度降到 0.2 以下精简 context 内容Ollama 模型加载慢磁盘 IO 瓶颈或模型未常驻设为 keep_alive 常驻优先把模型放到 SSD 分区离线模型导入失败Modelfile 路径写错或 GGUF 文件损坏检查路径绝对/相对路径重新下载校验 sha256还有一个非常实用的排查技巧如果你怀疑是模型输出质量的问题而不是链路配置的问题可以直接用 Ollama 的原生命令单独跑一次ollama run deepseek-coder-local 请审查以下代码...如果原生命令的回复质量正常说明问题出在 OpenClaw 的提示词封装或上下文处理上如果原生命令回复也差那就是模型版本或者量化精度的问题。这个二分排查法帮我省了很多时间。5.3 关于模型微调与提示词调优的进阶建议如果有服务化需求比如要把整条链路部署成对团队开放的代码评审平台光靠 OpenClaw 默认配置可能不太够。你需要考虑加一层前置代码分析工具比如用 JavaParser 或者 PMD 先做一轮静态规则检查把规则检测结果也喂给模型让模型结合规则命中行做深入分析。这样能大幅提升评审的覆盖面和准确性因为静态规则擅长模式匹配而 DeepSeek 擅长语义理解两者互补。模型微调这块我也简单说一句我不建议普通团队自己微调 DeepSeek成本高而且收益不稳定。与其花时间微调不如把提示词和上下文管理做到极致。我实测下来配合动态获取变更文件对应的 Service 层方法定义后评审准确率至少提升了三成。如果你手里的 Spring Boot 项目有统一的代码规范文档也可以把它作为上下文片段加入提示词模型会严格贴着你的规范来给建议。另外提醒一下如果你用 IDEA 社区版它是支持 Git 钩子的OpenClaw 的--diff-only模式可以直接在提交时触发不需要依赖付费插件。我就是在 IDEA 社区版里体验整个流程的没花一分钱工具钱。6. 一些心得与扩展方向这套方案跑通之后我现在每天提交代码前都会习惯性地跑一次 AI 评审每次大概 30 秒到 2 分钟不等取决于改动量。绝大多数时候它能发现一两个我忽略的小问题偶尔还能给出让我“拍大腿”的好建议。我把这些建议同步到团队的评审流里同事们一开始觉得新鲜后来也开始在本地试这套组合。最值得说的一个收获是有了自动评审之后我自己写代码的心态发生了微妙的变化。以前赶功能的时候总想着“先跑通再说”现在想到代码提交后会被 AI 翻一遍下意识会多检查一遍事务、异常和边界条件。这种正向反馈是工具本身的额外价值。如果你也想在手机或者其他轻量设备上尝试这套流程其实 OpenClaw 在 Android 上也有部署可能用 Termux 就能跑起来DeepSeek 走在线 API 的话手机也没压力。不过说实话手机端体验更多是尝鲜真的做工程代码评审还是建议用桌面环境。最后分享一个小技巧在 OpenClaw 的技能里可以把提示词里的审查重点做成外部配置文件这样不同项目可以挂不同规范。比如电商项目挂订单事务和库存一致性审查规则内部管理系统挂权限校验和日志审计审查规则。这样复用性会强很多团队协作时也更加省心。我在实际操作中就是这么做的效果很好这套思路你也可以直接拿去用。