给个人博客装上“大脑”:用 Spring Boot + LangChain4j 实现全知全能的 Ops Copilot
参加 #人工智能创作者签约季# 活动
在 AI 时代,作为一个爱折腾的程序员,我一直在思考:大模型除了能帮我们写代码,能不能帮我们“管服务器”?
以前,管理个人博客往往意味着繁琐的流程:
- 博客图片需要一张张压缩上传到云存储。
- 服务器内存满了要 SSH 连上去排查日志。
- 忘了某个数据库容器的启动端口,还要翻查
docker-compose.yml。
为了彻底解放双手,我在重构最近的个人博客(Next.js + Spring Boot 前后端分离项目)时,索性把大模型作为 Agent 接入了系统的后台管理中。
经过几个周末的填坑,我终于实现了一个能够自动化管理服务器、执行命令行、上传文件、管理文章状态的 “Ops Copilot(运维副驾驶)”。
写下这篇文章,除了分享这个项目的架构和实现思路,也想和大家一起探讨 AI Agent 在日常 DevOps 场景中的无限潜力!🔥
🏗️ 整体架构设计:从 “瞎聊” 到 “干实事”
要做一个能管服务器的 AI,核心在于 LLM 必须具备 Tool Calling(工具调用)能力。它不能只停留在回答你“如何清理 Linux 日存”,而是能在你下达指令后,自动调用 SSH 工具去执行 rm -rf (当然需要二次确认😅)。
我选择了 Java + Spring Boot + LangChain4j 作为大模型后端基座,前端使用 Next.js 16 + Server-Sent Events (SSE) 实现流式交互。
整体的对话和执行流如下:
sequenceDiagram
participant User as 👨💻 用户 (Admin UI)
participant NextJS as 🌐 Next.js (前端代理)
participant Spring as 🚀 Spring Boot (业务后端)
participant LLM as 🧠 大模型 (DeepSeek/GPT-4)
participant Linux as 🖥️ 宿主机服务器
User->>NextJS: 1. "帮我查一下 docker 运行状态"
NextJS->>Spring: 2. 发起 SSE SSE 连接请求
Spring->>LLM: 3. 带着 System Prompt 和 Tools 列表请求大模型
LLM-->>Spring: 4. 大模型决定调用 `executeSshCommand` 工具
Spring->>NextJS: 5. [流式返回] 推送 Tool Call 事件前端展示状态
Spring->>Linux: 6. JSch 建立 SSH 连接并执行 `docker ps`
Linux-->>Spring: 7. 返回终端执行结果
Spring->>LLM: 8. 将终端日志交还给大模型分析
LLM-->>Spring: 9. 大模型生成易读的总结文本
Spring->>NextJS: 10. [流式返回] 将 Markdown 字幕逐字推送给用户
NextJS-->>User: 11. 渲染最终结果并断开连接
正如你所见,这不仅仅是一个聊天框,而是真实连接了宿主机环境的控制台。
🛠️ 后端基座:Spring Boot 拥抱 LangChain4j
很多人提起 AI 应用开发第一反应是 Python + LangChain。但如果你和我一样,是后端 Java 体系的老面孔,LangChain4j 绝对是不二之选。
在这个项目中,我们不需要写一堆底层的 API 封装代码,只需要利用 LangChain4j 提供的 @Tool 注解和声明式 AI Service,就能光速构建 Agent。
1. 声明式配置 AI Agent
通过 @AiService 注解,注入系统的预设人格和上下文。这种接口化的写法非常 Spring 风格,优雅且易于测试:
@AiService
public interface OpsCopilotService {
@SystemMessage({
"你是系统高级运维副驾驶 (Ops Copilot)。",
"你有能力通过提供的工具执行系统级操作,包括文件管理、SSH 命令执行等。",
"在执行破坏性命令(如 rm -rf 等)之前,必须先询问用户确认。",
"不要随意暴露服务器的底层密码或密钥信息。"
})
TokenStream chat(@MemoryId String sessionId, @UserMessage String userMessage);
}
2. 赋予 AI 灵魂:工具箱 (Tools)
大模型本身是不联网、不能碰磁盘的。我们要手动把“操作系统的手脚”给它接上。
这是我实现的一个 SSH 远程命令执行工具。只要给方法加上 @Tool 并且认真写好描述参数,大模型就能在需要时精准调用:
@Component
public class SshTools {
@Tool("执行宿主机 Linux Bash 命令,常用于查看系统状态、操作 docker 等。")
public String executeSshCommand(
@P("需要执行的 Linux 命令语句,不要包含危险的 rm -rf 等指令") String command
) {
log.info("【Ops Copilot】准备执行远程命令: {}", command);
// 伪代码:这里利用 com.jcraft.jsch 实现远程 SSH 执行并捕获输出
String output = jschService.exec(command);
return output;
}
}
💡 Tip: 大模型极其依赖
@Tool和参数上面的描述文字(@P)。你把这个描述当成给新员工写的岗位 S.O.P 手册就行,越详细,模型调用的错误率越低。
🌐 前端展现:Next.js + SSE 的流式魅力
想要好的用户体验,“打字机效果”是跑不掉的。但更复杂的是,我们不仅要展示文本,要在 AI "正在思考"、"正在执行脚本"、"执行完成" 这几个状态间来回切换。
由于管理后台 (personal-blog-admin) 是用 Next.js 16 (App Router) 写的,我通过原生的 fetch 结合 ReadableStream 实现了多态事件的流式接收 (Server-Sent Events)。
我定义了这几种事件:
message: 常规文本输出tool_call: 触发了服务器脚本操作(前端会打开一个伪终端窗口,打出“正在执行:xxx”)ops_log: 真正的终端日志(剥离 ANSI 转义码高亮显示)done: 流结束
在前端,自定义了 useOpsStream Hook 来解析这种混合事件:
// 解析自定义的混合 SSE 流数据块
const processChunk = (chunk: string) => {
const lines = chunk.split('\n');
for (const line of lines) {
if (!line.trim()) continue;
try {
const data = JSON.parse(line);
switch(data.type) {
case 'message':
updateChat(data.content);
break;
case 'tool_call':
showTerminalEffect(data.toolName, data.args);
break;
case 'ops_log':
appendTerminalLog(data.log);
break;
case 'done':
finishStream();
break;
}
} catch (e) {
console.error("解析流式数据失败", e);
}
}
}
前端 UI 最终呈现出了一种极客风格的双窗口模式:左侧是和 AI 聊天的窗口,右侧是一个嵌入的 Terminal 终端。AI 的每一步操作都会在右侧终端中刷出真实的执行日志,非常有赛博朋克的快感!

