# spring-ai-agent-demo **Repository Path**: jackXUYY/spring-ai-agent-demo ## Basic Information - **Project Name**: spring-ai-agent-demo - **Description**: spring-ai-agent-demo - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-30 - **Last Updated**: 2026-08-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README --- AIGC: Label: "1" ContentProducer: 001191440300708461136T1XGW3 ProduceID: d9131e1e6ecd94de9637295002cb1e5c_607510d78fe511f19340525400f8a581 ReservedCode1: p/4hZ0NIr/B5qsFVBq7DvOP1hZDMBoAgHEeFnejfotoHqF+B7LH3PWNbzK43GFBvxYCrekWx+HMdaCx0KutK5k0llzP5YUuIp5Yt8t3/wtDgLMe5hCQkvh8mg4X24cdO2NWENbTmglZCITawCX+xC0sUj/rnTb7FFGmSfj3/E0wfh2NEf5TpKcElwdc= ContentPropagator: 001191440300708461136T1XGW3 PropagateID: d9131e1e6ecd94de9637295002cb1e5c_607510d78fe511f19340525400f8a581 ReservedCode2: p/4hZ0NIr/B5qsFVBq7DvOP1hZDMBoAgHEeFnejfotoHqF+B7LH3PWNbzK43GFBvxYCrekWx+HMdaCx0KutK5k0llzP5YUuIp5Yt8t3/wtDgLMe5hCQkvh8mg4X24cdO2NWENbTmglZCITawCX+xC0sUj/rnTb7FFGmSfj3/E0wfh2NEf5TpKcElwdc= --- # Spring AI Agent Demo 基于 **Spring AI Alibaba Agent Framework (ReactAgent)** + **阿里云 DashScope / 智谱 GLM** 的多 Agent 协作平台。 ## 架构概览 ``` 用户请求 → ChatController (SSE) → MainAgent (ReactAgent, recursionLimit=15) │ └── DispatchTool.dispatchTask ──→ 5 个子 Agent ├── file (文件系统操作) ├── browser (网页浏览) ├── computer (系统控制) ├── search (深度搜索) └── app (应用管理) ``` - **MainAgent**:仅持有 `DispatchTool.dispatchTask` 一个工具,负责理解用户意图并派发给专业子 Agent。 - **5 个子 Agent**:各自基于 `ReactAgent`,拥有独立 System Prompt 和专属工具集,通过 `SubAgentManager` 统一注册和调度。 - **RecursionLimit**:所有 Agent(主 + 子)统一设为 15。 - **存储**:纯内存存储(`MemorySaver` + `ConversationManager` + `MemoryManager`),无数据库依赖,重启即丢失数据。 ## 项目结构 ``` spring-ai-agent-demo/ ├── pom.xml # 父工程 POM(统一版本管理) ├── spring-ai-agent-demo-backend/ # 后端 Spring Boot 服务 │ ├── pom.xml │ └── src/main/java/com/example/demo/ │ ├── Application.java # 启动类 │ ├── agent/ │ │ ├── core/ │ │ │ ├── MainAgent.java # 主 Agent(派发) │ │ │ └── ConfirmManager.java # 高风险工具确认 │ │ ├── event/ │ │ │ ├── StreamEvent.java # SSE 事件模型 │ │ │ ├── ToolEventSink.java # 工具事件推送 │ │ │ ├── ProgressTracker.java # 进度追踪 │ │ │ └── DiffUtil.java # 文本差异工具 │ │ ├── interceptor/ │ │ │ └── SseToolInterceptor.java # SSE 工具拦截器 │ │ ├── subagent/ │ │ │ └── SubAgentManager.java # 子 Agent 注册与调度 │ │ └── tool/ │ │ └── DispatchTool.java # 任务派发工具 │ ├── chat/ │ │ ├── ChatController.java # REST + SSE 对话 API │ │ ├── ConversationManager.java # 会话上下文管理(内存) │ │ ├── TestController.java # 测试端点 │ │ └── dto/ │ │ ├── ChatRequest.java # 请求 DTO │ │ └── ConfirmRequest.java # 确认请求 DTO │ ├── checkpoint/ │ │ ├── CheckpointManager.java # 检查点管理(undo/redo) │ │ └── CheckpointController.java # 检查点 API │ ├── memory/ │ │ └── MemoryManager.java # 记忆管理器(ConcurrentHashMap) │ ├── config/ │ │ ├── AiConfig.java # Agent 注册与模型配置 │ │ ├── CorsConfig.java # CORS 跨域 │ │ ├── RequestLoggingFilter.java # 请求日志拦截 │ │ └── AiApiHealthIndicator.java # API 健康检查 │ ├── common/ │ │ ├── Result.java # 统一响应体 │ │ ├── GlobalExceptionHandler.java # 全局异常处理 │ │ ├── constants/ # 常量枚举 │ │ └── exception/ # 自定义异常 │ ├── controller/ │ │ └── ScreenshotController.java # 截图 API │ ├── tools/ │ │ ├── filesystem/ # 文件系统工具 (4 类) │ │ ├── browser/ # 浏览器工具 (3 类) │ │ ├── computer/ # 系统控制工具 (5 类) │ │ ├── terminal/ # 终端执行工具 (2 类 + 沙箱) │ │ ├── codesearch/ # 代码搜索工具 (2 类) │ │ ├── search/ # 深度搜索工具 │ │ ├── app/ # 应用管理工具 │ │ └── mcp/ # MCP 工具注册 │ └── util/ │ └── JasyptUtil.java # Jasypt 加密工具 ├── spring-ai-agent-demo-front/ # 前端 React + Vite 项目 │ ├── package.json │ ├── vite.config.ts │ ├── tsconfig.json │ ├── tailwind.config.js │ └── src/ │ ├── main.tsx │ ├── App.tsx # 根组件 │ ├── constants.ts # 全局常量 │ ├── types/index.ts # TypeScript 类型 │ ├── api/chat.ts # SSE 流式 API │ ├── store/ │ │ ├── chatStore.ts # Zustand 聊天状态 │ │ └── themeStore.ts # Zustand 主题状态 │ └── components/ │ ├── ChatWindow.tsx # 主聊天窗口 │ ├── InputArea.tsx # 输入区域 │ ├── MessageBubble.tsx # 消息气泡 │ ├── VirtualMessageList.tsx # 虚拟滚动列表 │ ├── CodeBlock.tsx # 代码块高亮 │ ├── ToolCallCard.tsx # 工具调用卡片 │ ├── StepCard.tsx # 执行步骤卡片 │ ├── TokenUsage.tsx # Token 用量展示 │ ├── FileCard.tsx # 文件卡片 │ ├── ImageUploader.tsx # 图片上传 │ ├── ConfirmDialog.tsx # 确认弹窗 │ ├── StreamConfirmDialog.tsx # 流式确认弹窗 │ ├── SkillPanel.tsx # 技能面板(懒加载) │ ├── SessionList.tsx # 会话列表(懒加载) │ ├── DiffView.tsx # 差异对比(懒加载) │ ├── TabBar.tsx # 标签栏 │ ├── ConversationTree.tsx # 对话树 │ ├── ErrorBoundary.tsx # 错误边界 │ ├── Skeleton.tsx # 骨架屏 │ └── Components.module.css # 组件样式模块 ``` ## 技术栈 | 层级 | 技术 | 版本 | |------|------|------| | 框架 | Spring Boot | 3.5.16 | | AI 框架 | Spring AI Alibaba Agent Framework | 1.1.2.0 | | AI 协议 | Spring AI OpenAI Starter | 1.1.2 | | 模型 | 阿里云 DashScope (qwen3.7-max) / 智谱 GLM-4.7 | — | | 存储 | 纯内存(无数据库依赖,重启即丢失数据) | — | | 加密 | Jasypt Spring Boot Starter | 3.0.5 | | 缓存 | Caffeine | 3.1.8 | | Markdown | CommonMark + Flexmark | 0.21.0 / 0.64.8 | | HTTP 抓取 | Jsoup | 1.18.1 | | MCP | Spring AI MCP Client | 1.1.2 | | 前端 | React + TypeScript + Vite | 18 / 5.5 / 5.4 | | 状态管理 | Zustand | 5.0 | | 虚拟滚动 | react-window | 1.8 | | XSS 防护 | DOMPurify | 3.4 | | Markdown 渲染 | marked + highlight.js | 18.0 / 11.11 | | 样式 | Tailwind CSS | 4.3 | | PWA | vite-plugin-pwa | 1.3 | | 测试 | vitest + @testing-library/react | 4.1 / 16.3 | | JDK | Java 17 | — | ## 快速启动 ### 1. 前置条件 - JDK 17+ - Maven 3.8+ - Node.js 18+(前端) - API Key(阿里云 DashScope 或智谱 GLM) ### 2. 配置 API Key **环境变量(推荐)** ```powershell # PowerShell (阿里云 DashScope) $env:QWEN_API_KEY="你的 API Key" ``` ```bash # Linux / macOS export QWEN_API_KEY="你的 API Key" ``` **IDEA Run Configuration** 编辑 Run Configuration → Environment variables 添加:`QWEN_API_KEY=你的 API Key` ### 3. 启动后端 ```bash cd spring-ai-agent-demo mvn clean install -DskipTests cd spring-ai-agent-demo-backend mvn spring-boot:run ``` 服务启动后访问:http://localhost:8080 ### 4. 启动前端 ```bash cd spring-ai-agent-demo-front npm install npm run dev ``` 浏览器访问:http://localhost:3000 ### 5. IDEA 导入 直接用 IDEA 打开 `spring-ai-agent-demo` 目录,自动识别多模块 Maven 结构。 ## API 接口 | 方法 | 路径 | 说明 | |------|------|------| | `POST` | `/api/chat` | 同步对话(非流式) | | `POST` | `/api/chat/stream` | SSE 流式对话(双通道:文本流 + 工具事件流) | | `POST` | `/api/chat/confirm` | 确认对话框响应(HITL) | | `POST` | `/api/chat/upload` | 文件上传 | | `GET` | `/api/memory/search` | 记忆检索(sessionId + query + limit) | | `GET` | `/api/sessions` | 列出所有会话 | | `GET` | `/api/sessions/{sessionId}` | 获取会话上下文 | | `DELETE` | `/api/sessions/{sessionId}` | 删除会话(同时清理 checkpoint) | | `POST` | `/api/sessions/{sessionId}/checkpoint` | 创建检查点快照 | | `POST` | `/api/sessions/{sessionId}/checkpoint/undo` | 撤销到上一个检查点 | | `POST` | `/api/sessions/{sessionId}/checkpoint/redo` | 重做到下一个检查点 | | `GET` | `/api/sessions/{sessionId}/checkpoints` | 列出会话所有检查点 | | `GET` | `/api/sessions/{sessionId}/checkpoint/latest` | 获取最新检查点 | ### 流式对话示例 ```bash curl -X POST http://localhost:8080/api/chat/stream \ -H "Content-Type: application/json" \ -d '{"message":"用 Python 写一个快速排序"}' ``` **SSE 事件流格式:** ``` data: {"type":"THOUGHT","content":"分析中..."} data: {"type":"TOOL_CALL","toolName":"dispatchTask"} data: {"type":"TOOL_RESULT","content":"..."} data: {"type":"TEXT","content":"排序完成"} ``` ## 核心设计 ### 子 Agent 与工具生态 共 **18 个工具类**,**103 个 @Tool 方法**,按子 Agent 分组: #### MainAgent(派发层) | 工具类 | 方法 | 说明 | |--------|------|------| | `DispatchTool` | `dispatchTask` | 将任务派发给指定的专业子 Agent 执行 | #### file(文件系统 Agent) | 工具类 | 方法 | 说明 | |--------|------|------| | `FileTool` | `readFile` / `writeFile` / `editFile` / `listDirectory` | 文件读写、编辑、目录列表 | | `DeleteTool` | `deleteFiles` | 删除文件或文件夹(移至回收站) | | `ImageAnalysisTool` | `analyzeImage` | 图片内容视觉理解 | | `SearchContentTool` | `searchContent` | 全文搜索文件内容 | | `CodeSearchTool` | `searchCodebase` / `searchFilesByGlob` / `diffLines` | 正则搜索 / glob 匹配 / 行级 diff | #### browser(浏览器 Agent) | 工具类 | 方法 | 说明 | |--------|------|------| | `WebSearchTool` | `webSearch` | 联网搜索,返回标题+链接+摘要 | | `WebFetchTool` | `webFetch` | 抓取网页正文纯文本 | | `BrowserPlaywrightTool` | `navigate` / `click` / `type` / `getText` / `screenshot` | 浏览器自动化操作 | #### computer(系统控制 Agent) | 工具类 | 方法 | 说明 | |--------|------|------| | `ShellExecutionTool` | `executeShellCommand` | 沙箱内执行 Shell 命令 | | `PythonExecutionTool` | `executePython` | 沙箱内执行 Python 代码 | | `SystemInfoTool` | `getSystemInfo` / `getOsInfo` / `getCpuInfo` / `getMemoryInfo` / `getDiskInfo` / `getEnvVariables` | 系统信息查询 | | `WindowTool` | `listWindows` / `focusWindow` / `minimizeWindow` / `maximizeWindow` / `closeWindow` | 窗口管理 | | `ProcessTool` | `listProcesses` / `killProcess` | 进程管理 | | `SettingsTool` | `openSettings` / `openAdminTool` | 系统设置面板 | | `InputTool` | `typeText` / `pressKeys` / `mouseClick` | 键盘鼠标模拟 | #### search(搜索 Agent) | 工具类 | 方法 | 说明 | |--------|------|------| | `DeepSearchTool` | `deepResearch` / `quickSearch` | 深度联网研究与快速检索 | | `WebSearchTool` | `webSearch` | 联网搜索 | | `WebFetchTool` | `webFetch` | 网页抓取 | #### app(应用管理 Agent) | 工具类 | 方法 | 说明 | |--------|------|------| | `AppManagerTool` | `searchApp` / `installApp` / `uninstallApp` / `updateApp` / `listInstalledApps` | 应用搜索、安装(winget)、卸载、更新 | | `ShellExecutionTool` | `executeShellCommand` | Shell 命令执行 | | `WindowTool` | 5 个窗口管理方法 | 窗口控制 | | `ProcessTool` | 2 个进程管理方法 | 进程管理 | ### 安全防线 Shell 命令执行的安全保护(`ShellExecutionTool.executeShellCommand`): 1. **命令白名单放行**:提取命令第一个 token,匹配白名单的命令直接放行;未知命令打印 WARN 日志后放行(避免无害命令导致任务失败) 2. **危险命令黑名单拦截**:`rm -rf` / `del /f` / `format` / `shutdown` 等直接拒绝执行 3. **路径检查**:当前为全放行模式,仅由黑名单拦截破坏性操作 4. **超时控制**:超过配置时间自动终止进程 5. **输出容量限制**:最大 100KB,防止超大输出撑爆内存 高风险操作(Shell / Python 执行)执行前通过 `ConfirmManager` 向用户请求确认(HITL)。 ### 记忆系统 - **存储**:`ConcurrentHashMap` 纯内存存储,重启即丢失 - **检索**:基于关键词的字符串包含匹配(key + value),按重要性降序排列 - **短期记忆**:60 分钟 TTL,定时清理(每 5 分钟),重要性 < 7 的过期自动清除 - **长期记忆**:重要性 ≥ 7 自动提升,不受 TTL 限制 - **会话隔离**:记忆按 sessionId 隔离 ### 检查点系统(Checkpoint) - 基于 `MemorySaver` 的快照机制,支持 undo / redo - 通过 `CheckpointManager` 管理会话级检查点 - 删除会话时自动清理关联检查点 ### 前端生产级特性 | 特性 | 实现 | |------|------| | 深色/亮色主题 | Zustand themeStore + Tailwind dark mode | | 虚拟滚动 | react-window,消息 >50 条启用 | | SSE 流式输出 | EventSource + 指数退避重连(最多 3 次) | | XSS 防护 | DOMPurify sanitize HTML | | 错误边界 | ErrorBoundary 降级 UI + 重试 | | 代码分割 | SkillPanel / SessionList / DiffView React.lazy | | 骨架屏 | 组件加载态 Skeleton | | 键盘导航 | ConfirmDialog Escape 关闭 + 焦点陷阱 | | PWA | Service Worker + manifest,可离线访问 | | 测试 | vitest + @testing-library/react | ## 配置项 `application.yml` 关键配置(默认 profile,使用阿里云 DashScope qwen3.7-max): ```yaml app: session: max-history-rounds: 20 # 会话最大轮数 timeout-minutes: 30 # 会话超时(分钟) cleanup-interval-ms: 300000 # 定时清理间隔(毫秒) sandbox: timeout-seconds: 60 # 命令执行超时(秒) shell-blacklist: "rm -rf,rmdir /s,del /f,del /q,format,shutdown,reboot,diskpart,chkdsk /f" python-forbidden: "os.system,subprocess,shutil.rmtree" allowed-paths: - "./data/" - "./temp/" memory: short-term-ttl-minutes: 60 long-term-importance-threshold: 7 ``` `application-dev.yml` 使用智谱 GLM-4.7,sandbox 超时调整为 30 秒,额外放行用户目录路径。 ## Jasypt 加密 ```bash # Windows encrypt.bat "你的明文" "你的密码" # Linux / macOS ./encrypt.sh "你的明文" "你的密码" ``` 输出 `ENC(...)` 密文写入 `application.yml` 对应配置项即可。 ## 对标分析 | 维度 | Spring AI Agent Demo | Claude Code | Trae | WorkBuddy | |------|---------------------|-------------|------|-----------| | Agent 架构 | Spring AI Alibaba ReactAgent + 5 子 Agent | Agentic Loop | Agentic Loop | Task Loop | | 工具生态 | 18 工具类 / 103 @Tool 方法 | MCP + 内置工具 | MCP + 插件 | 内置工具 | | 安全防线 | 白名单放行 → 黑名单拦截 → 超时 + 输出限制 | 沙箱 | 沙箱 | 权限控制 | | 会话持久化 | 纯内存(无数据库依赖) | 本地文件 | 云端 | 云端 | | 记忆系统 | ConcurrentHashMap 关键词匹配 + TTL | — | — | — | | 检查点 | MemorySaver undo/redo | 任务恢复 | — | — | | 流式输出 | SSE + 双通道 + 重连 | SSE | SSE | SSE | | 前端 | React 18 + PWA | CLI | Electron | Electron | | 部署 | 本地服务 | CLI / API | 桌面应用 | 桌面应用 | ## 许可证 MIT License *(内容由AI生成,仅供参考)*