# Agent-for-Java **Repository Path**: jzwsoft/agent-for-java ## Basic Information - **Project Name**: Agent-for-Java - **Description**: 使用Java开发客户咨询的AI Agent - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-17 - **Last Updated**: 2026-06-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Agent-for-Java 基于 **Spring Boot + Spring AI + 本地 Ollama** 的客服咨询 Agent 示例项目,面向 Java 团队,Agent 内嵌于 Java 业务中,无需 Python 技术栈。 ## 功能特性 | 阶段 | 能力 | 说明 | |------|------|------| | 1 | 基础对话 | Spring AI 接入 Ollama,REST Chat API | | 2 | Tool Calling | 订单查询、退换货政策、工单创建 | | 3 | RAG 知识库 | FAQ 文档检索增强,回答积分/保修/配送等问题 | | 4 | 多轮记忆 | 基于 `sessionId` 的会话上下文 | | 5 | SSE 流式 | 逐字推送回复,改善前端体验 | | 6 | 生产化基础 | Actuator 健康检查、请求追踪、Micrometer 指标 | | **7.1** | **多 Agent 编排** | **LangGraph4j:研究 Agent 分析意图 + 执行 Agent 调用工具/RAG** | | **7.2** | **MCP 集成** | **MCP Server 暴露外部能力 + MCP Client 接入执行 Agent** | | **7.3** | **Human-in-the-loop** | **工单创建需人工确认,审批 API 确认/拒绝后生效** | > 阶段 1~7 已全部实现。 | 阶段 7 子项 | 状态 | 目标 | |-------------|------|------| | 7.1 多 Agent 编排 | **已实现** | LangGraph4j:研究 Agent 分析意图 + 执行 Agent 调用工具 | | 7.2 MCP 集成 | **已实现** | MCP Server/Client:物流、库存、门店、变更记录等外部工具 | | 7.3 Human-in-the-loop | **已实现** | 创建工单等敏感操作需人工确认后再执行 | ## 技术栈 - Java 21 - Spring Boot 3.4.5 - Spring AI 1.1.8 - LangGraph4j 1.8.19(多 Agent 图编排) - Ollama(本地 LLM + Embedding) - SimpleVectorStore(内存向量库,适合 Demo) - MessageWindowChatMemory(内存会话,适合 Demo) ## 架构概览 ```mermaid flowchart TB Client[客户端] --> API[REST / SSE API] API --> Graph[LangGraph4j 图编排] Graph --> Research[研究 Agent] Research -->|意图/策略| Execute[执行 Agent] Execute --> Memory[MessageChatMemoryAdvisor] Memory --> RAG[QuestionAnswerAdvisor] RAG --> Tools[CustomerServiceTools] Execute --> McpClient[MCP Client] McpClient --> McpServer[MCP Server /mcp] McpServer --> ExtTools[物流 / 库存 / 门店 / Git] Execute --> Ollama[Ollama qwen3] RAG --> VectorDB[(SimpleVectorStore)] VectorDB --> FAQ[knowledge/*.md] Tools --> Repo[Order / Policy / Ticket] Tools --> Approval[TicketApproval 待确认] Approval -->|confirm| Repo ``` ## 环境要求 - JDK 21+ - Maven 3.9+ - [Ollama](https://ollama.com/) 已安装并运行 拉取所需模型: ```bash ollama pull qwen3:4b-instruct ollama pull nomic-embed-text ``` 可用 `ollama list` 确认模型已就绪。 ## 快速开始 ```bash # 克隆项目 git clone cd Agent-for-Java # 编译打包 mvn clean package -DskipTests # 启动(推荐 jar 方式,避免 IDE/conda 类路径干扰) java -jar target/customer-agent-0.1.0-SNAPSHOT.jar # 或使用 Maven 插件 mvn spring-boot:run ``` 默认端口:`8088` ## API 说明 ### 非流式对话 ```bash curl -X POST http://localhost:8088/api/chat \ -H "Content-Type: application/json" \ -d '{"message":"帮我查一下订单 ORD-10001"}' ``` 响应示例: ```json { "sessionId": "d403e51e-cc50-406f-9d19-d55abfb5ba5e", "reply": "...", "pendingApprovalId": "APR-1001" } ``` 当 Agent 调用 `createSupportTicket` 提交工单申请时,响应会附带 `pendingApprovalId`(无待确认工单时为 `null`),前端可据此展示确认/取消按钮。 ### 工单人工确认(Human-in-the-loop) Agent 提交工单后**不会立即创建**,需调用审批 API 确认或拒绝: ```bash # 查看审批单详情 curl http://localhost:8088/api/approvals/APR-1001 # 确认创建工单 curl -X POST http://localhost:8088/api/approvals/APR-1001/confirm # 拒绝/取消申请 curl -X POST http://localhost:8088/api/approvals/APR-1001/reject ``` 确认成功响应示例: ```json { "approvalId": "APR-1001", "status": "CONFIRMED", "ticketId": "TKT-2001", "message": "工单已创建:工单号 TKT-2001,预计 24 小时内由人工客服跟进。" } ``` 审批单默认 **30 分钟**过期(`customer-agent.approval.expire-minutes`),过期后需重新发起申请。 完整流程示例: ```bash # 1. 用户请求创建工单 curl -X POST http://localhost:8088/api/chat \ -H "Content-Type: application/json" \ -d '{"message":"我要投诉订单 ORD-10001,商品有质量问题,请帮我建工单"}' # 2. 从响应中取出 pendingApprovalId,人工确认 curl -X POST http://localhost:8088/api/approvals/APR-1001/confirm ``` ### 多轮对话 第二轮请求需带上第一轮返回的 **真实** `sessionId`: ```bash curl -X POST http://localhost:8088/api/chat \ -H "Content-Type: application/json" \ -d '{ "message": "这个订单能退货吗?", "sessionId": "d403e51e-cc50-406f-9d19-d55abfb5ba5e" }' ``` ### 流式对话(SSE) ```bash curl -N -X POST http://localhost:8088/api/chat/stream \ -H "Content-Type: application/json" \ -d '{"message":"在线客服几点到几点?"}' ``` SSE 事件: | event | 含义 | |-------|------| | `session` | 会话 ID | | `message` | 回复片段 | | `done` | 流结束 | ### 清除会话 ```bash curl -X DELETE http://localhost:8088/api/chat/sessions/{sessionId} ``` ### 健康检查与监控 | 端点 | 说明 | |------|------| | `GET /api/health` | 简单健康检查 | | `GET /actuator/health` | 完整健康状态 | | `GET /actuator/health/readiness` | 就绪探针(Ollama + 知识库 + MCP) | | `GET /actuator/info` | 应用与 Agent 信息 | | `GET /actuator/metrics` | Micrometer 指标 | 每个请求响应头会携带 `X-Trace-Id`,便于日志排查。 ### MCP 状态 ```bash curl http://localhost:8088/api/mcp/status ``` 响应示例: ```json { "enabled": true, "connected": true, "toolCount": 4, "serverEndpoint": "/mcp", "protocol": "STREAMABLE", "tools": [ {"name": "queryShippingStatus", "description": "..."}, {"name": "queryInventory", "description": "..."} ] } ``` 外部 MCP 客户端(如 MCP Inspector、Cursor)可连接:`http://localhost:8088/mcp` MCP 工具调用示例: ```bash # 物流查询(经 Agent 自动路由 MCP 工具) curl -X POST http://localhost:8088/api/chat \ -H "Content-Type: application/json" \ -d '{"message":"帮我查一下订单 ORD-10001 的物流进度"}' # 门店查询 curl -X POST http://localhost:8088/api/chat \ -H "Content-Type: application/json" \ -d '{"message":"北京有哪些门店?营业时间是什么?"}' ``` ## 测试数据 ### 订单 | 订单号 | 商品 | 状态 | |--------|------|------| | ORD-10001 | 无线蓝牙耳机 | 已发货 | | ORD-10002 | 纯棉 T 恤 | 已完成 | | ORD-10003 | 坚果礼盒 | 待发货 | ### 退换货政策类目 `电子产品` · `服装` · `食品` ### 知识库文档 位于 `src/main/resources/knowledge/`: - `member-points.md` — 会员积分 - `warranty-policy.md` — 保修政策 - `shipping-policy.md` — 配送说明 - `payment-invoice.md` — 支付与发票 - `customer-service.md` — 客服服务时间 ## 配置说明 `src/main/resources/application.yml`: ```yaml spring.ai.ollama.base-url: http://localhost:11434 spring.ai.ollama.chat.options.model: qwen3:4b-instruct spring.ai.ollama.embedding.options.model: nomic-embed-text customer-agent.rag.top-k: 4 customer-agent.rag.similarity-threshold: 0.5 customer-agent.memory.max-messages: 20 customer-agent.mcp.enabled: true spring.ai.mcp.server.protocol: STREAMABLE spring.ai.mcp.server.streamable-http.mcp-endpoint: /mcp ``` > 默认端口改为 **8088**,避免本机 8080 常被 nginx 等占用。若 8088 也被占用,可设置环境变量 `SERVER_PORT=9090`。 ## 项目结构 ``` src/main/java/com/agent/customer/ ├── api/ # REST 控制器、DTO、异常处理 ├── config/ # ChatClient、Memory、RAG、追踪 Filter ├── actuator/ # Ollama / 知识库健康检查、Info 贡献者 ├── metrics/ # 对话耗时指标 ├── graph/ # LangGraph4j 状态、节点与图配置 ├── mcp/ # MCP Server 工具(@McpTool) ├── tools/ # 本地 @Tool 客服工具 ├── model/ # 领域模型 ├── repository/ # 模拟业务数据、审批单存储 ├── rag/ # 知识库加载与统计 └── service/ # 对话、流式、工单审批服务 src/main/resources/ ├── application.yml └── knowledge/ # FAQ Markdown 文档 ``` ## 阶段 7 ### 7.1 多 Agent 编排(LangGraph4j,已实现) ```mermaid flowchart LR User[用户问题] --> Research[研究 Agent] Research -->|意图/策略| Execute[执行 Agent] Execute --> Tools[Tool / RAG] Tools --> Reply[回复用户] ``` - **研究 Agent**(`ResearchAgentNode`):理解问题、结合会话历史,输出意图类型与执行策略(查订单 / 查政策 / 知识库 / 建工单) - **执行 Agent**(`ExecuteAgentNode`):按策略调用 `CustomerServiceTools`、RAG 与多轮记忆,生成最终回复 - **图编排**:`START → research → execute → END`,由 `CustomerAgentGraphService` 驱动 - **流式对话**:先同步完成研究阶段,再流式执行阶段推送 SSE 核心类: | 类 | 职责 | |----|------| | `CustomerAgentGraphState` | 图状态(sessionId、userMessage、strategy、reply) | | `CustomerAgentGraphConfig` | 注册 LangGraph4j 节点与边 | | `CustomerAgentGraphService` | 非流式 `invoke` / 流式 research + execute | ### 7.3 Human-in-the-loop(已实现) ```mermaid flowchart LR User[用户请求建工单] --> Agent[ChatClient + Tool] Agent --> Pending[待确认审批单 APR-xxxx] Pending -->|POST confirm| Ticket[正式工单 TKT-xxxx] Pending -->|POST reject| Cancel[取消申请] ``` - `createSupportTicket` 工具改为提交**审批单**,通过 `toolContext` 关联 `sessionId` - 内存 `TicketApprovalRepository` 存储审批状态(PENDING / CONFIRMED / REJECTED / EXPIRED) - `POST /api/chat` 响应附带 `pendingApprovalId`,供前端展示确认入口 - 审批 API:`GET /api/approvals/{id}`、`POST .../confirm`、`POST .../reject` ### 7.2 MCP(Model Context Protocol,已实现) ```mermaid flowchart LR Agent[执行 Agent] -->|MCP Client| Server[MCP Server /mcp] Server --> Ship[queryShippingStatus] Server --> Inv[queryInventory] Server --> Git[queryRecentChanges] Server --> Store[queryStoreInfo] ``` - **MCP Server**(`spring-ai-starter-mcp-server-webmvc`):通过 `@McpTool` 暴露 4 个外部能力,协议 `STREAMABLE`,端点 `/mcp` - **Agent 集成**:通过本地 `MethodToolCallbackProvider` 桥接同一套 MCP 工具实现(避免同进程 HTTP 回环与端口冲突) - **外部接入**:MCP Inspector / Cursor 等客户端可连接 `http://localhost:8088/mcp` - **模拟场景**:物流轨迹、只读库存(数据库)、Git 风格变更记录、线下门店信息 - **状态 API**:`GET /api/mcp/status`;就绪探针包含 `mcp` 健康检查 | MCP 工具 | 说明 | |----------|------| | `queryShippingStatus` | 按订单号查物流轨迹 | | `queryInventory` | 只读库存查询 | | `queryRecentChanges` | 最近系统变更(Git 风格) | | `queryStoreInfo` | 门店地址与营业时间 | ### 建议后续扩展 - 对接真实外部 MCP Server(Git、数据库、IDE 等) - 将 MCP Server 独立部署,Client 通过配置连接远程地址 ## 常见问题 **Q: 多轮对话不生效?** A: 确认第二轮使用了第一轮响应中的真实 `sessionId`(UUID 格式),不要填占位符文本。 **Q: 启动报 Ollama 相关错误?** A: 执行 `ollama serve`,并确认 chat / embedding 模型均已 `ollama pull`。 **Q: 日志出现 `ThrowableProxy` 错误?** A: 多为旧进程或 webflux starter 与 Tomcat 冲突导致;请 `mvn clean package` 后重新 `java -jar` 启动。 **Q: 如何上生产?** A: 建议替换为持久化向量库(pgvector / Redis)和 Redis 会话记忆;当前内存实现仅适合本地 Demo。 ## 参与贡献 1. Fork 本仓库 2. 新建功能分支 3. 提交代码 4. 新建 Pull Request ## 许可证 见 [LICENSE](LICENSE) 文件。