🚀 开源与踩坑总结
把大模型引入到 CRUD 项目里,让我真切地体会到了开发范式的转变:未来,我们的系统将越来越多地从 "API 驱动" 变成 "Agent 驱动"。
这个项目已经完全开源,分为 3 个仓库(后端、前端、管理端)。如果你想自己搭一套带 AI Agent 的高颜值博客,或者想白嫖一套开箱即用的代码学习 Spring Boot + LangChain4j,非常欢迎来看看!
👉 GitHub: personal-blog-backend(求个✨Star!写得头秃)
踩坑贴士
- 流式传输的跨域坑:前端使用 Nginx 代理或者 Next.js rewrites 时,经常会把 SSE 的 chunk 给合并缓存了,导致打字机效果失效(变成一坨坨直接崩出来)。记得在后端 Controller 和网关层加上强力的 Header
Cache-Control: no-cache。 - 大模型 Token 上限:让大模型执行
tail -n 100或者docker logs的时候,如果日志太长,返回给大模型上下文直接爆掉超载。必须要加最大字数截断!
科技永远在发展,不拥抱 AI 迟早会被淘汰。与其抵触它,不如让它成为替我们干脏活累活的 Copilot 吧!
欢迎在评论区交流,大家平时还有哪些工作希望用 Agent 自动化的?👇