RuoYi AI 环境搭建,这个标题我盯着琢磨了挺久。说白了,就是两件事凑到一块:RuoYi(若依)这套在 Java 圈子里用得极广的后台管理框架,和当下到处都在喊的 AI 能力。我最近正好把一个若依项目做了智能化改造,从 JDK、Maven、MySQL、Redis 这些若依的老搭档,到 Python、PyTorch、FastAPI 这一套 AI 服务栈,再到两边怎么对接、怎么鉴权、怎么处理超时和乱码,整个链路走了一遍,踩了不少坑,也沉淀了一套比较稳定的打法。这篇东西就是把这些实操整理出来,给两类人看:一类是想在若依项目里加 AI 功能的后端开发,另一类是准备把大模型接入传统 Java 项目、还没理清环境的同学。我尽量把每一步背后的“为什么”也讲透,而不是只扔给你一堆照敲即可的命令。
1. 总体思路:为什么若依和 AI 要分两个环境
1.1 若依是什么,它能解决什么问题
若依是一个基于 Spring Boot + Spring Security + MyBatis 的前后端分离管理后台脚手架,前端有 Vue2/Vue3 两个大版本,后端代码结构高度统一。它自带用户管理、角色管理、菜单管理、部门管理、字典管理、定时任务、操作日志、代码生成这些绝大部分后台系统都要重复造轮子的模块。你拿到手,改改配置,导入 SQL,基本就有一个能登录、能分配权限、能管理用户的后台主干,然后只需要往里面填自己的业务模块。
打个比方:若依就像是一个已经帮你把行政、人事、财务这些后台支持部门都建好的公司,你要做的只是招几个业务骨干去干正事。很多中小团队做管理平台,与其从零写权限和安全框架,不如直接用若依做底座,这也是它火了很多年的原因。
1.2 AI 能力为什么不能直接塞进 Java 项目
一开始我也有过偷懒的想法:既然若依是 Java 项目,能不能直接在 Java 里加载模型做推理?试了之后发现,这条路的性价比非常低。PyTorch 这类深度学习框架的生态主要在 Python 侧,模型加载、分词、推理逻辑、微调工具链全在 Python 环境里。Java 虽然也有一堆深度学习库,但模型格式的兼容、预训练模型的支持、社区文档的丰富度都差一大截。真要是把一个大模型塞进 Java 进程,光是处理分词器版本和模型权重格式就能折腾掉你一个周末。
所以我最终采用了“Java 管业务、Python 管智能”的分层思路:后端若依负责登录、鉴权、流程编排、数据存储这些确定性业务;Python 独立起一个 AI 推理服务,专门负责模型加载和推理;两个服务之间通过 HTTP 接口通信。这样做的核心好处有三个:第一,Java 侧不引入重型 AI 依赖,项目构建体积和复杂度都可控;第二,Python 侧可以独立升级模型、换模型,不影响若依的稳定运行;第三,故障隔离,模型服务挂了不会把整个业务系统拖垮。打个比方,Java 是前台的业务经理,Python 是坐在后台的专家顾问,业务经理有问题就写个单子给专家,专家干完活把结果递回来,二者各自保持边界,效率反而最高。
1.3 目录规划与版本选型总览
正式动手前,先把目录和版本定下来,避免后面东一榔头西一棒子。我的项目结构很简单:
my-project/ruoyi:若依前后端分离工程,后端 Java,前端 Vue。my-project/ai-service:Python 独立 AI 服务,用 FastAPI 框架。
版本选型方面,我整理了一张表格,基本照着这个组合可以少踩很多坑:
| 组件 | 版本 | 说明 |
|---|---|---|
| JDK | 8 或 17 | 若依新版已兼容 17,旧工程用 8 最稳 |
| Maven | 3.8+ | 配置国内镜像,否则依赖下载能等到你怀疑人生 |
| MySQL | 8.0 | 字符集务必 utf8mb4 |
| Redis | 6.x | 若依的验证码、会话缓存依赖它 |
| Node.js | 16/18 | Vue3 前端工程必需,推荐 18 |
| Python | 3.10 | PyTorch 对 3.10 的支持最均衡 |
| PyTorch | 2.1+ | 根据显卡 CUDA 版本选对应安装包 |
这个清单看着简单,但版本之间稍有错配就会引发连锁问题。比如 JDK 版本和 Lombok 版本不匹配,编译直接报错;Node 版本太老,Vue3 工程跑不起来。提前定版本,其实是在提前买保险。
2. 先把若依跑起来:基础环境的搭建细节
2.1 中间件与工具链的准备
若依跑起来需要 MySQL、Redis、JDK、Maven、Node 这几样东西。MySQL 安装时最容易被忽略的是字符集,建议建库时直接指定 utf8mb4:
CREATE DATABASE ruoyi_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;为什么不建议用默认字符集?因为如果表里要存 AI 对话内容、用户输入的特殊符号(比如 emoji),latin1 或者 utf8mb3 要么存不进去,要么取出来乱码。AI 场景下输入输出文本非常多样,这一步千万别省。Redis 默认端口 6379,安装完直接启动即可,若依默认配置是无密码连接,本地开发完全够用。
JDK 和环境变量这步,我建议直接装 JDK 8 或 17,然后配好JAVA_HOME。Maven 的核心难点不是安装,而是仓库下载慢,在settings.xml里加阿里云镜像基本是必做操作:
<mirror> <id>aliyunmaven</id> <mirrorOf>central</mirrorOf> <url>https://maven.aliyun.com/repository/public</url> </mirror>Node 端我强烈建议用 nvm 管理多版本,因为若依的 Vue3 工程和可能存在的其他前端项目,对 Node 版本要求并不完全一致。用 nvm 装 Node 18,再配 npm 的国内镜像,前端依赖安装就能快非常多。
2.2 导入数据库与修改配置的实操要点
从官方仓库拉最新的 RuoYi-Vue3 源码后,在sql目录下通常会有两个文件:一个是主库脚本(类似ry_2024xxxx.sql),另一个是quartz.sql(若依集成 Quartz 定时任务的表结构)。两个都要导入,顺序无所谓,但导入前确认数据库字符集是 utf8mb4。
然后改后端配置,关键文件是application-druid.yml,数据库连接串一定要注意这几项参数:
url: jdbc:mysql://localhost:3306/ruoyi_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: your_passwordserverTimezone是必填项,不填的话高版本 MySQL 驱动会直接报时区错误,中文环境下报错信息甚至可能是乱码,很容易让人摸不着头脑。useSSL=false在本地开发也必须加,MySQL 8 默认 SSL 设置和本地调试容易冲突。
改完配置后,启动顺序有讲究:先启动 Redis,再启动后端。后端启动入口是RuoYiApplication.java,启动成功后访问http://localhost:8080,用默认账号admin/admin123登录。如果你发现后端启动后短暂正常、然后报 Redis 连接异常,多半就是 Redis 没启动或者密码配置和实际不一致。
2.3 前端启动与打包发布的常见处理
前端工程在ruoyi-ui目录下,启动命令很常规:
npm install --registry=https://registry.npmmirror.com npm run dev开发模式下,前端默认端口是 80 或者 8081,Vue CLI 的代理配置在vue.config.js里,开发服务器会把/dev-api开头的请求代理到后端的http://localhost:8080。这一步不需要前端同学操心太多,但如果登录时出现验证码加载失败、接口 404,第一条排查思路就是看代理配置里的 target 是否正确指到了后端端口。
打包发布时,执行npm run build,产物在dist目录,丢到 Nginx 或者任意静态资源服务器即可。要注意后端的接口路径和前端请求路径必须保持一致,若依后端默认接口前缀是/dev-api,如果部署到测试环境,需要在 Nginx 里把/dev-api反向代理到后端服务:
location /dev-api/ { proxy_pass http://127.0.0.1:8080/; }这一节的感受是:若依本身的启动流程已经非常成熟,真正费时间的不是若依,而是环境之间的版本匹配。先把这套基础环境跑通,后面接 AI 服务才有稳定的落脚点。
3. AI 运行环境:PyTorch 这一侧的准备工作
3.1 显卡环境与 CUDA/PyTorch 版本匹配
AI 服务这边,第一个大坑就是 PyTorch 和 CUDA 的版本匹配。我先说结论:不要凭感觉装 GPU 版 PyTorch,先看显卡驱动支持到什么 CUDA 版本。在命令行执行:
nvidia-smi右上角有一个CUDA Version,比如12.0。这是驱动支持的 CUDA 最高版本,不代表你机器上装了 CUDA 工具包,但 PyTorch 安装时主要看这个。比如驱动支持 CUDA 12.0,你就可以装对应 cu118 或 cu121 的 PyTorch,命令类似:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118如果你机器上根本没有 NVIDIA 显卡,或者用的是笔记本核显,千万别装 CUDA 版 PyTorch,否则 import 阶段大概率报错或者 torch.cuda.is_available() 永远是 False。老老实实装 CPU 版:
pip install torch torchvision torchaudio装完先验证环境:
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"输出True说明 GPU 可用,输出False就是你装成了 CPU 版或者驱动不匹配。这一步验证看起来简单,却能帮你省下后面排查模型推理慢的实际问题的时间。
3.2 没有独立显卡怎么办:CPU 推理与云 GPU
AI 环境搭建最大的现实障碍,就是很多开发机没有高性能显卡。我有一次想在一台普通办公机器上跑一个 7B 参数模型,结果模型加载占掉了 16G 内存,推理一个短句都要几十秒,根本没法用。后来我总结了几条路:
第一,CPU 模式跑小模型。比如 Qwen 系列的小尺寸模型、ChatGLM 的 6B 量化版,在 CPU 上能跑,但速度只适合验证逻辑,不适合实际业务。第二,租云 GPU 实例,按小时付费,把模型服务部署在云上,本地 Java 服务通过内网或公网调用。第三,也是我现在最推荐的,直接用国产大模型 API,比如阿里百炼、百度千帆、智谱 AI 开放平台,省去显卡、模型部署、运维这一整套麻烦,按调用量付费,业务验证阶段成本极低。
很多人一提到 AI 就习惯性想本地部署,但我的观点是:环境搭建阶段没必要一步到位。先用 API 把若依和 AI 服务之间的接口链路打通,验证业务逻辑没问题,再根据需求决定要不要切换到本地大模型。这就像先坐公共汽车通勤,确认路线没问题后再决定要不要买车自己开。
3.3 模型服务框架与选型建议
本地部署模型时,除了 PyTorch,还需要一个对外提供 HTTP 接口的服务框架。FastAPI 是目前 Python 生态里最适合做这个的,性能好,写起来简洁,自动生成接口文档,对 JSON 的支持天然适合前后端对接。
如果业务场景涉及知识库问答、Agent 多轮工具调用,会用到 LangChain 或 Dify 这类编排框架。再往前一步,要做知识库检索,就需要一个向量数据库,小规模用 Chroma,规模大了用 Milvus 或者 Elasticsearch。我的建议是环境搭建初期不要把这些全铺开,先把最小链路跑通:FastAPI + 一个模型(或 API),能返回对话结果就算成功,向量库这类组件等具体需求出现时再引入。
选型上有个重要的取舍,我整理成表格:
| 对比项 | 本地模型部署 | 云端大模型 API |
|---|---|---|
| 硬件成本 | 高,需要显卡/大内存 | 低,按量付费 |
| 数据安全 | 数据不出内网 | 数据要传到服务商 |
| 响应速度 | 受硬件限制,可能慢 | 通常更快,且有流式接口 |
| 运维成本 | 模型更新、GPU 宕机都要管 | 服务商维护 |
| 定制能力 | 可微调、可换模型 | 基本取决于服务商能力 |
我的实践经验是:初期一律走 API,只有数据安全要求高或者需要模型深度定制时才考虑本地部署。这样能让你的精力集中在若依和 AI 的集成逻辑上,而不是被显卡驱动困住。
4. 若依与 AI 服务对接的三种方案
4.1 方案一:HTTP 调用独立 AI 服务(推荐)
这是我最推荐、也是最后稳定使用的方案。整体链路是:若依前端发起请求,若依后端接收请求后调用 Python AI 服务的接口,AI 服务返回结果,若依后端加工后返回给前端。
FastAPI 侧定义一个简单的对话接口:
from fastapi import FastAPI, Header, HTTPException from pydantic import BaseModel app = FastAPI() API_KEY = "sk-xxxxxxxx" class ChatRequest(BaseModel): message: str history: list = [] @app.post("/chat") def chat(req: ChatRequest, x_api_key: str = Header(default="")): if x_api_key != API_KEY: raise HTTPException(status_code=401, detail="invalid api key") # 这里调用模型或第三方 API reply = "这是 AI 服务返回的回复" return {"reply": reply}若依后端这边,用若依自带的 Hutool 工具类发 HTTP 请求非常方便:
String url = "http://127.0.0.1:8000/chat"; JSONObject body = new JSONObject(); body.put("message", message); body.put("history", history); JSONObject result = JSONUtil.parseObj( HttpRequest.post(url) .header("X-API-Key", "sk-xxxxxxxx") .body(body.toString()) .timeout(20000) .execute() .body() ); String reply = result.getStr("reply");这里有几个细节值得注意。第一,超时时间我设置了 20 秒,因为大模型接口就算再快,也要几秒到十几秒,用默认的超时配置很容易在并发时被断开。第二,API Key 放在后端,前端永远接触不到密钥。第三,AI 服务跟若依之间是纯 HTTP 协议,换模型、调整 prompt 都不需要改动若依代码。
4.2 方案二:Java 直连大模型 SDK
如果不想维护一个 Python 服务,也可以让若依后端直接调用大模型服务商提供的 Java SDK 或者 HTTP 接口。这个方案适合“只做业务验证”的场景。
思路很简单:在 pom.xml 里引入服务商 SDK,或者直接用 Hutool 的 HTTP 工具发请求。比如调用一个 OpenAI 兼容接口:
String url = "https://api.example.com/v1/chat/completions"; JSONObject body = new JSONObject(); body.put("model", "qwen-plus"); body.put("messages", JSONUtil.parseArray("[{\"role\":\"user\",\"content\":\"" + prompt + "\"}]")); JSONObject result = JSONUtil.parseObj( HttpRequest.post(url) .header("Authorization", "Bearer " + apiKey) .body(body.toString()) .timeout(30000) .execute() .body() );这个方案的优点是架构极简,不引入 Python 环境,缺点是后续一旦要换本地模型、要做私有化部署、要接入 LangChain 工具调用,Java 侧写起来非常痛苦。我只把它定位成临时的、快速验证的方案,线上环境我仍然会切回独立的 AI 服务。
4.3 方案三:MQ 异步任务解耦
第三个方案适合 AI 任务耗时特别长的场景,比如批量内容审核、自动生成周报、异步分析日志。如果直接用 HTTP 同步调用,用户会一直盯着页面转圈,体验很差。这种情况下可以用消息队列做异步解耦。
大致流程是:若依后端把任务参数发到 RabbitMQ/RocketMQ 的某个队列,Python AI 服务监听队列,处理完成后再把结果写回数据库,或者通过回调接口通知若依。用户不感知具体耗时,前端在任务完成后展示结果。这个方案的好处是削峰填谷,高并发时任务排队,AI 服务不会被打爆。
但我不建议刚开始接触若依 + AI 就去上 MQ。原因很简单:它会引入一套额外的中间件运维成本,RabbitMQ 本身又要安装、配置、启停,问题是环境复杂度越高,排查链路越长。先同步接口跑通业务,等确实有异步需求再切入 MQ,这个节奏比较合理。
4.4 接口鉴权与安全设计
两个服务之间通信,最容易被忽略的是安全。很多人搭建环境时觉得“反正本地调用,无所谓”,但如果这个系统要部署到测试环境甚至生产环境,AI 服务端口直接裸奔,风险会非常大。
我的做法是三层防护:第一层,AI 服务通过请求头校验 API Key,没有正确密钥的直接 401;第二层,若依后端的 AI 相关接口加上 Spring Security 权限注解,比如@PreAuthorize("@ss.hasPermi('system:ai:chat')"),这样只有分配了权限的用户才能调用;第三层,AI 接口做限流,若依自带接口限流注解@RateLimiter,可以直接加在 Controller 方法上,防止某个用户频繁刷请求把模型资源耗尽。
另外要注意提示词安全。用户输入的内容会原样拼进 prompt,如果用户输入“忽略以上所有规则”这类文本,有可能绕开系统设定。我的处理是:在后端拼 prompt 时把用户输入作为一个普通文本字段传入,而不是直接拼进系统指令,同时在 AI 服务里对输入长度做限制,比如超过 2000 字符直接拒绝。
5. 实际操作:一个 AI 助手功能从 0 到 1
5.1 搭建 FastAPI 推理服务
以一个最典型的“AI 对话助手”为例,我完整走一遍流程。先在ai-service目录下创建虚拟环境:
python -m venv venv source venv/bin/activate # Windows 下是 venv\Scripts\activate pip install fastapi uvicorn requests然后写main.py:
from fastapi import FastAPI, Header, HTTPException from pydantic import BaseModel import requests app = FastAPI() API_KEY = "sk-ai-service-key" class ChatRequest(BaseModel): message: str history: list = [] class ChatResponse(BaseModel): reply: str @app.get("/health") def health(): return {"status": "ok"} @app.post("/chat", response_model=ChatResponse) def chat(req: ChatRequest, x_api_key: str = Header(default="")): if x_api_key != API_KEY: raise HTTPException(status_code=401, detail="invalid api key") # 这里可以是调用本地模型,也可以是调用云端 API # 示例:调用第三方 API resp = requests.post( "https://api.example.com/v1/chat/completions", headers={"Authorization": "Bearer sk-xxxx"}, json={ "model": "qwen-plus", "messages": [{"role": "user", "content": req.message}] }, timeout=30 ) reply = resp.json()["choices"][0]["message"]["content"] return ChatResponse(reply=reply)启动服务:
uvicorn main:app --host 0.0.0.0 --port 8000访问http://127.0.0.1:8000/docs,能看到 FastAPI 自动生成的接口文档,直接在线测试/chat接口。到这里 AI 服务的最小链路已经通了。
5.2 若依后端封装 AI 接口
接下来在若依工程里新建一个AIController,路径为com.ruoyi.web.controller.system:
@RestController @RequestMapping("/system/ai") public class AIController { private static final String AI_SERVICE_URL = "http://127.0.0.1:8000/chat"; private static final String API_KEY = "sk-ai-service-key"; @PostMapping("/chat") @PreAuthorize("@ss.hasPermi('system:ai:chat')") public AjaxResult chat(@RequestBody JSONObject params) { String message = params.getStr("message"); if (StringUtils.isEmpty(message)) { return AjaxResult.error("消息不能为空"); } try { JSONObject body = new JSONObject(); body.put("message", message); body.put("history", params.getJSONArray("history")); String result = HttpRequest.post(AI_SERVICE_URL) .header("X-API-Key", API_KEY) .body(body.toString()) .timeout(30000) .execute() .body(); JSONObject resultObj = JSONUtil.parseObj(result); return AjaxResult.success("success", resultObj.getStr("reply")); } catch (Exception e) { return AjaxResult.error("AI 服务调用失败:" + e.getMessage()); } } }这段代码的关键点在于:把 AI 服务地址和 API Key 集中在常量里,方便后续统一配置到 Nacos 或配置中心;超时时间给足 30 秒;异常统一转成若依的AjaxResult结构,前端拿到错误提示不会乱。登录用户访问这个接口时,若依的 Token 校验会先拦截一层,服务器端的权限注解再拦一层,双保险。
5.3 新增 AI 助手菜单与对话页面
若依的管理后台加一个新功能页面很简单。登录 admin 账号,在菜单管理中新增一个菜单,菜单类型选“C 菜单”,路由地址填ai/chat,组件路径填system/ai/chat/index,然后分配权限标识system:ai:chat给对应角色。
前端页面我用 Vue3 写一个极简聊天框,核心逻辑只有三块:消息列表、输入框、调用接口。核心请求部分直接复用若依封装的request工具:
import request from '@/utils/request' export function sendChatMessage(message, history) { return request({ url: '/system/ai/chat', method: 'post', data: { message: message, history: history } }) }页面里维护一个messages数组,用户发送消息时先 push 一条用户消息到列表,再调接口把 AI 回复 push 进去。这个阶段先不做流式输出,等后端稳定后再考虑 SSE。界面上不需要花哨,能直观看到对话往返,这个功能就算立住了。
5.4 连接定时任务:让 AI 自动产出日报
若依自带 Quartz,把 AI 能力和定时任务结合起来,能做出很多实用功能。我这边做的是“每日 AI 工作日报生成”:每天凌晨定时调用 AI 服务,把当天系统里的操作日志、任务完成情况汇总发给模型,让模型生成一段总结文本,再存到业务表里。
在若依的定时任务管理页面新建一个任务,调用目标填一个后端方法,比如aiReportTask.run()。后端方法里写逻辑:
public void run() { // 1. 查询当天日志和任务数据 // 2. 拼装提示词 // 3. 调用 AI 服务 // 4. 保存结果到数据库 }定时表达式直接支持 Cron,比如0 0 1 * * ?表示每天凌晨 1 点执行。这个组合的价值在于:若依的调度能力补足了 AI 服务缺失的周期性触发能力,两边优势互补,形成一个真正能落地的自动化场景。做完这个功能,我明显感觉 AI 环境搭建不只是“接个接口”,而是能给业务带来实在的效率变化。
6. 踩坑记录:从环境到对接的常见问题
6.1 环境搭建阶段的坑
第一个坑是 MySQL 时区问题。若依连接数据库报时区错误是最常见的环境问题之一,报错信息在中文系统下可能显示成乱码。解决办法就是在 JDBC 连接串里加serverTimezone=Asia/Shanghai。这个坑几乎每个新手都会遇到,我建议在数据库连接串的模板里直接写全参数,以后每个项目都复用。
第二个坑是 Redis。启动后端时报 Redis 连接失败,但实际 Redis 明明装好了。后来发现是 Redis 密码问题,若依默认配置里密码为空,而本地 Redis 被我之前设置过密码,改了配置里的spring.redis.password才解决。另外,若依的验证码存在 Redis 里,如果 Redis 里残留旧数据,可能出现验证码明明输入正确却总是校验失败的情况,这时候清一下 Redis 缓存就好了。
第三个坑是 Maven 依赖下载慢。国内网络环境下,如果没有配镜像,第一次mvn package能把人活活等疯。配好阿里云公共仓库之后,构建时间从几十分钟缩短到几分钟,这属于“一次配置,长期受益”的操作。
6.2 依赖与版本引发的坑
先说 Java 侧。如果用 JDK 17 跑旧版若依,Lombok 版本太低会导致编译直接失败。我的建议:新项目直接拉最新版若依,老项目留在 JDK 8,不要轻易升级 JDK。另外,MySQL 驱动版本和数据库版本不匹配时会报通信协议错误,本地调试统一用和 MySQL 8.0 配套的驱动版本。
再说 Python 侧。最经典的问题就是torch.cuda.is_available()返回False,原因基本就三个:装成了 CPU 版、显卡驱动太老、PyTorch 的 CUDA 版本和驱动不匹配。排查思路很直接:先跑nvidia-smi看驱动支持的最高 CUDA 版本,再到 PyTorch 官网选择对应版本的安装命令重装。Python 版本也有坑,PyTorch 对 Python 3.12 以上的支持通常有滞后,建议环境统一用 Python 3.10,能省很多琐事。
6.3 对接阶段的坑
对接阶段我最常碰到的有三个问题。
第一个是超时。若依后端调用 AI 服务,如果模型推理慢,默认的 HTTP 客户端很容易在等待阶段就断开。解决方案是在调用 AI 服务时显式设置超时时间,并在若依侧的服务配置里适当调整。如果用户反馈页面一直转圈但没有错误提示,大概率就是超时时间太短,或者 AI 进程卡死。
第二个是跨域。如果前端页面直接请求 AI 服务地址,而不是经过若依后端转发,大概率会遇到跨域问题。FastAPI 里需要配置 CORSMiddleware,但我更推荐的是让所有请求都走若依后端,前端只需要跟若依通信,跨域问题直接绕开。这样架构也清晰,权限控制也容易统一。
第三个是中文乱码。FastAPI 返回中文默认就是 UTF-8,正常情况下不会乱码;出问题的地方常常在 Java 侧处理响应时,没有正确指定字符集。用 Hutool 的HttpRequest通常没问题,但如果你自己写原生 HttpClient,记得在解析响应时指定StandardCharsets.UTF_8。
还有一个看起来不算问题、实际很要命的细节:AI 服务的日志级别。FastAPI 默认的 access log 在并发高的时候会刷屏,Uvicorn 启动时加个--log-level warning参数,能显著降低日志噪音。排查问题时再看完整日志,平时保持安静,这是一种很实用的运维习惯。
结尾:几点真实体会
整套若依 AI 环境搭建走下来,我最深的体会是:真正耗时间的从来不是写代码,而是环境里的版本匹配和依赖安装。PyTorch 的 CUDA 版本、Java 的 JDK 版本、Node 的版本、MySQL 的字符集,任何一个错位都可能让你卡上半天。所以我强烈建议按这个顺序推进:先把若依自身跑通,再把 AI 服务单独冒烟验证,然后通过一个最简单的接口把两边连起来,最后再去加页面、定时任务、安全防护这些外围能力。每一步都验证完再进入下一步,能省掉大量“不知道是前端问题还是后端问题还是中间件问题”的无谓排查。
还有一个值得尝试的扩展方向:若依的代码生成器本身已经很强了,如果能把它生成的代码模版喂给 AI,让模型根据表结构描述自动产出增删改查的业务代码建议,再人工复核,那这套环境的价值就不只是“接了个聊天机器人”了,而是真正长在开发流程里的 AI 赋能。后面我会继续在这个方向折腾,踩出新的坑再来分享。