基于 Spring Boot + LangChain4j 构建的 AI 智能旅游规划后端,集成了 ReAct / Plan-Act Agent、RAG 检索增强、Function Calling、MCP 工具、输入/输出护轨(Guardrail)、熔断器与限流(Resilience)、多轮会话记忆、Sa-Token 鉴权与 RBAC、Prometheus/Grafana 监控 等工程能力,面向「大模型不可靠、工具调用不可控、Prompt 易被注入」等真实生产问题提供可落地的解决方案。
本项目是 ai-tourism 的核心后端代码整理与开源版本,已对 API 密钥、JWT 密钥等隐私配置做脱敏处理,仅保留可运行的核心代码与建表 SQL。
| 分类 | 技术 | 说明 |
|---|---|---|
| 语言/框架 | Java 21(最低 17) | 主开发语言 |
| Spring Boot 3.5.6 | 应用框架 | |
| AI 编排 | LangChain4j 1.4.0(部分 community 模块 1.5.0-beta11) | Agent / ChatModel / MCP / Embedding 集成 |
| 数据库 | MySQL 8.0+ | 业务与用户数据持久化 |
| 向量/缓存 | Redis / Redis Stack 7.2 | 对话记忆、RAG 向量库(Redis Embedding Store)、限流计数 |
| ORM | MyBatis 3.0.5 | 注解式数据访问 |
| 鉴权 | Sa-Token 1.38.0(JWT 插件) | 登录态、Refresh Token、RBAC 注解鉴权 |
| 密码 | Spring Security BCrypt | 密码哈希 |
| 本地缓存 | Caffeine | AssistantService 实例缓存、LLM 响应缓存、Embedding 缓存 |
| HTTP | OkHttp3 / Hutool | 外部服务调用与工具库 |
| 文档解析 | Apache PDFBox 3.0.3 | RAG 文档(PDF)上传解析 |
| 监控 | Micrometer + Prometheus + Grafana | 指标采集、暴露、可视化 |
| 构建 | Maven | 依赖管理与打包 |
ai/agent/ReActAgentService 自建 Thought → Action → Observation 循环(不是简单套用框架),具备生产级健壮性:
- 最大步数控制(
react.max-steps,默认 5),超限强制总结,避免无限推理。 - 死循环检测:连续两次
Action+Input完全相同则自动终止。 - 工具结果缓存:同一 session 内相同工具调用复用结果,降低延迟与成本。
- 单步工具超时保护(
react.tool-timeout-seconds,默认 10s)。 - Thought 可观测:通过 SSE 把每一步的 Thought / Action / Observation 推送给前端,用户可见规划过程。
- 最终答案以 SSE 流式返回,配套
ReActPromptBuilder/ReActOutputParser/ReActStep完成提示词构建与结构化输出解析。
ai/advanced/PlanActAgentService 提供与 ReAct 互补的另一种范式:
- Stage 1 Planning:先让 LLM 生成 JSON 多步计划(全局规划能力更强)。
- Stage 2 Execution:按计划逐步调用工具,每步结果隔离存储、可追踪。
- Stage 3 Summarization:汇总所有步骤 Observation 生成最终答案。
- 适合步骤间有依赖关系的复杂任务。
ai/advanced/SelfReflectionService 实现「生成 → 检查 → 修正」闭环:回答生成后,用 Reflection Prompt 从完整性 / 合理性 / 安全性三个维度独立校验,不通过则返回修改建议并重新生成。
ai/rag/ 包是完整的 RAG 链路:
- Embedding:GLM Embedding-2(1024 维),
RagConfig支持${GLM_API_KEY}环境变量注入。 - 向量库:LangChain4j Community Redis Embedding Store,文档切片写入 Redis。
- 多路召回
MultiRecallService:向量检索(语义)+ 关键词检索(字面精确匹配,简化 BM25 思路)融合,互补召回。 - 重排序
RerankService:轻量级关键词命中数 + 位置加权精排,从 20+ 候选中筛选 Top-K。 - 入库质量门禁
ContentQualityChecker:入库前拦截低中文占比 / 高空白率 / 高重复率的垃圾文本,防止污染向量库。 - 用户隔离:向量 metadata 写入
userId,检索时多取后校验,防止跨用户文档交叉污染。 - Embedding 缓存
EmbeddingCache:基于文本 SHA-256,命中直接返回,避免重复调用 Embedding API。
ai/tool/ 包实现统一工具注册与调度:
BaseTool抽象基类,ToolManager统一注册、按名获取、动态扩展。- 内置
WeatherTool(天气)、POISearchTool(景点检索)两个 Function Call 工具。 - ReAct / Plan-Act 均通过
ToolManager执行工具,并做参数名适配(LLM 输出参数名不稳定)。
ai/mcp/McpClientService 基于 LangChain4j MCP 通过 SSE 连接外部 MCP 服务(如高德地图):
- 配置化、可热插拔(启停由
application.yml的mcp.clients控制)。 - 结果裁剪
ai/truncator/:McpResultTruncator+TruncatingToolProvider+ModelTrimmingProxies防止免费 API 的 4096 token 上限被击穿,支持 smart / simple / summary 多种策略与按工具差异化长度限制。
- 输入护轨
PromptSafetyInputGuardrail(实现 LangChain4jInputGuardrail):- 防御管线:长度/空值 → Unicode NFKC 归一化 → 同形字映射(西里尔/希腊 → 拉丁,防混淆攻击)→ URL / HTML 实体递归解码 → 敏感词 → 注入正则 → 越狱意图正则 → 编码差异检测。
- 可防御:直接指令覆盖、「忽略之前的指令」、编码绕过(%20 /
I)、角色扮演越狱(DAN)、系统提示词泄露尝试、参数注入等。
- 输出护轨
RetryOutputGuardrail(实现OutputGuardrail):- 检测空/过短响应、敏感内容泄露(密钥 / token /
sk-...)、系统 Prompt 指纹泄露(5-gram shingle 指纹,命中率超 30% 即判定泄露并重试)。
- 检测空/过短响应、敏感内容泄露(密钥 / token /
- 熔断器 + 重试 + 降级
AiResilienceService:- 三级容错:指数退避重试(最多 3 次,1s/3s/6s)→ 熔断器(连续失败 5 次熔断 30s,半开探测)→ 多模型降级(主模型不可用时切备用模型)。
- 业务价值:大模型 API 抖动时用户不会直接看到 500,系统自动恢复。
- 限流 + 隔舱
AiRateLimiter(纯 Java 零依赖实现,对标 Resilience4j):- 隔舱(Semaphore,最大并发 5)+ 滑动窗口 QPS 限流(默认 10/s)+ 每用户级限流,防止打爆 LLM API 或被恶意请求拖垮。
CustomRedisChatMemoryStore:短期记忆优先存 Redis(TTL 1800s),未命中回退 MySQL,降低数据库压力。MemoryAssistantServiceFactory:按sessionId隔离构建AssistantService实例,并用 Caffeine 缓存,减少实例重复创建(实测实例创建耗时下降约 28%)。- 长期历史通过 MyBatis 写入
t_ai_assistant_sessions/t_ai_assistant_chat_messages。
Sa-Token+ JWT:Access Token(10 分钟)+ Refresh Token(长期),@SaCheckLogin/@SaCheckPermission注解式鉴权。- 角色:
USER/ROOT;权限:ai:chat、ai:history、ai:session、user:disable、user:set-root。 - 密码 BCrypt 哈希存储。
AiModelMonitorListener(实现ChatModelListener)全程监听,经AiModelMetricsCollector(Micrometer)记录:请求数、Token 消耗、响应耗时、错误率、工具缓存命中节省的 Token。- 通过 Spring Boot Actuator 暴露
/actuator/prometheus,由 Prometheus 抓取、Grafana 可视化(仪表盘配置 JSON 可参考原项目doc/Prometheus-Grafana.json)。
- Caffeine 三级缓存:AssistantService 实例缓存、LLM 响应缓存
LlmResponseCache、Embedding 缓存EmbeddingCache,CacheStatsController暴露统计。 - A/B 测试框架
AbTestService+AbTestConfig:按比例分流,对比缓存 / 裁剪 / 不同策略的实际收益,用真实数据验证优化效果。
前端 (Vue) ──SSE──▶ Controller (鉴权/限流) ──▶ Service (MemoryChatServiceImpl / ReActAgentController)
│
┌──────────────────────────┼───────────────────────────┐
▼ ▼ ▼
AI Service 工厂 工具层 (Function Call + MCP) RAG 层
(AssistantService / ReAct / Plan-Act / Self-Reflection) ToolManager (Embedding + 向量库 + 多路召回 + 重排)
│ │ │
▼ ▼ ▼
护轨 Guardrail Resilience(熔断/重试/降级/限流) 记忆 (Redis + MySQL)
│
▼
监控 Micrometer → Prometheus → Grafana
数据流(一次对话):
ChatController/ReActAgentController接收请求并做登录态与权限校验;MemoryAssistantServiceFactory按sessionId取/建隔离的 AI Service 实例(Caffeine 缓存);- 系统提示词 → 窗口记忆 → 工具调用(Function Call + MCP)→ 输入护轨 → 模型推理 → 输出护轨 → SSE 流式返回;
AiModelMonitorListener全程记录指标。
smart-traver-agent/
├── pom.xml
├── docker-compose.yml # Redis Stack 一键启动
├── sql/
│ └── create_table.sql # 全部建表 + 种子数据(角色/权限)
└── src/
├── main/
│ ├── java/com/example/aitourism/
│ │ ├── ai/ # 核心 AI 能力
│ │ │ ├── agent/ # ReAct Agent
│ │ │ ├── advanced/ # Plan-Act / Self-Reflection / 多路召回 / 重排 / 缓存
│ │ │ ├── rag/ # RAG 检索增强
│ │ │ ├── tool/ # Function Calling 工具
│ │ │ ├── mcp/ # MCP 客户端
│ │ │ ├── guardrail/ # 输入/输出护轨
│ │ │ ├── resilience/ # 熔断器 + 限流
│ │ │ ├── memory/ # Redis 会话记忆
│ │ │ ├── truncator/ # MCP 结果裁剪
│ │ │ ├── AssistantService.java
│ │ │ └── MemoryAssistantServiceFactory.java
│ │ ├── config/ # Sa-Token / Redis / MCP / RAG / CORS / A/B 等配置
│ │ ├── controller/ # REST API
│ │ ├── dto/ # 传输对象
│ │ ├── entity/ # 实体
│ │ ├── exception/ # 全局异常处理
│ │ ├── mapper/ # MyBatis
│ │ ├── monitor/ # 监控埋点
│ │ ├── service/ # 业务 + AI 集成
│ │ └── util/
│ └── resources/
│ ├── application.yml # 主配置(密钥已脱敏,见下)
│ ├── application.properties
│ └── prompt/ # 系统提示词模板
└── test/ # 单元测试(缓存/召回重排/护轨/切片等)
- JDK 21(最低 17)
- Maven 3.8+
- MySQL 8.0+
- Redis / Redis Stack 7.2+(向量库需要 Redis Stack 的 RedisSearch 模块)
git clone https://github.com/<your-username>/smart-traver-agent.git
cd smart-traver-agent
mysql -u root -p < sql/create_table.sqldocker compose up -d # 使用仓库内 docker-compose.yml 启动 redis-stack仓库中的 application.yml 已脱敏,请用环境变量或本地覆盖填入真实密钥(推荐环境变量,避免再次泄露):
| 配置项 | 环境变量 | 说明 |
|---|---|---|
glm.api-key / glm-small.api-key / rag.embedding.api-key |
GLM_API_KEY |
智谱 GLM 兼容 OpenAI 协议,主模型 / 小模型 / Embedding 共用 |
openweather.api-key |
OPENWEATHER_API_KEY |
天气工具 API Key |
mcp.clients[amap].sse-url 中的 key |
— | 高德 MCP 服务的 key(直接改 URL) |
示例(Linux/macOS):
export GLM_API_KEY="你的真实GLM密钥"
export OPENWEATHER_API_KEY="你的OpenWeather密钥"
mvn spring-boot:runWindows(PowerShell):
$env:GLM_API_KEY="你的真实GLM密钥"
mvn spring-boot:run如需修改数据库连接、Redis 地址、JWT 密钥(
sa-token.jwt-secret-key,生产务必替换)、端口(默认 8290)等,直接编辑src/main/resources/application.yml。
# 构建(跳过测试可加 -DskipTests)
mvn clean package
# 运行
java -jar target/ai-tourism-0.0.1-SNAPSHOT.jar服务默认监听 http://localhost:8290。
| 接口 | 方法 | 说明 |
|---|---|---|
/auth/register |
POST | 注册(自动分配 USER 角色) |
/auth/login |
POST | 登录,返回 access + refresh token |
/auth/me |
GET | 当前用户信息及角色 |
/auth/refresh |
POST | 刷新 token |
/auth/logout |
POST | 登出 |
/auth/disable |
POST | 禁用用户(需 user:disable) |
/auth/set_root |
POST | 授权 ROOT(需 user:set-root) |
| 接口 | 方法 | 说明 |
|---|---|---|
/ai_assistant/chat |
POST | SSE 流式对话,返回旅游路线规划 |
/ai_assistant/get_history |
POST | 获取会话历史 |
/ai_assistant/session_list |
POST | 历史会话列表(分页) |
/api/react/agent |
POST | ReAct Agent SSE 流式执行(Thought/Action/Observation 可见) |
/api/document/upload |
POST | RAG 文档(PDF)上传与向量化 |
/api/document/list |
GET | 已上传文档列表 |
- 用户体系:
t_user、t_role、t_permission、t_user_role、t_role_permission、t_refresh_token - 业务体系:
t_ai_assistant_sessions、t_ai_assistant_chat_messages、t_poi - RAG 体系:
t_document_info、t_document_chunk
建表与种子数据(角色、权限、关联)见 sql/create_table.sql。
本项目仅供学习与研究使用,禁止未经授权的商业用途。